1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
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/
20 spec: "view-source:about:blank",
21 scheme: "view-source",
22 prePath: "view-source:",
23 pathQueryRef: "about:blank",
30 spec: "view-source:http://www.mozilla.org/",
31 scheme: "view-source",
32 prePath: "view-source:",
33 pathQueryRef: "http://www.mozilla.org/",
42 prePath: "x-external:",
49 spec: "x-external:abc",
51 prePath: "x-external:",
58 spec: "http://www2.example.com/",
59 relativeURI: "a/b/c/d",
61 prePath: "http://www2.example.com",
62 pathQueryRef: "/a/b/c/d",
67 // relative URL testcases from http://greenbytes.de/tech/webdav/rfc3986.html#rfc.section.5.4
69 spec: "http://a/b/c/d;p?q",
79 spec: "http://a/b/c/d;p?q",
83 pathQueryRef: "/b/c/g",
89 spec: "http://a/b/c/d;p?q",
93 pathQueryRef: "/b/c/g",
99 spec: "http://a/b/c/d;p?q",
103 pathQueryRef: "/b/c/g/",
109 spec: "http://a/b/c/d;p?q",
119 spec: "http://a/b/c/d;p?q",
123 pathQueryRef: "/b/c/d;p?y",
129 spec: "http://a/b/c/d;p?q",
133 pathQueryRef: "/b/c/g?y",
135 specIgnoringRef: "http://a/b/c/g?y",
141 spec: "http://a/b/c/d;p?q",
145 pathQueryRef: "/b/c/d;p?q#s",
147 specIgnoringRef: "http://a/b/c/d;p?q",
153 spec: "http://a/b/c/d;p?q",
157 pathQueryRef: "/b/c/g#s",
163 spec: "http://a/b/c/d;p?q",
164 relativeURI: "g?y#s",
167 pathQueryRef: "/b/c/g?y#s",
173 Bug xxxxxx - we return a path of b/c/;x
174 { spec: "http://a/b/c/d;p?q",
178 pathQueryRef: "/b/c/d;x",
180 nsIURL: true, nsINestedURI: false },
183 spec: "http://a/b/c/d;p?q",
187 pathQueryRef: "/b/c/g;x",
193 spec: "http://a/b/c/d;p?q",
194 relativeURI: "g;x?y#s",
197 pathQueryRef: "/b/c/g;x?y#s",
203 Can't easily specify a relative URI of "" to the test code
204 { spec: "http://a/b/c/d;p?q",
208 pathQueryRef: "/b/c/d",
210 nsIURL: true, nsINestedURI: false },
213 spec: "http://a/b/c/d;p?q",
217 pathQueryRef: "/b/c/",
223 spec: "http://a/b/c/d;p?q",
227 pathQueryRef: "/b/c/",
233 spec: "http://a/b/c/d;p?q",
243 spec: "http://a/b/c/d;p?q",
253 spec: "http://a/b/c/d;p?q",
257 pathQueryRef: "/b/g",
263 spec: "http://a/b/c/d;p?q",
264 relativeURI: "../..",
273 spec: "http://a/b/c/d;p?q",
274 relativeURI: "../../",
283 spec: "http://a/b/c/d;p?q",
284 relativeURI: "../../g",
295 spec: "http://a/b/c/d;p?q",
296 relativeURI: "../../../g",
305 spec: "http://a/b/c/d;p?q",
306 relativeURI: "../../../../g",
317 spec: "http://a/b/c/d;p?q",
327 spec: "http://a/b/c/d;p?q",
328 relativeURI: "/../g",
337 spec: "http://a/b/c/d;p?q",
341 pathQueryRef: "/b/c/g.",
347 spec: "http://a/b/c/d;p?q",
351 pathQueryRef: "/b/c/.g",
357 spec: "http://a/b/c/d;p?q",
361 pathQueryRef: "/b/c/g..",
367 spec: "http://a/b/c/d;p?q",
371 pathQueryRef: "/b/c/..g",
377 spec: "http://a/b/c/d;p?q",
381 pathQueryRef: "/b/c/",
387 spec: "http://a/b/c/d;p?q",
388 relativeURI: "./../g",
391 pathQueryRef: "/b/g",
397 spec: "http://a/b/c/d;p?q",
398 relativeURI: "./g/.",
401 pathQueryRef: "/b/c/g/",
407 spec: "http://a/b/c/d;p?q",
408 relativeURI: "g/./h",
411 pathQueryRef: "/b/c/g/h",
417 spec: "http://a/b/c/d;p?q",
418 relativeURI: "g/../h",
421 pathQueryRef: "/b/c/h",
427 spec: "http://a/b/c/d;p?q",
428 relativeURI: "g;x=1/./y",
431 pathQueryRef: "/b/c/g;x=1/y",
437 spec: "http://a/b/c/d;p?q",
438 relativeURI: "g;x=1/../y",
441 pathQueryRef: "/b/c/y",
446 // protocol-relative http://tools.ietf.org/html/rfc3986#section-4.2
448 spec: "http://www2.example.com/",
449 relativeURI: "//www3.example2.com/bar",
451 prePath: "http://www3.example2.com",
452 pathQueryRef: "/bar",
458 spec: "https://www2.example.com/",
459 relativeURI: "//www3.example2.com/bar",
461 prePath: "https://www3.example2.com",
462 pathQueryRef: "/bar",
469 var gHashSuffixes = ["#", "#myRef", "#myRef?a=b", "#myRef#", "#myRef#x:yz"];
471 // TEST HELPER FUNCTIONS
472 // ---------------------
473 function do_info(text, stack) {
475 stack = Components.stack.caller;
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);
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) {
518 "(uri equalsExceptRef check: '" + aURI1.spec + "' == '" + aURI2.spec + "')"
520 aCheckTrueFunc(aURI1.equalsExceptRef(aURI2));
522 "(uri equalsExceptRef check: '" + aURI2.spec + "' == '" + aURI1.spec + "')"
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];
540 (aTestFunctor ? "modified '" : "'") +
546 Assert.equal(aURI[aPropertyName], expectedVal);
550 // Test that a given URI parses correctly into its various components.
551 function do_test_uri_basic(aTest) {
555 "Basic tests for " + aTest.spec + " relative URI: " + aTest.relativeURI
559 URI = NetUtil.newURI(aTest.spec);
561 do_info("Caught error on parse of" + aTest.spec + " Error: " + e.result);
563 Assert.equal(e.result, aTest.result);
569 if (aTest.relativeURI) {
573 relURI = Services.io.newURI(aTest.relativeURI, null, URI);
576 "Caught error on Relative parse of " +
583 if (aTest.relativeFail) {
584 Assert.equal(e.result, aTest.relativeFail);
590 "relURI.pathQueryRef = " +
591 relURI.pathQueryRef +
596 do_info("URI.pathQueryRef now = " + URI.pathQueryRef);
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);
611 " throws or returns false " +
614 // XXXdholbert At some point it'd probably be worth making this behavior
615 // (throwing vs. returning false) consistent across URI implementations.
619 isEqualToNull = URI.equals(null);
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);
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);
650 if (aTest.relativeURI) {
652 origURI = Services.io.newURI(aTest.relativeURI, null, origURI);
655 "Caught error on Relative parse of " +
665 testURI = Services.io.newURI(aSuffix, null, origURI);
668 "Caught error adding suffix to " +
680 testURI = NetUtil.newURI(aTest.spec + aSuffix);
689 "equals a clone of itself"
691 do_check_uri_eq(testURI, testURI.mutate().finalize());
696 " doesn't equal self with '" +
701 Assert.ok(!origURI.equals(testURI));
706 " is equalExceptRef to self with '" +
710 do_check_uri_eqExceptRef(origURI, testURI);
712 Assert.equal(testURI.hasRef, true);
715 // These tests fail if origURI has a ref
717 "testing cloneIgnoringRef on " +
719 " is equal to no-ref version but not equal to ref version"
721 var cloneNoRef = testURI.mutate().setRef("").finalize();
722 do_check_uri_eq(cloneNoRef, origURI);
723 Assert.ok(!cloneNoRef.equals(testURI));
726 do_check_property(aTest, testURI, "scheme");
727 do_check_property(aTest, testURI, "prePath");
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;
733 do_check_property(aTest, testURI, "ref", function (aStr) {
734 return aSuffix.substr(1);
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
751 "testing that setting .ref on " +
755 "' does what we expect"
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 #)
766 "testing that setting .ref on " +
770 "' does what we expect"
772 testURI = testURI.mutate().setRef(suffixLackingHash).finalize();
773 do_check_uri_eq(testURI, refURIWithSuffix);
774 do_check_uri_eqExceptRef(testURI, refURIWithoutSuffix);
777 // Now, clear .ref (should get us back the original spec)
779 "testing that clearing .ref on " + testURI.spec + " does what we expect"
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;
791 "testing that setting spec to " +
793 " and then clearing ref does what we expect"
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;
807 "testing that setting path to " +
809 " and then clearing ref does what we expect"
813 .setPathQueryRef(pathWithSuffix)
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();
822 "testing that clearing path from " +
826 testURI = testURI.mutate().setPathQueryRef("").finalize();
827 Assert.equal(testURI.ref, "");
832 // TEST MAIN FUNCTION
833 // ------------------
834 function run_test() {
835 // UTF-8 check - From bug 622981
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");
841 "Bug 662981: ACSII - comparing " + resolved.spec + " and " + expected.spec
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");
851 "Bug 662981: UTF8 - comparing " + resolved.spec + " and " + expected.spec
853 Assert.ok(resolved.equals(expected));
855 gTests.forEach(function (aTest) {
856 // Check basic URI functionality
857 do_test_uri_basic(aTest);
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);
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);