girepository: Make gi_repository_get_loaded_namespaces() deterministic

As with the previous two commits, the results of calling
`gi_repository_get_loaded_namespaces()` were previously
non-deterministic due to being generated by iterating over a hash table,
which has a non-deterministic iteration order.

Fix that by using the new `ordered_typelibs` and `ordered_lazy_typelibs`
arrays to provide deterministic ordering.

At the same time, significantly reduce the number of allocations needed
to build the return value — previously the results would be built as a
linked list before being turned into an array. The linked list is now
banished to history.

Add some more unit tests to maximise test coverage of this method.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Fixes: #3303
This commit is contained in:
Philip Withnall
2024-05-02 16:30:09 +01:00
parent 0d199d6199
commit 03248e7b18
2 changed files with 45 additions and 14 deletions

View File

@@ -863,6 +863,35 @@ test_repository_find_by_gtype (RepositoryFixture *fx,
}
}
static void
test_repository_loaded_namespaces (RepositoryFixture *fx,
const void *unused)
{
char **namespaces;
size_t n_namespaces;
/* These should be in alphabetical order */
#if defined(G_OS_UNIX)
const char *expected_namespaces[] = { "GLib", "GModule", "GObject", "Gio", "GioUnix", NULL };
#elif defined(G_OS_WIN32)
const char *expected_namespaces[] = { "GLib", "GModule", "GObject", "Gio", "GioWin32", NULL };
#else
const char *expected_namespaces[] = { "GLib", "GModule", "GObject", "Gio", NULL };
#endif
g_test_summary ("Test listing loaded namespaces");
namespaces = gi_repository_get_loaded_namespaces (fx->repository, &n_namespaces);
g_assert_cmpstrv (namespaces, expected_namespaces);
g_assert_cmpuint (n_namespaces, ==, g_strv_length ((char **) expected_namespaces));
g_strfreev (namespaces);
/* Test again but without passing `n_namespaces`. */
namespaces = gi_repository_get_loaded_namespaces (fx->repository, NULL);
g_assert_cmpstrv (namespaces, expected_namespaces);
g_strfreev (namespaces);
}
int
main (int argc,
char *argv[])
@@ -891,6 +920,7 @@ main (int argc,
ADD_REPOSITORY_TEST ("/repository/vfunc-info-with-invoker-on-interface", test_repository_vfunc_info_with_invoker_on_interface, &typelib_load_spec_gio);
ADD_REPOSITORY_TEST ("/repository/vfunc-info-with-invoker-on-object", test_repository_vfunc_info_with_invoker_on_object, &typelib_load_spec_gio);
ADD_REPOSITORY_TEST ("/repository/find-by-gtype", test_repository_find_by_gtype, &typelib_load_spec_gio_platform);
ADD_REPOSITORY_TEST ("/repository/loaded-namespaces", test_repository_loaded_namespaces, &typelib_load_spec_gio_platform);
return g_test_run ();
}