| /* GLIB - Library of useful routines for C programming | |
| * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald | |
| * | |
| * SPDX-License-Identifier: LGPL-2.1-or-later | |
| * | |
| * 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/. | |
| */ | |
| #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS | |
| #define GLIB_DISABLE_DEPRECATION_WARNINGS | |
| #endif | |
| #include <glib-object.h> | |
| #include <stdlib.h> | |
| 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); | |
| 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_char (&value), ==, 20); | |
| g_value_set_char (&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_char (&value), ==, 20); | |
| g_value_set_char (&value, 40); | |
| 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_char (&value), ==, 40); | |
| g_value_set_char (&value, 60); | |
| 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_char (&value), ==, 40); | |
| g_value_set_schar (&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_schar (&value), ==, 20); | |
| g_value_set_schar (&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_schar (&value), ==, 20); | |
| g_value_set_schar (&value, 40); | |
| 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_schar (&value), ==, 40); | |
| g_value_set_schar (&value, 60); | |
| 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_schar (&value), ==, 40); | |
| g_param_spec_unref (pspec); | |
| } | |
| 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); | |
| } | |
| 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); | |
| } | |
| 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"); | |
| g_assert_true (g_param_value_is_valid (pspec, &value)); | |
| g_assert_false (g_param_value_validate (pspec, &value)); | |
| g_value_set_string (&value, ""); | |
| g_assert_true (g_param_value_is_valid (pspec, &value)); | |
| 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); | |
| g_assert_false (g_param_value_is_valid (pspec, &value)); | |
| 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, ""); | |
| g_assert_false (g_param_value_is_valid (pspec, &value)); | |
| g_assert_true (g_param_value_validate (pspec, &value)); | |
| g_assert_null (g_value_get_string (&value)); | |
| g_value_set_static_string (&value, ""); | |
| g_assert_false (g_param_value_is_valid (pspec, &value)); | |
| 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"); | |
| 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_string (&value)[0], ==, '-'); | |
| g_value_set_static_string (&value, "ABC"); | |
| 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_string (&value)[0], ==, '-'); | |
| /* test cset_nth */ | |
| G_PARAM_SPEC_STRING (pspec)->cset_nth = g_strdup ("abc"); | |
| g_value_set_string (&value, "aBC"); | |
| 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_string (&value)[1], ==, '-'); | |
| g_value_set_static_string (&value, "aBC"); | |
| 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_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); | |
| 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_char (&value), ==, 20); | |
| g_value_set_char (&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_char (&value), ==, 20); | |
| g_value_set_char (&value, 40); | |
| 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_char (&value), ==, 40); | |
| g_value_set_char (&value, 60); | |
| 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_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); | |
| 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_gtype (&value), ==, G_TYPE_PARAM); | |
| g_value_set_gtype (&value, G_TYPE_PARAM_INT); | |
| 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_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)); | |
| g_assert_true (g_param_value_is_valid (pspec, &value)); | |
| g_assert_false (g_param_value_validate (pspec, &value)); | |
| g_value_reset (&value); | |
| g_value_set_variant (&value, g_variant_new_uint32 (41)); | |
| 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)); | |
| 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); | |
| } | |
| } | |
| static void | |
| test_param_value (void) | |
| { | |
| GParamSpec *p, *p2; | |
| GParamSpec *pp; | |
| GValue value = G_VALUE_INIT; | |
| g_value_init (&value, G_TYPE_PARAM); | |
| g_assert_true (G_VALUE_HOLDS_PARAM (&value)); | |
| 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); | |
| g_assert_true (p2 == p); | |
| pp = g_param_spec_uint ("my-uint", "My UInt", "Blurb", 0, 10, 5, G_PARAM_READWRITE); | |
| g_value_set_param (&value, pp); | |
| p2 = g_value_dup_param (&value); | |
| g_assert_true (p2 == pp); /* param specs use ref/unref for copy/free */ | |
| g_param_spec_unref (p2); | |
| g_value_unset (&value); | |
| g_param_spec_unref (pp); | |
| } | |
| 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); | |
| g_assert_null (g_param_spec_get_qdata (p, q)); | |
| g_param_spec_ref_sink (p); | |
| g_param_spec_unref (p); | |
| } | |
| static void | |
| test_param_validate (void) | |
| { | |
| GParamSpec *p; | |
| GValue value = G_VALUE_INIT; | |
| 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); | |
| g_assert_false (g_param_value_defaults (p, &value)); | |
| g_assert_true (g_param_value_validate (p, &value)); | |
| g_assert_cmpint (g_value_get_int (&value), ==, 20); | |
| g_param_value_set_default (p, &value); | |
| g_assert_true (g_param_value_defaults (p, &value)); | |
| g_assert_cmpint (g_value_get_int (&value), ==, 10); | |
| g_param_spec_unref (p); | |
| } | |
| static void | |
| test_param_strings (void) | |
| { | |
| GParamSpec *p; | |
| /* test canonicalization */ | |
| p = g_param_spec_int ("my_int", "My Int", "Blurb", 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"); | |
| 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"); | |
| g_assert_null (g_param_spec_get_blurb (p)); | |
| g_param_spec_unref (p); | |
| } | |
| 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; | |
| } | |
| g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); | |
| g_test_trap_assert_failed (); | |
| g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*"); | |
| } | |
| static void | |
| test_param_convert (void) | |
| { | |
| GParamSpec *p; | |
| GValue v1 = G_VALUE_INIT; | |
| GValue v2 = G_VALUE_INIT; | |
| 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); | |
| g_assert_false (g_param_value_convert (p, &v1, &v2, TRUE)); | |
| g_assert_cmpint (g_value_get_int (&v2), ==, -4); | |
| g_assert_true (g_param_value_convert (p, &v1, &v2, FALSE)); | |
| g_assert_cmpint (g_value_get_int (&v2), ==, 20); | |
| g_param_spec_unref (p); | |
| } | |
| static void | |
| test_value_transform (void) | |
| { | |
| GValue src = G_VALUE_INIT; | |
| GValue dest = G_VALUE_INIT; | |
| #define CHECK_INT_CONVERSION(type, getter, value) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_INT, type)); \ | |
| g_value_init (&src, G_TYPE_INT); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_int (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| /* 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. | |
| */ | |
| CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124) | |
| CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124) | |
| CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124) | |
| 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) | |
| #define CHECK_UINT_CONVERSION(type, getter, value) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_UINT, type)); \ | |
| g_value_init (&src, G_TYPE_UINT); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_uint (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ | |
| 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) | |
| #define CHECK_LONG_CONVERSION(type, getter, value) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_LONG, type)); \ | |
| g_value_init (&src, G_TYPE_LONG); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_long (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, -124) | |
| CHECK_LONG_CONVERSION(G_TYPE_CHAR, schar, 124) | |
| 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) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_ULONG, type)); \ | |
| g_value_init (&src, G_TYPE_ULONG); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_ulong (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| CHECK_ULONG_CONVERSION(G_TYPE_CHAR, char, 124) | |
| 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) | |
| CHECK_ULONG_CONVERSION(G_TYPE_LONG, long, 12345678) | |
| CHECK_ULONG_CONVERSION(G_TYPE_ULONG, ulong, 12345678) | |
| CHECK_ULONG_CONVERSION(G_TYPE_INT64, int64, 12345678) | |
| 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) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_INT64, type)); \ | |
| g_value_init (&src, G_TYPE_INT64); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_int64 (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpint (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, -124) | |
| CHECK_INT64_CONVERSION(G_TYPE_CHAR, schar, 124) | |
| 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) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_UINT64, type)); \ | |
| g_value_init (&src, G_TYPE_UINT64); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_uint64 (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpuint (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, -124) | |
| CHECK_UINT64_CONVERSION(G_TYPE_CHAR, schar, 124) | |
| 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) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_FLOAT, type)); \ | |
| g_value_init (&src, G_TYPE_FLOAT); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_float (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, -124) | |
| CHECK_FLOAT_CONVERSION(G_TYPE_CHAR, schar, 124) | |
| 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) \ | |
| g_assert_true (g_value_type_transformable (G_TYPE_DOUBLE, type)); \ | |
| g_value_init (&src, G_TYPE_DOUBLE); \ | |
| g_value_init (&dest, type); \ | |
| g_value_set_double (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpfloat (g_value_get_##getter (&dest), ==, value); \ | |
| g_value_unset (&src); \ | |
| g_value_unset (&dest); | |
| CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, -124) | |
| CHECK_DOUBLE_CONVERSION(G_TYPE_CHAR, schar, 124) | |
| 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) | |
| #define CHECK_BOOLEAN_CONVERSION(type, setter, value) \ | |
| g_assert_true (g_value_type_transformable (type, G_TYPE_BOOLEAN)); \ | |
| g_value_init (&src, type); \ | |
| g_value_init (&dest, G_TYPE_BOOLEAN); \ | |
| g_value_set_##setter (&src, value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| g_assert_cmpint (g_value_get_boolean (&dest), ==, TRUE); \ | |
| g_value_set_##setter (&src, 0); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| 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) \ | |
| g_assert_true (g_value_type_transformable (int_type, G_TYPE_STRING)); \ | |
| g_value_init (&src, int_type); \ | |
| g_value_init (&dest, G_TYPE_STRING); \ | |
| g_value_set_##setter (&src, int_value); \ | |
| g_assert_true (g_value_transform (&src, &dest)); \ | |
| 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) | |
| g_assert_false (g_value_type_transformable (G_TYPE_STRING, G_TYPE_CHAR)); | |
| g_value_init (&src, G_TYPE_STRING); | |
| g_value_init (&dest, G_TYPE_CHAR); | |
| g_value_set_static_string (&src, "bla"); | |
| g_value_set_schar (&dest, 'c'); | |
| g_assert_false (g_value_transform (&src, &dest)); | |
| g_assert_cmpint (g_value_get_schar (&dest), ==, 'c'); | |
| g_value_unset (&src); | |
| g_value_unset (&dest); | |
| } | |
| /* 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; | |
| G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT) | |
| 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; | |
| G_DEFINE_TYPE (TestObjectB, test_object_b, test_object_a_get_type ()) | |
| 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; | |
| G_DEFINE_TYPE (TestObjectC, test_object_c, G_TYPE_OBJECT) | |
| 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; | |
| static GType test_interface_get_type (void); | |
| //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) | |
| { | |
| if (!g_test_undefined ()) | |
| continue; | |
| /* we think that this is impossible. make sure. */ | |
| 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 (); | |
| 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 */ | |
| /* 'a-' */ { 0, }, | |
| /* 'a-r' */ { 'v', 'v', '<', '<' }, | |
| /* 'a-w' */ { 'v', '>', '>', 'v' }, | |
| /* 'a-rw' */ { 'v', '=', '=', '=' }, | |
| /* 'a-c */ { 0, }, | |
| /* 'a-rc' */ { 0, }, | |
| /* 'a-wc' */ { 'v', '>', '>', 'v' }, | |
| /* 'a-rwc' */ { 'v', '=', '=', '=' }, | |
| /* 'a-C */ { 0, }, | |
| /* 'a-rC' */ { 0, }, | |
| /* 'a-wC' */ { 'v', '>', '>', 'v' }, | |
| /* 'a-rwC' */ { 'v', '=', '=', '=' }, | |
| /* 'a-cC */ { 0, }, | |
| /* 'a-rcC' */ { 0, }, | |
| /* 'a-wcC' */ { 0, }, | |
| /* 'a-rwcC' */ { 0, }, | |
| /* 'b-' */ { 0, }, | |
| /* 'b-r' */ { '<', 'v', '<', '<' }, | |
| /* 'b-w' */ { 'v', 'v', '>', 'v' }, | |
| /* 'b-rw' */ { '=', 'v', '=', '=' }, | |
| /* 'b-c */ { 0, }, | |
| /* 'b-rc' */ { 0, }, | |
| /* 'b-wc' */ { 'v', 'v', '>', 'v' }, | |
| /* 'b-rwc' */ { '=', 'v', '=', '=' }, | |
| /* 'b-C */ { 0, }, | |
| /* 'b-rC' */ { 0, }, | |
| /* 'b-wC' */ { 'v', 'v', '>', 'v' }, | |
| /* 'b-rwC' */ { '=', 'v', '=', '=' }, | |
| /* 'b-cC */ { 0, }, | |
| /* 'b-rcC' */ { 0, }, | |
| /* 'b-wcC' */ { 0, }, | |
| /* 'b-rwcC' */ { 0, }, | |
| /* 'c-' */ { 0, }, | |
| /* 'c-r' */ { '<', '<', 'v', '<' }, | |
| /* 'c-w' */ { '>', '>', 'v', 'v' }, | |
| /* 'c-rw' */ { '=', '=', 'v', '=' }, | |
| /* 'c-c */ { 0, }, | |
| /* 'c-rc' */ { 0, }, | |
| /* 'c-wc' */ { '>', '>', 'v', 'v' }, | |
| /* 'c-rwc' */ { '=', '=', 'v', '=' }, | |
| /* 'c-C */ { 0, }, | |
| /* 'c-rC' */ { 0, }, | |
| /* 'c-wC' */ { '>', '>', 'v', 'v' }, | |
| /* 'c-rwC' */ { '=', '=', 'v', '=' }, | |
| /* 'c-cC */ { 0, }, | |
| /* 'c-rcC' */ { 0, }, | |
| /* 'c-wcC' */ { 0, }, | |
| /* 'c-rwcC' */ { 0, } | |
| }; | |
| /* 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 | |
| * 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. | |
| * | |
| * Properties Valid Access Reason | |
| * | |
| * *-r r, rw, rwc, rwC Must keep readable, but can restrict newly-added writable | |
| * *-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 | |
| * *-wC rwC, rw, w, wC Can add readability or remove 'construct only' restriction | |
| * rwc, wc | |
| * | |
| * 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 | |
| * - 'r': invalid because of the addition of restrictions (ie: construct-only) | |
| * | |
| * 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 */ | |
| /* '*-' */ { 0, }, | |
| /* '*-r' */ { 'i', 'v', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'f', 'v', 'i', 'i', 'i', 'i' }, | |
| /* '*-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' }, | |
| /* '*-c */ { 0, }, | |
| /* '*-rc' */ { 0, }, | |
| /* '*-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' }, | |
| /* '*-C */ { 0, }, | |
| /* '*-rC' */ { 0, }, | |
| /* '*-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' }, | |
| }; | |
| 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); | |
| } | |
| typedef struct { | |
| gint change_this_flag; | |
| gint change_this_type; | |
| gint use_this_flag; | |
| gint use_this_type; | |
| } TestParamImplementData; | |
| static void | |
| test_param_implement_child (gconstpointer user_data) | |
| { | |
| TestParamImplementData *data = (gpointer) user_data; | |
| /* 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 ()); | |
| /* 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; | |
| /* This test is slow. */ | |
| if (!g_test_slow ()) | |
| { | |
| g_test_skip ("Skipping slow /param/implement test"); | |
| return; | |
| } | |
| 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++) | |
| { | |
| 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; | |
| } | |
| test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d", | |
| change_this_flag, change_this_type, | |
| use_this_flag, use_this_type); | |
| g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, | |
| G_TEST_SUBPROCESS_DEFAULT); | |
| g_free (test_path); | |
| /* 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 */ | |
| g_assert_cmpint (valid_impl_types[change_this_type * 16 + change_this_flag][use_this_type], ==, 0); | |
| g_test_trap_assert_failed (); | |
| g_test_trap_assert_stderr ("*Interface property does not exist*"); | |
| continue; | |
| case 'i': | |
| g_test_trap_assert_failed (); | |
| g_test_trap_assert_stderr ("*pspec->flags*"); | |
| 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 (); | |
| } | |
| } | |
| 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); | |
| g_assert_true (G_VALUE_HOLDS (def, G_TYPE_INT)); | |
| g_assert_cmpint (g_value_get_int (def), ==, 10); | |
| g_param_spec_unref (param); | |
| } | |
| 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])); | |
| } | |
| 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); | |
| } | |
| static void | |
| test_param_spec_pool (void) | |
| { | |
| GParamSpecPool *pool = g_param_spec_pool_new (FALSE); | |
| GParamSpec *pspec = g_param_spec_ref_sink (g_param_spec_int ("int", NULL, NULL, -1, 100, -1, G_PARAM_READWRITE)); | |
| GParamSpec *check = NULL; | |
| g_param_spec_pool_insert (pool, pspec, G_TYPE_OBJECT); | |
| 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); | |
| g_param_spec_unref (pspec); | |
| } | |
| int | |
| main (int argc, char *argv[]) | |
| { | |
| TestParamImplementData data, *test_data; | |
| gchar *test_path; | |
| g_test_init (&argc, &argv, NULL); | |
| g_test_add_func ("/param/value", test_param_value); | |
| g_test_add_func ("/param/strings", test_param_strings); | |
| 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); | |
| 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); | |
| g_test_add_func ("/param/implement", test_param_implement); | |
| 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); | |
| test_data = g_memdup2 (&data, sizeof (TestParamImplementData)); | |
| g_test_add_data_func_full (test_path, g_steal_pointer (&test_data), test_param_implement_child, g_free); | |
| g_free (test_path); | |
| } | |
| g_test_add_func ("/value/transform", test_value_transform); | |
| g_test_add_func ("/param/default", test_param_default); | |
| g_test_add_func ("/param/is-valid-name", test_param_is_valid_name); | |
| g_test_add_func ("/paramspec/char", test_param_spec_char); | |
| 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); | |
| g_test_add_func ("/paramspec/null-param", test_param_spec_null_param); | |
| 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); | |
| g_test_add_func ("/paramspec/custom", test_param_spec_custom); | |
| g_test_add_func ("/paramspec/pool", test_param_spec_pool); | |
| return g_test_run (); | |
| } |