LCOV - code coverage report
Current view: top level - glib/gobject/tests - properties-introspection.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 45 45 100.0 %
Date: 2024-04-30 05:17:35 Functions: 6 6 100.0 %
Branches: 15 18 83.3 %

           Branch data     Line data    Source code
       1                 :            : /* properties-introspection.c: Test the properties introspection API
       2                 :            :  *
       3                 :            :  * SPDX-FileCopyrightText: 2023 Emmanuele Bassi
       4                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       5                 :            :  */
       6                 :            : 
       7                 :            : /* This test is isolated so we can control the initialization of
       8                 :            :  * GObjectClass, and the global GParamSpecPool
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <stdlib.h>
      12                 :            : #include <glib-object.h>
      13                 :            : 
      14                 :            : G_DECLARE_INTERFACE (MyTestable, my_testable, MY, TESTABLE, GObject)
      15                 :            : 
      16                 :            : struct _MyTestableInterface
      17                 :            : {
      18                 :            :   GTypeInterface g_iface;
      19                 :            : };
      20                 :            : 
      21   [ +  +  +  -  :         11 : G_DEFINE_INTERFACE (MyTestable, my_testable, G_TYPE_OBJECT)
                   +  + ]
      22                 :            : 
      23                 :            : static void
      24                 :          2 : my_testable_default_init (MyTestableInterface *iface)
      25                 :            : {
      26                 :          2 :   g_object_interface_install_property (iface,
      27                 :            :     g_param_spec_int ("check", NULL, NULL, -1, 10, 0, G_PARAM_READWRITE));
      28                 :          2 : }
      29                 :            : 
      30                 :            : static void
      31                 :          2 : properties_introspection (void)
      32                 :            : {
      33                 :          2 :   g_test_summary ("Verify that introspecting properties on an interface initializes the GParamSpecPool.");
      34                 :            : 
      35         [ +  + ]:          2 :   if (g_test_subprocess ())
      36                 :            :     {
      37                 :          1 :       gpointer klass = g_type_default_interface_ref (my_testable_get_type ());
      38                 :          1 :       g_assert_nonnull (klass);
      39                 :            : 
      40                 :          1 :       GParamSpec *pspec = g_object_interface_find_property (klass, "check");
      41                 :          1 :       g_assert_nonnull (pspec);
      42                 :            : 
      43                 :          1 :       g_type_default_interface_unref (klass);
      44                 :          1 :       return;
      45                 :            :     }
      46                 :            : 
      47                 :          1 :   g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
      48                 :          1 :   g_test_trap_assert_passed ();
      49                 :          1 :   g_test_trap_assert_stderr ("");
      50                 :            : }
      51                 :            : 
      52                 :            : static gpointer
      53                 :         10 : inspect_func (gpointer data)
      54                 :            : {
      55                 :         10 :   unsigned int *n_checks = data; /* (atomic) */
      56                 :            : 
      57                 :         10 :   gpointer klass = NULL;
      58                 :            :   do
      59                 :            :     {
      60                 :         10 :       klass = g_type_default_interface_ref (my_testable_get_type ());
      61                 :            :     }
      62         [ -  + ]:         10 :   while (klass == NULL);
      63                 :            : 
      64                 :         10 :   GParamSpec *pspec = NULL;
      65                 :            :   do
      66                 :            :     {
      67                 :         10 :       pspec = g_object_interface_find_property (klass, "check");
      68                 :            :     }
      69         [ -  + ]:         10 :   while (pspec == NULL);
      70                 :            : 
      71                 :         10 :   g_type_default_interface_unref (klass);
      72                 :            : 
      73                 :         10 :   g_atomic_int_inc (n_checks);
      74                 :            : 
      75                 :         10 :   return NULL;
      76                 :            : }
      77                 :            : 
      78                 :            : #define N_THREADS 10
      79                 :            : 
      80                 :            : static void
      81                 :          1 : properties_collision (void)
      82                 :            : {
      83                 :            :   GThread *threads[N_THREADS];
      84                 :          1 :   unsigned int n_checks = 0; /* (atomic) */
      85                 :            : 
      86                 :          1 :   g_test_summary ("Verify that multiple threads create a single GParamSpecPool.");
      87                 :            : 
      88         [ +  + ]:         11 :   for (unsigned int i = 0; i < N_THREADS; i++)
      89                 :            :     {
      90                 :         10 :       char *t_name = g_strdup_printf ("inspect [%d]", i);
      91                 :         10 :       threads[i] = g_thread_new (t_name, inspect_func, &n_checks);
      92                 :         10 :       g_assert_nonnull (threads[i]);
      93                 :         10 :       g_free (t_name);
      94                 :            :     }
      95                 :            : 
      96         [ +  + ]:        114 :   while (g_atomic_int_get (&n_checks) != N_THREADS)
      97                 :        113 :     g_usleep (50);
      98                 :            : 
      99         [ +  + ]:         11 :   for (unsigned int i = 0; i < N_THREADS; i++)
     100                 :         10 :     g_thread_join (threads[i]);
     101                 :          1 : }
     102                 :            : 
     103                 :            : #undef N_THREADS
     104                 :            : 
     105                 :            : int
     106                 :          2 : main (int argc, char *argv[])
     107                 :            : {
     108                 :          2 :   g_test_init (&argc, &argv, NULL);
     109                 :            : 
     110                 :          2 :   g_test_add_func ("/properties/introspection", properties_introspection);
     111                 :          2 :   g_test_add_func ("/properties/collision", properties_collision);
     112                 :            : 
     113                 :          2 :   return g_test_run ();
     114                 :            : }

Generated by: LCOV version 1.14