2021-01-11 12:13:41 -05:00
|
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
2020-09-27 06:22:32 -04:00
|
|
|
|
import { assert, assertEquals, assertThrows, unitTest } from "./test_util.ts";
|
2018-12-17 20:07:47 -05:00
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function urlParsing(): void {
|
2018-12-17 20:07:47 -05:00
|
|
|
|
const url = new URL(
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.hash, "#qat");
|
|
|
|
|
assertEquals(url.host, "baz.qat:8000");
|
|
|
|
|
assertEquals(url.hostname, "baz.qat");
|
|
|
|
|
assertEquals(
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.origin, "https://baz.qat:8000");
|
|
|
|
|
assertEquals(url.password, "bar");
|
|
|
|
|
assertEquals(url.pathname, "/qux/quux");
|
|
|
|
|
assertEquals(url.port, "8000");
|
|
|
|
|
assertEquals(url.protocol, "https:");
|
|
|
|
|
assertEquals(url.search, "?foo=bar&baz=12");
|
|
|
|
|
assertEquals(url.searchParams.getAll("foo"), ["bar"]);
|
|
|
|
|
assertEquals(url.searchParams.getAll("baz"), ["12"]);
|
|
|
|
|
assertEquals(url.username, "foo");
|
|
|
|
|
assertEquals(
|
2018-12-17 20:07:47 -05:00
|
|
|
|
String(url),
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
2020-07-10 15:51:24 -04:00
|
|
|
|
});
|
2020-06-10 14:05:10 -04:00
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
unitTest(function urlProtocolParsing(): void {
|
|
|
|
|
assertEquals(new URL("Aa+-.1://foo").protocol, "aa+-.1:");
|
|
|
|
|
assertEquals(new URL("aA+-.1://foo").protocol, "aa+-.1:");
|
|
|
|
|
assertThrows(() => new URL("1://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("+://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("-://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL(".://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("_://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("=://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("!://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL(`"://foo`), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("$://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("%://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("^://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("*://foo"), TypeError, "Invalid URL.");
|
|
|
|
|
});
|
|
|
|
|
|
2020-07-13 00:56:45 -04:00
|
|
|
|
unitTest(function urlAuthenticationParsing(): void {
|
|
|
|
|
const specialUrl = new URL("http://foo:bar@baz");
|
|
|
|
|
assertEquals(specialUrl.username, "foo");
|
|
|
|
|
assertEquals(specialUrl.password, "bar");
|
|
|
|
|
assertEquals(specialUrl.hostname, "baz");
|
|
|
|
|
assertThrows(() => new URL("file://foo:bar@baz"), TypeError, "Invalid URL.");
|
|
|
|
|
const nonSpecialUrl = new URL("abcd://foo:bar@baz");
|
|
|
|
|
assertEquals(nonSpecialUrl.username, "foo");
|
|
|
|
|
assertEquals(nonSpecialUrl.password, "bar");
|
|
|
|
|
assertEquals(nonSpecialUrl.hostname, "baz");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
unitTest(function urlHostnameParsing(): void {
|
2020-07-10 15:51:24 -04:00
|
|
|
|
// IPv6.
|
2020-07-13 00:56:45 -04:00
|
|
|
|
assertEquals(new URL("http://[::1]").hostname, "[::1]");
|
|
|
|
|
assertEquals(new URL("file://[::1]").hostname, "[::1]");
|
|
|
|
|
assertEquals(new URL("abcd://[::1]").hostname, "[::1]");
|
2020-07-16 12:08:29 -04:00
|
|
|
|
assertEquals(new URL("http://[0:f:0:0:f:f:0:0]").hostname, "[0:f::f:f:0:0]");
|
|
|
|
|
assertEquals(new URL("http://[0:0:5:6:7:8]").hostname, "[::5:6:7:8]");
|
2020-07-10 15:51:24 -04:00
|
|
|
|
|
|
|
|
|
// Forbidden host code point.
|
2020-07-13 00:56:45 -04:00
|
|
|
|
assertThrows(() => new URL("http:// a"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("file:// a"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("abcd:// a"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("http://%"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("file://%"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("abcd://%").hostname, "%");
|
2020-07-10 15:51:24 -04:00
|
|
|
|
|
|
|
|
|
// Percent-decode.
|
2020-07-13 00:56:45 -04:00
|
|
|
|
assertEquals(new URL("http://%21").hostname, "!");
|
|
|
|
|
assertEquals(new URL("file://%21").hostname, "!");
|
|
|
|
|
assertEquals(new URL("abcd://%21").hostname, "%21");
|
|
|
|
|
|
|
|
|
|
// IPv4 parsing.
|
|
|
|
|
assertEquals(new URL("http://260").hostname, "0.0.1.4");
|
|
|
|
|
assertEquals(new URL("file://260").hostname, "0.0.1.4");
|
|
|
|
|
assertEquals(new URL("abcd://260").hostname, "260");
|
|
|
|
|
assertEquals(new URL("http://255.0.0.0").hostname, "255.0.0.0");
|
|
|
|
|
assertThrows(() => new URL("http://256.0.0.0"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("http://0.255.0.0").hostname, "0.255.0.0");
|
|
|
|
|
assertThrows(() => new URL("http://0.256.0.0"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("http://0.0.255.0").hostname, "0.0.255.0");
|
|
|
|
|
assertThrows(() => new URL("http://0.0.256.0"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("http://0.0.0.255").hostname, "0.0.0.255");
|
|
|
|
|
assertThrows(() => new URL("http://0.0.0.256"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("http://0.0.65535").hostname, "0.0.255.255");
|
|
|
|
|
assertThrows(() => new URL("http://0.0.65536"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("http://0.16777215").hostname, "0.255.255.255");
|
|
|
|
|
assertThrows(() => new URL("http://0.16777216"), TypeError, "Invalid URL.");
|
|
|
|
|
assertEquals(new URL("http://4294967295").hostname, "255.255.255.255");
|
|
|
|
|
assertThrows(() => new URL("http://4294967296"), TypeError, "Invalid URL.");
|
|
|
|
|
});
|
2020-07-10 15:51:24 -04:00
|
|
|
|
|
2020-07-13 00:56:45 -04:00
|
|
|
|
unitTest(function urlPortParsing(): void {
|
|
|
|
|
const specialUrl = new URL("http://foo:8000");
|
|
|
|
|
assertEquals(specialUrl.hostname, "foo");
|
|
|
|
|
assertEquals(specialUrl.port, "8000");
|
|
|
|
|
assertThrows(() => new URL("file://foo:8000"), TypeError, "Invalid URL.");
|
|
|
|
|
const nonSpecialUrl = new URL("abcd://foo:8000");
|
|
|
|
|
assertEquals(nonSpecialUrl.hostname, "foo");
|
|
|
|
|
assertEquals(nonSpecialUrl.port, "8000");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function urlModifications(): void {
|
2018-12-17 20:07:47 -05:00
|
|
|
|
const url = new URL(
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
|
|
|
|
url.hash = "";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12",
|
2019-03-06 20:48:46 -05:00
|
|
|
|
);
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.host = "qat.baz:8080";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@qat.baz:8080/qux/quux?foo=bar&baz=12",
|
2019-03-06 20:48:46 -05:00
|
|
|
|
);
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.hostname = "foo.bar";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@foo.bar:8080/qux/quux?foo=bar&baz=12",
|
2019-03-06 20:48:46 -05:00
|
|
|
|
);
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.password = "qux";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:qux@foo.bar:8080/qux/quux?foo=bar&baz=12",
|
2019-03-06 20:48:46 -05:00
|
|
|
|
);
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.pathname = "/foo/bar%qat";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:qux@foo.bar:8080/foo/bar%qat?foo=bar&baz=12",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
|
|
|
|
url.port = "";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.href, "https://foo:qux@foo.bar/foo/bar%qat?foo=bar&baz=12");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.protocol = "http:";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.href, "http://foo:qux@foo.bar/foo/bar%qat?foo=bar&baz=12");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.search = "?foo=bar&foo=baz";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.href, "http://foo:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz");
|
|
|
|
|
assertEquals(url.searchParams.getAll("foo"), ["bar", "baz"]);
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.username = "foo@bar";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
|
|
|
|
url.searchParams.set("bar", "qat");
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz&bar=qat",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
|
|
|
|
url.searchParams.delete("foo");
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.href, "http://foo%40bar:qux@foo.bar/foo/bar%qat?bar=qat");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.searchParams.append("foo", "bar");
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"http://foo%40bar:qux@foo.bar/foo/bar%qat?bar=qat&foo=bar",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function urlModifyHref(): void {
|
2018-12-17 20:07:47 -05:00
|
|
|
|
const url = new URL("http://example.com/");
|
|
|
|
|
url.href = "https://foo:bar@example.com:8080/baz/qat#qux";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.protocol, "https:");
|
|
|
|
|
assertEquals(url.username, "foo");
|
|
|
|
|
assertEquals(url.password, "bar");
|
|
|
|
|
assertEquals(url.host, "example.com:8080");
|
|
|
|
|
assertEquals(url.hostname, "example.com");
|
|
|
|
|
assertEquals(url.pathname, "/baz/qat");
|
|
|
|
|
assertEquals(url.hash, "#qux");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
});
|
|
|
|
|
|
2020-03-28 13:03:49 -04:00
|
|
|
|
unitTest(function urlNormalize(): void {
|
|
|
|
|
const url = new URL("http://example.com");
|
|
|
|
|
assertEquals(url.pathname, "/");
|
|
|
|
|
assertEquals(url.href, "http://example.com/");
|
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function urlModifyPathname(): void {
|
2018-12-17 20:07:47 -05:00
|
|
|
|
const url = new URL("http://foo.bar/baz%qat/qux%quux");
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.pathname, "/baz%qat/qux%quux");
|
2020-08-26 15:01:03 -04:00
|
|
|
|
// Self-assignment is to invoke the setter.
|
|
|
|
|
// deno-lint-ignore no-self-assign
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.pathname = url.pathname;
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.pathname, "/baz%qat/qux%quux");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.pathname = "baz#qat qux";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.pathname, "/baz%23qat%20qux");
|
2020-08-26 15:01:03 -04:00
|
|
|
|
// deno-lint-ignore no-self-assign
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.pathname = url.pathname;
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.pathname, "/baz%23qat%20qux");
|
2020-10-13 11:16:10 -04:00
|
|
|
|
url.pathname = "\\a\\b\\c";
|
|
|
|
|
assertEquals(url.pathname, "/a/b/c");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function urlModifyHash(): void {
|
2018-12-17 20:07:47 -05:00
|
|
|
|
const url = new URL("http://foo.bar");
|
|
|
|
|
url.hash = "%foo bar/qat%qux#bar";
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.hash, "#%foo%20bar/qat%qux#bar");
|
2020-08-26 15:01:03 -04:00
|
|
|
|
// deno-lint-ignore no-self-assign
|
2018-12-17 20:07:47 -05:00
|
|
|
|
url.hash = url.hash;
|
2019-03-06 20:48:46 -05:00
|
|
|
|
assertEquals(url.hash, "#%foo%20bar/qat%qux#bar");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function urlSearchParamsReuse(): void {
|
2018-12-17 20:07:47 -05:00
|
|
|
|
const url = new URL(
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat",
|
2018-12-17 20:07:47 -05:00
|
|
|
|
);
|
|
|
|
|
const sp = url.searchParams;
|
|
|
|
|
url.host = "baz.qat";
|
|
|
|
|
assert(sp === url.searchParams, "Search params should be reused.");
|
|
|
|
|
});
|
|
|
|
|
|
2020-05-04 14:32:54 -04:00
|
|
|
|
unitTest(function urlBackSlashes(): void {
|
|
|
|
|
const url = new URL(
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https:\\\\foo:bar@baz.qat:8000\\qux\\quux?foo=bar&baz=12#qat",
|
2020-05-04 14:32:54 -04:00
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
url.href,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat",
|
2020-05-04 14:32:54 -04:00
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
unitTest(function urlProtocolSlashes(): void {
|
|
|
|
|
assertEquals(new URL("http:foo").href, "http://foo/");
|
|
|
|
|
assertEquals(new URL("http://foo").href, "http://foo/");
|
|
|
|
|
assertEquals(new URL("file:foo").href, "file:///foo");
|
|
|
|
|
assertEquals(new URL("file://foo").href, "file://foo/");
|
|
|
|
|
assertEquals(new URL("abcd:foo").href, "abcd:foo");
|
|
|
|
|
assertEquals(new URL("abcd://foo").href, "abcd://foo");
|
|
|
|
|
});
|
|
|
|
|
|
2020-05-04 14:32:54 -04:00
|
|
|
|
unitTest(function urlRequireHost(): void {
|
|
|
|
|
assertEquals(new URL("file:///").href, "file:///");
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertThrows(() => new URL("ftp:///"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("http:///"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("https:///"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("ws:///"), TypeError, "Invalid URL.");
|
|
|
|
|
assertThrows(() => new URL("wss:///"), TypeError, "Invalid URL.");
|
2020-05-04 14:32:54 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
unitTest(function urlDriveLetter() {
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("file:///C:").href, "file:///C:");
|
|
|
|
|
assertEquals(new URL("file:///C:/").href, "file:///C:/");
|
|
|
|
|
assertEquals(new URL("file:///C:/..").href, "file:///C:/");
|
|
|
|
|
// Don't recognise drive letters with extra leading slashes.
|
|
|
|
|
assertEquals(new URL("file:////C:/..").href, "file:///");
|
|
|
|
|
// Drop the hostname if a drive letter is parsed.
|
|
|
|
|
assertEquals(new URL("file://foo/C:").href, "file:///C:");
|
|
|
|
|
// Don't recognise drive letters in non-file protocols.
|
|
|
|
|
assertEquals(new URL("http://foo/C:/..").href, "http://foo/");
|
|
|
|
|
assertEquals(new URL("abcd://foo/C:/..").href, "abcd://foo/");
|
2020-06-26 08:34:17 -04:00
|
|
|
|
});
|
|
|
|
|
|
2020-05-18 09:47:45 -04:00
|
|
|
|
unitTest(function urlHostnameUpperCase() {
|
2020-07-13 00:56:45 -04:00
|
|
|
|
assertEquals(new URL("http://EXAMPLE.COM").href, "http://example.com/");
|
|
|
|
|
assertEquals(new URL("abcd://EXAMPLE.COM").href, "abcd://EXAMPLE.COM");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
unitTest(function urlEmptyPath() {
|
|
|
|
|
assertEquals(new URL("http://foo").pathname, "/");
|
|
|
|
|
assertEquals(new URL("file://foo").pathname, "/");
|
|
|
|
|
assertEquals(new URL("abcd://foo").pathname, "");
|
2020-05-18 09:47:45 -04:00
|
|
|
|
});
|
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
unitTest(function urlPathRepeatedSlashes() {
|
|
|
|
|
assertEquals(new URL("http://foo//bar//").pathname, "//bar//");
|
|
|
|
|
assertEquals(new URL("file://foo///bar//").pathname, "/bar//");
|
|
|
|
|
assertEquals(new URL("abcd://foo//bar//").pathname, "//bar//");
|
|
|
|
|
});
|
|
|
|
|
|
2020-05-18 09:47:45 -04:00
|
|
|
|
unitTest(function urlTrim() {
|
2020-07-13 00:56:45 -04:00
|
|
|
|
assertEquals(new URL(" http://example.com ").href, "http://example.com/");
|
2020-05-18 09:47:45 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
unitTest(function urlEncoding() {
|
|
|
|
|
assertEquals(
|
2020-08-21 22:35:34 -04:00
|
|
|
|
new URL("http://a !$&*()=,;+'\"@example.com").username,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"a%20!$&*()%3D,%3B+%27%22",
|
2020-05-18 09:47:45 -04:00
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
2020-08-21 22:35:34 -04:00
|
|
|
|
new URL("http://:a !$&*()=,;+'\"@example.com").password,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"a%20!$&*()%3D,%3B+%27%22",
|
2020-05-18 09:47:45 -04:00
|
|
|
|
);
|
2020-07-10 15:51:24 -04:00
|
|
|
|
// https://url.spec.whatwg.org/#idna
|
2020-08-21 22:35:34 -04:00
|
|
|
|
assertEquals(new URL("http://mañana/c?d#e").hostname, "xn--maana-pta");
|
|
|
|
|
assertEquals(new URL("abcd://mañana/c?d#e").hostname, "ma%C3%B1ana");
|
2020-05-18 09:47:45 -04:00
|
|
|
|
assertEquals(
|
2020-08-21 22:35:34 -04:00
|
|
|
|
new URL("http://example.com/a ~!@$&*()=:/,;+'\"\\").pathname,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"/a%20~!@$&*()=:/,;+'%22/",
|
2020-05-18 09:47:45 -04:00
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
2020-08-21 22:35:34 -04:00
|
|
|
|
new URL("http://example.com?a ~!@$&*()=:/,;?+'\"\\").search,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"?a%20~!@$&*()=:/,;?+%27%22\\",
|
2020-05-18 09:47:45 -04:00
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
2020-08-21 22:35:34 -04:00
|
|
|
|
new URL("abcd://example.com?a ~!@$&*()=:/,;?+'\"\\").search,
|
|
|
|
|
"?a%20~!@$&*()=:/,;?+'%22\\",
|
|
|
|
|
);
|
|
|
|
|
assertEquals(
|
|
|
|
|
new URL("http://example.com#a ~!@#$&*()=:/,;?+'\"\\").hash,
|
2020-07-14 15:24:17 -04:00
|
|
|
|
"#a%20~!@#$&*()=:/,;?+'%22\\",
|
2020-05-18 09:47:45 -04:00
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
unitTest(function urlBase(): void {
|
|
|
|
|
assertEquals(new URL("d", new URL("http://foo/a?b#c")).href, "http://foo/d");
|
2020-07-13 00:53:36 -04:00
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("", "http://foo/a/b?c#d").href, "http://foo/a/b?c");
|
|
|
|
|
assertEquals(new URL("", "file://foo/a/b?c#d").href, "file://foo/a/b?c");
|
|
|
|
|
assertEquals(new URL("", "abcd://foo/a/b?c#d").href, "abcd://foo/a/b?c");
|
2020-07-13 00:53:36 -04:00
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("#e", "http://foo/a/b?c#d").href, "http://foo/a/b?c#e");
|
|
|
|
|
assertEquals(new URL("#e", "file://foo/a/b?c#d").href, "file://foo/a/b?c#e");
|
|
|
|
|
assertEquals(new URL("#e", "abcd://foo/a/b?c#d").href, "abcd://foo/a/b?c#e");
|
2020-07-13 00:53:36 -04:00
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("?e", "http://foo/a/b?c#d").href, "http://foo/a/b?e");
|
|
|
|
|
assertEquals(new URL("?e", "file://foo/a/b?c#d").href, "file://foo/a/b?e");
|
|
|
|
|
assertEquals(new URL("?e", "abcd://foo/a/b?c#d").href, "abcd://foo/a/b?e");
|
2018-12-17 20:07:47 -05:00
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("e", "http://foo/a/b?c#d").href, "http://foo/a/e");
|
|
|
|
|
assertEquals(new URL("e", "file://foo/a/b?c#d").href, "file://foo/a/e");
|
|
|
|
|
assertEquals(new URL("e", "abcd://foo/a/b?c#d").href, "abcd://foo/a/e");
|
|
|
|
|
|
|
|
|
|
assertEquals(new URL(".", "http://foo/a/b?c#d").href, "http://foo/a/");
|
|
|
|
|
assertEquals(new URL(".", "file://foo/a/b?c#d").href, "file://foo/a/");
|
|
|
|
|
assertEquals(new URL(".", "abcd://foo/a/b?c#d").href, "abcd://foo/a/");
|
|
|
|
|
|
|
|
|
|
assertEquals(new URL("..", "http://foo/a/b?c#d").href, "http://foo/");
|
|
|
|
|
assertEquals(new URL("..", "file://foo/a/b?c#d").href, "file://foo/");
|
|
|
|
|
assertEquals(new URL("..", "abcd://foo/a/b?c#d").href, "abcd://foo/");
|
2019-04-29 19:45:20 -04:00
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("/e", "http://foo/a/b?c#d").href, "http://foo/e");
|
|
|
|
|
assertEquals(new URL("/e", "file://foo/a/b?c#d").href, "file://foo/e");
|
|
|
|
|
assertEquals(new URL("/e", "abcd://foo/a/b?c#d").href, "abcd://foo/e");
|
|
|
|
|
|
|
|
|
|
assertEquals(new URL("//bar", "http://foo/a/b?c#d").href, "http://bar/");
|
|
|
|
|
assertEquals(new URL("//bar", "file://foo/a/b?c#d").href, "file://bar/");
|
|
|
|
|
assertEquals(new URL("//bar", "abcd://foo/a/b?c#d").href, "abcd://bar");
|
|
|
|
|
|
|
|
|
|
assertEquals(new URL("efgh:", "http://foo/a/b?c#d").href, "efgh:");
|
|
|
|
|
assertEquals(new URL("efgh:", "file://foo/a/b?c#d").href, "efgh:");
|
|
|
|
|
assertEquals(new URL("efgh:", "abcd://foo/a/b?c#d").href, "efgh:");
|
2020-08-29 04:12:10 -04:00
|
|
|
|
|
|
|
|
|
assertEquals(new URL("/foo", "abcd:/").href, "abcd:/foo");
|
2019-09-05 20:01:27 -04:00
|
|
|
|
});
|
|
|
|
|
|
2020-05-04 14:32:54 -04:00
|
|
|
|
unitTest(function urlDriveLetterBase() {
|
2020-07-23 21:37:11 -04:00
|
|
|
|
assertEquals(new URL("/b", "file:///C:/a/b").href, "file:///C:/b");
|
|
|
|
|
assertEquals(new URL("/D:", "file:///C:/a/b").href, "file:///D:");
|
2020-05-04 14:32:54 -04:00
|
|
|
|
});
|
|
|
|
|
|
2020-07-23 21:37:11 -04:00
|
|
|
|
unitTest(function urlSameProtocolBase() {
|
|
|
|
|
assertEquals(new URL("http:", "http://foo/a").href, "http://foo/a");
|
|
|
|
|
assertEquals(new URL("file:", "file://foo/a").href, "file://foo/a");
|
|
|
|
|
assertEquals(new URL("abcd:", "abcd://foo/a").href, "abcd:");
|
|
|
|
|
|
|
|
|
|
assertEquals(new URL("http:b", "http://foo/a").href, "http://foo/b");
|
|
|
|
|
assertEquals(new URL("file:b", "file://foo/a").href, "file://foo/b");
|
|
|
|
|
assertEquals(new URL("abcd:b", "abcd://foo/a").href, "abcd:b");
|
2019-09-11 16:20:54 -04:00
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function deletingAllParamsRemovesQuestionMarkFromURL(): void {
|
2019-04-29 19:45:20 -04:00
|
|
|
|
const url = new URL("http://example.com/?param1¶m2");
|
|
|
|
|
url.searchParams.delete("param1");
|
|
|
|
|
url.searchParams.delete("param2");
|
|
|
|
|
assertEquals(url.href, "http://example.com/");
|
|
|
|
|
assertEquals(url.search, "");
|
|
|
|
|
});
|
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function removingNonExistentParamRemovesQuestionMarkFromURL(): void {
|
2019-04-29 19:45:20 -04:00
|
|
|
|
const url = new URL("http://example.com/?");
|
|
|
|
|
assertEquals(url.href, "http://example.com/?");
|
|
|
|
|
url.searchParams.delete("param1");
|
|
|
|
|
assertEquals(url.href, "http://example.com/");
|
|
|
|
|
assertEquals(url.search, "");
|
|
|
|
|
});
|
2019-06-10 23:55:38 -04:00
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function sortingNonExistentParamRemovesQuestionMarkFromURL(): void {
|
2019-06-10 23:55:38 -04:00
|
|
|
|
const url = new URL("http://example.com/?");
|
|
|
|
|
assertEquals(url.href, "http://example.com/?");
|
|
|
|
|
url.searchParams.sort();
|
|
|
|
|
assertEquals(url.href, "http://example.com/");
|
|
|
|
|
assertEquals(url.search, "");
|
|
|
|
|
});
|
2019-10-31 14:55:54 -04:00
|
|
|
|
|
2021-01-29 08:08:22 -05:00
|
|
|
|
unitTest(function customInspectFunction(): void {
|
|
|
|
|
const url = new URL("http://example.com/?");
|
|
|
|
|
assertEquals(
|
|
|
|
|
Deno.inspect(url),
|
|
|
|
|
`URL {
|
|
|
|
|
href: "http://example.com/?",
|
|
|
|
|
origin: "http://example.com",
|
|
|
|
|
protocol: "http:",
|
|
|
|
|
username: "",
|
|
|
|
|
password: "",
|
|
|
|
|
host: "example.com",
|
|
|
|
|
hostname: "example.com",
|
|
|
|
|
port: "",
|
|
|
|
|
pathname: "/",
|
|
|
|
|
hash: "",
|
|
|
|
|
search: "?"
|
|
|
|
|
}`,
|
|
|
|
|
);
|
|
|
|
|
});
|
2019-11-12 13:45:48 -05:00
|
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
|
unitTest(function protocolNotHttpOrFile() {
|
2019-11-12 13:45:48 -05:00
|
|
|
|
const url = new URL("about:blank");
|
|
|
|
|
assertEquals(url.href, "about:blank");
|
|
|
|
|
assertEquals(url.protocol, "about:");
|
|
|
|
|
assertEquals(url.origin, "null");
|
|
|
|
|
});
|
|
|
|
|
|
2020-04-28 01:23:06 -04:00
|
|
|
|
unitTest(function throwForInvalidPortConstructor(): void {
|
|
|
|
|
const urls = [
|
|
|
|
|
// If port is greater than 2^16 − 1, validation error, return failure.
|
|
|
|
|
`https://baz.qat:${2 ** 16}`,
|
|
|
|
|
"https://baz.qat:-32",
|
|
|
|
|
"https://baz.qat:deno",
|
2020-04-28 10:40:17 -04:00
|
|
|
|
"https://baz.qat:9land",
|
|
|
|
|
"https://baz.qat:10.5",
|
2020-04-28 01:23:06 -04:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const url of urls) {
|
2020-05-04 10:06:47 -04:00
|
|
|
|
assertThrows(() => new URL(url), TypeError, "Invalid URL.");
|
2020-04-28 01:23:06 -04:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 10:40:17 -04:00
|
|
|
|
// Do not throw for 0 & 65535
|
|
|
|
|
new URL("https://baz.qat:65535");
|
|
|
|
|
new URL("https://baz.qat:0");
|
2020-04-28 01:23:06 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
unitTest(function doNotOverridePortIfInvalid(): void {
|
|
|
|
|
const initialPort = "3000";
|
|
|
|
|
const ports = [
|
|
|
|
|
// If port is greater than 2^16 − 1, validation error, return failure.
|
|
|
|
|
`${2 ** 16}`,
|
|
|
|
|
"-32",
|
|
|
|
|
"deno",
|
2020-04-28 10:40:17 -04:00
|
|
|
|
"9land",
|
|
|
|
|
"10.5",
|
2020-04-28 01:23:06 -04:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const port of ports) {
|
|
|
|
|
const url = new URL(`https://deno.land:${initialPort}`);
|
|
|
|
|
url.port = port;
|
|
|
|
|
assertEquals(url.port, initialPort);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
unitTest(function emptyPortForSchemeDefaultPort(): void {
|
|
|
|
|
const nonDefaultPort = "3500";
|
|
|
|
|
const urls = [
|
|
|
|
|
{ url: "ftp://baz.qat:21", port: "21", protocol: "ftp:" },
|
|
|
|
|
{ url: "https://baz.qat:443", port: "443", protocol: "https:" },
|
|
|
|
|
{ url: "wss://baz.qat:443", port: "443", protocol: "wss:" },
|
|
|
|
|
{ url: "http://baz.qat:80", port: "80", protocol: "http:" },
|
|
|
|
|
{ url: "ws://baz.qat:80", port: "80", protocol: "ws:" },
|
|
|
|
|
{ url: "file://home/index.html", port: "", protocol: "file:" },
|
|
|
|
|
{ url: "/foo", baseUrl: "ftp://baz.qat:21", port: "21", protocol: "ftp:" },
|
|
|
|
|
{
|
|
|
|
|
url: "/foo",
|
|
|
|
|
baseUrl: "https://baz.qat:443",
|
|
|
|
|
port: "443",
|
|
|
|
|
protocol: "https:",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
url: "/foo",
|
|
|
|
|
baseUrl: "wss://baz.qat:443",
|
|
|
|
|
port: "443",
|
|
|
|
|
protocol: "wss:",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
url: "/foo",
|
|
|
|
|
baseUrl: "http://baz.qat:80",
|
|
|
|
|
port: "80",
|
|
|
|
|
protocol: "http:",
|
|
|
|
|
},
|
|
|
|
|
{ url: "/foo", baseUrl: "ws://baz.qat:80", port: "80", protocol: "ws:" },
|
|
|
|
|
{
|
|
|
|
|
url: "/foo",
|
|
|
|
|
baseUrl: "file://home/index.html",
|
|
|
|
|
port: "",
|
|
|
|
|
protocol: "file:",
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const { url: urlString, baseUrl, port, protocol } of urls) {
|
|
|
|
|
const url = new URL(urlString, baseUrl);
|
|
|
|
|
assertEquals(url.port, "");
|
|
|
|
|
|
|
|
|
|
url.port = nonDefaultPort;
|
|
|
|
|
assertEquals(url.port, nonDefaultPort);
|
|
|
|
|
|
|
|
|
|
url.port = port;
|
|
|
|
|
assertEquals(url.port, "");
|
|
|
|
|
|
|
|
|
|
// change scheme
|
|
|
|
|
url.protocol = "sftp:";
|
|
|
|
|
assertEquals(url.port, port);
|
|
|
|
|
|
|
|
|
|
url.protocol = protocol;
|
|
|
|
|
assertEquals(url.port, "");
|
|
|
|
|
}
|
|
|
|
|
});
|