(root)/
glib-2.79.0/
gobject/
tests/
type-flags.c
       1  // SPDX-License-Identifier: LGPL-2.1-or-later
       2  // SPDX-FileCopyrightText: 2021  Emmanuele Bassi
       3  
       4  #include <glib-object.h>
       5  
       6  typedef struct
       7  {
       8    GTypeInterface g_iface;
       9  } TestInterfaceInterface;
      10  
      11  GType test_interface_get_type (void);
      12  #define TEST_TYPE_INTERFACE test_interface_get_type ()
      13  G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_INVALID)
      14  
      15  static void
      16  test_interface_default_init (TestInterfaceInterface *iface)
      17  {
      18  }
      19  
      20  static void
      21  test_type_flags_interface (void)
      22  {
      23    g_assert_false (G_TYPE_IS_ABSTRACT (TEST_TYPE_INTERFACE));
      24    g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_ABSTRACT));
      25  
      26    g_assert_false (G_TYPE_IS_CLASSED (TEST_TYPE_INTERFACE));
      27    g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_CLASSED));
      28  
      29    g_assert_false (G_TYPE_IS_DEEP_DERIVABLE (TEST_TYPE_INTERFACE));
      30    g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DEEP_DERIVABLE));
      31  
      32    g_assert_true (G_TYPE_IS_DERIVABLE (TEST_TYPE_INTERFACE));
      33    g_assert_true (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DERIVABLE));
      34  
      35    g_assert_false (G_TYPE_IS_FINAL (TEST_TYPE_INTERFACE));
      36    g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_FINAL));
      37  
      38    g_assert_false (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_INTERFACE));
      39    g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_INSTANTIATABLE));
      40  }
      41  
      42  #define TEST_TYPE_FINAL (test_final_get_type())
      43  G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject)
      44  
      45  struct _TestFinal
      46  {
      47    GObject parent_instance;
      48  };
      49  
      50  struct _TestFinalClass
      51  {
      52    GObjectClass parent_class;
      53  };
      54  
      55  G_DEFINE_FINAL_TYPE (TestFinal, test_final, G_TYPE_OBJECT)
      56  
      57  static void
      58  test_final_class_init (TestFinalClass *klass)
      59  {
      60  }
      61  
      62  static void
      63  test_final_init (TestFinal *self)
      64  {
      65  }
      66  
      67  #define TEST_TYPE_FINAL2 (test_final2_get_type())
      68  G_DECLARE_FINAL_TYPE (TestFinal2, test_final2, TEST, FINAL2, TestFinal)
      69  
      70  struct _TestFinal2
      71  {
      72    TestFinal parent_instance;
      73  };
      74  
      75  struct _TestFinal2Class
      76  {
      77    TestFinalClass parent_class;
      78  };
      79  
      80  G_DEFINE_TYPE (TestFinal2, test_final2, TEST_TYPE_FINAL)
      81  
      82  static void
      83  test_final2_class_init (TestFinal2Class *klass)
      84  {
      85  }
      86  
      87  static void
      88  test_final2_init (TestFinal2 *self)
      89  {
      90  }
      91  
      92  /* test_type_flags_final: Check that trying to derive from a final class
      93   * will result in a warning from the type system
      94   */
      95  static void
      96  test_type_flags_final (void)
      97  {
      98    GType final2_type;
      99  
     100    g_assert_true (G_TYPE_IS_FINAL (TEST_TYPE_FINAL));
     101    g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_FINAL));
     102    g_assert_true (G_TYPE_IS_CLASSED (TEST_TYPE_FINAL));
     103    g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_CLASSED));
     104    g_assert_true (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_FINAL));
     105    g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_INSTANTIATABLE));
     106    g_assert_true (g_type_test_flags (TEST_TYPE_FINAL,
     107                                      G_TYPE_FLAG_FINAL |
     108                                      G_TYPE_FLAG_CLASSED |
     109                                      G_TYPE_FLAG_INSTANTIATABLE));
     110    g_assert_false (g_type_test_flags (TEST_TYPE_FINAL,
     111                                       G_TYPE_FLAG_FINAL |
     112                                       G_TYPE_FLAG_CLASSED |
     113                                       G_TYPE_FLAG_DEPRECATED |
     114                                       G_TYPE_FLAG_INSTANTIATABLE));
     115  
     116    /* This is the message we print out when registering the type */
     117    g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
     118                           "*cannot derive*");
     119  
     120    /* This is the message when we fail to return from the GOnce init
     121     * block within the test_final2_get_type() function
     122     */
     123    g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
     124                           "*g_once_init_leave_pointer: assertion*");
     125  
     126    final2_type = TEST_TYPE_FINAL2;
     127    g_assert_true (final2_type == G_TYPE_INVALID);
     128  
     129    g_test_assert_expected_messages ();
     130  }
     131  
     132  #define TEST_TYPE_DEPRECATED (test_deprecated_get_type())
     133  G_DECLARE_FINAL_TYPE (TestDeprecated, test_deprecated, TEST, DEPRECATED, GObject)
     134  
     135  struct _TestDeprecated
     136  {
     137    GObject parent_instance;
     138  };
     139  
     140  struct _TestDeprecatedClass
     141  {
     142    GObjectClass parent_class;
     143  };
     144  
     145  G_DEFINE_TYPE_EXTENDED (TestDeprecated, test_deprecated, G_TYPE_OBJECT, G_TYPE_FLAG_FINAL | G_TYPE_FLAG_DEPRECATED, {})
     146  
     147  static void
     148  test_deprecated_class_init (TestDeprecatedClass *klass)
     149  {
     150  }
     151  
     152  static void
     153  test_deprecated_init (TestDeprecated *self)
     154  {
     155  }
     156  
     157  static void
     158  test_type_flags_final_instance_check (void)
     159  {
     160    TestFinal *final;
     161  
     162    final = g_object_new (TEST_TYPE_FINAL, NULL);
     163    g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
     164                                                TEST_TYPE_FINAL));
     165    g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
     166                                                TEST_TYPE_DEPRECATED));
     167    g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
     168                                                G_TYPE_OBJECT));
     169    g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
     170                                                G_TYPE_INVALID));
     171  
     172    g_clear_object (&final);
     173  }
     174  
     175  static void
     176  test_type_flags_deprecated (void)
     177  {
     178    GType deprecated_type;
     179    GObject *deprecated_object = NULL;
     180  
     181    g_test_summary ("Test that trying to instantiate a deprecated type results in a warning.");
     182  
     183    /* This is the message we print out when registering the type */
     184    g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING,
     185                           "*The type TestDeprecated is deprecated and shouldn’t be used any more*");
     186  
     187    /* The type itself should not be considered invalid. */
     188    deprecated_type = TEST_TYPE_DEPRECATED;
     189    g_assert_false (deprecated_type == G_TYPE_INVALID);
     190    g_assert_true (G_TYPE_IS_DEPRECATED (deprecated_type));
     191  
     192    g_assert_true (G_TYPE_IS_FINAL (deprecated_type));
     193    g_assert_true (g_type_test_flags (deprecated_type, G_TYPE_FLAG_FINAL));
     194  
     195    g_assert_true (g_type_test_flags (deprecated_type,
     196                                      G_TYPE_FLAG_DEPRECATED |
     197                                      G_TYPE_FLAG_CLASSED |
     198                                      G_TYPE_FLAG_FINAL |
     199                                      G_TYPE_FLAG_INSTANTIATABLE));
     200    g_assert_false (g_type_test_flags (deprecated_type,
     201                                       G_TYPE_FLAG_DEPRECATED |
     202                                       G_TYPE_FLAG_CLASSED |
     203                                       G_TYPE_FLAG_FINAL |
     204                                       G_TYPE_FLAG_ABSTRACT |
     205                                       G_TYPE_FLAG_INSTANTIATABLE));
     206  
     207    /* Instantiating it should work, but emit a warning. */
     208    deprecated_object = g_object_new (deprecated_type, NULL);
     209    g_assert_nonnull (deprecated_object);
     210  
     211    g_test_assert_expected_messages ();
     212  
     213    g_object_unref (deprecated_object);
     214  
     215    /* Instantiating it again should not emit a second warning. */
     216    deprecated_object = g_object_new (deprecated_type, NULL);
     217    g_assert_nonnull (deprecated_object);
     218  
     219    g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
     220                                                TEST_TYPE_DEPRECATED));
     221    g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
     222                                                G_TYPE_OBJECT));
     223    g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
     224                                                TEST_TYPE_FINAL));
     225    g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
     226                                                G_TYPE_INVALID));
     227  
     228    g_test_assert_expected_messages ();
     229  
     230    g_object_unref (deprecated_object);
     231  }
     232  
     233  int
     234  main (int argc, char *argv[])
     235  {
     236    g_test_init (&argc, &argv, NULL);
     237  
     238    g_setenv ("G_ENABLE_DIAGNOSTIC", "1", TRUE);
     239  
     240    g_test_add_func ("/type/flags/interface", test_type_flags_interface);
     241    g_test_add_func ("/type/flags/final", test_type_flags_final);
     242    g_test_add_func ("/type/flags/final/instance-check", test_type_flags_final_instance_check);
     243    g_test_add_func ("/type/flags/deprecated", test_type_flags_deprecated);
     244  
     245    return g_test_run ();
     246  }