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_structure_nested)
426 GstStructure *sp, *sc1, *sc2;
429 sc1 = gst_structure_new ("Camera",
430 "XResolution", G_TYPE_INT, 72, "YResolution", G_TYPE_INT, 73, NULL);
431 fail_unless (sc1 != NULL);
433 sc2 = gst_structure_new ("Image-Data",
434 "Orientation", G_TYPE_STRING, "top-left",
435 "Comment", G_TYPE_STRING, "super photo", NULL);
436 fail_unless (sc2 != NULL);
438 sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
439 "Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
440 fail_unless (sp != NULL);
442 fail_unless (gst_structure_n_fields (sp) == 2);
444 fail_unless (gst_structure_has_field_typed (sp, "Camera",
445 GST_TYPE_STRUCTURE));
447 str = gst_structure_to_string (sp);
448 fail_unless (str != NULL);
450 GST_DEBUG ("serialized to '%s'", str);
452 fail_unless (g_str_equal (str,
454 ", Camera=(structure)\"Camera\\,\\ XResolution\\=\\(int\\)72\\,\\ YResolution\\=\\(int\\)73\\;\""
455 ", Image Data=(structure)\"Image-Data\\,\\ Orientation\\=\\(string\\)top-left\\,\\ Comment\\=\\(string\\)\\\"super\\\\\\ photo\\\"\\;\";"));
460 gst_structure_free (sc1);
461 gst_structure_free (sc2);
462 gst_structure_free (sp);
467 GST_START_TEST (test_structure_nested_from_and_to_string)
471 gchar *str2, *end = NULL;
474 ", main-sub1=(structure)\"type-b\\,\\ machine-type\\=\\(int\\)0\\;\""
475 ", main-sub2=(structure)\"type-a\\,\\ plugin-filename\\=\\(string\\)\\\"/home/user/lib/lib\\\\\\ with\\\\\\ spaces.dll\\\"\\,\\ machine-type\\=\\(int\\)1\\;\""
476 ", main-sub3=(structure)\"type-b\\,\\ plugin-filename\\=\\(string\\)/home/user/lib/lib_no_spaces.so\\,\\ machine-type\\=\\(int\\)1\\;\""
479 s = gst_structure_from_string (str1, &end);
480 fail_unless (s != NULL);
482 GST_DEBUG ("not parsed part : %s", end);
483 fail_unless (*end == '\0');
485 fail_unless (gst_structure_n_fields (s) == 3);
487 fail_unless (gst_structure_has_field_typed (s, "main-sub1",
488 GST_TYPE_STRUCTURE));
490 str2 = gst_structure_to_string (s);
491 fail_unless (str2 != NULL);
493 fail_unless (g_str_equal (str1, str2));
497 gst_structure_free (s);
502 GST_START_TEST (test_vararg_getters)
505 GstBuffer *buf, *buf2;
507 GstCaps *caps, *caps2;
513 buf = gst_buffer_new_and_alloc (3);
514 GST_BUFFER_DATA (buf)[0] = 0xf0;
515 GST_BUFFER_DATA (buf)[1] = 0x66;
516 GST_BUFFER_DATA (buf)[2] = 0x0d;
518 caps = gst_caps_new_simple ("video/x-foo", NULL);
520 s = gst_structure_new ("test", "int", G_TYPE_INT, 12345678, "string",
521 G_TYPE_STRING, "Hello World!", "buf", GST_TYPE_BUFFER, buf, "caps",
522 GST_TYPE_CAPS, caps, "int64", G_TYPE_INT64, G_GINT64_CONSTANT (-99),
523 "double", G_TYPE_DOUBLE, G_MAXDOUBLE, "frag", GST_TYPE_FRACTION, 39, 14,
526 /* first the plain one */
527 ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, &d, "string",
528 G_TYPE_STRING, &c, "caps", GST_TYPE_CAPS, &caps2, "buf",
529 GST_TYPE_BUFFER, &buf2, "frag", GST_TYPE_FRACTION, &num, &denom, "int",
530 G_TYPE_INT, &i, "int64", G_TYPE_INT64, &i64, NULL);
533 fail_unless_equals_string (c, "Hello World!");
534 fail_unless_equals_int (i, 12345678);
535 fail_unless_equals_float (d, G_MAXDOUBLE);
536 fail_unless_equals_int (num, 39);
537 fail_unless_equals_int (denom, 14);
538 fail_unless (i64 == -99);
539 fail_unless (caps == caps2);
540 fail_unless (buf == buf2);
542 /* expected failures */
543 ASSERT_CRITICAL (gst_structure_get (s, NULL, G_TYPE_INT, &i, NULL));
544 fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "double",
545 G_TYPE_FLOAT, &d, NULL));
546 fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "dooble",
547 G_TYPE_DOUBLE, &d, NULL));
551 gst_caps_unref (caps2);
553 gst_buffer_unref (buf2);
556 /* and now the _id variant */
557 ret = gst_structure_id_get (s, g_quark_from_static_string ("double"),
558 G_TYPE_DOUBLE, &d, g_quark_from_static_string ("string"), G_TYPE_STRING,
559 &c, g_quark_from_static_string ("caps"), GST_TYPE_CAPS, &caps2,
560 g_quark_from_static_string ("buf"), GST_TYPE_BUFFER, &buf2,
561 g_quark_from_static_string ("int"), G_TYPE_INT, &i,
562 g_quark_from_static_string ("int64"), G_TYPE_INT64, &i64, NULL);
565 fail_unless_equals_string (c, "Hello World!");
566 fail_unless_equals_int (i, 12345678);
567 fail_unless_equals_float (d, G_MAXDOUBLE);
568 fail_unless (i64 == -99);
569 fail_unless (caps == caps2);
570 fail_unless (buf == buf2);
572 /* expected failures */
573 ASSERT_CRITICAL (gst_structure_get (s, 0, G_TYPE_INT, &i, NULL));
574 fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
575 G_TYPE_INT, &i, g_quark_from_static_string ("double"), G_TYPE_FLOAT,
577 fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
578 G_TYPE_INT, &i, g_quark_from_static_string ("dooble"), G_TYPE_DOUBLE,
582 gst_caps_unref (caps2);
583 gst_buffer_unref (buf2);
585 /* finally make sure NULL as return location is handled gracefully */
586 ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, NULL, "string",
587 G_TYPE_STRING, NULL, "caps", GST_TYPE_CAPS, NULL, "buf",
588 GST_TYPE_BUFFER, NULL, "int", G_TYPE_INT, &i, "frag", GST_TYPE_FRACTION,
589 NULL, NULL, "int64", G_TYPE_INT64, &i64, NULL);
591 ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, NULL,
593 ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, &num,
597 gst_caps_unref (caps);
598 gst_buffer_unref (buf);
599 gst_structure_free (s);
605 gst_structure_suite (void)
607 Suite *s = suite_create ("GstStructure");
608 TCase *tc_chain = tcase_create ("general");
610 suite_add_tcase (s, tc_chain);
611 tcase_add_test (tc_chain, test_from_string_int);
612 tcase_add_test (tc_chain, test_from_string_uint);
613 tcase_add_test (tc_chain, test_from_string);
614 tcase_add_test (tc_chain, test_to_string);
615 tcase_add_test (tc_chain, test_to_from_string);
616 tcase_add_test (tc_chain, test_string_properties);
617 tcase_add_test (tc_chain, test_complete_structure);
618 tcase_add_test (tc_chain, test_structure_new);
619 tcase_add_test (tc_chain, test_fixate);
620 tcase_add_test (tc_chain, test_fixate_frac_list);
621 tcase_add_test (tc_chain, test_structure_nested);
622 tcase_add_test (tc_chain, test_structure_nested_from_and_to_string);
623 tcase_add_test (tc_chain, test_vararg_getters);
627 GST_CHECK_MAIN (gst_structure);