b86eef4e78ba18e7f83aad4a69c291441cb72d25
[platform/upstream/gstreamer.git] / subprojects / gstreamer / tests / check / gst / gstvalue.c
1 /* GStreamer
2  * Copyright (C) <2004> David Schleef <david at schleef dot org>
3  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
4  *
5  * gstvalue.c: Unit tests for GstValue
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #define GLIB_DISABLE_DEPRECATION_WARNINGS
27 #include <gst/check/gstcheck.h>
28
29
30 GST_START_TEST (test_deserialize_buffer)
31 {
32   GValue value = { 0 };
33   GstBuffer *buf;
34   guint8 data[8];
35   guint64 val;
36
37   g_value_init (&value, GST_TYPE_BUFFER);
38   fail_unless (gst_value_deserialize (&value, "1234567890abcdef"));
39   /* does not increase the refcount */
40   buf = GST_BUFFER (g_value_get_boxed (&value));
41   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
42
43   /* does not increase the refcount */
44   buf = gst_value_get_buffer (&value);
45   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
46
47   gst_buffer_extract (buf, 0, data, 8);
48   val = GST_READ_UINT64_BE (data);
49   fail_unless_equals_uint64 (val, G_GUINT64_CONSTANT (0x1234567890abcdef));
50
51   /* cleanup */
52   g_value_unset (&value);
53 }
54
55 GST_END_TEST;
56
57 /* create and serialize a buffer */
58 GST_START_TEST (test_serialize_buffer)
59 {
60   GValue value = { 0 };
61   GstBuffer *buf;
62   gchar *serialized;
63   const guint8 buf_data[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };
64   gint len;
65
66   len = sizeof (buf_data);
67   buf = gst_buffer_new_and_alloc (len);
68
69   gst_buffer_fill (buf, 0, (gchar *) buf_data, len);
70
71   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
72
73   /* and assign buffer to mini object */
74   g_value_init (&value, GST_TYPE_BUFFER);
75   gst_value_take_buffer (&value, buf);
76   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
77
78   /* now serialize it */
79   serialized = gst_value_serialize (&value);
80   GST_DEBUG ("serialized buffer to %s", serialized);
81   fail_unless (serialized != NULL);
82   fail_unless_equals_string (serialized, "1234567890abcdef");
83
84   /* refcount should not change */
85   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
86
87   /* cleanup */
88   g_free (serialized);
89   g_value_unset (&value);
90
91   /* take NULL buffer */
92   g_value_init (&value, GST_TYPE_BUFFER);
93   GST_DEBUG ("setting NULL buffer");
94   gst_value_take_buffer (&value, NULL);
95
96   /* now serialize it */
97   GST_DEBUG ("serializing NULL buffer");
98   serialized = gst_value_serialize (&value);
99   /* should return NULL */
100   fail_unless (serialized == NULL);
101
102   g_free (serialized);
103   g_value_unset (&value);
104 }
105
106 GST_END_TEST;
107
108 GST_START_TEST (test_deserialize_gint64)
109 {
110   GValue value = { 0 };
111   const char *strings[] = {
112     "12345678901",
113     "-12345678901",
114     "1152921504606846976",
115     "-1152921504606846976",
116   };
117   gint64 results[] = {
118     12345678901LL,
119     -12345678901LL,
120     1152921504606846976LL,
121     -1152921504606846976LL,
122   };
123   int i;
124
125   g_value_init (&value, G_TYPE_INT64);
126
127   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
128     fail_unless (gst_value_deserialize (&value, strings[i]),
129         "could not deserialize %s (%d)", strings[i], i);
130     fail_unless (g_value_get_int64 (&value) == results[i],
131         "resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT
132         ", for string %s (%d)", g_value_get_int64 (&value),
133         results[i], strings[i], i);
134   }
135 }
136
137 GST_END_TEST;
138
139 GST_START_TEST (test_deserialize_guint64)
140 {
141   GValue value = { 0 };
142   const char *strings[] = {
143     "0xffffffffffffffff",
144     "9223372036854775810",
145     "-9223372036854775810",
146     "-1",
147     "1",
148     "-0",
149   };
150   guint64 results[] = {
151     0xffffffffffffffffULL,
152     9223372036854775810ULL,
153     9223372036854775806ULL,
154     (guint64) - 1,
155     1,
156     0,
157   };
158   int i;
159
160   g_value_init (&value, G_TYPE_UINT64);
161
162   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
163     fail_unless (gst_value_deserialize (&value, strings[i]),
164         "could not deserialize %s (%d)", strings[i], i);
165     fail_unless (g_value_get_uint64 (&value) == results[i],
166         "resulting value is %" G_GUINT64_FORMAT ", not %" G_GUINT64_FORMAT
167         ", for string %s (%d)", g_value_get_uint64 (&value),
168         results[i], strings[i], i);
169   }
170 }
171
172 GST_END_TEST;
173
174 GST_START_TEST (test_deserialize_guchar)
175 {
176   GValue value = { 0 };
177   const char *strings[] = {
178     "0xff",
179     "255",
180     "-1",
181     "1",
182     "-0",
183   };
184   guchar results[] = {
185     0xff,
186     255,
187     (guchar) - 1,
188     1,
189     0,
190   };
191   int i;
192
193   g_value_init (&value, G_TYPE_UCHAR);
194
195   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
196     fail_unless (gst_value_deserialize (&value, strings[i]),
197         "could not deserialize %s (%d)", strings[i], i);
198     fail_unless (g_value_get_uchar (&value) == results[i],
199         "resulting value is %u not %u, for string %s (%d)",
200         g_value_get_uchar (&value), results[i], strings[i], i);
201   }
202
203   /* test serialisation as well while we're at it */
204   {
205     gchar *str;
206     GValue value = { 0 };
207     g_value_init (&value, G_TYPE_UCHAR);
208
209     g_value_set_uchar (&value, 255);
210     str = gst_value_serialize (&value);
211
212     fail_unless_equals_string (str, "255");
213     g_free (str);
214   }
215 }
216
217 GST_END_TEST;
218
219 GST_START_TEST (test_deserialize_gstfraction)
220 {
221   GValue value = { 0 };
222   const char *strings[] = {
223     "4/5",
224     "-8/9"
225   };
226   gint64 result_numers[] = {
227     4,
228     -8
229   };
230   gint64 result_denoms[] = {
231     5,
232     9
233   };
234
235   int i;
236
237   g_value_init (&value, GST_TYPE_FRACTION);
238   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
239     fail_unless (gst_value_deserialize (&value, strings[i]),
240         "could not deserialize %s (%d)", strings[i], i);
241     fail_unless (gst_value_get_fraction_numerator (&value) == result_numers[i],
242         "resulting numerator value is %d, not %d"
243         ", for string %s (%d)", gst_value_get_fraction_numerator (&value),
244         result_numers[i], strings[i], i);
245     fail_unless (gst_value_get_fraction_denominator (&value) ==
246         result_denoms[i], "resulting denominator value is %d, not %d"
247         ", for string %s (%d)", gst_value_get_fraction_denominator (&value),
248         result_denoms[i], strings[i], i);
249   }
250 }
251
252 GST_END_TEST;
253
254 GST_START_TEST (test_deserialize_gint)
255 {
256   GValue value = { 0 };
257   const char *strings[] = {
258     "123456",
259     "-123456",
260     "0xFFFF",
261     "0x0000FFFF",
262     /* a positive long long, serializing to highest possible positive sint */
263     "0x7FFFFFFF",
264     /* a positive long long, serializing to lowest possible negative sint */
265     "0x80000000",
266     /* a negative long long, serializing to lowest possible negative sint */
267     "0xFFFFFFFF80000000",
268     "0xFF000000",
269     /* a positive long long serializing to -1 */
270     "0xFFFFFFFF",
271     "0xFFFFFFFF",
272     /* a negative long long serializing to -1 */
273     "0xFFFFFFFFFFFFFFFF",
274     "0xFFFFFFFFFFFFFFFF",
275     "0xEFFFFFFF",
276   };
277   /* some casts need to be explicit because of unsigned -> signed */
278   gint results[] = {
279     123456,
280     -123456,
281     0xFFFF,
282     0xFFFF,
283     0x7FFFFFFF,
284     (gint) 0x80000000,
285     (gint) 0x80000000,
286     (gint) 0xFF000000,
287     -1,
288     (gint) 0xFFFFFFFF,
289     -1,
290     (gint) 0xFFFFFFFFFFFFFFFFLL,
291     (gint) 0xEFFFFFFF,
292   };
293   int i;
294
295   g_value_init (&value, G_TYPE_INT);
296
297   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
298     fail_unless (gst_value_deserialize (&value, strings[i]),
299         "could not deserialize %s (%d)", strings[i], i);
300     fail_unless (g_value_get_int (&value) == results[i],
301         "resulting value is %d, not %d, for string %s (%d)",
302         g_value_get_int (&value), results[i], strings[i], i);
303   }
304 }
305
306 GST_END_TEST;
307
308 GST_START_TEST (test_deserialize_gint_failures)
309 {
310   GValue value = { 0 };
311   const char *strings[] = {
312     "-",                        /* not a complete number */
313     "- TEST",                   /* not a complete number */
314     "0x0000000100000000",       /* lowest long long that cannot fit in 32 bits */
315     "0xF000000000000000",
316     "0xFFFFFFF000000000",
317     "0xFFFFFFFF00000000",
318     "0x10000000000000000",      /* first number too long to fit into a long long */
319     /* invent a new processor first before trying to make this one pass */
320     "0x10000000000000000000000000000000000000000000",
321   };
322   int i;
323
324   g_value_init (&value, G_TYPE_INT);
325
326   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
327     fail_if (gst_value_deserialize (&value, strings[i]),
328         "deserialized %s (%d), while it should have failed", strings[i], i);
329   }
330 }
331
332 GST_END_TEST;
333
334 GST_START_TEST (test_deserialize_guint)
335 {
336   GValue value = { 0 };
337   const char *strings[] = {
338     "123456",
339     "-123456",
340     "0xFFFF",
341     "0x0000FFFF",
342     /* a positive long long, serializing to highest possible positive sint */
343     "0x7FFFFFFF",
344     /* a positive long long, serializing to lowest possible negative sint */
345     "0x80000000",
346     "2147483648",
347     /* a negative long long, serializing to lowest possible negative sint */
348     "0xFFFFFFFF80000000",
349     /* a value typically used for rgb masks */
350     "0xFF000000",
351     /* a positive long long serializing to highest possible positive uint */
352     "0xFFFFFFFF",
353     "0xFFFFFFFF",
354     /* a negative long long serializing to highest possible positive uint */
355     "0xFFFFFFFFFFFFFFFF",
356     "0xEFFFFFFF",
357   };
358   guint results[] = {
359     123456,
360     (guint) - 123456,
361     0xFFFF,
362     0xFFFF,
363     0x7FFFFFFF,
364     0x80000000,
365     (guint) 2147483648LL,
366     0x80000000,
367     0xFF000000,
368     0xFFFFFFFF,
369     G_MAXUINT,
370     (guint) 0xFFFFFFFFFFFFFFFFLL,
371     0xEFFFFFFF,
372   };
373   int i;
374
375   g_value_init (&value, G_TYPE_UINT);
376
377   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
378     fail_unless (gst_value_deserialize (&value, strings[i]),
379         "could not deserialize %s (%d)", strings[i], i);
380     fail_unless (g_value_get_uint (&value) == results[i],
381         "resulting value is %d, not %d, for string %s (%d)",
382         g_value_get_uint (&value), results[i], strings[i], i);
383   }
384 }
385
386 GST_END_TEST;
387
388 GST_START_TEST (test_deserialize_guint_failures)
389 {
390   GValue value = { 0 };
391   const char *strings[] = {
392     "-",                        /* not a complete number */
393     "- TEST",                   /* not a complete number */
394 #if 0
395 /* FIXME: these values should not be deserializable, since they overflow
396  * the target format */
397     "0x0000000100000000",       /* lowest long long that cannot fit in 32 bits */
398     "0xF000000000000000",
399     "0xFFFFFFF000000000",
400     "0xFFFFFFFF00000000",
401     "0x10000000000000000",      /* first number too long to fit into a long long */
402     /* invent a new processor first before trying to make this one pass */
403     "0x10000000000000000000000000000000000000000000",
404 #endif
405   };
406   int i;
407
408   g_value_init (&value, G_TYPE_UINT);
409
410   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
411     fail_if (gst_value_deserialize (&value, strings[i]),
412         "deserialized %s (%d), while it should have failed", strings[i], i);
413   }
414 }
415
416 GST_END_TEST;
417
418 GST_START_TEST (test_serialize_flags)
419 {
420   GValue value = { 0 };
421   gchar *string;
422   GstSeekFlags flags[] = {
423     0,
424     GST_SEEK_FLAG_NONE,
425     GST_SEEK_FLAG_FLUSH,
426     GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
427   };
428   const char *results[] = {
429     "GST_SEEK_FLAG_NONE",
430     "GST_SEEK_FLAG_NONE",
431     "GST_SEEK_FLAG_FLUSH",
432     "GST_SEEK_FLAG_FLUSH+GST_SEEK_FLAG_ACCURATE",
433   };
434   int i;
435
436   g_value_init (&value, GST_TYPE_SEEK_FLAGS);
437
438   for (i = 0; i < G_N_ELEMENTS (flags); ++i) {
439     g_value_set_flags (&value, flags[i]);
440     string = gst_value_serialize (&value);
441     fail_if (string == NULL, "could not serialize flags %d", i);
442     fail_unless (strcmp (string, results[i]) == 0,
443         "resulting value is %s, not %s, for flags #%d", string, results[i], i);
444     g_free (string);
445   }
446 }
447
448 GST_END_TEST;
449
450
451 GST_START_TEST (test_deserialize_flags)
452 {
453   GValue value = { 0 };
454   const char *strings[] = {
455     "",
456     "0",
457     "GST_SEEK_FLAG_NONE",
458     "GST_SEEK_FLAG_FLUSH",
459     "0xf",
460     "15",
461     "GST_SEEK_FLAG_FLUSH+GST_SEEK_FLAG_ACCURATE",
462   };
463   GstSeekFlags results[] = {
464     GST_SEEK_FLAG_NONE,
465     GST_SEEK_FLAG_NONE,
466     GST_SEEK_FLAG_NONE,
467     GST_SEEK_FLAG_FLUSH,
468     0xf,
469     15,
470     GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
471   };
472   int i;
473
474   g_value_init (&value, GST_TYPE_SEEK_FLAGS);
475
476   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
477     fail_unless (gst_value_deserialize (&value, strings[i]),
478         "could not deserialize %s (%d)", strings[i], i);
479     fail_unless (g_value_get_flags (&value) == results[i],
480         "resulting value is %d, not %d, for string %s (%d)",
481         g_value_get_flags (&value), results[i], strings[i], i);
482   }
483
484   fail_if (gst_value_deserialize (&value, "foo"),
485       "flag deserializing for bogus value should have failed!");
486   fail_if (gst_value_deserialize (&value, "GST_SEEK_FLAG_FLUSH+foo"),
487       "flag deserializing for bogus value should have failed!");
488   fail_if (gst_value_deserialize (&value,
489           "GST_SEEK_FLAG_FLUSH+foo+GST_SEEK_FLAG_ACCURATE"),
490       "flag deserializing for bogus value should have failed!");
491 }
492
493 GST_END_TEST;
494
495 GST_START_TEST (test_deserialize_gtype)
496 {
497   GValue value = { 0 };
498   const char *strings[] = {
499     "gchararray",
500     "gint",
501   };
502   GType results[] = {
503     G_TYPE_STRING,
504     G_TYPE_INT,
505   };
506   int i;
507
508   g_value_init (&value, G_TYPE_GTYPE);
509
510   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
511     fail_unless (gst_value_deserialize (&value, strings[i]),
512         "could not deserialize %s (%d)", strings[i], i);
513     fail_unless (g_value_get_gtype (&value) == results[i],
514         "resulting value is %" G_GSIZE_FORMAT ", not %" G_GSIZE_FORMAT
515         ", for string %s (%d)",
516         g_value_get_gtype (&value), results[i], strings[i], i);
517   }
518 }
519
520 GST_END_TEST;
521
522 GST_START_TEST (test_deserialize_gtype_failures)
523 {
524   GValue value = { 0 };
525   const char *strings[] = {
526     "-",                        /* not a gtype */
527   };
528   int i;
529
530   g_value_init (&value, G_TYPE_GTYPE);
531
532   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
533     fail_if (gst_value_deserialize (&value, strings[i]),
534         "deserialized %s (%d), while it should have failed", strings[i], i);
535   }
536 }
537
538 GST_END_TEST;
539
540 GST_START_TEST (test_deserialize_bitmask)
541 {
542   GValue value = { 0 };
543   const char *strings[] = {
544     "0xffffffffffffffff",
545     "0x1234567890ABCDEF",
546   };
547   guint64 results[] = {
548     0xffffffffffffffffULL,
549     0x1234567890ABCDEFULL,
550   };
551   int i;
552
553   g_value_init (&value, GST_TYPE_BITMASK);
554
555   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
556     fail_unless (gst_value_deserialize (&value, strings[i]),
557         "could not deserialize %s (%d)", strings[i], i);
558     fail_unless (gst_value_get_bitmask (&value) == results[i],
559         "resulting value is 0x%016" G_GINT64_MODIFIER "x, not 0x%016"
560         G_GINT64_MODIFIER "x, for string %s (%d)",
561         gst_value_get_bitmask (&value), results[i], strings[i], i);
562   }
563 }
564
565 GST_END_TEST;
566
567 static void
568 check_flagset_mask_serialisation (GValue * value, guint test_flags,
569     guint test_mask)
570 {
571   gchar *string;
572   gst_value_set_flagset (value, test_flags, test_mask);
573
574   /* Normalise our test flags against the mask now for easier testing,
575    * as that's what we expect to get back from the flagset after it
576    * normalises internally */
577   test_flags &= test_mask;
578
579   /* Check the values got stored correctly */
580   fail_unless (gst_value_get_flagset_flags (value) == test_flags,
581       "resulting flags value is 0x%u, not 0x%x",
582       gst_value_get_flagset_flags (value), test_flags);
583   fail_unless (gst_value_get_flagset_mask (value) == test_mask,
584       "resulting mask is 0x%u, not 0x%x",
585       gst_value_get_flagset_mask (value), test_mask);
586
587   string = gst_value_serialize (value);
588   fail_if (string == NULL, "could not serialize flagset");
589
590   GST_DEBUG ("Serialized flagset to: %s", string);
591
592   fail_unless (gst_value_deserialize (value, string),
593       "could not deserialize %s", string);
594
595   fail_unless (gst_value_get_flagset_flags (value) == test_flags,
596       "resulting flags value is 0x%u, not 0x%x, for string %s",
597       gst_value_get_flagset_flags (value), test_flags, string);
598
599   fail_unless (gst_value_get_flagset_mask (value) == test_mask,
600       "resulting mask is 0x%u, not 0x%x, for string %s",
601       gst_value_get_flagset_mask (value), test_mask, string);
602
603   g_free (string);
604 }
605
606 GST_START_TEST (test_flagset)
607 {
608   GValue value = G_VALUE_INIT;
609   GValue value2 = G_VALUE_INIT;
610   GValue dest = G_VALUE_INIT;
611   gchar *string;
612   GType test_flagset_type;
613   guint test_flags, test_mask;
614
615   /* Test serialisation of abstract type */
616   g_value_init (&value, GST_TYPE_FLAG_SET);
617
618   test_flags = 0xf1f1;
619   test_mask = 0xffff;
620
621   gst_value_set_flagset (&value, test_flags, test_mask);
622   string = gst_value_serialize (&value);
623   fail_if (string == NULL, "could not serialize flagset");
624
625   fail_unless (gst_value_deserialize (&value, string),
626       "could not deserialize %s", string);
627
628   fail_unless (gst_value_get_flagset_flags (&value) == test_flags,
629       "resulting value is 0x%u, not 0x%x, for string %s",
630       gst_value_get_flagset_flags (&value), test_flags, string);
631
632   fail_unless (gst_value_get_flagset_mask (&value) == test_mask,
633       "resulting value is 0x%u, not 0x%x, for string %s",
634       gst_value_get_flagset_mask (&value), test_mask, string);
635
636   g_free (string);
637   g_value_unset (&value);
638
639   /* Check we can't wrap a random non-flags type */
640   ASSERT_CRITICAL (gst_flagset_register (GST_TYPE_OBJECT));
641
642   test_flagset_type = gst_flagset_register (GST_TYPE_SEEK_FLAGS);
643
644   fail_unless (g_type_is_a (test_flagset_type, GST_TYPE_FLAG_SET));
645
646   g_value_init (&value, test_flagset_type);
647
648   test_flags =
649       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE |
650       GST_SEEK_FLAG_TRICKMODE_KEY_UNITS;
651   test_mask =
652       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE |
653       GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
654
655   check_flagset_mask_serialisation (&value, test_flags, test_mask);
656   /* Check serialisation works with the generic 'exact' flag */
657   check_flagset_mask_serialisation (&value, test_flags,
658       GST_FLAG_SET_MASK_EXACT);
659
660   /* Check deserialisation of flagset in 'flags' form, without
661    * the hex strings at the start */
662   test_flags = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE;
663   test_mask = GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_TRICKMODE |
664       GST_SEEK_FLAG_TRICKMODE_NO_AUDIO;
665   string = g_strdup ("+flush+trickmode/trickmode-no-audio");
666
667   fail_unless (gst_value_deserialize (&value, string),
668       "could not deserialize %s", string);
669
670   GST_DEBUG ("Deserialized %s to 0x%x:0x%x", string,
671       gst_value_get_flagset_flags (&value),
672       gst_value_get_flagset_mask (&value));
673
674   fail_unless (gst_value_get_flagset_flags (&value) == test_flags,
675       "resulting flags value is 0x%u, not 0x%x, for string %s",
676       gst_value_get_flagset_flags (&value), (test_flags & test_mask), string);
677
678   fail_unless (gst_value_get_flagset_mask (&value) == test_mask,
679       "resulting mask is 0x%u, not 0x%x, for string %s",
680       gst_value_get_flagset_mask (&value), test_mask, string);
681
682   g_free (string);
683   g_value_unset (&value);
684
685   /* Test that fixating don't-care fields works, using our
686    * sub-type flagset for good measure  */
687   g_value_init (&value, test_flagset_type);
688   gst_value_set_flagset (&value, test_flags, test_mask);
689
690   fail_unless (gst_value_fixate (&dest, &value));
691   fail_unless (gst_value_get_flagset_flags (&dest) == test_flags);
692   fail_unless (gst_value_get_flagset_mask (&dest) == GST_FLAG_SET_MASK_EXACT);
693
694   g_value_unset (&value);
695
696   /* Intersection tests */
697   g_value_init (&value, GST_TYPE_FLAG_SET);
698   g_value_init (&value2, test_flagset_type);
699
700   /* We want Accurate, but not Snap-Before */
701   gst_value_set_flagset (&value, GST_SEEK_FLAG_ACCURATE,
702       GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_SNAP_BEFORE);
703
704   /* This only cares that things are flushing */
705   gst_value_set_flagset (&value2, GST_SEEK_FLAG_FLUSH, GST_SEEK_FLAG_FLUSH);
706
707   test_flags = GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH;
708   test_mask =
709       GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SNAP_BEFORE;
710
711   /* GstFlagSet should always intersect with itself */
712   g_value_unset (&dest);
713   fail_unless (gst_value_can_intersect (&value, &value));
714   fail_unless (gst_value_intersect (&dest, &value, &value));
715
716   /* GstFlagSet subtype should intersect with itself */
717   g_value_unset (&dest);
718   fail_unless (gst_value_can_intersect (&value2, &value2));
719   fail_unless (gst_value_intersect (&dest, &value2, &value2));
720
721   /* Check we can intersect custom flagset subtype with flagset */
722   g_value_unset (&dest);
723   fail_unless (gst_value_can_intersect (&value2, &value));
724   fail_unless (gst_value_intersect (&dest, &value2, &value));
725
726   /* and in the other order */
727   g_value_unset (&dest);
728   fail_unless (gst_value_can_intersect (&value, &value2));
729   fail_unless (gst_value_intersect (&dest, &value, &value2));
730
731   fail_unless (gst_value_get_flagset_flags (&dest) == test_flags,
732       "resulting flags value is 0x%u, not 0x%x",
733       gst_value_get_flagset_flags (&dest), test_flags);
734
735   fail_unless (gst_value_get_flagset_mask (&dest) == test_mask,
736       "resulting mask is 0x%u, not 0x%x",
737       gst_value_get_flagset_mask (&dest), test_mask);
738
739   gst_value_set_flagset (&value,
740       GST_SEEK_FLAG_ACCURATE, GST_SEEK_FLAG_ACCURATE);
741   gst_value_set_flagset (&value2, GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
742       GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_SNAP_BEFORE | GST_SEEK_FLAG_FLUSH);
743   /* Check that accurate alone is a subset of accurate+!snap_before+flush,
744    * but not vice-versa */
745   fail_unless (gst_value_is_subset (&value, &value2));
746   fail_if (gst_value_is_subset (&value2, &value));
747
748   g_value_unset (&dest);
749   g_value_unset (&value);
750   g_value_unset (&value2);
751 }
752
753 GST_END_TEST;
754
755
756 GST_START_TEST (test_string)
757 {
758   const gchar *try[] = {
759     "Dude",
760     "Hi, I'm a string",
761     "tĆ¼Ć¼Ć¼t!",
762     "\"\""                      /* Empty string */
763   };
764   gchar *tmp;
765   GValue v = { 0, };
766   guint i;
767
768   g_value_init (&v, G_TYPE_STRING);
769   for (i = 0; i < G_N_ELEMENTS (try); i++) {
770     g_value_set_string (&v, try[i]);
771     tmp = gst_value_serialize (&v);
772     fail_if (tmp == NULL, "couldn't serialize: %s\n", try[i]);
773     fail_unless (gst_value_deserialize (&v, tmp),
774         "couldn't deserialize: %s\n", tmp);
775     g_free (tmp);
776
777     fail_unless (g_str_equal (g_value_get_string (&v), try[i]),
778         "\nserialized  : %s\ndeserialized: %s", try[i],
779         g_value_get_string (&v));
780   }
781   /* NULL strings should not be serializable */
782   g_value_set_string (&v, NULL);
783   fail_unless (gst_value_serialize (&v) == NULL);
784   g_value_unset (&v);
785 }
786
787 GST_END_TEST;
788
789 GST_START_TEST (test_deserialize_string)
790 {
791   struct
792   {
793     const gchar *from;
794     const gchar *to;
795   } tests[] = {
796     {
797     "\"foo\"", "foo"}, {
798     "\"foo\\%\"", "foo%"}, {
799     "\"0123456789_-+/:.\"", "0123456789_-+/:."}, {
800     "\"Hello\\ World\"", "Hello World"}, {
801     "\"Hello\\ World", "\"Hello\\ World"}, {
802     "\"\\", "\"\\"}, {
803     "\"\\0", "\"\\0"}, {
804     "\"t\\303\\274t\"", "tĆ¼t"}, {
805       /* utf8 octal sequence */
806     "", ""},                    /* empty strings */
807     {
808     "\"\"", ""}, {              /* quoted empty string -> empty string */
809     "\" \"", " "}, {            /* allow spaces to be not escaped */
810     "tĆ¼Ć¼t", "tĆ¼Ć¼t"},        /* allow special chars to be not escaped */
811         /* Expected FAILURES: */
812     {
813     "\"\\0\"", NULL}, {         /* unfinished escaped character */
814     "\"", NULL}, {              /* solitary quote */
815     "\"\\380\"", NULL}, {       /* invalid octal sequence */
816     "\"\\344\\204\\062\"", NULL}, {
817       /* invalid utf8: wrong end byte */
818     "\"\\344\\204\"", NULL}     /* invalid utf8: wrong number of bytes */
819   };
820   guint i;
821   GValue v = { 0, };
822
823   g_value_init (&v, G_TYPE_STRING);
824   for (i = 0; i < G_N_ELEMENTS (tests); i++) {
825     if (gst_value_deserialize (&v, tests[i].from)) {
826       fail_if (tests[i].to == NULL,
827           "I got %s instead of a failure", g_value_get_string (&v));
828       fail_unless (g_str_equal (g_value_get_string (&v), tests[i].to),
829           "\nwanted: %s\ngot    : %s", tests[i].to, g_value_get_string (&v));
830     } else {
831       fail_if (tests[i].to != NULL, "failed, but wanted: %s", tests[i].to);
832     }
833   }
834   g_value_unset (&v);
835 }
836
837 GST_END_TEST;
838
839 GST_START_TEST (test_value_compare)
840 {
841   GValue value1 = { 0 };
842   GValue value2 = { 0 };
843   GValue tmp = { 0 };
844   GstAllocationParams alloc_params = { 0 };
845
846   g_value_init (&value1, G_TYPE_INT);
847   g_value_set_int (&value1, 10);
848   g_value_init (&value2, G_TYPE_INT);
849   g_value_set_int (&value2, 20);
850   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
851   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
852   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
853   g_value_unset (&value1);
854   g_value_unset (&value2);
855
856   g_value_init (&value1, G_TYPE_DOUBLE);
857   g_value_set_double (&value1, 10);
858   g_value_init (&value2, G_TYPE_DOUBLE);
859   g_value_set_double (&value2, 20);
860   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
861   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
862   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
863   g_value_unset (&value1);
864   g_value_unset (&value2);
865
866   g_value_init (&value1, G_TYPE_STRING);
867   g_value_set_string (&value1, "a");
868   g_value_init (&value2, G_TYPE_STRING);
869   g_value_set_string (&value2, "b");
870   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
871   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
872   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
873   /* Test some NULL string comparisons */
874   g_value_set_string (&value2, NULL);
875   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
876   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_UNORDERED);
877   fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL);
878
879   g_value_unset (&value1);
880   g_value_unset (&value2);
881
882   /* comparing 2/3 with 3/4 */
883   g_value_init (&value1, GST_TYPE_FRACTION);
884   gst_value_set_fraction (&value1, 2, 3);
885   g_value_init (&value2, GST_TYPE_FRACTION);
886   gst_value_set_fraction (&value2, 3, 4);
887   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
888   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
889   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
890   g_value_unset (&value1);
891   g_value_unset (&value2);
892
893   /* comparing -4/5 with 2/-3 */
894   g_value_init (&value1, GST_TYPE_FRACTION);
895   gst_value_set_fraction (&value1, -4, 5);
896   g_value_init (&value2, GST_TYPE_FRACTION);
897   gst_value_set_fraction (&value2, 2, -3);
898   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
899   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
900   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
901   g_value_unset (&value1);
902   g_value_unset (&value2);
903
904   /* comparing 10/100 with 200/2000 */
905   g_value_init (&value1, GST_TYPE_FRACTION);
906   gst_value_set_fraction (&value1, 10, 100);
907   g_value_init (&value2, GST_TYPE_FRACTION);
908   gst_value_set_fraction (&value2, 200, 2000);
909   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
910   g_value_unset (&value1);
911   g_value_unset (&value2);
912
913   /* comparing -4/5 with 2/-3 */
914   g_value_init (&value1, GST_TYPE_FRACTION);
915   gst_value_set_fraction (&value1, -4, 5);
916   g_value_init (&value2, GST_TYPE_FRACTION);
917   gst_value_set_fraction (&value2, 2, -3);
918   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
919   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
920   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
921   g_value_unset (&value1);
922   g_value_unset (&value2);
923
924   /* Check that lists are equal regardless of order */
925   g_value_init (&value1, GST_TYPE_LIST);
926   g_value_init (&tmp, G_TYPE_INT);
927   g_value_set_int (&tmp, 1);
928   gst_value_list_append_value (&value1, &tmp);
929   g_value_set_int (&tmp, 2);
930   gst_value_list_append_value (&value1, &tmp);
931   g_value_set_int (&tmp, 3);
932   gst_value_list_append_value (&value1, &tmp);
933   g_value_set_int (&tmp, 4);
934   gst_value_list_append_value (&value1, &tmp);
935
936   g_value_init (&value2, GST_TYPE_LIST);
937   g_value_set_int (&tmp, 4);
938   gst_value_list_append_value (&value2, &tmp);
939   g_value_set_int (&tmp, 3);
940   gst_value_list_append_value (&value2, &tmp);
941   g_value_set_int (&tmp, 2);
942   gst_value_list_append_value (&value2, &tmp);
943   g_value_set_int (&tmp, 1);
944   gst_value_list_append_value (&value2, &tmp);
945
946   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
947       "value lists with different order were not equal when they should be");
948   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL,
949       "value lists with same order were not equal when they should be");
950   fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL,
951       "value lists with same order were not equal when they should be");
952
953   /* Carry over the lists to this next check: */
954   /* Lists with different sizes are unequal */
955   g_value_set_int (&tmp, 1);
956   gst_value_list_append_value (&value2, &tmp);
957
958   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
959       "Value lists with different size were equal when they shouldn't be");
960
961   /* Carry over the lists to this next check: */
962   /* Lists with same size but list1 contains one more element not in list2 */
963   g_value_set_int (&tmp, 5);
964   gst_value_list_append_value (&value1, &tmp);
965
966   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
967       "Value lists with different elements were equal when they shouldn't be");
968   fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL,
969       "Value lists with different elements were equal when they shouldn't be");
970
971   g_value_unset (&value1);
972   g_value_unset (&value2);
973   g_value_unset (&tmp);
974
975   /* Arrays are only equal when in the same order */
976   g_value_init (&value1, GST_TYPE_ARRAY);
977   g_value_init (&tmp, G_TYPE_INT);
978   g_value_set_int (&tmp, 1);
979   gst_value_array_append_value (&value1, &tmp);
980   g_value_set_int (&tmp, 2);
981   gst_value_array_append_value (&value1, &tmp);
982   g_value_set_int (&tmp, 3);
983   gst_value_array_append_value (&value1, &tmp);
984   g_value_set_int (&tmp, 4);
985   gst_value_array_append_value (&value1, &tmp);
986
987   g_value_init (&value2, GST_TYPE_ARRAY);
988   g_value_set_int (&tmp, 4);
989   gst_value_array_append_value (&value2, &tmp);
990   g_value_set_int (&tmp, 3);
991   gst_value_array_append_value (&value2, &tmp);
992   g_value_set_int (&tmp, 2);
993   gst_value_array_append_value (&value2, &tmp);
994   g_value_set_int (&tmp, 1);
995   gst_value_array_append_value (&value2, &tmp);
996
997   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
998       "Value arrays with different order were equal when they shouldn't be");
999   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL,
1000       "Identical value arrays were not equal when they should be");
1001   fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL,
1002       "Identical value arrays were not equal when they should be");
1003
1004   /* Carry over the arrays to this next check: */
1005   /* Arrays with different sizes are unequal */
1006   g_value_unset (&value2);
1007   g_value_init (&value2, GST_TYPE_ARRAY);
1008   g_value_copy (&value1, &value2);
1009
1010   g_value_set_int (&tmp, 1);
1011   gst_value_array_append_value (&value2, &tmp);
1012
1013   fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
1014       "Value arrays with different size were equal when they shouldn't be");
1015   /* order should not matter */
1016   fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL,
1017       "Value arrays with different size were equal when they shouldn't be");
1018
1019   g_value_unset (&value1);
1020   g_value_unset (&value2);
1021   g_value_unset (&tmp);
1022
1023   g_value_init (&value1, G_TYPE_VALUE_ARRAY);
1024   g_value_init (&value2, G_TYPE_VALUE_ARRAY);
1025
1026   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
1027       "Empty Value arrays aren't equals when they should");
1028
1029   g_value_unset (&value1);
1030   g_value_unset (&value2);
1031
1032   g_value_init (&value1, GST_TYPE_BITMASK);
1033   gst_value_set_bitmask (&value1, 0x123);
1034   g_value_init (&value2, GST_TYPE_BITMASK);
1035   gst_value_set_bitmask (&value2, 0x321);
1036   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1037   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_UNORDERED);
1038   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
1039   g_value_unset (&value1);
1040   g_value_unset (&value2);
1041
1042   /* Check that we can compare objects */
1043   g_value_init (&value1, GST_TYPE_BIN);
1044   g_value_take_object (&value1, gst_bin_new (NULL));
1045   g_value_init (&value2, GST_TYPE_BIN);
1046   g_value_take_object (&value2, gst_bin_new (NULL));
1047   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1048   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
1049   g_value_unset (&value1);
1050   g_value_unset (&value2);
1051
1052   /* Check that we can compare allocation params */
1053   g_value_init (&value1, GST_TYPE_ALLOCATION_PARAMS);
1054   g_value_set_boxed (&value1, &alloc_params);
1055   g_value_init (&value2, GST_TYPE_ALLOCATION_PARAMS);
1056   alloc_params.align = 1;
1057   g_value_set_boxed (&value2, &alloc_params);
1058   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1059   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
1060   g_value_unset (&value1);
1061   g_value_unset (&value2);
1062
1063   /* Check that we can compare structure */
1064   {
1065     GstStructure *s = gst_structure_new_empty ("test");
1066
1067     g_value_init (&value1, GST_TYPE_STRUCTURE);
1068     g_value_init (&value2, GST_TYPE_STRUCTURE);
1069     fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
1070
1071     gst_value_set_structure (&value1, s);
1072     fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
1073     gst_value_set_structure (&value2, s);
1074     fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
1075     g_value_unset (&value1);
1076     g_value_unset (&value2);
1077     gst_structure_free (s);
1078   }
1079 }
1080
1081 GST_END_TEST;
1082
1083 GST_START_TEST (test_value_intersect)
1084 {
1085   GValue dest = { 0 };
1086   GValue src1 = { 0 };
1087   GValue src2 = { 0 };
1088   GValue item = { 0 };
1089   gboolean ret;
1090
1091   g_value_init (&src1, G_TYPE_INT);
1092   g_value_set_int (&src1, 10);
1093   g_value_init (&src2, G_TYPE_INT);
1094   g_value_set_int (&src2, 20);
1095   ret = gst_value_intersect (&dest, &src1, &src2);
1096   fail_unless (ret == FALSE);
1097   g_value_unset (&src1);
1098   g_value_unset (&src2);
1099
1100   g_value_init (&src1, G_TYPE_STRING);
1101   g_value_set_static_string (&src1, "YUY2");
1102   g_value_init (&src2, GST_TYPE_LIST);
1103   g_value_init (&item, G_TYPE_STRING);
1104   g_value_set_static_string (&item, "YUY2");
1105   gst_value_list_append_value (&src2, &item);
1106   g_value_set_static_string (&item, "I420");
1107   gst_value_list_append_value (&src2, &item);
1108   g_value_set_static_string (&item, "ABCD");
1109   gst_value_list_append_value (&src2, &item);
1110
1111   fail_unless (gst_value_intersect (&dest, &src1, &src2));
1112   fail_unless (G_VALUE_HOLDS_STRING (&dest));
1113   fail_unless (g_str_equal (g_value_get_string (&dest), "YUY2"));
1114
1115   g_value_unset (&src1);
1116   g_value_unset (&src2);
1117   g_value_unset (&dest);
1118 }
1119
1120 GST_END_TEST;
1121
1122
1123 GST_START_TEST (test_value_subtract_int)
1124 {
1125   GValue dest = { 0 };
1126   GValue src1 = { 0 };
1127   GValue src2 = { 0 };
1128   const GValue *tmp;
1129   gboolean ret;
1130
1131   /*  int <-> int
1132    */
1133   g_value_init (&src1, G_TYPE_INT);
1134   g_value_set_int (&src1, 10);
1135   g_value_init (&src2, G_TYPE_INT);
1136   g_value_set_int (&src2, 20);
1137   /* subtract as in sets, result is 10 */
1138   ret = gst_value_subtract (&dest, &src1, &src2);
1139   fail_unless (ret == TRUE);
1140   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1141   g_value_unset (&dest);
1142
1143   /* same values, yields empty set */
1144   ret = gst_value_subtract (&dest, &src1, &src1);
1145   fail_unless (ret == FALSE);
1146   g_value_unset (&src1);
1147   g_value_unset (&src2);
1148
1149   /*  int <-> int_range
1150    */
1151
1152   /* would yield an empty set */
1153   g_value_init (&src1, G_TYPE_INT);
1154   g_value_set_int (&src1, 10);
1155   g_value_init (&src2, GST_TYPE_INT_RANGE);
1156   gst_value_set_int_range (&src2, 0, 20);
1157   ret = gst_value_subtract (&dest, &src1, &src2);
1158   fail_unless (ret == FALSE);
1159
1160   /* and the other way around, should create a list of two ranges. */
1161   ret = gst_value_subtract (&dest, &src2, &src1);
1162   fail_unless (ret == TRUE);
1163   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1164   tmp = gst_value_list_get_value (&dest, 0);
1165   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1166   fail_unless (gst_value_get_int_range_min (tmp) == 0);
1167   fail_unless (gst_value_get_int_range_max (tmp) == 9);
1168   tmp = gst_value_list_get_value (&dest, 1);
1169   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1170   fail_unless (gst_value_get_int_range_min (tmp) == 11);
1171   fail_unless (gst_value_get_int_range_max (tmp) == 20);
1172   g_value_unset (&dest);
1173   g_value_unset (&src1);
1174   g_value_unset (&src2);
1175
1176   /* border case 1, empty set */
1177   g_value_init (&src1, G_TYPE_INT);
1178   g_value_set_int (&src1, 10);
1179   g_value_init (&src2, GST_TYPE_INT_RANGE);
1180   gst_value_set_int_range (&src2, 10, 20);
1181   ret = gst_value_subtract (&dest, &src1, &src2);
1182   fail_unless (ret == FALSE);
1183
1184   /* and the other way around, should create a new range. */
1185   ret = gst_value_subtract (&dest, &src2, &src1);
1186   fail_unless (ret == TRUE);
1187   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1188   fail_unless (gst_value_get_int_range_min (&dest) == 11);
1189   fail_unless (gst_value_get_int_range_max (&dest) == 20);
1190   g_value_unset (&dest);
1191   g_value_unset (&src1);
1192   g_value_unset (&src2);
1193
1194   /* border case 2, empty set */
1195   g_value_init (&src1, G_TYPE_INT);
1196   g_value_set_int (&src1, 20);
1197   g_value_init (&src2, GST_TYPE_INT_RANGE);
1198   gst_value_set_int_range (&src2, 10, 20);
1199   ret = gst_value_subtract (&dest, &src1, &src2);
1200   fail_unless (ret == FALSE);
1201
1202   /* and the other way around, should create a new range. */
1203   ret = gst_value_subtract (&dest, &src2, &src1);
1204   fail_unless (ret == TRUE);
1205   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1206   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1207   fail_unless (gst_value_get_int_range_max (&dest) == 19);
1208   g_value_unset (&dest);
1209   g_value_unset (&src1);
1210   g_value_unset (&src2);
1211
1212   /* case 3, valid set */
1213   g_value_init (&src1, G_TYPE_INT);
1214   g_value_set_int (&src1, 0);
1215   g_value_init (&src2, GST_TYPE_INT_RANGE);
1216   gst_value_set_int_range (&src2, 10, 20);
1217   ret = gst_value_subtract (&dest, &src1, &src2);
1218   fail_unless (ret == TRUE);
1219   fail_unless (G_VALUE_HOLDS_INT (&dest) == TRUE);
1220   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1221   g_value_unset (&dest);
1222
1223   /* and the other way around, should keep the range. */
1224   ret = gst_value_subtract (&dest, &src2, &src1);
1225   fail_unless (ret == TRUE);
1226   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1227   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1228   fail_unless (gst_value_get_int_range_max (&dest) == 20);
1229   g_value_unset (&dest);
1230   g_value_unset (&src1);
1231   g_value_unset (&src2);
1232
1233   /*  int_range <-> int_range
1234    */
1235
1236   /* same range, empty set */
1237   g_value_init (&src1, GST_TYPE_INT_RANGE);
1238   gst_value_set_int_range (&src1, 10, 20);
1239   g_value_init (&src2, GST_TYPE_INT_RANGE);
1240   gst_value_set_int_range (&src2, 10, 20);
1241   ret = gst_value_subtract (&dest, &src1, &src2);
1242   fail_unless (ret == FALSE);
1243   ret = gst_value_subtract (&dest, &src2, &src1);
1244   fail_unless (ret == FALSE);
1245   g_value_unset (&src1);
1246   g_value_unset (&src2);
1247
1248   /* non overlapping ranges */
1249   g_value_init (&src1, GST_TYPE_INT_RANGE);
1250   gst_value_set_int_range (&src1, 10, 20);
1251   g_value_init (&src2, GST_TYPE_INT_RANGE);
1252   gst_value_set_int_range (&src2, 30, 40);
1253   ret = gst_value_subtract (&dest, &src1, &src2);
1254   fail_unless (ret == TRUE);
1255   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1256   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1257   fail_unless (gst_value_get_int_range_max (&dest) == 20);
1258   g_value_unset (&dest);
1259   /* the other way */
1260   ret = gst_value_subtract (&dest, &src2, &src1);
1261   fail_unless (ret == TRUE);
1262   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1263   fail_unless (gst_value_get_int_range_min (&dest) == 30);
1264   fail_unless (gst_value_get_int_range_max (&dest) == 40);
1265   g_value_unset (&dest);
1266   g_value_unset (&src1);
1267   g_value_unset (&src2);
1268
1269   /* completely overlapping ranges */
1270   g_value_init (&src1, GST_TYPE_INT_RANGE);
1271   gst_value_set_int_range (&src1, 10, 20);
1272   g_value_init (&src2, GST_TYPE_INT_RANGE);
1273   gst_value_set_int_range (&src2, 10, 30);
1274   ret = gst_value_subtract (&dest, &src1, &src2);
1275   fail_unless (ret == FALSE);
1276   /* the other way */
1277   ret = gst_value_subtract (&dest, &src2, &src1);
1278   fail_unless (ret == TRUE);
1279   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1280   fail_unless (gst_value_get_int_range_min (&dest) == 21);
1281   fail_unless (gst_value_get_int_range_max (&dest) == 30);
1282   g_value_unset (&dest);
1283   g_value_unset (&src1);
1284   g_value_unset (&src2);
1285
1286   /* partially overlapping ranges */
1287   g_value_init (&src1, GST_TYPE_INT_RANGE);
1288   gst_value_set_int_range (&src1, 10, 20);
1289   g_value_init (&src2, GST_TYPE_INT_RANGE);
1290   gst_value_set_int_range (&src2, 15, 30);
1291   ret = gst_value_subtract (&dest, &src1, &src2);
1292   fail_unless (ret == TRUE);
1293   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1294   fail_unless (gst_value_get_int_range_min (&dest) == 10);
1295   fail_unless (gst_value_get_int_range_max (&dest) == 14);
1296   g_value_unset (&dest);
1297   /* the other way */
1298   ret = gst_value_subtract (&dest, &src2, &src1);
1299   fail_unless (ret == TRUE);
1300   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
1301   fail_unless (gst_value_get_int_range_min (&dest) == 21);
1302   fail_unless (gst_value_get_int_range_max (&dest) == 30);
1303   g_value_unset (&dest);
1304   g_value_unset (&src1);
1305   g_value_unset (&src2);
1306
1307   /* create a hole { int_range, int_range } */
1308   g_value_init (&src1, GST_TYPE_INT_RANGE);
1309   gst_value_set_int_range (&src1, 10, 30);
1310   g_value_init (&src2, GST_TYPE_INT_RANGE);
1311   gst_value_set_int_range (&src2, 15, 20);
1312   ret = gst_value_subtract (&dest, &src1, &src2);
1313   fail_unless (ret == TRUE);
1314   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1315   tmp = gst_value_list_get_value (&dest, 0);
1316   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1317   fail_unless (gst_value_get_int_range_min (tmp) == 10);
1318   fail_unless (gst_value_get_int_range_max (tmp) == 14);
1319   tmp = gst_value_list_get_value (&dest, 1);
1320   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1321   fail_unless (gst_value_get_int_range_min (tmp) == 21);
1322   fail_unless (gst_value_get_int_range_max (tmp) == 30);
1323   g_value_unset (&dest);
1324   /* the other way */
1325   ret = gst_value_subtract (&dest, &src2, &src1);
1326   fail_unless (ret == FALSE);
1327   g_value_unset (&src1);
1328   g_value_unset (&src2);
1329
1330   /* create a hole, { int, int } */
1331   g_value_init (&src1, GST_TYPE_INT_RANGE);
1332   gst_value_set_int_range (&src1, 10, 30);
1333   g_value_init (&src2, GST_TYPE_INT_RANGE);
1334   gst_value_set_int_range (&src2, 11, 29);
1335   ret = gst_value_subtract (&dest, &src1, &src2);
1336   fail_unless (ret == TRUE);
1337   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1338   tmp = gst_value_list_get_value (&dest, 0);
1339   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1340   fail_unless (g_value_get_int (tmp) == 10);
1341   tmp = gst_value_list_get_value (&dest, 1);
1342   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1343   fail_unless (g_value_get_int (tmp) == 30);
1344   g_value_unset (&dest);
1345   /* the other way */
1346   ret = gst_value_subtract (&dest, &src2, &src1);
1347   fail_unless (ret == FALSE);
1348   g_value_unset (&src1);
1349   g_value_unset (&src2);
1350
1351   /* create a hole, { int, int_range } */
1352   g_value_init (&src1, GST_TYPE_INT_RANGE);
1353   gst_value_set_int_range (&src1, 10, 30);
1354   g_value_init (&src2, GST_TYPE_INT_RANGE);
1355   gst_value_set_int_range (&src2, 11, 28);
1356   ret = gst_value_subtract (&dest, &src1, &src2);
1357   fail_unless (ret == TRUE);
1358   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1359   tmp = gst_value_list_get_value (&dest, 0);
1360   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1361   fail_unless (g_value_get_int (tmp) == 10);
1362   tmp = gst_value_list_get_value (&dest, 1);
1363   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1364   fail_unless (gst_value_get_int_range_min (tmp) == 29);
1365   fail_unless (gst_value_get_int_range_max (tmp) == 30);
1366   g_value_unset (&dest);
1367   /* the other way */
1368   ret = gst_value_subtract (&dest, &src2, &src1);
1369   fail_unless (ret == FALSE);
1370   g_value_unset (&src1);
1371   g_value_unset (&src2);
1372
1373   /* create a hole, { int_range, int } */
1374   g_value_init (&src1, GST_TYPE_INT_RANGE);
1375   gst_value_set_int_range (&src1, 10, 30);
1376   g_value_init (&src2, GST_TYPE_INT_RANGE);
1377   gst_value_set_int_range (&src2, 12, 29);
1378   ret = gst_value_subtract (&dest, &src1, &src2);
1379   fail_unless (ret == TRUE);
1380   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1381   tmp = gst_value_list_get_value (&dest, 0);
1382   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
1383   fail_unless (gst_value_get_int_range_min (tmp) == 10);
1384   fail_unless (gst_value_get_int_range_max (tmp) == 11);
1385   tmp = gst_value_list_get_value (&dest, 1);
1386   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
1387   fail_unless (g_value_get_int (tmp) == 30);
1388   g_value_unset (&dest);
1389   /* the other way */
1390   ret = gst_value_subtract (&dest, &src2, &src1);
1391   fail_unless (ret == FALSE);
1392   g_value_unset (&src1);
1393   g_value_unset (&src2);
1394 }
1395
1396 GST_END_TEST;
1397
1398 GST_START_TEST (test_value_subtract_int64)
1399 {
1400   GValue dest = { 0 };
1401   GValue src1 = { 0 };
1402   GValue src2 = { 0 };
1403   const GValue *tmp;
1404   gboolean ret;
1405
1406   /*  int64 <-> int64
1407    */
1408   g_value_init (&src1, G_TYPE_INT64);
1409   g_value_set_int64 (&src1, 10);
1410   g_value_init (&src2, G_TYPE_INT64);
1411   g_value_set_int64 (&src2, 20);
1412   /* subtract as in sets, result is 10 */
1413   ret = gst_value_subtract (&dest, &src1, &src2);
1414   fail_unless (ret == TRUE);
1415   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1416   g_value_unset (&dest);
1417
1418   /* same values, yields empty set */
1419   ret = gst_value_subtract (&dest, &src1, &src1);
1420   fail_unless (ret == FALSE);
1421   g_value_unset (&src1);
1422   g_value_unset (&src2);
1423
1424   /*  int64 <-> int64_range
1425    */
1426
1427   /* would yield an empty set */
1428   g_value_init (&src1, G_TYPE_INT64);
1429   g_value_set_int64 (&src1, 10);
1430   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1431   gst_value_set_int64_range (&src2, 0, 20);
1432   ret = gst_value_subtract (&dest, &src1, &src2);
1433   fail_unless (ret == FALSE);
1434
1435   /* and the other way around, should create a list of two ranges. */
1436   ret = gst_value_subtract (&dest, &src2, &src1);
1437   fail_unless (ret == TRUE);
1438   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1439   tmp = gst_value_list_get_value (&dest, 0);
1440   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1441   fail_unless (gst_value_get_int64_range_min (tmp) == 0);
1442   fail_unless (gst_value_get_int64_range_max (tmp) == 9);
1443   tmp = gst_value_list_get_value (&dest, 1);
1444   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1445   fail_unless (gst_value_get_int64_range_min (tmp) == 11);
1446   fail_unless (gst_value_get_int64_range_max (tmp) == 20);
1447   g_value_unset (&dest);
1448   g_value_unset (&src1);
1449   g_value_unset (&src2);
1450
1451   /* border case 1, empty set */
1452   g_value_init (&src1, G_TYPE_INT64);
1453   g_value_set_int64 (&src1, 10);
1454   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1455   gst_value_set_int64_range (&src2, 10, 20);
1456   ret = gst_value_subtract (&dest, &src1, &src2);
1457   fail_unless (ret == FALSE);
1458
1459   /* and the other way around, should create a new range. */
1460   ret = gst_value_subtract (&dest, &src2, &src1);
1461   fail_unless (ret == TRUE);
1462   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1463   fail_unless (gst_value_get_int64_range_min (&dest) == 11);
1464   fail_unless (gst_value_get_int64_range_max (&dest) == 20);
1465   g_value_unset (&dest);
1466   g_value_unset (&src1);
1467   g_value_unset (&src2);
1468
1469   /* border case 2, empty set */
1470   g_value_init (&src1, G_TYPE_INT64);
1471   g_value_set_int64 (&src1, 20);
1472   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1473   gst_value_set_int64_range (&src2, 10, 20);
1474   ret = gst_value_subtract (&dest, &src1, &src2);
1475   fail_unless (ret == FALSE);
1476
1477   /* and the other way around, should create a new range. */
1478   ret = gst_value_subtract (&dest, &src2, &src1);
1479   fail_unless (ret == TRUE);
1480   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1481   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1482   fail_unless (gst_value_get_int64_range_max (&dest) == 19);
1483   g_value_unset (&dest);
1484   g_value_unset (&src1);
1485   g_value_unset (&src2);
1486
1487   /* case 3, valid set */
1488   g_value_init (&src1, G_TYPE_INT64);
1489   g_value_set_int64 (&src1, 0);
1490   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1491   gst_value_set_int64_range (&src2, 10, 20);
1492   ret = gst_value_subtract (&dest, &src1, &src2);
1493   fail_unless (ret == TRUE);
1494   fail_unless (G_VALUE_HOLDS_INT64 (&dest) == TRUE);
1495   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1496   g_value_unset (&dest);
1497
1498   /* and the other way around, should keep the range. */
1499   ret = gst_value_subtract (&dest, &src2, &src1);
1500   fail_unless (ret == TRUE);
1501   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1502   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1503   fail_unless (gst_value_get_int64_range_max (&dest) == 20);
1504   g_value_unset (&dest);
1505   g_value_unset (&src1);
1506   g_value_unset (&src2);
1507
1508   /*  int64_range <-> int64_range
1509    */
1510
1511   /* same range, empty set */
1512   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1513   gst_value_set_int64_range (&src1, 10, 20);
1514   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1515   gst_value_set_int64_range (&src2, 10, 20);
1516   ret = gst_value_subtract (&dest, &src1, &src2);
1517   fail_unless (ret == FALSE);
1518   ret = gst_value_subtract (&dest, &src2, &src1);
1519   fail_unless (ret == FALSE);
1520   g_value_unset (&src1);
1521   g_value_unset (&src2);
1522
1523   /* non overlapping ranges */
1524   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1525   gst_value_set_int64_range (&src1, 10, 20);
1526   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1527   gst_value_set_int64_range (&src2, 30, 40);
1528   ret = gst_value_subtract (&dest, &src1, &src2);
1529   fail_unless (ret == TRUE);
1530   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1531   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1532   fail_unless (gst_value_get_int64_range_max (&dest) == 20);
1533   g_value_unset (&dest);
1534   /* the other way */
1535   ret = gst_value_subtract (&dest, &src2, &src1);
1536   fail_unless (ret == TRUE);
1537   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1538   fail_unless (gst_value_get_int64_range_min (&dest) == 30);
1539   fail_unless (gst_value_get_int64_range_max (&dest) == 40);
1540   g_value_unset (&dest);
1541   g_value_unset (&src1);
1542   g_value_unset (&src2);
1543
1544   /* completely overlapping ranges */
1545   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1546   gst_value_set_int64_range (&src1, 10, 20);
1547   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1548   gst_value_set_int64_range (&src2, 10, 30);
1549   ret = gst_value_subtract (&dest, &src1, &src2);
1550   fail_unless (ret == FALSE);
1551   /* the other way */
1552   ret = gst_value_subtract (&dest, &src2, &src1);
1553   fail_unless (ret == TRUE);
1554   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1555   fail_unless (gst_value_get_int64_range_min (&dest) == 21);
1556   fail_unless (gst_value_get_int64_range_max (&dest) == 30);
1557   g_value_unset (&dest);
1558   g_value_unset (&src1);
1559   g_value_unset (&src2);
1560
1561   /* partially overlapping ranges */
1562   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1563   gst_value_set_int64_range (&src1, 10, 20);
1564   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1565   gst_value_set_int64_range (&src2, 15, 30);
1566   ret = gst_value_subtract (&dest, &src1, &src2);
1567   fail_unless (ret == TRUE);
1568   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1569   fail_unless (gst_value_get_int64_range_min (&dest) == 10);
1570   fail_unless (gst_value_get_int64_range_max (&dest) == 14);
1571   g_value_unset (&dest);
1572   /* the other way */
1573   ret = gst_value_subtract (&dest, &src2, &src1);
1574   fail_unless (ret == TRUE);
1575   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
1576   fail_unless (gst_value_get_int64_range_min (&dest) == 21);
1577   fail_unless (gst_value_get_int64_range_max (&dest) == 30);
1578   g_value_unset (&dest);
1579   g_value_unset (&src1);
1580   g_value_unset (&src2);
1581
1582   /* create a hole { int64_range, int64_range } */
1583   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1584   gst_value_set_int64_range (&src1, 10, 30);
1585   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1586   gst_value_set_int64_range (&src2, 15, 20);
1587   ret = gst_value_subtract (&dest, &src1, &src2);
1588   fail_unless (ret == TRUE);
1589   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1590   tmp = gst_value_list_get_value (&dest, 0);
1591   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1592   fail_unless (gst_value_get_int64_range_min (tmp) == 10);
1593   fail_unless (gst_value_get_int64_range_max (tmp) == 14);
1594   tmp = gst_value_list_get_value (&dest, 1);
1595   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1596   fail_unless (gst_value_get_int64_range_min (tmp) == 21);
1597   fail_unless (gst_value_get_int64_range_max (tmp) == 30);
1598   g_value_unset (&dest);
1599   /* the other way */
1600   ret = gst_value_subtract (&dest, &src2, &src1);
1601   fail_unless (ret == FALSE);
1602   g_value_unset (&src1);
1603   g_value_unset (&src2);
1604
1605   /* create a hole, { int64, int64 } */
1606   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1607   gst_value_set_int64_range (&src1, 10, 30);
1608   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1609   gst_value_set_int64_range (&src2, 11, 29);
1610   ret = gst_value_subtract (&dest, &src1, &src2);
1611   fail_unless (ret == TRUE);
1612   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1613   tmp = gst_value_list_get_value (&dest, 0);
1614   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1615   fail_unless (g_value_get_int64 (tmp) == 10);
1616   tmp = gst_value_list_get_value (&dest, 1);
1617   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1618   fail_unless (g_value_get_int64 (tmp) == 30);
1619   g_value_unset (&dest);
1620   /* the other way */
1621   ret = gst_value_subtract (&dest, &src2, &src1);
1622   fail_unless (ret == FALSE);
1623   g_value_unset (&src1);
1624   g_value_unset (&src2);
1625
1626   /* create a hole, { int64, int64_range } */
1627   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1628   gst_value_set_int64_range (&src1, 10, 30);
1629   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1630   gst_value_set_int64_range (&src2, 11, 28);
1631   ret = gst_value_subtract (&dest, &src1, &src2);
1632   fail_unless (ret == TRUE);
1633   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1634   tmp = gst_value_list_get_value (&dest, 0);
1635   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1636   fail_unless (g_value_get_int64 (tmp) == 10);
1637   tmp = gst_value_list_get_value (&dest, 1);
1638   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1639   fail_unless (gst_value_get_int64_range_min (tmp) == 29);
1640   fail_unless (gst_value_get_int64_range_max (tmp) == 30);
1641   g_value_unset (&dest);
1642   /* the other way */
1643   ret = gst_value_subtract (&dest, &src2, &src1);
1644   fail_unless (ret == FALSE);
1645   g_value_unset (&src1);
1646   g_value_unset (&src2);
1647
1648   /* create a hole, { int64_range, int64 } */
1649   g_value_init (&src1, GST_TYPE_INT64_RANGE);
1650   gst_value_set_int64_range (&src1, 10, 30);
1651   g_value_init (&src2, GST_TYPE_INT64_RANGE);
1652   gst_value_set_int64_range (&src2, 12, 29);
1653   ret = gst_value_subtract (&dest, &src1, &src2);
1654   fail_unless (ret == TRUE);
1655   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1656   tmp = gst_value_list_get_value (&dest, 0);
1657   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
1658   fail_unless (gst_value_get_int64_range_min (tmp) == 10);
1659   fail_unless (gst_value_get_int64_range_max (tmp) == 11);
1660   tmp = gst_value_list_get_value (&dest, 1);
1661   fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
1662   fail_unless (g_value_get_int64 (tmp) == 30);
1663   g_value_unset (&dest);
1664   /* the other way */
1665   ret = gst_value_subtract (&dest, &src2, &src1);
1666   fail_unless (ret == FALSE);
1667   g_value_unset (&src1);
1668   g_value_unset (&src2);
1669 }
1670
1671 GST_END_TEST;
1672
1673 GST_START_TEST (test_value_subtract_double)
1674 {
1675   GValue dest = { 0 };
1676   GValue src1 = { 0 };
1677   GValue src2 = { 0 };
1678   const GValue *tmp;
1679   gboolean ret;
1680
1681   /*  double <-> double
1682    */
1683   g_value_init (&src1, G_TYPE_DOUBLE);
1684   g_value_set_double (&src1, 10.0);
1685   g_value_init (&src2, G_TYPE_DOUBLE);
1686   g_value_set_double (&src2, 20.0);
1687   /* subtract as in sets, result is 10 */
1688   ret = gst_value_subtract (&dest, &src1, &src2);
1689   fail_unless (ret == TRUE);
1690   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1691   g_value_unset (&dest);
1692
1693   /* same values, yields empty set */
1694   ret = gst_value_subtract (&dest, &src1, &src1);
1695   fail_unless (ret == FALSE);
1696   g_value_unset (&src1);
1697   g_value_unset (&src2);
1698
1699   /*  double <-> double_range
1700    */
1701
1702   /* would yield an empty set */
1703   g_value_init (&src1, G_TYPE_DOUBLE);
1704   g_value_set_double (&src1, 10.0);
1705   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1706   gst_value_set_double_range (&src2, 0.0, 20.0);
1707   ret = gst_value_subtract (&dest, &src1, &src2);
1708   fail_unless (ret == FALSE);
1709
1710   /* and the other way around, we cannot create open ranges
1711    * so the result is the range again */
1712   ret = gst_value_subtract (&dest, &src2, &src1);
1713   fail_unless (ret == TRUE);
1714   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1715   fail_unless (gst_value_get_double_range_min (&dest) == 0.0);
1716   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1717   g_value_unset (&dest);
1718   g_value_unset (&src1);
1719   g_value_unset (&src2);
1720
1721   /* border case 1, empty set */
1722   g_value_init (&src1, G_TYPE_DOUBLE);
1723   g_value_set_double (&src1, 10.0);
1724   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1725   gst_value_set_double_range (&src2, 10.0, 20.0);
1726   ret = gst_value_subtract (&dest, &src1, &src2);
1727   fail_unless (ret == FALSE);
1728
1729   /* and the other way around, should keep same range as
1730    * we don't have open ranges. */
1731   ret = gst_value_subtract (&dest, &src2, &src1);
1732   fail_unless (ret == TRUE);
1733   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1734   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1735   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1736   g_value_unset (&dest);
1737   g_value_unset (&src1);
1738   g_value_unset (&src2);
1739
1740   /* border case 2, empty set */
1741   g_value_init (&src1, G_TYPE_DOUBLE);
1742   g_value_set_double (&src1, 20.0);
1743   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1744   gst_value_set_double_range (&src2, 10.0, 20.0);
1745   ret = gst_value_subtract (&dest, &src1, &src2);
1746   fail_unless (ret == FALSE);
1747
1748   /* and the other way around, should keep same range as
1749    * we don't have open ranges. */
1750   ret = gst_value_subtract (&dest, &src2, &src1);
1751   fail_unless (ret == TRUE);
1752   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1753   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1754   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1755   g_value_unset (&dest);
1756   g_value_unset (&src1);
1757   g_value_unset (&src2);
1758
1759   /* case 3, valid set */
1760   g_value_init (&src1, G_TYPE_DOUBLE);
1761   g_value_set_double (&src1, 0.0);
1762   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1763   gst_value_set_double_range (&src2, 10.0, 20.0);
1764   ret = gst_value_subtract (&dest, &src1, &src2);
1765   fail_unless (ret == TRUE);
1766   fail_unless (G_VALUE_HOLDS_DOUBLE (&dest) == TRUE);
1767   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1768   g_value_unset (&dest);
1769
1770   /* and the other way around, should keep the range. */
1771   ret = gst_value_subtract (&dest, &src2, &src1);
1772   fail_unless (ret == TRUE);
1773   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1774   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1775   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1776   g_value_unset (&dest);
1777   g_value_unset (&src1);
1778   g_value_unset (&src2);
1779
1780   /*  double_range <-> double_range
1781    */
1782
1783   /* Check equality */
1784   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1785   gst_value_set_double_range (&src1, 10.0, 20.0);
1786   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1787   gst_value_set_double_range (&src2, 10.0, 15.0);
1788   /* They are not equal (higher bound is different */
1789   fail_if (gst_value_compare (&src1, &src2) == GST_VALUE_EQUAL);
1790   g_value_unset (&src1);
1791   /* They are not equal (lower bound is different */
1792   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1793   gst_value_set_double_range (&src1, 5.0, 15.0);
1794   fail_if (gst_value_compare (&src1, &src2) == GST_VALUE_EQUAL);
1795   g_value_unset (&src1);
1796   /* And finally check equality */
1797   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1798   gst_value_set_double_range (&src1, 10.0, 15.0);
1799   fail_unless (gst_value_compare (&src1, &src2) == GST_VALUE_EQUAL);
1800   g_value_unset (&src1);
1801   g_value_unset (&src2);
1802
1803   /* same range, empty set */
1804   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1805   gst_value_set_double_range (&src1, 10.0, 20.0);
1806   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1807   gst_value_set_double_range (&src2, 10.0, 20.0);
1808   ret = gst_value_subtract (&dest, &src1, &src2);
1809   fail_unless (ret == FALSE);
1810   ret = gst_value_subtract (&dest, &src2, &src1);
1811   fail_unless (ret == FALSE);
1812   g_value_unset (&src1);
1813   g_value_unset (&src2);
1814
1815   /* non overlapping ranges */
1816   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1817   gst_value_set_double_range (&src1, 10.0, 20.0);
1818   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1819   gst_value_set_double_range (&src2, 30.0, 40.0);
1820   ret = gst_value_subtract (&dest, &src1, &src2);
1821   fail_unless (ret == TRUE);
1822   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1823   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1824   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
1825   g_value_unset (&dest);
1826   /* the other way */
1827   ret = gst_value_subtract (&dest, &src2, &src1);
1828   fail_unless (ret == TRUE);
1829   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1830   fail_unless (gst_value_get_double_range_min (&dest) == 30.0);
1831   fail_unless (gst_value_get_double_range_max (&dest) == 40.0);
1832   g_value_unset (&dest);
1833   g_value_unset (&src1);
1834   g_value_unset (&src2);
1835
1836   /* completely overlapping ranges */
1837   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1838   gst_value_set_double_range (&src1, 10.0, 20.0);
1839   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1840   gst_value_set_double_range (&src2, 10.0, 30.0);
1841   ret = gst_value_subtract (&dest, &src1, &src2);
1842   fail_unless (ret == FALSE);
1843   /* the other way */
1844   ret = gst_value_subtract (&dest, &src2, &src1);
1845   fail_unless (ret == TRUE);
1846   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1847   fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
1848   fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
1849   g_value_unset (&dest);
1850   g_value_unset (&src1);
1851   g_value_unset (&src2);
1852
1853   /* partially overlapping ranges */
1854   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1855   gst_value_set_double_range (&src1, 10.0, 20.0);
1856   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1857   gst_value_set_double_range (&src2, 15.0, 30.0);
1858   ret = gst_value_subtract (&dest, &src1, &src2);
1859   fail_unless (ret == TRUE);
1860   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1861   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
1862   fail_unless (gst_value_get_double_range_max (&dest) == 15.0);
1863   g_value_unset (&dest);
1864   /* the other way */
1865   ret = gst_value_subtract (&dest, &src2, &src1);
1866   fail_unless (ret == TRUE);
1867   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_DOUBLE_RANGE);
1868   fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
1869   fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
1870   g_value_unset (&dest);
1871   g_value_unset (&src1);
1872   g_value_unset (&src2);
1873
1874   /* create a hole { double_range, double_range } */
1875   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
1876   gst_value_set_double_range (&src1, 10.0, 30.0);
1877   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
1878   gst_value_set_double_range (&src2, 15.0, 20.0);
1879   ret = gst_value_subtract (&dest, &src1, &src2);
1880   fail_unless (ret == TRUE);
1881   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
1882   tmp = gst_value_list_get_value (&dest, 0);
1883   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
1884   fail_unless (gst_value_get_double_range_min (tmp) == 10.0);
1885   fail_unless (gst_value_get_double_range_max (tmp) == 15.0);
1886   tmp = gst_value_list_get_value (&dest, 1);
1887   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
1888   fail_unless (gst_value_get_double_range_min (tmp) == 20.0);
1889   fail_unless (gst_value_get_double_range_max (tmp) == 30.0);
1890   g_value_unset (&dest);
1891   /* the other way */
1892   ret = gst_value_subtract (&dest, &src2, &src1);
1893   fail_unless (ret == FALSE);
1894   g_value_unset (&src1);
1895   g_value_unset (&src2);
1896 }
1897
1898 GST_END_TEST;
1899
1900 /* Test arithmetic subtraction of fractions */
1901 GST_START_TEST (test_value_subtract_fraction)
1902 {
1903   GValue result = { 0 };
1904   GValue src1 = { 0 };
1905   GValue src2 = { 0 };
1906
1907   /* Subtract 1/4 from 1/2 */
1908   g_value_init (&src1, GST_TYPE_FRACTION);
1909   g_value_init (&src2, GST_TYPE_FRACTION);
1910   g_value_init (&result, GST_TYPE_FRACTION);
1911   gst_value_set_fraction (&src1, 1, 2);
1912   gst_value_set_fraction (&src2, 1, 4);
1913   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
1914   fail_unless (gst_value_get_fraction_numerator (&result) == 1);
1915   fail_unless (gst_value_get_fraction_denominator (&result) == 4);
1916
1917   g_value_unset (&src1);
1918   g_value_unset (&src2);
1919   g_value_unset (&result);
1920
1921   /* Subtract 1/12 from 7/8 */
1922   g_value_init (&src1, GST_TYPE_FRACTION);
1923   g_value_init (&src2, GST_TYPE_FRACTION);
1924   g_value_init (&result, GST_TYPE_FRACTION);
1925   gst_value_set_fraction (&src1, 7, 8);
1926   gst_value_set_fraction (&src2, 1, 12);
1927   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
1928   fail_unless (gst_value_get_fraction_numerator (&result) == 19);
1929   fail_unless (gst_value_get_fraction_denominator (&result) == 24);
1930
1931   g_value_unset (&src1);
1932   g_value_unset (&src2);
1933   g_value_unset (&result);
1934
1935   /* Subtract 12/13 from 4/3 */
1936   g_value_init (&src1, GST_TYPE_FRACTION);
1937   g_value_init (&src2, GST_TYPE_FRACTION);
1938   g_value_init (&result, GST_TYPE_FRACTION);
1939   gst_value_set_fraction (&src1, 4, 3);
1940   gst_value_set_fraction (&src2, 12, 13);
1941   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
1942   fail_unless (gst_value_get_fraction_numerator (&result) == 16);
1943   fail_unless (gst_value_get_fraction_denominator (&result) == 39);
1944
1945   g_value_unset (&src1);
1946   g_value_unset (&src2);
1947   g_value_unset (&result);
1948
1949   /* Subtract 1/12 from 7/8 */
1950 }
1951
1952 GST_END_TEST;
1953
1954 /* Test set subtraction operations on fraction ranges */
1955 GST_START_TEST (test_value_subtract_fraction_range)
1956 {
1957   GValue dest = { 0 };
1958   GValue src1 = { 0 };
1959   GValue src2 = { 0 };
1960   GValue cmp = { 0 };
1961   const GValue *tmp;
1962   gboolean ret;
1963
1964   /* Value for tests */
1965   g_value_init (&cmp, GST_TYPE_FRACTION);
1966
1967   /*  fraction <-> fraction
1968    */
1969   g_value_init (&src1, GST_TYPE_FRACTION);
1970   gst_value_set_fraction (&src1, 10, 1);
1971   g_value_init (&src2, GST_TYPE_FRACTION);
1972   gst_value_set_fraction (&src2, 20, 1);
1973   gst_value_set_fraction (&src1, 10, 1);
1974
1975   /* subtract as in sets, result is 10 */
1976   ret = gst_value_subtract (&dest, &src1, &src2);
1977   fail_unless (ret == TRUE);
1978   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1979   g_value_unset (&dest);
1980
1981   /* same values, yields empty set */
1982   ret = gst_value_subtract (&dest, &src1, &src1);
1983   fail_unless (ret == FALSE);
1984   g_value_unset (&src1);
1985   g_value_unset (&src2);
1986
1987   /*  fraction <-> fraction_range
1988    */
1989
1990   /* would yield an empty set */
1991   g_value_init (&src1, GST_TYPE_FRACTION);
1992   gst_value_set_fraction (&src1, 10, 1);
1993   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1994   gst_value_set_fraction_range_full (&src2, 0, 1, 20, 1);
1995   ret = gst_value_subtract (&dest, &src1, &src2);
1996   fail_unless (ret == FALSE);
1997
1998   /* and the other way around, we cannot create open ranges
1999    * so the result is the range again */
2000   ret = gst_value_subtract (&dest, &src2, &src1);
2001   fail_unless (ret == TRUE);
2002   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2003   gst_value_set_fraction (&cmp, 0, 1);
2004   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2005           &cmp) == GST_VALUE_EQUAL);
2006   gst_value_set_fraction (&cmp, 20, 1);
2007   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2008           &cmp) == GST_VALUE_EQUAL);
2009   g_value_unset (&dest);
2010   g_value_unset (&src1);
2011   g_value_unset (&src2);
2012
2013   /* border case 1, empty set */
2014   g_value_init (&src1, GST_TYPE_FRACTION);
2015   gst_value_set_fraction (&src1, 10, 1);
2016   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2017   gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
2018   ret = gst_value_subtract (&dest, &src1, &src2);
2019   fail_unless (ret == FALSE);
2020
2021   /* and the other way around, should keep same range as
2022    * we don't have open ranges. */
2023   ret = gst_value_subtract (&dest, &src2, &src1);
2024   fail_unless (ret == TRUE);
2025   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2026   gst_value_set_fraction (&cmp, 10, 1);
2027   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2028           &cmp) == GST_VALUE_EQUAL);
2029   gst_value_set_fraction (&cmp, 20, 1);
2030   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2031           &cmp) == GST_VALUE_EQUAL);
2032   g_value_unset (&dest);
2033   g_value_unset (&src1);
2034   g_value_unset (&src2);
2035
2036   /* case 2, valid set */
2037   g_value_init (&src1, GST_TYPE_FRACTION);
2038   gst_value_set_fraction (&src1, 0, 1);
2039   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2040   gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
2041   ret = gst_value_subtract (&dest, &src1, &src2);
2042   fail_unless (ret == TRUE);
2043   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
2044   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
2045   g_value_unset (&dest);
2046
2047   /* and the other way around, should keep the range. */
2048   ret = gst_value_subtract (&dest, &src2, &src1);
2049   fail_unless (ret == TRUE);
2050   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2051   fail_unless (gst_value_compare (&dest, &src2) == GST_VALUE_EQUAL);
2052   g_value_unset (&dest);
2053   g_value_unset (&src1);
2054   g_value_unset (&src2);
2055
2056   /*  fraction_range <-> fraction_range
2057    */
2058
2059   /* same range, empty set */
2060   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2061   gst_value_set_fraction_range_full (&src1, 10, 2, 20, 2);
2062   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2063   gst_value_set_fraction_range_full (&src2, 10, 2, 20, 2);
2064   ret = gst_value_subtract (&dest, &src1, &src2);
2065   fail_unless (ret == FALSE);
2066   ret = gst_value_subtract (&dest, &src2, &src1);
2067   fail_unless (ret == FALSE);
2068   g_value_unset (&src1);
2069   g_value_unset (&src2);
2070
2071   /* non overlapping ranges */
2072   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2073   gst_value_set_fraction_range_full (&src1, 10, 2, 10, 1);
2074   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2075   gst_value_set_fraction_range_full (&src2, 30, 2, 40, 2);
2076   ret = gst_value_subtract (&dest, &src1, &src2);
2077   fail_unless (ret == TRUE);
2078   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2079   gst_value_set_fraction (&cmp, 5, 1);
2080   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2081           &cmp) == GST_VALUE_EQUAL);
2082   gst_value_set_fraction (&cmp, 10, 1);
2083   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2084           &cmp) == GST_VALUE_EQUAL);
2085
2086   g_value_unset (&dest);
2087   /* the other way */
2088   ret = gst_value_subtract (&dest, &src2, &src1);
2089   fail_unless (ret == TRUE);
2090   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2091   gst_value_set_fraction (&cmp, 15, 1);
2092   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2093           &cmp) == GST_VALUE_EQUAL);
2094   gst_value_set_fraction (&cmp, 20, 1);
2095   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2096           &cmp) == GST_VALUE_EQUAL);
2097   g_value_unset (&dest);
2098   g_value_unset (&src1);
2099   g_value_unset (&src2);
2100
2101   /* completely overlapping ranges */
2102   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2103   gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
2104   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2105   gst_value_set_fraction_range_full (&src2, 10, 1, 30, 1);
2106   ret = gst_value_subtract (&dest, &src1, &src2);
2107   fail_unless (ret == FALSE);
2108   /* the other way */
2109   ret = gst_value_subtract (&dest, &src2, &src1);
2110   fail_unless (ret == TRUE);
2111   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2112   gst_value_set_fraction (&cmp, 20, 1);
2113   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2114           &cmp) == GST_VALUE_EQUAL);
2115   gst_value_set_fraction (&cmp, 30, 1);
2116   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2117           &cmp) == GST_VALUE_EQUAL);
2118   g_value_unset (&dest);
2119   g_value_unset (&src1);
2120   g_value_unset (&src2);
2121
2122   /* partially overlapping ranges */
2123   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2124   gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
2125   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2126   gst_value_set_fraction_range_full (&src2, 15, 1, 30, 1);
2127   ret = gst_value_subtract (&dest, &src1, &src2);
2128   fail_unless (ret == TRUE);
2129   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2130   gst_value_set_fraction (&cmp, 10, 1);
2131   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2132           &cmp) == GST_VALUE_EQUAL);
2133   gst_value_set_fraction (&cmp, 15, 1);
2134   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2135           &cmp) == GST_VALUE_EQUAL);
2136   g_value_unset (&dest);
2137
2138   /* the other way */
2139   ret = gst_value_subtract (&dest, &src2, &src1);
2140   fail_unless (ret == TRUE);
2141   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2142   gst_value_set_fraction (&cmp, 20, 1);
2143   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
2144           &cmp) == GST_VALUE_EQUAL);
2145   gst_value_set_fraction (&cmp, 30, 1);
2146   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
2147           &cmp) == GST_VALUE_EQUAL);
2148   g_value_unset (&dest);
2149   g_value_unset (&src1);
2150   g_value_unset (&src2);
2151
2152   /* create a hole { double_range, double_range } */
2153   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
2154   gst_value_set_fraction_range_full (&src1, 10, 1, 30, 1);
2155   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
2156   gst_value_set_fraction_range_full (&src2, 15, 1, 20, 1);
2157   ret = gst_value_subtract (&dest, &src1, &src2);
2158   fail_unless (ret == TRUE);
2159   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_LIST);
2160   /* 1st list entry */
2161   tmp = gst_value_list_get_value (&dest, 0);
2162   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
2163   gst_value_set_fraction (&cmp, 10, 1);
2164   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
2165           &cmp) == GST_VALUE_EQUAL);
2166   gst_value_set_fraction (&cmp, 15, 1);
2167   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
2168           &cmp) == GST_VALUE_EQUAL);
2169   /* 2nd list entry */
2170   tmp = gst_value_list_get_value (&dest, 1);
2171   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
2172   gst_value_set_fraction (&cmp, 20, 1);
2173   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
2174           &cmp) == GST_VALUE_EQUAL);
2175   gst_value_set_fraction (&cmp, 30, 1);
2176   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
2177           &cmp) == GST_VALUE_EQUAL);
2178   g_value_unset (&dest);
2179   /* the other way */
2180   ret = gst_value_subtract (&dest, &src2, &src1);
2181   fail_unless (ret == FALSE);
2182   g_value_unset (&src1);
2183   g_value_unset (&src2);
2184
2185   g_value_unset (&cmp);
2186 }
2187
2188 GST_END_TEST;
2189
2190 /* Test set subtraction operations on fraction lists */
2191 GST_START_TEST (test_value_subtract_fraction_list)
2192 {
2193   GValue list1 = { 0 };
2194   GValue list2 = { 0 };
2195   GValue val1 = { 0 };
2196   GValue val2 = { 0 };
2197   GValue tmp = { 0 };
2198   gboolean ret;
2199
2200   g_value_init (&list1, GST_TYPE_LIST);
2201   g_value_init (&val1, GST_TYPE_FRACTION);
2202   gst_value_set_fraction (&val1, 15, 2);
2203   gst_value_list_append_value (&list1, &val1);
2204   g_value_init (&tmp, GST_TYPE_FRACTION);
2205   gst_value_set_fraction (&tmp, 5, 1);
2206   gst_value_list_append_value (&list1, &tmp);
2207   g_value_unset (&tmp);
2208
2209   g_value_init (&list2, GST_TYPE_LIST);
2210   g_value_init (&val2, GST_TYPE_FRACTION);
2211   gst_value_set_fraction (&val2, 15, 1);
2212   gst_value_list_append_value (&list2, &val2);
2213   g_value_init (&tmp, GST_TYPE_FRACTION);
2214   gst_value_set_fraction (&tmp, 5, 1);
2215   gst_value_list_append_value (&list2, &tmp);
2216   g_value_unset (&tmp);
2217
2218   /* should subtract all common elements */
2219   ret = gst_value_subtract (&tmp, &list1, &list2);
2220   fail_unless (ret == TRUE);
2221   fail_unless (gst_value_compare (&tmp, &val1) == GST_VALUE_EQUAL);
2222   g_value_unset (&val1);
2223   g_value_unset (&tmp);
2224
2225   ret = gst_value_subtract (&tmp, &list2, &list1);
2226   fail_unless (ret == TRUE);
2227   fail_unless (gst_value_compare (&tmp, &val2) == GST_VALUE_EQUAL);
2228   g_value_unset (&val2);
2229   g_value_unset (&tmp);
2230
2231   g_value_unset (&list1);
2232   g_value_unset (&list2);
2233 }
2234
2235 GST_END_TEST;
2236
2237 GST_START_TEST (test_date)
2238 {
2239   GstStructure *s;
2240   GDate *date, *date2;
2241   gchar *str;
2242
2243   date = g_date_new_dmy (22, 9, 2005);
2244
2245   s = gst_structure_new ("media/x-type", "SOME_DATE_TAG", G_TYPE_DATE,
2246       date, NULL);
2247
2248   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG", G_TYPE_DATE));
2249   fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date2));
2250   fail_unless (date2 != NULL);
2251   fail_unless (g_date_valid (date2));
2252   fail_unless (g_date_compare (date, date2) == 0);
2253
2254   g_date_free (date);
2255   g_date_free (date2);
2256   date = NULL;
2257   date2 = NULL;
2258
2259   str = gst_structure_to_string (s);
2260   gst_structure_free (s);
2261   s = NULL;
2262
2263   fail_unless (g_str_equal (str,
2264           "media/x-type, SOME_DATE_TAG=(date)2005-09-22;"));
2265
2266   s = gst_structure_from_string (str, NULL);
2267   g_free (str);
2268   str = NULL;
2269
2270   fail_unless (s != NULL);
2271   fail_unless (gst_structure_has_name (s, "media/x-type"));
2272   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG", G_TYPE_DATE));
2273   fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date));
2274   fail_unless (date != NULL);
2275   fail_unless (g_date_valid (date));
2276   fail_unless (g_date_get_day (date) == 22);
2277   fail_unless (g_date_get_month (date) == 9);
2278   fail_unless (g_date_get_year (date) == 2005);
2279   g_date_free (date);
2280   date = NULL;
2281
2282   str = gst_structure_to_string (s);
2283   gst_structure_free (s);
2284   s = NULL;
2285
2286   fail_unless (g_str_equal (str,
2287           "media/x-type, SOME_DATE_TAG=(date)2005-09-22;"));
2288   g_free (str);
2289   str = NULL;
2290 }
2291
2292 GST_END_TEST;
2293
2294 static gboolean
2295 date_time_equal (GstDateTime * a, GstDateTime * b)
2296 {
2297   if (gst_date_time_get_year (a) != gst_date_time_get_year (b) ||
2298       gst_date_time_get_month (a) != gst_date_time_get_month (b) ||
2299       gst_date_time_get_day (a) != gst_date_time_get_day (b))
2300     return FALSE;
2301
2302   if (gst_date_time_get_hour (a) != gst_date_time_get_hour (b) ||
2303       gst_date_time_get_minute (a) != gst_date_time_get_minute (b) ||
2304       gst_date_time_get_second (a) != gst_date_time_get_second (b) ||
2305       gst_date_time_get_microsecond (a) != gst_date_time_get_microsecond (b))
2306     return FALSE;
2307
2308   if (gst_date_time_get_time_zone_offset (a) !=
2309       gst_date_time_get_time_zone_offset (b))
2310     return FALSE;
2311
2312   return TRUE;
2313 }
2314
2315 GST_START_TEST (test_date_time)
2316 {
2317   GstStructure *s;
2318   GstDateTime *datetime, *datetime2;
2319   GValue val = { 0, };
2320   gchar *str;
2321
2322   /* utc timezone */
2323   datetime = gst_date_time_new (0, 2010, 6, 23, 7, 40, 10);
2324
2325   s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
2326       GST_TYPE_DATE_TIME, datetime, NULL);
2327
2328   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2329           GST_TYPE_DATE_TIME));
2330   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2331           &datetime2));
2332   fail_unless (datetime2 != NULL);
2333   fail_unless (date_time_equal (datetime, datetime2));
2334
2335   gst_date_time_unref (datetime);
2336   gst_date_time_unref (datetime2);
2337   datetime = NULL;
2338   datetime2 = NULL;
2339
2340   str = gst_structure_to_string (s);
2341   gst_structure_free (s);
2342   s = NULL;
2343
2344   fail_unless_equals_string (str,
2345       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10Z;");
2346
2347   s = gst_structure_from_string (str, NULL);
2348   g_free (str);
2349   str = NULL;
2350
2351   fail_unless (s != NULL);
2352   fail_unless (gst_structure_has_name (s, "media/x-type"));
2353   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2354           GST_TYPE_DATE_TIME));
2355   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2356           &datetime));
2357   fail_unless (datetime != NULL);
2358   fail_unless (gst_date_time_get_year (datetime) == 2010);
2359   fail_unless (gst_date_time_get_month (datetime) == 6);
2360   fail_unless (gst_date_time_get_day (datetime) == 23);
2361   fail_unless (gst_date_time_get_hour (datetime) == 7);
2362   fail_unless (gst_date_time_get_minute (datetime) == 40);
2363   fail_unless (gst_date_time_get_second (datetime) == 10);
2364   fail_unless (gst_date_time_get_microsecond (datetime) == 0);
2365   fail_unless (gst_date_time_get_time_zone_offset (datetime) == 0);
2366   gst_date_time_unref (datetime);
2367   datetime = NULL;
2368
2369   str = gst_structure_to_string (s);
2370   gst_structure_free (s);
2371   s = NULL;
2372
2373   fail_unless_equals_string (str,
2374       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10Z;");
2375   g_free (str);
2376   str = NULL;
2377
2378   /* with timezone */
2379   datetime = gst_date_time_new (-3.0, 2010, 6, 23, 7, 40, 10.000001);
2380
2381   s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
2382       GST_TYPE_DATE_TIME, datetime, NULL);
2383
2384   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2385           GST_TYPE_DATE_TIME));
2386   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2387           &datetime2));
2388   fail_unless (datetime2 != NULL);
2389   fail_unless (date_time_equal (datetime, datetime2));
2390
2391   gst_date_time_unref (datetime);
2392   gst_date_time_unref (datetime2);
2393   datetime = NULL;
2394   datetime2 = NULL;
2395
2396   str = gst_structure_to_string (s);
2397   gst_structure_free (s);
2398   s = NULL;
2399
2400   fail_unless_equals_string (str,
2401       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001-0300;");
2402
2403   s = gst_structure_from_string (str, NULL);
2404   g_free (str);
2405   str = NULL;
2406
2407   fail_unless (s != NULL);
2408   fail_unless (gst_structure_has_name (s, "media/x-type"));
2409   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2410           GST_TYPE_DATE_TIME));
2411   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2412           &datetime));
2413   fail_unless (datetime != NULL);
2414   fail_unless (gst_date_time_get_year (datetime) == 2010);
2415   fail_unless (gst_date_time_get_month (datetime) == 6);
2416   fail_unless (gst_date_time_get_day (datetime) == 23);
2417   fail_unless (gst_date_time_get_hour (datetime) == 7);
2418   fail_unless (gst_date_time_get_minute (datetime) == 40);
2419   fail_unless (gst_date_time_get_second (datetime) == 10);
2420   fail_unless (gst_date_time_get_microsecond (datetime) == 1);
2421   fail_unless (gst_date_time_get_time_zone_offset (datetime) == -3);
2422   gst_date_time_unref (datetime);
2423   datetime = NULL;
2424
2425   str = gst_structure_to_string (s);
2426   gst_structure_free (s);
2427   s = NULL;
2428   fail_unless_equals_string (str,
2429       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001-0300;");
2430
2431   g_free (str);
2432   str = NULL;
2433
2434   /* with positive timezone */
2435   datetime = gst_date_time_new (2.0, 2010, 6, 23, 7, 40, 10.000001);
2436
2437   s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
2438       GST_TYPE_DATE_TIME, datetime, NULL);
2439
2440   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2441           GST_TYPE_DATE_TIME));
2442   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2443           &datetime2));
2444   fail_unless (datetime2 != NULL);
2445   fail_unless (date_time_equal (datetime, datetime2));
2446
2447   gst_date_time_unref (datetime);
2448   gst_date_time_unref (datetime2);
2449   datetime = NULL;
2450   datetime2 = NULL;
2451
2452   str = gst_structure_to_string (s);
2453   gst_structure_free (s);
2454   s = NULL;
2455
2456   fail_unless_equals_string (str,
2457       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001+0200;");
2458
2459   s = gst_structure_from_string (str, NULL);
2460   g_free (str);
2461   str = NULL;
2462
2463   fail_unless (s != NULL);
2464   fail_unless (gst_structure_has_name (s, "media/x-type"));
2465   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
2466           GST_TYPE_DATE_TIME));
2467   fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
2468           &datetime));
2469   fail_unless (datetime != NULL);
2470   fail_unless (gst_date_time_get_year (datetime) == 2010);
2471   fail_unless (gst_date_time_get_month (datetime) == 6);
2472   fail_unless (gst_date_time_get_day (datetime) == 23);
2473   fail_unless (gst_date_time_get_hour (datetime) == 7);
2474   fail_unless (gst_date_time_get_minute (datetime) == 40);
2475   fail_unless (gst_date_time_get_second (datetime) == 10);
2476   fail_unless (gst_date_time_get_microsecond (datetime) == 1);
2477   fail_unless (gst_date_time_get_time_zone_offset (datetime) == 2);
2478   gst_date_time_unref (datetime);
2479   datetime = NULL;
2480
2481   str = gst_structure_to_string (s);
2482   gst_structure_free (s);
2483   s = NULL;
2484   fail_unless_equals_string (str,
2485       "media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001+0200;");
2486
2487   g_free (str);
2488   str = NULL;
2489
2490   /* test partial dates */
2491   datetime = gst_date_time_new (0.0, 2010, -1, -1, -1, -1, -1.0);
2492   g_value_init (&val, GST_TYPE_DATE_TIME);
2493   g_value_take_boxed (&val, datetime);
2494   str = gst_value_serialize (&val);
2495   g_value_reset (&val);
2496   fail_unless_equals_string (str, "2010");
2497   fail_unless (gst_value_deserialize (&val, str));
2498   datetime = g_value_get_boxed (&val);
2499   fail_if (!gst_date_time_has_year (datetime));
2500   fail_if (gst_date_time_has_month (datetime));
2501   fail_if (gst_date_time_has_day (datetime));
2502   fail_if (gst_date_time_has_time (datetime));
2503   g_value_unset (&val);
2504   g_free (str);
2505
2506   datetime = gst_date_time_new (0.0, 2010, 9, -1, -1, -1, -1.0);
2507   g_value_init (&val, GST_TYPE_DATE_TIME);
2508   g_value_take_boxed (&val, datetime);
2509   str = gst_value_serialize (&val);
2510   g_value_reset (&val);
2511   fail_unless_equals_string (str, "2010-09");
2512   fail_unless (gst_value_deserialize (&val, str));
2513   datetime = g_value_get_boxed (&val);
2514   fail_if (!gst_date_time_has_year (datetime));
2515   fail_if (!gst_date_time_has_month (datetime));
2516   fail_if (gst_date_time_has_day (datetime));
2517   fail_if (gst_date_time_has_time (datetime));
2518   g_value_unset (&val);
2519   g_free (str);
2520
2521   datetime = gst_date_time_new (0.0, 1983, 11, 30, -1, -1, -1.0);
2522   g_value_init (&val, GST_TYPE_DATE_TIME);
2523   g_value_take_boxed (&val, datetime);
2524   str = gst_value_serialize (&val);
2525   g_value_reset (&val);
2526   fail_unless_equals_string (str, "1983-11-30");
2527   fail_unless (gst_value_deserialize (&val, str));
2528   datetime = g_value_get_boxed (&val);
2529   fail_if (!gst_date_time_has_year (datetime));
2530   fail_if (!gst_date_time_has_month (datetime));
2531   fail_if (!gst_date_time_has_day (datetime));
2532   fail_if (gst_date_time_has_time (datetime));
2533   g_value_unset (&val);
2534   g_free (str);
2535
2536   datetime = gst_date_time_new (0.0, 1983, 11, 30, 3, 52, -1.0);
2537   g_value_init (&val, GST_TYPE_DATE_TIME);
2538   g_value_take_boxed (&val, datetime);
2539   str = gst_value_serialize (&val);
2540   g_value_reset (&val);
2541   fail_unless_equals_string (str, "1983-11-30T03:52Z");
2542   fail_unless (gst_value_deserialize (&val, str));
2543   datetime = g_value_get_boxed (&val);
2544   fail_if (!gst_date_time_has_year (datetime));
2545   fail_if (!gst_date_time_has_month (datetime));
2546   fail_if (!gst_date_time_has_day (datetime));
2547   fail_if (!gst_date_time_has_time (datetime));
2548   fail_if (gst_date_time_has_second (datetime));
2549   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime), 0.0);
2550   g_value_unset (&val);
2551   g_free (str);
2552
2553   datetime = gst_date_time_new (-4.5, 1983, 11, 30, 3, 52, -1.0);
2554   g_value_init (&val, GST_TYPE_DATE_TIME);
2555   g_value_take_boxed (&val, datetime);
2556   str = gst_value_serialize (&val);
2557   g_value_reset (&val);
2558   fail_unless_equals_string (str, "1983-11-30T03:52-0430");
2559   fail_unless (gst_value_deserialize (&val, str));
2560   datetime = g_value_get_boxed (&val);
2561   fail_if (!gst_date_time_has_year (datetime));
2562   fail_if (!gst_date_time_has_month (datetime));
2563   fail_if (!gst_date_time_has_day (datetime));
2564   fail_if (!gst_date_time_has_time (datetime));
2565   fail_if (gst_date_time_has_second (datetime));
2566   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime),
2567       -4.5);
2568   g_value_unset (&val);
2569   g_free (str);
2570
2571   datetime = gst_date_time_new (4.5, 1983, 11, 30, 14, 52, 9);
2572   g_value_init (&val, GST_TYPE_DATE_TIME);
2573   g_value_take_boxed (&val, datetime);
2574   str = gst_value_serialize (&val);
2575   g_value_reset (&val);
2576   fail_unless_equals_string (str, "1983-11-30T14:52:09+0430");
2577   fail_unless (gst_value_deserialize (&val, str));
2578   datetime = g_value_get_boxed (&val);
2579   fail_if (!gst_date_time_has_year (datetime));
2580   fail_if (!gst_date_time_has_month (datetime));
2581   fail_if (!gst_date_time_has_day (datetime));
2582   fail_if (!gst_date_time_has_time (datetime));
2583   fail_if (!gst_date_time_has_second (datetime));
2584   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime), 4.5);
2585   g_value_unset (&val);
2586   g_free (str);
2587
2588   datetime = gst_date_time_new (-4.5, 1983, 11, 30, 14, 52, 9.702);
2589   g_value_init (&val, GST_TYPE_DATE_TIME);
2590   g_value_take_boxed (&val, datetime);
2591   str = gst_value_serialize (&val);
2592   g_value_reset (&val);
2593   fail_unless_equals_string (str, "1983-11-30T14:52:09.702-0430");
2594   fail_unless (gst_value_deserialize (&val, str));
2595   datetime = g_value_get_boxed (&val);
2596   fail_if (!gst_date_time_has_year (datetime));
2597   fail_if (!gst_date_time_has_month (datetime));
2598   fail_if (!gst_date_time_has_day (datetime));
2599   fail_if (!gst_date_time_has_time (datetime));
2600   fail_if (!gst_date_time_has_second (datetime));
2601   fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime),
2602       -4.5);
2603   g_value_unset (&val);
2604   g_free (str);
2605 }
2606
2607 GST_END_TEST;
2608
2609 GST_START_TEST (test_fraction_range)
2610 {
2611   GValue range = { 0, };
2612   GValue start = { 0, };
2613   GValue end = { 0, };
2614   GValue src = { 0, };
2615   GValue dest = { 0, };
2616   GValue range2 = { 0, };
2617
2618   g_value_init (&range, GST_TYPE_FRACTION_RANGE);
2619   g_value_init (&range2, GST_TYPE_FRACTION_RANGE);
2620   g_value_init (&start, GST_TYPE_FRACTION);
2621   g_value_init (&end, GST_TYPE_FRACTION);
2622   g_value_init (&src, GST_TYPE_FRACTION);
2623
2624   gst_value_set_fraction (&src, 1, 2);
2625
2626   /* Check that a intersection of fraction & range = fraction */
2627   gst_value_set_fraction (&start, 1, 4);
2628   gst_value_set_fraction (&end, 2, 3);
2629   gst_value_set_fraction_range (&range, &start, &end);
2630
2631   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
2632   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
2633   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
2634
2635   /* Check that a intersection selects the overlapping range */
2636   gst_value_set_fraction (&start, 1, 3);
2637   gst_value_set_fraction (&end, 2, 3);
2638   gst_value_set_fraction_range (&range2, &start, &end);
2639   g_value_unset (&dest);
2640   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
2641   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
2642
2643   gst_value_set_fraction_range (&range2, &start, &end);
2644   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
2645
2646   /* Check that non intersection ranges don't intersect */
2647   gst_value_set_fraction (&start, 4, 2);
2648   gst_value_set_fraction (&end, 5, 2);
2649   gst_value_set_fraction_range (&range2, &start, &end);
2650   g_value_unset (&dest);
2651   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
2652
2653   g_value_unset (&start);
2654   g_value_unset (&end);
2655   g_value_unset (&range);
2656   g_value_unset (&range2);
2657   g_value_unset (&src);
2658 }
2659
2660 GST_END_TEST;
2661
2662 GST_START_TEST (test_serialize_deserialize_format_enum)
2663 {
2664   GstStructure *s, *s2;
2665   GstFormat foobar_fmt;
2666   gchar *str, *str2, *end = NULL;
2667
2668   /* make sure custom formats are serialised properly as well */
2669   foobar_fmt = gst_format_register ("foobar", "GST_FORMAT_FOOBAR");
2670   fail_unless (foobar_fmt != GST_FORMAT_UNDEFINED);
2671
2672   s = gst_structure_new ("foo/bar", "format1", GST_TYPE_FORMAT,
2673       GST_FORMAT_BYTES, "format2", GST_TYPE_FORMAT, GST_FORMAT_TIME,
2674       "format3", GST_TYPE_FORMAT, GST_FORMAT_DEFAULT, "format4",
2675       GST_TYPE_FORMAT, foobar_fmt, NULL);
2676
2677   str = gst_structure_to_string (s);
2678   GST_LOG ("Got structure string '%s'", GST_STR_NULL (str));
2679   fail_unless (str != NULL);
2680   fail_unless (strstr (str, "time") != NULL);
2681   fail_unless (strstr (str, "byte") != NULL);
2682   fail_unless (strstr (str, "default") != NULL);
2683   fail_unless (strstr (str, "FOOBAR") != NULL);
2684
2685   s2 = gst_structure_from_string (str, &end);
2686   fail_unless (s2 != NULL);
2687
2688   str2 = gst_structure_to_string (s2);
2689   fail_unless (str2 != NULL);
2690
2691   fail_unless (g_str_equal (str, str2));
2692
2693   g_free (str);
2694   g_free (str2);
2695   gst_structure_free (s);
2696   gst_structure_free (s2);
2697 }
2698
2699 GST_END_TEST;
2700
2701 GST_START_TEST (test_serialize_deserialize_value_array)
2702 {
2703   GValue v = G_VALUE_INIT, v2 = G_VALUE_INIT, v3 = G_VALUE_INIT;
2704   gchar *str = NULL;
2705
2706   g_value_init (&v, GST_TYPE_ARRAY);
2707   g_value_init (&v2, GST_TYPE_ARRAY);
2708   g_value_init (&v3, G_TYPE_DOUBLE);
2709   g_value_set_double (&v3, 1);
2710   gst_value_array_append_value (&v2, &v3);
2711   g_value_unset (&v3);
2712   g_value_init (&v3, G_TYPE_DOUBLE);
2713   g_value_set_double (&v3, 0);
2714   gst_value_array_append_value (&v2, &v3);
2715   g_value_unset (&v3);
2716   gst_value_array_append_value (&v, &v2);
2717   g_value_unset (&v2);
2718
2719   str = gst_value_serialize (&v);
2720
2721   g_value_init (&v2, GST_TYPE_ARRAY);
2722   fail_unless (gst_value_deserialize (&v2, str));
2723   fail_unless (gst_value_compare (&v, &v2) == 0);
2724
2725   g_value_unset (&v2);
2726   g_value_unset (&v);
2727   g_free (str);
2728 }
2729
2730 GST_END_TEST;
2731
2732 GST_START_TEST (test_compare_caps)
2733 {
2734   GValue value = { 0 }
2735   , value2 = {
2736   0};
2737
2738   g_value_init (&value, GST_TYPE_CAPS);
2739   g_value_init (&value2, GST_TYPE_CAPS);
2740   g_value_take_boxed (&value, NULL);
2741   g_value_take_boxed (&value2, NULL);
2742
2743   fail_unless_equals_int (gst_value_compare (&value, &value2), GST_VALUE_EQUAL);
2744
2745   g_value_take_boxed (&value, gst_caps_new_empty_simple ("something"));
2746
2747   fail_unless_equals_int (gst_value_compare (&value, &value2),
2748       GST_VALUE_UNORDERED);
2749
2750   g_value_unset (&value);
2751   g_value_unset (&value2);
2752
2753 }
2754
2755 GST_END_TEST;
2756
2757 static void
2758 _test_serialize_deserialize_boxed_in_structure (const gpointer boxed_value,
2759     GType type)
2760 {
2761   GValue value = G_VALUE_INIT, str_val = G_VALUE_INIT;
2762   const GValue *value_after;
2763   GstStructure *s, *s2;
2764   const gchar *first_str_val = "first \" string", *second_str_val =
2765       "second \" string";
2766   gchar *str, *str2, *end;
2767
2768   g_value_init (&value, type);
2769   g_value_init (&str_val, G_TYPE_STRING);
2770   g_value_set_boxed (&value, boxed_value);
2771
2772   s = gst_structure_new_empty ("test-struct");
2773   g_value_set_string (&str_val, first_str_val);
2774   gst_structure_set_value (s, "first", &str_val);
2775   gst_structure_set_value (s, "test-value", &value);
2776   g_value_set_string (&str_val, second_str_val);
2777   gst_structure_set_value (s, "second", &str_val);
2778
2779   /* serialize the values in the structure */
2780   str = gst_structure_to_string (s);
2781   fail_unless (str != NULL);
2782   GST_DEBUG ("Got structure string '%s'", str);
2783
2784   /* recreate the structure */
2785   s2 = gst_structure_from_string (str, &end);
2786   fail_unless (s2 != NULL);
2787   fail_unless (end[0] == '\0');
2788
2789   /* make sure the new structure serializes to the same string */
2790   str2 = gst_structure_to_string (s2);
2791   fail_unless_equals_string (str, str2);
2792
2793   /* test for equality if values can be compared */
2794   value_after = gst_structure_get_value (s2, "test-value");
2795   fail_unless (value_after != NULL);
2796   fail_unless (G_VALUE_TYPE (value_after) == G_VALUE_TYPE (&value));
2797   if (gst_value_can_compare (&value, value_after))
2798     fail_unless (gst_value_compare (&value, value_after) == GST_VALUE_EQUAL);
2799
2800   /* test to make sure that the string values are still present, and
2801    * haven't been gobbled by the value serialization */
2802   fail_unless_equals_string (gst_structure_get_string (s2, "first"),
2803       first_str_val);
2804   fail_unless_equals_string (gst_structure_get_string (s2, "second"),
2805       second_str_val);
2806
2807   /* cleanup */
2808   gst_structure_free (s);
2809   gst_structure_free (s2);
2810   g_free (str);
2811   g_free (str2);
2812   g_value_unset (&value);
2813   g_value_unset (&str_val);
2814 }
2815
2816 GST_START_TEST (test_serialize_deserialize_caps)
2817 {
2818   GValue value = G_VALUE_INIT, value2 = G_VALUE_INIT;
2819   GstCaps *incaps = gst_caps_new_simple ("caps/internal",
2820       "in-field", G_TYPE_INT, 20, "in-field2",
2821       G_TYPE_STRING, "some in ternal field", NULL);
2822   GstCaps *test_caps[] = {
2823     gst_caps_new_simple ("test/caps",
2824         "foo", G_TYPE_INT, 10, "bar", G_TYPE_STRING, "test",
2825         "int-caps", GST_TYPE_CAPS, incaps, NULL),
2826     gst_caps_new_any (),
2827     gst_caps_new_empty ()
2828   };
2829   GstCaps *caps, *caps2;
2830   gchar *serialized;
2831   gint i;
2832
2833   gst_caps_unref (incaps);
2834   g_value_init (&value, GST_TYPE_CAPS);
2835   g_value_init (&value2, GST_TYPE_CAPS);
2836
2837   for (i = 0; i < G_N_ELEMENTS (test_caps); i++) {
2838     caps = test_caps[i];
2839     fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
2840
2841     /* and assign caps to gvalue */
2842     g_value_take_boxed (&value, caps);
2843     fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
2844
2845     /* now serialize it */
2846     serialized = gst_value_serialize (&value);
2847     GST_DEBUG ("serialized caps to %s", serialized);
2848     fail_unless (serialized != NULL);
2849
2850     /* refcount should not change */
2851     fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
2852
2853     /* now deserialize again */
2854     fail_unless (gst_value_deserialize (&value2, serialized));
2855
2856     caps2 = g_value_get_boxed (&value2);
2857     fail_if (GST_CAPS_REFCOUNT_VALUE (caps2) != 1);
2858
2859     /* they should be equal */
2860     fail_unless (gst_caps_is_equal (caps, caps2));
2861     fail_unless (gst_caps_is_any (caps) == gst_caps_is_any (caps2));
2862
2863     _test_serialize_deserialize_boxed_in_structure (caps, GST_TYPE_CAPS);
2864     /* cleanup */
2865     g_free (serialized);
2866   }
2867   g_value_unset (&value);
2868   g_value_unset (&value2);
2869 }
2870
2871 GST_END_TEST;
2872
2873 GST_START_TEST (test_int_range)
2874 {
2875   GValue range = { 0, };
2876   GValue start = { 0, };
2877   GValue end = { 0, };
2878   GValue src = { 0, };
2879   GValue dest = { 0, };
2880   GValue range2 = { 0, };
2881
2882   g_value_init (&range, GST_TYPE_INT_RANGE);
2883   g_value_init (&range2, GST_TYPE_INT_RANGE);
2884   g_value_init (&start, G_TYPE_INT);
2885   g_value_init (&end, G_TYPE_INT);
2886   g_value_init (&src, G_TYPE_INT);
2887
2888   g_value_set_int (&src, 2);
2889
2890   /* Check that a intersection of int & range = int */
2891   gst_value_set_int_range (&range, 1, 5);
2892
2893   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
2894   fail_unless (G_VALUE_TYPE (&dest) == G_TYPE_INT);
2895   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
2896
2897   /* Check that a intersection selects the overlapping range */
2898   gst_value_set_int_range (&range2, 2, 3);
2899   g_value_unset (&dest);
2900   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
2901   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
2902
2903   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
2904
2905   /* Check that non intersection ranges don't intersect */
2906   gst_value_set_int_range (&range2, 6, 7);
2907   g_value_unset (&dest);
2908   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
2909
2910   gst_value_set_int_range (&range, -7, -6);
2911   fail_unless_equals_int (gst_value_get_int_range_min (&range), -7);
2912   fail_unless_equals_int (gst_value_get_int_range_max (&range), -6);
2913   gst_value_set_int_range (&range, -7, 7);
2914   fail_unless_equals_int (gst_value_get_int_range_min (&range), -7);
2915   fail_unless_equals_int (gst_value_get_int_range_max (&range), 7);
2916
2917   g_value_unset (&start);
2918   g_value_unset (&end);
2919   g_value_unset (&range);
2920   g_value_unset (&range2);
2921   g_value_unset (&src);
2922 }
2923
2924 GST_END_TEST;
2925
2926 GST_START_TEST (test_int64_range)
2927 {
2928   GValue range = { 0, };
2929   GValue start = { 0, };
2930   GValue end = { 0, };
2931   GValue src = { 0, };
2932   GValue dest = { 0, };
2933   GValue range2 = { 0, };
2934
2935   g_value_init (&range, GST_TYPE_INT64_RANGE);
2936   g_value_init (&range2, GST_TYPE_INT64_RANGE);
2937   g_value_init (&start, G_TYPE_INT64);
2938   g_value_init (&end, G_TYPE_INT64);
2939   g_value_init (&src, G_TYPE_INT64);
2940
2941   g_value_set_int64 (&src, 2);
2942
2943   /* Check that a intersection of int64 & range = int64 */
2944   gst_value_set_int64_range (&range, 1, 5);
2945
2946   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
2947   fail_unless (G_VALUE_TYPE (&dest) == G_TYPE_INT64);
2948   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
2949
2950   /* Check that a intersection selects the overlapping range */
2951   gst_value_set_int64_range (&range2, 2, 3);
2952   g_value_unset (&dest);
2953   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
2954   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
2955
2956   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
2957
2958   /* Check that non intersection ranges don't intersect */
2959   gst_value_set_int64_range (&range2, 6, 7);
2960   g_value_unset (&dest);
2961   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
2962
2963   g_value_unset (&start);
2964   g_value_unset (&end);
2965   g_value_unset (&range);
2966   g_value_unset (&range2);
2967   g_value_unset (&src);
2968 }
2969
2970 GST_END_TEST;
2971
2972 GST_START_TEST (test_serialize_int64_range)
2973 {
2974   int i = 0;
2975
2976   gint64 int64_ranges[] = {
2977     0, 5,
2978     0, G_MAXINT,
2979     5, G_MAXINT32,
2980     5, G_MAXINT64,
2981   };
2982   gint int64_ranges_size = sizeof (int64_ranges) / sizeof (int64_ranges[0]) / 2;
2983
2984   gchar *int64_range_strings[] = {
2985     g_strdup ("[ 0, 5 ]"),
2986     g_strdup_printf ("[ 0, %" G_GINT64_FORMAT " ]", (gint64) G_MAXINT),
2987     g_strdup_printf ("[ 5, %" G_GINT64_FORMAT " ]", (gint64) G_MAXINT32),
2988     g_strdup_printf ("[ 5, %" G_GINT64_FORMAT " ]", G_MAXINT64),
2989   };
2990   gint int64_range_strings_size =
2991       sizeof (int64_range_strings) / sizeof (int64_range_strings[0]);
2992
2993   fail_unless (int64_ranges_size == int64_range_strings_size);
2994
2995   while (i + 1 < (int64_ranges_size * 2)) {
2996     if ((i + 1) % 2) {
2997       gchar *str;
2998       gchar *str2;
2999       GValue value = { 0 };
3000       const GValue *deserialized_value;
3001       int idx = i / 2;
3002       GstStructure *s;
3003
3004       g_value_init (&value, GST_TYPE_INT64_RANGE);
3005
3006       /* check serialization */
3007       gst_value_set_int64_range (&value, int64_ranges[i], int64_ranges[i + 1]);
3008       str = gst_value_serialize (&value);
3009       fail_unless (strcmp (str, int64_range_strings[idx]) == 0);
3010       g_free (int64_range_strings[idx]);
3011       g_value_unset (&value);
3012
3013       /* now deserialize again to an int64 range */
3014       s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT64_RANGE,
3015           int64_ranges[i], int64_ranges[i + 1], NULL);
3016       deserialized_value = gst_structure_get_value (s, "range");
3017       fail_unless (GST_VALUE_HOLDS_INT64_RANGE (deserialized_value) == TRUE);
3018       str2 = gst_value_serialize (deserialized_value);
3019
3020       fail_unless (gst_value_get_int64_range_min (deserialized_value) ==
3021           int64_ranges[i]);
3022       fail_unless (gst_value_get_int64_range_max (deserialized_value) ==
3023           int64_ranges[i + 1]);
3024
3025       gst_structure_free (s);
3026       g_free (str);
3027       g_free (str2);
3028     }
3029     i++;
3030   }
3031 }
3032
3033 GST_END_TEST;
3034
3035 GST_START_TEST (test_deserialize_int_range)
3036 {
3037   GstStructure *s;
3038   gchar *str, *str2;
3039   gchar *end = NULL;
3040   const GValue *deserialized_value;
3041
3042   /* check a valid int_range deserialization */
3043   str = g_strdup_printf ("foo/bar, range=[ 1, %d ];", G_MAXINT);
3044   s = gst_structure_from_string (str, &end);
3045   fail_unless (*end == '\0');
3046   deserialized_value = gst_structure_get_value (s, "range");
3047   fail_unless (GST_VALUE_HOLDS_INT_RANGE (deserialized_value) == TRUE);
3048   fail_unless (gst_value_get_int_range_min (deserialized_value) == 1);
3049   fail_unless (gst_value_get_int_range_max (deserialized_value) == G_MAXINT);
3050   gst_structure_free (s);
3051   end = NULL;
3052   g_free (str);
3053
3054   /* check invalid int_range deserialization */
3055   str =
3056       g_strdup_printf ("foo/bar, range=[ 1, %" G_GINT64_FORMAT " ];",
3057       (gint64) G_MAXINT + 1);
3058   s = NULL;
3059   ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
3060   g_free (str);
3061   if (s)
3062     gst_structure_free (s);
3063   str =
3064       g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %"
3065       G_GINT64_FORMAT " ];", (gint64) G_MAXINT, (gint64) G_MAXINT + 1);
3066   ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL));
3067   end = NULL;
3068   g_free (str);
3069   if (s)
3070     gst_structure_free (s);
3071
3072   /* check a valid int64_range deserialization. Those ranges need to
3073    * be explicit about their storage type. */
3074   str = g_strdup_printf ("foo/bar, range=(gint64)[ 1, %d ];", G_MAXINT);
3075   s = gst_structure_from_string (str, &end);
3076   fail_unless (*end == '\0');
3077   deserialized_value = gst_structure_get_value (s, "range");
3078   fail_unless (GST_VALUE_HOLDS_INT64_RANGE (deserialized_value) == TRUE);
3079   fail_unless (gst_value_get_int64_range_min (deserialized_value) == 1);
3080   fail_unless (gst_value_get_int64_range_max (deserialized_value) == G_MAXINT);
3081   str2 = gst_structure_to_string (s);
3082   fail_unless (strcmp (str, str2) == 0);
3083   gst_structure_free (s);
3084   end = NULL;
3085   g_free (str);
3086   g_free (str2);
3087
3088   /* check invalid int64_range (starting with a gint) deserialization */
3089   str =
3090       g_strdup_printf ("foo/bar, range=(gint64)[ 1, %" G_GUINT64_FORMAT " ];",
3091       (guint64) G_MAXINT64 + 1);
3092   s = NULL;
3093   ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
3094   if (s) {
3095     fail_unless (*end == '\0');
3096     gst_structure_free (s);
3097     end = NULL;
3098   }
3099   g_free (str);
3100
3101   /* check invalid int64_range deserialization into a int64_range */
3102   str =
3103       g_strdup_printf ("foo/bar, range=(gint64)[ %" G_GINT64_FORMAT ", %"
3104       G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1);
3105   ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL));
3106   g_free (str);
3107   if (s)
3108     gst_structure_free (s);
3109
3110   /* check invalid int64_range deserialization into a int_range */
3111   str =
3112       g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %"
3113       G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1);
3114   s = gst_structure_from_string (str, &end);
3115   fail_unless (s == NULL);
3116   fail_unless (end == NULL);
3117   g_free (str);
3118 }
3119
3120 GST_END_TEST;
3121
3122 GST_START_TEST (test_stepped_range_collection)
3123 {
3124   GstStructure *s;
3125   const GValue *v;
3126
3127   s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT_RANGE, 8, 12, NULL);
3128   fail_unless (s != NULL);
3129   v = gst_structure_get_value (s, "range");
3130   fail_unless (v != NULL);
3131   fail_unless (gst_value_get_int_range_min (v) == 8);
3132   fail_unless (gst_value_get_int_range_max (v) == 12);
3133   fail_unless (gst_value_get_int_range_step (v) == 1);
3134   gst_structure_free (s);
3135
3136   s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT64_RANGE, (gint64) 8,
3137       (gint64) 12, NULL);
3138   fail_unless (s != NULL);
3139   v = gst_structure_get_value (s, "range");
3140   fail_unless (v != NULL);
3141   fail_unless (gst_value_get_int64_range_min (v) == 8);
3142   fail_unless (gst_value_get_int64_range_max (v) == 12);
3143   fail_unless (gst_value_get_int64_range_step (v) == 1);
3144   gst_structure_free (s);
3145 }
3146
3147 GST_END_TEST;
3148
3149 GST_START_TEST (test_stepped_int_range_parsing)
3150 {
3151   gchar *str;
3152   guint n;
3153   gchar *end = NULL;
3154   GstStructure *s;
3155
3156   static const gchar *good_ranges[] = {
3157     "[0, 1, 1]",
3158     "[-2, 2, 2]",
3159     "[16, 4096, 16]",
3160   };
3161
3162   static const gchar *bad_ranges[] = {
3163     "[0, 1, -1]",
3164     "[1, 2, 2]",
3165     "[2, 3, 2]",
3166     "[0, 0, 0]",
3167     "[0, 0, 1]",
3168     "[1, 2, 0]",
3169     "[1, 1, 1]",
3170   };
3171
3172   /* check we can parse good ranges */
3173   for (n = 0; n < G_N_ELEMENTS (good_ranges); ++n) {
3174     str = g_strdup_printf ("foo/bar, range=%s", good_ranges[n]);
3175     s = gst_structure_from_string (str, &end);
3176     fail_unless (s != NULL);
3177     fail_unless (*end == '\0');
3178     gst_structure_free (s);
3179     s = NULL;
3180     g_free (str);
3181   }
3182
3183   /* check we cannot parse bad ranges */
3184   for (n = 0; n < G_N_ELEMENTS (bad_ranges); ++n) {
3185     str = g_strdup_printf ("foo/bar, range=%s", bad_ranges[n]);
3186     ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
3187     if (s)
3188       gst_structure_free (s);
3189     g_free (str);
3190   }
3191 }
3192
3193 GST_END_TEST;
3194
3195 GST_START_TEST (test_stepped_int_range_ops)
3196 {
3197   gchar *str1, *str2, *str3;
3198   guint n;
3199   GstStructure *s1, *s2, *s3;
3200   const GValue *v1, *v2, *v3;
3201
3202   static const struct
3203   {
3204     const gchar *set1;
3205     const gchar *op;
3206     const gchar *set2;
3207     const gchar *result;
3208   } ranges[] = {
3209     {
3210     "[16, 4096, 16]", "inter", "[100, 200, 10]", "160"}, {
3211     "[16, 4096, 16]", "inter", "[100, 200, 100]", NULL}, {
3212     "[16, 4096, 16]", "inter", "[0, 512, 256]", "[256, 512, 256]"}, {
3213     "[16, 32, 16]", "union", "[32, 96, 16]", "[16, 96, 16]"}, {
3214     "[16, 32, 16]", "union", "[48, 96, 16]", "[16, 96, 16]"}, {
3215     "[112, 192, 16]", "union", "[48, 96, 16]", "[48, 192, 16]"}, {
3216     "[16, 32, 16]", "union", "[64, 96, 16]", NULL}, {
3217     "[112, 192, 16]", "union", "[48, 96, 8]", NULL}, {
3218     "[10, 20, 5]", "union", "10", "[10, 20, 5]"}, {
3219     "[10, 20, 5]", "union", "20", "[10, 20, 5]"}, {
3220     "[10, 20, 5]", "union", "15", "[10, 20, 5]"}, {
3221     "[10, 20, 5]", "union", "5", "[5, 20, 5]"}, {
3222     "[10, 20, 5]", "union", "12", NULL}, {
3223     "[10, 20, 5]", "union", "30", NULL}, {
3224   "[10, 20, 5]", "union", "25", "[10, 25, 5]"},};
3225
3226   for (n = 0; n < G_N_ELEMENTS (ranges); ++n) {
3227     gchar *end = NULL;
3228     GValue dest = { 0 };
3229     gboolean ret;
3230
3231     str1 = g_strdup_printf ("foo/bar, range=%s", ranges[n].set1);
3232     s1 = gst_structure_from_string (str1, &end);
3233     fail_unless (s1 != NULL);
3234     fail_unless (*end == '\0');
3235     v1 = gst_structure_get_value (s1, "range");
3236     fail_unless (v1 != NULL);
3237
3238     str2 = g_strdup_printf ("foo/bar, range=%s", ranges[n].set2);
3239     s2 = gst_structure_from_string (str2, &end);
3240     fail_unless (s2 != NULL);
3241     fail_unless (*end == '\0');
3242     v2 = gst_structure_get_value (s2, "range");
3243     fail_unless (v2 != NULL);
3244
3245     if (!strcmp (ranges[n].op, "inter")) {
3246       ret = gst_value_intersect (&dest, v1, v2);
3247     } else if (!strcmp (ranges[n].op, "union")) {
3248       ret = gst_value_union (&dest, v1, v2);
3249     } else {
3250       fail_unless (FALSE);
3251       ret = FALSE;
3252     }
3253
3254     if (ranges[n].result) {
3255       fail_unless (ret);
3256     } else {
3257       fail_unless (!ret);
3258     }
3259
3260     if (ret) {
3261       str3 = g_strdup_printf ("foo/bar, range=%s", ranges[n].result);
3262       s3 = gst_structure_from_string (str3, &end);
3263       fail_unless (s3 != NULL);
3264       fail_unless (*end == '\0');
3265       v3 = gst_structure_get_value (s3, "range");
3266       fail_unless (v3 != NULL);
3267
3268       if (gst_value_compare (&dest, v3) != GST_VALUE_EQUAL) {
3269         GST_ERROR ("%s %s %s yielded %s, expected %s", str1, ranges[n].op, str2,
3270             gst_value_serialize (&dest), gst_value_serialize (v3));
3271         fail_unless (FALSE);
3272       }
3273
3274       gst_structure_free (s3);
3275       g_free (str3);
3276
3277       g_value_unset (&dest);
3278     }
3279
3280     gst_structure_free (s2);
3281     g_free (str2);
3282     gst_structure_free (s1);
3283     g_free (str1);
3284   }
3285 }
3286
3287 GST_END_TEST;
3288
3289 GST_START_TEST (test_structure_basic)
3290 {
3291   GstStructure *s1, *s2;
3292   GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
3293
3294   /* sanity test */
3295   s1 = gst_structure_from_string ("foo,bar=1", NULL);
3296   g_value_init (&v1, GST_TYPE_STRUCTURE);
3297   gst_value_set_structure (&v1, s1);
3298   fail_unless (gst_structure_is_equal (s1, gst_value_get_structure (&v1)));
3299
3300   s2 = gst_structure_copy (s1);
3301   g_value_init (&v2, GST_TYPE_STRUCTURE);
3302   gst_value_set_structure (&v2, s2);
3303
3304   /* can do everything but subtract */
3305   fail_unless (gst_value_can_compare (&v1, &v2));
3306   fail_unless (gst_value_can_intersect (&v1, &v2));
3307   fail_unless (!gst_value_can_subtract (&v1, &v2));
3308   fail_unless (gst_value_can_union (&v1, &v2));
3309
3310   gst_structure_free (s1);
3311   gst_structure_free (s2);
3312   g_value_unset (&v1);
3313   g_value_unset (&v2);
3314 }
3315
3316 GST_END_TEST;
3317
3318 GST_START_TEST (test_structure_single_ops)
3319 {
3320   static const struct
3321   {
3322     const gchar *str1;
3323     gboolean is_fixed;
3324     gboolean can_fixate;
3325   } single_struct[] = {
3326     {
3327     "foo,bar=(int)1", TRUE, TRUE}, {
3328   "foo,bar=(int)[1,2]", FALSE, TRUE},};
3329   gint i;
3330
3331   for (i = 0; i < G_N_ELEMENTS (single_struct); i++) {
3332     GstStructure *s1 = gst_structure_from_string (single_struct[i].str1, NULL);
3333     GValue v1 = G_VALUE_INIT;
3334     GValue v2 = G_VALUE_INIT;
3335
3336     fail_unless (s1 != NULL);
3337
3338     GST_DEBUG ("checking structure %" GST_PTR_FORMAT, s1);
3339
3340     g_value_init (&v1, GST_TYPE_STRUCTURE);
3341     gst_value_set_structure (&v1, s1);
3342
3343     fail_unless (gst_value_is_fixed (&v1) == single_struct[i].is_fixed);
3344     fail_unless (gst_value_fixate (&v2, &v1) == single_struct[i].can_fixate);
3345     if (single_struct[i].can_fixate)
3346       g_value_unset (&v2);
3347
3348     g_value_unset (&v1);
3349     gst_structure_free (s1);
3350   }
3351 }
3352
3353 GST_END_TEST;
3354
3355 GST_START_TEST (test_structure_ops)
3356 {
3357   struct
3358   {
3359     const gchar *str1;
3360     const gchar *str2;
3361     const gchar *op;
3362     gint ret;
3363     GType str_type;
3364   } comparisons[] = {
3365     /* *INDENT-OFF* */
3366     {"foo,bar=(int)1", "foo,bar=(int)1", "compare", GST_VALUE_EQUAL, 0},
3367     {"foo,bar=(int)1", "foo,bar=(int)1", "is_subset", TRUE, 0},
3368     {"foo,bar=(int)1", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE},
3369     {"foo,bar=(int)1", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE},
3370     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0},
3371     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "is_subset", FALSE, 0},
3372     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "intersect", TRUE, GST_TYPE_STRUCTURE},
3373     {"foo,bar=(int)[1,2]", "foo,bar=(int)1", "union", TRUE, GST_TYPE_STRUCTURE},
3374     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "compare", GST_VALUE_UNORDERED, 0},
3375     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "is_subset", TRUE, 0},
3376     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "intersect", TRUE, GST_TYPE_STRUCTURE},
3377     {"foo,bar=(int)1", "foo,bar=(int)[1,2]", "union", TRUE, GST_TYPE_STRUCTURE},
3378     {"foo,bar=(int)1", "foo,bar=(int)2", "compare", GST_VALUE_UNORDERED, 0},
3379     {"foo,bar=(int)1", "foo,bar=(int)2", "is_subset", FALSE, 0},
3380     {"foo,bar=(int)1", "foo,bar=(int)2", "intersect", FALSE, 0},
3381     {"foo,bar=(int)1", "foo,bar=(int)2", "union", TRUE, GST_TYPE_STRUCTURE},
3382     {"foo,bar=(int)1", "baz,bar=(int)1", "compare", GST_VALUE_UNORDERED, 0},
3383     {"foo,bar=(int)1", "baz,bar=(int)1", "is_subset", FALSE, 0},
3384     {"foo,bar=(int)1", "baz,bar=(int)1", "intersect", FALSE, 0},
3385 #if 0
3386     /* deserializing lists is not implemented (but this should still work!) */
3387     {"foo,bar=(int)1", "baz,bar=(int)1", "union", TRUE, G_TYPE_LIST},
3388 #endif
3389     /* *INDENT-ON* */
3390   };
3391   gint i;
3392
3393   for (i = 0; i < G_N_ELEMENTS (comparisons); i++) {
3394     GstStructure *s1 = gst_structure_from_string (comparisons[i].str1, NULL);
3395     GstStructure *s2 = gst_structure_from_string (comparisons[i].str2, NULL);
3396     GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT, v3 = G_VALUE_INIT;
3397
3398     fail_unless (s1 != NULL);
3399     fail_unless (s2 != NULL);
3400
3401     GST_DEBUG ("checking %s with structure1 %" GST_PTR_FORMAT " structure2 %"
3402         GST_PTR_FORMAT " is %d", comparisons[i].op, s1, s2, comparisons[i].ret);
3403
3404     g_value_init (&v1, GST_TYPE_STRUCTURE);
3405     gst_value_set_structure (&v1, s1);
3406     g_value_init (&v2, GST_TYPE_STRUCTURE);
3407     gst_value_set_structure (&v2, s2);
3408
3409     if (g_strcmp0 (comparisons[i].op, "compare") == 0) {
3410       fail_unless (gst_value_compare (&v1, &v2) == comparisons[i].ret);
3411     } else if (g_strcmp0 (comparisons[i].op, "is_subset") == 0) {
3412       fail_unless (gst_value_is_subset (&v1, &v2) == comparisons[i].ret);
3413     } else {
3414       if (g_strcmp0 (comparisons[i].op, "intersect") == 0) {
3415         fail_unless (gst_value_intersect (&v3, &v1, &v2) == comparisons[i].ret);
3416       } else if (g_strcmp0 (comparisons[i].op, "union") == 0) {
3417         fail_unless (gst_value_union (&v3, &v1, &v2) == comparisons[i].ret);
3418       }
3419       if (comparisons[i].ret) {
3420         GValue result = G_VALUE_INIT;
3421         gchar *str;
3422
3423         str = gst_value_serialize (&v3);
3424         GST_LOG ("result %s", str);
3425
3426         g_value_init (&result, comparisons[i].str_type);
3427         fail_unless (gst_value_deserialize (&result, str));
3428         g_free (str);
3429         fail_unless (gst_value_compare (&result, &v3) == GST_VALUE_EQUAL);
3430         g_value_unset (&v3);
3431         g_value_unset (&result);
3432       }
3433     }
3434
3435     gst_structure_free (s1);
3436     gst_structure_free (s2);
3437     g_value_unset (&v1);
3438     g_value_unset (&v2);
3439   }
3440 }
3441
3442 GST_END_TEST;
3443
3444 static gpointer
3445 get_serialize_deserialize_boxed (const gpointer boxed, GType type)
3446 {
3447   gchar *serialized, *cmp;
3448   GValue value = G_VALUE_INIT, value2 = G_VALUE_INIT;
3449   gpointer ret;
3450
3451   g_value_init (&value, type);
3452   g_value_init (&value2, type);
3453
3454   g_value_set_boxed (&value, boxed);
3455   serialized = gst_value_serialize (&value);
3456   fail_unless (serialized != NULL);
3457   GST_DEBUG ("serialized to %s", serialized);
3458   fail_unless (gst_value_deserialize (&value2, serialized));
3459   cmp = gst_value_serialize (&value2);
3460   fail_unless_equals_string (cmp, serialized);
3461
3462   ret = g_value_dup_boxed (&value2);
3463
3464   g_free (serialized);
3465   g_free (cmp);
3466   g_value_unset (&value);
3467   g_value_unset (&value2);
3468   return ret;
3469 }
3470
3471 GST_START_TEST (test_serialize_deserialize_structure)
3472 {
3473   GstStructure *instr = gst_structure_new ("structure/internal",
3474       "in-field", G_TYPE_INT, 20, "in-field2",
3475       G_TYPE_STRING, "some in ternal field", NULL);
3476   GstStructure *test_str[] = {
3477     gst_structure_new ("test/structure",
3478         "foo", G_TYPE_INT, 10, "bar", G_TYPE_STRING, "test",
3479         "int-str", GST_TYPE_STRUCTURE, instr, NULL),
3480     gst_structure_new_empty ("empty")
3481   };
3482   gint i;
3483   GstStructure *str, *str2;
3484
3485   gst_structure_free (instr);
3486   for (i = 0; i < G_N_ELEMENTS (test_str); i++) {
3487     str = test_str[i];
3488     str2 = get_serialize_deserialize_boxed (str, GST_TYPE_STRUCTURE);
3489     fail_unless (gst_structure_is_equal (str, str2));
3490
3491     _test_serialize_deserialize_boxed_in_structure (str, GST_TYPE_STRUCTURE);
3492
3493     gst_structure_free (str);
3494     gst_structure_free (str2);
3495   }
3496 }
3497
3498 GST_END_TEST;
3499
3500 static void
3501 setup_test_value_array (GValue * value)
3502 {
3503   GValueArray *array;
3504   GValue v = G_VALUE_INIT;
3505
3506   g_value_init (&v, G_TYPE_INT);
3507   g_value_init (value, G_TYPE_VALUE_ARRAY);
3508
3509   array = g_value_array_new (3);
3510   g_value_set_int (&v, 1);
3511   g_value_array_append (array, &v);
3512   g_value_set_int (&v, 2);
3513   g_value_array_append (array, &v);
3514   g_value_set_int (&v, 3);
3515   g_value_array_append (array, &v);
3516
3517   g_value_take_boxed (value, array);
3518 }
3519
3520 static void
3521 test_revert_array_transform (GValue * v1, GValue * v2)
3522 {
3523   GValueArray *array;
3524
3525   g_value_reset (v1);
3526
3527   fail_unless (g_value_transform (v2, v1));
3528   array = g_value_get_boxed (v1);
3529   fail_unless (array->n_values == 3);
3530   fail_unless (g_value_get_int (g_value_array_get_nth (array, 0)) == 1);
3531   fail_unless (g_value_get_int (g_value_array_get_nth (array, 1)) == 2);
3532   fail_unless (g_value_get_int (g_value_array_get_nth (array, 2)) == 3);
3533 }
3534
3535 GST_START_TEST (test_transform_array)
3536 {
3537   GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
3538
3539   setup_test_value_array (&v1);
3540
3541   g_value_init (&v2, GST_TYPE_ARRAY);
3542
3543   fail_unless (g_value_transform (&v1, &v2));
3544   fail_unless (gst_value_array_get_size (&v2) == 3);
3545   fail_unless (g_value_get_int (gst_value_array_get_value (&v2, 0)) == 1);
3546   fail_unless (g_value_get_int (gst_value_array_get_value (&v2, 1)) == 2);
3547   fail_unless (g_value_get_int (gst_value_array_get_value (&v2, 2)) == 3);
3548
3549   test_revert_array_transform (&v1, &v2);
3550
3551   g_value_unset (&v1);
3552   g_value_unset (&v2);
3553 }
3554
3555 GST_END_TEST;
3556
3557 GST_START_TEST (test_transform_list)
3558 {
3559   GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
3560
3561   setup_test_value_array (&v1);
3562
3563   g_value_init (&v2, GST_TYPE_LIST);
3564
3565   fail_unless (g_value_transform (&v1, &v2));
3566   fail_unless (gst_value_list_get_size (&v2) == 3);
3567   fail_unless (g_value_get_int (gst_value_list_get_value (&v2, 0)) == 1);
3568   fail_unless (g_value_get_int (gst_value_list_get_value (&v2, 1)) == 2);
3569   fail_unless (g_value_get_int (gst_value_list_get_value (&v2, 2)) == 3);
3570
3571   test_revert_array_transform (&v1, &v2);
3572
3573   g_value_unset (&v1);
3574   g_value_unset (&v2);
3575 }
3576
3577 GST_END_TEST;
3578
3579 GST_START_TEST (test_serialize_null_aray)
3580 {
3581   gchar *serialized;
3582   GValue v = G_VALUE_INIT;
3583
3584   g_value_init (&v, G_TYPE_VALUE_ARRAY);
3585
3586   g_value_set_boxed (&v, NULL);
3587   serialized = gst_value_serialize (&v);
3588   fail_unless_equals_string (serialized, "<  >");
3589   g_value_unset (&v);
3590   g_free (serialized);
3591 }
3592
3593 GST_END_TEST;
3594
3595 GST_START_TEST (test_deserialize_array)
3596 {
3597   GValue value = { 0 };
3598   const gchar *strings[] = {
3599     "{ test, }",
3600     "{ , }",
3601     "{ test,, }",
3602     "{ , , }",
3603   };
3604   gint results_size[] = { 1, 0, -1, -1 };       /* -1 means deserialization should fail */
3605   int i;
3606
3607   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
3608     /* Workaround a bug in our parser that would lead to segfaults
3609      * when deserializing container types using static strings */
3610     gchar *str = g_strdup (strings[i]);
3611     g_value_init (&value, GST_TYPE_LIST);
3612
3613     if (results_size[i] == -1) {
3614       fail_if (gst_value_deserialize (&value, str),
3615           "Should not be able to deserialize %s (%d) as list", str, i);
3616     } else {
3617       fail_unless (gst_value_deserialize (&value, str),
3618           "could not deserialize %s (%d)", str, i);
3619       fail_unless (gst_value_list_get_size (&value) == results_size[i],
3620           "Wrong array size: %d. expected %d",
3621           gst_value_array_get_size (&value), results_size[i]);
3622     }
3623
3624     g_value_unset (&value);
3625     g_free (str);
3626   }
3627 }
3628
3629 GST_END_TEST;
3630
3631 #define TEST_FLAGS_TYPE (test_flags_get_type())
3632 static GType
3633 test_flags_get_type (void)
3634 {
3635   static const GFlagsValue values[] = {
3636     {1, "One", "one"},
3637     {1 << 1, "Two", "two"},
3638     {1 << 3, "Eight", "eight"},
3639     {0, NULL, NULL}
3640   };
3641   static GType id = 0;
3642
3643   if (g_once_init_enter ((gsize *) & id)) {
3644     GType _id;
3645
3646     _id = g_flags_register_static ("TestFlags", values);
3647
3648     g_once_init_leave ((gsize *) & id, _id);
3649   }
3650
3651   return id;
3652 }
3653
3654 #define _RESULT(i) result_##i
3655 #define RESULT(i) _RESULT(i)
3656
3657 GST_START_TEST (test_deserialize_with_pspec)
3658 {
3659   GValue value = { 0 };
3660   GParamSpec *pspec;
3661   const gchar *strings[] = {
3662     "< one, 0>",
3663     "< one+eight, two >",
3664     "< 9, 0>",
3665   };
3666   int i;
3667
3668   gint results[3][2] = {
3669     {1, 0},
3670     {9, 2},
3671     {9, 0}
3672   };
3673
3674   pspec = gst_param_spec_array ("flags-array",
3675       "Flags Array", "An array of flags",
3676       g_param_spec_flags ("flags", "Flags", "Flags", TEST_FLAGS_TYPE, 0,
3677           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
3678       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
3679
3680   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
3681     int j;
3682     gchar *str = g_strdup (strings[i]);
3683     g_value_init (&value, GST_TYPE_ARRAY);
3684
3685     fail_unless (gst_value_deserialize_with_pspec (&value, str, pspec),
3686         "could not deserialize %s (%d)", str, i);
3687
3688     fail_unless (gst_value_array_get_size (&value) ==
3689         G_N_ELEMENTS (results[i]));
3690
3691     for (j = 0; j < G_N_ELEMENTS (results[i]); j++) {
3692       const GValue *elem_value = gst_value_array_get_value (&value, j);
3693       fail_unless (G_VALUE_TYPE (elem_value) == TEST_FLAGS_TYPE);
3694       fail_unless_equals_int (g_value_get_flags (elem_value), results[i][j]);
3695     }
3696
3697     g_value_unset (&value);
3698     g_free (str);
3699   }
3700
3701   g_param_spec_unref (pspec);
3702 }
3703
3704 GST_END_TEST;
3705
3706 GST_START_TEST (test_serialize_deserialize_segment)
3707 {
3708   GstSegment *seg, *seg2;
3709
3710   seg = gst_segment_new ();
3711   gst_segment_init (seg, GST_FORMAT_DEFAULT);
3712   fail_unless (gst_segment_do_seek (seg, 1.2, GST_FORMAT_DEFAULT,
3713           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_SET, 30,
3714           NULL));
3715   seg2 = get_serialize_deserialize_boxed (seg, GST_TYPE_SEGMENT);
3716   fail_unless (gst_segment_is_equal (seg, seg2));
3717
3718   _test_serialize_deserialize_boxed_in_structure (seg, GST_TYPE_SEGMENT);
3719
3720   gst_segment_free (seg);
3721   gst_segment_free (seg2);
3722 }
3723
3724 GST_END_TEST;
3725
3726 GST_START_TEST (test_serialize_deserialize_caps_features)
3727 {
3728   GstCapsFeatures *test_feats[] = {
3729     gst_caps_features_new ("abc:val1", "xyz:val2", NULL),
3730     gst_caps_features_new ("feat:val", NULL),
3731     gst_caps_features_new_any (),
3732     gst_caps_features_new_empty ()
3733   };
3734   gint i;
3735   GstCapsFeatures *feats, *feats2;
3736
3737   for (i = 0; i < G_N_ELEMENTS (test_feats); i++) {
3738     feats = test_feats[i];
3739     fail_unless (feats != NULL);
3740     feats2 = get_serialize_deserialize_boxed (feats, GST_TYPE_CAPS_FEATURES);
3741     fail_unless (gst_caps_features_is_equal (feats, feats2));
3742     fail_unless (gst_caps_features_is_any (feats) ==
3743         gst_caps_features_is_any (feats2));
3744
3745     _test_serialize_deserialize_boxed_in_structure (feats,
3746         GST_TYPE_CAPS_FEATURES);
3747
3748     gst_caps_features_free (feats);
3749     gst_caps_features_free (feats2);
3750   }
3751 }
3752
3753 GST_END_TEST;
3754
3755 GST_START_TEST (test_serialize_deserialize_tag_list)
3756 {
3757   GstTagList *test_tags[] = {
3758     gst_tag_list_new (GST_TAG_TITLE, "A Title", GST_TAG_ARTIST, "Art꫱",
3759         GST_TAG_TRACK_NUMBER, 1, NULL),
3760     gst_tag_list_new_empty ()
3761   };
3762   gint i;
3763   GstTagList *tags, *tags2;
3764
3765   for (i = 0; i < G_N_ELEMENTS (test_tags); i++) {
3766     tags = test_tags[i];
3767     fail_unless (tags != NULL);
3768     tags2 = get_serialize_deserialize_boxed (tags, GST_TYPE_TAG_LIST);
3769     fail_unless (gst_tag_list_is_equal (tags, tags2));
3770
3771     _test_serialize_deserialize_boxed_in_structure (tags, GST_TYPE_TAG_LIST);
3772
3773     gst_tag_list_unref (tags);
3774     gst_tag_list_unref (tags2);
3775   }
3776 }
3777
3778 GST_END_TEST;
3779
3780 GST_START_TEST (test_deserialize_serialize_nested_structures)
3781 {
3782   gint i;
3783   gchar *structure_str;
3784   GstStructure *structure, *structure2;
3785
3786   /* *INDENT-OFF* */
3787   struct
3788   {
3789     const gchar *serialized_struct;
3790     gboolean should_fail;
3791     const gchar *path_to_bool;
3792     const gchar *subcaps_str;
3793   } tests_data[] = {
3794       {"s, substruct=[sub, is-deepest=true]", FALSE, "substruct"},
3795       {"s, substruct=(structure) [sub, is-deepest=true]", FALSE, "substruct"},
3796       {"s, substruct=[sub, is-substruct=true, subsubstruct=[subsub, is-deepest=true]]", FALSE, "substruct/subsubstruct"},
3797       {"s, substruct=[sub, is-substruct=true, subsubstruct=[subsub, subsubsubstruct=[subsubsub, is-deepest=true]]]", FALSE, "substruct/subsubstruct/subsubsubstruct"},
3798       {"s, substruct=[sub, an-array={a, b}, subsubstruct=[subsub, a-range=[1,2], a-string=\"this is a \\\"string\\\"\"]]", FALSE, NULL},
3799       {"s, sub-caps=[nested-caps(some:Feature), is-caps=true; second, caps-structure=true]", FALSE, NULL, "nested-caps(some:Feature), is-caps=true; second, caps-structure=true"},
3800       {"s, sub-caps=[nested-caps(some:Feature)]", FALSE, NULL, "nested-caps(some:Feature)"},
3801       {"s, array=(structure){[struct, n=1], [struct, n=2]}"},
3802       /* Broken structure with substructures */
3803       {"s, substruct=[sub, is-substruct=true", TRUE},
3804       {"s, substruct=[sub, is-substruct=true, sub=\"yes]", TRUE},
3805       {"s, substruct=[sub, a-broken-string=$broken]", TRUE},
3806       {"s, sub-caps=(int)[nested-caps(some:Feature)]", TRUE},
3807   };
3808   /* *INDENT-ON* */
3809
3810   for (i = 0; i < G_N_ELEMENTS (tests_data); i++) {
3811     structure = gst_structure_new_from_string (tests_data[i].serialized_struct);
3812     if (tests_data[i].should_fail) {
3813       fail_if (structure, "%s not be deserialized",
3814           tests_data[i].serialized_struct);
3815       continue;
3816     }
3817     fail_unless (structure, "%s could not be deserialized",
3818         tests_data[i].serialized_struct);
3819     structure_str = gst_structure_to_string (structure);
3820     structure2 = gst_structure_new_from_string (structure_str);
3821     fail_unless (gst_structure_is_equal (structure, structure2));
3822     g_free (structure_str);
3823
3824     if (tests_data[i].path_to_bool) {
3825       const GstStructure *tmpstruct = structure;
3826       gchar **tmpstrv = g_strsplit (tests_data[i].path_to_bool, "/", -1);
3827       gint j;
3828
3829       for (j = 0; tmpstrv[j]; j++) {
3830         const GValue *v = gst_structure_get_value (tmpstruct, tmpstrv[j]);
3831
3832         fail_unless (v, "Could not find '%s' in %s", tmpstrv[j],
3833             gst_structure_to_string (tmpstruct));
3834         tmpstruct = gst_value_get_structure (v);
3835
3836         fail_unless (GST_IS_STRUCTURE (tmpstruct));
3837         if (!tmpstrv[j + 1]) {
3838           gboolean tmp;
3839
3840           fail_unless (gst_structure_get_boolean (tmpstruct, "is-deepest", &tmp)
3841               && tmp);
3842         }
3843       }
3844       g_strfreev (tmpstrv);
3845     }
3846     if (tests_data[i].subcaps_str) {
3847       const GValue *v = gst_structure_get_value (structure, "sub-caps");
3848       const GstCaps *caps = gst_value_get_caps (v);
3849       GstCaps *caps2 = gst_caps_from_string (tests_data[i].subcaps_str);
3850
3851       fail_unless (gst_caps_is_equal (caps, caps2));
3852       gst_caps_unref (caps2);
3853     }
3854
3855     /* Ensure that doing a round trip works as expected */
3856     structure_str = gst_structure_to_string (structure2);
3857     gst_structure_free (structure2);
3858     structure2 = gst_structure_new_from_string (structure_str);
3859     fail_unless (gst_structure_is_equal (structure, structure2));
3860     gst_structure_free (structure);
3861     gst_structure_free (structure2);
3862     g_free (structure_str);
3863   }
3864 }
3865
3866 GST_END_TEST;
3867
3868 GST_START_TEST (test_serialize_deserialize_sample)
3869 {
3870   GstSample *samp, *samp2;
3871   gsize buff_len = 8;
3872   const gchar buff_str[8] = "buf\ndat";
3873   gchar *buff_val;
3874   GstBuffer *buff = gst_buffer_new_wrapped (g_strdup (buff_str), buff_len);
3875   GstCaps *caps = gst_caps_new_simple ("caps", "Int", G_TYPE_INT, 20,
3876       "String", G_TYPE_STRING, "a string", NULL);
3877   GstSegment *seg = gst_segment_new ();
3878
3879   gst_segment_init (seg, GST_FORMAT_DEFAULT);
3880   fail_unless (gst_segment_do_seek (seg, 1.2, GST_FORMAT_DEFAULT,
3881           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_SET, 30,
3882           NULL));
3883   fail_unless (buff != NULL);
3884   fail_unless (caps != NULL);
3885   samp = gst_sample_new (buff, caps, seg,
3886       gst_structure_new ("structure", "Float", G_TYPE_FLOAT, -2.5, NULL));
3887   gst_buffer_unref (buff);
3888   gst_caps_unref (caps);
3889
3890   samp2 = get_serialize_deserialize_boxed (samp, GST_TYPE_SAMPLE);
3891   fail_unless (gst_caps_is_equal (gst_sample_get_caps (samp),
3892           gst_sample_get_caps (samp2)));
3893   fail_unless (gst_structure_is_equal (gst_sample_get_info (samp),
3894           gst_sample_get_info (samp2)));
3895   fail_unless (gst_segment_is_equal (gst_sample_get_segment (samp),
3896           gst_sample_get_segment (samp2)));
3897
3898   buff = gst_sample_get_buffer (samp);
3899   gst_buffer_extract_dup (buff, 0, -1, (gpointer *) & buff_val, &buff_len);
3900   fail_unless_equals_int (buff_len, 8);
3901   fail_unless_equals_string (buff_val, buff_str);
3902   g_free (buff_val);
3903   buff = gst_sample_get_buffer (samp2);
3904   gst_buffer_extract_dup (buff, 0, -1, (gpointer *) & buff_val, &buff_len);
3905   fail_unless_equals_int (buff_len, 8);
3906   fail_unless_equals_string (buff_val, buff_str);
3907   g_free (buff_val);
3908
3909   _test_serialize_deserialize_boxed_in_structure (samp, GST_TYPE_SAMPLE);
3910
3911   gst_sample_unref (samp);
3912   gst_sample_unref (samp2);
3913   gst_segment_free (seg);
3914 }
3915
3916 GST_END_TEST;
3917
3918 static Suite *
3919 gst_value_suite (void)
3920 {
3921   Suite *s = suite_create ("GstValue");
3922   TCase *tc_chain = tcase_create ("general");
3923
3924   suite_add_tcase (s, tc_chain);
3925   tcase_add_test (tc_chain, test_deserialize_buffer);
3926   tcase_add_test (tc_chain, test_serialize_buffer);
3927   tcase_add_test (tc_chain, test_deserialize_gint);
3928   tcase_add_test (tc_chain, test_deserialize_gint_failures);
3929   tcase_add_test (tc_chain, test_deserialize_guint);
3930   tcase_add_test (tc_chain, test_deserialize_guint_failures);
3931   tcase_add_test (tc_chain, test_deserialize_gint64);
3932   tcase_add_test (tc_chain, test_deserialize_guint64);
3933   tcase_add_test (tc_chain, test_deserialize_guchar);
3934   tcase_add_test (tc_chain, test_deserialize_gstfraction);
3935   tcase_add_test (tc_chain, test_deserialize_gtype);
3936   tcase_add_test (tc_chain, test_deserialize_gtype_failures);
3937   tcase_add_test (tc_chain, test_deserialize_bitmask);
3938   tcase_add_test (tc_chain, test_deserialize_array);
3939   tcase_add_test (tc_chain, test_serialize_flags);
3940   tcase_add_test (tc_chain, test_deserialize_flags);
3941   tcase_add_test (tc_chain, test_serialize_deserialize_format_enum);
3942   tcase_add_test (tc_chain, test_serialize_deserialize_value_array);
3943   tcase_add_test (tc_chain, test_string);
3944   tcase_add_test (tc_chain, test_deserialize_string);
3945   tcase_add_test (tc_chain, test_value_compare);
3946   tcase_add_test (tc_chain, test_value_intersect);
3947   tcase_add_test (tc_chain, test_value_subtract_int);
3948   tcase_add_test (tc_chain, test_value_subtract_int64);
3949   tcase_add_test (tc_chain, test_value_subtract_double);
3950   tcase_add_test (tc_chain, test_value_subtract_fraction);
3951   tcase_add_test (tc_chain, test_value_subtract_fraction_range);
3952   tcase_add_test (tc_chain, test_value_subtract_fraction_list);
3953   tcase_add_test (tc_chain, test_date);
3954   tcase_add_test (tc_chain, test_date_time);
3955   tcase_add_test (tc_chain, test_fraction_range);
3956   tcase_add_test (tc_chain, test_serialize_deserialize_caps);
3957   tcase_add_test (tc_chain, test_compare_caps);
3958   tcase_add_test (tc_chain, test_int_range);
3959   tcase_add_test (tc_chain, test_int64_range);
3960   tcase_add_test (tc_chain, test_serialize_int64_range);
3961   tcase_add_test (tc_chain, test_deserialize_int_range);
3962   tcase_add_test (tc_chain, test_stepped_range_collection);
3963   tcase_add_test (tc_chain, test_stepped_int_range_parsing);
3964   tcase_add_test (tc_chain, test_stepped_int_range_ops);
3965   tcase_add_test (tc_chain, test_flagset);
3966   tcase_add_test (tc_chain, test_structure_basic);
3967   tcase_add_test (tc_chain, test_structure_single_ops);
3968   tcase_add_test (tc_chain, test_structure_ops);
3969   tcase_add_test (tc_chain, test_serialize_deserialize_structure);
3970   tcase_add_test (tc_chain, test_transform_array);
3971   tcase_add_test (tc_chain, test_transform_list);
3972   tcase_add_test (tc_chain, test_serialize_null_aray);
3973   tcase_add_test (tc_chain, test_deserialize_with_pspec);
3974   tcase_add_test (tc_chain, test_deserialize_serialize_nested_structures);
3975   tcase_add_test (tc_chain, test_serialize_deserialize_segment);
3976   tcase_add_test (tc_chain, test_serialize_deserialize_caps_features);
3977   tcase_add_test (tc_chain, test_serialize_deserialize_tag_list);
3978   tcase_add_test (tc_chain, test_serialize_deserialize_sample);
3979
3980   return s;
3981 }
3982
3983 GST_CHECK_MAIN (gst_value);