summaryrefslogtreecommitdiff
path: root/cli/tests/node_compat/test/parallel/test-url-parse-format.js
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2023-02-21 00:35:04 +0900
committerGitHub <noreply@github.com>2023-02-20 16:35:04 +0100
commit6915a9b7a701dde0e1078867961c9a91811c1850 (patch)
treee6822f2b8400c7c7941d3cb9ace59842389b5bc9 /cli/tests/node_compat/test/parallel/test-url-parse-format.js
parenta1cd2a5915c13f6a9b8eafa3807e143a02616bc1 (diff)
test(ext/node): more node compat tests (#17827)
This PR adds the remaining ~650 Node.js compat test cases from std/node. Among these 650 cases, about 130 cases are now failing. These failing cases are prefixed with `TODO:` in `tests/node_compat/config.json`. These will be addressed in later PRs.
Diffstat (limited to 'cli/tests/node_compat/test/parallel/test-url-parse-format.js')
-rw-r--r--cli/tests/node_compat/test/parallel/test-url-parse-format.js1053
1 files changed, 1053 insertions, 0 deletions
diff --git a/cli/tests/node_compat/test/parallel/test-url-parse-format.js b/cli/tests/node_compat/test/parallel/test-url-parse-format.js
new file mode 100644
index 000000000..7079857bd
--- /dev/null
+++ b/cli/tests/node_compat/test/parallel/test-url-parse-format.js
@@ -0,0 +1,1053 @@
+// deno-fmt-ignore-file
+// deno-lint-ignore-file
+
+// Copyright Joyent and Node contributors. All rights reserved. MIT license.
+// Taken from Node 18.12.1
+// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually
+
+'use strict';
+const common = require('../common');
+
+if (!common.hasIntl)
+ common.skip('missing Intl');
+
+const assert = require('assert');
+const inspect = require('util').inspect;
+
+const url = require('url');
+
+// URLs to parse, and expected data
+// { url : parsed }
+const parseTests = {
+ '//some_path': {
+ href: '//some_path',
+ pathname: '//some_path',
+ path: '//some_path'
+ },
+
+ 'http:\\\\evil-phisher\\foo.html#h\\a\\s\\h': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'evil-phisher',
+ hostname: 'evil-phisher',
+ pathname: '/foo.html',
+ path: '/foo.html',
+ hash: '#h%5Ca%5Cs%5Ch',
+ href: 'http://evil-phisher/foo.html#h%5Ca%5Cs%5Ch'
+ },
+
+ 'http:\\\\evil-phisher\\foo.html?json="\\"foo\\""#h\\a\\s\\h': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'evil-phisher',
+ hostname: 'evil-phisher',
+ pathname: '/foo.html',
+ search: '?json=%22%5C%22foo%5C%22%22',
+ query: 'json=%22%5C%22foo%5C%22%22',
+ path: '/foo.html?json=%22%5C%22foo%5C%22%22',
+ hash: '#h%5Ca%5Cs%5Ch',
+ href: 'http://evil-phisher/foo.html?json=%22%5C%22foo%5C%22%22#h%5Ca%5Cs%5Ch'
+ },
+
+ 'http:\\\\evil-phisher\\foo.html#h\\a\\s\\h?blarg': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'evil-phisher',
+ hostname: 'evil-phisher',
+ pathname: '/foo.html',
+ path: '/foo.html',
+ hash: '#h%5Ca%5Cs%5Ch?blarg',
+ href: 'http://evil-phisher/foo.html#h%5Ca%5Cs%5Ch?blarg'
+ },
+
+
+ 'http:\\\\evil-phisher\\foo.html': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'evil-phisher',
+ hostname: 'evil-phisher',
+ pathname: '/foo.html',
+ path: '/foo.html',
+ href: 'http://evil-phisher/foo.html'
+ },
+
+ 'HTTP://www.example.com/': {
+ href: 'http://www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'HTTP://www.example.com': {
+ href: 'http://www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://www.ExAmPlE.com/': {
+ href: 'http://www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://user:pw@www.ExAmPlE.com/': {
+ href: 'http://user:pw@www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:pw',
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://USER:PW@www.ExAmPlE.com/': {
+ href: 'http://USER:PW@www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ auth: 'USER:PW',
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://user@www.example.com/': {
+ href: 'http://user@www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user',
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://user%3Apw@www.example.com/': {
+ href: 'http://user:pw@www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:pw',
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://x.com/path?that\'s#all, folks': {
+ href: 'http://x.com/path?that%27s#all,%20folks',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x.com',
+ hostname: 'x.com',
+ search: '?that%27s',
+ query: 'that%27s',
+ pathname: '/path',
+ hash: '#all,%20folks',
+ path: '/path?that%27s'
+ },
+
+ 'HTTP://X.COM/Y': {
+ href: 'http://x.com/Y',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x.com',
+ hostname: 'x.com',
+ pathname: '/Y',
+ path: '/Y'
+ },
+
+ // Whitespace in the front
+ ' http://www.example.com/': {
+ href: 'http://www.example.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.example.com',
+ hostname: 'www.example.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ // + not an invalid host character
+ // per https://url.spec.whatwg.org/#host-parsing
+ 'http://x.y.com+a/b/c': {
+ href: 'http://x.y.com+a/b/c',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x.y.com+a',
+ hostname: 'x.y.com+a',
+ pathname: '/b/c',
+ path: '/b/c'
+ },
+
+ // An unexpected invalid char in the hostname.
+ 'HtTp://x.y.cOm;a/b/c?d=e#f g<h>i': {
+ href: 'http://x.y.com/;a/b/c?d=e#f%20g%3Ch%3Ei',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x.y.com',
+ hostname: 'x.y.com',
+ pathname: ';a/b/c',
+ search: '?d=e',
+ query: 'd=e',
+ hash: '#f%20g%3Ch%3Ei',
+ path: ';a/b/c?d=e'
+ },
+
+ // Make sure that we don't accidentally lcast the path parts.
+ 'HtTp://x.y.cOm;A/b/c?d=e#f g<h>i': {
+ href: 'http://x.y.com/;A/b/c?d=e#f%20g%3Ch%3Ei',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x.y.com',
+ hostname: 'x.y.com',
+ pathname: ';A/b/c',
+ search: '?d=e',
+ query: 'd=e',
+ hash: '#f%20g%3Ch%3Ei',
+ path: ';A/b/c?d=e'
+ },
+
+ 'http://x...y...#p': {
+ href: 'http://x...y.../#p',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x...y...',
+ hostname: 'x...y...',
+ hash: '#p',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://x/p/"quoted"': {
+ href: 'http://x/p/%22quoted%22',
+ protocol: 'http:',
+ slashes: true,
+ host: 'x',
+ hostname: 'x',
+ pathname: '/p/%22quoted%22',
+ path: '/p/%22quoted%22'
+ },
+
+ '<http://goo.corn/bread> Is a URL!': {
+ href: '%3Chttp://goo.corn/bread%3E%20Is%20a%20URL!',
+ pathname: '%3Chttp://goo.corn/bread%3E%20Is%20a%20URL!',
+ path: '%3Chttp://goo.corn/bread%3E%20Is%20a%20URL!'
+ },
+
+ 'http://www.narwhaljs.org/blog/categories?id=news': {
+ href: 'http://www.narwhaljs.org/blog/categories?id=news',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.narwhaljs.org',
+ hostname: 'www.narwhaljs.org',
+ search: '?id=news',
+ query: 'id=news',
+ pathname: '/blog/categories',
+ path: '/blog/categories?id=news'
+ },
+
+ 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=': {
+ href: 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=',
+ protocol: 'http:',
+ slashes: true,
+ host: 'mt0.google.com',
+ hostname: 'mt0.google.com',
+ pathname: '/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=',
+ path: '/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s='
+ },
+
+ 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=': {
+ href: 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api' +
+ '&x=2&y=2&z=3&s=',
+ protocol: 'http:',
+ slashes: true,
+ host: 'mt0.google.com',
+ hostname: 'mt0.google.com',
+ search: '???&hl=en&src=api&x=2&y=2&z=3&s=',
+ query: '??&hl=en&src=api&x=2&y=2&z=3&s=',
+ pathname: '/vt/lyrs=m@114',
+ path: '/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s='
+ },
+
+ 'http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=': {
+ href: 'http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=',
+ protocol: 'http:',
+ slashes: true,
+ host: 'mt0.google.com',
+ auth: 'user:pass',
+ hostname: 'mt0.google.com',
+ search: '???&hl=en&src=api&x=2&y=2&z=3&s=',
+ query: '??&hl=en&src=api&x=2&y=2&z=3&s=',
+ pathname: '/vt/lyrs=m@114',
+ path: '/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s='
+ },
+
+ 'file:///etc/passwd': {
+ href: 'file:///etc/passwd',
+ slashes: true,
+ protocol: 'file:',
+ pathname: '/etc/passwd',
+ hostname: '',
+ host: '',
+ path: '/etc/passwd'
+ },
+
+ 'file://localhost/etc/passwd': {
+ href: 'file://localhost/etc/passwd',
+ protocol: 'file:',
+ slashes: true,
+ pathname: '/etc/passwd',
+ hostname: 'localhost',
+ host: 'localhost',
+ path: '/etc/passwd'
+ },
+
+ 'file://foo/etc/passwd': {
+ href: 'file://foo/etc/passwd',
+ protocol: 'file:',
+ slashes: true,
+ pathname: '/etc/passwd',
+ hostname: 'foo',
+ host: 'foo',
+ path: '/etc/passwd'
+ },
+
+ 'file:///etc/node/': {
+ href: 'file:///etc/node/',
+ slashes: true,
+ protocol: 'file:',
+ pathname: '/etc/node/',
+ hostname: '',
+ host: '',
+ path: '/etc/node/'
+ },
+
+ 'file://localhost/etc/node/': {
+ href: 'file://localhost/etc/node/',
+ protocol: 'file:',
+ slashes: true,
+ pathname: '/etc/node/',
+ hostname: 'localhost',
+ host: 'localhost',
+ path: '/etc/node/'
+ },
+
+ 'file://foo/etc/node/': {
+ href: 'file://foo/etc/node/',
+ protocol: 'file:',
+ slashes: true,
+ pathname: '/etc/node/',
+ hostname: 'foo',
+ host: 'foo',
+ path: '/etc/node/'
+ },
+
+ 'http:/baz/../foo/bar': {
+ href: 'http:/baz/../foo/bar',
+ protocol: 'http:',
+ pathname: '/baz/../foo/bar',
+ path: '/baz/../foo/bar'
+ },
+
+ 'http://user:pass@example.com:8000/foo/bar?baz=quux#frag': {
+ href: 'http://user:pass@example.com:8000/foo/bar?baz=quux#frag',
+ protocol: 'http:',
+ slashes: true,
+ host: 'example.com:8000',
+ auth: 'user:pass',
+ port: '8000',
+ hostname: 'example.com',
+ hash: '#frag',
+ search: '?baz=quux',
+ query: 'baz=quux',
+ pathname: '/foo/bar',
+ path: '/foo/bar?baz=quux'
+ },
+
+ '//user:pass@example.com:8000/foo/bar?baz=quux#frag': {
+ href: '//user:pass@example.com:8000/foo/bar?baz=quux#frag',
+ slashes: true,
+ host: 'example.com:8000',
+ auth: 'user:pass',
+ port: '8000',
+ hostname: 'example.com',
+ hash: '#frag',
+ search: '?baz=quux',
+ query: 'baz=quux',
+ pathname: '/foo/bar',
+ path: '/foo/bar?baz=quux'
+ },
+
+ '/foo/bar?baz=quux#frag': {
+ href: '/foo/bar?baz=quux#frag',
+ hash: '#frag',
+ search: '?baz=quux',
+ query: 'baz=quux',
+ pathname: '/foo/bar',
+ path: '/foo/bar?baz=quux'
+ },
+
+ 'http:/foo/bar?baz=quux#frag': {
+ href: 'http:/foo/bar?baz=quux#frag',
+ protocol: 'http:',
+ hash: '#frag',
+ search: '?baz=quux',
+ query: 'baz=quux',
+ pathname: '/foo/bar',
+ path: '/foo/bar?baz=quux'
+ },
+
+ 'mailto:foo@bar.com?subject=hello': {
+ href: 'mailto:foo@bar.com?subject=hello',
+ protocol: 'mailto:',
+ host: 'bar.com',
+ auth: 'foo',
+ hostname: 'bar.com',
+ search: '?subject=hello',
+ query: 'subject=hello',
+ path: '?subject=hello'
+ },
+
+ 'javascript:alert(\'hello\');': {
+ href: 'javascript:alert(\'hello\');',
+ protocol: 'javascript:',
+ pathname: 'alert(\'hello\');',
+ path: 'alert(\'hello\');'
+ },
+
+ 'xmpp:isaacschlueter@jabber.org': {
+ href: 'xmpp:isaacschlueter@jabber.org',
+ protocol: 'xmpp:',
+ host: 'jabber.org',
+ auth: 'isaacschlueter',
+ hostname: 'jabber.org'
+ },
+
+ 'http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar': {
+ href: 'http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar',
+ protocol: 'http:',
+ slashes: true,
+ host: '127.0.0.1:8080',
+ auth: 'atpass:foo@bar',
+ hostname: '127.0.0.1',
+ port: '8080',
+ pathname: '/path',
+ search: '?search=foo',
+ query: 'search=foo',
+ hash: '#bar',
+ path: '/path?search=foo'
+ },
+
+ 'svn+ssh://foo/bar': {
+ href: 'svn+ssh://foo/bar',
+ host: 'foo',
+ hostname: 'foo',
+ protocol: 'svn+ssh:',
+ pathname: '/bar',
+ path: '/bar',
+ slashes: true
+ },
+
+ 'dash-test://foo/bar': {
+ href: 'dash-test://foo/bar',
+ host: 'foo',
+ hostname: 'foo',
+ protocol: 'dash-test:',
+ pathname: '/bar',
+ path: '/bar',
+ slashes: true
+ },
+
+ 'dash-test:foo/bar': {
+ href: 'dash-test:foo/bar',
+ host: 'foo',
+ hostname: 'foo',
+ protocol: 'dash-test:',
+ pathname: '/bar',
+ path: '/bar'
+ },
+
+ 'dot.test://foo/bar': {
+ href: 'dot.test://foo/bar',
+ host: 'foo',
+ hostname: 'foo',
+ protocol: 'dot.test:',
+ pathname: '/bar',
+ path: '/bar',
+ slashes: true
+ },
+
+ 'dot.test:foo/bar': {
+ href: 'dot.test:foo/bar',
+ host: 'foo',
+ hostname: 'foo',
+ protocol: 'dot.test:',
+ pathname: '/bar',
+ path: '/bar'
+ },
+
+ // IDNA tests
+ 'http://www.日本語.com/': {
+ href: 'http://www.xn--wgv71a119e.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.xn--wgv71a119e.com',
+ hostname: 'www.xn--wgv71a119e.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://example.Bücher.com/': {
+ href: 'http://example.xn--bcher-kva.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'example.xn--bcher-kva.com',
+ hostname: 'example.xn--bcher-kva.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://www.Äffchen.com/': {
+ href: 'http://www.xn--ffchen-9ta.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.xn--ffchen-9ta.com',
+ hostname: 'www.xn--ffchen-9ta.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://www.Äffchen.cOm;A/b/c?d=e#f g<h>i': {
+ href: 'http://www.xn--ffchen-9ta.com/;A/b/c?d=e#f%20g%3Ch%3Ei',
+ protocol: 'http:',
+ slashes: true,
+ host: 'www.xn--ffchen-9ta.com',
+ hostname: 'www.xn--ffchen-9ta.com',
+ pathname: ';A/b/c',
+ search: '?d=e',
+ query: 'd=e',
+ hash: '#f%20g%3Ch%3Ei',
+ path: ';A/b/c?d=e'
+ },
+
+ 'http://SÉLIER.COM/': {
+ href: 'http://xn--slier-bsa.com/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'xn--slier-bsa.com',
+ hostname: 'xn--slier-bsa.com',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://ليهمابتكلموشعربي؟.ي؟/': {
+ href: 'http://xn--egbpdaj6bu4bxfgehfvwxn.xn--egb9f/',
+ protocol: 'http:',
+ slashes: true,
+ host: 'xn--egbpdaj6bu4bxfgehfvwxn.xn--egb9f',
+ hostname: 'xn--egbpdaj6bu4bxfgehfvwxn.xn--egb9f',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://➡.ws/➡': {
+ href: 'http://xn--hgi.ws/➡',
+ protocol: 'http:',
+ slashes: true,
+ host: 'xn--hgi.ws',
+ hostname: 'xn--hgi.ws',
+ pathname: '/➡',
+ path: '/➡'
+ },
+
+ 'http://bucket_name.s3.amazonaws.com/image.jpg': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'bucket_name.s3.amazonaws.com',
+ hostname: 'bucket_name.s3.amazonaws.com',
+ pathname: '/image.jpg',
+ href: 'http://bucket_name.s3.amazonaws.com/image.jpg',
+ path: '/image.jpg'
+ },
+
+ 'git+http://github.com/joyent/node.git': {
+ protocol: 'git+http:',
+ slashes: true,
+ host: 'github.com',
+ hostname: 'github.com',
+ pathname: '/joyent/node.git',
+ path: '/joyent/node.git',
+ href: 'git+http://github.com/joyent/node.git'
+ },
+
+ // If local1@domain1 is uses as a relative URL it may
+ // be parse into auth@hostname, but here there is no
+ // way to make it work in url.parse, I add the test to be explicit
+ 'local1@domain1': {
+ pathname: 'local1@domain1',
+ path: 'local1@domain1',
+ href: 'local1@domain1'
+ },
+
+ // While this may seem counter-intuitive, a browser will parse
+ // <a href='www.google.com'> as a path.
+ 'www.example.com': {
+ href: 'www.example.com',
+ pathname: 'www.example.com',
+ path: 'www.example.com'
+ },
+
+ // ipv6 support
+ '[fe80::1]': {
+ href: '[fe80::1]',
+ pathname: '[fe80::1]',
+ path: '[fe80::1]'
+ },
+
+ 'coap://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]': {
+ protocol: 'coap:',
+ slashes: true,
+ host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]',
+ hostname: 'fedc:ba98:7654:3210:fedc:ba98:7654:3210',
+ href: 'coap://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'coap://[1080:0:0:0:8:800:200C:417A]:61616/': {
+ protocol: 'coap:',
+ slashes: true,
+ host: '[1080:0:0:0:8:800:200c:417a]:61616',
+ port: '61616',
+ hostname: '1080:0:0:0:8:800:200c:417a',
+ href: 'coap://[1080:0:0:0:8:800:200c:417a]:61616/',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://user:password@[3ffe:2a00:100:7031::1]:8080': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:password',
+ host: '[3ffe:2a00:100:7031::1]:8080',
+ port: '8080',
+ hostname: '3ffe:2a00:100:7031::1',
+ href: 'http://user:password@[3ffe:2a00:100:7031::1]:8080/',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'coap://u:p@[::192.9.5.5]:61616/.well-known/r?n=Temperature': {
+ protocol: 'coap:',
+ slashes: true,
+ auth: 'u:p',
+ host: '[::192.9.5.5]:61616',
+ port: '61616',
+ hostname: '::192.9.5.5',
+ href: 'coap://u:p@[::192.9.5.5]:61616/.well-known/r?n=Temperature',
+ search: '?n=Temperature',
+ query: 'n=Temperature',
+ pathname: '/.well-known/r',
+ path: '/.well-known/r?n=Temperature'
+ },
+
+ // empty port
+ 'http://example.com:': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'example.com',
+ hostname: 'example.com',
+ href: 'http://example.com/',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://example.com:/a/b.html': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'example.com',
+ hostname: 'example.com',
+ href: 'http://example.com/a/b.html',
+ pathname: '/a/b.html',
+ path: '/a/b.html'
+ },
+
+ 'http://example.com:?a=b': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'example.com',
+ hostname: 'example.com',
+ href: 'http://example.com/?a=b',
+ search: '?a=b',
+ query: 'a=b',
+ pathname: '/',
+ path: '/?a=b'
+ },
+
+ 'http://example.com:#abc': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'example.com',
+ hostname: 'example.com',
+ href: 'http://example.com/#abc',
+ hash: '#abc',
+ pathname: '/',
+ path: '/'
+ },
+
+ 'http://[fe80::1]:/a/b?a=b#abc': {
+ protocol: 'http:',
+ slashes: true,
+ host: '[fe80::1]',
+ hostname: 'fe80::1',
+ href: 'http://[fe80::1]/a/b?a=b#abc',
+ search: '?a=b',
+ query: 'a=b',
+ hash: '#abc',
+ pathname: '/a/b',
+ path: '/a/b?a=b'
+ },
+
+ 'http://-lovemonsterz.tumblr.com/rss': {
+ protocol: 'http:',
+ slashes: true,
+ host: '-lovemonsterz.tumblr.com',
+ hostname: '-lovemonsterz.tumblr.com',
+ href: 'http://-lovemonsterz.tumblr.com/rss',
+ pathname: '/rss',
+ path: '/rss',
+ },
+
+ 'http://-lovemonsterz.tumblr.com:80/rss': {
+ protocol: 'http:',
+ slashes: true,
+ port: '80',
+ host: '-lovemonsterz.tumblr.com:80',
+ hostname: '-lovemonsterz.tumblr.com',
+ href: 'http://-lovemonsterz.tumblr.com:80/rss',
+ pathname: '/rss',
+ path: '/rss',
+ },
+
+ 'http://user:pass@-lovemonsterz.tumblr.com/rss': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:pass',
+ host: '-lovemonsterz.tumblr.com',
+ hostname: '-lovemonsterz.tumblr.com',
+ href: 'http://user:pass@-lovemonsterz.tumblr.com/rss',
+ pathname: '/rss',
+ path: '/rss',
+ },
+
+ 'http://user:pass@-lovemonsterz.tumblr.com:80/rss': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:pass',
+ port: '80',
+ host: '-lovemonsterz.tumblr.com:80',
+ hostname: '-lovemonsterz.tumblr.com',
+ href: 'http://user:pass@-lovemonsterz.tumblr.com:80/rss',
+ pathname: '/rss',
+ path: '/rss',
+ },
+
+ 'http://_jabber._tcp.google.com/test': {
+ protocol: 'http:',
+ slashes: true,
+ host: '_jabber._tcp.google.com',
+ hostname: '_jabber._tcp.google.com',
+ href: 'http://_jabber._tcp.google.com/test',
+ pathname: '/test',
+ path: '/test',
+ },
+
+ 'http://user:pass@_jabber._tcp.google.com/test': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:pass',
+ host: '_jabber._tcp.google.com',
+ hostname: '_jabber._tcp.google.com',
+ href: 'http://user:pass@_jabber._tcp.google.com/test',
+ pathname: '/test',
+ path: '/test',
+ },
+
+ 'http://_jabber._tcp.google.com:80/test': {
+ protocol: 'http:',
+ slashes: true,
+ port: '80',
+ host: '_jabber._tcp.google.com:80',
+ hostname: '_jabber._tcp.google.com',
+ href: 'http://_jabber._tcp.google.com:80/test',
+ pathname: '/test',
+ path: '/test',
+ },
+
+ 'http://user:pass@_jabber._tcp.google.com:80/test': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'user:pass',
+ port: '80',
+ host: '_jabber._tcp.google.com:80',
+ hostname: '_jabber._tcp.google.com',
+ href: 'http://user:pass@_jabber._tcp.google.com:80/test',
+ pathname: '/test',
+ path: '/test',
+ },
+
+ 'http://x:1/\' <>"`/{}|\\^~`/': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'x:1',
+ port: '1',
+ hostname: 'x',
+ pathname: '/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/',
+ path: '/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/',
+ href: 'http://x:1/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/'
+ },
+
+ 'http://a@b@c/': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'a@b',
+ host: 'c',
+ hostname: 'c',
+ href: 'http://a%40b@c/',
+ path: '/',
+ pathname: '/'
+ },
+
+ 'http://a@b?@c': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'a',
+ host: 'b',
+ hostname: 'b',
+ href: 'http://a@b/?@c',
+ path: '/?@c',
+ pathname: '/',
+ search: '?@c',
+ query: '@c'
+ },
+
+ 'http://a.b/\tbc\ndr\ref g"hq\'j<kl>?mn\\op^q=r`99{st|uv}wz': {
+ protocol: 'http:',
+ slashes: true,
+ host: 'a.b',
+ port: null,
+ hostname: 'a.b',
+ hash: null,
+ pathname: '/%09bc%0Adr%0Def%20g%22hq%27j%3Ckl%3E',
+ path: '/%09bc%0Adr%0Def%20g%22hq%27j%3Ckl%3E?mn%5Cop%5Eq=r%6099%7Bst%7Cuv%7Dwz',
+ search: '?mn%5Cop%5Eq=r%6099%7Bst%7Cuv%7Dwz',
+ query: 'mn%5Cop%5Eq=r%6099%7Bst%7Cuv%7Dwz',
+ href: 'http://a.b/%09bc%0Adr%0Def%20g%22hq%27j%3Ckl%3E?mn%5Cop%5Eq=r%6099%7Bst%7Cuv%7Dwz'
+ },
+
+ 'http://a\r" \t\n<\'b:b@c\r\nd/e?f': {
+ protocol: 'http:',
+ slashes: true,
+ auth: 'a\r" \t\n<\'b:b',
+ host: 'c',
+ port: null,
+ hostname: 'c',
+ hash: null,
+ search: '?f',
+ query: 'f',
+ pathname: '%0D%0Ad/e',
+ path: '%0D%0Ad/e?f',
+ href: 'http://a%0D%22%20%09%0A%3C\'b:b@c/%0D%0Ad/e?f'
+ },
+
+ // Git urls used by npm
+ 'git+ssh://git@github.com:npm/npm': {
+ protocol: 'git+ssh:',
+ slashes: true,
+ auth: 'git',
+ host: 'github.com',
+ port: null,
+ hostname: 'github.com',
+ hash: null,
+ search: null,
+ query: null,
+ pathname: '/:npm/npm',
+ path: '/:npm/npm',
+ href: 'git+ssh://git@github.com/:npm/npm'
+ },
+
+ 'https://*': {
+ protocol: 'https:',
+ slashes: true,
+ auth: null,
+ host: '',
+ port: null,
+ hostname: '',
+ hash: null,
+ search: null,
+ query: null,
+ pathname: '/*',
+ path: '/*',
+ href: 'https:///*'
+ },
+
+ // The following two URLs are the same, but they differ for a capital A.
+ // Verify that the protocol is checked in a case-insensitive manner.
+ 'javascript:alert(1);a=\x27@white-listed.com\x27': {
+ protocol: 'javascript:',
+ slashes: null,
+ auth: null,
+ host: null,
+ port: null,
+ hostname: null,
+ hash: null,
+ search: null,
+ query: null,
+ pathname: "alert(1);a='@white-listed.com'",
+ path: "alert(1);a='@white-listed.com'",
+ href: "javascript:alert(1);a='@white-listed.com'"
+ },
+
+ 'javAscript:alert(1);a=\x27@white-listed.com\x27': {
+ protocol: 'javascript:',
+ slashes: null,
+ auth: null,
+ host: null,
+ port: null,
+ hostname: null,
+ hash: null,
+ search: null,
+ query: null,
+ pathname: "alert(1);a='@white-listed.com'",
+ path: "alert(1);a='@white-listed.com'",
+ href: "javascript:alert(1);a='@white-listed.com'"
+ },
+
+ 'ws://www.example.com': {
+ protocol: 'ws:',
+ slashes: true,
+ hostname: 'www.example.com',
+ host: 'www.example.com',
+ pathname: '/',
+ path: '/',
+ href: 'ws://www.example.com/'
+ },
+
+ 'wss://www.example.com': {
+ protocol: 'wss:',
+ slashes: true,
+ hostname: 'www.example.com',
+ host: 'www.example.com',
+ pathname: '/',
+ path: '/',
+ href: 'wss://www.example.com/'
+ },
+
+ '//fhqwhgads@example.com/everybody-to-the-limit': {
+ protocol: null,
+ slashes: true,
+ auth: 'fhqwhgads',
+ host: 'example.com',
+ port: null,
+ hostname: 'example.com',
+ hash: null,
+ search: null,
+ query: null,
+ pathname: '/everybody-to-the-limit',
+ path: '/everybody-to-the-limit',
+ href: '//fhqwhgads@example.com/everybody-to-the-limit'
+ },
+
+ '//fhqwhgads@example.com/everybody#to-the-limit': {
+ protocol: null,
+ slashes: true,
+ auth: 'fhqwhgads',
+ host: 'example.com',
+ port: null,
+ hostname: 'example.com',
+ hash: '#to-the-limit',
+ search: null,
+ query: null,
+ pathname: '/everybody',
+ path: '/everybody',
+ href: '//fhqwhgads@example.com/everybody#to-the-limit'
+ },
+
+ '\bhttp://example.com/\b': {
+ protocol: 'http:',
+ slashes: true,
+ auth: null,
+ host: 'example.com',
+ port: null,
+ hostname: 'example.com',
+ hash: null,
+ search: null,
+ query: null,
+ pathname: '/',
+ path: '/',
+ href: 'http://example.com/'
+ }
+};
+
+for (const u in parseTests) {
+ let actual = url.parse(u);
+ const spaced = url.parse(` \t ${u}\n\t`);
+ let expected = Object.assign(new url.Url(), parseTests[u]);
+
+ Object.keys(actual).forEach(function(i) {
+ if (expected[i] === undefined && actual[i] === null) {
+ expected[i] = null;
+ }
+ });
+
+ assert.deepStrictEqual(
+ actual,
+ expected,
+ `expected ${inspect(expected)}, got ${inspect(actual)}`
+ );
+ assert.deepStrictEqual(
+ spaced,
+ expected,
+ `expected ${inspect(expected)}, got ${inspect(spaced)}`
+ );
+
+ expected = parseTests[u].href;
+ actual = url.format(parseTests[u]);
+
+ assert.strictEqual(actual, expected,
+ `format(${u}) == ${u}\nactual:${actual}`);
+}
+
+{
+ const parsed = url.parse('http://nodejs.org/')
+ .resolveObject('jAvascript:alert(1);a=\x27@white-listed.com\x27');
+
+ const expected = Object.assign(new url.Url(), {
+ protocol: 'javascript:',
+ slashes: null,
+ auth: null,
+ host: null,
+ port: null,
+ hostname: null,
+ hash: null,
+ search: null,
+ query: null,
+ pathname: "alert(1);a='@white-listed.com'",
+ path: "alert(1);a='@white-listed.com'",
+ href: "javascript:alert(1);a='@white-listed.com'"
+ });
+
+ assert.deepStrictEqual(parsed, expected);
+}