LCOV - code coverage report
Current view: top level - gobject/tests - param.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 85.2 % 827 705
Test Date: 2024-11-26 05:23:01 Functions: 58.1 % 62 36
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GLIB - Library of useful routines for C programming
       2                 :             :  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       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 Public
      17                 :             :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18                 :             :  */
      19                 :             : 
      20                 :             : /*
      21                 :             :  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      22                 :             :  * file for a list of people on the GLib Team.  See the ChangeLog
      23                 :             :  * files for a list of changes.  These files are distributed with
      24                 :             :  * GLib at ftp://ftp.gtk.org/pub/gtk/.
      25                 :             :  */
      26                 :             : 
      27                 :             : #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
      28                 :             : #define GLIB_DISABLE_DEPRECATION_WARNINGS
      29                 :             : #endif
      30                 :             : 
      31                 :             : #include <glib-object.h>
      32                 :             : #include <stdlib.h>
      33                 :             : 
      34                 :             : static void
      35                 :           1 : test_param_spec_char (void)
      36                 :             : {
      37                 :             :   GParamSpec *pspec;
      38                 :           1 :   GValue value = G_VALUE_INIT;
      39                 :             : 
      40                 :           1 :   pspec = g_param_spec_char ("char", "nick", "blurb",
      41                 :             :                              20, 40, 30, G_PARAM_READWRITE);
      42                 :             : 
      43                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char");
      44                 :           1 :   g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick");
      45                 :           1 :   g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb");
      46                 :             : 
      47                 :           1 :   g_value_init (&value, G_TYPE_CHAR);
      48                 :           1 :   g_value_set_char (&value, 30);
      49                 :             : 
      50                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
      51                 :             : 
      52                 :           1 :   g_value_set_char (&value, 0);
      53                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
      54                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
      55                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 20);
      56                 :             : 
      57                 :           1 :   g_value_set_char (&value, 20);
      58                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
      59                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
      60                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 20);
      61                 :             : 
      62                 :           1 :   g_value_set_char (&value, 40);
      63                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
      64                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
      65                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 40);
      66                 :             : 
      67                 :           1 :   g_value_set_char (&value, 60);
      68                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
      69                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
      70                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 40);
      71                 :             : 
      72                 :           1 :   g_value_set_schar (&value, 0);
      73                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
      74                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
      75                 :           1 :   g_assert_cmpint (g_value_get_schar (&value), ==, 20);
      76                 :             : 
      77                 :           1 :   g_value_set_schar (&value, 20);
      78                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
      79                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
      80                 :           1 :   g_assert_cmpint (g_value_get_schar (&value), ==, 20);
      81                 :             : 
      82                 :           1 :   g_value_set_schar (&value, 40);
      83                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
      84                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
      85                 :           1 :   g_assert_cmpint (g_value_get_schar (&value), ==, 40);
      86                 :             : 
      87                 :           1 :   g_value_set_schar (&value, 60);
      88                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
      89                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
      90                 :           1 :   g_assert_cmpint (g_value_get_schar (&value), ==, 40);
      91                 :             : 
      92                 :           1 :   g_param_spec_unref (pspec);
      93                 :           1 : }
      94                 :             : 
      95                 :             : static void
      96                 :           1 : test_param_spec_uchar (void)
      97                 :             : {
      98                 :             :   GParamSpec *pspec;
      99                 :           1 :   GValue value = G_VALUE_INIT;
     100                 :             : 
     101                 :           1 :   pspec = g_param_spec_uchar ("char", NULL, NULL,
     102                 :             :                              20, 40, 30, G_PARAM_READWRITE);
     103                 :             : 
     104                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char");
     105                 :             : 
     106                 :           1 :   g_value_init (&value, G_TYPE_UCHAR);
     107                 :             : 
     108                 :           1 :   g_value_set_uchar (&value, 0);
     109                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     110                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     111                 :           1 :   g_assert_cmpint (g_value_get_uchar (&value), ==, 20);
     112                 :             : 
     113                 :           1 :   g_value_set_uchar (&value, 20);
     114                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     115                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     116                 :           1 :   g_assert_cmpint (g_value_get_uchar (&value), ==, 20);
     117                 :             : 
     118                 :           1 :   g_param_spec_unref (pspec);
     119                 :           1 : }
     120                 :             : 
     121                 :             : static void
     122                 :           1 : test_param_spec_int (void)
     123                 :             : {
     124                 :             :   GParamSpec *pspec;
     125                 :           1 :   GValue value = G_VALUE_INIT;
     126                 :             : 
     127                 :           1 :   pspec = g_param_spec_int ("int", NULL, NULL,
     128                 :             :                             20, 40, 30, G_PARAM_READWRITE);
     129                 :             : 
     130                 :           1 :   g_param_value_set_default (pspec, &value);
     131                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_INT);
     132                 :           1 :   g_assert_cmpint (g_value_get_int (&value), ==, 30);
     133                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     134                 :             : 
     135                 :           1 :   g_value_set_int (&value, 0);
     136                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     137                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     138                 :           1 :   g_assert_cmpint (g_value_get_int (&value), ==, 20);
     139                 :             : 
     140                 :           1 :   g_param_spec_unref (pspec);
     141                 :           1 : }
     142                 :             : 
     143                 :             : static void
     144                 :           1 : test_param_spec_uint (void)
     145                 :             : {
     146                 :             :   GParamSpec *pspec;
     147                 :           1 :   GValue value = G_VALUE_INIT;
     148                 :             : 
     149                 :           1 :   pspec = g_param_spec_uint ("uint", NULL, NULL,
     150                 :             :                              20, 40, 30, G_PARAM_READWRITE);
     151                 :             : 
     152                 :           1 :   g_param_value_set_default (pspec, &value);
     153                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_UINT);
     154                 :           1 :   g_assert_cmpint (g_value_get_uint (&value), ==, 30);
     155                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     156                 :             : 
     157                 :           1 :   g_value_set_uint (&value, 0);
     158                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     159                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     160                 :           1 :   g_assert_cmpint (g_value_get_uint (&value), ==, 20);
     161                 :             : 
     162                 :           1 :   g_param_spec_unref (pspec);
     163                 :           1 : }
     164                 :             : 
     165                 :             : static void
     166                 :           1 : test_param_spec_long (void)
     167                 :             : {
     168                 :             :   GParamSpec *pspec;
     169                 :           1 :   GValue value = G_VALUE_INIT;
     170                 :             : 
     171                 :           1 :   pspec = g_param_spec_long ("long", NULL, NULL,
     172                 :             :                              20, 40, 30, G_PARAM_READWRITE);
     173                 :             : 
     174                 :           1 :   g_param_value_set_default (pspec, &value);
     175                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_LONG);
     176                 :           1 :   g_assert_cmpint (g_value_get_long (&value), ==, 30);
     177                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     178                 :             : 
     179                 :           1 :   g_value_set_long (&value, 0);
     180                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     181                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     182                 :           1 :   g_assert_cmpint (g_value_get_long (&value), ==, 20);
     183                 :             : 
     184                 :           1 :   g_param_spec_unref (pspec);
     185                 :           1 : }
     186                 :             : 
     187                 :             : static void
     188                 :           1 : test_param_spec_ulong (void)
     189                 :             : {
     190                 :             :   GParamSpec *pspec;
     191                 :           1 :   GValue value = G_VALUE_INIT;
     192                 :             : 
     193                 :           1 :   pspec = g_param_spec_ulong ("ulong", NULL, NULL,
     194                 :             :                               20, 40, 30, G_PARAM_READWRITE);
     195                 :             : 
     196                 :           1 :   g_param_value_set_default (pspec, &value);
     197                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_ULONG);
     198                 :           1 :   g_assert_cmpint (g_value_get_ulong (&value), ==, 30);
     199                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     200                 :             : 
     201                 :           1 :   g_value_set_ulong (&value, 0);
     202                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     203                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     204                 :           1 :   g_assert_cmpint (g_value_get_ulong (&value), ==, 20);
     205                 :             : 
     206                 :           1 :   g_param_spec_unref (pspec);
     207                 :           1 : }
     208                 :             : 
     209                 :             : static void
     210                 :           1 : test_param_spec_int64 (void)
     211                 :             : {
     212                 :             :   GParamSpec *pspec;
     213                 :           1 :   GValue value = G_VALUE_INIT;
     214                 :             : 
     215                 :           1 :   pspec = g_param_spec_int64 ("int64", NULL, NULL,
     216                 :             :                               20, 40, 30, G_PARAM_READWRITE);
     217                 :             : 
     218                 :           1 :   g_param_value_set_default (pspec, &value);
     219                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_INT64);
     220                 :           1 :   g_assert_cmpint (g_value_get_int64 (&value), ==, 30);
     221                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     222                 :             : 
     223                 :           1 :   g_value_set_int64 (&value, 0);
     224                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     225                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     226                 :           1 :   g_assert_cmpint (g_value_get_int64 (&value), ==, 20);
     227                 :             : 
     228                 :           1 :   g_param_spec_unref (pspec);
     229                 :           1 : }
     230                 :             : 
     231                 :             : static void
     232                 :           1 : test_param_spec_uint64 (void)
     233                 :             : {
     234                 :             :   GParamSpec *pspec;
     235                 :           1 :   GValue value = G_VALUE_INIT;
     236                 :             : 
     237                 :           1 :   pspec = g_param_spec_uint64 ("uint64", NULL, NULL,
     238                 :             :                                20, 40, 30, G_PARAM_READWRITE);
     239                 :             : 
     240                 :           1 :   g_param_value_set_default (pspec, &value);
     241                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_UINT64);
     242                 :           1 :   g_assert_cmpint (g_value_get_uint64 (&value), ==, 30);
     243                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     244                 :             : 
     245                 :           1 :   g_value_set_uint64 (&value, 0);
     246                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     247                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     248                 :           1 :   g_assert_cmpint (g_value_get_uint64 (&value), ==, 20);
     249                 :             : 
     250                 :           1 :   g_param_spec_unref (pspec);
     251                 :           1 : }
     252                 :             : 
     253                 :             : static void
     254                 :           1 : test_param_spec_float (void)
     255                 :             : {
     256                 :             :   GParamSpec *pspec;
     257                 :           1 :   GValue value = G_VALUE_INIT;
     258                 :             : 
     259                 :           1 :   pspec = g_param_spec_float ("float", NULL, NULL,
     260                 :             :                               20.0, 40.0, 30.0, G_PARAM_READWRITE);
     261                 :             : 
     262                 :           1 :   g_param_value_set_default (pspec, &value);
     263                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_FLOAT);
     264                 :           1 :   g_assert_cmpfloat (g_value_get_float (&value), ==, 30.0);
     265                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     266                 :             : 
     267                 :           1 :   g_value_set_float (&value, 0.0);
     268                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     269                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     270                 :           1 :   g_assert_cmpfloat (g_value_get_float (&value), ==, 20.0);
     271                 :             : 
     272                 :           1 :   g_param_spec_unref (pspec);
     273                 :           1 : }
     274                 :             : 
     275                 :             : static void
     276                 :           1 : test_param_spec_double (void)
     277                 :             : {
     278                 :             :   GParamSpec *pspec;
     279                 :           1 :   GValue value = G_VALUE_INIT;
     280                 :             : 
     281                 :           1 :   pspec = g_param_spec_double ("double", NULL, NULL,
     282                 :             :                                20.0, 40.0, 30.0, G_PARAM_READWRITE);
     283                 :             : 
     284                 :           1 :   g_param_value_set_default (pspec, &value);
     285                 :           1 :   g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_DOUBLE);
     286                 :           1 :   g_assert_cmpfloat (g_value_get_double (&value), ==, 30.0);
     287                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     288                 :             : 
     289                 :           1 :   g_value_set_double (&value, 0.0);
     290                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     291                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     292                 :           1 :   g_assert_cmpfloat (g_value_get_double (&value), ==, 20.0);
     293                 :             : 
     294                 :           1 :   g_param_spec_unref (pspec);
     295                 :             : 
     296                 :             :   /* Test validation with some larger values, which fit in a double but not in a float.
     297                 :             :    * In particular, check there are no double → float conversions in the pipeline,
     298                 :             :    * by using a valid range which is entirely outside the range of numbers
     299                 :             :    * representable in a float. */
     300                 :           1 :   pspec = g_param_spec_double ("double", NULL, NULL,
     301                 :             :                                1.2e308, 1.3e308, 1.21e308, G_PARAM_READWRITE);
     302                 :             : 
     303                 :           1 :   g_param_value_set_default (pspec, &value);
     304                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     305                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     306                 :           1 :   g_assert_cmpfloat (g_value_get_double (&value), ==, 1.21e308);
     307                 :             : 
     308                 :           1 :   g_param_spec_unref (pspec);
     309                 :           1 : }
     310                 :             : 
     311                 :             : static void
     312                 :           1 : test_param_spec_unichar (void)
     313                 :             : {
     314                 :             :   GParamSpec *pspec;
     315                 :           1 :   GValue value = G_VALUE_INIT;
     316                 :             : 
     317                 :           1 :   pspec = g_param_spec_unichar ("unichar", NULL, NULL,
     318                 :             :                                 0x1F4A9, G_PARAM_READWRITE);
     319                 :             : 
     320                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "unichar");
     321                 :             : 
     322                 :           1 :   g_value_init (&value, G_TYPE_UINT);
     323                 :             : 
     324                 :             :   /* Unicode codepoints can’t be 0x110000 or above, as that’s not representable
     325                 :             :    * in UTF-16. */
     326                 :           1 :   g_value_set_uint (&value, 0x110000);
     327                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     328                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     329                 :           1 :   g_assert_cmpint (g_value_get_uint (&value), ==, 0);
     330                 :             : 
     331                 :           1 :   g_value_set_uint (&value, 0x20);
     332                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     333                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     334                 :           1 :   g_assert_cmpint (g_value_get_uint (&value), ==, 0x20);
     335                 :             : 
     336                 :           1 :   g_param_spec_unref (pspec);
     337                 :           1 : }
     338                 :             : 
     339                 :             : static void
     340                 :           1 : test_param_spec_param (void)
     341                 :             : {
     342                 :             :   GParamSpec *wrapped_pspec_uint;
     343                 :             :   GParamSpec *pspec;
     344                 :           1 :   GValue value = G_VALUE_INIT;
     345                 :             : 
     346                 :           1 :   wrapped_pspec_uint = g_param_spec_uint ("uint", NULL, NULL,
     347                 :             :                                           0, G_MAXUINT, 5, G_PARAM_READWRITE);
     348                 :             : 
     349                 :           1 :   pspec = g_param_spec_param ("param", NULL, NULL,
     350                 :           1 :                               G_TYPE_PARAM_UINT, G_PARAM_READWRITE);
     351                 :             : 
     352                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "param");
     353                 :             : 
     354                 :           1 :   g_value_init (&value, G_TYPE_PARAM_UINT);
     355                 :             : 
     356                 :           1 :   g_value_set_param (&value, wrapped_pspec_uint);
     357                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     358                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     359                 :           1 :   g_assert_true (g_value_get_param (&value) == wrapped_pspec_uint);
     360                 :             : 
     361                 :           1 :   g_value_unset (&value);
     362                 :           1 :   g_param_spec_unref (pspec);
     363                 :           1 :   g_param_spec_unref (wrapped_pspec_uint);
     364                 :           1 : }
     365                 :             : 
     366                 :             : static void
     367                 :           1 : test_param_spec_null_param (void)
     368                 :             : {
     369                 :             :   GParamSpec *pspec;
     370                 :           1 :   GValue value = G_VALUE_INIT;
     371                 :             : 
     372                 :           1 :   pspec = g_param_spec_param ("param", NULL, NULL,
     373                 :           1 :                               G_TYPE_PARAM_POINTER, G_PARAM_READWRITE);
     374                 :             : 
     375                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "param");
     376                 :             : 
     377                 :           1 :   g_value_init (&value, G_TYPE_PARAM_POINTER);
     378                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     379                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     380                 :             : 
     381                 :           1 :   g_value_unset (&value);
     382                 :           1 :   g_param_spec_unref (pspec);
     383                 :           1 : }
     384                 :             : 
     385                 :             : static void
     386                 :           1 : test_param_spec_string (void)
     387                 :             : {
     388                 :             :   GParamSpec *pspec;
     389                 :           1 :   GValue value = G_VALUE_INIT;
     390                 :             : 
     391                 :           1 :   pspec = g_param_spec_string ("string", "nick", "blurb",
     392                 :             :                                NULL, G_PARAM_READWRITE);
     393                 :           1 :   g_value_init (&value, G_TYPE_STRING);
     394                 :             : 
     395                 :           1 :   g_value_set_string (&value, "foobar");
     396                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     397                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     398                 :             : 
     399                 :           1 :   g_value_set_string (&value, "");
     400                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     401                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     402                 :           1 :   g_assert_nonnull (g_value_get_string (&value));
     403                 :             : 
     404                 :             :   /* test ensure_non_null */
     405                 :             : 
     406                 :           1 :   G_PARAM_SPEC_STRING (pspec)->ensure_non_null = TRUE;
     407                 :             : 
     408                 :           1 :   g_value_set_string (&value, NULL);
     409                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     410                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     411                 :           1 :   g_assert_nonnull (g_value_get_string (&value));
     412                 :             : 
     413                 :           1 :   G_PARAM_SPEC_STRING (pspec)->ensure_non_null = FALSE;
     414                 :             : 
     415                 :             :   /* test null_fold_if_empty */
     416                 :             : 
     417                 :           1 :   G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = TRUE;
     418                 :             : 
     419                 :           1 :   g_value_set_string (&value, "");
     420                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     421                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     422                 :           1 :   g_assert_null (g_value_get_string (&value));
     423                 :             : 
     424                 :           1 :   g_value_set_static_string (&value, "");
     425                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     426                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     427                 :           1 :   g_assert_null (g_value_get_string (&value));
     428                 :             : 
     429                 :           1 :   G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = FALSE;
     430                 :             : 
     431                 :             :   /* test cset_first */
     432                 :             : 
     433                 :           1 :   G_PARAM_SPEC_STRING (pspec)->cset_first = g_strdup ("abc");
     434                 :           1 :   G_PARAM_SPEC_STRING (pspec)->substitutor = '-';
     435                 :             : 
     436                 :           1 :   g_value_set_string (&value, "ABC");
     437                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     438                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     439                 :           1 :   g_assert_cmpint (g_value_get_string (&value)[0], ==, '-');
     440                 :             : 
     441                 :           1 :   g_value_set_static_string (&value, "ABC");
     442                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     443                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     444                 :           1 :   g_assert_cmpint (g_value_get_string (&value)[0], ==, '-');
     445                 :             : 
     446                 :             :   /* test cset_nth */
     447                 :             : 
     448                 :           1 :   G_PARAM_SPEC_STRING (pspec)->cset_nth = g_strdup ("abc");
     449                 :             : 
     450                 :           1 :   g_value_set_string (&value, "aBC");
     451                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     452                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     453                 :           1 :   g_assert_cmpint (g_value_get_string (&value)[1], ==, '-');
     454                 :             : 
     455                 :           1 :   g_value_set_static_string (&value, "aBC");
     456                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     457                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     458                 :           1 :   g_assert_cmpint (g_value_get_string (&value)[1], ==, '-');
     459                 :             : 
     460                 :           1 :   g_value_unset (&value);
     461                 :           1 :   g_param_spec_unref (pspec);
     462                 :           1 : }
     463                 :             : 
     464                 :             : static void
     465                 :           1 : test_param_spec_override (void)
     466                 :             : {
     467                 :             :   GParamSpec *ospec, *pspec;
     468                 :           1 :   GValue value = G_VALUE_INIT;
     469                 :             : 
     470                 :           1 :   ospec = g_param_spec_char ("char", "nick", "blurb",
     471                 :             :                              20, 40, 30, G_PARAM_READWRITE);
     472                 :             : 
     473                 :           1 :   pspec = g_param_spec_override ("override", ospec);
     474                 :             : 
     475                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "override");
     476                 :           1 :   g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick");
     477                 :           1 :   g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb");
     478                 :             : 
     479                 :           1 :   g_value_init (&value, G_TYPE_CHAR);
     480                 :           1 :   g_value_set_char (&value, 30);
     481                 :             : 
     482                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     483                 :             : 
     484                 :           1 :   g_value_set_char (&value, 0);
     485                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     486                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     487                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 20);
     488                 :             : 
     489                 :           1 :   g_value_set_char (&value, 20);
     490                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     491                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     492                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 20);
     493                 :             : 
     494                 :           1 :   g_value_set_char (&value, 40);
     495                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     496                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     497                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 40);
     498                 :             : 
     499                 :           1 :   g_value_set_char (&value, 60);
     500                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     501                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     502                 :           1 :   g_assert_cmpint (g_value_get_char (&value), ==, 40);
     503                 :             : 
     504                 :           1 :   g_param_spec_unref (pspec);
     505                 :           1 :   g_param_spec_unref (ospec);
     506                 :           1 : }
     507                 :             : 
     508                 :             : static void
     509                 :           1 : test_param_spec_gtype (void)
     510                 :             : {
     511                 :             :   GParamSpec *pspec;
     512                 :           1 :   GValue value = G_VALUE_INIT;
     513                 :             : 
     514                 :           1 :   pspec = g_param_spec_gtype ("gtype", "nick", "blurb",
     515                 :             :                               G_TYPE_PARAM, G_PARAM_READWRITE);
     516                 :             : 
     517                 :           1 :   g_value_init (&value, G_TYPE_GTYPE);
     518                 :           1 :   g_value_set_gtype (&value, G_TYPE_PARAM);
     519                 :             : 
     520                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     521                 :             : 
     522                 :           1 :   g_value_set_gtype (&value, G_TYPE_INT);
     523                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     524                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     525                 :           1 :   g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM);
     526                 :             : 
     527                 :           1 :   g_value_set_gtype (&value, G_TYPE_PARAM_INT);
     528                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     529                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     530                 :           1 :   g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM_INT);
     531                 :             : 
     532                 :           1 :   g_param_spec_unref (pspec);
     533                 :           1 : }
     534                 :             : 
     535                 :             : static void
     536                 :           1 : test_param_spec_variant (void)
     537                 :             : {
     538                 :             :   GParamSpec *pspec;
     539                 :           1 :   GValue value = G_VALUE_INIT;
     540                 :           1 :   GValue value2 = G_VALUE_INIT;
     541                 :           1 :   GValue value3 = G_VALUE_INIT;
     542                 :           1 :   GValue value4 = G_VALUE_INIT;
     543                 :           1 :   GValue value5 = G_VALUE_INIT;
     544                 :             : 
     545                 :           1 :   pspec = g_param_spec_variant ("variant", "nick", "blurb",
     546                 :             :                                 G_VARIANT_TYPE ("i"),
     547                 :             :                                 g_variant_new_int32 (42),
     548                 :             :                                 G_PARAM_READWRITE);
     549                 :             : 
     550                 :           1 :   g_value_init (&value, G_TYPE_VARIANT);
     551                 :           1 :   g_value_set_variant (&value, g_variant_new_int32 (42));
     552                 :             : 
     553                 :           1 :   g_value_init (&value2, G_TYPE_VARIANT);
     554                 :           1 :   g_value_set_variant (&value2, g_variant_new_int32 (43));
     555                 :             : 
     556                 :           1 :   g_value_init (&value3, G_TYPE_VARIANT);
     557                 :           1 :   g_value_set_variant (&value3, g_variant_new_int16 (42));
     558                 :             : 
     559                 :           1 :   g_value_init (&value4, G_TYPE_VARIANT);
     560                 :           1 :   g_value_set_variant (&value4, g_variant_new_parsed ("[@u 15, @u 10]"));
     561                 :             : 
     562                 :           1 :   g_value_init (&value5, G_TYPE_VARIANT);
     563                 :           1 :   g_value_set_variant (&value5, NULL);
     564                 :             : 
     565                 :           1 :   g_assert_true (g_param_value_defaults (pspec, &value));
     566                 :           1 :   g_assert_false (g_param_value_defaults (pspec, &value2));
     567                 :           1 :   g_assert_false (g_param_value_defaults (pspec, &value3));
     568                 :           1 :   g_assert_false (g_param_value_defaults (pspec, &value4));
     569                 :           1 :   g_assert_false (g_param_value_defaults (pspec, &value5));
     570                 :             : 
     571                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     572                 :           1 :   g_assert_false (g_param_value_validate (pspec, &value));
     573                 :             : 
     574                 :           1 :   g_value_reset (&value);
     575                 :           1 :   g_value_set_variant (&value, g_variant_new_uint32 (41));
     576                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
     577                 :           1 :   g_assert_true (g_param_value_validate (pspec, &value));
     578                 :           1 :   g_assert_true (g_param_value_is_valid (pspec, &value));
     579                 :           1 :   g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42);
     580                 :           1 :   g_value_unset (&value);
     581                 :             : 
     582                 :           1 :   g_value_unset (&value5);
     583                 :           1 :   g_value_unset (&value4);
     584                 :           1 :   g_value_unset (&value3);
     585                 :           1 :   g_value_unset (&value2);
     586                 :             : 
     587                 :           1 :   g_param_spec_unref (pspec);
     588                 :           1 : }
     589                 :             : 
     590                 :             : /* Test g_param_values_cmp() for #GParamSpecVariant. */
     591                 :             : static void
     592                 :           1 : test_param_spec_variant_cmp (void)
     593                 :             : {
     594                 :             :   const struct
     595                 :             :     {
     596                 :             :       const GVariantType *pspec_type;
     597                 :             :       const gchar *v1;
     598                 :             :       enum
     599                 :             :         {
     600                 :             :           LESS_THAN = -1,
     601                 :             :           EQUAL = 0,
     602                 :             :           GREATER_THAN = 1,
     603                 :             :           NOT_EQUAL,
     604                 :             :         } expected_result;
     605                 :             :       const gchar *v2;
     606                 :             :     }
     607                 :          10 :   vectors[] =
     608                 :             :     {
     609                 :           1 :       { G_VARIANT_TYPE ("i"), "@i 1", LESS_THAN, "@i 2" },
     610                 :           1 :       { G_VARIANT_TYPE ("i"), "@i 2", EQUAL, "@i 2" },
     611                 :           1 :       { G_VARIANT_TYPE ("i"), "@i 3", GREATER_THAN, "@i 2" },
     612                 :           1 :       { G_VARIANT_TYPE ("i"), NULL, LESS_THAN, "@i 2" },
     613                 :           1 :       { G_VARIANT_TYPE ("i"), NULL, EQUAL, NULL },
     614                 :           1 :       { G_VARIANT_TYPE ("i"), "@i 1", GREATER_THAN, NULL },
     615                 :           1 :       { G_VARIANT_TYPE ("i"), "@u 1", LESS_THAN, "@u 2" },
     616                 :           1 :       { G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@u 2" },
     617                 :           1 :       { G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@as ['there']" },
     618                 :           1 :       { G_VARIANT_TYPE ("i"), "@as ['hi']", EQUAL, "@as ['hi']" },
     619                 :             :     };
     620                 :             :   gsize i;
     621                 :             : 
     622                 :          11 :   for (i = 0; i < G_N_ELEMENTS (vectors); i++)
     623                 :             :     {
     624                 :             :       GParamSpec *pspec;
     625                 :          10 :       GValue v1 = G_VALUE_INIT;
     626                 :          10 :       GValue v2 = G_VALUE_INIT;
     627                 :             :       gint cmp;
     628                 :             : 
     629                 :          10 :       pspec = g_param_spec_variant ("variant", "nick", "blurb",
     630                 :          10 :                                     vectors[i].pspec_type,
     631                 :             :                                     NULL,
     632                 :             :                                     G_PARAM_READWRITE);
     633                 :             : 
     634                 :          10 :       g_value_init (&v1, G_TYPE_VARIANT);
     635                 :          10 :       g_value_set_variant (&v1,
     636                 :          10 :                            (vectors[i].v1 != NULL) ?
     637                 :           8 :                            g_variant_new_parsed (vectors[i].v1) : NULL);
     638                 :             : 
     639                 :          10 :       g_value_init (&v2, G_TYPE_VARIANT);
     640                 :          10 :       g_value_set_variant (&v2,
     641                 :          10 :                            (vectors[i].v2 != NULL) ?
     642                 :           8 :                            g_variant_new_parsed (vectors[i].v2) : NULL);
     643                 :             : 
     644                 :          10 :       cmp = g_param_values_cmp (pspec, &v1, &v2);
     645                 :             : 
     646                 :          10 :       switch (vectors[i].expected_result)
     647                 :             :         {
     648                 :           8 :         case LESS_THAN:
     649                 :             :         case EQUAL:
     650                 :             :         case GREATER_THAN:
     651                 :           8 :           g_assert_cmpint (cmp, ==, vectors[i].expected_result);
     652                 :           8 :           break;
     653                 :           2 :         case NOT_EQUAL:
     654                 :           2 :           g_assert_cmpint (cmp, !=, 0);
     655                 :           2 :           break;
     656                 :           0 :         default:
     657                 :             :           g_assert_not_reached ();
     658                 :             :         }
     659                 :             : 
     660                 :          10 :       g_value_unset (&v2);
     661                 :          10 :       g_value_unset (&v1);
     662                 :          10 :       g_param_spec_unref (pspec);
     663                 :             :     }
     664                 :           1 : }
     665                 :             : 
     666                 :             : static void
     667                 :           1 : test_param_value (void)
     668                 :             : {
     669                 :             :   GParamSpec *p, *p2;
     670                 :             :   GParamSpec *pp;
     671                 :           1 :   GValue value = G_VALUE_INIT;
     672                 :             : 
     673                 :           1 :   g_value_init (&value, G_TYPE_PARAM);
     674                 :           1 :   g_assert_true (G_VALUE_HOLDS_PARAM (&value));
     675                 :             : 
     676                 :           1 :   p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
     677                 :             : 
     678                 :           1 :   g_value_take_param (&value, p);
     679                 :           1 :   p2 = g_value_get_param (&value);
     680                 :           1 :   g_assert_true (p2 == p);
     681                 :             : 
     682                 :           1 :   pp = g_param_spec_uint ("my-uint", "My UInt", "Blurb", 0, 10, 5, G_PARAM_READWRITE);
     683                 :           1 :   g_value_set_param (&value, pp);
     684                 :             : 
     685                 :           1 :   p2 = g_value_dup_param (&value);
     686                 :           1 :   g_assert_true (p2 == pp); /* param specs use ref/unref for copy/free */
     687                 :           1 :   g_param_spec_unref (p2);
     688                 :             : 
     689                 :           1 :   g_value_unset (&value);
     690                 :           1 :   g_param_spec_unref (pp);
     691                 :           1 : }
     692                 :             : 
     693                 :             : static gint destroy_count;
     694                 :             : 
     695                 :             : static void
     696                 :           1 : my_destroy (gpointer data)
     697                 :             : {
     698                 :           1 :   destroy_count++;
     699                 :           1 : }
     700                 :             : 
     701                 :             : static void
     702                 :           1 : test_param_qdata (void)
     703                 :             : {
     704                 :             :   GParamSpec *p;
     705                 :             :   gchar *bla;
     706                 :             :   GQuark q;
     707                 :             : 
     708                 :           1 :   q = g_quark_from_string ("bla");
     709                 :             : 
     710                 :           1 :   p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
     711                 :           1 :   g_param_spec_set_qdata (p, q, "bla");
     712                 :           1 :   bla = g_param_spec_get_qdata (p, q);
     713                 :           1 :   g_assert_cmpstr (bla, ==, "bla");
     714                 :             : 
     715                 :           1 :   g_assert_cmpint (destroy_count, ==, 0);
     716                 :           1 :   g_param_spec_set_qdata_full (p, q, "bla", my_destroy);
     717                 :           1 :   g_param_spec_set_qdata_full (p, q, "blabla", my_destroy);
     718                 :           1 :   g_assert_cmpint (destroy_count, ==, 1);
     719                 :           1 :   g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla");
     720                 :           1 :   g_assert_cmpint (destroy_count, ==, 1);
     721                 :           1 :   g_assert_null (g_param_spec_get_qdata (p, q));
     722                 :             : 
     723                 :           1 :   g_param_spec_ref_sink (p);
     724                 :             : 
     725                 :           1 :   g_param_spec_unref (p);
     726                 :           1 : }
     727                 :             : 
     728                 :             : static void
     729                 :           1 : test_param_validate (void)
     730                 :             : {
     731                 :             :   GParamSpec *p;
     732                 :           1 :   GValue value = G_VALUE_INIT;
     733                 :             : 
     734                 :           1 :   p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
     735                 :             : 
     736                 :           1 :   g_value_init (&value, G_TYPE_INT);
     737                 :           1 :   g_value_set_int (&value, 100);
     738                 :           1 :   g_assert_false (g_param_value_defaults (p, &value));
     739                 :           1 :   g_assert_true (g_param_value_validate (p, &value));
     740                 :           1 :   g_assert_cmpint (g_value_get_int (&value), ==, 20);
     741                 :             : 
     742                 :           1 :   g_param_value_set_default (p, &value);
     743                 :           1 :   g_assert_true (g_param_value_defaults (p, &value));
     744                 :           1 :   g_assert_cmpint (g_value_get_int (&value), ==, 10);
     745                 :             : 
     746                 :           1 :   g_param_spec_unref (p);
     747                 :           1 : }
     748                 :             : 
     749                 :             : static void
     750                 :           1 : test_param_strings (void)
     751                 :             : {
     752                 :             :   GParamSpec *p;
     753                 :             : 
     754                 :             :   /* test canonicalization */
     755                 :           1 :   p = g_param_spec_int ("my_int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
     756                 :             : 
     757                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
     758                 :           1 :   g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int");
     759                 :           1 :   g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb");
     760                 :             : 
     761                 :           1 :   g_param_spec_unref (p);
     762                 :             : 
     763                 :             :   /* test nick defaults to name */
     764                 :           1 :   p = g_param_spec_int ("my-int", NULL, NULL, 0, 20, 10, G_PARAM_READWRITE);
     765                 :             : 
     766                 :           1 :   g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
     767                 :           1 :   g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int");
     768                 :           1 :   g_assert_null (g_param_spec_get_blurb (p));
     769                 :             : 
     770                 :           1 :   g_param_spec_unref (p);
     771                 :           1 : }
     772                 :             : 
     773                 :             : static void
     774                 :           3 : test_param_invalid_name (gconstpointer test_data)
     775                 :             : {
     776                 :           3 :   const gchar *invalid_name = test_data;
     777                 :             : 
     778                 :           3 :   g_test_summary ("Test that properties cannot be created with invalid names");
     779                 :             : 
     780                 :           3 :   if (g_test_subprocess ())
     781                 :             :     {
     782                 :             :       GParamSpec *p;
     783                 :           0 :       p = g_param_spec_int (invalid_name, "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
     784                 :           0 :       g_param_spec_unref (p);
     785                 :           0 :       return;
     786                 :             :     }
     787                 :             : 
     788                 :           3 :   g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
     789                 :           3 :   g_test_trap_assert_failed ();
     790                 :           3 :   g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*");
     791                 :             : }
     792                 :             : 
     793                 :             : static void
     794                 :           1 : test_param_convert (void)
     795                 :             : {
     796                 :             :   GParamSpec *p;
     797                 :           1 :   GValue v1 = G_VALUE_INIT;
     798                 :           1 :   GValue v2 = G_VALUE_INIT;
     799                 :             : 
     800                 :           1 :   p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
     801                 :           1 :   g_value_init (&v1, G_TYPE_UINT);
     802                 :           1 :   g_value_set_uint (&v1, 43);
     803                 :             : 
     804                 :           1 :   g_value_init (&v2, G_TYPE_INT);
     805                 :           1 :   g_value_set_int (&v2, -4);
     806                 :             : 
     807                 :           1 :   g_assert_false (g_param_value_convert (p, &v1, &v2, TRUE));
     808                 :           1 :   g_assert_cmpint (g_value_get_int (&v2), ==, -4);
     809                 :             : 
     810                 :           1 :   g_assert_true (g_param_value_convert (p, &v1, &v2, FALSE));
     811                 :           1 :   g_assert_cmpint (g_value_get_int (&v2), ==, 20);
     812                 :             : 
     813                 :           1 :   g_param_spec_unref (p);
     814                 :           1 : }
     815                 :             : 
     816                 :             : static void
     817                 :           1 : test_value_transform (void)
     818                 :             : {
     819                 :           1 :   GValue src = G_VALUE_INIT;
     820                 :           1 :   GValue dest = G_VALUE_INIT;
     821                 :             : 
     822                 :             : #define CHECK_INT_CONVERSION(type, cmpfunc, getter, value)              \
     823                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_INT, type));        \
     824                 :             :   g_value_init (&src, G_TYPE_INT);                                      \
     825                 :             :   g_value_init (&dest, type);                                           \
     826                 :             :   g_value_set_int (&src, value);                                        \
     827                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
     828                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
     829                 :             :   g_value_unset (&src);                                                 \
     830                 :             :   g_value_unset (&dest);
     831                 :             : 
     832                 :             :   /* Keep a check for an integer in the range of 0-127 so we're
     833                 :             :    * still testing g_value_get_char().  See
     834                 :             :    * https://bugzilla.gnome.org/show_bug.cgi?id=659870
     835                 :             :    * for why it is broken.
     836                 :             :    */
     837                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_CHAR, g_assert_cmpuint, char, 124)
     838                 :             : 
     839                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, -124)
     840                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, 124)
     841                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     842                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     843                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
     844                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     845                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     846                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     847                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, -12345678)
     848                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     849                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, -12345678)
     850                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
     851                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
     852                 :           1 :   CHECK_INT_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
     853                 :             : 
     854                 :             : #define CHECK_UINT_CONVERSION(type, cmpfunc, getter, value)             \
     855                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_UINT, type));       \
     856                 :             :   g_value_init (&src, G_TYPE_UINT);                                     \
     857                 :             :   g_value_init (&dest, type);                                           \
     858                 :             :   g_value_set_uint (&src, value);                                       \
     859                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
     860                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
     861                 :             :   g_value_unset (&src);                                                 \
     862                 :             :   g_value_unset (&dest);
     863                 :             : 
     864                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, char, 124)
     865                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, char, 124)
     866                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     867                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     868                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     869                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     870                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     871                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     872                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, 12345678)
     873                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     874                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, 12345678)
     875                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
     876                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
     877                 :           1 :   CHECK_UINT_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
     878                 :             : 
     879                 :             : #define CHECK_LONG_CONVERSION(type, cmpfunc, getter, value)             \
     880                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_LONG, type));       \
     881                 :             :   g_value_init (&src, G_TYPE_LONG);                                     \
     882                 :             :   g_value_init (&dest, type);                                           \
     883                 :             :   g_value_set_long (&src, value);                                       \
     884                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
     885                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
     886                 :             :   g_value_unset (&src);                                                 \
     887                 :             :   g_value_unset (&dest);
     888                 :             : 
     889                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, -124)
     890                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, 124)
     891                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     892                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     893                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
     894                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     895                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     896                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     897                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, -12345678)
     898                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     899                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, -12345678)
     900                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
     901                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
     902                 :           1 :   CHECK_LONG_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
     903                 :             : 
     904                 :             : #define CHECK_ULONG_CONVERSION(type, cmpfunc, getter, value)            \
     905                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_ULONG, type));      \
     906                 :             :   g_value_init (&src, G_TYPE_ULONG);                                    \
     907                 :             :   g_value_init (&dest, type);                                           \
     908                 :             :   g_value_set_ulong (&src, value);                                      \
     909                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
     910                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
     911                 :             :   g_value_unset (&src);                                                 \
     912                 :             :   g_value_unset (&dest);
     913                 :             : 
     914                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, char, 124)
     915                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, char, 124)
     916                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     917                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     918                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
     919                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     920                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     921                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     922                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, 12345678)
     923                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     924                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, 12345678)
     925                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
     926                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
     927                 :           1 :   CHECK_ULONG_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
     928                 :             : 
     929                 :             : #define CHECK_INT64_CONVERSION(type, cmpfunc, getter, value)            \
     930                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_INT64, type));      \
     931                 :             :   g_value_init (&src, G_TYPE_INT64);                                    \
     932                 :             :   g_value_init (&dest, type);                                           \
     933                 :             :   g_value_set_int64 (&src, value);                                      \
     934                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
     935                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
     936                 :             :   g_value_unset (&src);                                                 \
     937                 :             :   g_value_unset (&dest);
     938                 :             : 
     939                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, -124)
     940                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, 124)
     941                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     942                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     943                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
     944                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     945                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     946                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     947                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, -12345678)
     948                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     949                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, -12345678)
     950                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
     951                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
     952                 :           1 :   CHECK_INT64_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
     953                 :             : 
     954                 :             : #define CHECK_UINT64_CONVERSION(type, cmpfunc, getter, value)           \
     955                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_UINT64, type));     \
     956                 :             :   g_value_init (&src, G_TYPE_UINT64);                                   \
     957                 :             :   g_value_init (&dest, type);                                           \
     958                 :             :   g_value_set_uint64 (&src, value);                                     \
     959                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
     960                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
     961                 :             :   g_value_unset (&src);                                                 \
     962                 :             :   g_value_unset (&dest);
     963                 :             : 
     964                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, -124)
     965                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, 124)
     966                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     967                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     968                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
     969                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     970                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     971                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     972                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, -12345678)
     973                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     974                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, -12345678)
     975                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
     976                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
     977                 :           1 :   CHECK_UINT64_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
     978                 :             : 
     979                 :             : #define CHECK_FLOAT_CONVERSION(type, cmpfunc, getter, value)           \
     980                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_FLOAT, type));     \
     981                 :             :   g_value_init (&src, G_TYPE_FLOAT);                                   \
     982                 :             :   g_value_init (&dest, type);                                          \
     983                 :             :   g_value_set_float (&src, value);                                     \
     984                 :             :   g_assert_true (g_value_transform (&src, &dest));                     \
     985                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                   \
     986                 :             :   g_value_unset (&src);                                                \
     987                 :             :   g_value_unset (&dest);
     988                 :             : 
     989                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, -124)
     990                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, 124)
     991                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
     992                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
     993                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
     994                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
     995                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
     996                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
     997                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, -12345678)
     998                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
     999                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, -12345678)
    1000                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
    1001                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
    1002                 :           1 :   CHECK_FLOAT_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
    1003                 :             : 
    1004                 :             : #define CHECK_DOUBLE_CONVERSION(type, cmpfunc, getter, value)           \
    1005                 :             :   g_assert_true (g_value_type_transformable (G_TYPE_DOUBLE, type));     \
    1006                 :             :   g_value_init (&src, G_TYPE_DOUBLE);                                   \
    1007                 :             :   g_value_init (&dest, type);                                           \
    1008                 :             :   g_value_set_double (&src, value);                                     \
    1009                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
    1010                 :             :   cmpfunc (g_value_get_##getter (&dest), ==, value);                    \
    1011                 :             :   g_value_unset (&src);                                                 \
    1012                 :             :   g_value_unset (&dest);
    1013                 :             : 
    1014                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, -124)
    1015                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, g_assert_cmpint, schar, 124)
    1016                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 0)
    1017                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, g_assert_cmpuint, uchar, 255)
    1018                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, -12345)
    1019                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_INT, g_assert_cmpint, int, 12345)
    1020                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 0)
    1021                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, g_assert_cmpuint, uint, 12345)
    1022                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_LONG, g_assert_cmpint, long, -12345678)
    1023                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_ULONG, g_assert_cmpuint, ulong, 12345678)
    1024                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_INT64, g_assert_cmpint, int64, -12345678)
    1025                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_UINT64, g_assert_cmpuint, uint64, 12345678)
    1026                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_FLOAT, g_assert_cmpfloat, float, 12345678)
    1027                 :           1 :   CHECK_DOUBLE_CONVERSION(G_TYPE_DOUBLE, g_assert_cmpfloat, double, 12345678)
    1028                 :             : 
    1029                 :             : #define CHECK_BOOLEAN_CONVERSION(type, setter, value)                   \
    1030                 :             :   g_assert_true (g_value_type_transformable (type, G_TYPE_BOOLEAN));    \
    1031                 :             :   g_value_init (&src, type);                                            \
    1032                 :             :   g_value_init (&dest, G_TYPE_BOOLEAN);                                 \
    1033                 :             :   g_value_set_##setter (&src, value);                                   \
    1034                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
    1035                 :             :   g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE);              \
    1036                 :             :   g_value_set_##setter (&src, 0);                                       \
    1037                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
    1038                 :             :   g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE);             \
    1039                 :             :   g_value_unset (&src);                                                 \
    1040                 :             :   g_value_unset (&dest);
    1041                 :             : 
    1042                 :           1 :   CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345)
    1043                 :           1 :   CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345)
    1044                 :           1 :   CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678)
    1045                 :           1 :   CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
    1046                 :           1 :   CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678)
    1047                 :           1 :   CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
    1048                 :             : 
    1049                 :             : #define CHECK_STRING_CONVERSION(int_type, setter, int_value)            \
    1050                 :             :   g_assert_true (g_value_type_transformable (int_type, G_TYPE_STRING)); \
    1051                 :             :   g_value_init (&src, int_type);                                        \
    1052                 :             :   g_value_init (&dest, G_TYPE_STRING);                                  \
    1053                 :             :   g_value_set_##setter (&src, int_value);                               \
    1054                 :             :   g_assert_true (g_value_transform (&src, &dest));                      \
    1055                 :             :   g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value);         \
    1056                 :             :   g_value_unset (&src);                                                 \
    1057                 :             :   g_value_unset (&dest);
    1058                 :             : 
    1059                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345)
    1060                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345)
    1061                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678)
    1062                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
    1063                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678)
    1064                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
    1065                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000)
    1066                 :           1 :   CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567)
    1067                 :             : 
    1068                 :           1 :   g_assert_false (g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR));
    1069                 :           1 :   g_value_init (&src, G_TYPE_STRING);
    1070                 :           1 :   g_value_init (&dest, G_TYPE_CHAR);
    1071                 :           1 :   g_value_set_static_string (&src, "bla");
    1072                 :           1 :   g_value_set_schar (&dest, 'c');
    1073                 :           1 :   g_assert_false (g_value_transform (&src, &dest));
    1074                 :           1 :   g_assert_cmpint (g_value_get_schar (&dest), ==, 'c');
    1075                 :           1 :   g_value_unset (&src);
    1076                 :           1 :   g_value_unset (&dest);
    1077                 :           1 : }
    1078                 :             : 
    1079                 :             : 
    1080                 :             : /* We create some dummy objects with a simple relationship:
    1081                 :             :  *
    1082                 :             :  *           GObject
    1083                 :             :  *          /       \
    1084                 :             :  * TestObjectA     TestObjectC
    1085                 :             :  *      |
    1086                 :             :  * TestObjectB
    1087                 :             :  *
    1088                 :             :  * ie: TestObjectB is a subclass of TestObjectA and TestObjectC is
    1089                 :             :  * related to neither.
    1090                 :             :  */
    1091                 :             : 
    1092                 :             : static GType test_object_a_get_type (void);
    1093                 :             : typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
    1094                 :           0 : G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
    1095                 :           0 : static void test_object_a_class_init (TestObjectAClass *class) { }
    1096                 :           0 : static void test_object_a_init (TestObjectA *a) { }
    1097                 :             : 
    1098                 :             : static GType test_object_b_get_type (void);
    1099                 :             : typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
    1100                 :           0 : G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ())
    1101                 :           0 : static void test_object_b_class_init (TestObjectBClass *class) { }
    1102                 :           0 : static void test_object_b_init (TestObjectB *b) { }
    1103                 :             : 
    1104                 :             : static GType test_object_c_get_type (void);
    1105                 :             : typedef GObject TestObjectC; typedef GObjectClass TestObjectCClass;
    1106                 :           0 : G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT)
    1107                 :           0 : static void test_object_c_class_init (TestObjectCClass *class) { }
    1108                 :           0 : static void test_object_c_init (TestObjectC *c) { }
    1109                 :             : 
    1110                 :             : /* We create an interface and programmatically populate it with
    1111                 :             :  * properties of each of the above type, with various flag combinations.
    1112                 :             :  *
    1113                 :             :  * Properties are named like "type-perm" where type is 'a', 'b' or 'c'
    1114                 :             :  * and perm is a series of characters, indicating the permissions:
    1115                 :             :  *
    1116                 :             :  *   - 'r': readable
    1117                 :             :  *   - 'w': writable
    1118                 :             :  *   - 'c': construct
    1119                 :             :  *   - 'C': construct-only
    1120                 :             :  *
    1121                 :             :  * It doesn't make sense to have a property that is neither readable nor
    1122                 :             :  * writable.  It is also not valid to have construct or construct-only
    1123                 :             :  * on read-only params.  Finally, it is invalid to have both construct
    1124                 :             :  * and construct-only specified, so we do not consider those cases.
    1125                 :             :  * That gives us 7 possible permissions:
    1126                 :             :  *
    1127                 :             :  *     'r', 'w', 'rw', 'wc', 'rwc', 'wC', 'rwC'
    1128                 :             :  *
    1129                 :             :  * And 9 impossible ones:
    1130                 :             :  *
    1131                 :             :  *     '', 'c', 'rc', 'C', 'rC', 'cC', 'rcC', 'wcC', rwcC'
    1132                 :             :  *
    1133                 :             :  * For a total of 16 combinations.
    1134                 :             :  *
    1135                 :             :  * That gives a total of 48 (16 * 3) possible flag/type combinations, of
    1136                 :             :  * which 27 (9 * 3) are impossible to install.
    1137                 :             :  *
    1138                 :             :  * That gives 21 (7 * 3) properties that will be installed.
    1139                 :             :  */
    1140                 :             : typedef GTypeInterface TestInterfaceInterface;
    1141                 :             : static GType test_interface_get_type (void);
    1142                 :             : //typedef struct _TestInterface TestInterface;
    1143                 :           0 : G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
    1144                 :             : static void
    1145                 :           0 : test_interface_default_init (TestInterfaceInterface *iface)
    1146                 :             : {
    1147                 :           0 :   const gchar *names[] = { "a", "b", "c" };
    1148                 :           0 :   const gchar *perms[] = { NULL, "r",  "w",  "rw",
    1149                 :             :                            NULL, NULL, "wc", "rwc",
    1150                 :             :                            NULL, NULL, "wC", "rwC",
    1151                 :             :                            NULL, NULL, NULL, NULL };
    1152                 :           0 :   const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), test_object_c_get_type () };
    1153                 :             :   guint i, j;
    1154                 :             : 
    1155                 :           0 :   for (i = 0; i < G_N_ELEMENTS (types); i++)
    1156                 :           0 :     for (j = 0; j < G_N_ELEMENTS (perms); j++)
    1157                 :             :       {
    1158                 :             :         gchar prop_name[10];
    1159                 :             :         GParamSpec *pspec;
    1160                 :             : 
    1161                 :           0 :         if (perms[j] == NULL)
    1162                 :             :           {
    1163                 :           0 :             if (!g_test_undefined ())
    1164                 :           0 :               continue;
    1165                 :             : 
    1166                 :             :             /* we think that this is impossible.  make sure. */
    1167                 :           0 :             pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j);
    1168                 :             : 
    1169                 :           0 :             g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
    1170                 :             :                                    "*assertion*pspec->flags*failed*");
    1171                 :           0 :             g_object_interface_install_property (iface, pspec);
    1172                 :           0 :             g_test_assert_expected_messages ();
    1173                 :             : 
    1174                 :           0 :             continue;
    1175                 :             :           }
    1176                 :             : 
    1177                 :             :         /* install the property */
    1178                 :           0 :         g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
    1179                 :           0 :         pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[i], j);
    1180                 :           0 :         g_object_interface_install_property (iface, pspec);
    1181                 :             :       }
    1182                 :           0 : }
    1183                 :             : 
    1184                 :             : /* We now have 21 properties.  Each property may be correctly
    1185                 :             :  * implemented with the following types:
    1186                 :             :  *
    1187                 :             :  *   Properties         Valid Types       Reason
    1188                 :             :  *
    1189                 :             :  *   a-r                a, b              Read only can provide subclasses
    1190                 :             :  *   a-w, wc, wC        a, GObject        Write only can accept superclasses
    1191                 :             :  *   a-rw, rwc, rwC     a                 Read-write must be exactly equal
    1192                 :             :  *
    1193                 :             :  *   b-r                b                 (as above)
    1194                 :             :  *   b-w, wc, wC        b, a, GObject
    1195                 :             :  *   b-rw, rwc, rwC     b
    1196                 :             :  *
    1197                 :             :  *   c-r                c                 (as above)
    1198                 :             :  *   c-wo, wc, wC       c, GObject
    1199                 :             :  *   c-rw, rwc, rwC     c
    1200                 :             :  *
    1201                 :             :  * We can express this in a 48-by-4 table where each row represents an
    1202                 :             :  * installed property and each column represents a type.  The value in
    1203                 :             :  * the table represents if it is valid to subclass the row's property
    1204                 :             :  * with the type of the column:
    1205                 :             :  *
    1206                 :             :  *   - 0:   invalid because the interface property doesn't exist (invalid flags)
    1207                 :             :  *   - 'v': valid
    1208                 :             :  *   - '=': invalid because of the type not being exactly equal
    1209                 :             :  *   - '<': invalid because of the type not being a subclass
    1210                 :             :  *   - '>': invalid because of the type not being a superclass
    1211                 :             :  *
    1212                 :             :  * We organise the table by interface property type ('a', 'b', 'c') then
    1213                 :             :  * by interface property flags.
    1214                 :             :  */
    1215                 :             : 
    1216                 :             : static gint valid_impl_types[48][4] = {
    1217                 :             :                     /* a    b    c    GObject */
    1218                 :             :     /* 'a-' */       { 0, },
    1219                 :             :     /* 'a-r' */      { 'v', 'v', '<', '<' },
    1220                 :             :     /* 'a-w' */      { 'v', '>', '>', 'v' },
    1221                 :             :     /* 'a-rw' */     { 'v', '=', '=', '=' },
    1222                 :             :     /* 'a-c */       { 0, },
    1223                 :             :     /* 'a-rc' */     { 0, },
    1224                 :             :     /* 'a-wc' */     { 'v', '>', '>', 'v' },
    1225                 :             :     /* 'a-rwc' */    { 'v', '=', '=', '=' },
    1226                 :             :     /* 'a-C */       { 0, },
    1227                 :             :     /* 'a-rC' */     { 0, },
    1228                 :             :     /* 'a-wC' */     { 'v', '>', '>', 'v' },
    1229                 :             :     /* 'a-rwC' */    { 'v', '=', '=', '=' },
    1230                 :             :     /* 'a-cC */      { 0, },
    1231                 :             :     /* 'a-rcC' */    { 0, },
    1232                 :             :     /* 'a-wcC' */    { 0, },
    1233                 :             :     /* 'a-rwcC' */   { 0, },
    1234                 :             : 
    1235                 :             :     /* 'b-' */       { 0, },
    1236                 :             :     /* 'b-r' */      { '<', 'v', '<', '<' },
    1237                 :             :     /* 'b-w' */      { 'v', 'v', '>', 'v' },
    1238                 :             :     /* 'b-rw' */     { '=', 'v', '=', '=' },
    1239                 :             :     /* 'b-c */       { 0, },
    1240                 :             :     /* 'b-rc' */     { 0, },
    1241                 :             :     /* 'b-wc' */     { 'v', 'v', '>', 'v' },
    1242                 :             :     /* 'b-rwc' */    { '=', 'v', '=', '=' },
    1243                 :             :     /* 'b-C */       { 0, },
    1244                 :             :     /* 'b-rC' */     { 0, },
    1245                 :             :     /* 'b-wC' */     { 'v', 'v', '>', 'v' },
    1246                 :             :     /* 'b-rwC' */    { '=', 'v', '=', '=' },
    1247                 :             :     /* 'b-cC */      { 0, },
    1248                 :             :     /* 'b-rcC' */    { 0, },
    1249                 :             :     /* 'b-wcC' */    { 0, },
    1250                 :             :     /* 'b-rwcC' */   { 0, },
    1251                 :             : 
    1252                 :             :     /* 'c-' */       { 0, },
    1253                 :             :     /* 'c-r' */      { '<', '<', 'v', '<' },
    1254                 :             :     /* 'c-w' */      { '>', '>', 'v', 'v' },
    1255                 :             :     /* 'c-rw' */     { '=', '=', 'v', '=' },
    1256                 :             :     /* 'c-c */       { 0, },
    1257                 :             :     /* 'c-rc' */     { 0, },
    1258                 :             :     /* 'c-wc' */     { '>', '>', 'v', 'v' },
    1259                 :             :     /* 'c-rwc' */    { '=', '=', 'v', '=' },
    1260                 :             :     /* 'c-C */       { 0, },
    1261                 :             :     /* 'c-rC' */     { 0, },
    1262                 :             :     /* 'c-wC' */     { '>', '>', 'v', 'v' },
    1263                 :             :     /* 'c-rwC' */    { '=', '=', 'v', '=' },
    1264                 :             :     /* 'c-cC */      { 0, },
    1265                 :             :     /* 'c-rcC' */    { 0, },
    1266                 :             :     /* 'c-wcC' */    { 0, },
    1267                 :             :     /* 'c-rwcC' */   { 0, }
    1268                 :             : };
    1269                 :             : 
    1270                 :             : /* We also try to change the flags.  We must ensure that all
    1271                 :             :  * implementations provide all functionality promised by the interface.
    1272                 :             :  * We must therefore never remove readability or writability (but we can
    1273                 :             :  * add them).  Construct-only is a restrictions that applies to
    1274                 :             :  * writability, so we can never add it unless writability was never
    1275                 :             :  * present in the first place, in which case "writable at construct
    1276                 :             :  * only" is still better than "not writable".
    1277                 :             :  *
    1278                 :             :  * The 'construct' flag is of interest only to the implementation.  It
    1279                 :             :  * may be changed at any time.
    1280                 :             :  *
    1281                 :             :  *   Properties         Valid Access      Reason
    1282                 :             :  *
    1283                 :             :  *   *-r                r, rw, rwc, rwC   Must keep readable, but can restrict newly-added writable
    1284                 :             :  *   *-w                w, rw, rwc        Must keep writable unrestricted
    1285                 :             :  *   *-rw               rw, rwc           Must not add any restrictions
    1286                 :             :  *   *-rwc              rw, rwc           Must not add any restrictions
    1287                 :             :  *   *-rwC              rw, rwc, rwC      Can remove 'construct-only' restriction
    1288                 :             :  *   *-wc               rwc, rw, w, wc    Can add readability
    1289                 :             :  *   *-wC               rwC, rw, w, wC    Can add readability or remove 'construct only' restriction
    1290                 :             :  *                        rwc, wc
    1291                 :             :  *
    1292                 :             :  * We can represent this with a 16-by-16 table.  The rows represent the
    1293                 :             :  * flags of the property on the interface.  The columns is the flags to
    1294                 :             :  * try to use when overriding the property.  The cell contents are:
    1295                 :             :  *
    1296                 :             :  *   - 0:   invalid because the interface property doesn't exist (invalid flags)
    1297                 :             :  *   - 'v': valid
    1298                 :             :  *   - 'i': invalid because the implementation flags are invalid
    1299                 :             :  *   - 'f': invalid because of the removal of functionality
    1300                 :             :  *   - 'r': invalid because of the addition of restrictions (ie: construct-only)
    1301                 :             :  *
    1302                 :             :  * We also ensure that removal of functionality is reported before
    1303                 :             :  * addition of restrictions, since this is a more basic problem.
    1304                 :             :  */
    1305                 :             : static gint valid_impl_flags[16][16] = {
    1306                 :             :                  /* ''   r    w    rw   c    rc   wc   rwc  C    rC   wC   rwC  cC   rcC  wcC  rwcC */
    1307                 :             :     /* '*-' */    { 0, },
    1308                 :             :     /* '*-r' */   { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
    1309                 :             :     /* '*-w' */   { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
    1310                 :             :     /* '*-rw' */  { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
    1311                 :             :     /* '*-c */    { 0, },
    1312                 :             :     /* '*-rc' */  { 0, },
    1313                 :             :     /* '*-wc' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
    1314                 :             :     /* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
    1315                 :             :     /* '*-C */    { 0, },
    1316                 :             :     /* '*-rC' */  { 0, },
    1317                 :             :     /* '*-wC' */  { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' },
    1318                 :             :     /* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
    1319                 :             : };
    1320                 :             : 
    1321                 :             : static guint change_this_flag;
    1322                 :             : static guint change_this_type;
    1323                 :             : static guint use_this_flag;
    1324                 :             : static guint use_this_type;
    1325                 :             : 
    1326                 :             : typedef GObjectClass TestImplementationClass;
    1327                 :             : typedef GObject TestImplementation;
    1328                 :             : 
    1329                 :           0 : static void test_implementation_init (TestImplementation *impl) { }
    1330                 :           0 : static void test_implementation_iface_init (TestInterfaceInterface *iface) { }
    1331                 :             : 
    1332                 :             : static GType test_implementation_get_type (void);
    1333                 :           0 : G_DEFINE_TYPE_WITH_CODE (TestImplementation, test_implementation, G_TYPE_OBJECT,
    1334                 :             :                          G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_implementation_iface_init))
    1335                 :             : 
    1336                 :           0 : static void test_implementation_class_init (TestImplementationClass *class)
    1337                 :             : {
    1338                 :           0 :   const gchar *names[] = { "a", "b", "c" };
    1339                 :           0 :   const gchar *perms[] = { NULL, "r",  "w",  "rw",
    1340                 :             :                            NULL, NULL, "wc", "rwc",
    1341                 :             :                            NULL, NULL, "wC", "rwC",
    1342                 :             :                            NULL, NULL, NULL, NULL };
    1343                 :           0 :   const GType types[] = { test_object_a_get_type (), test_object_b_get_type (),
    1344                 :           0 :                           test_object_c_get_type (), G_TYPE_OBJECT };
    1345                 :             :   gchar prop_name[10];
    1346                 :             :   GParamSpec *pspec;
    1347                 :             :   guint i, j;
    1348                 :             : 
    1349                 :           0 :   class->get_property = GINT_TO_POINTER (1);
    1350                 :           0 :   class->set_property = GINT_TO_POINTER (1);
    1351                 :             : 
    1352                 :             :   /* Install all of the non-modified properties or else GObject will
    1353                 :             :    * complain about non-implemented properties.
    1354                 :             :    */
    1355                 :           0 :   for (i = 0; i < 3; i++)
    1356                 :           0 :     for (j = 0; j < G_N_ELEMENTS (perms); j++)
    1357                 :             :       {
    1358                 :           0 :         if (i == change_this_type && j == change_this_flag)
    1359                 :           0 :           continue;
    1360                 :             : 
    1361                 :           0 :         if (perms[j] != NULL)
    1362                 :             :           {
    1363                 :             :             /* override the property without making changes */
    1364                 :           0 :             g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
    1365                 :           0 :             g_object_class_override_property (class, 1, prop_name);
    1366                 :             :           }
    1367                 :             :       }
    1368                 :             : 
    1369                 :             :   /* Now try installing our modified property */
    1370                 :           0 :   if (perms[change_this_flag] == NULL)
    1371                 :           0 :     g_error ("Interface property does not exist");
    1372                 :             : 
    1373                 :           0 :   g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[change_this_type], perms[change_this_flag]);
    1374                 :           0 :   pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[use_this_type], use_this_flag);
    1375                 :           0 :   g_object_class_install_property (class, 1, pspec);
    1376                 :           0 : }
    1377                 :             : 
    1378                 :             : typedef struct {
    1379                 :             :   gint change_this_flag;
    1380                 :             :   gint change_this_type;
    1381                 :             :   gint use_this_flag;
    1382                 :             :   gint use_this_type;
    1383                 :             : } TestParamImplementData;
    1384                 :             : 
    1385                 :             : static void
    1386                 :           0 : test_param_implement_child (gconstpointer user_data)
    1387                 :             : {
    1388                 :           0 :   TestParamImplementData *data = (gpointer) user_data;
    1389                 :             : 
    1390                 :             :   /* GObject oddity: GObjectClass must be initialised before we can
    1391                 :             :    * initialise a GTypeInterface.
    1392                 :             :    */
    1393                 :           0 :   g_type_class_ref (G_TYPE_OBJECT);
    1394                 :             : 
    1395                 :             :   /* Bring up the interface first. */
    1396                 :           0 :   g_type_default_interface_ref (test_interface_get_type ());
    1397                 :             : 
    1398                 :             :   /* Copy the flags into the global vars so
    1399                 :             :    * test_implementation_class_init() will see them.
    1400                 :             :    */
    1401                 :           0 :   change_this_flag = data->change_this_flag;
    1402                 :           0 :   change_this_type = data->change_this_type;
    1403                 :           0 :   use_this_flag = data->use_this_flag;
    1404                 :           0 :   use_this_type = data->use_this_type;
    1405                 :             : 
    1406                 :           0 :   g_type_class_ref (test_implementation_get_type ());
    1407                 :           0 : }
    1408                 :             : 
    1409                 :             : static void
    1410                 :           1 : test_param_implement (void)
    1411                 :             : {
    1412                 :             :   gchar *test_path;
    1413                 :             : 
    1414                 :             :   /* This test is slow. */
    1415                 :           1 :   if (!g_test_slow ())
    1416                 :             :     {
    1417                 :           1 :       g_test_skip ("Skipping slow /param/implement test");
    1418                 :           1 :       return;
    1419                 :             :     }
    1420                 :             : 
    1421                 :           0 :   for (change_this_flag = 0; change_this_flag < 16; change_this_flag++)
    1422                 :           0 :     for (change_this_type = 0; change_this_type < 3; change_this_type++)
    1423                 :           0 :       for (use_this_flag = 0; use_this_flag < 16; use_this_flag++)
    1424                 :           0 :         for (use_this_type = 0; use_this_type < 4; use_this_type++)
    1425                 :             :           {
    1426                 :           0 :             if (!g_test_undefined ())
    1427                 :             :               {
    1428                 :             :                 /* only test the valid (defined) cases, e.g. under valgrind */
    1429                 :           0 :                 if (valid_impl_flags[change_this_flag][use_this_flag] != 'v')
    1430                 :           0 :                   continue;
    1431                 :             : 
    1432                 :           0 :                 if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v')
    1433                 :           0 :                   continue;
    1434                 :             :               }
    1435                 :             : 
    1436                 :           0 :             test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
    1437                 :             :                                          change_this_flag, change_this_type,
    1438                 :             :                                          use_this_flag, use_this_type);
    1439                 :           0 :             g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND,
    1440                 :             :                                     G_TEST_SUBPROCESS_DEFAULT);
    1441                 :           0 :             g_free (test_path);
    1442                 :             : 
    1443                 :             :             /* We want to ensure that any flags mismatch problems are reported first. */
    1444                 :           0 :             switch (valid_impl_flags[change_this_flag][use_this_flag])
    1445                 :             :               {
    1446                 :           0 :               case 0:
    1447                 :             :                 /* make sure the other table agrees */
    1448                 :           0 :                 g_assert_cmpint (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type], ==, 0);
    1449                 :           0 :                 g_test_trap_assert_failed ();
    1450                 :           0 :                 g_test_trap_assert_stderr ("*Interface property does not exist*");
    1451                 :           0 :                 continue;
    1452                 :             : 
    1453                 :           0 :               case 'i':
    1454                 :           0 :                 g_test_trap_assert_failed ();
    1455                 :           0 :                 g_test_trap_assert_stderr ("*pspec->flags*");
    1456                 :           0 :                 continue;
    1457                 :             : 
    1458                 :           0 :               case 'f':
    1459                 :           0 :                 g_test_trap_assert_failed ();
    1460                 :           0 :                 g_test_trap_assert_stderr ("*remove functionality*");
    1461                 :           0 :                 continue;
    1462                 :             : 
    1463                 :           0 :               case 'r':
    1464                 :           0 :                 g_test_trap_assert_failed ();
    1465                 :           0 :                 g_test_trap_assert_stderr ("*introduce additional restrictions*");
    1466                 :           0 :                 continue;
    1467                 :             : 
    1468                 :           0 :               case 'v':
    1469                 :           0 :                 break;
    1470                 :             :               }
    1471                 :             : 
    1472                 :             :             /* Next, we check if there should have been a type error. */
    1473                 :           0 :             switch (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type])
    1474                 :             :               {
    1475                 :           0 :               case 0:
    1476                 :             :                 /* this should have been caught above */
    1477                 :             :                 g_assert_not_reached ();
    1478                 :             : 
    1479                 :           0 :               case '=':
    1480                 :           0 :                 g_test_trap_assert_failed ();
    1481                 :           0 :                 g_test_trap_assert_stderr ("*exactly equal*");
    1482                 :           0 :                 continue;
    1483                 :             : 
    1484                 :           0 :               case '<':
    1485                 :           0 :                 g_test_trap_assert_failed ();
    1486                 :           0 :                 g_test_trap_assert_stderr ("*equal to or more restrictive*");
    1487                 :           0 :                 continue;
    1488                 :             : 
    1489                 :           0 :               case '>':
    1490                 :           0 :                 g_test_trap_assert_failed ();
    1491                 :           0 :                 g_test_trap_assert_stderr ("*equal to or less restrictive*");
    1492                 :           0 :                 continue;
    1493                 :             : 
    1494                 :           0 :               case 'v':
    1495                 :           0 :                 break;
    1496                 :             :               }
    1497                 :             : 
    1498                 :           0 :             g_test_trap_assert_passed ();
    1499                 :             :           }
    1500                 :             : }
    1501                 :             : 
    1502                 :             : static void
    1503                 :           1 : test_param_default (void)
    1504                 :             : {
    1505                 :             :   GParamSpec *param;
    1506                 :             :   const GValue *def;
    1507                 :             : 
    1508                 :           1 :   param = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
    1509                 :           1 :   def = g_param_spec_get_default_value (param);
    1510                 :             : 
    1511                 :           1 :   g_assert_true (G_VALUE_HOLDS (def, G_TYPE_INT));
    1512                 :           1 :   g_assert_cmpint (g_value_get_int (def), ==, 10);
    1513                 :             : 
    1514                 :           1 :   g_param_spec_unref (param);
    1515                 :           1 : }
    1516                 :             : 
    1517                 :             : static void
    1518                 :           1 : test_param_is_valid_name (void)
    1519                 :             : {
    1520                 :           1 :   const gchar *valid_names[] =
    1521                 :             :     {
    1522                 :             :       "property",
    1523                 :             :       "i",
    1524                 :             :       "multiple-segments",
    1525                 :             :       "segment0-SEGMENT1",
    1526                 :             :       "using_underscores",
    1527                 :             :     };
    1528                 :           1 :   const gchar *invalid_names[] =
    1529                 :             :     {
    1530                 :             :       "",
    1531                 :             :       "7zip",
    1532                 :             :       "my_int:hello",
    1533                 :             :     };
    1534                 :             :   gsize i;
    1535                 :             : 
    1536                 :           6 :   for (i = 0; i < G_N_ELEMENTS (valid_names); i++)
    1537                 :           5 :     g_assert_true (g_param_spec_is_valid_name (valid_names[i]));
    1538                 :             : 
    1539                 :           4 :   for (i = 0; i < G_N_ELEMENTS (invalid_names); i++)
    1540                 :           3 :     g_assert_false (g_param_spec_is_valid_name (invalid_names[i]));
    1541                 :           1 : }
    1542                 :             : 
    1543                 :             : static void
    1544                 :           1 : param_int_init (GParamSpec *pspec)
    1545                 :             : {
    1546                 :           1 :   GParamSpecInt *ispec = (GParamSpecInt *)pspec;
    1547                 :             : 
    1548                 :           1 :   ispec->minimum = 0x7fffffff;
    1549                 :           1 :   ispec->maximum = 0x80000000;
    1550                 :           1 :   ispec->default_value = 0;
    1551                 :           1 : }
    1552                 :             : 
    1553                 :             : static void
    1554                 :           0 : param_int_set_default (GParamSpec *pspec,
    1555                 :             :                        GValue     *value)
    1556                 :             : {
    1557                 :           0 :   value->data[0].v_int = ((GParamSpecInt *)pspec)->default_value;
    1558                 :           0 : }
    1559                 :             : 
    1560                 :             : static gboolean
    1561                 :           1 : param_int_validate (GParamSpec *pspec,
    1562                 :             :                     GValue     *value)
    1563                 :             : {
    1564                 :           1 :   GParamSpecInt *ispec = (GParamSpecInt *)pspec;
    1565                 :           1 :   int oval = value->data[0].v_int;
    1566                 :             : 
    1567                 :           1 :   value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
    1568                 :             : 
    1569                 :           1 :   return value->data[0].v_int != oval;
    1570                 :             : }
    1571                 :             : 
    1572                 :             : static int
    1573                 :           0 : param_int_values_cmp (GParamSpec   *pspec,
    1574                 :             :                       const GValue *value1,
    1575                 :             :                       const GValue *value2)
    1576                 :             : {
    1577                 :           0 :   if (value1->data[0].v_int < value2->data[0].v_int)
    1578                 :           0 :     return -1;
    1579                 :             :   else
    1580                 :           0 :     return value1->data[0].v_int > value2->data[0].v_int;
    1581                 :             : }
    1582                 :             : 
    1583                 :             : static GType custom_type;
    1584                 :             : 
    1585                 :             : /* Register a pspec that has a validate vfunc, but not
    1586                 :             :  * value_is_valid, to test the fallback in g_param_value_is_valid
    1587                 :             :  */
    1588                 :             : static void
    1589                 :           1 : register_custom_pspec (void)
    1590                 :             : {
    1591                 :           1 :   const GParamSpecTypeInfo pspec_info = {
    1592                 :             :     sizeof (GParamSpecInt),   /* instance_size */
    1593                 :             :     16,                       /* n_preallocs */
    1594                 :             :     param_int_init,           /* instance_init */
    1595                 :             :     G_TYPE_INT,               /* value_type */
    1596                 :             :     NULL,                     /* finalize */
    1597                 :             :     param_int_set_default,    /* value_set_default */
    1598                 :             :     param_int_validate,       /* value_validate */
    1599                 :             :     param_int_values_cmp,     /* values_cmp */
    1600                 :             :   };
    1601                 :             : 
    1602                 :           1 :   custom_type = g_param_type_register_static ("GParamInt2", &pspec_info);
    1603                 :           1 : }
    1604                 :             : 
    1605                 :             : static GParamSpec *
    1606                 :           1 : g_param_spec_custom (const char   *name,
    1607                 :             :                      int           minimum,
    1608                 :             :                      int           maximum,
    1609                 :             :                      int           default_value,
    1610                 :             :                       GParamFlags  flags)
    1611                 :             : {
    1612                 :             :   GParamSpecInt *ispec;
    1613                 :             : 
    1614                 :           1 :   g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
    1615                 :             : 
    1616                 :           1 :   ispec = g_param_spec_internal (custom_type, name, NULL, NULL, flags);
    1617                 :           1 :   if (ispec == NULL)
    1618                 :           0 :     return NULL;
    1619                 :             : 
    1620                 :           1 :   ispec->minimum = minimum;
    1621                 :           1 :   ispec->maximum = maximum;
    1622                 :           1 :   ispec->default_value = default_value;
    1623                 :             : 
    1624                 :           1 :   return G_PARAM_SPEC (ispec);
    1625                 :             : }
    1626                 :             : 
    1627                 :             : static void
    1628                 :           1 : test_param_spec_custom (void)
    1629                 :             : {
    1630                 :             :   GParamSpec *pspec;
    1631                 :           1 :   GValue value = G_VALUE_INIT;
    1632                 :             : 
    1633                 :           1 :   register_custom_pspec ();
    1634                 :             : 
    1635                 :           1 :   pspec = g_param_spec_custom ("myint", 10, 30, 20, G_PARAM_READWRITE);
    1636                 :             : 
    1637                 :           1 :   g_value_init (&value, G_TYPE_INT);
    1638                 :             : 
    1639                 :           1 :   g_value_set_int (&value, 40);
    1640                 :             : 
    1641                 :           1 :   g_assert_false (g_param_value_is_valid (pspec, &value));
    1642                 :           1 :   g_assert_cmpint (g_value_get_int (&value), ==, 40);
    1643                 :             : 
    1644                 :           1 :   g_param_spec_unref (pspec);
    1645                 :           1 : }
    1646                 :             : 
    1647                 :             : static void
    1648                 :           1 : test_param_spec_pool (void)
    1649                 :             : {
    1650                 :           1 :   GParamSpecPool *pool = g_param_spec_pool_new (FALSE);
    1651                 :           1 :   GParamSpec *pspec = g_param_spec_ref_sink (g_param_spec_int ("int", NULL, NULL, -1, 100, -1, G_PARAM_READWRITE));
    1652                 :           1 :   GParamSpec *check = NULL;
    1653                 :             : 
    1654                 :           1 :   g_param_spec_pool_insert (pool, pspec, G_TYPE_OBJECT);
    1655                 :           1 :   check = g_param_spec_pool_lookup (pool, "int", G_TYPE_OBJECT, FALSE);
    1656                 :           1 :   g_assert_true (check->owner_type == G_TYPE_OBJECT);
    1657                 :             : 
    1658                 :           1 :   g_param_spec_pool_remove (pool, pspec);
    1659                 :           1 :   g_assert_null (g_param_spec_pool_lookup (pool, "int", G_TYPE_OBJECT, FALSE));
    1660                 :             : 
    1661                 :           1 :   g_param_spec_pool_free (pool);
    1662                 :           1 :   g_param_spec_unref (pspec);
    1663                 :           1 : }
    1664                 :             : 
    1665                 :             : int
    1666                 :           1 : main (int argc, char *argv[])
    1667                 :             : {
    1668                 :             :   TestParamImplementData data, *test_data;
    1669                 :             :   gchar *test_path;
    1670                 :             : 
    1671                 :           1 :   g_test_init (&argc, &argv, NULL);
    1672                 :             : 
    1673                 :           1 :   g_test_add_func ("/param/value", test_param_value);
    1674                 :           1 :   g_test_add_func ("/param/strings", test_param_strings);
    1675                 :           1 :   g_test_add_data_func ("/param/invalid-name/colon", "my_int:hello", test_param_invalid_name);
    1676                 :           1 :   g_test_add_data_func ("/param/invalid-name/first-char", "7zip", test_param_invalid_name);
    1677                 :           1 :   g_test_add_data_func ("/param/invalid-name/empty", "", test_param_invalid_name);
    1678                 :           1 :   g_test_add_func ("/param/qdata", test_param_qdata);
    1679                 :           1 :   g_test_add_func ("/param/validate", test_param_validate);
    1680                 :           1 :   g_test_add_func ("/param/convert", test_param_convert);
    1681                 :             : 
    1682                 :           1 :   g_test_add_func ("/param/implement", test_param_implement);
    1683                 :             : 
    1684                 :          17 :   for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++)
    1685                 :          64 :     for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++)
    1686                 :         816 :       for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++)
    1687                 :        3840 :         for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++)
    1688                 :             :           {
    1689                 :        3072 :             test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
    1690                 :             :                                          data.change_this_flag, data.change_this_type,
    1691                 :             :                                          data.use_this_flag, data.use_this_type);
    1692                 :        3072 :             test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
    1693                 :        3072 :             g_test_add_data_func_full (test_path, g_steal_pointer (&test_data), test_param_implement_child, g_free);
    1694                 :        3072 :             g_free (test_path);
    1695                 :             :           }
    1696                 :             : 
    1697                 :           1 :   g_test_add_func ("/value/transform", test_value_transform);
    1698                 :           1 :   g_test_add_func ("/param/default", test_param_default);
    1699                 :           1 :   g_test_add_func ("/param/is-valid-name", test_param_is_valid_name);
    1700                 :           1 :   g_test_add_func ("/paramspec/char", test_param_spec_char);
    1701                 :           1 :   g_test_add_func ("/paramspec/uchar", test_param_spec_uchar);
    1702                 :           1 :   g_test_add_func ("/paramspec/int", test_param_spec_int);
    1703                 :           1 :   g_test_add_func ("/paramspec/uint", test_param_spec_uint);
    1704                 :           1 :   g_test_add_func ("/paramspec/long", test_param_spec_long);
    1705                 :           1 :   g_test_add_func ("/paramspec/ulong", test_param_spec_ulong);
    1706                 :           1 :   g_test_add_func ("/paramspec/int64", test_param_spec_int64);
    1707                 :           1 :   g_test_add_func ("/paramspec/uint64", test_param_spec_uint64);
    1708                 :           1 :   g_test_add_func ("/paramspec/float", test_param_spec_float);
    1709                 :           1 :   g_test_add_func ("/paramspec/double", test_param_spec_double);
    1710                 :           1 :   g_test_add_func ("/paramspec/unichar", test_param_spec_unichar);
    1711                 :           1 :   g_test_add_func ("/paramspec/param", test_param_spec_param);
    1712                 :           1 :   g_test_add_func ("/paramspec/null-param", test_param_spec_null_param);
    1713                 :           1 :   g_test_add_func ("/paramspec/string", test_param_spec_string);
    1714                 :           1 :   g_test_add_func ("/paramspec/override", test_param_spec_override);
    1715                 :           1 :   g_test_add_func ("/paramspec/gtype", test_param_spec_gtype);
    1716                 :           1 :   g_test_add_func ("/paramspec/variant", test_param_spec_variant);
    1717                 :           1 :   g_test_add_func ("/paramspec/variant/cmp", test_param_spec_variant_cmp);
    1718                 :           1 :   g_test_add_func ("/paramspec/custom", test_param_spec_custom);
    1719                 :           1 :   g_test_add_func ("/paramspec/pool", test_param_spec_pool);
    1720                 :             : 
    1721                 :           1 :   return g_test_run ();
    1722                 :             : }
        

Generated by: LCOV version 2.0-1