2022-01-12 22:19:24 +01:00
|
|
|
|
/* GLIB - Library of useful routines for C programming
|
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
|
|
|
*
|
2022-06-01 13:17:28 +02:00
|
|
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
*
|
2022-01-12 22:19:24 +01:00
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
|
|
|
|
* file for a list of people on the GLib Team. See the ChangeLog
|
|
|
|
|
* files for a list of changes. These files are distributed with
|
|
|
|
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
|
|
|
|
*/
|
|
|
|
|
|
2020-07-27 16:40:13 +02:00
|
|
|
|
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
|
2011-10-12 06:37:02 +02:00
|
|
|
|
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
2020-07-27 16:40:13 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
#include <glib-object.h>
|
2011-12-21 00:44:48 +01:00
|
|
|
|
#include <stdlib.h>
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
2022-01-12 22:19:24 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_spec_char (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_char ("char", "nick", "blurb",
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char");
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick");
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb");
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_CHAR);
|
|
|
|
|
g_value_set_char (&value, 30);
|
|
|
|
|
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 0);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 20);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 40);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 60);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_value_set_schar (&value, 0);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_schar (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_schar (&value, 20);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_schar (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_schar (&value, 40);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_schar (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_value_set_schar (&value, 60);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_schar (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 14:16:30 +02:00
|
|
|
|
static void
|
|
|
|
|
test_param_spec_uchar (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_uchar ("char", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "char");
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_UCHAR);
|
|
|
|
|
|
|
|
|
|
g_value_set_uchar (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_uchar (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_uchar (&value, 20);
|
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_uchar (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_int (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_int ("int", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_INT);
|
|
|
|
|
g_assert_cmpint (g_value_get_int (&value), ==, 30);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_int (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_int (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_uint (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_uint ("uint", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_UINT);
|
|
|
|
|
g_assert_cmpint (g_value_get_uint (&value), ==, 30);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_uint (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_uint (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_long (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_long ("long", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_LONG);
|
|
|
|
|
g_assert_cmpint (g_value_get_long (&value), ==, 30);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_long (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_long (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_ulong (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_ulong ("ulong", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_ULONG);
|
|
|
|
|
g_assert_cmpint (g_value_get_ulong (&value), ==, 30);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_ulong (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_ulong (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_int64 (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_int64 ("int64", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_INT64);
|
|
|
|
|
g_assert_cmpint (g_value_get_int64 (&value), ==, 30);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_int64 (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_int64 (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_uint64 (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_uint64 ("uint64", NULL, NULL,
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_UINT64);
|
|
|
|
|
g_assert_cmpint (g_value_get_uint64 (&value), ==, 30);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_uint64 (&value, 0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_uint64 (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_float (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_float ("float", NULL, NULL,
|
|
|
|
|
20.0, 40.0, 30.0, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_FLOAT);
|
|
|
|
|
g_assert_cmpfloat (g_value_get_float (&value), ==, 30.0);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_float (&value, 0.0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_float (&value), ==, 20.0);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_double (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_double ("double", NULL, NULL,
|
|
|
|
|
20.0, 40.0, 30.0, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (pspec, &value);
|
|
|
|
|
g_assert_true (G_VALUE_TYPE (&value) == G_TYPE_DOUBLE);
|
|
|
|
|
g_assert_cmpfloat (g_value_get_double (&value), ==, 30.0);
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_double (&value, 0.0);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_double (&value), ==, 20.0);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_unichar (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_unichar ("unichar", NULL, NULL,
|
|
|
|
|
0x1F4A9, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "unichar");
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_UINT);
|
|
|
|
|
|
|
|
|
|
/* Unicode codepoints can’t be 0x110000 or above, as that’s not representable
|
|
|
|
|
* in UTF-16. */
|
|
|
|
|
g_value_set_uint (&value, 0x110000);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_uint (&value), ==, 0);
|
|
|
|
|
|
|
|
|
|
g_value_set_uint (&value, 0x20);
|
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_uint (&value), ==, 0x20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_param (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *wrapped_pspec_uint;
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
wrapped_pspec_uint = g_param_spec_uint ("uint", NULL, NULL,
|
|
|
|
|
0, G_MAXUINT, 5, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_param ("param", NULL, NULL,
|
|
|
|
|
G_TYPE_PARAM_UINT, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "param");
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_PARAM_UINT);
|
|
|
|
|
|
|
|
|
|
g_value_set_param (&value, wrapped_pspec_uint);
|
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_true (g_value_get_param (&value) == wrapped_pspec_uint);
|
|
|
|
|
|
|
|
|
|
g_value_unset (&value);
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
g_param_spec_unref (wrapped_pspec_uint);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-10 20:55:24 +02:00
|
|
|
|
static void
|
|
|
|
|
test_param_spec_null_param (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_param ("param", NULL, NULL,
|
|
|
|
|
G_TYPE_PARAM_POINTER, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "param");
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_PARAM_POINTER);
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_unset (&value);
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-12 22:19:24 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_spec_string (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_string ("string", "nick", "blurb",
|
|
|
|
|
NULL, G_PARAM_READWRITE);
|
|
|
|
|
g_value_init (&value, G_TYPE_STRING);
|
|
|
|
|
|
|
|
|
|
g_value_set_string (&value, "foobar");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_string (&value, "");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_nonnull (g_value_get_string (&value));
|
|
|
|
|
|
|
|
|
|
/* test ensure_non_null */
|
|
|
|
|
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->ensure_non_null = TRUE;
|
|
|
|
|
|
|
|
|
|
g_value_set_string (&value, NULL);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_nonnull (g_value_get_string (&value));
|
|
|
|
|
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->ensure_non_null = FALSE;
|
|
|
|
|
|
|
|
|
|
/* test null_fold_if_empty */
|
|
|
|
|
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = TRUE;
|
|
|
|
|
|
|
|
|
|
g_value_set_string (&value, "");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_null (g_value_get_string (&value));
|
|
|
|
|
|
|
|
|
|
g_value_set_static_string (&value, "");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_null (g_value_get_string (&value));
|
|
|
|
|
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->null_fold_if_empty = FALSE;
|
|
|
|
|
|
|
|
|
|
/* test cset_first */
|
|
|
|
|
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->cset_first = g_strdup ("abc");
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->substitutor = '-';
|
|
|
|
|
|
|
|
|
|
g_value_set_string (&value, "ABC");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_string (&value)[0], ==, '-');
|
|
|
|
|
|
|
|
|
|
g_value_set_static_string (&value, "ABC");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_string (&value)[0], ==, '-');
|
|
|
|
|
|
|
|
|
|
/* test cset_nth */
|
|
|
|
|
|
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->cset_nth = g_strdup ("abc");
|
|
|
|
|
|
|
|
|
|
g_value_set_string (&value, "aBC");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_string (&value)[1], ==, '-');
|
|
|
|
|
|
|
|
|
|
g_value_set_static_string (&value, "aBC");
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_string (&value)[1], ==, '-');
|
|
|
|
|
|
|
|
|
|
g_value_unset (&value);
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_override (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *ospec, *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
ospec = g_param_spec_char ("char", "nick", "blurb",
|
|
|
|
|
20, 40, 30, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_override ("override", ospec);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (pspec), ==, "override");
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_nick (pspec), ==, "nick");
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_blurb (pspec), ==, "blurb");
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_CHAR);
|
|
|
|
|
g_value_set_char (&value, 30);
|
|
|
|
|
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 0);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 20);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 40);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_value_set_char (&value, 60);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_char (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
g_param_spec_unref (ospec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_gtype (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_gtype ("gtype", "nick", "blurb",
|
|
|
|
|
G_TYPE_PARAM, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_GTYPE);
|
|
|
|
|
g_value_set_gtype (&value, G_TYPE_PARAM);
|
|
|
|
|
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
|
|
|
|
|
g_value_set_gtype (&value, G_TYPE_INT);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM);
|
|
|
|
|
|
|
|
|
|
g_value_set_gtype (&value, G_TYPE_PARAM_INT);
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_gtype (&value), ==, G_TYPE_PARAM_INT);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_variant (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
GValue value2 = G_VALUE_INIT;
|
|
|
|
|
GValue value3 = G_VALUE_INIT;
|
|
|
|
|
GValue value4 = G_VALUE_INIT;
|
|
|
|
|
GValue value5 = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_variant ("variant", "nick", "blurb",
|
|
|
|
|
G_VARIANT_TYPE ("i"),
|
|
|
|
|
g_variant_new_int32 (42),
|
|
|
|
|
G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&value, g_variant_new_int32 (42));
|
|
|
|
|
|
|
|
|
|
g_value_init (&value2, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&value2, g_variant_new_int32 (43));
|
|
|
|
|
|
|
|
|
|
g_value_init (&value3, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&value3, g_variant_new_int16 (42));
|
|
|
|
|
|
|
|
|
|
g_value_init (&value4, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&value4, g_variant_new_parsed ("[@u 15, @u 10]"));
|
|
|
|
|
|
|
|
|
|
g_value_init (&value5, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&value5, NULL);
|
|
|
|
|
|
|
|
|
|
g_assert_true (g_param_value_defaults (pspec, &value));
|
|
|
|
|
g_assert_false (g_param_value_defaults (pspec, &value2));
|
|
|
|
|
g_assert_false (g_param_value_defaults (pspec, &value3));
|
|
|
|
|
g_assert_false (g_param_value_defaults (pspec, &value4));
|
|
|
|
|
g_assert_false (g_param_value_defaults (pspec, &value5));
|
|
|
|
|
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_false (g_param_value_validate (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
|
|
|
|
|
g_value_reset (&value);
|
|
|
|
|
g_value_set_variant (&value, g_variant_new_uint32 (41));
|
2022-05-20 14:53:33 +02:00
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (pspec, &value));
|
|
|
|
|
g_assert_true (g_param_value_is_valid (pspec, &value));
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_assert_cmpint (g_variant_get_int32 (g_value_get_variant (&value)), ==, 42);
|
|
|
|
|
g_value_unset (&value);
|
|
|
|
|
|
|
|
|
|
g_value_unset (&value5);
|
|
|
|
|
g_value_unset (&value4);
|
|
|
|
|
g_value_unset (&value3);
|
|
|
|
|
g_value_unset (&value2);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Test g_param_values_cmp() for #GParamSpecVariant. */
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_variant_cmp (void)
|
|
|
|
|
{
|
|
|
|
|
const struct
|
|
|
|
|
{
|
|
|
|
|
const GVariantType *pspec_type;
|
|
|
|
|
const gchar *v1;
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
LESS_THAN = -1,
|
|
|
|
|
EQUAL = 0,
|
|
|
|
|
GREATER_THAN = 1,
|
|
|
|
|
NOT_EQUAL,
|
|
|
|
|
} expected_result;
|
|
|
|
|
const gchar *v2;
|
|
|
|
|
}
|
|
|
|
|
vectors[] =
|
|
|
|
|
{
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@i 1", LESS_THAN, "@i 2" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@i 2", EQUAL, "@i 2" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@i 3", GREATER_THAN, "@i 2" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), NULL, LESS_THAN, "@i 2" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), NULL, EQUAL, NULL },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@i 1", GREATER_THAN, NULL },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@u 1", LESS_THAN, "@u 2" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@u 2" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@as ['hi']", NOT_EQUAL, "@as ['there']" },
|
|
|
|
|
{ G_VARIANT_TYPE ("i"), "@as ['hi']", EQUAL, "@as ['hi']" },
|
|
|
|
|
};
|
|
|
|
|
gsize i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (vectors); i++)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue v1 = G_VALUE_INIT;
|
|
|
|
|
GValue v2 = G_VALUE_INIT;
|
|
|
|
|
gint cmp;
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_variant ("variant", "nick", "blurb",
|
|
|
|
|
vectors[i].pspec_type,
|
|
|
|
|
NULL,
|
|
|
|
|
G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_value_init (&v1, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&v1,
|
|
|
|
|
(vectors[i].v1 != NULL) ?
|
|
|
|
|
g_variant_new_parsed (vectors[i].v1) : NULL);
|
|
|
|
|
|
|
|
|
|
g_value_init (&v2, G_TYPE_VARIANT);
|
|
|
|
|
g_value_set_variant (&v2,
|
|
|
|
|
(vectors[i].v2 != NULL) ?
|
|
|
|
|
g_variant_new_parsed (vectors[i].v2) : NULL);
|
|
|
|
|
|
|
|
|
|
cmp = g_param_values_cmp (pspec, &v1, &v2);
|
|
|
|
|
|
|
|
|
|
switch (vectors[i].expected_result)
|
|
|
|
|
{
|
|
|
|
|
case LESS_THAN:
|
|
|
|
|
case EQUAL:
|
|
|
|
|
case GREATER_THAN:
|
|
|
|
|
g_assert_cmpint (cmp, ==, vectors[i].expected_result);
|
|
|
|
|
break;
|
|
|
|
|
case NOT_EQUAL:
|
|
|
|
|
g_assert_cmpint (cmp, !=, 0);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_value_unset (&v2);
|
|
|
|
|
g_value_unset (&v1);
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_value (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *p, *p2;
|
2011-02-15 01:15:41 +01:00
|
|
|
|
GParamSpec *pp;
|
2011-09-30 18:19:50 +02:00
|
|
|
|
GValue value = G_VALUE_INIT;
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_PARAM);
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (G_VALUE_HOLDS_PARAM (&value));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_value_take_param (&value, p);
|
|
|
|
|
p2 = g_value_get_param (&value);
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (p2 == p);
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
2011-02-15 01:15:41 +01:00
|
|
|
|
pp = g_param_spec_uint ("my-uint", "My UInt", "Blurb", 0, 10, 5, G_PARAM_READWRITE);
|
|
|
|
|
g_value_set_param (&value, pp);
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
p2 = g_value_dup_param (&value);
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (p2 == pp); /* param specs use ref/unref for copy/free */
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_param_spec_unref (p2);
|
|
|
|
|
|
|
|
|
|
g_value_unset (&value);
|
2011-12-13 20:01:42 +01:00
|
|
|
|
g_param_spec_unref (pp);
|
2011-02-14 05:47:42 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gint destroy_count;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
my_destroy (gpointer data)
|
|
|
|
|
{
|
|
|
|
|
destroy_count++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_qdata (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *p;
|
|
|
|
|
gchar *bla;
|
|
|
|
|
GQuark q;
|
|
|
|
|
|
|
|
|
|
q = g_quark_from_string ("bla");
|
|
|
|
|
|
|
|
|
|
p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
g_param_spec_set_qdata (p, q, "bla");
|
|
|
|
|
bla = g_param_spec_get_qdata (p, q);
|
|
|
|
|
g_assert_cmpstr (bla, ==, "bla");
|
|
|
|
|
|
|
|
|
|
g_assert_cmpint (destroy_count, ==, 0);
|
|
|
|
|
g_param_spec_set_qdata_full (p, q, "bla", my_destroy);
|
|
|
|
|
g_param_spec_set_qdata_full (p, q, "blabla", my_destroy);
|
|
|
|
|
g_assert_cmpint (destroy_count, ==, 1);
|
|
|
|
|
g_assert_cmpstr (g_param_spec_steal_qdata (p, q), ==, "blabla");
|
|
|
|
|
g_assert_cmpint (destroy_count, ==, 1);
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_null (g_param_spec_get_qdata (p, q));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
g_param_spec_ref_sink (p);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_validate (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *p;
|
2011-09-30 18:19:50 +02:00
|
|
|
|
GValue value = G_VALUE_INIT;
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_INT);
|
|
|
|
|
g_value_set_int (&value, 100);
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_false (g_param_value_defaults (p, &value));
|
|
|
|
|
g_assert_true (g_param_value_validate (p, &value));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_int (&value), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_value_set_default (p, &value);
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_param_value_defaults (p, &value));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_int (&value), ==, 10);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_strings (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *p;
|
|
|
|
|
|
|
|
|
|
/* test canonicalization */
|
2019-11-12 19:30:47 +01:00
|
|
|
|
p = g_param_spec_int ("my_int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
2019-11-12 19:30:47 +01:00
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpstr (g_param_spec_get_nick (p), ==, "My Int");
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_blurb (p), ==, "Blurb");
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (p);
|
|
|
|
|
|
|
|
|
|
/* test nick defaults to name */
|
|
|
|
|
p = g_param_spec_int ("my-int", NULL, NULL, 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_name (p), ==, "my-int");
|
|
|
|
|
g_assert_cmpstr (g_param_spec_get_nick (p), ==, "my-int");
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_null (g_param_spec_get_blurb (p));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
g_param_spec_unref (p);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-12 20:34:05 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_invalid_name (gconstpointer test_data)
|
|
|
|
|
{
|
|
|
|
|
const gchar *invalid_name = test_data;
|
|
|
|
|
|
|
|
|
|
g_test_summary ("Test that properties cannot be created with invalid names");
|
|
|
|
|
|
|
|
|
|
if (g_test_subprocess ())
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *p;
|
|
|
|
|
p = g_param_spec_int (invalid_name, "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
g_param_spec_unref (p);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-31 15:30:43 +02:00
|
|
|
|
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
|
2019-11-12 20:34:05 +01:00
|
|
|
|
g_test_trap_assert_failed ();
|
2019-12-23 18:36:21 +01:00
|
|
|
|
g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*");
|
2019-11-12 20:34:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_convert (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *p;
|
2011-09-30 18:19:50 +02:00
|
|
|
|
GValue v1 = G_VALUE_INIT;
|
|
|
|
|
GValue v2 = G_VALUE_INIT;
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
p = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
g_value_init (&v1, G_TYPE_UINT);
|
|
|
|
|
g_value_set_uint (&v1, 43);
|
|
|
|
|
|
|
|
|
|
g_value_init (&v2, G_TYPE_INT);
|
|
|
|
|
g_value_set_int (&v2, -4);
|
|
|
|
|
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_false (g_param_value_convert (p, &v1, &v2, TRUE));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_int (&v2), ==, -4);
|
|
|
|
|
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_param_value_convert (p, &v1, &v2, FALSE));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_int (&v2), ==, 20);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_value_transform (void)
|
|
|
|
|
{
|
2011-09-30 18:19:50 +02:00
|
|
|
|
GValue src = G_VALUE_INIT;
|
|
|
|
|
GValue dest = G_VALUE_INIT;
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
#define CHECK_INT_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_INT, type)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_value_init (&src, G_TYPE_INT); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_int (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-09-22 22:08:35 +02:00
|
|
|
|
/* Keep a check for an integer in the range of 0-127 so we're
|
|
|
|
|
* still testing g_value_get_char(). See
|
|
|
|
|
* https://bugzilla.gnome.org/show_bug.cgi?id=659870
|
|
|
|
|
* for why it is broken.
|
|
|
|
|
*/
|
2011-02-14 05:47:42 +01:00
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124)
|
2011-09-22 22:08:35 +02:00
|
|
|
|
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124)
|
2011-02-14 05:47:42 +01:00
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_INT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
2011-02-15 01:15:41 +01:00
|
|
|
|
#define CHECK_UINT_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_UINT, type)); \
|
2011-02-15 01:15:41 +01:00
|
|
|
|
g_value_init (&src, G_TYPE_UINT); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_uint (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \
|
2011-02-15 01:15:41 +01:00
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_CHAR, char, 124)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_LONG, long, 12345678)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_INT64, int64, 12345678)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_UINT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
2011-06-21 06:52:43 +02:00
|
|
|
|
#define CHECK_LONG_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_LONG, type)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_value_init (&src, G_TYPE_LONG); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_long (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-12-14 15:32:11 +01:00
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, -124)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, 124)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_LONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
|
|
|
|
#define CHECK_ULONG_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_ULONG, type)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_value_init (&src, G_TYPE_ULONG); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_ulong (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-07-11 03:57:45 +02:00
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_UINT, uint, 12345)
|
2011-07-11 03:57:45 +02:00
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_LONG, long, 12345678)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
2011-07-11 03:57:45 +02:00
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_INT64, int64, 12345678)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_ULONG_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
|
|
|
|
#define CHECK_INT64_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_INT64, type)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_value_init (&src, G_TYPE_INT64); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_int64 (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-12-14 15:32:11 +01:00
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, -124)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, 124)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_INT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
|
|
|
|
#define CHECK_UINT64_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_UINT64, type)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_value_init (&src, G_TYPE_UINT64); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_uint64 (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-12-14 15:32:11 +01:00
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, -124)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, 124)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_UINT64_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
|
|
|
|
#define CHECK_FLOAT_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_FLOAT, type)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_value_init (&src, G_TYPE_FLOAT); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_float (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-12-14 15:32:11 +01:00
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, -124)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, 124)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_FLOAT_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
|
|
|
|
#define CHECK_DOUBLE_CONVERSION(type, getter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (G_TYPE_DOUBLE, type)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_value_init (&src, G_TYPE_DOUBLE); \
|
|
|
|
|
g_value_init (&dest, type); \
|
|
|
|
|
g_value_set_double (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-06-21 06:52:43 +02:00
|
|
|
|
g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
2011-12-14 15:32:11 +01:00
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, -124)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, 124)
|
2011-06-21 06:52:43 +02:00
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 0)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_UCHAR, uchar, 255)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_INT, int, 12345)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 0)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_FLOAT, float, 12345678)
|
|
|
|
|
CHECK_DOUBLE_CONVERSION(G_TYPE_DOUBLE, double, 12345678)
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
#define CHECK_BOOLEAN_CONVERSION(type, setter, value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (type, G_TYPE_BOOLEAN)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_value_init (&src, type); \
|
|
|
|
|
g_value_init (&dest, G_TYPE_BOOLEAN); \
|
|
|
|
|
g_value_set_##setter (&src, value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE); \
|
|
|
|
|
g_value_set_##setter (&src, 0); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpint (g_value_get_boolean (&dest), ==, FALSE); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
|
|
|
|
CHECK_BOOLEAN_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_BOOLEAN_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_BOOLEAN_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_BOOLEAN_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_BOOLEAN_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
|
|
|
|
|
#define CHECK_STRING_CONVERSION(int_type, setter, int_value) \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_type_transformable (int_type, G_TYPE_STRING)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_value_init (&src, int_type); \
|
|
|
|
|
g_value_init (&dest, G_TYPE_STRING); \
|
|
|
|
|
g_value_set_##setter (&src, int_value); \
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (g_value_transform (&src, &dest)); \
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_assert_cmpstr (g_value_get_string (&dest), ==, #int_value); \
|
|
|
|
|
g_value_unset (&src); \
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_INT, int, -12345)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_UINT, uint, 12345)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_LONG, long, -12345678)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_ULONG, ulong, 12345678)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_INT64, int64, -12345678)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_UINT64, uint64, 12345678)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_FLOAT, float, 0.500000)
|
|
|
|
|
CHECK_STRING_CONVERSION(G_TYPE_DOUBLE, double, -1.234567)
|
|
|
|
|
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_false (g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR));
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_value_init (&src, G_TYPE_STRING);
|
|
|
|
|
g_value_init (&dest, G_TYPE_CHAR);
|
|
|
|
|
g_value_set_static_string (&src, "bla");
|
2011-09-22 22:08:35 +02:00
|
|
|
|
g_value_set_schar (&dest, 'c');
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_false (g_value_transform (&src, &dest));
|
2011-09-22 22:08:35 +02:00
|
|
|
|
g_assert_cmpint (g_value_get_schar (&dest), ==, 'c');
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_value_unset (&src);
|
|
|
|
|
g_value_unset (&dest);
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-21 00:44:48 +01:00
|
|
|
|
|
|
|
|
|
/* We create some dummy objects with a simple relationship:
|
|
|
|
|
*
|
|
|
|
|
* GObject
|
|
|
|
|
* / \
|
|
|
|
|
* TestObjectA TestObjectC
|
|
|
|
|
* |
|
|
|
|
|
* TestObjectB
|
|
|
|
|
*
|
|
|
|
|
* ie: TestObjectB is a subclass of TestObjectA and TestObjectC is
|
|
|
|
|
* related to neither.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static GType test_object_a_get_type (void);
|
|
|
|
|
typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
|
2014-10-17 12:54:02 +02:00
|
|
|
|
G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
|
2011-12-21 00:44:48 +01:00
|
|
|
|
static void test_object_a_class_init (TestObjectAClass *class) { }
|
|
|
|
|
static void test_object_a_init (TestObjectA *a) { }
|
|
|
|
|
|
|
|
|
|
static GType test_object_b_get_type (void);
|
|
|
|
|
typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
|
2014-10-17 12:54:02 +02:00
|
|
|
|
G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ())
|
2011-12-21 00:44:48 +01:00
|
|
|
|
static void test_object_b_class_init (TestObjectBClass *class) { }
|
|
|
|
|
static void test_object_b_init (TestObjectB *b) { }
|
|
|
|
|
|
|
|
|
|
static GType test_object_c_get_type (void);
|
|
|
|
|
typedef GObject TestObjectC; typedef GObjectClass TestObjectCClass;
|
2014-10-17 12:54:02 +02:00
|
|
|
|
G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT)
|
2011-12-21 00:44:48 +01:00
|
|
|
|
static void test_object_c_class_init (TestObjectCClass *class) { }
|
|
|
|
|
static void test_object_c_init (TestObjectC *c) { }
|
|
|
|
|
|
|
|
|
|
/* We create an interface and programmatically populate it with
|
|
|
|
|
* properties of each of the above type, with various flag combinations.
|
|
|
|
|
*
|
|
|
|
|
* Properties are named like "type-perm" where type is 'a', 'b' or 'c'
|
|
|
|
|
* and perm is a series of characters, indicating the permissions:
|
|
|
|
|
*
|
|
|
|
|
* - 'r': readable
|
|
|
|
|
* - 'w': writable
|
|
|
|
|
* - 'c': construct
|
|
|
|
|
* - 'C': construct-only
|
|
|
|
|
*
|
|
|
|
|
* It doesn't make sense to have a property that is neither readable nor
|
|
|
|
|
* writable. It is also not valid to have construct or construct-only
|
|
|
|
|
* on read-only params. Finally, it is invalid to have both construct
|
|
|
|
|
* and construct-only specified, so we do not consider those cases.
|
|
|
|
|
* That gives us 7 possible permissions:
|
|
|
|
|
*
|
|
|
|
|
* 'r', 'w', 'rw', 'wc', 'rwc', 'wC', 'rwC'
|
|
|
|
|
*
|
|
|
|
|
* And 9 impossible ones:
|
|
|
|
|
*
|
|
|
|
|
* '', 'c', 'rc', 'C', 'rC', 'cC', 'rcC', 'wcC', rwcC'
|
|
|
|
|
*
|
|
|
|
|
* For a total of 16 combinations.
|
|
|
|
|
*
|
|
|
|
|
* That gives a total of 48 (16 * 3) possible flag/type combinations, of
|
|
|
|
|
* which 27 (9 * 3) are impossible to install.
|
|
|
|
|
*
|
|
|
|
|
* That gives 21 (7 * 3) properties that will be installed.
|
|
|
|
|
*/
|
|
|
|
|
typedef GTypeInterface TestInterfaceInterface;
|
2012-11-02 00:36:15 +01:00
|
|
|
|
static GType test_interface_get_type (void);
|
2011-12-21 00:44:48 +01:00
|
|
|
|
//typedef struct _TestInterface TestInterface;
|
|
|
|
|
G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
|
|
|
|
|
static void
|
|
|
|
|
test_interface_default_init (TestInterfaceInterface *iface)
|
|
|
|
|
{
|
|
|
|
|
const gchar *names[] = { "a", "b", "c" };
|
|
|
|
|
const gchar *perms[] = { NULL, "r", "w", "rw",
|
|
|
|
|
NULL, NULL, "wc", "rwc",
|
|
|
|
|
NULL, NULL, "wC", "rwC",
|
|
|
|
|
NULL, NULL, NULL, NULL };
|
|
|
|
|
const GType types[] = { test_object_a_get_type (), test_object_b_get_type (), test_object_c_get_type () };
|
|
|
|
|
guint i, j;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (types); i++)
|
|
|
|
|
for (j = 0; j < G_N_ELEMENTS (perms); j++)
|
|
|
|
|
{
|
|
|
|
|
gchar prop_name[10];
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
|
|
|
|
|
if (perms[j] == NULL)
|
|
|
|
|
{
|
2012-01-05 16:02:07 +01:00
|
|
|
|
if (!g_test_undefined ())
|
|
|
|
|
continue;
|
|
|
|
|
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* we think that this is impossible. make sure. */
|
2012-08-27 13:45:08 +02:00
|
|
|
|
pspec = g_param_spec_object ("xyz", "xyz", "xyz", types[i], j);
|
|
|
|
|
|
|
|
|
|
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
|
|
|
|
"*assertion*pspec->flags*failed*");
|
|
|
|
|
g_object_interface_install_property (iface, pspec);
|
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
|
|
2011-12-21 00:44:48 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* install the property */
|
|
|
|
|
g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
|
|
|
|
|
pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[i], j);
|
|
|
|
|
g_object_interface_install_property (iface, pspec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We now have 21 properties. Each property may be correctly
|
|
|
|
|
* implemented with the following types:
|
|
|
|
|
*
|
|
|
|
|
* Properties Valid Types Reason
|
|
|
|
|
*
|
|
|
|
|
* a-r a, b Read only can provide subclasses
|
|
|
|
|
* a-w, wc, wC a, GObject Write only can accept superclasses
|
|
|
|
|
* a-rw, rwc, rwC a Read-write must be exactly equal
|
|
|
|
|
*
|
|
|
|
|
* b-r b (as above)
|
|
|
|
|
* b-w, wc, wC b, a, GObject
|
|
|
|
|
* b-rw, rwc, rwC b
|
|
|
|
|
*
|
|
|
|
|
* c-r c (as above)
|
|
|
|
|
* c-wo, wc, wC c, GObject
|
|
|
|
|
* c-rw, rwc, rwC c
|
|
|
|
|
*
|
|
|
|
|
* We can express this in a 48-by-4 table where each row represents an
|
|
|
|
|
* installed property and each column represents a type. The value in
|
|
|
|
|
* the table represents if it is valid to subclass the row's property
|
|
|
|
|
* with the type of the column:
|
|
|
|
|
*
|
|
|
|
|
* - 0: invalid because the interface property doesn't exist (invalid flags)
|
|
|
|
|
* - 'v': valid
|
|
|
|
|
* - '=': invalid because of the type not being exactly equal
|
|
|
|
|
* - '<': invalid because of the type not being a subclass
|
|
|
|
|
* - '>': invalid because of the type not being a superclass
|
|
|
|
|
*
|
|
|
|
|
* We organise the table by interface property type ('a', 'b', 'c') then
|
|
|
|
|
* by interface property flags.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static gint valid_impl_types[48][4] = {
|
|
|
|
|
/* a b c GObject */
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'a-' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'a-r' */ { 'v', 'v', '<', '<' },
|
|
|
|
|
/* 'a-w' */ { 'v', '>', '>', 'v' },
|
|
|
|
|
/* 'a-rw' */ { 'v', '=', '=', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'a-c */ { 0, },
|
|
|
|
|
/* 'a-rc' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'a-wc' */ { 'v', '>', '>', 'v' },
|
|
|
|
|
/* 'a-rwc' */ { 'v', '=', '=', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'a-C */ { 0, },
|
|
|
|
|
/* 'a-rC' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'a-wC' */ { 'v', '>', '>', 'v' },
|
|
|
|
|
/* 'a-rwC' */ { 'v', '=', '=', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'a-cC */ { 0, },
|
|
|
|
|
/* 'a-rcC' */ { 0, },
|
|
|
|
|
/* 'a-wcC' */ { 0, },
|
|
|
|
|
/* 'a-rwcC' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'b-' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'b-r' */ { '<', 'v', '<', '<' },
|
|
|
|
|
/* 'b-w' */ { 'v', 'v', '>', 'v' },
|
|
|
|
|
/* 'b-rw' */ { '=', 'v', '=', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'b-c */ { 0, },
|
|
|
|
|
/* 'b-rc' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'b-wc' */ { 'v', 'v', '>', 'v' },
|
|
|
|
|
/* 'b-rwc' */ { '=', 'v', '=', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'b-C */ { 0, },
|
|
|
|
|
/* 'b-rC' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'b-wC' */ { 'v', 'v', '>', 'v' },
|
|
|
|
|
/* 'b-rwC' */ { '=', 'v', '=', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'b-cC */ { 0, },
|
|
|
|
|
/* 'b-rcC' */ { 0, },
|
|
|
|
|
/* 'b-wcC' */ { 0, },
|
|
|
|
|
/* 'b-rwcC' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'c-' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'c-r' */ { '<', '<', 'v', '<' },
|
|
|
|
|
/* 'c-w' */ { '>', '>', 'v', 'v' },
|
|
|
|
|
/* 'c-rw' */ { '=', '=', 'v', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'c-c */ { 0, },
|
|
|
|
|
/* 'c-rc' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'c-wc' */ { '>', '>', 'v', 'v' },
|
|
|
|
|
/* 'c-rwc' */ { '=', '=', 'v', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'c-C */ { 0, },
|
|
|
|
|
/* 'c-rC' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* 'c-wC' */ { '>', '>', 'v', 'v' },
|
|
|
|
|
/* 'c-rwC' */ { '=', '=', 'v', '=' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* 'c-cC */ { 0, },
|
|
|
|
|
/* 'c-rcC' */ { 0, },
|
|
|
|
|
/* 'c-wcC' */ { 0, },
|
|
|
|
|
/* 'c-rwcC' */ { 0, }
|
2011-12-21 00:44:48 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* We also try to change the flags. We must ensure that all
|
|
|
|
|
* implementations provide all functionality promised by the interface.
|
|
|
|
|
* We must therefore never remove readability or writability (but we can
|
2011-12-21 01:33:02 +01:00
|
|
|
|
* add them). Construct-only is a restrictions that applies to
|
|
|
|
|
* writability, so we can never add it unless writability was never
|
|
|
|
|
* present in the first place, in which case "writable at construct
|
|
|
|
|
* only" is still better than "not writable".
|
|
|
|
|
*
|
|
|
|
|
* The 'construct' flag is of interest only to the implementation. It
|
|
|
|
|
* may be changed at any time.
|
2011-12-21 00:44:48 +01:00
|
|
|
|
*
|
|
|
|
|
* Properties Valid Access Reason
|
|
|
|
|
*
|
|
|
|
|
* *-r r, rw, rwc, rwC Must keep readable, but can restrict newly-added writable
|
2011-12-21 01:33:02 +01:00
|
|
|
|
* *-w w, rw, rwc Must keep writable unrestricted
|
|
|
|
|
* *-rw rw, rwc Must not add any restrictions
|
|
|
|
|
* *-rwc rw, rwc Must not add any restrictions
|
|
|
|
|
* *-rwC rw, rwc, rwC Can remove 'construct-only' restriction
|
|
|
|
|
* *-wc rwc, rw, w, wc Can add readability
|
2011-12-21 00:44:48 +01:00
|
|
|
|
* *-wC rwC, rw, w, wC Can add readability or remove 'construct only' restriction
|
2011-12-21 01:33:02 +01:00
|
|
|
|
* rwc, wc
|
2011-12-21 00:44:48 +01:00
|
|
|
|
*
|
|
|
|
|
* We can represent this with a 16-by-16 table. The rows represent the
|
|
|
|
|
* flags of the property on the interface. The columns is the flags to
|
|
|
|
|
* try to use when overriding the property. The cell contents are:
|
|
|
|
|
*
|
|
|
|
|
* - 0: invalid because the interface property doesn't exist (invalid flags)
|
|
|
|
|
* - 'v': valid
|
|
|
|
|
* - 'i': invalid because the implementation flags are invalid
|
|
|
|
|
* - 'f': invalid because of the removal of functionality
|
2011-12-21 01:33:02 +01:00
|
|
|
|
* - 'r': invalid because of the addition of restrictions (ie: construct-only)
|
2011-12-21 00:44:48 +01:00
|
|
|
|
*
|
|
|
|
|
* We also ensure that removal of functionality is reported before
|
|
|
|
|
* addition of restrictions, since this is a more basic problem.
|
|
|
|
|
*/
|
|
|
|
|
static gint valid_impl_flags[16][16] = {
|
|
|
|
|
/* '' r w rw c rc wc rwc C rC wC rwC cC rcC wcC rwcC */
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* '*-' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* '*-r' */ { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
|
2011-12-21 01:33:02 +01:00
|
|
|
|
/* '*-w' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
|
|
|
|
|
/* '*-rw' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* '*-c */ { 0, },
|
|
|
|
|
/* '*-rc' */ { 0, },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* '*-wc' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'r', 'r', 'i', 'i', 'i', 'i' },
|
|
|
|
|
/* '*-rwc' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'r', 'i', 'i', 'i', 'i' },
|
2013-11-06 09:45:12 +01:00
|
|
|
|
/* '*-C */ { 0, },
|
|
|
|
|
/* '*-rC' */ { 0, },
|
2011-12-21 01:33:02 +01:00
|
|
|
|
/* '*-wC' */ { 'i', 'f', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'v', 'v', 'i', 'i', 'i', 'i' },
|
|
|
|
|
/* '*-rwC' */ { 'i', 'f', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' },
|
2011-12-21 00:44:48 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static guint change_this_flag;
|
|
|
|
|
static guint change_this_type;
|
|
|
|
|
static guint use_this_flag;
|
|
|
|
|
static guint use_this_type;
|
|
|
|
|
|
|
|
|
|
typedef GObjectClass TestImplementationClass;
|
|
|
|
|
typedef GObject TestImplementation;
|
|
|
|
|
|
|
|
|
|
static void test_implementation_init (TestImplementation *impl) { }
|
|
|
|
|
static void test_implementation_iface_init (TestInterfaceInterface *iface) { }
|
|
|
|
|
|
|
|
|
|
static GType test_implementation_get_type (void);
|
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (TestImplementation, test_implementation, G_TYPE_OBJECT,
|
|
|
|
|
G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_implementation_iface_init))
|
|
|
|
|
|
|
|
|
|
static void test_implementation_class_init (TestImplementationClass *class)
|
|
|
|
|
{
|
|
|
|
|
const gchar *names[] = { "a", "b", "c" };
|
|
|
|
|
const gchar *perms[] = { NULL, "r", "w", "rw",
|
|
|
|
|
NULL, NULL, "wc", "rwc",
|
|
|
|
|
NULL, NULL, "wC", "rwC",
|
|
|
|
|
NULL, NULL, NULL, NULL };
|
|
|
|
|
const GType types[] = { test_object_a_get_type (), test_object_b_get_type (),
|
|
|
|
|
test_object_c_get_type (), G_TYPE_OBJECT };
|
|
|
|
|
gchar prop_name[10];
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
guint i, j;
|
|
|
|
|
|
|
|
|
|
class->get_property = GINT_TO_POINTER (1);
|
|
|
|
|
class->set_property = GINT_TO_POINTER (1);
|
|
|
|
|
|
|
|
|
|
/* Install all of the non-modified properties or else GObject will
|
|
|
|
|
* complain about non-implemented properties.
|
|
|
|
|
*/
|
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
|
for (j = 0; j < G_N_ELEMENTS (perms); j++)
|
|
|
|
|
{
|
|
|
|
|
if (i == change_this_type && j == change_this_flag)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (perms[j] != NULL)
|
|
|
|
|
{
|
|
|
|
|
/* override the property without making changes */
|
|
|
|
|
g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[i], perms[j]);
|
|
|
|
|
g_object_class_override_property (class, 1, prop_name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now try installing our modified property */
|
|
|
|
|
if (perms[change_this_flag] == NULL)
|
|
|
|
|
g_error ("Interface property does not exist");
|
|
|
|
|
|
|
|
|
|
g_snprintf (prop_name, sizeof prop_name, "%s-%s", names[change_this_type], perms[change_this_flag]);
|
|
|
|
|
pspec = g_param_spec_object (prop_name, prop_name, prop_name, types[use_this_type], use_this_flag);
|
|
|
|
|
g_object_class_install_property (class, 1, pspec);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-24 21:58:36 +01:00
|
|
|
|
typedef struct {
|
|
|
|
|
gint change_this_flag;
|
|
|
|
|
gint change_this_type;
|
|
|
|
|
gint use_this_flag;
|
|
|
|
|
gint use_this_type;
|
|
|
|
|
} TestParamImplementData;
|
|
|
|
|
|
2011-12-21 00:44:48 +01:00
|
|
|
|
static void
|
2012-11-24 21:58:36 +01:00
|
|
|
|
test_param_implement_child (gconstpointer user_data)
|
2011-12-21 00:44:48 +01:00
|
|
|
|
{
|
2012-11-24 21:58:36 +01:00
|
|
|
|
TestParamImplementData *data = (gpointer) user_data;
|
|
|
|
|
|
2011-12-21 00:44:48 +01:00
|
|
|
|
/* GObject oddity: GObjectClass must be initialised before we can
|
|
|
|
|
* initialise a GTypeInterface.
|
|
|
|
|
*/
|
|
|
|
|
g_type_class_ref (G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
/* Bring up the interface first. */
|
|
|
|
|
g_type_default_interface_ref (test_interface_get_type ());
|
|
|
|
|
|
2012-11-24 21:58:36 +01:00
|
|
|
|
/* Copy the flags into the global vars so
|
|
|
|
|
* test_implementation_class_init() will see them.
|
|
|
|
|
*/
|
|
|
|
|
change_this_flag = data->change_this_flag;
|
|
|
|
|
change_this_type = data->change_this_type;
|
|
|
|
|
use_this_flag = data->use_this_flag;
|
|
|
|
|
use_this_type = data->use_this_type;
|
|
|
|
|
|
|
|
|
|
g_type_class_ref (test_implementation_get_type ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_implement (void)
|
|
|
|
|
{
|
|
|
|
|
gchar *test_path;
|
|
|
|
|
|
2024-02-06 12:01:46 +01:00
|
|
|
|
/* This test is slow. */
|
|
|
|
|
if (!g_test_slow ())
|
|
|
|
|
{
|
|
|
|
|
g_test_skip ("Skipping slow /param/implement test");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-21 00:44:48 +01:00
|
|
|
|
for (change_this_flag = 0; change_this_flag < 16; change_this_flag++)
|
|
|
|
|
for (change_this_type = 0; change_this_type < 3; change_this_type++)
|
|
|
|
|
for (use_this_flag = 0; use_this_flag < 16; use_this_flag++)
|
|
|
|
|
for (use_this_type = 0; use_this_type < 4; use_this_type++)
|
|
|
|
|
{
|
2012-01-05 16:02:07 +01:00
|
|
|
|
if (!g_test_undefined ())
|
|
|
|
|
{
|
|
|
|
|
/* only test the valid (defined) cases, e.g. under valgrind */
|
|
|
|
|
if (valid_impl_flags[change_this_flag][use_this_flag] != 'v')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type] != 'v')
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-24 21:58:36 +01:00
|
|
|
|
test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
|
|
|
|
|
change_this_flag, change_this_type,
|
|
|
|
|
use_this_flag, use_this_type);
|
2022-03-31 15:30:43 +02:00
|
|
|
|
g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND,
|
|
|
|
|
G_TEST_SUBPROCESS_DEFAULT);
|
2012-11-24 21:58:36 +01:00
|
|
|
|
g_free (test_path);
|
2011-12-21 00:44:48 +01:00
|
|
|
|
|
|
|
|
|
/* We want to ensure that any flags mismatch problems are reported first. */
|
|
|
|
|
switch (valid_impl_flags[change_this_flag][use_this_flag])
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
/* make sure the other table agrees */
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_cmpint (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type], ==, 0);
|
2011-12-21 00:44:48 +01:00
|
|
|
|
g_test_trap_assert_failed ();
|
|
|
|
|
g_test_trap_assert_stderr ("*Interface property does not exist*");
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case 'i':
|
|
|
|
|
g_test_trap_assert_failed ();
|
2024-01-18 17:53:36 +01:00
|
|
|
|
g_test_trap_assert_stderr ("*pspec->flags*");
|
2011-12-21 00:44:48 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case 'f':
|
|
|
|
|
g_test_trap_assert_failed ();
|
|
|
|
|
g_test_trap_assert_stderr ("*remove functionality*");
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case 'r':
|
|
|
|
|
g_test_trap_assert_failed ();
|
|
|
|
|
g_test_trap_assert_stderr ("*introduce additional restrictions*");
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case 'v':
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Next, we check if there should have been a type error. */
|
|
|
|
|
switch (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type])
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
/* this should have been caught above */
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
|
|
|
|
|
case '=':
|
|
|
|
|
g_test_trap_assert_failed ();
|
|
|
|
|
g_test_trap_assert_stderr ("*exactly equal*");
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case '<':
|
|
|
|
|
g_test_trap_assert_failed ();
|
|
|
|
|
g_test_trap_assert_stderr ("*equal to or more restrictive*");
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case '>':
|
|
|
|
|
g_test_trap_assert_failed ();
|
|
|
|
|
g_test_trap_assert_stderr ("*equal to or less restrictive*");
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case 'v':
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_test_trap_assert_passed ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-23 17:11:20 +02:00
|
|
|
|
static void
|
|
|
|
|
test_param_default (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *param;
|
|
|
|
|
const GValue *def;
|
|
|
|
|
|
|
|
|
|
param = g_param_spec_int ("my-int", "My Int", "Blurb", 0, 20, 10, G_PARAM_READWRITE);
|
|
|
|
|
def = g_param_spec_get_default_value (param);
|
|
|
|
|
|
2019-11-12 19:34:50 +01:00
|
|
|
|
g_assert_true (G_VALUE_HOLDS (def, G_TYPE_INT));
|
2013-04-23 17:11:20 +02:00
|
|
|
|
g_assert_cmpint (g_value_get_int (def), ==, 10);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (param);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-23 18:36:21 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_is_valid_name (void)
|
|
|
|
|
{
|
|
|
|
|
const gchar *valid_names[] =
|
|
|
|
|
{
|
|
|
|
|
"property",
|
|
|
|
|
"i",
|
|
|
|
|
"multiple-segments",
|
|
|
|
|
"segment0-SEGMENT1",
|
|
|
|
|
"using_underscores",
|
|
|
|
|
};
|
|
|
|
|
const gchar *invalid_names[] =
|
|
|
|
|
{
|
|
|
|
|
"",
|
|
|
|
|
"7zip",
|
|
|
|
|
"my_int:hello",
|
|
|
|
|
};
|
|
|
|
|
gsize i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (valid_names); i++)
|
|
|
|
|
g_assert_true (g_param_spec_is_valid_name (valid_names[i]));
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (invalid_names); i++)
|
|
|
|
|
g_assert_false (g_param_spec_is_valid_name (invalid_names[i]));
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 14:34:38 +02:00
|
|
|
|
static void
|
|
|
|
|
param_int_init (GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
GParamSpecInt *ispec = (GParamSpecInt *)pspec;
|
|
|
|
|
|
|
|
|
|
ispec->minimum = 0x7fffffff;
|
|
|
|
|
ispec->maximum = 0x80000000;
|
|
|
|
|
ispec->default_value = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
param_int_set_default (GParamSpec *pspec,
|
|
|
|
|
GValue *value)
|
|
|
|
|
{
|
|
|
|
|
value->data[0].v_int = ((GParamSpecInt *)pspec)->default_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
param_int_validate (GParamSpec *pspec,
|
|
|
|
|
GValue *value)
|
|
|
|
|
{
|
|
|
|
|
GParamSpecInt *ispec = (GParamSpecInt *)pspec;
|
|
|
|
|
int oval = value->data[0].v_int;
|
|
|
|
|
|
|
|
|
|
value->data[0].v_int = CLAMP (value->data[0].v_int, ispec->minimum, ispec->maximum);
|
|
|
|
|
|
|
|
|
|
return value->data[0].v_int != oval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
param_int_values_cmp (GParamSpec *pspec,
|
|
|
|
|
const GValue *value1,
|
|
|
|
|
const GValue *value2)
|
|
|
|
|
{
|
|
|
|
|
if (value1->data[0].v_int < value2->data[0].v_int)
|
|
|
|
|
return -1;
|
|
|
|
|
else
|
|
|
|
|
return value1->data[0].v_int > value2->data[0].v_int;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GType custom_type;
|
|
|
|
|
|
|
|
|
|
/* Register a pspec that has a validate vfunc, but not
|
|
|
|
|
* value_is_valid, to test the fallback in g_param_value_is_valid
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
register_custom_pspec (void)
|
|
|
|
|
{
|
|
|
|
|
const GParamSpecTypeInfo pspec_info = {
|
|
|
|
|
sizeof (GParamSpecInt), /* instance_size */
|
|
|
|
|
16, /* n_preallocs */
|
|
|
|
|
param_int_init, /* instance_init */
|
|
|
|
|
G_TYPE_INT, /* value_type */
|
|
|
|
|
NULL, /* finalize */
|
|
|
|
|
param_int_set_default, /* value_set_default */
|
|
|
|
|
param_int_validate, /* value_validate */
|
|
|
|
|
param_int_values_cmp, /* values_cmp */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
custom_type = g_param_type_register_static ("GParamInt2", &pspec_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GParamSpec *
|
|
|
|
|
g_param_spec_custom (const char *name,
|
|
|
|
|
int minimum,
|
|
|
|
|
int maximum,
|
|
|
|
|
int default_value,
|
|
|
|
|
GParamFlags flags)
|
|
|
|
|
{
|
|
|
|
|
GParamSpecInt *ispec;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (default_value >= minimum && default_value <= maximum, NULL);
|
|
|
|
|
|
|
|
|
|
ispec = g_param_spec_internal (custom_type, name, NULL, NULL, flags);
|
|
|
|
|
if (ispec == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
ispec->minimum = minimum;
|
|
|
|
|
ispec->maximum = maximum;
|
|
|
|
|
ispec->default_value = default_value;
|
|
|
|
|
|
|
|
|
|
return G_PARAM_SPEC (ispec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_param_spec_custom (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpec *pspec;
|
|
|
|
|
GValue value = G_VALUE_INIT;
|
|
|
|
|
|
|
|
|
|
register_custom_pspec ();
|
|
|
|
|
|
|
|
|
|
pspec = g_param_spec_custom ("myint", 10, 30, 20, G_PARAM_READWRITE);
|
|
|
|
|
|
|
|
|
|
g_value_init (&value, G_TYPE_INT);
|
|
|
|
|
|
|
|
|
|
g_value_set_int (&value, 40);
|
|
|
|
|
|
|
|
|
|
g_assert_false (g_param_value_is_valid (pspec, &value));
|
|
|
|
|
g_assert_cmpint (g_value_get_int (&value), ==, 40);
|
|
|
|
|
|
|
|
|
|
g_param_spec_unref (pspec);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-19 20:22:18 +01:00
|
|
|
|
static void
|
|
|
|
|
test_param_spec_pool (void)
|
|
|
|
|
{
|
|
|
|
|
GParamSpecPool *pool = g_param_spec_pool_new (FALSE);
|
2024-01-03 13:04:16 +01:00
|
|
|
|
GParamSpec *pspec = g_param_spec_ref_sink (g_param_spec_int ("int", NULL, NULL, -1, 100, -1, G_PARAM_READWRITE));
|
2023-12-19 20:22:18 +01:00
|
|
|
|
GParamSpec *check = NULL;
|
|
|
|
|
|
2024-01-03 13:04:16 +01:00
|
|
|
|
g_param_spec_pool_insert (pool, pspec, G_TYPE_OBJECT);
|
2023-12-19 20:22:18 +01:00
|
|
|
|
check = g_param_spec_pool_lookup (pool, "int", G_TYPE_OBJECT, FALSE);
|
|
|
|
|
g_assert_true (check->owner_type == G_TYPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
g_param_spec_pool_remove (pool, pspec);
|
|
|
|
|
g_assert_null (g_param_spec_pool_lookup (pool, "int", G_TYPE_OBJECT, FALSE));
|
|
|
|
|
|
|
|
|
|
g_param_spec_pool_free (pool);
|
2024-01-03 13:04:16 +01:00
|
|
|
|
g_param_spec_unref (pspec);
|
2023-12-19 20:22:18 +01:00
|
|
|
|
}
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
int
|
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
|
{
|
2012-11-24 21:58:36 +01:00
|
|
|
|
TestParamImplementData data, *test_data;
|
|
|
|
|
gchar *test_path;
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
|
|
|
|
|
|
g_test_add_func ("/param/value", test_param_value);
|
|
|
|
|
g_test_add_func ("/param/strings", test_param_strings);
|
2019-11-12 20:34:05 +01:00
|
|
|
|
g_test_add_data_func ("/param/invalid-name/colon", "my_int:hello", test_param_invalid_name);
|
|
|
|
|
g_test_add_data_func ("/param/invalid-name/first-char", "7zip", test_param_invalid_name);
|
|
|
|
|
g_test_add_data_func ("/param/invalid-name/empty", "", test_param_invalid_name);
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_test_add_func ("/param/qdata", test_param_qdata);
|
|
|
|
|
g_test_add_func ("/param/validate", test_param_validate);
|
|
|
|
|
g_test_add_func ("/param/convert", test_param_convert);
|
2012-11-24 21:58:36 +01:00
|
|
|
|
|
2024-02-06 12:01:46 +01:00
|
|
|
|
g_test_add_func ("/param/implement", test_param_implement);
|
2013-11-27 16:13:10 +01:00
|
|
|
|
|
2012-11-24 21:58:36 +01:00
|
|
|
|
for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++)
|
|
|
|
|
for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++)
|
|
|
|
|
for (data.use_this_flag = 0; data.use_this_flag < 16; data.use_this_flag++)
|
|
|
|
|
for (data.use_this_type = 0; data.use_this_type < 4; data.use_this_type++)
|
|
|
|
|
{
|
|
|
|
|
test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
|
|
|
|
|
data.change_this_flag, data.change_this_type,
|
|
|
|
|
data.use_this_flag, data.use_this_type);
|
2021-02-04 14:39:25 +01:00
|
|
|
|
test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
|
2024-01-18 17:54:01 +01:00
|
|
|
|
g_test_add_data_func_full (test_path, g_steal_pointer (&test_data), test_param_implement_child, g_free);
|
2012-11-24 21:58:36 +01:00
|
|
|
|
g_free (test_path);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-14 05:47:42 +01:00
|
|
|
|
g_test_add_func ("/value/transform", test_value_transform);
|
2013-04-23 17:11:20 +02:00
|
|
|
|
g_test_add_func ("/param/default", test_param_default);
|
2019-12-23 18:36:21 +01:00
|
|
|
|
g_test_add_func ("/param/is-valid-name", test_param_is_valid_name);
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_test_add_func ("/paramspec/char", test_param_spec_char);
|
2022-05-23 14:16:30 +02:00
|
|
|
|
g_test_add_func ("/paramspec/uchar", test_param_spec_uchar);
|
|
|
|
|
g_test_add_func ("/paramspec/int", test_param_spec_int);
|
|
|
|
|
g_test_add_func ("/paramspec/uint", test_param_spec_uint);
|
|
|
|
|
g_test_add_func ("/paramspec/long", test_param_spec_long);
|
|
|
|
|
g_test_add_func ("/paramspec/ulong", test_param_spec_ulong);
|
|
|
|
|
g_test_add_func ("/paramspec/int64", test_param_spec_int64);
|
|
|
|
|
g_test_add_func ("/paramspec/uint64", test_param_spec_uint64);
|
|
|
|
|
g_test_add_func ("/paramspec/float", test_param_spec_float);
|
|
|
|
|
g_test_add_func ("/paramspec/double", test_param_spec_double);
|
|
|
|
|
g_test_add_func ("/paramspec/unichar", test_param_spec_unichar);
|
|
|
|
|
g_test_add_func ("/paramspec/param", test_param_spec_param);
|
2022-10-10 20:55:24 +02:00
|
|
|
|
g_test_add_func ("/paramspec/null-param", test_param_spec_null_param);
|
2022-01-12 22:19:24 +01:00
|
|
|
|
g_test_add_func ("/paramspec/string", test_param_spec_string);
|
|
|
|
|
g_test_add_func ("/paramspec/override", test_param_spec_override);
|
|
|
|
|
g_test_add_func ("/paramspec/gtype", test_param_spec_gtype);
|
|
|
|
|
g_test_add_func ("/paramspec/variant", test_param_spec_variant);
|
|
|
|
|
g_test_add_func ("/paramspec/variant/cmp", test_param_spec_variant_cmp);
|
2022-05-22 14:34:38 +02:00
|
|
|
|
g_test_add_func ("/paramspec/custom", test_param_spec_custom);
|
2023-12-19 20:22:18 +01:00
|
|
|
|
g_test_add_func ("/paramspec/pool", test_param_spec_pool);
|
2011-02-14 05:47:42 +01:00
|
|
|
|
|
|
|
|
|
return g_test_run ();
|
|
|
|
|
}
|