mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 16:32:18 +01:00 
			
		
		
		
	GType is either an integer or a pointer, so we have to use the _pointer version here to support architectures such as Morello. Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/2842 See also: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3578
		
			
				
	
	
		
			247 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: LGPL-2.1-or-later
 | ||
| // SPDX-FileCopyrightText: 2021  Emmanuele Bassi
 | ||
| 
 | ||
| #include <glib-object.h>
 | ||
| 
 | ||
| typedef struct
 | ||
| {
 | ||
|   GTypeInterface g_iface;
 | ||
| } TestInterfaceInterface;
 | ||
| 
 | ||
| GType test_interface_get_type (void);
 | ||
| #define TEST_TYPE_INTERFACE test_interface_get_type ()
 | ||
| G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_INVALID)
 | ||
| 
 | ||
| static void
 | ||
| test_interface_default_init (TestInterfaceInterface *iface)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| test_type_flags_interface (void)
 | ||
| {
 | ||
|   g_assert_false (G_TYPE_IS_ABSTRACT (TEST_TYPE_INTERFACE));
 | ||
|   g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_ABSTRACT));
 | ||
| 
 | ||
|   g_assert_false (G_TYPE_IS_CLASSED (TEST_TYPE_INTERFACE));
 | ||
|   g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_CLASSED));
 | ||
| 
 | ||
|   g_assert_false (G_TYPE_IS_DEEP_DERIVABLE (TEST_TYPE_INTERFACE));
 | ||
|   g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DEEP_DERIVABLE));
 | ||
| 
 | ||
|   g_assert_true (G_TYPE_IS_DERIVABLE (TEST_TYPE_INTERFACE));
 | ||
|   g_assert_true (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DERIVABLE));
 | ||
| 
 | ||
|   g_assert_false (G_TYPE_IS_FINAL (TEST_TYPE_INTERFACE));
 | ||
|   g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_FINAL));
 | ||
| 
 | ||
|   g_assert_false (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_INTERFACE));
 | ||
|   g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_INSTANTIATABLE));
 | ||
| }
 | ||
| 
 | ||
| #define TEST_TYPE_FINAL (test_final_get_type())
 | ||
| G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject)
 | ||
| 
 | ||
| struct _TestFinal
 | ||
| {
 | ||
|   GObject parent_instance;
 | ||
| };
 | ||
| 
 | ||
| struct _TestFinalClass
 | ||
| {
 | ||
|   GObjectClass parent_class;
 | ||
| };
 | ||
| 
 | ||
| G_DEFINE_FINAL_TYPE (TestFinal, test_final, G_TYPE_OBJECT)
 | ||
| 
 | ||
| static void
 | ||
| test_final_class_init (TestFinalClass *klass)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| test_final_init (TestFinal *self)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| #define TEST_TYPE_FINAL2 (test_final2_get_type())
 | ||
| G_DECLARE_FINAL_TYPE (TestFinal2, test_final2, TEST, FINAL2, TestFinal)
 | ||
| 
 | ||
| struct _TestFinal2
 | ||
| {
 | ||
|   TestFinal parent_instance;
 | ||
| };
 | ||
| 
 | ||
| struct _TestFinal2Class
 | ||
| {
 | ||
|   TestFinalClass parent_class;
 | ||
| };
 | ||
| 
 | ||
| G_DEFINE_TYPE (TestFinal2, test_final2, TEST_TYPE_FINAL)
 | ||
| 
 | ||
| static void
 | ||
| test_final2_class_init (TestFinal2Class *klass)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| test_final2_init (TestFinal2 *self)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| /* test_type_flags_final: Check that trying to derive from a final class
 | ||
|  * will result in a warning from the type system
 | ||
|  */
 | ||
| static void
 | ||
| test_type_flags_final (void)
 | ||
| {
 | ||
|   GType final2_type;
 | ||
| 
 | ||
|   g_assert_true (G_TYPE_IS_FINAL (TEST_TYPE_FINAL));
 | ||
|   g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_FINAL));
 | ||
|   g_assert_true (G_TYPE_IS_CLASSED (TEST_TYPE_FINAL));
 | ||
|   g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_CLASSED));
 | ||
|   g_assert_true (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_FINAL));
 | ||
|   g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_INSTANTIATABLE));
 | ||
|   g_assert_true (g_type_test_flags (TEST_TYPE_FINAL,
 | ||
|                                     G_TYPE_FLAG_FINAL |
 | ||
|                                     G_TYPE_FLAG_CLASSED |
 | ||
|                                     G_TYPE_FLAG_INSTANTIATABLE));
 | ||
|   g_assert_false (g_type_test_flags (TEST_TYPE_FINAL,
 | ||
|                                      G_TYPE_FLAG_FINAL |
 | ||
|                                      G_TYPE_FLAG_CLASSED |
 | ||
|                                      G_TYPE_FLAG_DEPRECATED |
 | ||
|                                      G_TYPE_FLAG_INSTANTIATABLE));
 | ||
| 
 | ||
|   /* This is the message we print out when registering the type */
 | ||
|   g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
 | ||
|                          "*cannot derive*");
 | ||
| 
 | ||
|   /* This is the message when we fail to return from the GOnce init
 | ||
|    * block within the test_final2_get_type() function
 | ||
|    */
 | ||
|   g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
 | ||
|                          "*g_once_init_leave_pointer: assertion*");
 | ||
| 
 | ||
|   final2_type = TEST_TYPE_FINAL2;
 | ||
|   g_assert_true (final2_type == G_TYPE_INVALID);
 | ||
