no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / netwerk / test / unit / test_URIs2.js
blob8101f95e8bece476a16ddf0627ca2e9e01231a28
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
2 "use strict";
4 // Run by: cd objdir;  make -C netwerk/test/ xpcshell-tests
5 // or: cd objdir; make SOLO_FILE="test_URIs2.js" -C netwerk/test/ check-one
7 // This is a clone of test_URIs.js, with a different set of test data in gTests.
8 // The original test data in test_URIs.js was split between test_URIs and test_URIs2.js
9 // because test_URIs.js was running for too long on slow platforms, causing
10 // intermittent timeouts.
12 // Relevant RFCs: 1738, 1808, 2396, 3986 (newer than the code)
13 // http://greenbytes.de/tech/webdav/rfc3986.html#rfc.section.5.4
14 // http://greenbytes.de/tech/tc/uris/
16 // TEST DATA
17 // ---------
18 var gTests = [
19   {
20     spec: "view-source:about:blank",
21     scheme: "view-source",
22     prePath: "view-source:",
23     pathQueryRef: "about:blank",
24     ref: "",
25     nsIURL: false,
26     nsINestedURI: true,
27     immutable: true,
28   },
29   {
30     spec: "view-source:http://www.mozilla.org/",
31     scheme: "view-source",
32     prePath: "view-source:",
33     pathQueryRef: "http://www.mozilla.org/",
34     ref: "",
35     nsIURL: false,
36     nsINestedURI: true,
37     immutable: true,
38   },
39   {
40     spec: "x-external:",
41     scheme: "x-external",
42     prePath: "x-external:",
43     pathQueryRef: "",
44     ref: "",
45     nsIURL: false,
46     nsINestedURI: false,
47   },
48   {
49     spec: "x-external:abc",
50     scheme: "x-external",
51     prePath: "x-external:",
52     pathQueryRef: "abc",
53     ref: "",
54     nsIURL: false,
55     nsINestedURI: false,
56   },
57   {
58     spec: "http://www2.example.com/",
59     relativeURI: "a/b/c/d",
60     scheme: "http",
61     prePath: "http://www2.example.com",
62     pathQueryRef: "/a/b/c/d",
63     ref: "",
64     nsIURL: true,
65     nsINestedURI: false,
66   },
67   // relative URL testcases from http://greenbytes.de/tech/webdav/rfc3986.html#rfc.section.5.4
68   {
69     spec: "http://a/b/c/d;p?q",
70     relativeURI: "g:h",
71     scheme: "g",
72     prePath: "g:",
73     pathQueryRef: "h",
74     ref: "",
75     nsIURL: false,
76     nsINestedURI: false,
77   },
78   {
79     spec: "http://a/b/c/d;p?q",
80     relativeURI: "g",
81     scheme: "http",
82     prePath: "http://a",
83     pathQueryRef: "/b/c/g",
84     ref: "",
85     nsIURL: true,
86     nsINestedURI: false,
87   },
88   {
89     spec: "http://a/b/c/d;p?q",
90     relativeURI: "./g",
91     scheme: "http",
92     prePath: "http://a",
93     pathQueryRef: "/b/c/g",
94     ref: "",
95     nsIURL: true,
96     nsINestedURI: false,
97   },
98   {
99     spec: "http://a/b/c/d;p?q",
100     relativeURI: "g/",
101     scheme: "http",
102     prePath: "http://a",
103     pathQueryRef: "/b/c/g/",
104     ref: "",
105     nsIURL: true,
106     nsINestedURI: false,
107   },
108   {
109     spec: "http://a/b/c/d;p?q",
110     relativeURI: "/g",
111     scheme: "http",
112     prePath: "http://a",
113     pathQueryRef: "/g",
114     ref: "",
115     nsIURL: true,
116     nsINestedURI: false,
117   },
118   {
119     spec: "http://a/b/c/d;p?q",
120     relativeURI: "?y",
121     scheme: "http",
122     prePath: "http://a",
123     pathQueryRef: "/b/c/d;p?y",
124     ref: "", // fix
125     nsIURL: true,
126     nsINestedURI: false,
127   },
128   {
129     spec: "http://a/b/c/d;p?q",
130     relativeURI: "g?y",
131     scheme: "http",
132     prePath: "http://a",
133     pathQueryRef: "/b/c/g?y",
134     ref: "", // fix
135     specIgnoringRef: "http://a/b/c/g?y",
136     hasRef: false,
137     hasQuery: true,
138     nsIURL: true,
139     nsINestedURI: false,
140   },
141   {
142     spec: "http://a/b/c/d;p?q",
143     relativeURI: "#s",
144     scheme: "http",
145     prePath: "http://a",
146     pathQueryRef: "/b/c/d;p?q#s",
147     ref: "s", // fix
148     specIgnoringRef: "http://a/b/c/d;p?q",
149     hasRef: true,
150     nsIURL: true,
151     nsINestedURI: false,
152   },
153   {
154     spec: "http://a/b/c/d;p?q",
155     relativeURI: "g#s",
156     scheme: "http",
157     prePath: "http://a",
158     pathQueryRef: "/b/c/g#s",
159     ref: "s",
160     nsIURL: true,
161     nsINestedURI: false,
162   },
163   {
164     spec: "http://a/b/c/d;p?q",
165     relativeURI: "g?y#s",
166     scheme: "http",
167     prePath: "http://a",
168     pathQueryRef: "/b/c/g?y#s",
169     ref: "s",
170     nsIURL: true,
171     nsINestedURI: false,
172   },
173   /*
174     Bug xxxxxx - we return a path of b/c/;x
175   { spec:    "http://a/b/c/d;p?q",
176     relativeURI: ";x",
177     scheme:  "http",
178     prePath: "http://a",
179     pathQueryRef: "/b/c/d;x",
180     ref:     "",
181     nsIURL:  true, nsINestedURI: false },
182   */
183   {
184     spec: "http://a/b/c/d;p?q",
185     relativeURI: "g;x",
186     scheme: "http",
187     prePath: "http://a",
188     pathQueryRef: "/b/c/g;x",
189     ref: "",
190     nsIURL: true,
191     nsINestedURI: false,
192   },
193   {
194     spec: "http://a/b/c/d;p?q",
195     relativeURI: "g;x?y#s",
196     scheme: "http",
197     prePath: "http://a",
198     pathQueryRef: "/b/c/g;x?y#s",
199     ref: "s",
200     nsIURL: true,
201     nsINestedURI: false,
202   },
203   /*
204     Can't easily specify a relative URI of "" to the test code
205   { spec:    "http://a/b/c/d;p?q",
206     relativeURI: "",
207     scheme:  "http",
208     prePath: "http://a",
209     pathQueryRef: "/b/c/d",
210     ref:     "",
211     nsIURL:  true, nsINestedURI: false },
212   */
213   {
214     spec: "http://a/b/c/d;p?q",
215     relativeURI: ".",
216     scheme: "http",
217     prePath: "http://a",
218     pathQueryRef: "/b/c/",
219     ref: "",
220     nsIURL: true,
221     nsINestedURI: false,
222   },
223   {
224     spec: "http://a/b/c/d;p?q",
225     relativeURI: "./",
226     scheme: "http",
227     prePath: "http://a",
228     pathQueryRef: "/b/c/",
229     ref: "",
230     nsIURL: true,
231     nsINestedURI: false,
232   },
233   {
234     spec: "http://a/b/c/d;p?q",
235     relativeURI: "..",
236     scheme: "http",
237     prePath: "http://a",
238     pathQueryRef: "/b/",
239     ref: "",
240     nsIURL: true,
241     nsINestedURI: false,
242   },
243   {
244     spec: "http://a/b/c/d;p?q",
245     relativeURI: "../",
246     scheme: "http",
247     prePath: "http://a",
248     pathQueryRef: "/b/",
249     ref: "",
250     nsIURL: true,
251     nsINestedURI: false,
252   },
253   {
254     spec: "http://a/b/c/d;p?q",
255     relativeURI: "../g",
256     scheme: "http",
257     prePath: "http://a",
258     pathQueryRef: "/b/g",
259     ref: "",
260     nsIURL: true,
261     nsINestedURI: false,
262   },
263   {
264     spec: "http://a/b/c/d;p?q",
265     relativeURI: "../..",
266     scheme: "http",
267     prePath: "http://a",
268     pathQueryRef: "/",
269     ref: "",
270     nsIURL: true,
271     nsINestedURI: false,
272   },
273   {
274     spec: "http://a/b/c/d;p?q",
275     relativeURI: "../../",
276     scheme: "http",
277     prePath: "http://a",
278     pathQueryRef: "/",
279     ref: "",
280     nsIURL: true,
281     nsINestedURI: false,
282   },
283   {
284     spec: "http://a/b/c/d;p?q",
285     relativeURI: "../../g",
286     scheme: "http",
287     prePath: "http://a",
288     pathQueryRef: "/g",
289     ref: "",
290     nsIURL: true,
291     nsINestedURI: false,
292   },
294   // abnormal examples
295   {
296     spec: "http://a/b/c/d;p?q",
297     relativeURI: "../../../g",
298     scheme: "http",
299     prePath: "http://a",
300     pathQueryRef: "/g",
301     ref: "",
302     nsIURL: true,
303     nsINestedURI: false,
304   },
305   {
306     spec: "http://a/b/c/d;p?q",
307     relativeURI: "../../../../g",
308     scheme: "http",
309     prePath: "http://a",
310     pathQueryRef: "/g",
311     ref: "",
312     nsIURL: true,
313     nsINestedURI: false,
314   },
316   // coalesce
317   {
318     spec: "http://a/b/c/d;p?q",
319     relativeURI: "/./g",
320     scheme: "http",
321     prePath: "http://a",
322     pathQueryRef: "/g",
323     ref: "",
324     nsIURL: true,
325     nsINestedURI: false,
326   },
327   {
328     spec: "http://a/b/c/d;p?q",
329     relativeURI: "/../g",
330     scheme: "http",
331     prePath: "http://a",
332     pathQueryRef: "/g",
333     ref: "",
334     nsIURL: true,
335     nsINestedURI: false,
336   },
337   {
338     spec: "http://a/b/c/d;p?q",
339     relativeURI: "g.",
340     scheme: "http",
341     prePath: "http://a",
342     pathQueryRef: "/b/c/g.",
343     ref: "",
344     nsIURL: true,
345     nsINestedURI: false,
346   },
347   {
348     spec: "http://a/b/c/d;p?q",
349     relativeURI: ".g",
350     scheme: "http",
351     prePath: "http://a",
352     pathQueryRef: "/b/c/.g",
353     ref: "",
354     nsIURL: true,
355     nsINestedURI: false,
356   },
357   {
358     spec: "http://a/b/c/d;p?q",
359     relativeURI: "g..",
360     scheme: "http",
361     prePath: "http://a",
362     pathQueryRef: "/b/c/g..",
363     ref: "",
364     nsIURL: true,
365     nsINestedURI: false,
366   },
367   {
368     spec: "http://a/b/c/d;p?q",
369     relativeURI: "..g",
370     scheme: "http",
371     prePath: "http://a",
372     pathQueryRef: "/b/c/..g",
373     ref: "",
374     nsIURL: true,
375     nsINestedURI: false,
376   },
377   {
378     spec: "http://a/b/c/d;p?q",
379     relativeURI: ".",
380     scheme: "http",
381     prePath: "http://a",
382     pathQueryRef: "/b/c/",
383     ref: "",
384     nsIURL: true,
385     nsINestedURI: false,
386   },
387   {
388     spec: "http://a/b/c/d;p?q",
389     relativeURI: "./../g",
390     scheme: "http",
391     prePath: "http://a",
392     pathQueryRef: "/b/g",
393     ref: "",
394     nsIURL: true,
395     nsINestedURI: false,
396   },
397   {
398     spec: "http://a/b/c/d;p?q",
399     relativeURI: "./g/.",
400     scheme: "http",
401     prePath: "http://a",
402     pathQueryRef: "/b/c/g/",
403     ref: "",
404     nsIURL: true,
405     nsINestedURI: false,
406   },
407   {
408     spec: "http://a/b/c/d;p?q",
409     relativeURI: "g/./h",
410     scheme: "http",
411     prePath: "http://a",
412     pathQueryRef: "/b/c/g/h",
413     ref: "",
414     nsIURL: true,
415     nsINestedURI: false,
416   },
417   {
418     spec: "http://a/b/c/d;p?q",
419     relativeURI: "g/../h",
420     scheme: "http",
421     prePath: "http://a",
422     pathQueryRef: "/b/c/h",
423     ref: "", // fix
424     nsIURL: true,
425     nsINestedURI: false,
426   },
427   {
428     spec: "http://a/b/c/d;p?q",
429     relativeURI: "g;x=1/./y",
430     scheme: "http",
431     prePath: "http://a",
432     pathQueryRef: "/b/c/g;x=1/y",
433     ref: "",
434     nsIURL: true,
435     nsINestedURI: false,
436   },
437   {
438     spec: "http://a/b/c/d;p?q",
439     relativeURI: "g;x=1/../y",
440     scheme: "http",
441     prePath: "http://a",
442     pathQueryRef: "/b/c/y",
443     ref: "",
444     nsIURL: true,
445     nsINestedURI: false,
446   },
447   // protocol-relative http://tools.ietf.org/html/rfc3986#section-4.2
448   {
449     spec: "http://www2.example.com/",
450     relativeURI: "//www3.example2.com/bar",
451     scheme: "http",
452     prePath: "http://www3.example2.com",
453     pathQueryRef: "/bar",
454     ref: "",
455     nsIURL: true,
456     nsINestedURI: false,
457   },
458   {
459     spec: "https://www2.example.com/",
460     relativeURI: "//www3.example2.com/bar",
461     scheme: "https",
462     prePath: "https://www3.example2.com",
463     pathQueryRef: "/bar",
464     hasQuery: false,
465     ref: "",
466     nsIURL: true,
467     nsINestedURI: false,
468   },
471 var gHashSuffixes = ["#", "#myRef", "#myRef?a=b", "#myRef#", "#myRef#x:yz"];
473 // TEST HELPER FUNCTIONS
474 // ---------------------
475 function do_info(text, stack) {
476   if (!stack) {
477     stack = Components.stack.caller;
478   }
480   dump(
481     "\n" +
482       "TEST-INFO | " +
483       stack.filename +
484       " | [" +
485       stack.name +
486       " : " +
487       stack.lineNumber +
488       "] " +
489       text +
490       "\n"
491   );
494 // Checks that the URIs satisfy equals(), in both possible orderings.
495 // Also checks URI.equalsExceptRef(), because equal URIs should also be equal
496 // when we ignore the ref.
498 // The third argument is optional. If the client passes a third argument
499 // (e.g. todo_check_true), we'll use that in lieu of ok.
500 function do_check_uri_eq(aURI1, aURI2, aCheckTrueFunc = ok) {
501   do_info("(uri equals check: '" + aURI1.spec + "' == '" + aURI2.spec + "')");
502   aCheckTrueFunc(aURI1.equals(aURI2));
503   do_info("(uri equals check: '" + aURI2.spec + "' == '" + aURI1.spec + "')");
504   aCheckTrueFunc(aURI2.equals(aURI1));
506   // (Only take the extra step of testing 'equalsExceptRef' when we expect the
507   // URIs to really be equal.  In 'todo' cases, the URIs may or may not be
508   // equal when refs are ignored - there's no way of knowing in general.)
509   if (aCheckTrueFunc == ok) {
510     do_check_uri_eqExceptRef(aURI1, aURI2, aCheckTrueFunc);
511   }
514 // Checks that the URIs satisfy equalsExceptRef(), in both possible orderings.
516 // The third argument is optional. If the client passes a third argument
517 // (e.g. todo_check_true), we'll use that in lieu of ok.
518 function do_check_uri_eqExceptRef(aURI1, aURI2, aCheckTrueFunc = ok) {
519   do_info(
520     "(uri equalsExceptRef check: '" + aURI1.spec + "' == '" + aURI2.spec + "')"
521   );
522   aCheckTrueFunc(aURI1.equalsExceptRef(aURI2));
523   do_info(
524     "(uri equalsExceptRef check: '" + aURI2.spec + "' == '" + aURI1.spec + "')"
525   );
526   aCheckTrueFunc(aURI2.equalsExceptRef(aURI1));
529 // Checks that the given property on aURI matches the corresponding property
530 // in the test bundle (or matches some function of that corresponding property,
531 // if aTestFunctor is passed in).
532 function do_check_property(aTest, aURI, aPropertyName, aTestFunctor) {
533   if (aTest[aPropertyName]) {
534     var expectedVal = aTestFunctor
535       ? aTestFunctor(aTest[aPropertyName])
536       : aTest[aPropertyName];
538     do_info(
539       "testing " +
540         aPropertyName +
541         " of " +
542         (aTestFunctor ? "modified '" : "'") +
543         aTest.spec +
544         "' is '" +
545         expectedVal +
546         "'"
547     );
548     Assert.equal(aURI[aPropertyName], expectedVal);
549   }
552 // Test that a given URI parses correctly into its various components.
553 function do_test_uri_basic(aTest) {
554   var URI;
556   do_info(
557     "Basic tests for " + aTest.spec + " relative URI: " + aTest.relativeURI
558   );
560   try {
561     URI = NetUtil.newURI(aTest.spec);
562   } catch (e) {
563     do_info("Caught error on parse of" + aTest.spec + " Error: " + e.result);
564     if (aTest.fail) {
565       Assert.equal(e.result, aTest.result);
566       return;
567     }
568     do_throw(e.result);
569   }
571   if (aTest.relativeURI) {
572     var relURI;
574     try {
575       relURI = Services.io.newURI(aTest.relativeURI, null, URI);
576     } catch (e) {
577       do_info(
578         "Caught error on Relative parse of " +
579           aTest.spec +
580           " + " +
581           aTest.relativeURI +
582           " Error: " +
583           e.result
584       );
585       if (aTest.relativeFail) {
586         Assert.equal(e.result, aTest.relativeFail);
587         return;
588       }
589       do_throw(e.result);
590     }
591     do_info(
592       "relURI.pathQueryRef = " +
593         relURI.pathQueryRef +
594         ", was " +
595         URI.pathQueryRef
596     );
597     URI = relURI;
598     do_info("URI.pathQueryRef now = " + URI.pathQueryRef);
599   }
601   // Sanity-check
602   do_info("testing " + aTest.spec + " equals a clone of itself");
603   do_check_uri_eq(URI, URI.mutate().finalize());
604   do_check_uri_eqExceptRef(URI, URI.mutate().setRef("").finalize());
605   do_info("testing " + aTest.spec + " instanceof nsIURL");
606   Assert.equal(URI instanceof Ci.nsIURL, aTest.nsIURL);
607   do_info("testing " + aTest.spec + " instanceof nsINestedURI");
608   Assert.equal(URI instanceof Ci.nsINestedURI, aTest.nsINestedURI);
610   do_info(
611     "testing that " +
612       aTest.spec +
613       " throws or returns false " +
614       "from equals(null)"
615   );
616   // XXXdholbert At some point it'd probably be worth making this behavior
617   // (throwing vs. returning false) consistent across URI implementations.
618   var threw = false;
619   var isEqualToNull;
620   try {
621     isEqualToNull = URI.equals(null);
622   } catch (e) {
623     threw = true;
624   }
625   Assert.ok(threw || !isEqualToNull);
627   // Check the various components
628   do_check_property(aTest, URI, "scheme");
629   do_check_property(aTest, URI, "prePath");
630   do_check_property(aTest, URI, "pathQueryRef");
631   do_check_property(aTest, URI, "query");
632   do_check_property(aTest, URI, "ref");
633   do_check_property(aTest, URI, "port");
634   do_check_property(aTest, URI, "username");
635   do_check_property(aTest, URI, "password");
636   do_check_property(aTest, URI, "host");
637   do_check_property(aTest, URI, "specIgnoringRef");
638   if ("hasRef" in aTest) {
639     do_info("testing hasref: " + aTest.hasRef + " vs " + URI.hasRef);
640     Assert.equal(aTest.hasRef, URI.hasRef);
641   }
642   if ("hasQuery" in aTest) {
643     do_info("testing hasQuery: " + aTest.hasQuery + " vs " + URI.hasQuery);
644     Assert.equal(aTest.hasQuery, URI.hasQuery);
645   }
648 // Test that a given URI parses correctly when we add a given ref to the end
649 function do_test_uri_with_hash_suffix(aTest, aSuffix) {
650   do_info("making sure caller is using suffix that starts with '#'");
651   Assert.equal(aSuffix[0], "#");
653   var origURI = NetUtil.newURI(aTest.spec);
654   var testURI;
656   if (aTest.relativeURI) {
657     try {
658       origURI = Services.io.newURI(aTest.relativeURI, null, origURI);
659     } catch (e) {
660       do_info(
661         "Caught error on Relative parse of " +
662           aTest.spec +
663           " + " +
664           aTest.relativeURI +
665           " Error: " +
666           e.result
667       );
668       return;
669     }
670     try {
671       testURI = Services.io.newURI(aSuffix, null, origURI);
672     } catch (e) {
673       do_info(
674         "Caught error adding suffix to " +
675           aTest.spec +
676           " + " +
677           aTest.relativeURI +
678           ", suffix " +
679           aSuffix +
680           " Error: " +
681           e.result
682       );
683       return;
684     }
685   } else {
686     testURI = NetUtil.newURI(aTest.spec + aSuffix);
687   }
689   do_info(
690     "testing " +
691       aTest.spec +
692       " with '" +
693       aSuffix +
694       "' appended " +
695       "equals a clone of itself"
696   );
697   do_check_uri_eq(testURI, testURI.mutate().finalize());
699   do_info(
700     "testing " +
701       aTest.spec +
702       " doesn't equal self with '" +
703       aSuffix +
704       "' appended"
705   );
707   Assert.ok(!origURI.equals(testURI));
709   do_info(
710     "testing " +
711       aTest.spec +
712       " is equalExceptRef to self with '" +
713       aSuffix +
714       "' appended"
715   );
716   do_check_uri_eqExceptRef(origURI, testURI);
718   Assert.equal(testURI.hasRef, true);
720   if (!origURI.ref) {
721     // These tests fail if origURI has a ref
722     do_info(
723       "testing cloneIgnoringRef on " +
724         testURI.spec +
725         " is equal to no-ref version but not equal to ref version"
726     );
727     var cloneNoRef = testURI.mutate().setRef("").finalize();
728     do_check_uri_eq(cloneNoRef, origURI);
729     Assert.ok(!cloneNoRef.equals(testURI));
730   }
732   do_check_property(aTest, testURI, "scheme");
733   do_check_property(aTest, testURI, "prePath");
734   if (!origURI.ref) {
735     // These don't work if it's a ref already because '+' doesn't give the right result
736     do_check_property(aTest, testURI, "pathQueryRef", function (aStr) {
737       return aStr + aSuffix;
738     });
739     do_check_property(aTest, testURI, "ref", function () {
740       return aSuffix.substr(1);
741     });
742   }
745 // Tests various ways of setting & clearing a ref on a URI.
746 function do_test_mutate_ref(aTest, aSuffix) {
747   do_info("making sure caller is using suffix that starts with '#'");
748   Assert.equal(aSuffix[0], "#");
750   var refURIWithSuffix = NetUtil.newURI(aTest.spec + aSuffix);
751   var refURIWithoutSuffix = NetUtil.newURI(aTest.spec);
753   var testURI = NetUtil.newURI(aTest.spec);
755   // First: Try setting .ref to our suffix
756   do_info(
757     "testing that setting .ref on " +
758       aTest.spec +
759       " to '" +
760       aSuffix +
761       "' does what we expect"
762   );
763   testURI = testURI.mutate().setRef(aSuffix).finalize();
764   do_check_uri_eq(testURI, refURIWithSuffix);
765   do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
767   // Now try setting .ref but leave off the initial hash (expect same result)
768   var suffixLackingHash = aSuffix.substr(1);
769   if (suffixLackingHash) {
770     // (skip this our suffix was *just* a #)
771     do_info(
772       "testing that setting .ref on " +
773         aTest.spec +
774         " to '" +
775         suffixLackingHash +
776         "' does what we expect"
777     );
778     testURI = testURI.mutate().setRef(suffixLackingHash).finalize();
779     do_check_uri_eq(testURI, refURIWithSuffix);
780     do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
781   }
783   // Now, clear .ref (should get us back the original spec)
784   do_info(
785     "testing that clearing .ref on " + testURI.spec + " does what we expect"
786   );
787   testURI = testURI.mutate().setRef("").finalize();
788   do_check_uri_eq(testURI, refURIWithoutSuffix);
789   do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
791   if (!aTest.relativeURI) {
792     // TODO: These tests don't work as-is for relative URIs.
794     // Now try setting .spec directly (including suffix) and then clearing .ref
795     var specWithSuffix = aTest.spec + aSuffix;
796     do_info(
797       "testing that setting spec to " +
798         specWithSuffix +
799         " and then clearing ref does what we expect"
800     );
801     testURI = testURI.mutate().setSpec(specWithSuffix).setRef("").finalize();
802     do_check_uri_eq(testURI, refURIWithoutSuffix);
803     do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
805     // XXX nsIJARURI throws an exception in SetPath(), so skip it for next part.
806     if (!(testURI instanceof Ci.nsIJARURI)) {
807       // Now try setting .pathQueryRef directly (including suffix) and then clearing .ref
808       // (same as above, but with now with .pathQueryRef instead of .spec)
809       testURI = NetUtil.newURI(aTest.spec);
811       var pathWithSuffix = aTest.pathQueryRef + aSuffix;
812       do_info(
813         "testing that setting path to " +
814           pathWithSuffix +
815           " and then clearing ref does what we expect"
816       );
817       testURI = testURI
818         .mutate()
819         .setPathQueryRef(pathWithSuffix)
820         .setRef("")
821         .finalize();
822       do_check_uri_eq(testURI, refURIWithoutSuffix);
823       do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
825       // Also: make sure that clearing .pathQueryRef also clears .ref
826       testURI = testURI.mutate().setPathQueryRef(pathWithSuffix).finalize();
827       do_info(
828         "testing that clearing path from " +
829           pathWithSuffix +
830           " also clears .ref"
831       );
832       testURI = testURI.mutate().setPathQueryRef("").finalize();
833       Assert.equal(testURI.ref, "");
834     }
835   }
838 // TEST MAIN FUNCTION
839 // ------------------
840 function run_test() {
841   // UTF-8 check - From bug 622981
842   // ASCII
843   let base = Services.io.newURI("http://example.org/xenia?");
844   let resolved = Services.io.newURI("?x", null, base);
845   let expected = Services.io.newURI("http://example.org/xenia?x");
846   do_info(
847     "Bug 662981: ACSII - comparing " + resolved.spec + " and " + expected.spec
848   );
849   Assert.ok(resolved.equals(expected));
851   // UTF-8 character "è"
852   // Bug 622981 was triggered by an empty query string
853   base = Services.io.newURI("http://example.org/xènia?");
854   resolved = Services.io.newURI("?x", null, base);
855   expected = Services.io.newURI("http://example.org/xènia?x");
856   do_info(
857     "Bug 662981: UTF8 - comparing " + resolved.spec + " and " + expected.spec
858   );
859   Assert.ok(resolved.equals(expected));
861   gTests.forEach(function (aTest) {
862     // Check basic URI functionality
863     do_test_uri_basic(aTest);
865     if (!aTest.fail) {
866       // Try adding various #-prefixed strings to the ends of the URIs
867       gHashSuffixes.forEach(function (aSuffix) {
868         do_test_uri_with_hash_suffix(aTest, aSuffix);
869         if (!aTest.immutable) {
870           do_test_mutate_ref(aTest, aSuffix);
871         }
872       });
874       // For URIs that we couldn't mutate above due to them being immutable:
875       // Now we check that they're actually immutable.
876       if (aTest.immutable) {
877         Assert.ok(aTest.immutable);
878       }
879     }
880   });