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 s = "0.10:decoder-video/mpeg, abc=(boolean)false";
163 ASSERT_CRITICAL (structure = gst_structure_from_string (s, NULL));
164 fail_unless (structure == NULL, "Could not get structure from string %s", s);
166 /* make sure we bail out correctly in case of an error or if parsing fails */
167 s = "***foo***, abc=(boolean)false";
168 structure = gst_structure_from_string (s, NULL);
169 fail_unless (structure == NULL);
171 /* assert that we get a warning if the structure wasn't entirely consumed, but
172 * we didn't provide an end pointer */
173 s = "foo/bar; other random data";
174 ASSERT_WARNING (structure = gst_structure_from_string (s, NULL));
175 fail_if (structure == NULL, "Could not get structure from string %s", s);
176 gst_structure_free (structure);
182 GST_START_TEST (test_to_string)
186 ASSERT_CRITICAL (st1 = gst_structure_new ("Foo\nwith-newline", NULL));
187 fail_unless (st1 == NULL);
189 ASSERT_CRITICAL (st1 = gst_structure_new ("Foo with whitespace", NULL));
190 fail_unless (st1 == NULL);
191 ASSERT_CRITICAL (st1 = gst_structure_new ("1st", NULL));
192 fail_unless (st1 == NULL);
198 GST_START_TEST (test_to_from_string)
200 GstCaps *caps1, *caps2;
201 GstStructure *st1, *st2;
202 gchar *str, *res1, *res2;
204 /* test escaping/unescaping */
205 st1 = gst_structure_new ("FooBar-123/0_1", "num", G_TYPE_INT, 9173,
206 "string", G_TYPE_STRING, "Something Like Face/Off", NULL);
207 str = gst_structure_to_string (st1);
208 st2 = gst_structure_from_string (str, NULL);
211 fail_unless (st2 != NULL);
213 /* need to put stuctures into caps to compare */
214 caps1 = gst_caps_new_empty ();
215 gst_caps_append_structure (caps1, st1);
216 caps2 = gst_caps_new_empty ();
217 gst_caps_append_structure (caps2, st2);
218 res1 = gst_caps_to_string (caps1);
219 res2 = gst_caps_to_string (caps2);
220 fail_unless (gst_caps_is_equal (caps1, caps2),
221 "Structures did not match:\n\tStructure 1: %s\n\tStructure 2: %s\n",
223 gst_caps_unref (caps1);
224 gst_caps_unref (caps2);
231 GST_START_TEST (test_complete_structure)
233 GstStructure *structure;
236 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";
237 structure = gst_structure_from_string (s, NULL);
238 fail_if (structure == NULL, "Could not get structure from string %s", s);
239 /* FIXME: TODO: add checks for correct serialization of members ? */
240 gst_structure_free (structure);
245 GST_START_TEST (test_string_properties)
247 GstCaps *caps1, *caps2;
248 GstStructure *st1, *st2;
249 gchar *str, *res1, *res2;
251 /* test escaping/unescaping */
252 st1 = gst_structure_new ("RandomStructure", "prop1", G_TYPE_STRING, "foo",
253 "prop2", G_TYPE_STRING, "", "prop3", G_TYPE_STRING, NULL,
254 "prop4", G_TYPE_STRING, "NULL", NULL);
255 str = gst_structure_to_string (st1);
256 st2 = gst_structure_from_string (str, NULL);
259 fail_unless (st2 != NULL);
261 /* need to put stuctures into caps to compare */
262 caps1 = gst_caps_new_empty ();
263 gst_caps_append_structure (caps1, st1);
264 caps2 = gst_caps_new_empty ();
265 gst_caps_append_structure (caps2, st2);
266 res1 = gst_caps_to_string (caps1);
267 res2 = gst_caps_to_string (caps2);
268 fail_unless (gst_caps_is_equal (caps1, caps2),
269 "Structures did not match:\n\tStructure 1: %s\n\tStructure 2: %s\n",
271 gst_caps_unref (caps1);
272 gst_caps_unref (caps2);
279 GST_START_TEST (test_structure_new)
286 GstClockTime clocktime;
288 s = gst_structure_new ("name",
289 "key", G_TYPE_STRING, "value",
290 "bool", G_TYPE_BOOLEAN, TRUE,
291 "fraction", GST_TYPE_FRACTION, 1, 5,
292 "clocktime", GST_TYPE_CLOCK_TIME, GST_CLOCK_TIME_NONE, NULL);
294 fail_unless (gst_structure_get_field_type (s, "unknown") == G_TYPE_INVALID);
295 /* test setting a different name */
296 gst_structure_set_name (s, "newname");
297 fail_unless (strcmp (gst_structure_get_string (s, "key"), "value") == 0);
298 fail_unless (gst_structure_has_field (s, "key"));
299 fail_unless_equals_int (gst_structure_n_fields (s), 4);
300 /* test removing a field */
301 gst_structure_remove_field (s, "key");
302 fail_if (gst_structure_get_string (s, "key"));
303 fail_if (gst_structure_has_field (s, "key"));
304 fail_unless_equals_int (gst_structure_n_fields (s), 3);
306 fail_unless (gst_structure_get_boolean (s, "bool", &bool));
309 fail_unless (gst_structure_get_fraction (s, "fraction", &num, &den));
310 fail_unless_equals_int (num, 1);
311 fail_unless_equals_int (den, 5);
313 fail_unless (gst_structure_get_clock_time (s, "clocktime", &clocktime));
314 fail_unless_equals_uint64 (clocktime, GST_CLOCK_TIME_NONE);
316 gst_structure_free (s);
318 domain = g_quark_from_static_string ("test");
319 e = g_error_new (domain, 0, "a test error");
320 s = gst_structure_new ("name", "key", GST_TYPE_G_ERROR, e, NULL);
322 gst_structure_free (s);
324 ASSERT_CRITICAL (gst_structure_free (gst_structure_new
325 ("0.10:decoder-video/mpeg", NULL)));
327 /* make sure we bail out correctly in case of an error or if parsing fails */
328 ASSERT_CRITICAL (s = gst_structure_new ("^joo\nba\ndoo^",
329 "abc", G_TYPE_BOOLEAN, FALSE, NULL));
330 fail_unless (s == NULL);
335 GST_START_TEST (test_fixate)
339 s = gst_structure_new ("name",
340 "int", G_TYPE_INT, 5,
341 "intrange", GST_TYPE_INT_RANGE, 5, 10,
342 "intrange2", GST_TYPE_INT_RANGE, 5, 10, NULL);
344 fail_if (gst_structure_fixate_field_nearest_int (s, "int", 5));
345 fail_unless (gst_structure_fixate_field_nearest_int (s, "intrange", 5));
346 fail_if (gst_structure_fixate_field_nearest_int (s, "intrange", 5));
347 fail_unless (gst_structure_fixate_field_nearest_int (s, "intrange2", 15));
348 fail_if (gst_structure_fixate_field_nearest_int (s, "intrange2", 15));
349 gst_structure_free (s);
354 GST_START_TEST (test_fixate_frac_list)
356 GstStructure *s, *s2;
362 g_value_init (&list, GST_TYPE_LIST);
363 g_value_init (&frac, GST_TYPE_FRACTION);
365 gst_value_set_fraction (&frac, 30, 1);
366 gst_value_list_append_value (&list, &frac);
367 gst_value_set_fraction (&frac, 15, 1);
368 gst_value_list_append_value (&list, &frac);
369 gst_value_set_fraction (&frac, 10, 1);
370 gst_value_list_append_value (&list, &frac);
372 s = gst_structure_new ("name", NULL);
373 gst_structure_set_value (s, "frac", &list);
374 g_value_unset (&frac);
375 g_value_unset (&list);
377 str = gst_structure_to_string (s);
378 GST_DEBUG ("list %s", str);
382 s2 = gst_structure_copy (s);
384 /* fixate to the nearest fraction, this should give 15/1 */
385 fail_unless (gst_structure_fixate_field_nearest_fraction (s, "frac", 14, 1));
387 fail_unless (gst_structure_get_fraction (s, "frac", &num, &denom));
388 fail_unless (num == 15);
389 fail_unless (denom == 1);
391 gst_structure_free (s);
394 /* fixate to the nearest fraction, this should give 30/1 */
395 fail_unless (gst_structure_fixate_field_nearest_fraction (s, "frac", G_MAXINT,
398 fail_unless (gst_structure_get_fraction (s, "frac", &num, &denom));
399 fail_unless (num == 30);
400 fail_unless (denom == 1);
401 gst_structure_free (s);
406 GST_START_TEST (test_structure_nested)
408 GstStructure *sp, *sc1, *sc2;
411 sc1 = gst_structure_new ("Camera",
412 "XResolution", G_TYPE_INT, 72, "YResolution", G_TYPE_INT, 73, NULL);
413 fail_unless (sc1 != NULL);
415 sc2 = gst_structure_new ("Image-Data",
416 "Orientation", G_TYPE_STRING, "top-left",
417 "Comment", G_TYPE_STRING, "super photo", NULL);
418 fail_unless (sc2 != NULL);
420 sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
421 "Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
422 fail_unless (sp != NULL);
424 fail_unless (gst_structure_n_fields (sp) == 2);
426 fail_unless (gst_structure_has_field_typed (sp, "Camera",
427 GST_TYPE_STRUCTURE));
429 str = gst_structure_to_string (sp);
430 fail_unless (str != NULL);
432 GST_DEBUG ("serialized to '%s'", str);
434 fail_unless (g_str_equal (str,
436 ", Camera=(structure)\"Camera\\,\\ XResolution\\=\\(int\\)72\\,\\ YResolution\\=\\(int\\)73\\;\""
437 ", Image Data=(structure)\"Image-Data\\,\\ Orientation\\=\\(string\\)top-left\\,\\ Comment\\=\\(string\\)\\\"super\\\\\\ photo\\\"\\;\";"));
442 gst_structure_free (sc1);
443 gst_structure_free (sc2);
444 gst_structure_free (sp);
449 GST_START_TEST (test_structure_nested_from_and_to_string)
453 gchar *str2, *end = NULL;
456 ", main-sub1=(structure)\"type-b\\,\\ machine-type\\=\\(int\\)0\\;\""
457 ", main-sub2=(structure)\"type-a\\,\\ plugin-filename\\=\\(string\\)\\\"/home/user/lib/lib\\\\\\ with\\\\\\ spaces.dll\\\"\\,\\ machine-type\\=\\(int\\)1\\;\""
458 ", main-sub3=(structure)\"type-b\\,\\ plugin-filename\\=\\(string\\)/home/user/lib/lib_no_spaces.so\\,\\ machine-type\\=\\(int\\)1\\;\""
461 s = gst_structure_from_string (str1, &end);
462 fail_unless (s != NULL);
464 GST_DEBUG ("not parsed part : %s", end);
465 fail_unless (*end == '\0');
467 fail_unless (gst_structure_n_fields (s) == 3);
469 fail_unless (gst_structure_has_field_typed (s, "main-sub1",
470 GST_TYPE_STRUCTURE));
472 str2 = gst_structure_to_string (s);
473 fail_unless (str2 != NULL);
475 fail_unless (g_str_equal (str1, str2));
479 gst_structure_free (s);
484 GST_START_TEST (test_vararg_getters)
487 GstBuffer *buf, *buf2;
489 GstCaps *caps, *caps2;
496 buf = gst_buffer_new_and_alloc (3);
498 data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
502 gst_buffer_unmap (buf, data, 3);
504 caps = gst_caps_new_simple ("video/x-foo", NULL);
506 s = gst_structure_new ("test", "int", G_TYPE_INT, 12345678, "string",
507 G_TYPE_STRING, "Hello World!", "buf", GST_TYPE_BUFFER, buf, "caps",
508 GST_TYPE_CAPS, caps, "int64", G_TYPE_INT64, G_GINT64_CONSTANT (-99),
509 "double", G_TYPE_DOUBLE, G_MAXDOUBLE, "frag", GST_TYPE_FRACTION, 39, 14,
512 /* first the plain one */
513 ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, &d, "string",
514 G_TYPE_STRING, &c, "caps", GST_TYPE_CAPS, &caps2, "buf",
515 GST_TYPE_BUFFER, &buf2, "frag", GST_TYPE_FRACTION, &num, &denom, "int",
516 G_TYPE_INT, &i, "int64", G_TYPE_INT64, &i64, NULL);
519 fail_unless_equals_string (c, "Hello World!");
520 fail_unless_equals_int (i, 12345678);
521 fail_unless_equals_float (d, G_MAXDOUBLE);
522 fail_unless_equals_int (num, 39);
523 fail_unless_equals_int (denom, 14);
524 fail_unless (i64 == -99);
525 fail_unless (caps == caps2);
526 fail_unless (buf == buf2);
528 /* expected failures */
529 ASSERT_CRITICAL (gst_structure_get (s, NULL, G_TYPE_INT, &i, NULL));
530 fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "double",
531 G_TYPE_FLOAT, &d, NULL));
532 fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "dooble",
533 G_TYPE_DOUBLE, &d, NULL));
537 gst_caps_unref (caps2);
539 gst_buffer_unref (buf2);
542 /* and now the _id variant */
543 ret = gst_structure_id_get (s, g_quark_from_static_string ("double"),
544 G_TYPE_DOUBLE, &d, g_quark_from_static_string ("string"), G_TYPE_STRING,
545 &c, g_quark_from_static_string ("caps"), GST_TYPE_CAPS, &caps2,
546 g_quark_from_static_string ("buf"), GST_TYPE_BUFFER, &buf2,
547 g_quark_from_static_string ("int"), G_TYPE_INT, &i,
548 g_quark_from_static_string ("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 (i64 == -99);
555 fail_unless (caps == caps2);
556 fail_unless (buf == buf2);
558 /* expected failures */
559 ASSERT_CRITICAL (gst_structure_get (s, 0, G_TYPE_INT, &i, NULL));
560 fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
561 G_TYPE_INT, &i, g_quark_from_static_string ("double"), G_TYPE_FLOAT,
563 fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
564 G_TYPE_INT, &i, g_quark_from_static_string ("dooble"), G_TYPE_DOUBLE,
568 gst_caps_unref (caps2);
569 gst_buffer_unref (buf2);
571 /* finally make sure NULL as return location is handled gracefully */
572 ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, NULL, "string",
573 G_TYPE_STRING, NULL, "caps", GST_TYPE_CAPS, NULL, "buf",
574 GST_TYPE_BUFFER, NULL, "int", G_TYPE_INT, &i, "frag", GST_TYPE_FRACTION,
575 NULL, NULL, "int64", G_TYPE_INT64, &i64, NULL);
577 ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, NULL,
579 ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, &num,
583 gst_caps_unref (caps);
584 gst_buffer_unref (buf);
585 gst_structure_free (s);
591 gst_structure_suite (void)
593 Suite *s = suite_create ("GstStructure");
594 TCase *tc_chain = tcase_create ("general");
596 suite_add_tcase (s, tc_chain);
597 tcase_add_test (tc_chain, test_from_string_int);
598 tcase_add_test (tc_chain, test_from_string_uint);
599 tcase_add_test (tc_chain, test_from_string);
600 tcase_add_test (tc_chain, test_to_string);
601 tcase_add_test (tc_chain, test_to_from_string);
602 tcase_add_test (tc_chain, test_string_properties);
603 tcase_add_test (tc_chain, test_complete_structure);
604 tcase_add_test (tc_chain, test_structure_new);
605 tcase_add_test (tc_chain, test_fixate);
606 tcase_add_test (tc_chain, test_fixate_frac_list);
607 tcase_add_test (tc_chain, test_structure_nested);
608 tcase_add_test (tc_chain, test_structure_nested_from_and_to_string);
609 tcase_add_test (tc_chain, test_vararg_getters);
613 GST_CHECK_MAIN (gst_structure);