• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2'use strict';
3
4// Tests below are not from WPT.
5
6require('../common');
7const assert = require('assert');
8
9const url = new URL('http://user:pass@foo.bar.com:21/aaa/zzz?l=24#test');
10const oldParams = url.searchParams;  // For test of [SameObject]
11
12// To retrieve enumerable but not necessarily own properties,
13// we need to use the for-in loop.
14const props = [];
15for (const prop in url) {
16  props.push(prop);
17}
18
19// See: https://url.spec.whatwg.org/#api
20// https://heycam.github.io/webidl/#es-attributes
21// https://heycam.github.io/webidl/#es-stringifier
22const expected = ['toString',
23                  'href', 'origin', 'protocol',
24                  'username', 'password', 'host', 'hostname', 'port',
25                  'pathname', 'search', 'searchParams', 'hash', 'toJSON'];
26
27assert.deepStrictEqual(props, expected);
28
29// `href` is writable (not readonly) and is stringifier
30assert.strictEqual(url.toString(), url.href);
31url.href = 'http://user:pass@foo.bar.com:21/aaa/zzz?l=25#test';
32assert.strictEqual(url.href,
33                   'http://user:pass@foo.bar.com:21/aaa/zzz?l=25#test');
34assert.strictEqual(url.toString(), url.href);
35// Return true because it's configurable, but because the properties
36// are defined on the prototype per the spec, the deletion has no effect
37assert.strictEqual((delete url.href), true);
38assert.strictEqual(url.href,
39                   'http://user:pass@foo.bar.com:21/aaa/zzz?l=25#test');
40assert.strictEqual(url.searchParams, oldParams);  // [SameObject]
41
42// searchParams is readonly. Under strict mode setting a
43// non-writable property should throw.
44// Note: this error message is subject to change in V8 updates
45assert.throws(
46  () => url.origin = 'http://foo.bar.com:22',
47  /^TypeError: Cannot set property origin of \[object URL\] which has only a getter$/
48);
49assert.strictEqual(url.origin, 'http://foo.bar.com:21');
50assert.strictEqual(url.toString(),
51                   'http://user:pass@foo.bar.com:21/aaa/zzz?l=25#test');
52assert.strictEqual((delete url.origin), true);
53assert.strictEqual(url.origin, 'http://foo.bar.com:21');
54
55// The following properties should be writable (not readonly)
56url.protocol = 'https:';
57assert.strictEqual(url.protocol, 'https:');
58assert.strictEqual(url.toString(),
59                   'https://user:pass@foo.bar.com:21/aaa/zzz?l=25#test');
60assert.strictEqual((delete url.protocol), true);
61assert.strictEqual(url.protocol, 'https:');
62
63url.username = 'user2';
64assert.strictEqual(url.username, 'user2');
65assert.strictEqual(url.toString(),
66                   'https://user2:pass@foo.bar.com:21/aaa/zzz?l=25#test');
67assert.strictEqual((delete url.username), true);
68assert.strictEqual(url.username, 'user2');
69
70url.password = 'pass2';
71assert.strictEqual(url.password, 'pass2');
72assert.strictEqual(url.toString(),
73                   'https://user2:pass2@foo.bar.com:21/aaa/zzz?l=25#test');
74assert.strictEqual((delete url.password), true);
75assert.strictEqual(url.password, 'pass2');
76
77url.host = 'foo.bar.net:22';
78assert.strictEqual(url.host, 'foo.bar.net:22');
79assert.strictEqual(url.toString(),
80                   'https://user2:pass2@foo.bar.net:22/aaa/zzz?l=25#test');
81assert.strictEqual((delete url.host), true);
82assert.strictEqual(url.host, 'foo.bar.net:22');
83
84url.hostname = 'foo.bar.org';
85assert.strictEqual(url.hostname, 'foo.bar.org');
86assert.strictEqual(url.toString(),
87                   'https://user2:pass2@foo.bar.org:22/aaa/zzz?l=25#test');
88assert.strictEqual((delete url.hostname), true);
89assert.strictEqual(url.hostname, 'foo.bar.org');
90
91url.port = '23';
92assert.strictEqual(url.port, '23');
93assert.strictEqual(url.toString(),
94                   'https://user2:pass2@foo.bar.org:23/aaa/zzz?l=25#test');
95assert.strictEqual((delete url.port), true);
96assert.strictEqual(url.port, '23');
97
98url.pathname = '/aaa/bbb';
99assert.strictEqual(url.pathname, '/aaa/bbb');
100assert.strictEqual(url.toString(),
101                   'https://user2:pass2@foo.bar.org:23/aaa/bbb?l=25#test');
102assert.strictEqual((delete url.pathname), true);
103assert.strictEqual(url.pathname, '/aaa/bbb');
104
105url.search = '?k=99';
106assert.strictEqual(url.search, '?k=99');
107assert.strictEqual(url.toString(),
108                   'https://user2:pass2@foo.bar.org:23/aaa/bbb?k=99#test');
109assert.strictEqual((delete url.search), true);
110assert.strictEqual(url.search, '?k=99');
111
112url.hash = '#abcd';
113assert.strictEqual(url.hash, '#abcd');
114assert.strictEqual(url.toString(),
115                   'https://user2:pass2@foo.bar.org:23/aaa/bbb?k=99#abcd');
116assert.strictEqual((delete url.hash), true);
117assert.strictEqual(url.hash, '#abcd');
118
119// searchParams is readonly. Under strict mode setting a
120// non-writable property should throw.
121// Note: this error message is subject to change in V8 updates
122assert.throws(
123  () => url.searchParams = '?k=88',
124  /^TypeError: Cannot set property searchParams of \[object URL\] which has only a getter$/
125);
126assert.strictEqual(url.searchParams, oldParams);
127assert.strictEqual(url.toString(),
128                   'https://user2:pass2@foo.bar.org:23/aaa/bbb?k=99#abcd');
129assert.strictEqual((delete url.searchParams), true);
130assert.strictEqual(url.searchParams, oldParams);
131
132// Test special origins
133[
134  { expected: 'https://whatwg.org',
135    url: 'blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6f' },
136  { expected: 'ftp://example.org', url: 'ftp://example.org/foo' },
137  { expected: 'gopher://gopher.quux.org', url: 'gopher://gopher.quux.org/1/' },
138  { expected: 'http://example.org', url: 'http://example.org/foo' },
139  { expected: 'https://example.org', url: 'https://example.org/foo' },
140  { expected: 'ws://example.org', url: 'ws://example.org/foo' },
141  { expected: 'wss://example.org', url: 'wss://example.org/foo' },
142  { expected: 'null', url: 'file:///tmp/mock/path' },
143  { expected: 'null', url: 'npm://nodejs/rules' },
144].forEach((test) => {
145  assert.strictEqual(new URL(test.url).origin, test.expected);
146});
147