meson: fix tests build with --werror
[platform/upstream/gstreamer.git] / tests / check / gst / gsturi.c
1 /* GStreamer unit tests for GstURI
2  *
3  * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include <gst/check/gstcheck.h>
22
23 GST_START_TEST (test_protocol_case)
24 {
25   GstElement *element;
26   GError *err = NULL;
27
28   element = gst_element_make_from_uri (GST_URI_SRC, "file:///foo/bar", NULL,
29       &err);
30
31   /* no element? probably no registry, bail out */
32   if (element == NULL && err->code == GST_URI_ERROR_UNSUPPORTED_PROTOCOL) {
33     g_error_free (err);
34     return;
35   }
36
37   gst_object_unref (element);
38   element = gst_element_make_from_uri (GST_URI_SRC, "FILE:///foo/bar", NULL,
39       NULL);
40   fail_unless (element != NULL,
41       "Got source for 'file://' URI but not for 'FILE://' URI");
42   gst_object_unref (element);
43 }
44
45 GST_END_TEST;
46
47 GST_START_TEST (test_uri_get_location)
48 {
49   gchar *l;
50
51   /* URI with no location should return empty string */
52   l = gst_uri_get_location ("dvd://");
53   fail_unless (l != NULL);
54   fail_unless_equals_string (l, "");
55   g_free (l);
56
57   /* URI with hostname */
58   l = gst_uri_get_location ("smb://supercomputer/path/to/file");
59   fail_unless (l != NULL);
60   fail_unless_equals_string (l, "supercomputer/path/to/file");
61   g_free (l);
62
63   /* URI */
64   l = gst_uri_get_location ("file:///path/to/file");
65   fail_unless (l != NULL);
66   fail_unless_equals_string (l, "/path/to/file");
67   g_free (l);
68
69   /* unescaping */
70   l = gst_uri_get_location ("file:///path/to/some%20file");
71   fail_unless (l != NULL);
72   fail_unless_equals_string (l, "/path/to/some file");
73   g_free (l);
74 }
75
76 GST_END_TEST;
77
78 #ifndef GST_REMOVE_DEPRECATED
79 GST_START_TEST (test_gst_uri_construct)
80 {
81   gchar *l;
82
83   /* URI with no protocol or empty protocol should return empty string */
84   ASSERT_CRITICAL (l = gst_uri_construct (NULL, "/path/to/file"));
85   fail_unless (l == NULL);
86   ASSERT_CRITICAL (l = gst_uri_construct ("", "/path/to/file"));
87   fail_unless (l == NULL);
88
89   /* URI with no location should return empty string */
90   ASSERT_CRITICAL (l = gst_uri_construct ("protocol", NULL));
91   fail_unless (l == NULL);
92
93   /* check the protocol for validity */
94   l = gst_uri_construct ("protocol1234567890+-.", "somefile");
95   fail_unless (l != NULL);
96   fail_unless_equals_string (l, "protocol1234567890+-.://somefile");
97   g_free (l);
98
99   /* check the location for correct handling */
100   l = gst_uri_construct ("aprotocol",
101       "/path+ to/some/file%d?akey=aval&key2=val2");
102   fail_unless (l != NULL);
103   fail_unless_equals_string (l,
104       "aprotocol:///path%2B%20to/some/file%25d?akey=aval&key2=val2");
105   g_free (l);
106 }
107
108 GST_END_TEST;
109 #endif
110
111 #ifdef G_OS_WIN32
112
113 GST_START_TEST (test_win32_uri)
114 {
115   gchar *uri, *l;
116
117   uri = g_strdup ("file:///c:/my%20music/foo.ogg");
118   l = gst_uri_get_location (uri);
119   fail_unless (l != NULL);
120   /* fail_unless_equals_string will screw up here in the failure case
121    * because the string constant will be appended to the printf format
122    * message string and contains a '%', that's why we use fail_unless here */
123   fail_unless (g_str_equal (l, "c:/my music/foo.ogg"),
124       "wrong location '%s' returned for URI '%s'", l, uri);
125   g_free (l);
126   g_free (uri);
127
128   /* make sure the other variant with two slashes before the C: (which was
129    * needed before because of a bug in _get_location()) still works */
130   uri = g_strdup ("file://c:/my%20music/foo.ogg");
131   l = gst_uri_get_location (uri);
132   fail_unless (l != NULL);
133   /* fail_unless_equals_string will screw up here in the failure case
134    * because the string constant will be appended to the printf format
135    * message string and contains a '%', that's why we use fail_unless here */
136   fail_unless (g_str_equal (l, "c:/my music/foo.ogg"),
137       "wrong location '%s' returned for URI '%s'", l, uri);
138   g_free (l);
139   g_free (uri);
140 }
141
142 GST_END_TEST;
143
144 #endif /* G_OS_WIN32 */
145
146 GST_START_TEST (test_uri_misc)
147 {
148   /* require at least two characters for the protocol */
149   fail_if (gst_uri_is_valid ("B:\\foo.txt"));
150   fail_if (gst_uri_is_valid ("B:/foo.txt"));
151   fail_if (gst_uri_is_valid ("B://foo.txt"));
152   fail_if (gst_uri_is_valid ("B:foo.txt"));
153
154   fail_unless (gst_uri_is_valid ("fd://0"));
155   fail_unless (gst_uri_is_valid ("AB:\\foo.txt"));
156   fail_unless (gst_uri_is_valid ("AB:/foo.txt"));
157   fail_unless (gst_uri_is_valid ("AB://foo.txt"));
158   fail_unless (gst_uri_is_valid ("AB:foo.txt"));
159
160   fail_unless (gst_uri_is_valid ("ABC:/foo.txt"));
161   fail_unless (gst_uri_is_valid ("ABC://foo.txt"));
162   fail_unless (gst_uri_is_valid ("ABC:foo.txt"));
163
164   fail_unless (gst_uri_is_valid ("ABCD:/foo.txt"));
165   fail_unless (gst_uri_is_valid ("ABCD://foo.txt"));
166   fail_unless (gst_uri_is_valid ("ABCD:foo.txt"));
167 }
168
169 GST_END_TEST;
170
171 GST_START_TEST (test_element_make_from_uri)
172 {
173   GstElement *element;
174   GError *err = NULL;
175
176   element = gst_element_make_from_uri (GST_URI_SRC, "foo://", NULL, NULL);
177   fail_unless (element == NULL);
178
179   element = gst_element_make_from_uri (GST_URI_SRC, "foo://", NULL, &err);
180   fail_unless (element == NULL);
181   fail_unless (err != NULL);
182   fail_unless (err->code == GST_URI_ERROR_UNSUPPORTED_PROTOCOL);
183   g_error_free (err);
184   err = NULL;
185
186   if (gst_registry_check_feature_version (gst_registry_get (), "filesrc",
187           GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO)) {
188     element = gst_element_make_from_uri (GST_URI_SRC, "file://host/foo", NULL,
189         &err);
190     fail_unless (element == NULL);
191     fail_unless (err != NULL);
192     fail_unless (err->code == GST_URI_ERROR_BAD_URI);
193     g_error_free (err);
194     err = NULL;
195   }
196 }
197
198 GST_END_TEST;
199
200 /* Taken from the GNet unit test and extended with other URIs:
201  * https://git.gnome.org/browse/archive/gnet/plain/tests/check/gnet/gneturi.c
202  */
203 struct QueryValue
204 {
205   const gchar *key;
206   const gchar *value;
207 };
208
209 struct URITest
210 {
211   const gchar *str;
212   struct
213   {
214     const gchar *scheme;
215     const gchar *userinfo;
216     const gchar *host;
217     gint port;
218     const gchar *path;
219     /* needs to be updated if more than 10 */
220     struct QueryValue query[10];
221     const gchar *fragment;
222   } uri;
223 };
224
225 static const struct URITest tests[] = {
226   /* VALID URIS.  PARSING AND PRINTING OF THESE SHOULD NOT CHANGE */
227
228   /* scheme/path */
229   {"scheme:",
230       {"scheme", NULL, NULL, GST_URI_NO_PORT, NULL, {{NULL, NULL}}, NULL}},
231
232   {"scheme:path",
233       {"scheme", NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}},
234
235   {"path",
236       {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}},
237
238   {"/path",
239       {NULL, NULL, NULL, GST_URI_NO_PORT, "/path", {{NULL, NULL}}, NULL}},
240
241   /* hostname/port */
242   {"scheme://hostname/path",
243         {"scheme", NULL, "hostname", GST_URI_NO_PORT, "/path", {{NULL, NULL}},
244           NULL}},
245
246   {"scheme://hostname:123/path",
247       {"scheme", NULL, "hostname", 123, "/path", {{NULL, NULL}}, NULL}},
248
249   /* ipv6 hostname/port */
250   {"scheme://[01:23:45:67:89:ab:cd:ef]/path",
251         {"scheme", NULL, "01:23:45:67:89:ab:cd:ef", GST_URI_NO_PORT, "/path",
252           {{NULL, NULL}}, NULL}},
253
254   {"scheme://[01:23:45:67:89:ab:cd:ef]:123/path",
255         {"scheme", NULL, "01:23:45:67:89:ab:cd:ef", 123, "/path", {{NULL,
256                   NULL}}, NULL}},
257
258   /* query/fragment */
259   {"path?query",
260         {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL,
261                   NULL}}, NULL}},
262   {"path?query=value",
263         {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", "value"}, {NULL,
264                   NULL}}, NULL}},
265
266   {"path?query#fragment",
267         {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL,
268                   NULL}}, "fragment"}},
269
270   {"path?query=value#fragment",
271         {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{"query", "value"}, {NULL,
272                   NULL}}, "fragment"}},
273
274   {"scheme:path?query#fragment",
275         {"scheme", NULL, NULL, GST_URI_NO_PORT, "path", {{"query", NULL}, {NULL,
276                   NULL}}, "fragment"}},
277
278   /* full */
279   {"scheme://hostname:123/path?query#fragment",
280         {"scheme", NULL, "hostname", 123, "/path", {{"query", NULL}, {NULL,
281                   NULL}}, "fragment"}},
282
283   {"scheme://hostname:123/path?query=value#fragment",
284         {"scheme", NULL, "hostname", 123, "/path", {{"query", "value"}, {NULL,
285                   NULL}}, "fragment"}},
286
287   {"scheme://hostname:123?query",
288         {"scheme", NULL, "hostname", 123, NULL, {{"query", NULL}, {NULL,
289                   NULL}}, NULL}},
290
291   {"scheme://hostname:123?query=value",
292         {"scheme", NULL, "hostname", 123, NULL, {{"query", "value"}, {NULL,
293                   NULL}}, NULL}},
294
295   {"scheme://hostname:123?query#fragment",
296         {"scheme", NULL, "hostname", 123, NULL, {{"query", NULL}, {NULL,
297                   NULL}}, "fragment"}},
298
299   {"scheme://hostname:123?query=value#fragment",
300         {"scheme", NULL, "hostname", 123, NULL, {{"query", "value"}, {NULL,
301                   NULL}}, "fragment"}},
302
303   /* user/pass */
304   {"scheme://userinfo@hostname",
305         {"scheme", "userinfo", "hostname", GST_URI_NO_PORT, NULL, {{NULL,
306                   NULL}}, NULL}},
307
308   {"scheme://userinfo@hostname:123/path?query#fragment",
309         {"scheme", "userinfo", "hostname", 123, "/path", {{"query", NULL},
310               {NULL, NULL}}, "fragment"}},
311
312   {"scheme://user:pass@hostname",
313         {"scheme", "user:pass", "hostname", GST_URI_NO_PORT, NULL, {{NULL,
314                   NULL}}, NULL}},
315
316   {"scheme://user:pass@hostname:123/path?query#fragment",
317         {"scheme", "user:pass", "hostname", 123, "/path", {{"query", NULL},
318               {NULL, NULL}}, "fragment"}},
319
320   /* FUNNY URIS.  PARSING AND PRINTING OF THESE MAY CHANGE */
321
322   {"scheme:hostname:123/path?query#fragment",
323         {"scheme", NULL, NULL, GST_URI_NO_PORT, "hostname:123/path", {{"query",
324                   NULL}, {NULL, NULL}}, "fragment"}},
325
326   {"scheme://:pass@hostname:123/path?query#fragment",
327         {"scheme", ":pass", "hostname", 123, "/path", {{"query", NULL}, {NULL,
328                   NULL}}, "fragment"}},
329
330   /* Skip initial white space */
331   {" \f\n\r\t\vscheme:",
332       {"scheme", NULL, NULL, GST_URI_NO_PORT, NULL, {{NULL, NULL}}, NULL}},
333
334   {" \f\n\r\t\vpath",
335       {NULL, NULL, NULL, GST_URI_NO_PORT, "path", {{NULL, NULL}}, NULL}},
336
337   /* file URI */
338   {"file://host/home/joe/foo.txt",
339         {"file", NULL, "host", GST_URI_NO_PORT, "/home/joe/foo.txt", {{NULL,
340                   NULL}}, NULL}},
341   {"file:///home/joe/foo.txt",
342         {"file", NULL, NULL, GST_URI_NO_PORT, "/home/joe/foo.txt", {{NULL,
343                   NULL}}, NULL}},
344 };
345
346 static const gchar *unparsable_uri_tests[] = {
347   /* Path not started correctly */
348   "scheme://hostname:123path?query#fragment",
349
350   /* Brackets that don't close */
351   "scheme://[01:23:45:67:89:ab:cd:ef:123/path",
352
353   /* IPv6 hostname without brackets */
354   "scheme://01:23:45:67:89:ab:cd:ef:123/path",
355 };
356
357 GST_START_TEST (test_url_parsing)
358 {
359   GstUri *uri;
360   GList *list;
361   gchar *tmp_str;
362   guint i, j;
363
364   for (i = 0; i < G_N_ELEMENTS (tests); i++) {
365     GST_DEBUG ("Testing URI '%s'", tests[i].str);
366
367     uri = gst_uri_from_string (tests[i].str);
368     fail_unless (uri != NULL);
369     fail_unless_equals_string (gst_uri_get_scheme (uri), tests[i].uri.scheme);
370     fail_unless_equals_string (gst_uri_get_userinfo (uri),
371         tests[i].uri.userinfo);
372     fail_unless_equals_string (gst_uri_get_host (uri), tests[i].uri.host);
373     fail_unless_equals_int (gst_uri_get_port (uri), tests[i].uri.port);
374     tmp_str = gst_uri_get_path (uri);
375     fail_unless_equals_string (tmp_str, tests[i].uri.path);
376     g_free (tmp_str);
377
378     for (j = 0; j < 10; j++) {
379       if (!tests[i].uri.query[j].key)
380         break;
381
382       if (tests[i].uri.query[j].value) {
383         fail_unless_equals_string (gst_uri_get_query_value (uri,
384                 tests[i].uri.query[j].key), tests[i].uri.query[j].value);
385       } else {
386         fail_unless (gst_uri_query_has_key (uri, tests[i].uri.query[j].key));
387       }
388     }
389     list = gst_uri_get_query_keys (uri);
390     fail_unless_equals_int (j, g_list_length (list));
391     g_list_free (list);
392     gst_uri_unref (uri);
393   }
394
395   for (i = 0; i < G_N_ELEMENTS (unparsable_uri_tests); i++) {
396     GST_DEBUG ("Testing unparsable URI '%s'", unparsable_uri_tests[i]);
397
398     uri = gst_uri_from_string (unparsable_uri_tests[i]);
399     fail_unless (uri == NULL);
400   }
401 }
402
403 GST_END_TEST;
404
405 static const struct URITest url_presenting_tests[] = {
406   /* check all URI elements present */
407   {.uri = {"scheme", "user:pass", "host", 1234, "/path/to/dir",
408           {{"query", NULL}, {"key", "value"}}, "fragment"},
409       .str =
410       "scheme://user:pass@host:1234/path/to/dir?query&key=value#fragment"},
411
412   /* IPv6 literal should render in square brackets */
413   {.uri = {"scheme", "user:pass", "12:34:56:78:9a:bc:de:f0", 1234,
414           "/path/to/dir", {{"query", "value"}}, "fragment"},
415       .str =
416       "scheme://user:pass@[12:34:56:78:9a:bc:de:f0]:1234/path/to/dir?query=value#fragment"},
417 };
418
419 GST_START_TEST (test_url_presenting)
420 {
421   GstUri *uri;
422   gchar *result;
423   guint i, j;
424
425   for (i = 0; i < G_N_ELEMENTS (url_presenting_tests); i++) {
426     uri = gst_uri_new (url_presenting_tests[i].uri.scheme,
427         url_presenting_tests[i].uri.userinfo,
428         url_presenting_tests[i].uri.host,
429         url_presenting_tests[i].uri.port,
430         url_presenting_tests[i].uri.path,
431         NULL, url_presenting_tests[i].uri.fragment);
432     fail_unless (uri != NULL);
433     for (j = 0; j < 10; j++) {
434       if (!url_presenting_tests[i].uri.query[j].key)
435         break;
436
437       fail_unless (gst_uri_set_query_value (uri,
438               url_presenting_tests[i].uri.query[j].key,
439               url_presenting_tests[i].uri.query[j].value));
440     }
441
442     result = gst_uri_to_string (uri);
443     fail_unless_equals_string (result, url_presenting_tests[i].str);
444     g_free (result);
445     gst_uri_unref (uri);
446   }
447 }
448
449 GST_END_TEST;
450
451 GST_START_TEST (test_url_normalization)
452 {
453   GstUri *url;
454   gchar *tmp_str;
455
456   url =
457       gst_uri_from_string
458       ("ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment");
459   fail_unless (gst_uri_normalize (url));
460   fail_unless_equals_string (gst_uri_get_scheme (url), "scheme");
461   fail_unless_equals_string (gst_uri_get_userinfo (url), "User:Pass");
462   fail_unless_equals_string (gst_uri_get_host (url), "host.com");
463   tmp_str = gst_uri_get_path (url);
464   fail_unless_equals_string (tmp_str, "/path/to}/item-obj");
465   g_free (tmp_str);
466   fail_unless (gst_uri_query_has_key (url, "query"));
467   fail_unless_equals_string (gst_uri_get_query_value (url, "query"),
468       "something");
469   fail_unless_equals_string (gst_uri_get_fragment (url), "fragment");
470   gst_uri_unref (url);
471 }
472
473 GST_END_TEST;
474
475 GST_START_TEST (test_url_joining)
476 {
477   GstUri *base, *rel, *joined;
478   gchar *l;
479
480   base =
481       gst_uri_from_string
482       ("http://example.com/path/to/dir/filename.html#fragment");
483
484   /* test change of fragment only */
485   rel = gst_uri_from_string ("#new_frag");
486   joined = gst_uri_join (base, rel);
487   l = gst_uri_to_string (joined);
488   fail_unless_equals_string (l,
489       "http://example.com/path/to/dir/filename.html#new_frag");
490   g_free (l);
491   gst_uri_unref (joined);
492   gst_uri_unref (rel);
493
494   /* test addition of new query string */
495   rel = gst_uri_from_string ("?key=val");
496   joined = gst_uri_join (base, rel);
497   l = gst_uri_to_string (joined);
498   fail_unless_equals_string (l,
499       "http://example.com/path/to/dir/filename.html?key=val");
500   g_free (l);
501   gst_uri_unref (joined);
502   gst_uri_unref (rel);
503
504   /* test new base filename */
505   rel = gst_uri_from_string ("new_filename.xml");
506   joined = gst_uri_join (base, rel);
507   l = gst_uri_to_string (joined);
508   fail_unless_equals_string (l,
509       "http://example.com/path/to/dir/new_filename.xml");
510   g_free (l);
511   gst_uri_unref (joined);
512   gst_uri_unref (rel);
513
514   /* test relative file same directory */
515   rel = gst_uri_from_string ("./new_filename.xml");
516   joined = gst_uri_join (base, rel);
517   l = gst_uri_to_string (joined);
518   fail_unless_equals_string (l,
519       "http://example.com/path/to/dir/new_filename.xml");
520   g_free (l);
521   gst_uri_unref (joined);
522   gst_uri_unref (rel);
523
524   /* test relative file parent directory */
525   rel = gst_uri_from_string ("../new_filename.xml");
526   joined = gst_uri_join (base, rel);
527   l = gst_uri_to_string (joined);
528   fail_unless_equals_string (l, "http://example.com/path/to/new_filename.xml");
529   g_free (l);
530   gst_uri_unref (joined);
531   gst_uri_unref (rel);
532
533   /* test relative file grandparent directory */
534   rel = gst_uri_from_string ("../../new_filename.xml");
535   joined = gst_uri_join (base, rel);
536   l = gst_uri_to_string (joined);
537   fail_unless_equals_string (l, "http://example.com/path/new_filename.xml");
538   g_free (l);
539   gst_uri_unref (joined);
540   gst_uri_unref (rel);
541
542   /* test relative file root directory */
543   rel = gst_uri_from_string ("../../../new_filename.xml");
544   joined = gst_uri_join (base, rel);
545   l = gst_uri_to_string (joined);
546   fail_unless_equals_string (l, "http://example.com/new_filename.xml");
547   g_free (l);
548   gst_uri_unref (joined);
549   gst_uri_unref (rel);
550
551   /* test relative file beyond root directory */
552   rel = gst_uri_from_string ("../../../../new_filename.xml");
553   joined = gst_uri_join (base, rel);
554   l = gst_uri_to_string (joined);
555   fail_unless_equals_string (l, "http://example.com/new_filename.xml");
556   g_free (l);
557   gst_uri_unref (joined);
558   gst_uri_unref (rel);
559
560   /* test add subdirectory */
561   rel = gst_uri_from_string ("subdir/new_filename.xml");
562   joined = gst_uri_join (base, rel);
563   l = gst_uri_to_string (joined);
564   fail_unless_equals_string (l,
565       "http://example.com/path/to/dir/subdir/new_filename.xml");
566   g_free (l);
567   gst_uri_unref (joined);
568   gst_uri_unref (rel);
569
570   /* test change directory */
571   rel = gst_uri_from_string ("../subdir/new_filename.xml");
572   joined = gst_uri_join (base, rel);
573   l = gst_uri_to_string (joined);
574   fail_unless_equals_string (l,
575       "http://example.com/path/to/subdir/new_filename.xml");
576   g_free (l);
577   gst_uri_unref (joined);
578   gst_uri_unref (rel);
579
580   gst_uri_unref (base);
581
582   /* change base for path ending in directory */
583   base = gst_uri_from_string ("http://example.com/path/to/dir/");
584
585   /* test adding file to directory */
586   rel = gst_uri_from_string ("new_filename.xml");
587   joined = gst_uri_join (base, rel);
588   l = gst_uri_to_string (joined);
589   fail_unless_equals_string (l,
590       "http://example.com/path/to/dir/new_filename.xml");
591   g_free (l);
592   gst_uri_unref (joined);
593   gst_uri_unref (rel);
594
595   /* test adding file to directory using relative path */
596   rel = gst_uri_from_string ("./new_filename.xml");
597   joined = gst_uri_join (base, rel);
598   l = gst_uri_to_string (joined);
599   fail_unless_equals_string (l,
600       "http://example.com/path/to/dir/new_filename.xml");
601   g_free (l);
602   gst_uri_unref (joined);
603   gst_uri_unref (rel);
604
605   /* test filename in parent directory */
606   rel = gst_uri_from_string ("../new_filename.xml");
607   joined = gst_uri_join (base, rel);
608   l = gst_uri_to_string (joined);
609   fail_unless_equals_string (l, "http://example.com/path/to/new_filename.xml");
610   g_free (l);
611   gst_uri_unref (joined);
612   gst_uri_unref (rel);
613
614   /* test path ending in '../' */
615   rel = gst_uri_from_string ("one/two/../");
616   joined = gst_uri_join (base, rel);
617   l = gst_uri_to_string (joined);
618   fail_unless_equals_string (l, "http://example.com/path/to/dir/one/");
619   g_free (l);
620   gst_uri_unref (joined);
621   gst_uri_unref (rel);
622
623   /* test path ending in '..' Result should be the same as when ending in '../' */
624   rel = gst_uri_from_string ("one/two/..");
625   joined = gst_uri_join (base, rel);
626   l = gst_uri_to_string (joined);
627   fail_unless_equals_string (l, "http://example.com/path/to/dir/one/");
628   g_free (l);
629   gst_uri_unref (joined);
630   gst_uri_unref (rel);
631
632   /* test replace with absolute */
633   rel = gst_uri_from_string ("https://ssl.example.com/new_filename.xml");
634   joined = gst_uri_join (base, rel);
635   l = gst_uri_to_string (joined);
636   fail_unless_equals_string (l, "https://ssl.example.com/new_filename.xml");
637   g_free (l);
638   gst_uri_unref (joined);
639   gst_uri_unref (rel);
640
641   gst_uri_unref (base);
642 }
643
644 GST_END_TEST;
645
646 GST_START_TEST (test_url_equality)
647 {
648   GstUri *url1, *url2;
649
650   url1 =
651       gst_uri_from_string
652       ("ScHeMe://User:Pass@HOST.com:1234/path/./from/../to%7d/item%2dobj?query=something#fragment");
653
654   /* equal */
655   url2 =
656       gst_uri_from_string
657       ("scheme://User:Pass@host.com:1234/path/to%7D/item-obj?query=something#fragment");
658   fail_unless (gst_uri_equal (url1, url2));
659   fail_unless (gst_uri_equal (url2, url1));
660   gst_uri_unref (url2);
661
662   /* different fragment */
663   url2 =
664       gst_uri_from_string
665       ("scheme://User:Pass@host.com:1234/path/to%7D/item-obj?query=something#different-fragment");
666   fail_unless (!gst_uri_equal (url1, url2));
667   gst_uri_unref (url2);
668
669   /* different query */
670   url2 =
671       gst_uri_from_string
672       ("scheme://User:Pass@host.com:1234/path/to%7D/item-obj?query=different-something#fragment");
673   fail_unless (!gst_uri_equal (url1, url2));
674   gst_uri_unref (url2);
675
676   /* different path */
677   url2 =
678       gst_uri_from_string
679       ("scheme://User:Pass@host.com:1234/path/to%7D/different-item-obj?query=something#fragment");
680   fail_unless (!gst_uri_equal (url1, url2));
681   gst_uri_unref (url2);
682
683   /* different port */
684   url2 =
685       gst_uri_from_string
686       ("scheme://User:Pass@host.com:4321/path/to%7D/item-obj?query=something#fragment");
687   fail_unless (!gst_uri_equal (url1, url2));
688   gst_uri_unref (url2);
689
690   /* different host */
691   url2 =
692       gst_uri_from_string
693       ("scheme://User:Pass@different-host.com:1234/path/to%7D/item-obj?query=something#fragment");
694   fail_unless (!gst_uri_equal (url1, url2));
695   gst_uri_unref (url2);
696
697   /* different userinfo */
698   url2 =
699       gst_uri_from_string
700       ("scheme://Different-User:Pass@host.com:1234/path/to%7D/item-obj?query=something#fragment");
701   fail_unless (!gst_uri_equal (url1, url2));
702   gst_uri_unref (url2);
703
704   /* different scheme */
705   url2 =
706       gst_uri_from_string
707       ("different+scheme://User:Pass@host.com:1234/path/to%7D/item-obj?query=something#fragment");
708   fail_unless (!gst_uri_equal (url1, url2));
709   gst_uri_unref (url2);
710
711   /* different (no scheme) */
712   url2 =
713       gst_uri_from_string
714       ("//User:Pass@host.com:1234/path/to%7D/item-obj?query=something#fragment");
715   fail_unless (!gst_uri_equal (url1, url2));
716   gst_uri_unref (url2);
717
718   /* different (no userinfo) */
719   url2 =
720       gst_uri_from_string
721       ("scheme://host.com:1234/path/to%7D/item-obj?query=something#fragment");
722   fail_unless (!gst_uri_equal (url1, url2));
723   gst_uri_unref (url2);
724
725   /* different (no host) */
726   url2 =
727       gst_uri_from_string
728       ("scheme://User:Pass@:1234/path/to%7D/item-obj?query=something#fragment");
729   fail_unless (!gst_uri_equal (url1, url2));
730   gst_uri_unref (url2);
731
732   /* different (no port) */
733   url2 =
734       gst_uri_from_string
735       ("scheme://User:Pass@host.com/path/to%7D/item-obj?query=something#fragment");
736   fail_unless (!gst_uri_equal (url1, url2));
737   gst_uri_unref (url2);
738
739   /* different (no path) */
740   url2 =
741       gst_uri_from_string
742       ("scheme://User:Pass@host.com:1234?query=something#fragment");
743   fail_unless (!gst_uri_equal (url1, url2));
744   gst_uri_unref (url2);
745
746   /* different (no query) */
747   url2 =
748       gst_uri_from_string
749       ("scheme://User:Pass@host.com:1234/path/to%7D/item-obj#fragment");
750   fail_unless (!gst_uri_equal (url1, url2));
751   gst_uri_unref (url2);
752
753   /* different (no fragment) */
754   url2 =
755       gst_uri_from_string
756       ("scheme://User:Pass@host.com:1234/path/to%7D/item-obj?query=something");
757   fail_unless (!gst_uri_equal (url1, url2));
758   gst_uri_unref (url2);
759
760   /* compare two NULL uris */
761   fail_unless (gst_uri_equal (NULL, NULL));
762
763   /* compare same object */
764   fail_unless (gst_uri_equal (url1, url1));
765
766   /* compare one NULL and one non-NULL uri */
767   fail_unless (!gst_uri_equal (url1, NULL));
768   fail_unless (!gst_uri_equal (NULL, url1));
769
770   gst_uri_unref (url1);
771 }
772
773 GST_END_TEST;
774
775 GST_START_TEST (test_url_constructors)
776 {
777   GstUri *url1, *url2;
778   gchar *tmp_str;
779   GHashTable *tmp_table;
780
781   url1 =
782       gst_uri_new ("scheme", "userinfo", "hostname", 1234, "/path/to/file",
783       "query", "fragment");
784   fail_unless_equals_string (gst_uri_get_scheme (url1), "scheme");
785   fail_unless_equals_string (gst_uri_get_userinfo (url1), "userinfo");
786   fail_unless_equals_string (gst_uri_get_host (url1), "hostname");
787   fail_unless (gst_uri_get_port (url1) == 1234);
788   tmp_str = gst_uri_get_path (url1);
789   fail_unless_equals_string (tmp_str, "/path/to/file");
790   g_free (tmp_str);
791   tmp_table = gst_uri_get_query_table (url1);
792   fail_unless (g_hash_table_size (tmp_table) == 1);
793   fail_unless (g_hash_table_contains (tmp_table, "query"));
794   fail_unless (g_hash_table_lookup (tmp_table, "query") == NULL);
795   g_hash_table_unref (tmp_table);
796   fail_unless_equals_string (gst_uri_get_fragment (url1), "fragment");
797   tmp_str = gst_uri_to_string (url1);
798   fail_unless_equals_string (tmp_str,
799       "scheme://userinfo@hostname:1234/path/to/file?query#fragment");
800   g_free (tmp_str);
801
802   url2 =
803       gst_uri_new_with_base (url1, NULL, NULL, NULL, GST_URI_NO_PORT,
804       "new_file", NULL, NULL);
805   fail_unless_equals_string (gst_uri_get_scheme (url2), "scheme");
806   fail_unless_equals_string (gst_uri_get_userinfo (url2), "userinfo");
807   fail_unless_equals_string (gst_uri_get_host (url2), "hostname");
808   fail_unless (gst_uri_get_port (url2) == 1234);
809   tmp_str = gst_uri_get_path (url2);
810   fail_unless_equals_string (tmp_str, "/path/to/new_file");
811   g_free (tmp_str);
812   fail_unless (gst_uri_get_query_table (url2) == NULL);
813   fail_unless (gst_uri_get_fragment (url2) == NULL);
814   tmp_str = gst_uri_to_string (url2);
815   fail_unless_equals_string (tmp_str,
816       "scheme://userinfo@hostname:1234/path/to/new_file");
817   g_free (tmp_str);
818   gst_uri_unref (url2);
819
820   url2 = gst_uri_from_string_with_base (url1, "/a/new/path/to/file");
821   fail_unless_equals_string (gst_uri_get_scheme (url2), "scheme");
822   fail_unless_equals_string (gst_uri_get_userinfo (url2), "userinfo");
823   fail_unless_equals_string (gst_uri_get_host (url2), "hostname");
824   fail_unless (gst_uri_get_port (url2) == 1234);
825   tmp_str = gst_uri_get_path (url2);
826   fail_unless_equals_string (tmp_str, "/a/new/path/to/file");
827   g_free (tmp_str);
828   fail_unless (gst_uri_get_query_table (url2) == NULL);
829   fail_unless (gst_uri_get_fragment (url2) == NULL);
830   tmp_str = gst_uri_to_string (url2);
831   fail_unless_equals_string (tmp_str,
832       "scheme://userinfo@hostname:1234/a/new/path/to/file");
833   g_free (tmp_str);
834   gst_uri_unref (url2);
835
836   url2 = gst_uri_from_string_with_base (url1, "http://foobar.com/bla");
837   fail_unless_equals_string (gst_uri_get_scheme (url2), "http");
838   fail_unless_equals_string (gst_uri_get_host (url2), "foobar.com");
839   fail_unless (gst_uri_get_port (url2) == 0);
840   tmp_str = gst_uri_get_path (url2);
841   fail_unless_equals_string (tmp_str, "/bla");
842   g_free (tmp_str);
843   fail_unless (gst_uri_get_query_table (url2) == NULL);
844   fail_unless (gst_uri_get_fragment (url2) == NULL);
845   tmp_str = gst_uri_to_string (url2);
846   fail_unless_equals_string (tmp_str, "http://foobar.com/bla");
847   g_free (tmp_str);
848   gst_uri_unref (url2);
849
850   url2 = gst_uri_copy (url1);
851   fail_unless (gst_uri_equal (url1, url2));
852   gst_uri_set_query_value (url2, "key", "value");
853   fail_unless (!gst_uri_equal (url1, url2));
854   gst_uri_unref (url2);
855
856   gst_uri_unref (url1);
857 }
858
859 GST_END_TEST;
860
861 GST_START_TEST (test_url_get_set)
862 {
863   GstUri *url;
864   gchar *tmp_str;
865   GList *tmp_list;
866
867   url = gst_uri_from_string ("scheme://hostname/path/to/file?query#fragment");
868
869   fail_unless (gst_uri_set_scheme (url, "new+scheme"));
870   fail_unless_equals_string (gst_uri_get_scheme (url), "new+scheme");
871   tmp_str = gst_uri_to_string (url);
872   fail_unless_equals_string (tmp_str,
873       "new+scheme://hostname/path/to/file?query#fragment");
874   g_free (tmp_str);
875
876   fail_unless (gst_uri_set_scheme (url, NULL));
877   fail_unless (gst_uri_get_scheme (url) == NULL);
878   tmp_str = gst_uri_to_string (url);
879   fail_unless_equals_string (tmp_str, "//hostname/path/to/file?query#fragment");
880   g_free (tmp_str);
881
882   fail_unless (!gst_uri_set_scheme (NULL, "fail"));
883   fail_unless (gst_uri_set_scheme (NULL, NULL));
884
885   fail_unless (gst_uri_set_userinfo (url, "username:password"));
886   fail_unless_equals_string (gst_uri_get_userinfo (url), "username:password");
887   tmp_str = gst_uri_to_string (url);
888   fail_unless_equals_string (tmp_str,
889       "//username:password@hostname/path/to/file?query#fragment");
890   g_free (tmp_str);
891
892   fail_unless (gst_uri_set_userinfo (url, NULL));
893   fail_unless (gst_uri_get_userinfo (url) == NULL);
894   tmp_str = gst_uri_to_string (url);
895   fail_unless_equals_string (tmp_str, "//hostname/path/to/file?query#fragment");
896   g_free (tmp_str);
897
898   fail_unless (!gst_uri_set_userinfo (NULL, "fail"));
899   fail_unless (gst_uri_set_userinfo (NULL, NULL));
900
901   fail_unless (gst_uri_set_host (url, NULL));
902   fail_unless (gst_uri_get_host (url) == NULL);
903   tmp_str = gst_uri_to_string (url);
904   fail_unless_equals_string (tmp_str, "/path/to/file?query#fragment");
905   g_free (tmp_str);
906
907   fail_unless (gst_uri_set_host (url, "example.com"));
908   fail_unless_equals_string (gst_uri_get_host (url), "example.com");
909   tmp_str = gst_uri_to_string (url);
910   fail_unless_equals_string (tmp_str,
911       "//example.com/path/to/file?query#fragment");
912   g_free (tmp_str);
913
914   fail_unless (!gst_uri_set_host (NULL, "fail"));
915   fail_unless (gst_uri_set_host (NULL, NULL));
916
917   fail_unless (gst_uri_set_port (url, 12345));
918   fail_unless (gst_uri_get_port (url) == 12345);
919   tmp_str = gst_uri_to_string (url);
920   fail_unless_equals_string (tmp_str,
921       "//example.com:12345/path/to/file?query#fragment");
922   g_free (tmp_str);
923
924   fail_unless (gst_uri_set_port (url, GST_URI_NO_PORT));
925   fail_unless (gst_uri_get_port (url) == GST_URI_NO_PORT);
926   tmp_str = gst_uri_to_string (url);
927   fail_unless_equals_string (tmp_str,
928       "//example.com/path/to/file?query#fragment");
929   g_free (tmp_str);
930
931   fail_unless (!gst_uri_set_port (NULL, 1234));
932   fail_unless (gst_uri_set_port (NULL, GST_URI_NO_PORT));
933
934   fail_unless (gst_uri_append_path_segment (url, "here"));
935   tmp_str = gst_uri_to_string (url);
936   fail_unless_equals_string (tmp_str,
937       "//example.com/path/to/file/here?query#fragment");
938   g_free (tmp_str);
939
940   fail_unless (!gst_uri_append_path_segment (NULL, "fail"));
941   fail_unless (gst_uri_append_path_segment (NULL, NULL));
942
943   fail_unless (gst_uri_append_path (url, "../there"));
944   tmp_str = gst_uri_to_string (url);
945   fail_unless_equals_string (tmp_str,
946       "//example.com/path/to/file/here/../there?query#fragment");
947   g_free (tmp_str);
948
949   fail_unless (!gst_uri_append_path (NULL, "fail"));
950   fail_unless (gst_uri_append_path (NULL, NULL));
951
952   gst_uri_normalize (url);
953
954   tmp_list = gst_uri_get_path_segments (url);
955   fail_unless (tmp_list != NULL);
956   tmp_list = g_list_append (tmp_list, g_strdup ("segment"));
957   tmp_str = gst_uri_to_string (url);
958   fail_unless_equals_string (tmp_str,
959       "//example.com/path/to/file/there?query#fragment");
960   g_free (tmp_str);
961   fail_unless (gst_uri_set_path_segments (url, tmp_list));
962   tmp_str = gst_uri_to_string (url);
963   fail_unless_equals_string (tmp_str,
964       "//example.com/path/to/file/there/segment?query#fragment");
965   g_free (tmp_str);
966
967   tmp_list = g_list_append (NULL, g_strdup ("test"));
968   fail_unless (!gst_uri_set_path_segments (NULL, tmp_list));
969   fail_unless (gst_uri_set_path_segments (NULL, NULL));
970
971   fail_unless (gst_uri_set_query_value (url, "key", "value"));
972   tmp_str = gst_uri_to_string (url);
973   fail_unless_equals_string (tmp_str,
974       "//example.com/path/to/file/there/segment?query&key=value#fragment");
975   g_free (tmp_str);
976
977   fail_unless (gst_uri_set_query_value (url, "key", NULL));
978   tmp_str = gst_uri_to_string (url);
979   fail_unless_equals_string (tmp_str,
980       "//example.com/path/to/file/there/segment?query&key#fragment");
981   g_free (tmp_str);
982
983   fail_unless (!gst_uri_set_query_value (NULL, "key", "value"));
984
985   fail_unless (gst_uri_remove_query_key (url, "key"));
986   tmp_str = gst_uri_to_string (url);
987   fail_unless_equals_string (tmp_str,
988       "//example.com/path/to/file/there/segment?query#fragment");
989   g_free (tmp_str);
990
991   fail_unless (!gst_uri_remove_query_key (url, "key"));
992   fail_unless (!gst_uri_remove_query_key (NULL, "key"));
993
994   fail_unless (gst_uri_set_fragment (url, NULL));
995   fail_unless (gst_uri_get_fragment (url) == NULL);
996   tmp_str = gst_uri_to_string (url);
997   fail_unless_equals_string (tmp_str,
998       "//example.com/path/to/file/there/segment?query");
999   g_free (tmp_str);
1000
1001   fail_unless (gst_uri_set_fragment (url, "tag"));
1002   fail_unless_equals_string (gst_uri_get_fragment (url), "tag");
1003   tmp_str = gst_uri_to_string (url);
1004   fail_unless_equals_string (tmp_str,
1005       "//example.com/path/to/file/there/segment?query#tag");
1006   g_free (tmp_str);
1007
1008   fail_unless (!gst_uri_set_fragment (NULL, "can't set if no URI"));
1009   fail_unless (gst_uri_set_fragment (NULL, NULL));
1010
1011   gst_uri_unref (url);
1012 }
1013
1014 GST_END_TEST;
1015
1016 GST_START_TEST (test_url_get_media_fragment_table)
1017 {
1018   GstUri *url;
1019   gchar *val;
1020   GHashTable *table;
1021
1022   /* Examples at https://www.w3.org/TR/media-frags/#processing-media-fragment-uri */
1023
1024   /* TEST "t=1" */
1025   url = gst_uri_from_string ("http://foo/var/file#t=1");
1026   table = gst_uri_get_media_fragment_table (url);
1027   fail_unless (table);
1028   fail_unless (g_hash_table_size (table) == 1);
1029   fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
1030           (gpointer) & val));
1031   fail_unless_equals_string ("1", val);
1032   g_hash_table_unref (table);
1033   gst_uri_unref (url);
1034
1035   /* NOTE: Media Fragments URI 1.0 (W3C) is saying that
1036    * "Multiple occurrences of the same dimension: only the last valid occurrence
1037    *  of a dimension (e.g. t=10 in #t=2&t=10) is interpreted and all previous
1038    *  occurrences (valid or invalid) SHOULD be ignored by the user agent"
1039    */
1040   /* TEST "t=1&t=2" */
1041   url = gst_uri_from_string ("http://foo/var/file#t=1&t=2");
1042   table = gst_uri_get_media_fragment_table (url);
1043   fail_unless (table);
1044   fail_unless (g_hash_table_size (table) == 1);
1045   fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
1046           (gpointer) & val));
1047   fail_unless_equals_string ("2", val);
1048   g_hash_table_unref (table);
1049   gst_uri_unref (url);
1050
1051   /* TEST "a=b=c" */
1052   url = gst_uri_from_string ("http://foo/var/file#a=b=c");
1053   table = gst_uri_get_media_fragment_table (url);
1054   fail_unless (table);
1055   fail_unless (g_hash_table_size (table) == 1);
1056   fail_unless (g_hash_table_lookup_extended (table, "a", NULL,
1057           (gpointer) & val));
1058   fail_unless_equals_string ("b=c", val);
1059   g_hash_table_unref (table);
1060   gst_uri_unref (url);
1061
1062   /* TEST "a&b=c" */
1063   url = gst_uri_from_string ("http://foo/var/file#a&b=c");
1064   table = gst_uri_get_media_fragment_table (url);
1065   fail_unless (table);
1066   fail_unless (g_hash_table_size (table) == 2);
1067   fail_unless (g_hash_table_lookup_extended (table, "a", NULL,
1068           (gpointer) & val));
1069   fail_unless (val == NULL);
1070   fail_unless (g_hash_table_lookup_extended (table, "b", NULL,
1071           (gpointer) & val));
1072   fail_unless_equals_string ("c", val);
1073   g_hash_table_unref (table);
1074   gst_uri_unref (url);
1075
1076   /* TEST "%74=%6ept%3A%310" */
1077   url = gst_uri_from_string ("http://foo/var/file#%74=%6ept%3A%310");
1078   table = gst_uri_get_media_fragment_table (url);
1079   fail_unless (table);
1080   fail_unless (g_hash_table_size (table) == 1);
1081   fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
1082           (gpointer) & val));
1083   fail_unless_equals_string ("npt:10", val);
1084   g_hash_table_unref (table);
1085   gst_uri_unref (url);
1086 }
1087
1088 GST_END_TEST;
1089
1090 static Suite *
1091 gst_uri_suite (void)
1092 {
1093   Suite *s = suite_create ("GstURI");
1094   TCase *tc_chain = tcase_create ("uri");
1095
1096   tcase_set_timeout (tc_chain, 20);
1097
1098   suite_add_tcase (s, tc_chain);
1099   tcase_add_test (tc_chain, test_protocol_case);
1100   tcase_add_test (tc_chain, test_uri_get_location);
1101 #ifndef GST_REMOVE_DEPRECATED
1102   tcase_add_test (tc_chain, test_gst_uri_construct);
1103 #endif
1104   tcase_add_test (tc_chain, test_uri_misc);
1105   tcase_add_test (tc_chain, test_element_make_from_uri);
1106 #ifdef G_OS_WIN32
1107   tcase_add_test (tc_chain, test_win32_uri);
1108 #endif
1109   tcase_add_test (tc_chain, test_url_parsing);
1110   tcase_add_test (tc_chain, test_url_presenting);
1111   tcase_add_test (tc_chain, test_url_normalization);
1112   tcase_add_test (tc_chain, test_url_joining);
1113   tcase_add_test (tc_chain, test_url_equality);
1114   tcase_add_test (tc_chain, test_url_constructors);
1115   tcase_add_test (tc_chain, test_url_get_set);
1116   tcase_add_test (tc_chain, test_url_get_media_fragment_table);
1117
1118   return s;
1119 }
1120
1121 GST_CHECK_MAIN (gst_uri);