Bug 1845311 - [Part 2] Use ChromeUtils.defineLazyGetter in more places r=arai,webcomp...
[gecko.git] / netwerk / test / unit / test_URIs2.js
blob75e88c595aebaf3566810228c2c7ecb3bc8273c5
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     nsIURL: true,
138     nsINestedURI: false,
139   },
140   {
141     spec: "http://a/b/c/d;p?q",
142     relativeURI: "#s",
143     scheme: "http",
144     prePath: "http://a",
145     pathQueryRef: "/b/c/d;p?q#s",
146     ref: "s", // fix
147     specIgnoringRef: "http://a/b/c/d;p?q",
148     hasRef: true,
149     nsIURL: true,
150     nsINestedURI: false,
151   },
152   {
153     spec: "http://a/b/c/d;p?q",
154     relativeURI: "g#s",
155     scheme: "http",
156     prePath: "http://a",
157     pathQueryRef: "/b/c/g#s",
158     ref: "s",
159     nsIURL: true,
160     nsINestedURI: false,
161   },
162   {
163     spec: "http://a/b/c/d;p?q",
164     relativeURI: "g?y#s",
165     scheme: "http",
166     prePath: "http://a",
167     pathQueryRef: "/b/c/g?y#s",
168     ref: "s",
169     nsIURL: true,
170     nsINestedURI: false,
171   },
172   /*
173     Bug xxxxxx - we return a path of b/c/;x
174   { spec:    "http://a/b/c/d;p?q",
175     relativeURI: ";x",
176     scheme:  "http",
177     prePath: "http://a",
178     pathQueryRef: "/b/c/d;x",
179     ref:     "",
180     nsIURL:  true, nsINestedURI: false },
181   */
182   {
183     spec: "http://a/b/c/d;p?q",
184     relativeURI: "g;x",
185     scheme: "http",
186     prePath: "http://a",
187     pathQueryRef: "/b/c/g;x",
188     ref: "",
189     nsIURL: true,
190     nsINestedURI: false,
191   },
192   {
193     spec: "http://a/b/c/d;p?q",
194     relativeURI: "g;x?y#s",
195     scheme: "http",
196     prePath: "http://a",
197     pathQueryRef: "/b/c/g;x?y#s",
198     ref: "s",
199     nsIURL: true,
200     nsINestedURI: false,
201   },
202   /*
203     Can't easily specify a relative URI of "" to the test code
204   { spec:    "http://a/b/c/d;p?q",
205     relativeURI: "",
206     scheme:  "http",
207     prePath: "http://a",
208     pathQueryRef: "/b/c/d",
209     ref:     "",
210     nsIURL:  true, nsINestedURI: false },
211   */
212   {
213     spec: "http://a/b/c/d;p?q",
214     relativeURI: ".",
215     scheme: "http",
216     prePath: "http://a",
217     pathQueryRef: "/b/c/",
218     ref: "",
219     nsIURL: true,
220     nsINestedURI: false,
221   },
222   {
223     spec: "http://a/b/c/d;p?q",
224     relativeURI: "./",
225     scheme: "http",
226     prePath: "http://a",
227     pathQueryRef: "/b/c/",
228     ref: "",
229     nsIURL: true,
230     nsINestedURI: false,
231   },
232   {
233     spec: "http://a/b/c/d;p?q",
234     relativeURI: "..",
235     scheme: "http",
236     prePath: "http://a",
237     pathQueryRef: "/b/",
238     ref: "",
239     nsIURL: true,
240     nsINestedURI: false,
241   },
242   {
243     spec: "http://a/b/c/d;p?q",
244     relativeURI: "../",
245     scheme: "http",
246     prePath: "http://a",
247     pathQueryRef: "/b/",
248     ref: "",
249     nsIURL: true,
250     nsINestedURI: false,
251   },
252   {
253     spec: "http://a/b/c/d;p?q",
254     relativeURI: "../g",
255     scheme: "http",
256     prePath: "http://a",
257     pathQueryRef: "/b/g",
258     ref: "",
259     nsIURL: true,
260     nsINestedURI: false,
261   },
262   {
263     spec: "http://a/b/c/d;p?q",
264     relativeURI: "../..",
265     scheme: "http",
266     prePath: "http://a",
267     pathQueryRef: "/",
268     ref: "",
269     nsIURL: true,
270     nsINestedURI: false,
271   },
272   {
273     spec: "http://a/b/c/d;p?q",
274     relativeURI: "../../",
275     scheme: "http",
276     prePath: "http://a",
277     pathQueryRef: "/",
278     ref: "",
279     nsIURL: true,
280     nsINestedURI: false,
281   },
282   {
283     spec: "http://a/b/c/d;p?q",
284     relativeURI: "../../g",
285     scheme: "http",
286     prePath: "http://a",
287     pathQueryRef: "/g",
288     ref: "",
289     nsIURL: true,
290     nsINestedURI: false,
291   },
293   // abnormal examples
294   {
295     spec: "http://a/b/c/d;p?q",
296     relativeURI: "../../../g",
297     scheme: "http",
298     prePath: "http://a",
299     pathQueryRef: "/g",
300     ref: "",
301     nsIURL: true,
302     nsINestedURI: false,
303   },
304   {
305     spec: "http://a/b/c/d;p?q",
306     relativeURI: "../../../../g",
307     scheme: "http",
308     prePath: "http://a",
309     pathQueryRef: "/g",
310     ref: "",
311     nsIURL: true,
312     nsINestedURI: false,
313   },
315   // coalesce
316   {
317     spec: "http://a/b/c/d;p?q",
318     relativeURI: "/./g",
319     scheme: "http",
320     prePath: "http://a",
321     pathQueryRef: "/g",
322     ref: "",
323     nsIURL: true,
324     nsINestedURI: false,
325   },
326   {
327     spec: "http://a/b/c/d;p?q",
328     relativeURI: "/../g",
329     scheme: "http",
330     prePath: "http://a",
331     pathQueryRef: "/g",
332     ref: "",
333     nsIURL: true,
334     nsINestedURI: false,
335   },
336   {
337     spec: "http://a/b/c/d;p?q",
338     relativeURI: "g.",
339     scheme: "http",
340     prePath: "http://a",
341     pathQueryRef: "/b/c/g.",
342     ref: "",
343     nsIURL: true,
344     nsINestedURI: false,
345   },
346   {
347     spec: "http://a/b/c/d;p?q",
348     relativeURI: ".g",
349     scheme: "http",
350     prePath: "http://a",
351     pathQueryRef: "/b/c/.g",
352     ref: "",
353     nsIURL: true,
354     nsINestedURI: false,
355   },
356   {
357     spec: "http://a/b/c/d;p?q",
358     relativeURI: "g..",
359     scheme: "http",
360     prePath: "http://a",
361     pathQueryRef: "/b/c/g..",
362     ref: "",
363     nsIURL: true,
364     nsINestedURI: false,
365   },
366   {
367     spec: "http://a/b/c/d;p?q",
368     relativeURI: "..g",
369     scheme: "http",
370     prePath: "http://a",
371     pathQueryRef: "/b/c/..g",
372     ref: "",
373     nsIURL: true,
374     nsINestedURI: false,
375   },
376   {
377     spec: "http://a/b/c/d;p?q",
378     relativeURI: ".",
379     scheme: "http",
380     prePath: "http://a",
381     pathQueryRef: "/b/c/",
382     ref: "",
383     nsIURL: true,
384     nsINestedURI: false,
385   },
386   {
387     spec: "http://a/b/c/d;p?q",
388     relativeURI: "./../g",
389     scheme: "http",
390     prePath: "http://a",
391     pathQueryRef: "/b/g",
392     ref: "",
393     nsIURL: true,
394     nsINestedURI: false,
395   },
396   {
397     spec: "http://a/b/c/d;p?q",
398     relativeURI: "./g/.",
399     scheme: "http",
400     prePath: "http://a",
401     pathQueryRef: "/b/c/g/",
402     ref: "",
403     nsIURL: true,
404     nsINestedURI: false,
405   },
406   {
407     spec: "http://a/b/c/d;p?q",
408     relativeURI: "g/./h",
409     scheme: "http",
410     prePath: "http://a",
411     pathQueryRef: "/b/c/g/h",
412     ref: "",
413     nsIURL: true,
414     nsINestedURI: false,
415   },
416   {
417     spec: "http://a/b/c/d;p?q",
418     relativeURI: "g/../h",
419     scheme: "http",
420     prePath: "http://a",
421     pathQueryRef: "/b/c/h",
422     ref: "", // fix
423     nsIURL: true,
424     nsINestedURI: false,
425   },
426   {
427     spec: "http://a/b/c/d;p?q",
428     relativeURI: "g;x=1/./y",
429     scheme: "http",
430     prePath: "http://a",
431     pathQueryRef: "/b/c/g;x=1/y",
432     ref: "",
433     nsIURL: true,
434     nsINestedURI: false,
435   },
436   {
437     spec: "http://a/b/c/d;p?q",
438     relativeURI: "g;x=1/../y",
439     scheme: "http",
440     prePath: "http://a",
441     pathQueryRef: "/b/c/y",
442     ref: "",
443     nsIURL: true,
444     nsINestedURI: false,
445   },
446   // protocol-relative http://tools.ietf.org/html/rfc3986#section-4.2
447   {
448     spec: "http://www2.example.com/",
449     relativeURI: "//www3.example2.com/bar",
450     scheme: "http",
451     prePath: "http://www3.example2.com",
452     pathQueryRef: "/bar",
453     ref: "",
454     nsIURL: true,
455     nsINestedURI: false,
456   },
457   {
458     spec: "https://www2.example.com/",
459     relativeURI: "//www3.example2.com/bar",
460     scheme: "https",
461     prePath: "https://www3.example2.com",
462     pathQueryRef: "/bar",
463     ref: "",
464     nsIURL: true,
465     nsINestedURI: false,
466   },
469 var gHashSuffixes = ["#", "#myRef", "#myRef?a=b", "#myRef#", "#myRef#x:yz"];
471 // TEST HELPER FUNCTIONS
472 // ---------------------
473 function do_info(text, stack) {
474   if (!stack) {
475     stack = Components.stack.caller;
476   }
478   dump(
479     "\n" +
480       "TEST-INFO | " +
481       stack.filename +
482       " | [" +
483       stack.name +
484       " : " +
485       stack.lineNumber +
486       "] " +
487       text +
488       "\n"
489   );
492 // Checks that the URIs satisfy equals(), in both possible orderings.
493 // Also checks URI.equalsExceptRef(), because equal URIs should also be equal
494 // when we ignore the ref.
496 // The third argument is optional. If the client passes a third argument
497 // (e.g. todo_check_true), we'll use that in lieu of ok.
498 function do_check_uri_eq(aURI1, aURI2, aCheckTrueFunc = ok) {
499   do_info("(uri equals check: '" + aURI1.spec + "' == '" + aURI2.spec + "')");
500   aCheckTrueFunc(aURI1.equals(aURI2));
501   do_info("(uri equals check: '" + aURI2.spec + "' == '" + aURI1.spec + "')");
502   aCheckTrueFunc(aURI2.equals(aURI1));
504   // (Only take the extra step of testing 'equalsExceptRef' when we expect the
505   // URIs to really be equal.  In 'todo' cases, the URIs may or may not be
506   // equal when refs are ignored - there's no way of knowing in general.)
507   if (aCheckTrueFunc == ok) {
508     do_check_uri_eqExceptRef(aURI1, aURI2, aCheckTrueFunc);
509   }
512 // Checks that the URIs satisfy equalsExceptRef(), in both possible orderings.
514 // The third argument is optional. If the client passes a third argument
515 // (e.g. todo_check_true), we'll use that in lieu of ok.
516 function do_check_uri_eqExceptRef(aURI1, aURI2, aCheckTrueFunc = ok) {
517   do_info(
518     "(uri equalsExceptRef check: '" + aURI1.spec + "' == '" + aURI2.spec + "')"
519   );
520   aCheckTrueFunc(aURI1.equalsExceptRef(aURI2));
521   do_info(
522     "(uri equalsExceptRef check: '" + aURI2.spec + "' == '" + aURI1.spec + "')"
523   );
524   aCheckTrueFunc(aURI2.equalsExceptRef(aURI1));
527 // Checks that the given property on aURI matches the corresponding property
528 // in the test bundle (or matches some function of that corresponding property,
529 // if aTestFunctor is passed in).
530 function do_check_property(aTest, aURI, aPropertyName, aTestFunctor) {
531   if (aTest[aPropertyName]) {
532     var expectedVal = aTestFunctor
533       ? aTestFunctor(aTest[aPropertyName])
534       : aTest[aPropertyName];
536     do_info(
537       "testing " +
538         aPropertyName +
539         " of " +
540         (aTestFunctor ? "modified '" : "'") +
541         aTest.spec +
542         "' is '" +
543         expectedVal +
544         "'"
545     );
546     Assert.equal(aURI[aPropertyName], expectedVal);
547   }
550 // Test that a given URI parses correctly into its various components.
551 function do_test_uri_basic(aTest) {
552   var URI;
554   do_info(
555     "Basic tests for " + aTest.spec + " relative URI: " + aTest.relativeURI
556   );
558   try {
559     URI = NetUtil.newURI(aTest.spec);
560   } catch (e) {
561     do_info("Caught error on parse of" + aTest.spec + " Error: " + e.result);
562     if (aTest.fail) {
563       Assert.equal(e.result, aTest.result);
564       return;
565     }
566     do_throw(e.result);
567   }
569   if (aTest.relativeURI) {
570     var relURI;
572     try {
573       relURI = Services.io.newURI(aTest.relativeURI, null, URI);
574     } catch (e) {
575       do_info(
576         "Caught error on Relative parse of " +
577           aTest.spec +
578           " + " +
579           aTest.relativeURI +
580           " Error: " +
581           e.result
582       );
583       if (aTest.relativeFail) {
584         Assert.equal(e.result, aTest.relativeFail);
585         return;
586       }
587       do_throw(e.result);
588     }
589     do_info(
590       "relURI.pathQueryRef = " +
591         relURI.pathQueryRef +
592         ", was " +
593         URI.pathQueryRef
594     );
595     URI = relURI;
596     do_info("URI.pathQueryRef now = " + URI.pathQueryRef);
597   }
599   // Sanity-check
600   do_info("testing " + aTest.spec + " equals a clone of itself");
601   do_check_uri_eq(URI, URI.mutate().finalize());
602   do_check_uri_eqExceptRef(URI, URI.mutate().setRef("").finalize());
603   do_info("testing " + aTest.spec + " instanceof nsIURL");
604   Assert.equal(URI instanceof Ci.nsIURL, aTest.nsIURL);
605   do_info("testing " + aTest.spec + " instanceof nsINestedURI");
606   Assert.equal(URI instanceof Ci.nsINestedURI, aTest.nsINestedURI);
608   do_info(
609     "testing that " +
610       aTest.spec +
611       " throws or returns false " +
612       "from equals(null)"
613   );
614   // XXXdholbert At some point it'd probably be worth making this behavior
615   // (throwing vs. returning false) consistent across URI implementations.
616   var threw = false;
617   var isEqualToNull;
618   try {
619     isEqualToNull = URI.equals(null);
620   } catch (e) {
621     threw = true;
622   }
623   Assert.ok(threw || !isEqualToNull);
625   // Check the various components
626   do_check_property(aTest, URI, "scheme");
627   do_check_property(aTest, URI, "prePath");
628   do_check_property(aTest, URI, "pathQueryRef");
629   do_check_property(aTest, URI, "query");
630   do_check_property(aTest, URI, "ref");
631   do_check_property(aTest, URI, "port");
632   do_check_property(aTest, URI, "username");
633   do_check_property(aTest, URI, "password");
634   do_check_property(aTest, URI, "host");
635   do_check_property(aTest, URI, "specIgnoringRef");
636   if ("hasRef" in aTest) {
637     do_info("testing hasref: " + aTest.hasRef + " vs " + URI.hasRef);
638     Assert.equal(aTest.hasRef, URI.hasRef);
639   }
642 // Test that a given URI parses correctly when we add a given ref to the end
643 function do_test_uri_with_hash_suffix(aTest, aSuffix) {
644   do_info("making sure caller is using suffix that starts with '#'");
645   Assert.equal(aSuffix[0], "#");
647   var origURI = NetUtil.newURI(aTest.spec);
648   var testURI;
650   if (aTest.relativeURI) {
651     try {
652       origURI = Services.io.newURI(aTest.relativeURI, null, origURI);
653     } catch (e) {
654       do_info(
655         "Caught error on Relative parse of " +
656           aTest.spec +
657           " + " +
658           aTest.relativeURI +
659           " Error: " +
660           e.result
661       );
662       return;
663     }
664     try {
665       testURI = Services.io.newURI(aSuffix, null, origURI);
666     } catch (e) {
667       do_info(
668         "Caught error adding suffix to " +
669           aTest.spec +
670           " + " +
671           aTest.relativeURI +
672           ", suffix " +
673           aSuffix +
674           " Error: " +
675           e.result
676       );
677       return;
678     }
679   } else {
680     testURI = NetUtil.newURI(aTest.spec + aSuffix);
681   }
683   do_info(
684     "testing " +
685       aTest.spec +
686       " with '" +
687       aSuffix +
688       "' appended " +
689       "equals a clone of itself"
690   );
691   do_check_uri_eq(testURI, testURI.mutate().finalize());
693   do_info(
694     "testing " +
695       aTest.spec +
696       " doesn't equal self with '" +
697       aSuffix +
698       "' appended"
699   );
701   Assert.ok(!origURI.equals(testURI));
703   do_info(
704     "testing " +
705       aTest.spec +
706       " is equalExceptRef to self with '" +
707       aSuffix +
708       "' appended"
709   );
710   do_check_uri_eqExceptRef(origURI, testURI);
712   Assert.equal(testURI.hasRef, true);
714   if (!origURI.ref) {
715     // These tests fail if origURI has a ref
716     do_info(
717       "testing cloneIgnoringRef on " +
718         testURI.spec +
719         " is equal to no-ref version but not equal to ref version"
720     );
721     var cloneNoRef = testURI.mutate().setRef("").finalize();
722     do_check_uri_eq(cloneNoRef, origURI);
723     Assert.ok(!cloneNoRef.equals(testURI));
724   }
726   do_check_property(aTest, testURI, "scheme");
727   do_check_property(aTest, testURI, "prePath");
728   if (!origURI.ref) {
729     // These don't work if it's a ref already because '+' doesn't give the right result
730     do_check_property(aTest, testURI, "pathQueryRef", function (aStr) {
731       return aStr + aSuffix;
732     });
733     do_check_property(aTest, testURI, "ref", function (aStr) {
734       return aSuffix.substr(1);
735     });
736   }
739 // Tests various ways of setting & clearing a ref on a URI.
740 function do_test_mutate_ref(aTest, aSuffix) {
741   do_info("making sure caller is using suffix that starts with '#'");
742   Assert.equal(aSuffix[0], "#");
744   var refURIWithSuffix = NetUtil.newURI(aTest.spec + aSuffix);
745   var refURIWithoutSuffix = NetUtil.newURI(aTest.spec);
747   var testURI = NetUtil.newURI(aTest.spec);
749   // First: Try setting .ref to our suffix
750   do_info(
751     "testing that setting .ref on " +
752       aTest.spec +
753       " to '" +
754       aSuffix +
755       "' does what we expect"
756   );
757   testURI = testURI.mutate().setRef(aSuffix).finalize();
758   do_check_uri_eq(testURI, refURIWithSuffix);
759   do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
761   // Now try setting .ref but leave off the initial hash (expect same result)
762   var suffixLackingHash = aSuffix.substr(1);
763   if (suffixLackingHash) {
764     // (skip this our suffix was *just* a #)
765     do_info(
766       "testing that setting .ref on " +
767         aTest.spec +
768         " to '" +
769         suffixLackingHash +
770         "' does what we expect"
771     );
772     testURI = testURI.mutate().setRef(suffixLackingHash).finalize();
773     do_check_uri_eq(testURI, refURIWithSuffix);
774     do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
775   }
777   // Now, clear .ref (should get us back the original spec)
778   do_info(
779     "testing that clearing .ref on " + testURI.spec + " does what we expect"
780   );
781   testURI = testURI.mutate().setRef("").finalize();
782   do_check_uri_eq(testURI, refURIWithoutSuffix);
783   do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
785   if (!aTest.relativeURI) {
786     // TODO: These tests don't work as-is for relative URIs.
788     // Now try setting .spec directly (including suffix) and then clearing .ref
789     var specWithSuffix = aTest.spec + aSuffix;
790     do_info(
791       "testing that setting spec to " +
792         specWithSuffix +
793         " and then clearing ref does what we expect"
794     );
795     testURI = testURI.mutate().setSpec(specWithSuffix).setRef("").finalize();
796     do_check_uri_eq(testURI, refURIWithoutSuffix);
797     do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
799     // XXX nsIJARURI throws an exception in SetPath(), so skip it for next part.
800     if (!(testURI instanceof Ci.nsIJARURI)) {
801       // Now try setting .pathQueryRef directly (including suffix) and then clearing .ref
802       // (same as above, but with now with .pathQueryRef instead of .spec)
803       testURI = NetUtil.newURI(aTest.spec);
805       var pathWithSuffix = aTest.pathQueryRef + aSuffix;
806       do_info(
807         "testing that setting path to " +
808           pathWithSuffix +
809           " and then clearing ref does what we expect"
810       );
811       testURI = testURI
812         .mutate()
813         .setPathQueryRef(pathWithSuffix)
814         .setRef("")
815         .finalize();
816       do_check_uri_eq(testURI, refURIWithoutSuffix);
817       do_check_uri_eqExceptRef(testURI, refURIWithSuffix);
819       // Also: make sure that clearing .pathQueryRef also clears .ref
820       testURI = testURI.mutate().setPathQueryRef(pathWithSuffix).finalize();
821       do_info(
822         "testing that clearing path from " +
823           pathWithSuffix +
824           " also clears .ref"
825       );
826       testURI = testURI.mutate().setPathQueryRef("").finalize();
827       Assert.equal(testURI.ref, "");
828     }
829   }
832 // TEST MAIN FUNCTION
833 // ------------------
834 function run_test() {
835   // UTF-8 check - From bug 622981
836   // ASCII
837   let base = Services.io.newURI("http://example.org/xenia?");
838   let resolved = Services.io.newURI("?x", null, base);
839   let expected = Services.io.newURI("http://example.org/xenia?x");
840   do_info(
841     "Bug 662981: ACSII - comparing " + resolved.spec + " and " + expected.spec
842   );
843   Assert.ok(resolved.equals(expected));
845   // UTF-8 character "è"
846   // Bug 622981 was triggered by an empty query string
847   base = Services.io.newURI("http://example.org/xènia?");
848   resolved = Services.io.newURI("?x", null, base);
849   expected = Services.io.newURI("http://example.org/xènia?x");
850   do_info(
851     "Bug 662981: UTF8 - comparing " + resolved.spec + " and " + expected.spec
852   );
853   Assert.ok(resolved.equals(expected));
855   gTests.forEach(function (aTest) {
856     // Check basic URI functionality
857     do_test_uri_basic(aTest);
859     if (!aTest.fail) {
860       // Try adding various #-prefixed strings to the ends of the URIs
861       gHashSuffixes.forEach(function (aSuffix) {
862         do_test_uri_with_hash_suffix(aTest, aSuffix);
863         if (!aTest.immutable) {
864           do_test_mutate_ref(aTest, aSuffix);
865         }
866       });
868       // For URIs that we couldn't mutate above due to them being immutable:
869       // Now we check that they're actually immutable.
870       if (aTest.immutable) {
871         Assert.ok(aTest.immutable);
872       }
873     }
874   });