2 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
4 * gststructure.c: Unit tests for GstStructure
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #include <gst/gststructure.h>
24 #include <gst/check/gstcheck.h>
27 GST_START_TEST (test_from_string_int)
29 const char *strings[] = {
30 "video/x-raw-rgb, width = (int) 123456",
31 "video/x-raw-rgb, stride = (int) -123456",
32 "video/x-raw-rgb, red_mask = (int) 0xFFFF",
33 "video/x-raw-rgb, red_mask = (int) 0x0000FFFF",
34 "video/x-raw-rgb, red_mask = (int) 0x7FFFFFFF",
35 "video/x-raw-rgb, red_mask = (int) 0x80000000",
36 "video/x-raw-rgb, red_mask = (int) 0xFF000000",
38 * gst-launch ... ! "video/x-raw-rgb, red_mask=(int)0xFF000000" ! ... */
39 "video/x-raw-rgb,\\ red_mask=(int)0xFF000000",
51 GstStructure *structure;
54 for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
61 structure = gst_structure_from_string (s, NULL);
62 fail_if (structure == NULL, "Could not get structure from string %s", s);
63 name = gst_structure_nth_field_name (structure, 0);
64 fail_unless (gst_structure_get_int (structure, name, &value));
65 fail_unless (value == results[i],
66 "Value %d is not the expected result %d for string %s",
67 value, results[i], s);
70 gst_structure_free (structure);
76 GST_START_TEST (test_from_string_uint)
78 const char *strings[] = {
79 "taglist, bar = (uint) 123456",
80 "taglist, bar = (uint) 0xFFFF",
81 "taglist, bar = (uint) 0x0000FFFF",
82 "taglist, bar = (uint) 0x7FFFFFFF",
83 "taglist, bar = (uint) 0x80000000",
84 "taglist, bar = (uint) 0xFF000000"
94 GstStructure *structure;
97 for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
104 structure = gst_structure_from_string (s, NULL);
105 fail_if (structure == NULL, "Could not get structure from string %s", s);
106 name = gst_structure_nth_field_name (structure, 0);
107 fail_unless (gst_structure_get_uint (structure, name, &value));
108 fail_unless (value == results[i],
109 "Value %u is not the expected result %u for string %s",
110 value, results[i], s);
113 gst_structure_free (structure);
119 /* Test type conversions from string */
120 GST_START_TEST (test_from_string)
122 GstStructure *structure;
126 s = "test-string,value=1";
127 structure = gst_structure_from_string (s, NULL);
128 fail_if (structure == NULL, "Could not get structure from string %s", s);
129 fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
130 fail_unless (G_VALUE_HOLDS_INT (val));
131 gst_structure_free (structure);
133 s = "test-string,value=1.0";
134 structure = gst_structure_from_string (s, NULL);
135 fail_if (structure == NULL, "Could not get structure from string %s", s);
136 fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
137 fail_unless (G_VALUE_HOLDS_DOUBLE (val));
138 gst_structure_free (structure);
140 s = "test-string,value=1/1";
141 structure = gst_structure_from_string (s, NULL);
142 fail_if (structure == NULL, "Could not get structure from string %s", s);
143 fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
144 fail_unless (GST_VALUE_HOLDS_FRACTION (val));
145 gst_structure_free (structure);
147 s = "test-string,value=bar";
148 structure = gst_structure_from_string (s, NULL);
149 fail_if (structure == NULL, "Could not get structure from string %s", s);
150 fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
151 fail_unless (G_VALUE_HOLDS_STRING (val));
152 gst_structure_free (structure);
154 s = "test-string,value=true";
155 structure = gst_structure_from_string (s, NULL);
156 fail_if (structure == NULL, "Could not get structure from string %s", s);
157 fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
158 fail_unless (G_VALUE_HOLDS_BOOLEAN (val));
159 fail_unless_equals_int (g_value_get_boolean (val), TRUE);
160 gst_structure_free (structure);
162 /* This should still work for now (FIXME: 0.11) */
163 s = "0.10:decoder-video/mpeg, abc=(boolean)false";
164 structure = gst_structure_from_string (s, NULL);
165 fail_if (structure == NULL, "Could not get structure from string %s", s);
166 gst_structure_free (structure);
168 /* make sure we bail out correctly in case of an error or if parsing fails */
169 s = "***foo***, abc=(boolean)false";
170 structure = gst_structure_from_string (s, NULL);
171 fail_unless (structure == NULL);
173 /* assert that we get a warning if the structure wasn't entirely consumed, but
174 * we didn't provide an end pointer */
175 s = "foo/bar; other random data";
176 ASSERT_WARNING (structure = gst_structure_from_string (s, NULL));
177 fail_if (structure == NULL, "Could not get structure from string %s", s);
178 gst_structure_free (structure);
184 GST_START_TEST (test_to_string)
188 ASSERT_CRITICAL (st1 = gst_structure_new ("Foo\nwith-newline", NULL));
189 fail_unless (st1 == NULL);
191 /* FIXME 0.11: re-enable this */
193 ASSERT_CRITICAL (st1 = gst_structure_new ("Foo with whitespace", NULL));
194 fail_unless (st1 == NULL);
195 ASSERT_CRITICAL (st1 = gst_structure_new ("1st", NULL));
196 fail_unless (st1 == NULL);
198 st1 = gst_structure_new ("Foo with whitespace is still allowed", NULL);
199 fail_unless (st1 != NULL);
200 gst_structure_free (st1);
202 /* structure names starting with a number are also still allowed */
203 st1 = gst_structure_new ("1st", NULL);
204 fail_unless (st1 != NULL);
205 gst_structure_free (st1);
212 GST_START_TEST (test_to_from_string)
214 GstCaps *caps1, *caps2;
215 GstStructure *st1, *st2;
216 gchar *str, *res1, *res2;
218 /* test escaping/unescaping */
219 st1 = gst_structure_new ("FooBar-123/0_1", "num", G_TYPE_INT, 9173,
220 "string", G_TYPE_STRING, "Something Like Face/Off", NULL);
221 str = gst_structure_to_string (st1);
222 st2 = gst_structure_from_string (str, NULL);
225 fail_unless (st2 != NULL);
227 /* need to put stuctures into caps to compare */
228 caps1 = gst_caps_new_empty ();
229 gst_caps_append_structure (caps1, st1);
230 caps2 = gst_caps_new_empty ();
231 gst_caps_append_structure (caps2, st2);
232 res1 = gst_caps_to_string (caps1);
233 res2 = gst_caps_to_string (caps2);
234 fail_unless (gst_caps_is_equal (caps1, caps2),
235 "Structures did not match:\n\tStructure 1: %s\n\tStructure 2: %s\n",
237 gst_caps_unref (caps1);
238 gst_caps_unref (caps2);
245 GST_START_TEST (test_complete_structure)
247 GstStructure *structure;
250 s = "GstEventSeek, rate=(double)1, format=(GstFormat)GST_FORMAT_TIME, flags=(GstSeekFlags)GST_SEEK_FLAGS_NONE, cur_type=(GstSeekType)GST_SEEK_TYPE_SET, cur=(gint64)1000000000, stop_type=(GstSeekType)GST_SEEK_TYPE_NONE, stop=(gint64)0";
251 structure = gst_structure_from_string (s, NULL);
252 fail_if (structure == NULL, "Could not get structure from string %s", s);
253 /* FIXME: TODO: add checks for correct serialization of members ? */
254 gst_structure_free (structure);
259 GST_START_TEST (test_string_properties)
261 GstCaps *caps1, *caps2;
262 GstStructure *st1, *st2;
263 gchar *str, *res1, *res2;
265 /* test escaping/unescaping */
266 st1 = gst_structure_new ("RandomStructure", "prop1", G_TYPE_STRING, "foo",
267 "prop2", G_TYPE_STRING, "", "prop3", G_TYPE_STRING, NULL,
268 "prop4", G_TYPE_STRING, "NULL", NULL);
269 str = gst_structure_to_string (st1);
270 st2 = gst_structure_from_string (str, NULL);
273 fail_unless (st2 != NULL);
275 /* need to put stuctures into caps to compare */
276 caps1 = gst_caps_new_empty ();
277 gst_caps_append_structure (caps1, st1);
278 caps2 = gst_caps_new_empty ();
279 gst_caps_append_structure (caps2, st2);
280 res1 = gst_caps_to_string (caps1);
281 res2 = gst_caps_to_string (caps2);
282 fail_unless (gst_caps_is_equal (caps1, caps2),
283 "Structures did not match:\n\tStructure 1: %s\n\tStructure 2: %s\n",
285 gst_caps_unref (caps1);
286 gst_caps_unref (caps2);
293 GST_START_TEST (test_structure_new)
300 GstClockTime clocktime;
303 s = gst_structure_new ("name",
304 "key", G_TYPE_STRING, "value",
305 "bool", G_TYPE_BOOLEAN, TRUE,
306 "fraction", GST_TYPE_FRACTION, 1, 5,
307 "clocktime", GST_TYPE_CLOCK_TIME, GST_CLOCK_TIME_NONE,
308 "fourcc", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('f', 'o', 'u', 'r'), NULL);
310 fail_unless (gst_structure_get_field_type (s, "unknown") == G_TYPE_INVALID);
311 /* test setting a different name */
312 gst_structure_set_name (s, "newname");
313 fail_unless (strcmp (gst_structure_get_string (s, "key"), "value") == 0);
314 fail_unless (gst_structure_has_field (s, "key"));
315 fail_unless_equals_int (gst_structure_n_fields (s), 5);
316 /* test removing a field */
317 gst_structure_remove_field (s, "key");
318 fail_if (gst_structure_get_string (s, "key"));
319 fail_if (gst_structure_has_field (s, "key"));
320 fail_unless_equals_int (gst_structure_n_fields (s), 4);
322 fail_unless (gst_structure_get_boolean (s, "bool", &bool));
325 fail_unless (gst_structure_get_fraction (s, "fraction", &num, &den));
326 fail_unless_equals_int (num, 1);
327 fail_unless_equals_int (den, 5);
329 fail_unless (gst_structure_get_clock_time (s, "clocktime", &clocktime));
330 fail_unless_equals_uint64 (clocktime, GST_CLOCK_TIME_NONE);
332 fail_unless (gst_structure_get_fourcc (s, "fourcc", &fourcc));
334 gst_structure_free (s);
336 domain = g_quark_from_static_string ("test");
337 e = g_error_new (domain, 0, "a test error");
338 s = gst_structure_new ("name", "key", GST_TYPE_G_ERROR, e, NULL);
340 gst_structure_free (s);
342 /* This should still work for now (FIXME 0.11) */
343 gst_structure_free (gst_structure_new ("0.10:decoder-video/mpeg", NULL));
345 /* make sure we bail out correctly in case of an error or if parsing fails */
346 ASSERT_CRITICAL (s = gst_structure_new ("^joo\nba\ndoo^",
347 "abc", G_TYPE_BOOLEAN, FALSE, NULL));
348 fail_unless (s == NULL);
353 GST_START_TEST (test_fixate)
357 s = gst_structure_new ("name",
358 "int", G_TYPE_INT, 5,
359 "intrange", GST_TYPE_INT_RANGE, 5, 10,
360 "intrange2", GST_TYPE_INT_RANGE, 5, 10, NULL);
362 fail_if (gst_structure_fixate_field_nearest_int (s, "int", 5));
363 fail_unless (gst_structure_fixate_field_nearest_int (s, "intrange", 5));
364 fail_if (gst_structure_fixate_field_nearest_int (s, "intrange", 5));
365 fail_unless (gst_structure_fixate_field_nearest_int (s, "intrange2", 15));
366 fail_if (gst_structure_fixate_field_nearest_int (s, "intrange2", 15));
367 gst_structure_free (s);
372 GST_START_TEST (test_fixate_frac_list)
374 GstStructure *s, *s2;
380 g_value_init (&list, GST_TYPE_LIST);
381 g_value_init (&frac, GST_TYPE_FRACTION);
383 gst_value_set_fraction (&frac, 30, 1);
384 gst_value_list_append_value (&list, &frac);
385 gst_value_set_fraction (&frac, 15, 1);
386 gst_value_list_append_value (&list, &frac);
387 gst_value_set_fraction (&frac, 10, 1);
388 gst_value_list_append_value (&list, &frac);
390 s = gst_structure_new ("name", NULL);
391 gst_structure_set_value (s, "frac", &list);
392 g_value_unset (&frac);
393 g_value_unset (&list);
395 str = gst_structure_to_string (s);
396 GST_DEBUG ("list %s", str);
400 s2 = gst_structure_copy (s);
402 /* fixate to the nearest fraction, this should give 15/1 */
403 fail_unless (gst_structure_fixate_field_nearest_fraction (s, "frac", 14, 1));
405 fail_unless (gst_structure_get_fraction (s, "frac", &num, &denom));
406 fail_unless (num == 15);
407 fail_unless (denom == 1);
409 gst_structure_free (s);
412 /* fixate to the nearest fraction, this should give 30/1 */
413 fail_unless (gst_structure_fixate_field_nearest_fraction (s, "frac", G_MAXINT,
416 fail_unless (gst_structure_get_fraction (s, "frac", &num, &denom));
417 fail_unless (num == 30);
418 fail_unless (denom == 1);
419 gst_structure_free (s);
424 GST_START_TEST (test_is_subset)
426 GstStructure *s1, *s2;
428 s1 = gst_structure_from_string ("test/test, channels=(int){ 1, 2 }", NULL);
429 fail_if (s1 == NULL);
430 s2 = gst_structure_from_string ("test/test, channels=(int)[ 1, 2 ]", NULL);
431 fail_if (s2 == NULL);
433 fail_unless (gst_structure_is_subset (s1, s2));
435 gst_structure_free (s1);
436 gst_structure_free (s2);
442 GST_START_TEST (test_structure_nested)
444 GstStructure *sp, *sc1, *sc2;
447 sc1 = gst_structure_new ("Camera",
448 "XResolution", G_TYPE_INT, 72, "YResolution", G_TYPE_INT, 73, NULL);
449 fail_unless (sc1 != NULL);
451 sc2 = gst_structure_new ("Image-Data",
452 "Orientation", G_TYPE_STRING, "top-left",
453 "Comment", G_TYPE_STRING, "super photo", NULL);
454 fail_unless (sc2 != NULL);
456 sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
457 "Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
458 fail_unless (sp != NULL);
460 fail_unless (gst_structure_n_fields (sp) == 2);
462 fail_unless (gst_structure_has_field_typed (sp, "Camera",
463 GST_TYPE_STRUCTURE));
465 str = gst_structure_to_string (sp);
466 fail_unless (str != NULL);
468 GST_DEBUG ("serialized to '%s'", str);
470 fail_unless (g_str_equal (str,
472 ", Camera=(structure)\"Camera\\,\\ XResolution\\=\\(int\\)72\\,\\ YResolution\\=\\(int\\)73\\;\""
473 ", Image Data=(structure)\"Image-Data\\,\\ Orientation\\=\\(string\\)top-left\\,\\ Comment\\=\\(string\\)\\\"super\\\\\\ photo\\\"\\;\";"));
478 gst_structure_free (sc1);
479 gst_structure_free (sc2);
480 gst_structure_free (sp);
485 GST_START_TEST (test_structure_nested_from_and_to_string)
489 gchar *str2, *end = NULL;
492 ", main-sub1=(structure)\"type-b\\,\\ machine-type\\=\\(int\\)0\\;\""
493 ", main-sub2=(structure)\"type-a\\,\\ plugin-filename\\=\\(string\\)\\\"/home/user/lib/lib\\\\\\ with\\\\\\ spaces.dll\\\"\\,\\ machine-type\\=\\(int\\)1\\;\""
494 ", main-sub3=(structure)\"type-b\\,\\ plugin-filename\\=\\(string\\)/home/user/lib/lib_no_spaces.so\\,\\ machine-type\\=\\(int\\)1\\;\""
497 s = gst_structure_from_string (str1, &end);
498 fail_unless (s != NULL);
500 GST_DEBUG ("not parsed part : %s", end);
501 fail_unless (*end == '\0');
503 fail_unless (gst_structure_n_fields (s) == 3);
505 fail_unless (gst_structure_has_field_typed (s, "main-sub1",
506 GST_TYPE_STRUCTURE));
508 str2 = gst_structure_to_string (s);
509 fail_unless (str2 != NULL);
511 fail_unless (g_str_equal (str1, str2));
515 gst_structure_free (s);
520 GST_START_TEST (test_vararg_getters)
523 GstBuffer *buf, *buf2;
525 GstCaps *caps, *caps2;
531 buf = gst_buffer_new_and_alloc (3);
532 GST_BUFFER_DATA (buf)[0] = 0xf0;
533 GST_BUFFER_DATA (buf)[1] = 0x66;
534 GST_BUFFER_DATA (buf)[2] = 0x0d;
536 caps = gst_caps_new_simple ("video/x-foo", NULL);
538 s = gst_structure_new ("test", "int", G_TYPE_INT, 12345678, "string",
539 G_TYPE_STRING, "Hello World!", "buf", GST_TYPE_BUFFER, buf, "caps",
540 GST_TYPE_CAPS, caps, "int64", G_TYPE_INT64, G_GINT64_CONSTANT (-99),
541 "double", G_TYPE_DOUBLE, G_MAXDOUBLE, "frag", GST_TYPE_FRACTION, 39, 14,
544 /* first the plain one */
545 ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, &d, "string",
546 G_TYPE_STRING, &c, "caps", GST_TYPE_CAPS, &caps2, "buf",
547 GST_TYPE_BUFFER, &buf2, "frag", GST_TYPE_FRACTION, &num, &denom, "int",
548 G_TYPE_INT, &i, "int64", G_TYPE_INT64, &i64, NULL);
551 fail_unless_equals_string (c, "Hello World!");
552 fail_unless_equals_int (i, 12345678);
553 fail_unless_equals_float (d, G_MAXDOUBLE);
554 fail_unless_equals_int (num, 39);
555 fail_unless_equals_int (denom, 14);
556 fail_unless (i64 == -99);
557 fail_unless (caps == caps2);
558 fail_unless (buf == buf2);
560 /* expected failures */
561 ASSERT_CRITICAL (gst_structure_get (s, NULL, G_TYPE_INT, &i, NULL));
562 fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "double",
563 G_TYPE_FLOAT, &d, NULL));
564 fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "dooble",
565 G_TYPE_DOUBLE, &d, NULL));
569 gst_caps_unref (caps2);
571 gst_buffer_unref (buf2);
574 /* and now the _id variant */
575 ret = gst_structure_id_get (s, g_quark_from_static_string ("double"),
576 G_TYPE_DOUBLE, &d, g_quark_from_static_string ("string"), G_TYPE_STRING,
577 &c, g_quark_from_static_string ("caps"), GST_TYPE_CAPS, &caps2,
578 g_quark_from_static_string ("buf"), GST_TYPE_BUFFER, &buf2,
579 g_quark_from_static_string ("int"), G_TYPE_INT, &i,
580 g_quark_from_static_string ("int64"), G_TYPE_INT64, &i64, NULL);
583 fail_unless_equals_string (c, "Hello World!");
584 fail_unless_equals_int (i, 12345678);
585 fail_unless_equals_float (d, G_MAXDOUBLE);
586 fail_unless (i64 == -99);
587 fail_unless (caps == caps2);
588 fail_unless (buf == buf2);
590 /* expected failures */
591 ASSERT_CRITICAL (gst_structure_get (s, 0, G_TYPE_INT, &i, NULL));
592 fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
593 G_TYPE_INT, &i, g_quark_from_static_string ("double"), G_TYPE_FLOAT,
595 fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
596 G_TYPE_INT, &i, g_quark_from_static_string ("dooble"), G_TYPE_DOUBLE,
600 gst_caps_unref (caps2);
601 gst_buffer_unref (buf2);
603 /* finally make sure NULL as return location is handled gracefully */
604 ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, NULL, "string",
605 G_TYPE_STRING, NULL, "caps", GST_TYPE_CAPS, NULL, "buf",
606 GST_TYPE_BUFFER, NULL, "int", G_TYPE_INT, &i, "frag", GST_TYPE_FRACTION,
607 NULL, NULL, "int64", G_TYPE_INT64, &i64, NULL);
609 ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, NULL,
611 ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, &num,
615 gst_caps_unref (caps);
616 gst_buffer_unref (buf);
617 gst_structure_free (s);
623 gst_structure_suite (void)
625 Suite *s = suite_create ("GstStructure");
626 TCase *tc_chain = tcase_create ("general");
628 suite_add_tcase (s, tc_chain);
629 tcase_add_test (tc_chain, test_from_string_int);
630 tcase_add_test (tc_chain, test_from_string_uint);
631 tcase_add_test (tc_chain, test_from_string);
632 tcase_add_test (tc_chain, test_to_string);
633 tcase_add_test (tc_chain, test_to_from_string);
634 tcase_add_test (tc_chain, test_string_properties);
635 tcase_add_test (tc_chain, test_complete_structure);
636 tcase_add_test (tc_chain, test_structure_new);
637 tcase_add_test (tc_chain, test_fixate);
638 tcase_add_test (tc_chain, test_fixate_frac_list);
639 tcase_add_test (tc_chain, test_is_subset);
640 tcase_add_test (tc_chain, test_structure_nested);
641 tcase_add_test (tc_chain, test_structure_nested_from_and_to_string);
642 tcase_add_test (tc_chain, test_vararg_getters);
646 GST_CHECK_MAIN (gst_structure);