| 
 | ||
|   g_test_assert_expected_messages ();
 | ||
| }
 | ||
| 
 | ||
| #define TEST_TYPE_DEPRECATED (test_deprecated_get_type())
 | ||
| G_DECLARE_FINAL_TYPE (TestDeprecated, test_deprecated, TEST, DEPRECATED, GObject)
 | ||
| 
 | ||
| struct _TestDeprecated
 | ||
| {
 | ||
|   GObject parent_instance;
 | ||
| };
 | ||
| 
 | ||
| struct _TestDeprecatedClass
 | ||
| {
 | ||
|   GObjectClass parent_class;
 | ||
| };
 | ||
| 
 | ||
| G_DEFINE_TYPE_EXTENDED (TestDeprecated, test_deprecated, G_TYPE_OBJECT, G_TYPE_FLAG_FINAL | G_TYPE_FLAG_DEPRECATED, {})
 | ||
| 
 | ||
| static void
 | ||
| test_deprecated_class_init (TestDeprecatedClass *klass)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| test_deprecated_init (TestDeprecated *self)
 | ||
| {
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| test_type_flags_final_instance_check (void)
 | ||
| {
 | ||
|   TestFinal *final;
 | ||
| 
 | ||
|   final = g_object_new (TEST_TYPE_FINAL, NULL);
 | ||
|   g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
 | ||
|                                               TEST_TYPE_FINAL));
 | ||
|   g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
 | ||
|                                               TEST_TYPE_DEPRECATED));
 | ||
|   g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
 | ||
|                                               G_TYPE_OBJECT));
 | ||
|   g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
 | ||
|                                               G_TYPE_INVALID));
 | ||
| 
 | ||
|   g_clear_object (&final);
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| test_type_flags_deprecated (void)
 | ||
| {
 | ||
|   GType deprecated_type;
 | ||
|   GObject *deprecated_object = NULL;
 | ||
| 
 | ||
|   g_test_summary ("Test that trying to instantiate a deprecated type results in a warning.");
 | ||
| 
 | ||
|   /* This is the message we print out when registering the type */
 | ||
|   g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING,
 | ||
|                          "*The type TestDeprecated is deprecated and shouldn’t be used any more*");
 | ||
| 
 | ||
|   /* The type itself should not be considered invalid. */
 | ||
|   deprecated_type = TEST_TYPE_DEPRECATED;
 | ||
|   g_assert_false (deprecated_type == G_TYPE_INVALID);
 | ||
|   g_assert_true (G_TYPE_IS_DEPRECATED (deprecated_type));
 | ||
| 
 | ||
|   g_assert_true (G_TYPE_IS_FINAL (deprecated_type));
 | ||
|   g_assert_true (g_type_test_flags (deprecated_type, G_TYPE_FLAG_FINAL));
 | ||
| 
 | ||
|   g_assert_true (g_type_test_flags (deprecated_type,
 | ||
|                                     G_TYPE_FLAG_DEPRECATED |
 | ||
|                                     G_TYPE_FLAG_CLASSED |
 | ||
|                                     G_TYPE_FLAG_FINAL |
 | ||
|                                     G_TYPE_FLAG_INSTANTIATABLE));
 | ||
|   g_assert_false (g_type_test_flags (deprecated_type,
 | ||
|                                      G_TYPE_FLAG_DEPRECATED |
 | ||
|                                      G_TYPE_FLAG_CLASSED |
 | ||
|                                      G_TYPE_FLAG_FINAL |
 | ||
|                                      G_TYPE_FLAG_ABSTRACT |
 | ||
|                                      G_TYPE_FLAG_INSTANTIATABLE));
 | ||
| 
 | ||
|   /* Instantiating it should work, but emit a warning. */
 | ||
|   deprecated_object = g_object_new (deprecated_type, NULL);
 | ||
|   g_assert_nonnull (deprecated_object);
 | ||
| 
 | ||
|   g_test_assert_expected_messages ();
 | ||
| 
 | ||
|   g_object_unref (deprecated_object);
 | ||
| 
 | ||
|   /* Instantiating it again should not emit a second warning. */
 | ||
|   deprecated_object = g_object_new (deprecated_type, NULL);
 | ||
|   g_assert_nonnull (deprecated_object);
 | ||
| 
 | ||
|   g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
 | ||
|                                               TEST_TYPE_DEPRECATED));
 | ||
|   g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
 | ||
|                                               G_TYPE_OBJECT));
 | ||
|   g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
 | ||
|                                               TEST_TYPE_FINAL));
 | ||
|   g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
 | ||
|                                               G_TYPE_INVALID));
 | ||
| 
 | ||
|   g_test_assert_expected_messages ();
 | ||
| 
 | ||
|   g_object_unref (deprecated_object);
 | ||
| }
 | ||
| 
 | ||
| int
 | ||
| main (int argc, char *argv[])
 | ||
| {
 | ||
|   g_test_init (&argc, &argv, NULL);
 | ||
| 
 | ||
|   g_setenv ("G_ENABLE_DIAGNOSTIC", "1", TRUE);
 | ||
| 
 | ||
|   g_test_add_func ("/type/flags/interface", test_type_flags_interface);
 | ||
|   g_test_add_func ("/type/flags/final", test_type_flags_final);
 | ||
|   g_test_add_func ("/type/flags/final/instance-check", test_type_flags_final_instance_check);
 | ||
|   g_test_add_func ("/type/flags/deprecated", test_type_flags_deprecated);
 | ||
| 
 | ||
|   return g_test_run ();
 | ||
| }
 |