Implement fraction ranges and extend GstFraction to support arithmetic subtraction...
[platform/upstream/gstreamer.git] / 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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23
24 #include <gst/check/gstcheck.h>
25
26
27 GST_START_TEST (test_deserialize_buffer)
28 {
29   GValue value = { 0 };
30   GstBuffer *buf;
31
32   g_value_init (&value, GST_TYPE_BUFFER);
33   fail_unless (gst_value_deserialize (&value, "1234567890abcdef"));
34   buf = GST_BUFFER (gst_value_get_mini_object (&value));
35
36   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
37
38   /* cleanup */
39   gst_buffer_unref (buf);
40 }
41
42 GST_END_TEST;
43
44 GST_START_TEST (test_deserialize_gint64)
45 {
46   GValue value = { 0 };
47   const char *strings[] = {
48     "12345678901",
49     "-12345678901",
50   };
51   gint64 results[] = {
52     12345678901LL,
53     -12345678901LL,
54   };
55   int i;
56
57   g_value_init (&value, G_TYPE_INT64);
58
59   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
60     fail_unless (gst_value_deserialize (&value, strings[i]),
61         "could not deserialize %s (%d)", strings[i], i);
62     fail_unless (g_value_get_int64 (&value) == results[i],
63         "resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT
64         ", for string %s (%d)", g_value_get_int64 (&value),
65         results[i], strings[i], i);
66   }
67 }
68
69 GST_END_TEST;
70
71 GST_START_TEST (test_deserialize_gstfraction)
72 {
73   GValue value = { 0 };
74   const char *strings[] = {
75     "4/5",
76     "-8/9"
77   };
78   gint64 result_numers[] = {
79     4,
80     -8
81   };
82   gint64 result_denoms[] = {
83     5,
84     9
85   };
86
87   int i;
88
89   g_value_init (&value, GST_TYPE_FRACTION);
90   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
91     fail_unless (gst_value_deserialize (&value, strings[i]),
92         "could not deserialize %s (%d)", strings[i], i);
93     fail_unless (gst_value_get_fraction_numerator (&value) == result_numers[i],
94         "resulting numerator value is %d, not %d"
95         ", for string %s (%d)", gst_value_get_fraction_numerator (&value),
96         result_numers[i], strings[i], i);
97     fail_unless (gst_value_get_fraction_denominator (&value) ==
98         result_denoms[i], "resulting denominator value is %d, not %d"
99         ", for string %s (%d)", gst_value_get_fraction_denominator (&value),
100         result_denoms[i], strings[i], i);
101   }
102 }
103
104 GST_END_TEST;
105
106 GST_START_TEST (test_deserialize_gint)
107 {
108   GValue value = { 0 };
109   const char *strings[] = {
110     "123456",
111     "-123456",
112     "0xFFFF",
113     "0x0000FFFF",
114     /* a positive long long, serializing to highest possible positive sint */
115     "0x7FFFFFFF",
116     /* a positive long long, serializing to lowest possible negative sint */
117     "0x80000000",
118     /* a negative long long, serializing to lowest possible negative sint */
119     "0xFFFFFFFF80000000",
120     "0xFF000000",
121     /* a positive long long serializing to -1 */
122     "0xFFFFFFFF",
123     "0xFFFFFFFF",
124     /* a negative long long serializing to -1 */
125     "0xFFFFFFFFFFFFFFFF",
126     "0xFFFFFFFFFFFFFFFF",
127     "0xEFFFFFFF",
128   };
129   gint results[] = {
130     123456,
131     -123456,
132     0xFFFF,
133     0xFFFF,
134     0x7FFFFFFF,
135     0x80000000,
136     0x80000000,
137     0xFF000000,
138     -1,
139     0xFFFFFFFF,
140     -1,
141     /* cast needs to be explicit because of unsigned -> signed */
142     (gint) 0xFFFFFFFFFFFFFFFFLL,
143     0xEFFFFFFF,
144   };
145   int i;
146
147   g_value_init (&value, G_TYPE_INT);
148
149   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
150     fail_unless (gst_value_deserialize (&value, strings[i]),
151         "could not deserialize %s (%d)", strings[i], i);
152     fail_unless (g_value_get_int (&value) == results[i],
153         "resulting value is %d, not %d, for string %s (%d)",
154         g_value_get_int (&value), results[i], strings[i], i);
155   }
156 }
157
158 GST_END_TEST;
159
160 GST_START_TEST (test_deserialize_gint_failures)
161 {
162   GValue value = { 0 };
163   const char *strings[] = {
164     "-",                        /* not a complete number */
165     "- TEST",                   /* not a complete number */
166     "0x0000000100000000",       /* lowest long long that cannot fit in 32 bits */
167     "0xF000000000000000",
168     "0xFFFFFFF000000000",
169     "0xFFFFFFFF00000000",
170     "0x10000000000000000",      /* first number too long to fit into a long long */
171     /* invent a new processor first before trying to make this one pass */
172     "0x10000000000000000000000000000000000000000000",
173   };
174   int i;
175
176   g_value_init (&value, G_TYPE_INT);
177
178   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
179     fail_if (gst_value_deserialize (&value, strings[i]),
180         "deserialized %s (%d), while it should have failed", strings[i], i);
181   }
182 }
183
184 GST_END_TEST;
185
186 GST_START_TEST (test_deserialize_guint)
187 {
188   GValue value = { 0 };
189   const char *strings[] = {
190     "123456",
191     "-123456",
192     "0xFFFF",
193     "0x0000FFFF",
194     /* a positive long long, serializing to highest possible positive sint */
195     "0x7FFFFFFF",
196     /* a positive long long, serializing to lowest possible negative sint */
197     "0x80000000",
198     "2147483648",
199     /* a negative long long, serializing to lowest possible negative sint */
200     "0xFFFFFFFF80000000",
201     /* a value typically used for rgb masks */
202     "0xFF000000",
203     /* a positive long long serializing to highest possible positive uint */
204     "0xFFFFFFFF",
205     "0xFFFFFFFF",
206     /* a negative long long serializing to highest possible positive uint */
207     "0xFFFFFFFFFFFFFFFF",
208     "0xEFFFFFFF",
209   };
210   guint results[] = {
211     123456,
212     -123456,
213     0xFFFF,
214     0xFFFF,
215     0x7FFFFFFF,
216     0x80000000,
217     (guint) 2147483648LL,
218     0x80000000,
219     0xFF000000,
220     0xFFFFFFFF,
221     G_MAXUINT,
222     (guint) 0xFFFFFFFFFFFFFFFFLL,
223     0xEFFFFFFF,
224   };
225   int i;
226
227   g_value_init (&value, G_TYPE_UINT);
228
229   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
230     fail_unless (gst_value_deserialize (&value, strings[i]),
231         "could not deserialize %s (%d)", strings[i], i);
232     fail_unless (g_value_get_uint (&value) == results[i],
233         "resulting value is %d, not %d, for string %s (%d)",
234         g_value_get_uint (&value), results[i], strings[i], i);
235   }
236 }
237
238 GST_END_TEST;
239
240 GST_START_TEST (test_deserialize_guint_failures)
241 {
242   GValue value = { 0 };
243   const char *strings[] = {
244     "-",                        /* not a complete number */
245     "- TEST",                   /* not a complete number */
246 #if 0
247 /* FIXME: these values should not be deserializable, since they overflow
248  * the target format */
249     "0x0000000100000000",       /* lowest long long that cannot fit in 32 bits */
250     "0xF000000000000000",
251     "0xFFFFFFF000000000",
252     "0xFFFFFFFF00000000",
253     "0x10000000000000000",      /* first number too long to fit into a long long */
254     /* invent a new processor first before trying to make this one pass */
255     "0x10000000000000000000000000000000000000000000",
256 #endif
257   };
258   int i;
259
260   g_value_init (&value, G_TYPE_UINT);
261
262   for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
263     fail_if (gst_value_deserialize (&value, strings[i]),
264         "deserialized %s (%d), while it should have failed", strings[i], i);
265   }
266 }
267
268 GST_END_TEST;
269
270
271 GST_START_TEST (test_string)
272 {
273   gchar *try[] = {
274     "Dude",
275     "Hi, I'm a string",
276     "tüüüt!"
277   };
278   gchar *tmp;
279   GValue v = { 0, };
280   guint i;
281
282   g_value_init (&v, G_TYPE_STRING);
283   for (i = 0; i < G_N_ELEMENTS (try); i++) {
284     g_value_set_string (&v, try[i]);
285     tmp = gst_value_serialize (&v);
286     fail_if (tmp == NULL, "couldn't serialize: %s\n", try[i]);
287     fail_unless (gst_value_deserialize (&v, tmp),
288         "couldn't deserialize: %s\n", tmp);
289     g_free (tmp);
290
291     fail_unless (g_str_equal (g_value_get_string (&v), try[i]),
292         "\nserialized  : %s\ndeserialized: %s", try[i],
293         g_value_get_string (&v));
294   }
295   /* NULL strings should not be serializable */
296   g_value_set_string (&v, NULL);
297   fail_unless (gst_value_serialize (&v) == NULL);
298   g_value_unset (&v);
299 }
300
301 GST_END_TEST;
302
303 GST_START_TEST (test_deserialize_string)
304 {
305   struct
306   {
307     gchar *from;
308     gchar *to;
309   } tests[] = {
310     {
311     "", ""},                    /* empty strings */
312     {
313     "\"\"", ""},                /* FAILURES */
314     {
315     "\"", NULL},                /* missing second quote */
316     {
317     "\"Hello\\ World", NULL},   /* missing second quote */
318     {
319     "\"\\", NULL},              /* quote at end, missing second quote */
320     {
321     "\"\\0", NULL},             /* missing second quote */
322     {
323     "\"\\0\"", NULL},           /* unfinished escaped character */
324     {
325     "\" \"", NULL},             /* spaces must be escaped */
326 #if 0
327         /* FIXME 0.9: this test should fail, but it doesn't */
328     {
329     "tüüt", NULL}             /* string with special chars must be escaped */
330 #endif
331   };
332   guint i;
333   GValue v = { 0, };
334   gboolean ret = TRUE;
335
336   g_value_init (&v, G_TYPE_STRING);
337   for (i = 0; i < G_N_ELEMENTS (tests); i++) {
338     if (gst_value_deserialize (&v, tests[i].from)) {
339       fail_if (tests[i].to == NULL,
340           "I got %s instead of a failure", g_value_get_string (&v));
341       fail_unless (g_str_equal (g_value_get_string (&v), tests[i].to),
342           "\nwanted: %s\ngot    : %s", tests[i].to, g_value_get_string (&v));
343     } else {
344       fail_if (tests[i].to != NULL, "failed, but wanted: %s", tests[i].to);
345       ret = FALSE;
346     }
347   }
348   g_value_unset (&v);
349 }
350
351 GST_END_TEST;
352
353 GST_START_TEST (test_value_compare)
354 {
355   GValue value1 = { 0 };
356   GValue value2 = { 0 };
357
358   g_value_init (&value1, G_TYPE_INT);
359   g_value_set_int (&value1, 10);
360   g_value_init (&value2, G_TYPE_INT);
361   g_value_set_int (&value2, 20);
362   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
363   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
364   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
365   g_value_unset (&value1);
366   g_value_unset (&value2);
367
368   g_value_init (&value1, G_TYPE_DOUBLE);
369   g_value_set_double (&value1, 10);
370   g_value_init (&value2, G_TYPE_DOUBLE);
371   g_value_set_double (&value2, 20);
372   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
373   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
374   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
375   g_value_unset (&value1);
376   g_value_unset (&value2);
377
378   g_value_init (&value1, G_TYPE_STRING);
379   g_value_set_string (&value1, "a");
380   g_value_init (&value2, G_TYPE_STRING);
381   g_value_set_string (&value2, "b");
382   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
383   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
384   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
385   g_value_unset (&value1);
386   g_value_unset (&value2);
387
388   g_value_init (&value1, GST_TYPE_FOURCC);
389   gst_value_set_fourcc (&value1, GST_MAKE_FOURCC ('a', 'b', 'c', 'd'));
390   g_value_init (&value2, GST_TYPE_FOURCC);
391   gst_value_set_fourcc (&value2, GST_MAKE_FOURCC ('1', '2', '3', '4'));
392   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
393   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
394   g_value_unset (&value1);
395   g_value_unset (&value2);
396
397   /* comparing 2/3 with 3/4 */
398   g_value_init (&value1, GST_TYPE_FRACTION);
399   gst_value_set_fraction (&value1, 2, 3);
400   g_value_init (&value2, GST_TYPE_FRACTION);
401   gst_value_set_fraction (&value2, 3, 4);
402   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
403   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
404   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
405   g_value_unset (&value1);
406   g_value_unset (&value2);
407
408   /* comparing -4/5 with 2/-3 */
409   g_value_init (&value1, GST_TYPE_FRACTION);
410   gst_value_set_fraction (&value1, -4, 5);
411   g_value_init (&value2, GST_TYPE_FRACTION);
412   gst_value_set_fraction (&value2, 2, -3);
413   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
414   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
415   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
416   g_value_unset (&value1);
417   g_value_unset (&value2);
418
419   /* comparing 10/100 with 200/2000 */
420   g_value_init (&value1, GST_TYPE_FRACTION);
421   gst_value_set_fraction (&value1, 10, 100);
422   g_value_init (&value2, GST_TYPE_FRACTION);
423   gst_value_set_fraction (&value2, 200, 2000);
424   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
425   g_value_unset (&value1);
426   g_value_unset (&value2);
427
428   /* comparing -4/5 with 2/-3 */
429   g_value_init (&value1, GST_TYPE_FRACTION);
430   gst_value_set_fraction (&value1, -4, 5);
431   g_value_init (&value2, GST_TYPE_FRACTION);
432   gst_value_set_fraction (&value2, 2, -3);
433   fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
434   fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
435   fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
436   g_value_unset (&value1);
437   g_value_unset (&value2);
438
439 }
440
441 GST_END_TEST;
442
443 GST_START_TEST (test_value_intersect)
444 {
445   GValue dest = { 0 };
446   GValue src1 = { 0 };
447   GValue src2 = { 0 };
448   GValue item = { 0 };
449   gboolean ret;
450
451   g_value_init (&src1, G_TYPE_INT);
452   g_value_set_int (&src1, 10);
453   g_value_init (&src2, G_TYPE_INT);
454   g_value_set_int (&src2, 20);
455   ret = gst_value_intersect (&dest, &src1, &src2);
456   fail_unless (ret == FALSE);
457   g_value_unset (&src1);
458   g_value_unset (&src2);
459
460   g_value_init (&src1, GST_TYPE_FOURCC);
461   gst_value_set_fourcc (&src1, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
462   g_value_init (&src2, GST_TYPE_LIST);
463   g_value_init (&item, GST_TYPE_FOURCC);
464   gst_value_set_fourcc (&item, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
465   gst_value_list_append_value (&src2, &item);
466   gst_value_set_fourcc (&item, GST_MAKE_FOURCC ('I', '4', '2', '0'));
467   gst_value_list_append_value (&src2, &item);
468   gst_value_set_fourcc (&item, GST_MAKE_FOURCC ('A', 'B', 'C', 'D'));
469   gst_value_list_append_value (&src2, &item);
470
471   fail_unless (gst_value_intersect (&dest, &src1, &src2));
472   fail_unless (GST_VALUE_HOLDS_FOURCC (&dest));
473   fail_unless (gst_value_get_fourcc (&dest) ==
474       GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
475 }
476
477 GST_END_TEST;
478
479
480 GST_START_TEST (test_value_subtract_int)
481 {
482   GValue dest = { 0 };
483   GValue src1 = { 0 };
484   GValue src2 = { 0 };
485   const GValue *tmp;
486   gboolean ret;
487
488   /*  int <-> int
489    */
490   g_value_init (&src1, G_TYPE_INT);
491   g_value_set_int (&src1, 10);
492   g_value_init (&src2, G_TYPE_INT);
493   g_value_set_int (&src2, 20);
494   /* subtract as in sets, result is 10 */
495   ret = gst_value_subtract (&dest, &src1, &src2);
496   fail_unless (ret == TRUE);
497   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
498   g_value_unset (&dest);
499
500   /* same values, yields empty set */
501   ret = gst_value_subtract (&dest, &src1, &src1);
502   fail_unless (ret == FALSE);
503   g_value_unset (&src1);
504   g_value_unset (&src2);
505
506   /*  int <-> int_range
507    */
508
509   /* would yield an empty set */
510   g_value_init (&src1, G_TYPE_INT);
511   g_value_set_int (&src1, 10);
512   g_value_init (&src2, GST_TYPE_INT_RANGE);
513   gst_value_set_int_range (&src2, 0, 20);
514   ret = gst_value_subtract (&dest, &src1, &src2);
515   fail_unless (ret == FALSE);
516
517   /* and the other way around, should create a list of two ranges. */
518   ret = gst_value_subtract (&dest, &src2, &src1);
519   fail_unless (ret == TRUE);
520   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
521   tmp = gst_value_list_get_value (&dest, 0);
522   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
523   fail_unless (gst_value_get_int_range_min (tmp) == 0);
524   fail_unless (gst_value_get_int_range_max (tmp) == 9);
525   tmp = gst_value_list_get_value (&dest, 1);
526   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
527   fail_unless (gst_value_get_int_range_min (tmp) == 11);
528   fail_unless (gst_value_get_int_range_max (tmp) == 20);
529   g_value_unset (&dest);
530   g_value_unset (&src1);
531   g_value_unset (&src2);
532
533   /* border case 1, empty set */
534   g_value_init (&src1, G_TYPE_INT);
535   g_value_set_int (&src1, 10);
536   g_value_init (&src2, GST_TYPE_INT_RANGE);
537   gst_value_set_int_range (&src2, 10, 20);
538   ret = gst_value_subtract (&dest, &src1, &src2);
539   fail_unless (ret == FALSE);
540
541   /* and the other way around, should create a new range. */
542   ret = gst_value_subtract (&dest, &src2, &src1);
543   fail_unless (ret == TRUE);
544   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
545   fail_unless (gst_value_get_int_range_min (&dest) == 11);
546   fail_unless (gst_value_get_int_range_max (&dest) == 20);
547   g_value_unset (&dest);
548   g_value_unset (&src1);
549   g_value_unset (&src2);
550
551   /* border case 2, empty set */
552   g_value_init (&src1, G_TYPE_INT);
553   g_value_set_int (&src1, 20);
554   g_value_init (&src2, GST_TYPE_INT_RANGE);
555   gst_value_set_int_range (&src2, 10, 20);
556   ret = gst_value_subtract (&dest, &src1, &src2);
557   fail_unless (ret == FALSE);
558
559   /* and the other way around, should create a new range. */
560   ret = gst_value_subtract (&dest, &src2, &src1);
561   fail_unless (ret == TRUE);
562   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
563   fail_unless (gst_value_get_int_range_min (&dest) == 10);
564   fail_unless (gst_value_get_int_range_max (&dest) == 19);
565   g_value_unset (&dest);
566   g_value_unset (&src1);
567   g_value_unset (&src2);
568
569   /* case 3, valid set */
570   g_value_init (&src1, G_TYPE_INT);
571   g_value_set_int (&src1, 0);
572   g_value_init (&src2, GST_TYPE_INT_RANGE);
573   gst_value_set_int_range (&src2, 10, 20);
574   ret = gst_value_subtract (&dest, &src1, &src2);
575   fail_unless (ret == TRUE);
576   fail_unless (G_VALUE_HOLDS_INT (&dest) == TRUE);
577   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
578   g_value_unset (&dest);
579
580   /* and the other way around, should keep the range. */
581   ret = gst_value_subtract (&dest, &src2, &src1);
582   fail_unless (ret == TRUE);
583   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
584   fail_unless (gst_value_get_int_range_min (&dest) == 10);
585   fail_unless (gst_value_get_int_range_max (&dest) == 20);
586   g_value_unset (&dest);
587   g_value_unset (&src1);
588   g_value_unset (&src2);
589
590   /*  int_range <-> int_range
591    */
592
593   /* same range, empty set */
594   g_value_init (&src1, GST_TYPE_INT_RANGE);
595   gst_value_set_int_range (&src1, 10, 20);
596   g_value_init (&src2, GST_TYPE_INT_RANGE);
597   gst_value_set_int_range (&src2, 10, 20);
598   ret = gst_value_subtract (&dest, &src1, &src2);
599   fail_unless (ret == FALSE);
600   ret = gst_value_subtract (&dest, &src2, &src1);
601   fail_unless (ret == FALSE);
602   g_value_unset (&src1);
603   g_value_unset (&src2);
604
605   /* non overlapping ranges */
606   g_value_init (&src1, GST_TYPE_INT_RANGE);
607   gst_value_set_int_range (&src1, 10, 20);
608   g_value_init (&src2, GST_TYPE_INT_RANGE);
609   gst_value_set_int_range (&src2, 30, 40);
610   ret = gst_value_subtract (&dest, &src1, &src2);
611   fail_unless (ret == TRUE);
612   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
613   fail_unless (gst_value_get_int_range_min (&dest) == 10);
614   fail_unless (gst_value_get_int_range_max (&dest) == 20);
615   g_value_unset (&dest);
616   /* the other way */
617   ret = gst_value_subtract (&dest, &src2, &src1);
618   fail_unless (ret == TRUE);
619   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
620   fail_unless (gst_value_get_int_range_min (&dest) == 30);
621   fail_unless (gst_value_get_int_range_max (&dest) == 40);
622   g_value_unset (&dest);
623   g_value_unset (&src1);
624   g_value_unset (&src2);
625
626   /* completely overlapping ranges */
627   g_value_init (&src1, GST_TYPE_INT_RANGE);
628   gst_value_set_int_range (&src1, 10, 20);
629   g_value_init (&src2, GST_TYPE_INT_RANGE);
630   gst_value_set_int_range (&src2, 10, 30);
631   ret = gst_value_subtract (&dest, &src1, &src2);
632   fail_unless (ret == FALSE);
633   /* the other way */
634   ret = gst_value_subtract (&dest, &src2, &src1);
635   fail_unless (ret == TRUE);
636   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
637   fail_unless (gst_value_get_int_range_min (&dest) == 21);
638   fail_unless (gst_value_get_int_range_max (&dest) == 30);
639   g_value_unset (&dest);
640   g_value_unset (&src1);
641   g_value_unset (&src2);
642
643   /* partially overlapping ranges */
644   g_value_init (&src1, GST_TYPE_INT_RANGE);
645   gst_value_set_int_range (&src1, 10, 20);
646   g_value_init (&src2, GST_TYPE_INT_RANGE);
647   gst_value_set_int_range (&src2, 15, 30);
648   ret = gst_value_subtract (&dest, &src1, &src2);
649   fail_unless (ret == TRUE);
650   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
651   fail_unless (gst_value_get_int_range_min (&dest) == 10);
652   fail_unless (gst_value_get_int_range_max (&dest) == 14);
653   g_value_unset (&dest);
654   /* the other way */
655   ret = gst_value_subtract (&dest, &src2, &src1);
656   fail_unless (ret == TRUE);
657   fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
658   fail_unless (gst_value_get_int_range_min (&dest) == 21);
659   fail_unless (gst_value_get_int_range_max (&dest) == 30);
660   g_value_unset (&dest);
661   g_value_unset (&src1);
662   g_value_unset (&src2);
663
664   /* create a hole { int_range, int_range } */
665   g_value_init (&src1, GST_TYPE_INT_RANGE);
666   gst_value_set_int_range (&src1, 10, 30);
667   g_value_init (&src2, GST_TYPE_INT_RANGE);
668   gst_value_set_int_range (&src2, 15, 20);
669   ret = gst_value_subtract (&dest, &src1, &src2);
670   fail_unless (ret == TRUE);
671   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
672   tmp = gst_value_list_get_value (&dest, 0);
673   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
674   fail_unless (gst_value_get_int_range_min (tmp) == 10);
675   fail_unless (gst_value_get_int_range_max (tmp) == 14);
676   tmp = gst_value_list_get_value (&dest, 1);
677   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
678   fail_unless (gst_value_get_int_range_min (tmp) == 21);
679   fail_unless (gst_value_get_int_range_max (tmp) == 30);
680   g_value_unset (&dest);
681   /* the other way */
682   ret = gst_value_subtract (&dest, &src2, &src1);
683   fail_unless (ret == FALSE);
684   g_value_unset (&src1);
685   g_value_unset (&src2);
686
687   /* create a hole, { int, int } */
688   g_value_init (&src1, GST_TYPE_INT_RANGE);
689   gst_value_set_int_range (&src1, 10, 30);
690   g_value_init (&src2, GST_TYPE_INT_RANGE);
691   gst_value_set_int_range (&src2, 11, 29);
692   ret = gst_value_subtract (&dest, &src1, &src2);
693   fail_unless (ret == TRUE);
694   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
695   tmp = gst_value_list_get_value (&dest, 0);
696   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
697   fail_unless (g_value_get_int (tmp) == 10);
698   tmp = gst_value_list_get_value (&dest, 1);
699   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
700   fail_unless (g_value_get_int (tmp) == 30);
701   g_value_unset (&dest);
702   /* the other way */
703   ret = gst_value_subtract (&dest, &src2, &src1);
704   fail_unless (ret == FALSE);
705   g_value_unset (&src1);
706   g_value_unset (&src2);
707
708   /* create a hole, { int, int_range } */
709   g_value_init (&src1, GST_TYPE_INT_RANGE);
710   gst_value_set_int_range (&src1, 10, 30);
711   g_value_init (&src2, GST_TYPE_INT_RANGE);
712   gst_value_set_int_range (&src2, 11, 28);
713   ret = gst_value_subtract (&dest, &src1, &src2);
714   fail_unless (ret == TRUE);
715   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
716   tmp = gst_value_list_get_value (&dest, 0);
717   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
718   fail_unless (g_value_get_int (tmp) == 10);
719   tmp = gst_value_list_get_value (&dest, 1);
720   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
721   fail_unless (gst_value_get_int_range_min (tmp) == 29);
722   fail_unless (gst_value_get_int_range_max (tmp) == 30);
723   g_value_unset (&dest);
724   /* the other way */
725   ret = gst_value_subtract (&dest, &src2, &src1);
726   fail_unless (ret == FALSE);
727   g_value_unset (&src1);
728   g_value_unset (&src2);
729
730   /* create a hole, { int_range, int } */
731   g_value_init (&src1, GST_TYPE_INT_RANGE);
732   gst_value_set_int_range (&src1, 10, 30);
733   g_value_init (&src2, GST_TYPE_INT_RANGE);
734   gst_value_set_int_range (&src2, 12, 29);
735   ret = gst_value_subtract (&dest, &src1, &src2);
736   fail_unless (ret == TRUE);
737   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
738   tmp = gst_value_list_get_value (&dest, 0);
739   fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
740   fail_unless (gst_value_get_int_range_min (tmp) == 10);
741   fail_unless (gst_value_get_int_range_max (tmp) == 11);
742   tmp = gst_value_list_get_value (&dest, 1);
743   fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
744   fail_unless (g_value_get_int (tmp) == 30);
745   g_value_unset (&dest);
746   /* the other way */
747   ret = gst_value_subtract (&dest, &src2, &src1);
748   fail_unless (ret == FALSE);
749   g_value_unset (&src1);
750   g_value_unset (&src2);
751 }
752
753 GST_END_TEST;
754
755 GST_START_TEST (test_value_subtract_double)
756 {
757   GValue dest = { 0 };
758   GValue src1 = { 0 };
759   GValue src2 = { 0 };
760   const GValue *tmp;
761   gboolean ret;
762
763   /*  double <-> double
764    */
765   g_value_init (&src1, G_TYPE_DOUBLE);
766   g_value_set_double (&src1, 10.0);
767   g_value_init (&src2, G_TYPE_DOUBLE);
768   g_value_set_double (&src2, 20.0);
769   /* subtract as in sets, result is 10 */
770   ret = gst_value_subtract (&dest, &src1, &src2);
771   fail_unless (ret == TRUE);
772   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
773   g_value_unset (&dest);
774
775   /* same values, yields empty set */
776   ret = gst_value_subtract (&dest, &src1, &src1);
777   fail_unless (ret == FALSE);
778   g_value_unset (&src1);
779   g_value_unset (&src2);
780
781   /*  double <-> double_range
782    */
783
784   /* would yield an empty set */
785   g_value_init (&src1, G_TYPE_DOUBLE);
786   g_value_set_double (&src1, 10.0);
787   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
788   gst_value_set_double_range (&src2, 0.0, 20.0);
789   ret = gst_value_subtract (&dest, &src1, &src2);
790   fail_unless (ret == FALSE);
791
792   /* and the other way around, we cannot create open ranges
793    * so the result is the range again */
794   ret = gst_value_subtract (&dest, &src2, &src1);
795   fail_unless (ret == TRUE);
796   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
797   fail_unless (gst_value_get_double_range_min (&dest) == 0.0);
798   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
799   g_value_unset (&dest);
800   g_value_unset (&src1);
801   g_value_unset (&src2);
802
803   /* border case 1, empty set */
804   g_value_init (&src1, G_TYPE_DOUBLE);
805   g_value_set_double (&src1, 10.0);
806   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
807   gst_value_set_double_range (&src2, 10.0, 20.0);
808   ret = gst_value_subtract (&dest, &src1, &src2);
809   fail_unless (ret == FALSE);
810
811   /* and the other way around, should keep same range as
812    * we don't have open ranges. */
813   ret = gst_value_subtract (&dest, &src2, &src1);
814   fail_unless (ret == TRUE);
815   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
816   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
817   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
818   g_value_unset (&dest);
819   g_value_unset (&src1);
820   g_value_unset (&src2);
821
822   /* border case 2, empty set */
823   g_value_init (&src1, G_TYPE_DOUBLE);
824   g_value_set_double (&src1, 20.0);
825   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
826   gst_value_set_double_range (&src2, 10.0, 20.0);
827   ret = gst_value_subtract (&dest, &src1, &src2);
828   fail_unless (ret == FALSE);
829
830   /* and the other way around, should keep same range as
831    * we don't have open ranges. */
832   ret = gst_value_subtract (&dest, &src2, &src1);
833   fail_unless (ret == TRUE);
834   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
835   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
836   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
837   g_value_unset (&dest);
838   g_value_unset (&src1);
839   g_value_unset (&src2);
840
841   /* case 3, valid set */
842   g_value_init (&src1, G_TYPE_DOUBLE);
843   g_value_set_double (&src1, 0.0);
844   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
845   gst_value_set_double_range (&src2, 10.0, 20.0);
846   ret = gst_value_subtract (&dest, &src1, &src2);
847   fail_unless (ret == TRUE);
848   fail_unless (G_VALUE_HOLDS_DOUBLE (&dest) == TRUE);
849   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
850   g_value_unset (&dest);
851
852   /* and the other way around, should keep the range. */
853   ret = gst_value_subtract (&dest, &src2, &src1);
854   fail_unless (ret == TRUE);
855   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
856   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
857   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
858   g_value_unset (&dest);
859   g_value_unset (&src1);
860   g_value_unset (&src2);
861
862   /*  double_range <-> double_range
863    */
864
865   /* same range, empty set */
866   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
867   gst_value_set_double_range (&src1, 10.0, 20.0);
868   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
869   gst_value_set_double_range (&src2, 10.0, 20.0);
870   ret = gst_value_subtract (&dest, &src1, &src2);
871   fail_unless (ret == FALSE);
872   ret = gst_value_subtract (&dest, &src2, &src1);
873   fail_unless (ret == FALSE);
874   g_value_unset (&src1);
875   g_value_unset (&src2);
876
877   /* non overlapping ranges */
878   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
879   gst_value_set_double_range (&src1, 10.0, 20.0);
880   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
881   gst_value_set_double_range (&src2, 30.0, 40.0);
882   ret = gst_value_subtract (&dest, &src1, &src2);
883   fail_unless (ret == TRUE);
884   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
885   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
886   fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
887   g_value_unset (&dest);
888   /* the other way */
889   ret = gst_value_subtract (&dest, &src2, &src1);
890   fail_unless (ret == TRUE);
891   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
892   fail_unless (gst_value_get_double_range_min (&dest) == 30.0);
893   fail_unless (gst_value_get_double_range_max (&dest) == 40.0);
894   g_value_unset (&dest);
895   g_value_unset (&src1);
896   g_value_unset (&src2);
897
898   /* completely overlapping ranges */
899   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
900   gst_value_set_double_range (&src1, 10.0, 20.0);
901   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
902   gst_value_set_double_range (&src2, 10.0, 30.0);
903   ret = gst_value_subtract (&dest, &src1, &src2);
904   fail_unless (ret == FALSE);
905   /* the other way */
906   ret = gst_value_subtract (&dest, &src2, &src1);
907   fail_unless (ret == TRUE);
908   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
909   fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
910   fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
911   g_value_unset (&dest);
912   g_value_unset (&src1);
913   g_value_unset (&src2);
914
915   /* partially overlapping ranges */
916   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
917   gst_value_set_double_range (&src1, 10.0, 20.0);
918   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
919   gst_value_set_double_range (&src2, 15.0, 30.0);
920   ret = gst_value_subtract (&dest, &src1, &src2);
921   fail_unless (ret == TRUE);
922   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
923   fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
924   fail_unless (gst_value_get_double_range_max (&dest) == 15.0);
925   g_value_unset (&dest);
926   /* the other way */
927   ret = gst_value_subtract (&dest, &src2, &src1);
928   fail_unless (ret == TRUE);
929   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
930   fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
931   fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
932   g_value_unset (&dest);
933   g_value_unset (&src1);
934   g_value_unset (&src2);
935
936   /* create a hole { double_range, double_range } */
937   g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
938   gst_value_set_double_range (&src1, 10.0, 30.0);
939   g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
940   gst_value_set_double_range (&src2, 15.0, 20.0);
941   ret = gst_value_subtract (&dest, &src1, &src2);
942   fail_unless (ret == TRUE);
943   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
944   tmp = gst_value_list_get_value (&dest, 0);
945   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
946   fail_unless (gst_value_get_double_range_min (tmp) == 10.0);
947   fail_unless (gst_value_get_double_range_max (tmp) == 15.0);
948   tmp = gst_value_list_get_value (&dest, 1);
949   fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
950   fail_unless (gst_value_get_double_range_min (tmp) == 20.0);
951   fail_unless (gst_value_get_double_range_max (tmp) == 30.0);
952   g_value_unset (&dest);
953   /* the other way */
954   ret = gst_value_subtract (&dest, &src2, &src1);
955   fail_unless (ret == FALSE);
956   g_value_unset (&src1);
957   g_value_unset (&src2);
958 }
959
960 GST_END_TEST;
961
962 /* Test arithmetic subtraction of fractions */
963 GST_START_TEST (test_value_subtract_fraction)
964 {
965   GValue result = { 0 };
966   GValue src1 = { 0 };
967   GValue src2 = { 0 };
968
969   /* Subtract 1/4 from 1/2 */
970   g_value_init (&src1, GST_TYPE_FRACTION);
971   g_value_init (&src2, GST_TYPE_FRACTION);
972   g_value_init (&result, GST_TYPE_FRACTION);
973   gst_value_set_fraction (&src1, 1, 2);
974   gst_value_set_fraction (&src2, 1, 4);
975   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
976   fail_unless (gst_value_get_fraction_numerator (&result) == 1);
977   fail_unless (gst_value_get_fraction_denominator (&result) == 4);
978
979   g_value_unset (&src1);
980   g_value_unset (&src2);
981   g_value_unset (&result);
982
983   /* Subtract 1/12 from 7/8 */
984   g_value_init (&src1, GST_TYPE_FRACTION);
985   g_value_init (&src2, GST_TYPE_FRACTION);
986   g_value_init (&result, GST_TYPE_FRACTION);
987   gst_value_set_fraction (&src1, 7, 8);
988   gst_value_set_fraction (&src2, 1, 12);
989   fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
990   fail_unless (gst_value_get_fraction_numerator (&result) == 19);
991   fail_unless (gst_value_get_fraction_denominator (&result) == 24);
992
993   g_value_unset (&src1);
994   g_value_unset (&src2);
995   g_value_unset (&result);
996 }
997
998 GST_END_TEST;
999
1000 /* Test set subtraction operations on fraction ranges */
1001 GST_START_TEST (test_value_subtract_fraction_range)
1002 {
1003   GValue dest = { 0 };
1004   GValue src1 = { 0 };
1005   GValue src2 = { 0 };
1006   GValue cmp = { 0 };
1007   const GValue *tmp;
1008   gboolean ret;
1009
1010   /* Value for tests */
1011   g_value_init (&cmp, GST_TYPE_FRACTION);
1012
1013   /*  fraction <-> fraction
1014    */
1015   g_value_init (&src1, GST_TYPE_FRACTION);
1016   gst_value_set_fraction (&src1, 10, 1);
1017   g_value_init (&src2, GST_TYPE_FRACTION);
1018   gst_value_set_fraction (&src2, 20, 1);
1019   gst_value_set_fraction (&src1, 10, 1);
1020
1021   /* subtract as in sets, result is 10 */
1022   ret = gst_value_subtract (&dest, &src1, &src2);
1023   fail_unless (ret == TRUE);
1024   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1025   g_value_unset (&dest);
1026
1027   /* same values, yields empty set */
1028   ret = gst_value_subtract (&dest, &src1, &src1);
1029   fail_unless (ret == FALSE);
1030   g_value_unset (&src1);
1031   g_value_unset (&src2);
1032
1033   /*  fraction <-> fraction_range
1034    */
1035
1036   /* would yield an empty set */
1037   g_value_init (&src1, GST_TYPE_FRACTION);
1038   gst_value_set_fraction (&src1, 10, 1);
1039   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1040   gst_value_set_fraction_range_full (&src2, 0, 1, 20, 1);
1041   ret = gst_value_subtract (&dest, &src1, &src2);
1042   fail_unless (ret == FALSE);
1043
1044   /* and the other way around, we cannot create open ranges
1045    * so the result is the range again */
1046   ret = gst_value_subtract (&dest, &src2, &src1);
1047   fail_unless (ret == TRUE);
1048   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1049   gst_value_set_fraction (&cmp, 0, 1);
1050   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1051           &cmp) == GST_VALUE_EQUAL);
1052   gst_value_set_fraction (&cmp, 20, 1);
1053   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1054           &cmp) == GST_VALUE_EQUAL);
1055   g_value_unset (&dest);
1056   g_value_unset (&src1);
1057   g_value_unset (&src2);
1058
1059   /* border case 1, empty set */
1060   g_value_init (&src1, GST_TYPE_FRACTION);
1061   gst_value_set_fraction (&src1, 10, 1);
1062   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1063   gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
1064   ret = gst_value_subtract (&dest, &src1, &src2);
1065   fail_unless (ret == FALSE);
1066
1067   /* and the other way around, should keep same range as
1068    * we don't have open ranges. */
1069   ret = gst_value_subtract (&dest, &src2, &src1);
1070   fail_unless (ret == TRUE);
1071   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1072   gst_value_set_fraction (&cmp, 10, 1);
1073   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1074           &cmp) == GST_VALUE_EQUAL);
1075   gst_value_set_fraction (&cmp, 20, 1);
1076   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1077           &cmp) == GST_VALUE_EQUAL);
1078   g_value_unset (&dest);
1079   g_value_unset (&src1);
1080   g_value_unset (&src2);
1081
1082   /* case 2, valid set */
1083   g_value_init (&src1, GST_TYPE_FRACTION);
1084   gst_value_set_fraction (&src1, 0, 1);
1085   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1086   gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
1087   ret = gst_value_subtract (&dest, &src1, &src2);
1088   fail_unless (ret == TRUE);
1089   fail_unless (GST_VALUE_HOLDS_FRACTION (&dest) == TRUE);
1090   fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
1091   g_value_unset (&dest);
1092
1093   /* and the other way around, should keep the range. */
1094   ret = gst_value_subtract (&dest, &src2, &src1);
1095   fail_unless (ret == TRUE);
1096   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1097   fail_unless (gst_value_compare (&dest, &src2) == GST_VALUE_EQUAL);
1098   g_value_unset (&dest);
1099   g_value_unset (&src1);
1100   g_value_unset (&src2);
1101
1102   /*  fraction_range <-> fraction_range
1103    */
1104
1105   /* same range, empty set */
1106   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
1107   gst_value_set_fraction_range_full (&src1, 10, 2, 20, 2);
1108   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1109   gst_value_set_fraction_range_full (&src2, 10, 2, 20, 2);
1110   ret = gst_value_subtract (&dest, &src1, &src2);
1111   fail_unless (ret == FALSE);
1112   ret = gst_value_subtract (&dest, &src2, &src1);
1113   fail_unless (ret == FALSE);
1114   g_value_unset (&src1);
1115   g_value_unset (&src2);
1116
1117   /* non overlapping ranges */
1118   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
1119   gst_value_set_fraction_range_full (&src1, 10, 2, 10, 1);
1120   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1121   gst_value_set_fraction_range_full (&src2, 30, 2, 40, 2);
1122   ret = gst_value_subtract (&dest, &src1, &src2);
1123   fail_unless (ret == TRUE);
1124   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1125   gst_value_set_fraction (&cmp, 5, 1);
1126   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1127           &cmp) == GST_VALUE_EQUAL);
1128   gst_value_set_fraction (&cmp, 10, 1);
1129   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1130           &cmp) == GST_VALUE_EQUAL);
1131
1132   g_value_unset (&dest);
1133   /* the other way */
1134   ret = gst_value_subtract (&dest, &src2, &src1);
1135   fail_unless (ret == TRUE);
1136   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1137   gst_value_set_fraction (&cmp, 15, 1);
1138   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1139           &cmp) == GST_VALUE_EQUAL);
1140   gst_value_set_fraction (&cmp, 20, 1);
1141   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1142           &cmp) == GST_VALUE_EQUAL);
1143   g_value_unset (&dest);
1144   g_value_unset (&src1);
1145   g_value_unset (&src2);
1146
1147   /* completely overlapping ranges */
1148   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
1149   gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
1150   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1151   gst_value_set_fraction_range_full (&src2, 10, 1, 30, 1);
1152   ret = gst_value_subtract (&dest, &src1, &src2);
1153   fail_unless (ret == FALSE);
1154   /* the other way */
1155   ret = gst_value_subtract (&dest, &src2, &src1);
1156   fail_unless (ret == TRUE);
1157   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1158   gst_value_set_fraction (&cmp, 20, 1);
1159   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1160           &cmp) == GST_VALUE_EQUAL);
1161   gst_value_set_fraction (&cmp, 30, 1);
1162   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1163           &cmp) == GST_VALUE_EQUAL);
1164   g_value_unset (&dest);
1165   g_value_unset (&src1);
1166   g_value_unset (&src2);
1167
1168   /* partially overlapping ranges */
1169   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
1170   gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
1171   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1172   gst_value_set_fraction_range_full (&src2, 15, 1, 30, 1);
1173   ret = gst_value_subtract (&dest, &src1, &src2);
1174   fail_unless (ret == TRUE);
1175   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1176   gst_value_set_fraction (&cmp, 10, 1);
1177   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1178           &cmp) == GST_VALUE_EQUAL);
1179   gst_value_set_fraction (&cmp, 15, 1);
1180   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1181           &cmp) == GST_VALUE_EQUAL);
1182   g_value_unset (&dest);
1183
1184   /* the other way */
1185   ret = gst_value_subtract (&dest, &src2, &src1);
1186   fail_unless (ret == TRUE);
1187   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
1188   gst_value_set_fraction (&cmp, 20, 1);
1189   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
1190           &cmp) == GST_VALUE_EQUAL);
1191   gst_value_set_fraction (&cmp, 30, 1);
1192   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
1193           &cmp) == GST_VALUE_EQUAL);
1194   g_value_unset (&dest);
1195   g_value_unset (&src1);
1196   g_value_unset (&src2);
1197
1198   /* create a hole { double_range, double_range } */
1199   g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
1200   gst_value_set_fraction_range_full (&src1, 10, 1, 30, 1);
1201   g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
1202   gst_value_set_fraction_range_full (&src2, 15, 1, 20, 1);
1203   ret = gst_value_subtract (&dest, &src1, &src2);
1204   fail_unless (ret == TRUE);
1205   fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
1206   /* 1st list entry */
1207   tmp = gst_value_list_get_value (&dest, 0);
1208   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
1209   gst_value_set_fraction (&cmp, 10, 1);
1210   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
1211           &cmp) == GST_VALUE_EQUAL);
1212   gst_value_set_fraction (&cmp, 15, 1);
1213   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
1214           &cmp) == GST_VALUE_EQUAL);
1215   /* 2nd list entry */
1216   tmp = gst_value_list_get_value (&dest, 1);
1217   fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
1218   gst_value_set_fraction (&cmp, 20, 1);
1219   fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
1220           &cmp) == GST_VALUE_EQUAL);
1221   gst_value_set_fraction (&cmp, 30, 1);
1222   fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
1223           &cmp) == GST_VALUE_EQUAL);
1224   g_value_unset (&dest);
1225   /* the other way */
1226   ret = gst_value_subtract (&dest, &src2, &src1);
1227   fail_unless (ret == FALSE);
1228   g_value_unset (&src1);
1229   g_value_unset (&src2);
1230
1231   g_value_unset (&cmp);
1232 }
1233
1234 GST_END_TEST;
1235
1236 GST_START_TEST (test_date)
1237 {
1238   GstStructure *s;
1239   GDate *date, *date2;
1240   gchar *str;
1241
1242   date = g_date_new_dmy (22, 9, 2005);
1243
1244   s = gst_structure_new ("media/x-type", "SOME_DATE_TAG", GST_TYPE_DATE,
1245       date, NULL);
1246
1247   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG",
1248           GST_TYPE_DATE));
1249   fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date2));
1250   fail_unless (date2 != NULL);
1251   fail_unless (g_date_valid (date2));
1252   fail_unless (g_date_compare (date, date2) == 0);
1253
1254   g_date_free (date);
1255   g_date_free (date2);
1256   date = NULL;
1257   date2 = NULL;
1258
1259   str = gst_structure_to_string (s);
1260   gst_structure_free (s);
1261   s = NULL;
1262
1263   fail_unless (g_str_equal (str,
1264           "media/x-type, SOME_DATE_TAG=(GstDate)2005-09-22"));
1265
1266   s = gst_structure_from_string (str, NULL);
1267   g_free (str);
1268   str = NULL;
1269
1270   fail_unless (s != NULL);
1271   fail_unless (gst_structure_has_name (s, "media/x-type"));
1272   fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG",
1273           GST_TYPE_DATE));
1274   fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date));
1275   fail_unless (date != NULL);
1276   fail_unless (g_date_valid (date));
1277   fail_unless (g_date_get_day (date) == 22);
1278   fail_unless (g_date_get_month (date) == 9);
1279   fail_unless (g_date_get_year (date) == 2005);
1280   g_date_free (date);
1281   date = NULL;
1282
1283   str = gst_structure_to_string (s);
1284   gst_structure_free (s);
1285   s = NULL;
1286
1287   fail_unless (g_str_equal (str,
1288           "media/x-type, SOME_DATE_TAG=(GstDate)2005-09-22"));
1289   g_free (str);
1290   str = NULL;
1291 }
1292
1293 GST_END_TEST;
1294
1295 GST_START_TEST (test_fraction_range)
1296 {
1297   GValue range = { 0, };
1298   GValue start = { 0, }, end = {
1299   0,};
1300   GValue src = { 0, }, dest = {
1301   0,};
1302   GValue range2 = { 0, };
1303
1304   g_value_init (&range, GST_TYPE_FRACTION_RANGE);
1305   g_value_init (&range2, GST_TYPE_FRACTION_RANGE);
1306   g_value_init (&start, GST_TYPE_FRACTION);
1307   g_value_init (&end, GST_TYPE_FRACTION);
1308   g_value_init (&src, GST_TYPE_FRACTION);
1309
1310   gst_value_set_fraction (&src, 1, 2);
1311
1312   /* Check that a intersection of fraction & range = fraction */
1313   gst_value_set_fraction (&start, 1, 4);
1314   gst_value_set_fraction (&end, 2, 3);
1315   gst_value_set_fraction_range (&range, &start, &end);
1316
1317   fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
1318   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
1319   fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
1320
1321   /* Check that a intersection selects the overlapping range */
1322   gst_value_set_fraction (&start, 1, 3);
1323   gst_value_set_fraction (&end, 2, 3);
1324   gst_value_set_fraction_range (&range2, &start, &end);
1325   g_value_unset (&dest);
1326   fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
1327   fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
1328
1329   gst_value_set_fraction_range (&range2, &start, &end);
1330   fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
1331
1332   /* Check that non intersection ranges don't intersect */
1333   gst_value_set_fraction (&start, 4, 2);
1334   gst_value_set_fraction (&end, 5, 2);
1335   gst_value_set_fraction_range (&range2, &start, &end);
1336   g_value_unset (&dest);
1337   fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
1338
1339   g_value_unset (&start);
1340   g_value_unset (&end);
1341   g_value_unset (&range);
1342   g_value_unset (&range2);
1343   g_value_unset (&src);
1344 }
1345
1346 GST_END_TEST;
1347
1348 Suite *
1349 gst_value_suite (void)
1350 {
1351   Suite *s = suite_create ("GstValue");
1352   TCase *tc_chain = tcase_create ("general");
1353
1354   suite_add_tcase (s, tc_chain);
1355   tcase_add_test (tc_chain, test_deserialize_buffer);
1356   tcase_add_test (tc_chain, test_deserialize_gint);
1357   tcase_add_test (tc_chain, test_deserialize_gint_failures);
1358   tcase_add_test (tc_chain, test_deserialize_guint);
1359   tcase_add_test (tc_chain, test_deserialize_guint_failures);
1360   tcase_add_test (tc_chain, test_deserialize_gint64);
1361   tcase_add_test (tc_chain, test_deserialize_gstfraction);
1362   tcase_add_test (tc_chain, test_string);
1363   tcase_add_test (tc_chain, test_deserialize_string);
1364   tcase_add_test (tc_chain, test_value_compare);
1365   tcase_add_test (tc_chain, test_value_intersect);
1366   tcase_add_test (tc_chain, test_value_subtract_int);
1367   tcase_add_test (tc_chain, test_value_subtract_double);
1368   tcase_add_test (tc_chain, test_value_subtract_fraction);
1369   tcase_add_test (tc_chain, test_value_subtract_fraction_range);
1370   tcase_add_test (tc_chain, test_date);
1371   tcase_add_test (tc_chain, test_fraction_range);
1372
1373   return s;
1374 }
1375
1376 int
1377 main (int argc, char **argv)
1378 {
1379   int nf;
1380
1381   Suite *s = gst_value_suite ();
1382   SRunner *sr = srunner_create (s);
1383
1384   gst_check_init (&argc, &argv);
1385
1386   srunner_run_all (sr, CK_NORMAL);
1387   nf = srunner_ntests_failed (sr);
1388   srunner_free (sr);
1389
1390   return nf;
1391 }