summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2020-04-27 11:12:55 +0200
committerBenjamin Berg <bberg@redhat.com>2021-01-11 18:01:27 +0100
commitabf8efd609658bf3c1b4fb132a8d8ee10823b3ac (patch)
treea6ebd3ba1d8382d80d5bdb251dc756ead36236b8
parent40d2392432036bee9e796a34e25ae381ec1d074f (diff)
downloadlibgweather-abf8efd609658bf3c1b4fb132a8d8ee10823b3ac.tar.gz
test: Add tree walk test
-rw-r--r--libgweather/test_libgweather.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/libgweather/test_libgweather.c b/libgweather/test_libgweather.c
index ea5d076..8484151 100644
--- a/libgweather/test_libgweather.c
+++ b/libgweather/test_libgweather.c
@@ -26,6 +26,7 @@
#include <gweather-version.h>
#include "gweather-location.h"
#include "gweather-weather.h"
+#include "gweather-private.h"
/* We use/test gweather_location_get_children */
#pragma GCC diagnostic push
@@ -797,6 +798,58 @@ test_weather_loop_use_after_free (void)
}
static void
+test_walk_world (void)
+{
+ g_autoptr(GWeatherLocation) cur = NULL, next = NULL;
+ gint visited = 0;
+
+ next = gweather_location_get_world ();
+ while (next) {
+ /* Update cur pointer. */
+ g_clear_pointer (&cur, gweather_location_unref);
+ cur = g_steal_pointer (&next);
+ visited += 1;
+ g_assert_cmpint (cur->ref_count, ==, 1);
+
+ /* Select next item, which is in this order:
+ * 1. The first child
+ * 2. Walk up the parent tree and try to find a sibbling
+ * Note that cur remains valid after the loop and points to the world
+ * again.
+ */
+ if ((next = gweather_location_next_child (cur, NULL)))
+ continue;
+
+ while (TRUE) {
+ g_autoptr(GWeatherLocation) child = NULL;
+ /* Move cur to the parent, keeping the child as reference. */
+ child = g_steal_pointer (&cur);
+ cur = gweather_location_get_parent (child);
+ if (!cur)
+ break;
+ g_assert_cmpint (cur->ref_count, ==, 1);
+ g_assert_cmpint (child->ref_count, ==, 1);
+
+ if ((next = gweather_location_next_child (cur, gweather_location_ref (child))))
+ break;
+ }
+ }
+
+ /* cur must be NULL at this point */
+ g_assert_null (cur);
+
+ /* Check that we visited a reasonable number of nodes.
+ * Due to implicit nearest nodes, this needs to be more than the number
+ * of DB entries. */
+ cur = gweather_location_get_world ();
+ g_assert_cmpint (visited, >, cur->db->locations->len);
+ g_clear_pointer (&cur, gweather_location_unref);
+
+ /* noop, but asserts we did not leak */
+ _gweather_location_reset_world ();
+}
+
+static void
log_handler (const char *log_domain, GLogLevelFlags log_level, const char *message, gpointer user_data)
{
g_print ("%s\n", message);
@@ -830,6 +883,7 @@ main (int argc, char *argv[])
g_test_add_func ("/weather/bad_duplicate_weather_stations", test_bad_duplicate_weather_stations);
g_test_add_func ("/weather/duplicate_weather_stations", test_duplicate_weather_stations);
g_test_add_func ("/weather/location-names", test_location_names);
+ g_test_add_func ("/weather/walk_world", test_walk_world);
return g_test_run ();
}