@gjsify/path 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -2
- package/lib/esm/constants.js +20 -0
- package/lib/esm/index.js +52 -0
- package/lib/esm/posix.js +339 -0
- package/lib/esm/util.js +113 -0
- package/lib/esm/win32.js +573 -0
- package/lib/types/constants.d.ts +9 -0
- package/lib/types/index.d.ts +23 -0
- package/lib/types/posix.d.ts +21 -0
- package/lib/types/util.d.ts +12 -0
- package/lib/types/win32.d.ts +21 -0
- package/package.json +35 -17
- package/src/constants.ts +11 -0
- package/src/index.spec.ts +964 -0
- package/src/index.ts +47 -0
- package/src/posix.ts +406 -0
- package/src/test.mts +6 -0
- package/src/util.ts +145 -0
- package/src/win32.ts +651 -0
- package/tsconfig.json +31 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/index.js +0 -75
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
// Ported from refs/node-test/parallel/test-path-*.js
|
|
2
|
+
// Original: MIT license, Node.js contributors
|
|
3
|
+
|
|
4
|
+
import { describe, it, expect } from '@gjsify/unit';
|
|
5
|
+
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import process from 'node:process';
|
|
8
|
+
|
|
9
|
+
export default async () => {
|
|
10
|
+
|
|
11
|
+
// ===== path.basename =====
|
|
12
|
+
|
|
13
|
+
await describe('path.basename', async () => {
|
|
14
|
+
await it('should return the last portion of a path', async () => {
|
|
15
|
+
expect(path.basename('/foo/bar/baz.html')).toBe('baz.html');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
await it('should strip the extension when provided', async () => {
|
|
19
|
+
expect(path.basename('/foo/bar/baz.html', '.html')).toBe('baz');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await it('should handle paths without directory', async () => {
|
|
23
|
+
expect(path.basename('baz.html')).toBe('baz.html');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
await it('should handle trailing separators', async () => {
|
|
27
|
+
expect(path.basename('/foo/bar/')).toBe('bar');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
await it('should return empty string for empty input', async () => {
|
|
31
|
+
expect(path.basename('')).toBe('');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
await it('should return empty when ext matches base exactly', async () => {
|
|
35
|
+
expect(path.basename('.js', '.js')).toBe('');
|
|
36
|
+
expect(path.basename('a', 'a')).toBe('');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
await it('should not strip mismatched extension', async () => {
|
|
40
|
+
expect(path.basename('file.js', '.ts')).toBe('file.js');
|
|
41
|
+
expect(path.basename('js', '.js')).toBe('js');
|
|
42
|
+
expect(path.basename('file', '.js')).toBe('file');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
await it('should strip compound extension', async () => {
|
|
46
|
+
expect(path.basename('file.js.old', '.js.old')).toBe('file');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
await it('should handle double trailing slashes', async () => {
|
|
50
|
+
expect(path.basename('basename.ext//')).toBe('basename.ext');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await it('should handle partial ext match', async () => {
|
|
54
|
+
expect(path.basename('aaa/bbb', 'bb')).toBe('b');
|
|
55
|
+
expect(path.basename('aaa/bbb', 'b')).toBe('bb');
|
|
56
|
+
expect(path.basename('/aaa/bbb', 'bb')).toBe('b');
|
|
57
|
+
expect(path.basename('/aaa/bbb', 'b')).toBe('bb');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await it('should handle ext containing path separator', async () => {
|
|
61
|
+
expect(path.basename('aaa/bbb', '/bbb')).toBe('bbb');
|
|
62
|
+
expect(path.basename('aaa/bbb', 'a/bbb')).toBe('bbb');
|
|
63
|
+
expect(path.basename('/aaa/bbb', '/bbb')).toBe('bbb');
|
|
64
|
+
expect(path.basename('/aaa/bbb', 'a/bbb')).toBe('bbb');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await it('should handle various absolute paths', async () => {
|
|
68
|
+
expect(path.basename('/dir/basename.ext')).toBe('basename.ext');
|
|
69
|
+
expect(path.basename('/basename.ext')).toBe('basename.ext');
|
|
70
|
+
expect(path.basename('/aaa/')).toBe('aaa');
|
|
71
|
+
expect(path.basename('/aaa/b')).toBe('b');
|
|
72
|
+
expect(path.basename('/a/b')).toBe('b');
|
|
73
|
+
expect(path.basename('//a')).toBe('a');
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// ===== path.dirname =====
|
|
78
|
+
|
|
79
|
+
await describe('path.dirname', async () => {
|
|
80
|
+
await it('should return the directory of a path', async () => {
|
|
81
|
+
expect(path.dirname('/foo/bar/baz.html')).toBe('/foo/bar');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
await it('should return . for filename only', async () => {
|
|
85
|
+
expect(path.dirname('baz.html')).toBe('.');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await it('should return / for root path', async () => {
|
|
89
|
+
expect(path.dirname('/foo')).toBe('/');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
await it('should return . for empty string', async () => {
|
|
93
|
+
expect(path.dirname('')).toBe('.');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
await it('should handle posix paths correctly', async () => {
|
|
97
|
+
expect(path.posix.dirname('/a/b/')).toBe('/a');
|
|
98
|
+
expect(path.posix.dirname('/a/b')).toBe('/a');
|
|
99
|
+
expect(path.posix.dirname('/a')).toBe('/');
|
|
100
|
+
expect(path.posix.dirname('/')).toBe('/');
|
|
101
|
+
expect(path.posix.dirname('////')).toBe('/');
|
|
102
|
+
expect(path.posix.dirname('//a')).toBe('//');
|
|
103
|
+
expect(path.posix.dirname('foo')).toBe('.');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// ===== path.extname =====
|
|
108
|
+
|
|
109
|
+
await describe('path.extname', async () => {
|
|
110
|
+
await it('should return the extension of a path', async () => {
|
|
111
|
+
expect(path.extname('index.html')).toBe('.html');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
await it('should return the last extension', async () => {
|
|
115
|
+
expect(path.extname('index.coffee.md')).toBe('.md');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
await it('should return empty string for no extension', async () => {
|
|
119
|
+
expect(path.extname('index')).toBe('');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
await it('should return empty string for dotfiles', async () => {
|
|
123
|
+
expect(path.extname('.index')).toBe('');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await it('should handle dotfile with extension', async () => {
|
|
127
|
+
expect(path.extname('.index.md')).toBe('.md');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
await it('should return dot for trailing dot', async () => {
|
|
131
|
+
expect(path.extname('index.')).toBe('.');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await it('should handle paths with directories', async () => {
|
|
135
|
+
expect(path.extname('/path/to/file')).toBe('');
|
|
136
|
+
expect(path.extname('/path/to/file.ext')).toBe('.ext');
|
|
137
|
+
expect(path.extname('/path.to/file.ext')).toBe('.ext');
|
|
138
|
+
expect(path.extname('/path.to/file')).toBe('');
|
|
139
|
+
expect(path.extname('/path.to/.file')).toBe('');
|
|
140
|
+
expect(path.extname('/path.to/.file.ext')).toBe('.ext');
|
|
141
|
+
expect(path.extname('/path/to/f.ext')).toBe('.ext');
|
|
142
|
+
expect(path.extname('/path/to/..ext')).toBe('.ext');
|
|
143
|
+
expect(path.extname('/path/to/..')).toBe('');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await it('should handle dotfile edge cases', async () => {
|
|
147
|
+
expect(path.extname('.file')).toBe('');
|
|
148
|
+
expect(path.extname('.file.ext')).toBe('.ext');
|
|
149
|
+
expect(path.extname('.file.')).toBe('.');
|
|
150
|
+
expect(path.extname('.file..')).toBe('.');
|
|
151
|
+
expect(path.extname('..file.ext')).toBe('.ext');
|
|
152
|
+
expect(path.extname('..file')).toBe('.file');
|
|
153
|
+
expect(path.extname('..file.')).toBe('.');
|
|
154
|
+
expect(path.extname('..file..')).toBe('.');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
await it('should handle multiple dots', async () => {
|
|
158
|
+
expect(path.extname('...')).toBe('.');
|
|
159
|
+
expect(path.extname('...ext')).toBe('.ext');
|
|
160
|
+
expect(path.extname('....')).toBe('.');
|
|
161
|
+
expect(path.extname('file.ext.ext')).toBe('.ext');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
await it('should handle trailing slashes', async () => {
|
|
165
|
+
expect(path.extname('./')).toBe('');
|
|
166
|
+
expect(path.extname('../')).toBe('');
|
|
167
|
+
expect(path.extname('file.ext/')).toBe('.ext');
|
|
168
|
+
expect(path.extname('file.ext//')).toBe('.ext');
|
|
169
|
+
expect(path.extname('file/')).toBe('');
|
|
170
|
+
expect(path.extname('file//')).toBe('');
|
|
171
|
+
expect(path.extname('file./')).toBe('.');
|
|
172
|
+
expect(path.extname('file.//')).toBe('.');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
await it('should handle root paths', async () => {
|
|
176
|
+
expect(path.extname('.')).toBe('');
|
|
177
|
+
expect(path.extname('..')).toBe('');
|
|
178
|
+
expect(path.extname('/file')).toBe('');
|
|
179
|
+
expect(path.extname('/file.ext')).toBe('.ext');
|
|
180
|
+
expect(path.extname('/.file')).toBe('');
|
|
181
|
+
expect(path.extname('/.file.ext')).toBe('.ext');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// ===== path.join =====
|
|
186
|
+
|
|
187
|
+
await describe('path.join', async () => {
|
|
188
|
+
await it('should join path segments', async () => {
|
|
189
|
+
expect(path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')).toBe('/foo/bar/baz/asdf');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
await it('should return . for no arguments', async () => {
|
|
193
|
+
expect(path.join()).toBe('.');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
await it('should normalize the result', async () => {
|
|
197
|
+
expect(path.join('foo', 'bar', '..', 'baz')).toBe('foo/baz');
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
await it('should handle absolute paths', async () => {
|
|
201
|
+
expect(path.join('/foo', '/bar')).toBe('/foo/bar');
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
await it('should handle dot segments', async () => {
|
|
205
|
+
expect(path.join('.', 'x/b', '..', '/b/c.js')).toBe('x/b/c.js');
|
|
206
|
+
expect(path.join('/.', 'x/b', '..', '/b/c.js')).toBe('/x/b/c.js');
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
await it('should resolve parent traversal beyond root', async () => {
|
|
210
|
+
expect(path.join('/foo', '../../../bar')).toBe('/bar');
|
|
211
|
+
expect(path.join('foo', '../../../bar')).toBe('../../bar');
|
|
212
|
+
expect(path.join('foo/', '../../../bar')).toBe('../../bar');
|
|
213
|
+
expect(path.join('foo/x', '../../../bar')).toBe('../bar');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
await it('should handle ./bar joins', async () => {
|
|
217
|
+
expect(path.join('foo/x', './bar')).toBe('foo/x/bar');
|
|
218
|
+
expect(path.join('foo/x/', './bar')).toBe('foo/x/bar');
|
|
219
|
+
expect(path.join('foo/x/', '.', 'bar')).toBe('foo/x/bar');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
await it('should handle trailing ./', async () => {
|
|
223
|
+
expect(path.join('./')).toBe('./');
|
|
224
|
+
expect(path.join('.', './')).toBe('./');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
await it('should handle multiple dot segments', async () => {
|
|
228
|
+
expect(path.join('.', '.', '.')).toBe('.');
|
|
229
|
+
expect(path.join('.', './', '.')).toBe('.');
|
|
230
|
+
expect(path.join('.', '/./', '.')).toBe('.');
|
|
231
|
+
expect(path.join('.', '/////./', '.')).toBe('.');
|
|
232
|
+
expect(path.join('.')).toBe('.');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
await it('should handle empty string arguments', async () => {
|
|
236
|
+
expect(path.join('', '.')).toBe('.');
|
|
237
|
+
expect(path.join('', 'foo')).toBe('foo');
|
|
238
|
+
expect(path.join('', '/foo')).toBe('/foo');
|
|
239
|
+
expect(path.join('', '', '/foo')).toBe('/foo');
|
|
240
|
+
expect(path.join('', '', 'foo')).toBe('foo');
|
|
241
|
+
expect(path.join('foo', '')).toBe('foo');
|
|
242
|
+
expect(path.join('foo/', '')).toBe('foo/');
|
|
243
|
+
expect(path.join('foo', '', '/bar')).toBe('foo/bar');
|
|
244
|
+
expect(path.join('')).toBe('.');
|
|
245
|
+
expect(path.join('', '')).toBe('.');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
await it('should handle complex .. chains', async () => {
|
|
249
|
+
expect(path.join('./', '..', '/foo')).toBe('../foo');
|
|
250
|
+
expect(path.join('./', '..', '..', '/foo')).toBe('../../foo');
|
|
251
|
+
expect(path.join('.', '..', '..', '/foo')).toBe('../../foo');
|
|
252
|
+
expect(path.join('', '..', '..', '/foo')).toBe('../../foo');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
await it('should handle root paths', async () => {
|
|
256
|
+
expect(path.join('/')).toBe('/');
|
|
257
|
+
expect(path.join('/', '.')).toBe('/');
|
|
258
|
+
expect(path.join('/', '..')).toBe('/');
|
|
259
|
+
expect(path.join('/', '..', '..')).toBe('/');
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
await it('should handle leading space in paths', async () => {
|
|
263
|
+
expect(path.join(' /foo')).toBe(' /foo');
|
|
264
|
+
expect(path.join(' ', 'foo')).toBe(' /foo');
|
|
265
|
+
expect(path.join(' ', '.')).toBe(' ');
|
|
266
|
+
expect(path.join(' ', '/')).toBe(' /');
|
|
267
|
+
expect(path.join(' ', '')).toBe(' ');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
await it('should handle multiple absolute segments', async () => {
|
|
271
|
+
expect(path.join('/', 'foo')).toBe('/foo');
|
|
272
|
+
expect(path.join('/', '/foo')).toBe('/foo');
|
|
273
|
+
expect(path.join('/', '//foo')).toBe('/foo');
|
|
274
|
+
expect(path.join('/', '', '/foo')).toBe('/foo');
|
|
275
|
+
expect(path.join('', '/', 'foo')).toBe('/foo');
|
|
276
|
+
expect(path.join('', '/', '/foo')).toBe('/foo');
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// ===== path.normalize =====
|
|
281
|
+
|
|
282
|
+
await describe('path.normalize', async () => {
|
|
283
|
+
await it('should resolve .. and .', async () => {
|
|
284
|
+
expect(path.normalize('/foo/bar//baz/asdf/quux/..')).toBe('/foo/bar/baz/asdf');
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
await it('should return . for empty string', async () => {
|
|
288
|
+
expect(path.normalize('')).toBe('.');
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
await it('should preserve trailing slash', async () => {
|
|
292
|
+
expect(path.normalize('/foo/bar/')).toBe('/foo/bar/');
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
await it('should normalize fixtures path with ..', async () => {
|
|
296
|
+
expect(path.posix.normalize('./fixtures///b/../b/c.js')).toBe('fixtures/b/c.js');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
await it('should not go above root with ..', async () => {
|
|
300
|
+
expect(path.posix.normalize('/foo/../../../bar')).toBe('/bar');
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
await it('should collapse double slashes and ..', async () => {
|
|
304
|
+
expect(path.posix.normalize('a//b//../b')).toBe('a/b');
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
await it('should collapse double slashes and .', async () => {
|
|
308
|
+
expect(path.posix.normalize('a//b//./c')).toBe('a/b/c');
|
|
309
|
+
expect(path.posix.normalize('a//b//.')).toBe('a/b');
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
await it('should handle deeply nested ..', async () => {
|
|
313
|
+
expect(path.posix.normalize('/a/b/c/../../../x/y/z')).toBe('/x/y/z');
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
await it('should handle leading triple slashes and dots', async () => {
|
|
317
|
+
expect(path.posix.normalize('///..//./foo/.//bar')).toBe('/foo/bar');
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
await it('should handle foo.. patterns (not real ..)', async () => {
|
|
321
|
+
expect(path.posix.normalize('bar/foo../../')).toBe('bar/');
|
|
322
|
+
expect(path.posix.normalize('bar/foo../..')).toBe('bar');
|
|
323
|
+
expect(path.posix.normalize('bar/foo../../baz')).toBe('bar/baz');
|
|
324
|
+
expect(path.posix.normalize('bar/foo../')).toBe('bar/foo../');
|
|
325
|
+
expect(path.posix.normalize('bar/foo..')).toBe('bar/foo..');
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
await it('should handle complex relative .. chains', async () => {
|
|
329
|
+
expect(path.posix.normalize('../foo../../../bar')).toBe('../../bar');
|
|
330
|
+
expect(path.posix.normalize('../.../.././.../../../bar')).toBe('../../bar');
|
|
331
|
+
expect(path.posix.normalize('../../../foo/../../../bar')).toBe('../../../../../bar');
|
|
332
|
+
expect(path.posix.normalize('../../../foo/../../../bar/../../')).toBe('../../../../../../');
|
|
333
|
+
expect(path.posix.normalize('../foobar/barfoo/foo/../../../bar/../../')).toBe('../../');
|
|
334
|
+
expect(path.posix.normalize('../.../../foobar/../../../bar/../../baz')).toBe('../../../../baz');
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
await it('should treat backslash as normal character on posix', async () => {
|
|
338
|
+
expect(path.posix.normalize('foo/bar\\baz')).toBe('foo/bar\\baz');
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// ===== path.isAbsolute =====
|
|
343
|
+
|
|
344
|
+
await describe('path.isAbsolute', async () => {
|
|
345
|
+
await it('should return true for absolute paths', async () => {
|
|
346
|
+
expect(path.isAbsolute('/foo/bar')).toBeTruthy();
|
|
347
|
+
expect(path.isAbsolute('/baz/..')).toBeTruthy();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
await it('should return false for relative paths', async () => {
|
|
351
|
+
expect(path.isAbsolute('qux/')).toBeFalsy();
|
|
352
|
+
expect(path.isAbsolute('.')).toBeFalsy();
|
|
353
|
+
expect(path.isAbsolute('')).toBeFalsy();
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
await it('posix: should detect absolute paths', async () => {
|
|
357
|
+
expect(path.posix.isAbsolute('/home/foo')).toBeTruthy();
|
|
358
|
+
expect(path.posix.isAbsolute('/home/foo/..')).toBeTruthy();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
await it('posix: should detect relative paths', async () => {
|
|
362
|
+
expect(path.posix.isAbsolute('bar/')).toBeFalsy();
|
|
363
|
+
expect(path.posix.isAbsolute('./baz')).toBeFalsy();
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
await it('win32: should detect absolute paths', async () => {
|
|
367
|
+
expect(path.win32.isAbsolute('/')).toBeTruthy();
|
|
368
|
+
expect(path.win32.isAbsolute('//')).toBeTruthy();
|
|
369
|
+
expect(path.win32.isAbsolute('//server')).toBeTruthy();
|
|
370
|
+
expect(path.win32.isAbsolute('//server/file')).toBeTruthy();
|
|
371
|
+
expect(path.win32.isAbsolute('\\\\server\\file')).toBeTruthy();
|
|
372
|
+
expect(path.win32.isAbsolute('\\\\server')).toBeTruthy();
|
|
373
|
+
expect(path.win32.isAbsolute('\\\\')).toBeTruthy();
|
|
374
|
+
expect(path.win32.isAbsolute('c:\\')).toBeTruthy();
|
|
375
|
+
expect(path.win32.isAbsolute('c:/')).toBeTruthy();
|
|
376
|
+
expect(path.win32.isAbsolute('c://')).toBeTruthy();
|
|
377
|
+
expect(path.win32.isAbsolute('C:/Users/')).toBeTruthy();
|
|
378
|
+
expect(path.win32.isAbsolute('C:\\Users\\')).toBeTruthy();
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
await it('win32: should detect relative paths', async () => {
|
|
382
|
+
expect(path.win32.isAbsolute('c')).toBeFalsy();
|
|
383
|
+
expect(path.win32.isAbsolute('c:')).toBeFalsy();
|
|
384
|
+
expect(path.win32.isAbsolute('C:cwd/another')).toBeFalsy();
|
|
385
|
+
expect(path.win32.isAbsolute('C:cwd\\another')).toBeFalsy();
|
|
386
|
+
expect(path.win32.isAbsolute('directory/directory')).toBeFalsy();
|
|
387
|
+
expect(path.win32.isAbsolute('directory\\directory')).toBeFalsy();
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// ===== path.resolve =====
|
|
392
|
+
|
|
393
|
+
await describe('path.resolve', async () => {
|
|
394
|
+
await it('should resolve absolute path with relative segment', async () => {
|
|
395
|
+
const result = path.resolve('/foo/bar', './baz');
|
|
396
|
+
expect(result).toBe('/foo/bar/baz');
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
await it('should resolve with absolute segment (later arg wins)', async () => {
|
|
400
|
+
const result = path.resolve('/foo/bar', '/tmp/file/');
|
|
401
|
+
expect(result).toBe('/tmp/file');
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
await it('should handle relative paths by prepending cwd', async () => {
|
|
405
|
+
const result = path.resolve('foo', 'bar', 'baz');
|
|
406
|
+
expect(path.isAbsolute(result)).toBeTruthy();
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
await it('posix: should resolve /var/lib with ../ and file/', async () => {
|
|
410
|
+
expect(path.posix.resolve('/var/lib', '../', 'file/')).toBe('/var/file');
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
await it('posix: should resolve /../ to root', async () => {
|
|
414
|
+
expect(path.posix.resolve('/var/lib', '/../', 'file/')).toBe('/file');
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
await it('posix: should resolve with later absolute overriding earlier', async () => {
|
|
418
|
+
expect(path.posix.resolve('/some/dir', '.', '/absolute/')).toBe('/absolute');
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
await it('posix: should resolve relative cycles with ..', async () => {
|
|
422
|
+
expect(path.posix.resolve('/foo/tmp.3/', '../tmp.3/cycles/root.js')).toBe('/foo/tmp.3/cycles/root.js');
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
await it('should resolve no args or empty string to cwd', async () => {
|
|
426
|
+
const cwd = process.cwd();
|
|
427
|
+
expect(path.resolve()).toBe(cwd);
|
|
428
|
+
expect(path.resolve('')).toBe(cwd);
|
|
429
|
+
expect(path.resolve('.')).toBe(cwd);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
await it('should always return an absolute path', async () => {
|
|
433
|
+
expect(path.isAbsolute(path.resolve('a', 'b', 'c'))).toBeTruthy();
|
|
434
|
+
expect(path.isAbsolute(path.resolve('/a', 'b', 'c'))).toBeTruthy();
|
|
435
|
+
expect(path.isAbsolute(path.resolve('.'))).toBeTruthy();
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// ===== path.relative =====
|
|
440
|
+
|
|
441
|
+
await describe('path.relative', async () => {
|
|
442
|
+
await it('should compute relative path', async () => {
|
|
443
|
+
expect(path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')).toBe('../../impl/bbb');
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
await it('should return empty string for same path', async () => {
|
|
447
|
+
expect(path.relative('/foo/bar', '/foo/bar')).toBe('');
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
await it('posix: should compute parent with ..', async () => {
|
|
451
|
+
expect(path.posix.relative('/var/lib', '/var')).toBe('..');
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
await it('posix: should compute sibling directory', async () => {
|
|
455
|
+
expect(path.posix.relative('/var/lib', '/bin')).toBe('../../bin');
|
|
456
|
+
expect(path.posix.relative('/var/lib', '/var/apache')).toBe('../apache');
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
await it('posix: should compute child from trailing slash', async () => {
|
|
460
|
+
expect(path.posix.relative('/var/', '/var/lib')).toBe('lib');
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
await it('posix: should compute child from root', async () => {
|
|
464
|
+
expect(path.posix.relative('/', '/var/lib')).toBe('var/lib');
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
await it('posix: should compute child with nested path', async () => {
|
|
468
|
+
expect(path.posix.relative('/foo/test', '/foo/test/bar/package.json')).toBe('bar/package.json');
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
await it('posix: should traverse up multiple levels', async () => {
|
|
472
|
+
expect(path.posix.relative('/Users/a/web/b/test/mails', '/Users/a/web/b')).toBe('../..');
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
await it('posix: should handle baz-quux vs baz (not a prefix match)', async () => {
|
|
476
|
+
expect(path.posix.relative('/foo/bar/baz-quux', '/foo/bar/baz')).toBe('../baz');
|
|
477
|
+
expect(path.posix.relative('/foo/bar/baz', '/foo/bar/baz-quux')).toBe('../baz-quux');
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
await it('posix: should handle root-level baz-quux vs baz', async () => {
|
|
481
|
+
expect(path.posix.relative('/baz-quux', '/baz')).toBe('../baz');
|
|
482
|
+
expect(path.posix.relative('/baz', '/baz-quux')).toBe('../baz-quux');
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
await it('posix: should traverse from deep path to root', async () => {
|
|
486
|
+
expect(path.posix.relative('/page1/page2/foo', '/')).toBe('../../..');
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
await it('should handle empty strings as cwd', async () => {
|
|
490
|
+
const cwd = process.cwd();
|
|
491
|
+
expect(path.relative('', cwd)).toBe('');
|
|
492
|
+
expect(path.relative(cwd, '')).toBe('');
|
|
493
|
+
expect(path.relative(cwd, cwd)).toBe('');
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// ===== path.parse =====
|
|
498
|
+
|
|
499
|
+
await describe('path.parse', async () => {
|
|
500
|
+
await it('should parse a path into components', async () => {
|
|
501
|
+
const parsed = path.parse('/home/user/dir/file.txt');
|
|
502
|
+
expect(parsed.root).toBe('/');
|
|
503
|
+
expect(parsed.dir).toBe('/home/user/dir');
|
|
504
|
+
expect(parsed.base).toBe('file.txt');
|
|
505
|
+
expect(parsed.ext).toBe('.txt');
|
|
506
|
+
expect(parsed.name).toBe('file');
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
await it('should handle root path', async () => {
|
|
510
|
+
const parsed = path.parse('/');
|
|
511
|
+
expect(parsed.root).toBe('/');
|
|
512
|
+
expect(parsed.dir).toBe('/');
|
|
513
|
+
expect(parsed.base).toBe('');
|
|
514
|
+
expect(parsed.ext).toBe('');
|
|
515
|
+
expect(parsed.name).toBe('');
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
await it('should handle relative path', async () => {
|
|
519
|
+
const parsed = path.parse('file.txt');
|
|
520
|
+
expect(parsed.root).toBe('');
|
|
521
|
+
expect(parsed.base).toBe('file.txt');
|
|
522
|
+
expect(parsed.name).toBe('file');
|
|
523
|
+
expect(parsed.ext).toBe('.txt');
|
|
524
|
+
expect(parsed.dir).toBe('');
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
await it('should return all string-typed fields', async () => {
|
|
528
|
+
const parsed = path.parse('/home/user/dir/file.txt');
|
|
529
|
+
expect(typeof parsed.root).toBe('string');
|
|
530
|
+
expect(typeof parsed.dir).toBe('string');
|
|
531
|
+
expect(typeof parsed.base).toBe('string');
|
|
532
|
+
expect(typeof parsed.ext).toBe('string');
|
|
533
|
+
expect(typeof parsed.name).toBe('string');
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
await it('should roundtrip with format for unix paths', async () => {
|
|
537
|
+
const unixPaths = [
|
|
538
|
+
'/home/user/dir/file.txt',
|
|
539
|
+
'/home/user/a dir/another File.zip',
|
|
540
|
+
'/home/user/a dir//another&File.',
|
|
541
|
+
'/home/user/a$$$dir//another File.zip',
|
|
542
|
+
'user/dir/another File.zip',
|
|
543
|
+
'file',
|
|
544
|
+
'.\\file',
|
|
545
|
+
'./file',
|
|
546
|
+
'C:\\foo',
|
|
547
|
+
'/',
|
|
548
|
+
'',
|
|
549
|
+
'.',
|
|
550
|
+
'..',
|
|
551
|
+
'/foo',
|
|
552
|
+
'/foo.',
|
|
553
|
+
'/foo.bar',
|
|
554
|
+
'/.',
|
|
555
|
+
'/.foo',
|
|
556
|
+
'/.foo.bar',
|
|
557
|
+
'/foo/bar.baz',
|
|
558
|
+
];
|
|
559
|
+
for (const p of unixPaths) {
|
|
560
|
+
const output = path.posix.parse(p);
|
|
561
|
+
expect(path.posix.format(output)).toBe(p);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
await it('should parse dotfiles correctly', async () => {
|
|
566
|
+
const parsed = path.parse('/.foo');
|
|
567
|
+
expect(parsed.root).toBe('/');
|
|
568
|
+
expect(parsed.base).toBe('.foo');
|
|
569
|
+
expect(parsed.ext).toBe('');
|
|
570
|
+
expect(parsed.name).toBe('.foo');
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
await it('should parse dotfile with extension', async () => {
|
|
574
|
+
const parsed = path.parse('/.foo.bar');
|
|
575
|
+
expect(parsed.root).toBe('/');
|
|
576
|
+
expect(parsed.base).toBe('.foo.bar');
|
|
577
|
+
expect(parsed.ext).toBe('.bar');
|
|
578
|
+
expect(parsed.name).toBe('.foo');
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
await it('should handle filename with trailing dot', async () => {
|
|
582
|
+
const parsed = path.parse('/foo.');
|
|
583
|
+
expect(parsed.root).toBe('/');
|
|
584
|
+
expect(parsed.base).toBe('foo.');
|
|
585
|
+
expect(parsed.ext).toBe('.');
|
|
586
|
+
expect(parsed.name).toBe('foo');
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
await it('should handle empty root for relative paths', async () => {
|
|
590
|
+
const tests: [string, string][] = [
|
|
591
|
+
['user/dir/another File.zip', ''],
|
|
592
|
+
['file', ''],
|
|
593
|
+
['.\\file', ''],
|
|
594
|
+
['./file', ''],
|
|
595
|
+
['C:\\foo', ''],
|
|
596
|
+
['.', ''],
|
|
597
|
+
['..', ''],
|
|
598
|
+
];
|
|
599
|
+
for (const [p, expectedRoot] of tests) {
|
|
600
|
+
const parsed = path.posix.parse(p);
|
|
601
|
+
expect(parsed.root).toBe(expectedRoot);
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
await it('should have dir starting with root', async () => {
|
|
606
|
+
const pathsToCheck = [
|
|
607
|
+
'/home/user/dir/file.txt',
|
|
608
|
+
'/foo',
|
|
609
|
+
'/foo.bar',
|
|
610
|
+
'/foo/bar.baz',
|
|
611
|
+
];
|
|
612
|
+
for (const p of pathsToCheck) {
|
|
613
|
+
const parsed = path.parse(p);
|
|
614
|
+
expect(parsed.dir.startsWith(parsed.root)).toBeTruthy();
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
await it('posix: should handle trailing separators on parse', async () => {
|
|
619
|
+
let parsed = path.posix.parse('./');
|
|
620
|
+
expect(parsed.root).toBe('');
|
|
621
|
+
expect(parsed.dir).toBe('');
|
|
622
|
+
expect(parsed.base).toBe('.');
|
|
623
|
+
expect(parsed.ext).toBe('');
|
|
624
|
+
expect(parsed.name).toBe('.');
|
|
625
|
+
|
|
626
|
+
parsed = path.posix.parse('//');
|
|
627
|
+
expect(parsed.root).toBe('/');
|
|
628
|
+
expect(parsed.dir).toBe('/');
|
|
629
|
+
expect(parsed.base).toBe('');
|
|
630
|
+
expect(parsed.name).toBe('');
|
|
631
|
+
|
|
632
|
+
parsed = path.posix.parse('///');
|
|
633
|
+
expect(parsed.root).toBe('/');
|
|
634
|
+
expect(parsed.dir).toBe('/');
|
|
635
|
+
expect(parsed.base).toBe('');
|
|
636
|
+
expect(parsed.name).toBe('');
|
|
637
|
+
|
|
638
|
+
parsed = path.posix.parse('/foo///');
|
|
639
|
+
expect(parsed.root).toBe('/');
|
|
640
|
+
expect(parsed.dir).toBe('/');
|
|
641
|
+
expect(parsed.base).toBe('foo');
|
|
642
|
+
expect(parsed.name).toBe('foo');
|
|
643
|
+
expect(parsed.ext).toBe('');
|
|
644
|
+
|
|
645
|
+
parsed = path.posix.parse('/foo///bar.baz');
|
|
646
|
+
expect(parsed.root).toBe('/');
|
|
647
|
+
expect(parsed.dir).toBe('/foo//');
|
|
648
|
+
expect(parsed.base).toBe('bar.baz');
|
|
649
|
+
expect(parsed.ext).toBe('.baz');
|
|
650
|
+
expect(parsed.name).toBe('bar');
|
|
651
|
+
});
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
// ===== path.format =====
|
|
655
|
+
|
|
656
|
+
await describe('path.format', async () => {
|
|
657
|
+
await it('should format a path object', async () => {
|
|
658
|
+
expect(path.format({
|
|
659
|
+
root: '/',
|
|
660
|
+
dir: '/home/user/dir',
|
|
661
|
+
base: 'file.txt'
|
|
662
|
+
})).toBe('/home/user/dir/file.txt');
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
await it('should use name and ext if base is not provided', async () => {
|
|
666
|
+
expect(path.format({
|
|
667
|
+
root: '/',
|
|
668
|
+
name: 'file',
|
|
669
|
+
ext: '.txt'
|
|
670
|
+
})).toBe('/file.txt');
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
await it('should format with dir only (adds trailing sep)', async () => {
|
|
674
|
+
expect(path.format({ dir: 'some/dir' })).toBe('some/dir/');
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
await it('should format with base only', async () => {
|
|
678
|
+
expect(path.format({ base: 'index.html' })).toBe('index.html');
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
await it('should format with root only', async () => {
|
|
682
|
+
expect(path.format({ root: '/' })).toBe('/');
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
await it('should format with name and ext only', async () => {
|
|
686
|
+
expect(path.format({ name: 'index', ext: '.html' })).toBe('index.html');
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
await it('should prefer dir over root when both present with name+ext', async () => {
|
|
690
|
+
expect(path.format({ dir: 'some/dir', name: 'index', ext: '.html' })).toBe('some/dir/index.html');
|
|
691
|
+
expect(path.format({ root: '/', name: 'index', ext: '.html' })).toBe('/index.html');
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
await it('should return empty string for empty object', async () => {
|
|
695
|
+
expect(path.format({})).toBe('');
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
await it('should handle ext without leading dot', async () => {
|
|
699
|
+
expect(path.format({ name: 'x', ext: 'png' })).toBe('x.png');
|
|
700
|
+
expect(path.format({ name: 'x', ext: '.png' })).toBe('x.png');
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
// ===== path.sep and path.delimiter =====
|
|
705
|
+
|
|
706
|
+
await describe('path.sep and path.delimiter', async () => {
|
|
707
|
+
await it('should have correct separator', async () => {
|
|
708
|
+
expect(path.sep).toBe('/');
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
await it('should have correct delimiter', async () => {
|
|
712
|
+
expect(path.delimiter).toBe(':');
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
await it('posix should have : delimiter', async () => {
|
|
716
|
+
expect(path.posix.delimiter).toBe(':');
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
await it('win32 should have ; delimiter', async () => {
|
|
720
|
+
expect(path.win32.delimiter).toBe(';');
|
|
721
|
+
});
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// ===== path.toNamespacedPath =====
|
|
725
|
+
|
|
726
|
+
await describe('path.toNamespacedPath', async () => {
|
|
727
|
+
await it('should be a no-op on POSIX', async () => {
|
|
728
|
+
expect(path.toNamespacedPath('/foo/bar')).toBe('/foo/bar');
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
await it('should return the same value for any string on posix', async () => {
|
|
732
|
+
expect(path.posix.toNamespacedPath('/foo/bar')).toBe('/foo/bar');
|
|
733
|
+
expect(path.posix.toNamespacedPath('foo/bar')).toBe('foo/bar');
|
|
734
|
+
expect(path.posix.toNamespacedPath('')).toBe('');
|
|
735
|
+
});
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
// ===== path.posix and path.win32 =====
|
|
739
|
+
|
|
740
|
+
await describe('path.posix and path.win32', async () => {
|
|
741
|
+
await it('should export posix sub-module', async () => {
|
|
742
|
+
expect(path.posix).toBeDefined();
|
|
743
|
+
expect(typeof path.posix.join).toBe('function');
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
await it('should export win32 sub-module', async () => {
|
|
747
|
+
expect(path.win32).toBeDefined();
|
|
748
|
+
expect(typeof path.win32.join).toBe('function');
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
await it('posix should have / separator', async () => {
|
|
752
|
+
expect(path.posix.sep).toBe('/');
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
await it('win32 should have \\\\ separator', async () => {
|
|
756
|
+
expect(path.win32.sep).toBe('\\');
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
await it('posix should export all path methods', async () => {
|
|
760
|
+
expect(typeof path.posix.resolve).toBe('function');
|
|
761
|
+
expect(typeof path.posix.normalize).toBe('function');
|
|
762
|
+
expect(typeof path.posix.isAbsolute).toBe('function');
|
|
763
|
+
expect(typeof path.posix.relative).toBe('function');
|
|
764
|
+
expect(typeof path.posix.dirname).toBe('function');
|
|
765
|
+
expect(typeof path.posix.basename).toBe('function');
|
|
766
|
+
expect(typeof path.posix.extname).toBe('function');
|
|
767
|
+
expect(typeof path.posix.format).toBe('function');
|
|
768
|
+
expect(typeof path.posix.parse).toBe('function');
|
|
769
|
+
expect(typeof path.posix.toNamespacedPath).toBe('function');
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
await it('win32 should export all path methods', async () => {
|
|
773
|
+
expect(typeof path.win32.resolve).toBe('function');
|
|
774
|
+
expect(typeof path.win32.normalize).toBe('function');
|
|
775
|
+
expect(typeof path.win32.isAbsolute).toBe('function');
|
|
776
|
+
expect(typeof path.win32.relative).toBe('function');
|
|
777
|
+
expect(typeof path.win32.dirname).toBe('function');
|
|
778
|
+
expect(typeof path.win32.basename).toBe('function');
|
|
779
|
+
expect(typeof path.win32.extname).toBe('function');
|
|
780
|
+
expect(typeof path.win32.format).toBe('function');
|
|
781
|
+
expect(typeof path.win32.parse).toBe('function');
|
|
782
|
+
expect(typeof path.win32.toNamespacedPath).toBe('function');
|
|
783
|
+
});
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
// ===== path.win32 specific tests =====
|
|
787
|
+
|
|
788
|
+
await describe('path.win32', async () => {
|
|
789
|
+
await it('win32.basename should handle backslashes', async () => {
|
|
790
|
+
expect(path.win32.basename('\\dir\\basename.ext')).toBe('basename.ext');
|
|
791
|
+
expect(path.win32.basename('\\basename.ext')).toBe('basename.ext');
|
|
792
|
+
expect(path.win32.basename('basename.ext')).toBe('basename.ext');
|
|
793
|
+
expect(path.win32.basename('basename.ext\\')).toBe('basename.ext');
|
|
794
|
+
expect(path.win32.basename('basename.ext\\\\')).toBe('basename.ext');
|
|
795
|
+
expect(path.win32.basename('foo')).toBe('foo');
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
await it('win32.basename should handle drive letters', async () => {
|
|
799
|
+
expect(path.win32.basename('C:')).toBe('');
|
|
800
|
+
expect(path.win32.basename('C:.')).toBe('.');
|
|
801
|
+
expect(path.win32.basename('C:\\')).toBe('');
|
|
802
|
+
expect(path.win32.basename('C:\\dir\\base.ext')).toBe('base.ext');
|
|
803
|
+
expect(path.win32.basename('C:\\basename.ext')).toBe('basename.ext');
|
|
804
|
+
expect(path.win32.basename('C:basename.ext')).toBe('basename.ext');
|
|
805
|
+
expect(path.win32.basename('C:basename.ext\\')).toBe('basename.ext');
|
|
806
|
+
expect(path.win32.basename('C:basename.ext\\\\')).toBe('basename.ext');
|
|
807
|
+
expect(path.win32.basename('C:foo')).toBe('foo');
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
await it('win32.basename should handle file:stream', async () => {
|
|
811
|
+
expect(path.win32.basename('file:stream')).toBe('file:stream');
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
await it('win32.dirname should handle drive letters and UNC', async () => {
|
|
815
|
+
expect(path.win32.dirname('c:\\')).toBe('c:\\');
|
|
816
|
+
expect(path.win32.dirname('c:\\foo')).toBe('c:\\');
|
|
817
|
+
expect(path.win32.dirname('c:\\foo\\')).toBe('c:\\');
|
|
818
|
+
expect(path.win32.dirname('c:\\foo\\bar')).toBe('c:\\foo');
|
|
819
|
+
expect(path.win32.dirname('c:\\foo\\bar\\')).toBe('c:\\foo');
|
|
820
|
+
expect(path.win32.dirname('c:\\foo\\bar\\baz')).toBe('c:\\foo\\bar');
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
await it('win32.dirname should handle UNC paths', async () => {
|
|
824
|
+
expect(path.win32.dirname('\\\\unc\\share')).toBe('\\\\unc\\share');
|
|
825
|
+
expect(path.win32.dirname('\\\\unc\\share\\foo')).toBe('\\\\unc\\share\\');
|
|
826
|
+
expect(path.win32.dirname('\\\\unc\\share\\foo\\')).toBe('\\\\unc\\share\\');
|
|
827
|
+
expect(path.win32.dirname('\\\\unc\\share\\foo\\bar')).toBe('\\\\unc\\share\\foo');
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
await it('win32.normalize should handle various paths', async () => {
|
|
831
|
+
expect(path.win32.normalize('./fixtures///b/../b/c.js')).toBe('fixtures\\b\\c.js');
|
|
832
|
+
expect(path.win32.normalize('/foo/../../../bar')).toBe('\\bar');
|
|
833
|
+
expect(path.win32.normalize('a//b//../b')).toBe('a\\b');
|
|
834
|
+
expect(path.win32.normalize('a//b//./c')).toBe('a\\b\\c');
|
|
835
|
+
expect(path.win32.normalize('a//b//.')).toBe('a\\b');
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
await it('win32.normalize should handle C: paths', async () => {
|
|
839
|
+
expect(path.win32.normalize('C:')).toBe('C:.');
|
|
840
|
+
expect(path.win32.normalize('C:\\.')).toBe('C:\\');
|
|
841
|
+
expect(path.win32.normalize('file:stream')).toBe('file:stream');
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
await it('win32.parse should handle windows paths', async () => {
|
|
845
|
+
const parsed = path.win32.parse('C:\\path\\dir\\index.html');
|
|
846
|
+
expect(parsed.root).toBe('C:\\');
|
|
847
|
+
expect(parsed.dir).toBe('C:\\path\\dir');
|
|
848
|
+
expect(parsed.base).toBe('index.html');
|
|
849
|
+
expect(parsed.ext).toBe('.html');
|
|
850
|
+
expect(parsed.name).toBe('index');
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
await it('win32.parse should handle UNC paths', async () => {
|
|
854
|
+
const parsed = path.win32.parse('\\\\server\\share\\file_path');
|
|
855
|
+
expect(parsed.root).toBe('\\\\server\\share\\');
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
await it('win32.format should format windows paths', async () => {
|
|
859
|
+
expect(path.win32.format({ dir: 'some\\dir' })).toBe('some\\dir\\');
|
|
860
|
+
expect(path.win32.format({ base: 'index.html' })).toBe('index.html');
|
|
861
|
+
expect(path.win32.format({ root: 'C:\\' })).toBe('C:\\');
|
|
862
|
+
expect(path.win32.format({ name: 'index', ext: '.html' })).toBe('index.html');
|
|
863
|
+
expect(path.win32.format({ dir: 'some\\dir', name: 'index', ext: '.html' })).toBe('some\\dir\\index.html');
|
|
864
|
+
expect(path.win32.format({ root: 'C:\\', name: 'index', ext: '.html' })).toBe('C:\\index.html');
|
|
865
|
+
expect(path.win32.format({})).toBe('');
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
await it('win32.relative should compute relative paths', async () => {
|
|
869
|
+
expect(path.win32.relative('c:/aaaa/bbbb', 'c:/aaaa')).toBe('..');
|
|
870
|
+
expect(path.win32.relative('c:/aaaa/bbbb', 'c:/cccc')).toBe('..\\..\\cccc');
|
|
871
|
+
expect(path.win32.relative('c:/aaaa/bbbb', 'c:/aaaa/bbbb')).toBe('');
|
|
872
|
+
expect(path.win32.relative('c:/aaaa/bbbb', 'c:/aaaa/cccc')).toBe('..\\cccc');
|
|
873
|
+
expect(path.win32.relative('c:/aaaa/', 'c:/aaaa/cccc')).toBe('cccc');
|
|
874
|
+
expect(path.win32.relative('c:/', 'c:\\aaaa\\bbbb')).toBe('aaaa\\bbbb');
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
await it('win32: case-insensitive drive letter comparison', async () => {
|
|
878
|
+
expect(path.win32.relative('c:/AaAa/bbbb', 'c:/aaaa/bbbb')).toBe('');
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
await it('win32.relative should handle cross-drive paths', async () => {
|
|
882
|
+
expect(path.win32.relative('c:/aaaa/bbbb', 'd:\\')).toBe('d:\\');
|
|
883
|
+
expect(path.win32.relative('c:/blah\\blah', 'd:/games')).toBe('d:\\games');
|
|
884
|
+
});
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// ===== Edge cases: zero-length strings =====
|
|
888
|
+
|
|
889
|
+
await describe('path zero-length strings', async () => {
|
|
890
|
+
await it('join should return . for zero-length input', async () => {
|
|
891
|
+
expect(path.posix.join('')).toBe('.');
|
|
892
|
+
expect(path.posix.join('', '')).toBe('.');
|
|
893
|
+
expect(path.win32.join('')).toBe('.');
|
|
894
|
+
expect(path.win32.join('', '')).toBe('.');
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
await it('normalize should return . for zero-length input', async () => {
|
|
898
|
+
expect(path.posix.normalize('')).toBe('.');
|
|
899
|
+
expect(path.win32.normalize('')).toBe('.');
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
await it('isAbsolute should return false for empty string', async () => {
|
|
903
|
+
expect(path.posix.isAbsolute('')).toBeFalsy();
|
|
904
|
+
expect(path.win32.isAbsolute('')).toBeFalsy();
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
await it('resolve should return cwd for empty string args', async () => {
|
|
908
|
+
const cwd = process.cwd();
|
|
909
|
+
expect(path.resolve('')).toBe(cwd);
|
|
910
|
+
expect(path.resolve('', '')).toBe(cwd);
|
|
911
|
+
});
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
// ===== Edge cases: misc =====
|
|
915
|
+
|
|
916
|
+
await describe('path edge cases', async () => {
|
|
917
|
+
await it('parse should have consistent dirname and basename', async () => {
|
|
918
|
+
const testPaths = [
|
|
919
|
+
'/home/user/dir/file.txt',
|
|
920
|
+
'/foo',
|
|
921
|
+
'/foo.bar',
|
|
922
|
+
'file',
|
|
923
|
+
'./file',
|
|
924
|
+
];
|
|
925
|
+
for (const p of testPaths) {
|
|
926
|
+
const parsed = path.parse(p);
|
|
927
|
+
expect(parsed.base).toBe(path.basename(p));
|
|
928
|
+
expect(parsed.ext).toBe(path.extname(p));
|
|
929
|
+
if (parsed.dir) {
|
|
930
|
+
expect(parsed.dir).toBe(path.dirname(p));
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
await it('posix.basename should treat backslash as normal char', async () => {
|
|
936
|
+
expect(path.posix.basename('\\dir\\basename.ext')).toBe('\\dir\\basename.ext');
|
|
937
|
+
expect(path.posix.basename('\\basename.ext')).toBe('\\basename.ext');
|
|
938
|
+
expect(path.posix.basename('basename.ext\\')).toBe('basename.ext\\');
|
|
939
|
+
expect(path.posix.basename('basename.ext\\\\')).toBe('basename.ext\\\\');
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
await it('posix.extname should treat backslash as normal char', async () => {
|
|
943
|
+
expect(path.posix.extname('.\\')).toBe('');
|
|
944
|
+
expect(path.posix.extname('..\\')).toBe('.\\');
|
|
945
|
+
expect(path.posix.extname('file.ext\\')).toBe('.ext\\');
|
|
946
|
+
expect(path.posix.extname('file.ext\\\\')).toBe('.ext\\\\');
|
|
947
|
+
expect(path.posix.extname('file\\')).toBe('');
|
|
948
|
+
expect(path.posix.extname('file\\\\')).toBe('');
|
|
949
|
+
expect(path.posix.extname('file.\\')).toBe('.\\');
|
|
950
|
+
expect(path.posix.extname('file.\\\\')).toBe('.\\\\');
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
await it('join should preserve cwd when joining with it', async () => {
|
|
954
|
+
const cwd = process.cwd();
|
|
955
|
+
expect(path.join(cwd)).toBe(cwd);
|
|
956
|
+
expect(path.join(cwd, '')).toBe(cwd);
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
await it('normalize should preserve cwd', async () => {
|
|
960
|
+
const cwd = process.cwd();
|
|
961
|
+
expect(path.normalize(cwd)).toBe(cwd);
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
}
|