1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       3   *
       4   * SPDX-License-Identifier: LGPL-2.1-or-later
       5   *
       6   * This library is free software; you can redistribute it and/or
       7   * modify it under the terms of the GNU Lesser General Public
       8   * License as published by the Free Software Foundation; either
       9   * version 2.1 of the License, or (at your option) any later version.
      10   *
      11   * This library is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14   * Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General Public
      17   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18   */
      19  
      20  /*
      21   * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      22   * file for a list of people on the GLib Team.  See the ChangeLog
      23   * files for a list of changes.  These files are distributed with
      24   * GLib at ftp://ftp.gtk.org/pub/gtk/.
      25   */
      26  
      27  #define GLIB_VERSION_MIN_REQUIRED       GLIB_VERSION_2_30
      28  
      29  #include <glib.h>
      30  #include <glib-object.h>
      31  #include "gobject/gvaluecollector.h"
      32  
      33  static void
      34  test_enum_transformation (void)
      35  {
      36    GType type;
      37    GValue orig = G_VALUE_INIT;
      38    GValue xform = G_VALUE_INIT;
      39    GEnumValue values[] = { {0,"0","0"}, {1,"1","1"}};
      40  
      41   type = g_enum_register_static ("TestEnum", values);
      42  
      43   g_value_init (&orig, type);
      44   g_value_set_enum (&orig, 1);
      45  
      46   memset (&xform, 0, sizeof (GValue));
      47   g_value_init (&xform, G_TYPE_CHAR);
      48   g_value_transform (&orig, &xform);
      49   g_assert_cmpint (g_value_get_char (&xform), ==, 1);
      50   g_assert_cmpint (g_value_get_schar (&xform), ==, 1);
      51  
      52   memset (&xform, 0, sizeof (GValue));
      53   g_value_init (&xform, G_TYPE_UCHAR);
      54   g_value_transform (&orig, &xform);
      55   g_assert_cmpint (g_value_get_uchar (&xform), ==, 1);
      56  
      57   memset (&xform, 0, sizeof (GValue));
      58   g_value_init (&xform, G_TYPE_INT);
      59   g_value_transform (&orig, &xform);
      60   g_assert_cmpint (g_value_get_int (&xform), ==, 1);
      61  
      62   memset (&xform, 0, sizeof (GValue));
      63   g_value_init (&xform, G_TYPE_UINT);
      64   g_value_transform (&orig, &xform);
      65   g_assert_cmpint (g_value_get_uint (&xform), ==, 1);
      66  
      67   memset (&xform, 0, sizeof (GValue));
      68   g_value_init (&xform, G_TYPE_LONG);
      69   g_value_transform (&orig, &xform);
      70   g_assert_cmpint (g_value_get_long (&xform), ==, 1);
      71  
      72   memset (&xform, 0, sizeof (GValue));
      73   g_value_init (&xform, G_TYPE_ULONG);
      74   g_value_transform (&orig, &xform);
      75   g_assert_cmpint (g_value_get_ulong (&xform), ==, 1);
      76  
      77   memset (&xform, 0, sizeof (GValue));
      78   g_value_init (&xform, G_TYPE_INT64);
      79   g_value_transform (&orig, &xform);
      80   g_assert_cmpint (g_value_get_int64 (&xform), ==, 1);
      81  
      82   memset (&xform, 0, sizeof (GValue));
      83   g_value_init (&xform, G_TYPE_UINT64);
      84   g_value_transform (&orig, &xform);
      85   g_assert_cmpint (g_value_get_uint64 (&xform), ==, 1);
      86  }
      87  
      88  
      89  static void
      90  test_gtype_value (void)
      91  {
      92    GType type;
      93    GValue value = G_VALUE_INIT;
      94    GValue copy = G_VALUE_INIT;
      95  
      96    g_value_init (&value, G_TYPE_GTYPE);
      97  
      98    g_value_set_gtype (&value, G_TYPE_BOXED);
      99    type = g_value_get_gtype (&value);
     100    g_assert_true (type == G_TYPE_BOXED);
     101  
     102    g_value_init (©, G_TYPE_GTYPE);
     103    g_value_copy (&value, ©);
     104    type = g_value_get_gtype (©);
     105    g_assert_true (type == G_TYPE_BOXED);
     106  }
     107  
     108  static gchar *
     109  collect (GValue *value, ...)
     110  {
     111    gchar *error;
     112    va_list var_args;
     113  
     114    error = NULL;
     115  
     116    va_start (var_args, value);
     117    G_VALUE_COLLECT (value, var_args, 0, &error);
     118    va_end (var_args);
     119  
     120    return error;
     121  }
     122  
     123  static gchar *
     124  lcopy (GValue *value, ...)
     125  {
     126    gchar *error;
     127    va_list var_args;
     128  
     129    error = NULL;
     130  
     131    va_start (var_args, value);
     132    G_VALUE_LCOPY (value, var_args, 0, &error);
     133    va_end (var_args);
     134  
     135    return error;
     136  }
     137  
     138  static void
     139  test_collection (void)
     140  {
     141    GValue value = G_VALUE_INIT;
     142    gchar *error;
     143  
     144    g_value_init (&value, G_TYPE_CHAR);
     145    error = collect (&value, 'c');
     146    g_assert_null (error);
     147    g_assert_cmpint (g_value_get_char (&value), ==, 'c');
     148  
     149    g_value_unset (&value);
     150    g_value_init (&value, G_TYPE_UCHAR);
     151    error = collect (&value, 129);
     152    g_assert_null (error);
     153    g_assert_cmpint (g_value_get_uchar (&value), ==, 129);
     154  
     155    g_value_unset (&value);
     156    g_value_init (&value, G_TYPE_BOOLEAN);
     157    error = collect (&value, TRUE);
     158    g_assert_null (error);
     159    g_assert_cmpint (g_value_get_boolean (&value), ==, TRUE);
     160  
     161    g_value_unset (&value);
     162    g_value_init (&value, G_TYPE_INT);
     163    error = collect (&value, G_MAXINT);
     164    g_assert_null (error);
     165    g_assert_cmpint (g_value_get_int (&value), ==, G_MAXINT);
     166  
     167    g_value_unset (&value);
     168    g_value_init (&value, G_TYPE_UINT);
     169    error = collect (&value, G_MAXUINT);
     170    g_assert_null (error);
     171    g_assert_cmpuint (g_value_get_uint (&value), ==, G_MAXUINT);
     172  
     173    g_value_unset (&value);
     174    g_value_init (&value, G_TYPE_LONG);
     175    error = collect (&value, G_MAXLONG);
     176    g_assert_null (error);
     177    g_assert_cmpint (g_value_get_long (&value), ==, G_MAXLONG);
     178  
     179    g_value_unset (&value);
     180    g_value_init (&value, G_TYPE_ULONG);
     181    error = collect (&value, G_MAXULONG);
     182    g_assert_null (error);
     183    g_assert_cmpuint (g_value_get_ulong (&value), ==, G_MAXULONG);
     184  
     185    g_value_unset (&value);
     186    g_value_init (&value, G_TYPE_INT64);
     187    error = collect (&value, G_MAXINT64);
     188    g_assert_null (error);
     189    g_assert_cmpint (g_value_get_int64 (&value), ==, G_MAXINT64);
     190  
     191    g_value_unset (&value);
     192    g_value_init (&value, G_TYPE_UINT64);
     193    error = collect (&value, G_MAXUINT64);
     194    g_assert_null (error);
     195    g_assert_cmpuint (g_value_get_uint64 (&value), ==, G_MAXUINT64);
     196  
     197    g_value_unset (&value);
     198    g_value_init (&value, G_TYPE_FLOAT);
     199    error = collect (&value, G_MAXFLOAT);
     200    g_assert_null (error);
     201    g_assert_cmpfloat (g_value_get_float (&value), ==, G_MAXFLOAT);
     202  
     203    g_value_unset (&value);
     204    g_value_init (&value, G_TYPE_DOUBLE);
     205    error = collect (&value, G_MAXDOUBLE);
     206    g_assert_null (error);
     207    g_assert_cmpfloat (g_value_get_double (&value), ==, G_MAXDOUBLE);
     208  
     209    g_value_unset (&value);
     210    g_value_init (&value, G_TYPE_STRING);
     211    error = collect (&value, "string ?");
     212    g_assert_null (error);
     213    g_assert_cmpstr (g_value_get_string (&value), ==, "string ?");
     214  
     215    g_value_unset (&value);
     216    g_value_init (&value, G_TYPE_GTYPE);
     217    error = collect (&value, G_TYPE_BOXED);
     218    g_assert_null (error);
     219    g_assert_true (g_value_get_gtype (&value) == G_TYPE_BOXED);
     220  
     221    g_value_unset (&value);
     222    g_value_init (&value, G_TYPE_VARIANT);
     223    error = collect (&value, g_variant_new_uint32 (42));
     224    g_assert_null (error);
     225    g_assert_true (g_variant_is_of_type (g_value_get_variant (&value),
     226                                         G_VARIANT_TYPE ("u")));
     227    g_assert_cmpuint (g_variant_get_uint32 (g_value_get_variant (&value)), ==, 42);
     228  
     229    g_value_unset (&value);
     230  }
     231  
     232  static void
     233  test_copying (void)
     234  {
     235    GValue value = G_VALUE_INIT;
     236    gchar *error;
     237  
     238    {
     239      gchar c = 0;
     240  
     241      g_value_init (&value, G_TYPE_CHAR);
     242      g_value_set_char (&value, 'c');
     243      error = lcopy (&value, &c);
     244      g_assert_null (error);
     245      g_assert_cmpint (c, ==, 'c');
     246    }
     247  
     248    {
     249      guchar c = 0;
     250  
     251      g_value_unset (&value);
     252      g_value_init (&value, G_TYPE_UCHAR);
     253      g_value_set_uchar (&value, 129);
     254      error = lcopy (&value, &c);
     255      g_assert_null (error);
     256      g_assert_cmpint (c, ==, 129);
     257    }
     258  
     259    {
     260      gint c = 0;
     261  
     262      g_value_unset (&value);
     263      g_value_init (&value, G_TYPE_INT);
     264      g_value_set_int (&value, G_MAXINT);
     265      error = lcopy (&value, &c);
     266      g_assert_null (error);
     267      g_assert_cmpint (c, ==, G_MAXINT);
     268    }
     269  
     270    {
     271      guint c = 0;
     272  
     273      g_value_unset (&value);
     274      g_value_init (&value, G_TYPE_UINT);
     275      g_value_set_uint (&value, G_MAXUINT);
     276      error = lcopy (&value, &c);
     277      g_assert_null (error);
     278      g_assert_cmpuint (c, ==, G_MAXUINT);
     279    }
     280  
     281    {
     282      glong c = 0;
     283  
     284      g_value_unset (&value);
     285      g_value_init (&value, G_TYPE_LONG);
     286      g_value_set_long (&value, G_MAXLONG);
     287      error = lcopy (&value, &c);
     288      g_assert_null (error);
     289      g_assert (c == G_MAXLONG);
     290    }
     291  
     292    {
     293      gulong c = 0;
     294  
     295      g_value_unset (&value);
     296      g_value_init (&value, G_TYPE_ULONG);
     297      g_value_set_ulong (&value, G_MAXULONG);
     298      error = lcopy (&value, &c);
     299      g_assert_null (error);
     300      g_assert (c == G_MAXULONG);
     301    }
     302  
     303    {
     304      gint64 c = 0;
     305  
     306      g_value_unset (&value);
     307      g_value_init (&value, G_TYPE_INT64);
     308      g_value_set_int64 (&value, G_MAXINT64);
     309      error = lcopy (&value, &c);
     310      g_assert_null (error);
     311      g_assert (c == G_MAXINT64);
     312    }
     313  
     314    {
     315      guint64 c = 0;
     316  
     317      g_value_unset (&value);
     318      g_value_init (&value, G_TYPE_UINT64);
     319      g_value_set_uint64 (&value, G_MAXUINT64);
     320      error = lcopy (&value, &c);
     321      g_assert_null (error);
     322      g_assert (c == G_MAXUINT64);
     323    }
     324  
     325    {
     326      gfloat c = 0;
     327  
     328      g_value_unset (&value);
     329      g_value_init (&value, G_TYPE_FLOAT);
     330      g_value_set_float (&value, G_MAXFLOAT);
     331      error = lcopy (&value, &c);
     332      g_assert_null (error);
     333      g_assert (c == G_MAXFLOAT);
     334    }
     335  
     336    {
     337      gdouble c = 0;
     338  
     339      g_value_unset (&value);
     340      g_value_init (&value, G_TYPE_DOUBLE);
     341      g_value_set_double (&value, G_MAXDOUBLE);
     342      error = lcopy (&value, &c);
     343      g_assert_null (error);
     344      g_assert (c == G_MAXDOUBLE);
     345    }
     346  
     347    {
     348      gchar *c = NULL;
     349  
     350      g_value_unset (&value);
     351      g_value_init (&value, G_TYPE_STRING);
     352      g_value_set_string (&value, "string ?");
     353      error = lcopy (&value, &c);
     354      g_assert_null (error);
     355      g_assert_cmpstr (c, ==, "string ?");
     356      g_free (c);
     357    }
     358  
     359    {
     360      GType c = G_TYPE_NONE;
     361  
     362      g_value_unset (&value);
     363      g_value_init (&value, G_TYPE_GTYPE);
     364      g_value_set_gtype (&value, G_TYPE_BOXED);
     365      error = lcopy (&value, &c);
     366      g_assert_null (error);
     367      g_assert_true (c == G_TYPE_BOXED);
     368    }
     369  
     370    {
     371      GVariant *c = NULL;
     372  
     373      g_value_unset (&value);
     374      g_value_init (&value, G_TYPE_VARIANT);
     375      g_value_set_variant (&value, g_variant_new_uint32 (42));
     376      error = lcopy (&value, &c);
     377      g_assert_null (error);
     378      g_assert_nonnull (c);
     379      g_assert (g_variant_is_of_type (c, G_VARIANT_TYPE ("u")));
     380      g_assert_cmpuint (g_variant_get_uint32 (c), ==, 42);
     381      g_variant_unref (c);
     382      g_value_unset (&value);
     383    }
     384  }
     385  
     386  static void
     387  test_value_basic (void)
     388  {
     389    GValue value = G_VALUE_INIT;
     390  
     391    g_assert_false (G_IS_VALUE (&value));
     392    g_assert_false (G_VALUE_HOLDS_INT (&value));
     393    g_value_unset (&value);
     394    g_assert_false (G_IS_VALUE (&value));
     395    g_assert_false (G_VALUE_HOLDS_INT (&value));
     396  
     397    g_value_init (&value, G_TYPE_INT);
     398    g_assert_true (G_IS_VALUE (&value));
     399    g_assert_true (G_VALUE_HOLDS_INT (&value));
     400    g_assert_false (G_VALUE_HOLDS_UINT (&value));
     401    g_assert_cmpint (g_value_get_int (&value), ==, 0);
     402  
     403    g_value_set_int (&value, 10);
     404    g_assert_cmpint (g_value_get_int (&value), ==, 10);
     405  
     406    g_value_reset (&value);
     407    g_assert_true (G_IS_VALUE (&value));
     408    g_assert_true (G_VALUE_HOLDS_INT (&value));
     409    g_assert_cmpint (g_value_get_int (&value), ==, 0);
     410  
     411    g_value_unset (&value);
     412    g_assert_false (G_IS_VALUE (&value));
     413    g_assert_false (G_VALUE_HOLDS_INT (&value));
     414  }
     415  
     416  static void
     417  test_value_string (void)
     418  {
     419    const gchar *static1 = "static1";
     420    const gchar *static2 = "static2";
     421    const gchar *storedstr;
     422    const gchar *copystr;
     423    gchar *str1, *str2, *stolen_str;
     424    GValue value = G_VALUE_INIT;
     425    GValue copy = G_VALUE_INIT;
     426  
     427    g_test_summary ("Test that G_TYPE_STRING GValue copy properly");
     428  
     429    /*
     430     * Regular strings (ownership not passed)
     431     */
     432  
     433    /* Create a regular string gvalue and make sure it copies the provided string */
     434    g_value_init (&value, G_TYPE_STRING);
     435    g_assert_true (G_VALUE_HOLDS_STRING (&value));
     436  
     437    /* The string contents should be empty at this point */
     438    storedstr = g_value_get_string (&value);
     439    g_assert_true (storedstr == NULL);
     440  
     441    g_value_set_string (&value, static1);
     442    /* The contents should be a copy of the same string */
     443    storedstr = g_value_get_string (&value);
     444    g_assert_true (storedstr != static1);
     445    g_assert_cmpstr (storedstr, ==, static1);
     446    /* Check g_value_dup_string() provides a copy */
     447    str1 = g_value_dup_string (&value);
     448    g_assert_true (storedstr != str1);
     449    g_assert_cmpstr (str1, ==, static1);
     450    g_free (str1);
     451  
     452    /* Copying a regular string gvalue should copy the contents */
     453    g_value_init (©, G_TYPE_STRING);
     454    g_value_copy (&value, ©);
     455    copystr = g_value_get_string (©);
     456    g_assert_true (copystr != storedstr);
     457    g_assert_cmpstr (copystr, ==, static1);
     458    g_value_unset (©);
     459  
     460    /* Setting a new string should change the contents */
     461    g_value_set_string (&value, static2);
     462    /* The contents should be a copy of that *new* string */
     463    storedstr = g_value_get_string (&value);
     464    g_assert_true (storedstr != static2);
     465    g_assert_cmpstr (storedstr, ==, static2);
     466  
     467    /* Setting a static string over that should also change it (test for
     468     * coverage and valgrind) */
     469    g_value_set_static_string (&value, static1);
     470    storedstr = g_value_get_string (&value);
     471    g_assert_true (storedstr != static2);
     472    g_assert_cmpstr (storedstr, ==, static1);
     473  
     474    /* Giving a string directly (ownership passed) should replace the content */
     475    str2 = g_strdup (static2);
     476    g_value_take_string (&value, str2);
     477    storedstr = g_value_get_string (&value);
     478    g_assert_true (storedstr != static2);
     479    g_assert_cmpstr (storedstr, ==, str2);
     480  
     481    g_value_unset (&value);
     482  
     483    /*
     484     * Regular strings (ownership passed)
     485     */
     486  
     487    g_value_init (&value, G_TYPE_STRING);
     488    g_assert_true (G_VALUE_HOLDS_STRING (&value));
     489    str1 = g_strdup (static1);
     490    g_value_take_string (&value, str1);
     491    /* The contents should be the string we provided */
     492    storedstr = g_value_get_string (&value);
     493    g_assert_true (storedstr == str1);
     494    /* But g_value_dup_string() should provide a copy */
     495    str2 = g_value_dup_string (&value);
     496    g_assert_true (storedstr != str2);
     497    g_assert_cmpstr (str2, ==, static1);
     498    g_free (str2);
     499  
     500    /* Copying a regular string gvalue (even with ownership passed) should copy
     501     * the contents */
     502    g_value_init (©, G_TYPE_STRING);
     503    g_value_copy (&value, ©);
     504    copystr = g_value_get_string (©);
     505    g_assert_true (copystr != storedstr);
     506    g_assert_cmpstr (copystr, ==, static1);
     507    g_value_unset (©);
     508  
     509    /* Setting a new regular string should change the contents */
     510    g_value_set_string (&value, static2);
     511    /* The contents should be a copy of that *new* string */
     512    storedstr = g_value_get_string (&value);
     513    g_assert_true (storedstr != static2);
     514    g_assert_cmpstr (storedstr, ==, static2);
     515  
     516    /* Now check stealing the ownership of the contents */
     517    stolen_str = g_value_steal_string (&value);
     518    g_assert_null (g_value_get_string (&value));
     519    g_value_unset (&value);
     520    g_assert_cmpstr (stolen_str, ==, static2);
     521    g_free (stolen_str);
     522  
     523    /*
     524     * Static strings
     525     */
     526    g_value_init (&value, G_TYPE_STRING);
     527    g_assert_true (G_VALUE_HOLDS_STRING (&value));
     528    g_value_set_static_string (&value, static1);
     529    /* The contents should be the string we provided */
     530    storedstr = g_value_get_string (&value);
     531    g_assert_true (storedstr == static1);
     532    /* But g_value_dup_string() should provide a copy */
     533    str2 = g_value_dup_string (&value);
     534    g_assert_true (storedstr != str2);
     535    g_assert_cmpstr (str2, ==, static1);
     536    g_free (str2);
     537  
     538    /* Copying a static string gvalue should *actually* copy the contents */
     539    g_value_init (©, G_TYPE_STRING);
     540    g_value_copy (&value, ©);
     541    copystr = g_value_get_string (©);
     542    g_assert_true (copystr != static1);
     543    g_value_unset (©);
     544  
     545    /* Setting a new string should change the contents */
     546    g_value_set_static_string (&value, static2);
     547    /* The contents should be a copy of that *new* string */
     548    storedstr = g_value_get_string (&value);
     549    g_assert_true (storedstr != static1);
     550    g_assert_cmpstr (storedstr, ==, static2);
     551  
     552    /* Check if g_value_steal_string() can handle GValue
     553     * with a static string */
     554    stolen_str = g_value_steal_string (&value);
     555    g_assert_true (stolen_str != static2);
     556    g_assert_cmpstr (stolen_str, ==, static2);
     557    g_assert_null (g_value_get_string (&value));
     558    g_free (stolen_str);
     559  
     560    g_value_unset (&value);
     561  
     562    /*
     563     * Interned/Canonical strings
     564     */
     565    static1 = g_intern_static_string (static1);
     566    g_value_init (&value, G_TYPE_STRING);
     567    g_assert_true (G_VALUE_HOLDS_STRING (&value));
     568    g_value_set_interned_string (&value, static1);
     569    g_assert_true (G_VALUE_IS_INTERNED_STRING (&value));
     570    /* The contents should be the string we provided */
     571    storedstr = g_value_get_string (&value);
     572    g_assert_true (storedstr == static1);
     573    /* But g_value_dup_string() should provide a copy */
     574    str2 = g_value_dup_string (&value);
     575    g_assert_true (storedstr != str2);
     576    g_assert_cmpstr (str2, ==, static1);
     577    g_free (str2);
     578  
     579    /* Copying an interned string gvalue should *not* copy the contents
     580     * and should still be an interned string */
     581    g_value_init (©, G_TYPE_STRING);
     582    g_value_copy (&value, ©);
     583    g_assert_true (G_VALUE_IS_INTERNED_STRING (©));
     584    copystr = g_value_get_string (©);
     585    g_assert_true (copystr == static1);
     586    g_value_unset (©);
     587  
     588    /* Setting a new interned string should change the contents */
     589    static2 = g_intern_static_string (static2);
     590    g_value_set_interned_string (&value, static2);
     591    g_assert_true (G_VALUE_IS_INTERNED_STRING (&value));
     592    /* The contents should be the interned string */
     593    storedstr = g_value_get_string (&value);
     594    g_assert_cmpstr (storedstr, ==, static2);
     595  
     596    /* Setting a new regular string should change the contents */
     597    g_value_set_string (&value, static2);
     598    g_assert_false (G_VALUE_IS_INTERNED_STRING (&value));
     599    /* The contents should be a copy of that *new* string */
     600    storedstr = g_value_get_string (&value);
     601    g_assert_true (storedstr != static2);
     602    g_assert_cmpstr (storedstr, ==, static2);
     603  
     604    /* Check if g_value_steal_string() can handle GValue
     605     * with an interned string */
     606    stolen_str = g_value_steal_string (&value);
     607    g_assert_true (stolen_str != static2);
     608    g_assert_cmpstr (stolen_str, ==, static2);
     609    g_assert_null (g_value_get_string (&value));
     610    g_free (stolen_str);
     611  
     612    g_value_unset (&value);
     613  }
     614  
     615  static gint
     616  cmpint (gconstpointer a, gconstpointer b)
     617  {
     618    const GValue *aa = a;
     619    const GValue *bb = b;
     620  
     621    return g_value_get_int (aa) - g_value_get_int (bb);
     622  }
     623  
     624  static void
     625  test_valuearray_basic (void)
     626  {
     627    GValueArray *a;
     628    GValueArray *a2;
     629    GValue v = G_VALUE_INIT;
     630    GValue *p;
     631    guint i;
     632  
     633    a = g_value_array_new (20);
     634  
     635    g_value_init (&v, G_TYPE_INT);
     636    for (i = 0; i < 100; i++)
     637      {
     638        g_value_set_int (&v, i);
     639        g_value_array_append (a, &v);
     640      }
     641  
     642    g_assert_cmpint (a->n_values, ==, 100);
     643    p = g_value_array_get_nth (a, 5);
     644    g_assert_cmpint (g_value_get_int (p), ==, 5);
     645  
     646    for (i = 20; i < 100; i+= 5)
     647      g_value_array_remove (a, 100 - i);
     648  
     649    for (i = 100; i < 150; i++)
     650      {
     651        g_value_set_int (&v, i);
     652        g_value_array_prepend (a, &v);
     653      }
     654  
     655    g_value_array_sort (a, cmpint);
     656    for (i = 0; i < a->n_values - 1; i++)
     657      g_assert_cmpint (g_value_get_int (&a->values[i]), <=, g_value_get_int (&a->values[i+1]));
     658  
     659    a2 = g_value_array_copy (a);
     660    for (i = 0; i < a->n_values; i++)
     661      g_assert_cmpint (g_value_get_int (&a->values[i]), ==, g_value_get_int (&a2->values[i]));
     662  
     663    g_value_array_free (a);
     664    g_value_array_free (a2);
     665  }
     666  
     667  /* We create some dummy objects with this relationship:
     668   *
     669   *               GObject           TestInterface
     670   *              /       \         /  /
     671   *     TestObjectA     TestObjectB  /
     672   *      /       \                  /
     673   * TestObjectA1 TestObjectA2-------   
     674   *
     675   * ie: TestObjectA1 and TestObjectA2 are subclasses of TestObjectA
     676   * and TestObjectB is related to neither. TestObjectA2 and TestObjectB
     677   * implement TestInterface
     678   */
     679  
     680  typedef GTypeInterface TestInterfaceInterface;
     681  static GType test_interface_get_type (void);
     682  G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_OBJECT)
     683  static void test_interface_default_init (TestInterfaceInterface *iface) { }
     684  
     685  static GType test_object_a_get_type (void);
     686  typedef GObject TestObjectA; typedef GObjectClass TestObjectAClass;
     687  G_DEFINE_TYPE (TestObjectA, test_object_a, G_TYPE_OBJECT)
     688  static void test_object_a_class_init (TestObjectAClass *class) { }
     689  static void test_object_a_init (TestObjectA *a) { }
     690  
     691  static GType test_object_b_get_type (void);
     692  typedef GObject TestObjectB; typedef GObjectClass TestObjectBClass;
     693  static void test_object_b_iface_init (TestInterfaceInterface *iface) { }
     694  G_DEFINE_TYPE_WITH_CODE (TestObjectB, test_object_b, G_TYPE_OBJECT,
     695                           G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_b_iface_init))
     696  static void test_object_b_class_init (TestObjectBClass *class) { }
     697  static void test_object_b_init (TestObjectB *b) { }
     698  
     699  static GType test_object_a1_get_type (void);
     700  typedef GObject TestObjectA1; typedef GObjectClass TestObjectA1Class;
     701  G_DEFINE_TYPE (TestObjectA1, test_object_a1, test_object_a_get_type ())
     702  static void test_object_a1_class_init (TestObjectA1Class *class) { }
     703  static void test_object_a1_init (TestObjectA1 *c) { }
     704  
     705  static GType test_object_a2_get_type (void);
     706  typedef GObject TestObjectA2; typedef GObjectClass TestObjectA2Class;
     707  static void test_object_a2_iface_init (TestInterfaceInterface *iface) { }
     708  G_DEFINE_TYPE_WITH_CODE (TestObjectA2, test_object_a2, test_object_a_get_type (),
     709                           G_IMPLEMENT_INTERFACE (test_interface_get_type (), test_object_a2_iface_init))
     710  static void test_object_a2_class_init (TestObjectA2Class *class) { }
     711  static void test_object_a2_init (TestObjectA2 *b) { }
     712  
     713  static void
     714  test_value_transform_object (void)
     715  {
     716    GValue src = G_VALUE_INIT;
     717    GValue dest = G_VALUE_INIT;
     718    GObject *object;
     719    guint i, s, d;
     720    GType types[] = {
     721      G_TYPE_OBJECT,
     722      test_interface_get_type (),
     723      test_object_a_get_type (),
     724      test_object_b_get_type (),
     725      test_object_a1_get_type (),
     726      test_object_a2_get_type ()
     727    };
     728  
     729    for (i = 0; i < G_N_ELEMENTS (types); i++)
     730      {
     731        if (!G_TYPE_IS_CLASSED (types[i]))
     732          continue;
     733  
     734        object = g_object_new (types[i], NULL);
     735  
     736        for (s = 0; s < G_N_ELEMENTS (types); s++)
     737          {
     738            if (!G_TYPE_CHECK_INSTANCE_TYPE (object, types[s]))
     739              continue;
     740  
     741            g_value_init (&src, types[s]);
     742            g_value_set_object (&src, object);
     743            g_value_set_object (&src, g_value_get_object (&src));
     744  
     745            for (d = 0; d < G_N_ELEMENTS (types); d++)
     746              {
     747                g_test_message ("Next: %s object in GValue of %s to GValue of %s", g_type_name (types[i]), g_type_name (types[s]), g_type_name (types[d]));
     748                g_assert_true (g_value_type_transformable (types[s], types[d]));
     749                g_value_init (&dest, types[d]);
     750                g_assert_true (g_value_transform (&src, &dest));
     751                g_assert_cmpint (g_value_get_object (&dest) != NULL, ==, G_TYPE_CHECK_INSTANCE_TYPE (object, types[d]));
     752                g_value_unset (&dest);
     753              }
     754            g_value_unset (&src);
     755          }
     756  
     757        g_object_unref (object);
     758      }
     759  }
     760  
     761  int
     762  main (int argc, char *argv[])
     763  {
     764    g_test_init (&argc, &argv, NULL);
     765  
     766    g_test_add_func ("/value/basic", test_value_basic);
     767    g_test_add_func ("/value/array/basic", test_valuearray_basic);
     768    g_test_add_func ("/value/collection", test_collection);
     769    g_test_add_func ("/value/copying", test_copying);
     770    g_test_add_func ("/value/enum-transformation", test_enum_transformation);
     771    g_test_add_func ("/value/gtype", test_gtype_value);
     772    g_test_add_func ("/value/string", test_value_string);
     773    g_test_add_func ("/value/transform-object", test_value_transform_object);
     774  
     775    return g_test_run ();
     776  }