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