(root)/
glib-2.79.0/
gobject/
tests/
defaultiface.c
       1  /* GObject - GLib Type, Object, Parameter and Signal Library
       2   * Copyright (C) 2001, 2003 Red Hat, Inc.
       3   *
       4   * SPDX-License-Identifier: LGPL-2.1-or-later
       5   *
       6   * This library is free software; you can redistribute it and/or
       7   * modify it under the terms of the GNU Lesser General Public
       8   * License as published by the Free Software Foundation; either
       9   * version 2.1 of the License, or (at your option) any later version.
      10   *
      11   * This library is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14   * Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General
      17   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18   */
      19  
      20  #include <glib-object.h>
      21  
      22  #include "testcommon.h"
      23  #include "testmodule.h"
      24  
      25  /* This test tests getting the default vtable for an interface
      26   * and the initialization and finalization of such default
      27   * interfaces.
      28   *
      29   * We test this both for static and for dynamic interfaces.
      30   */
      31  
      32  /**********************************************************************
      33   * Static interface tests
      34   **********************************************************************/
      35  
      36  typedef struct _TestStaticIfaceClass TestStaticIfaceClass;
      37  
      38  struct _TestStaticIfaceClass
      39  {
      40    GTypeInterface base_iface;
      41    guint val;
      42  };
      43  
      44  GType test_static_iface_get_type (void);
      45  #define TEST_TYPE_STATIC_IFACE (test_static_iface_get_type ())
      46  
      47  static void
      48  test_static_iface_default_init (TestStaticIfaceClass *iface)
      49  {
      50    iface->val = 42;
      51  }
      52  
      53  DEFINE_IFACE (TestStaticIface, test_static_iface,
      54                NULL, test_static_iface_default_init)
      55  
      56  static void
      57  test_static_iface (void)
      58  {
      59    TestStaticIfaceClass *static_iface;
      60  
      61    /* Not loaded until we call ref for the first time */
      62    static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
      63    g_assert_null (static_iface);
      64  
      65    /* Ref loads */
      66    static_iface = g_type_default_interface_ref (TEST_TYPE_STATIC_IFACE);
      67    g_assert_nonnull (static_iface);
      68    g_assert_cmpint (static_iface->val, ==, 42);
      69  
      70    /* Peek then works */
      71    static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
      72    g_assert_nonnull (static_iface);
      73    g_assert_cmpint (static_iface->val, ==, 42);
      74  
      75    /* Unref does nothing */
      76    g_type_default_interface_unref (static_iface);
      77  
      78    /* And peek still works */
      79    static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
      80    g_assert_nonnull (static_iface);
      81    g_assert_cmpint (static_iface->val, ==, 42);
      82  }
      83  
      84  /**********************************************************************
      85   * Dynamic interface tests
      86   **********************************************************************/
      87  
      88  typedef struct _TestDynamicIfaceClass TestDynamicIfaceClass;
      89  
      90  struct _TestDynamicIfaceClass
      91  {
      92    GTypeInterface base_iface;
      93    guint val;
      94  };
      95  
      96  static GType test_dynamic_iface_type;
      97  static gboolean dynamic_iface_init = FALSE;
      98  
      99  #define TEST_TYPE_DYNAMIC_IFACE (test_dynamic_iface_type)
     100  
     101  static void
     102  test_dynamic_iface_default_init (TestStaticIfaceClass *iface)
     103  {
     104    dynamic_iface_init = TRUE;
     105    iface->val = 42;
     106  }
     107  
     108  static void
     109  test_dynamic_iface_default_finalize (TestStaticIfaceClass *iface)
     110  {
     111    dynamic_iface_init = FALSE;
     112  }
     113  
     114  static void
     115  test_dynamic_iface_register (GTypeModule *module)
     116  {
     117    const GTypeInfo iface_info =
     118      {
     119        sizeof (TestDynamicIfaceClass),
     120        (GBaseInitFunc)      NULL,
     121        (GBaseFinalizeFunc)  NULL,
     122        (GClassInitFunc)     test_dynamic_iface_default_init,
     123        (GClassFinalizeFunc) test_dynamic_iface_default_finalize,
     124        NULL,
     125        0,
     126        0,
     127        NULL,
     128        NULL
     129      };
     130  
     131    test_dynamic_iface_type =
     132      g_type_module_register_type (module, G_TYPE_INTERFACE,
     133                                   "TestDynamicIface", &iface_info, 0);
     134  }
     135  
     136  static void
     137  module_register (GTypeModule *module)
     138  {
     139    test_dynamic_iface_register (module);
     140  }
     141  
     142  static void
     143  test_dynamic_iface (void)
     144  {
     145    TestDynamicIfaceClass *dynamic_iface;
     146  
     147    test_module_new (module_register);
     148  
     149    /* Not loaded until we call ref for the first time */
     150    dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
     151    g_assert_null (dynamic_iface);
     152  
     153    /* Ref loads */
     154    dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE);
     155    g_assert_true (dynamic_iface_init);
     156    g_assert_nonnull (dynamic_iface);
     157    g_assert_cmpint (dynamic_iface->val, ==, 42);
     158  
     159    /* Peek then works */
     160    dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
     161    g_assert_nonnull (dynamic_iface);
     162    g_assert_cmpint (dynamic_iface->val, ==, 42);
     163  
     164    /* Unref causes finalize */
     165    g_type_default_interface_unref (dynamic_iface);
     166  #if 0
     167    /* Disabled as unloading dynamic types is disabled.
     168     * See https://gitlab.gnome.org/GNOME/glib/-/issues/667 */
     169    g_assert_false (dynamic_iface_init);
     170  #endif
     171  
     172    /* Peek returns NULL */
     173    dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
     174  #if 0
     175    /* Disabled as unloading dynamic types is disabled.
     176     * See https://gitlab.gnome.org/GNOME/glib/-/issues/667 */
     177    g_assert_null (dynamic_iface);
     178  #endif
     179  
     180    /* Ref reloads */
     181    dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE);
     182    g_assert_true (dynamic_iface_init);
     183    g_assert_nonnull (dynamic_iface);
     184    g_assert_cmpint (dynamic_iface->val, ==, 42);
     185  
     186    /* And Unref causes finalize once more*/
     187    g_type_default_interface_unref (dynamic_iface);
     188  #if 0
     189    /* Disabled as unloading dynamic types is disabled.
     190     * See https://gitlab.gnome.org/GNOME/glib/-/issues/667 */
     191    g_assert_false (dynamic_iface_init);
     192  #endif
     193  }
     194  
     195  int
     196  main (int   argc,
     197        char *argv[])
     198  {
     199    g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
     200                            G_LOG_LEVEL_WARNING |
     201                            G_LOG_LEVEL_CRITICAL);
     202  
     203    g_test_init (&argc, &argv, NULL);
     204  
     205    g_test_add_func ("/gobject/static-iface", test_static_iface);
     206    g_test_add_func ("/gobject/dynamic-iface", test_dynamic_iface);
     207  
     208    return g_test_run ();
     209  }