1
import { expect, test, describe } from 'vitest';
2
import { Url } from './url.js';
4
describe('relative URL handling', () => {
5
test('parse and serialize a relative path', () => {
6
expect(new Url('/sample-path').toString()).toStrictEqual('/sample-path');
9
test('parse and serialize a relative path preserving path and hash components', () => {
10
expect(new Url('/sample-path?sample_var=sample_value#sample_hash').toString()).toStrictEqual(
11
'/sample-path?sample_var=sample_value#sample_hash',
16
describe('empty scheme handling', () => {
17
test('parse and serialize an URl without scheme', () => {
18
expect(new Url('//example.com/sample-path').toString()).toStrictEqual('//example.com/sample-path');
21
test('parse and serialize a relative path preserving path and hash components', () => {
22
expect(new Url('//example.com:1234/sample-path?sample_var=sample_value#sample_hash').toString()).toStrictEqual(
23
'//example.com:1234/sample-path?sample_var=sample_value#sample_hash',
28
describe('query parameter handling', () => {
29
const SAMPLE_URL = 'https://example.com:1234/sample-path?sample_param=sample_value';
31
test('parse and serialize an url to the original input', () => {
32
expect(new Url(SAMPLE_URL).toString()).toStrictEqual(SAMPLE_URL);
35
test('parse a URL containing escaped query parameters', () => {
36
expect(new Url('https://example.com:1234/sample-path?key+that+needs+encoding%21=sample%21').query).toStrictEqual({
37
'key that needs encoding!': 'sample!',
41
test('serialize an url without query', () => {
42
expect(new Url('https://example.com:1234/sample-path').toString()).toStrictEqual(
43
'https://example.com:1234/sample-path',
47
test('merge existing query params', () => {
48
expect(new Url(SAMPLE_URL).setQuery('new_query_pram', 'new_query_value').toString()).toStrictEqual(
49
'https://example.com:1234/sample-path?sample_param=sample_value&new_query_pram=new_query_value',
53
test('replace existing query params instead of adding with the same key', () => {
54
expect(new Url(SAMPLE_URL).setQuery('sample_param', 'new_value').toString()).toStrictEqual(
55
'https://example.com:1234/sample-path?sample_param=new_value',
59
test('properly serialize query params and URL encode them when needed', () => {
62
.setQuery('ascii', ` ,;:!?'()/&+=$@`)
63
.setQuery('encoding_optional', `*-.`)
64
.setQuery('non_ascii', `çÁâÑ清ゆ`)
65
.setQuery('key that needs encoding!', `sample`)
68
'https://example.com:1234/sample-path' +
69
'?sample_param=sample_value' +
70
'&ascii=+%2C%3B%3A%21%3F%27%28%29%2F%26%2B%3D%24%40' +
71
'&encoding_optional=*-.' +
72
'&non_ascii=%C3%A7%C3%81%C3%A2%C3%91%E6%B8%85%E3%82%86' +
73
'&key+that+needs+encoding%21=sample',
78
describe('isAbsolute', () => {
79
test('returns true for full URL', () => {
80
expect(new Url('https://example.com/sample-path').isAbsolute()).toStrictEqual(true);
83
test('returns false when URL has no protocol', () => {
84
expect(new Url('//example.com/sample-path').isAbsolute()).toStrictEqual(false);
87
test('returns false for relative URL', () => {
88
expect(new Url('/sample-path').isAbsolute()).toStrictEqual(false);
92
describe('isProtocolRelative', () => {
93
test('returns true when URL has no protocol', () => {
94
expect(new Url('//example.com/sample-path').isProtocolRelative()).toStrictEqual(true);
97
test('returns false for full URL', () => {
98
expect(new Url('https://example.com/sample-path').isProtocolRelative()).toStrictEqual(false);
101
test('returns false when for relative URL', () => {
102
expect(new Url('/sample-path').isProtocolRelative()).toStrictEqual(false);
106
describe('isRootRelative', () => {
107
test('returns true when for relative URL', () => {
108
expect(new Url('/sample-path').isRootRelative()).toStrictEqual(true);
111
test('returns false for full URL', () => {
112
expect(new Url('https://example.com/sample-path').isRootRelative()).toStrictEqual(false);
115
test('returns false when URL has host but no protocol', () => {
116
expect(new Url('//example.com/sample-path').isRootRelative()).toStrictEqual(false);
120
describe('trailing slash handling', () => {
121
test('parse and serialize an URL without path', () => {
122
expect(new Url('https://example.com').toString()).toStrictEqual('https://example.com');
125
test('parse and serialize an URL without path, keeping trailing slash', () => {
126
expect(new Url('https://example.com/').toString()).toStrictEqual('https://example.com/');
129
test('parse and serialize an URL preserving trailing slash with no query params', () => {
130
expect(new Url('https://example.com/path/').toString()).toStrictEqual('https://example.com/path/');
133
test('parse and serialize an URL preserving trailing slash with query params', () => {
134
expect(new Url('https://example.com/path/?foo=bar').toString()).toStrictEqual('https://example.com/path/?foo=bar');
137
test('parse, add query param, and serialize an URL preserving trailing slash', () => {
138
const testUrl = new Url('https://example.com/path/');
139
testUrl.setQuery('token', '123123');
140
expect(testUrl.toString()).toStrictEqual('https://example.com/path/?token=123123');
143
test('parse, add query param, and serialize an URL preserving trailing slash with existing query params', () => {
144
const testUrl = new Url('https://example.com/path/?foo=bar');
145
testUrl.setQuery('token', '123123');
146
expect(testUrl.toString()).toStrictEqual('https://example.com/path/?foo=bar&token=123123');
149
test('parse and serialize an URL without trailing slash with no query params', () => {
150
expect(new Url('https://example.com/path').toString()).toStrictEqual('https://example.com/path');
153
test('parse and serialize an URL without trailing slash with query params', () => {
154
expect(new Url('https://example.com/path?foo=bar').toString()).toStrictEqual('https://example.com/path?foo=bar');
157
test('parse, add query param, and serialize an URL without trailing slash', () => {
158
const testUrl = new Url('https://example.com/path');
159
testUrl.setQuery('token', '123123');
160
expect(testUrl.toString()).toStrictEqual('https://example.com/path?token=123123');
163
test('parse, add query param, and serialize an URL without trailing slash with existing query params', () => {
164
const testUrl = new Url('https://example.com/path?foo=bar');
165
testUrl.setQuery('token', '123123');
166
expect(testUrl.toString()).toStrictEqual('https://example.com/path?foo=bar&token=123123');
169
test('parse an URL and serialize after adding paths with and without trailing slashes', () => {
170
const testUrl = new Url('https://example.com/');
171
expect(testUrl.toString()).toStrictEqual('https://example.com/');
173
testUrl.addPath('path');
174
expect(testUrl.toString()).toStrictEqual('https://example.com/path');
176
testUrl.addPath('path2/');
177
expect(testUrl.toString()).toStrictEqual('https://example.com/path/path2/');
179
testUrl.addPath('/');
180
expect(testUrl.toString()).toStrictEqual('https://example.com/path/path2/');
182
testUrl.addPath('.');
183
expect(testUrl.toString()).toStrictEqual('https://example.com/path/path2/');
185
testUrl.addPath('..');
186
expect(testUrl.toString()).toStrictEqual('https://example.com/path/');
188
const testUrl2 = new Url('https://example.com');
189
testUrl2.addPath('./');
190
expect(testUrl2.toString()).toStrictEqual('https://example.com/');
192
const testUrl3 = new Url('https://example.com/path');
193
testUrl3.addPath('../');
194
expect(testUrl3.toString()).toStrictEqual('https://example.com/');