Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/test/common/glob.test.ts
5240 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import * as glob from '../../common/glob.js';
8
import { sep } from '../../common/path.js';
9
import { isLinux, isMacintosh, isWindows } from '../../common/platform.js';
10
import { URI } from '../../common/uri.js';
11
import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';
12
13
suite('Glob', () => {
14
15
// test('perf', () => {
16
17
// let patterns = [
18
// '{**/*.cs,**/*.json,**/*.csproj,**/*.sln}',
19
// '{**/*.cs,**/*.csproj,**/*.sln}',
20
// '{**/*.ts,**/*.tsx,**/*.js,**/*.jsx,**/*.es6,**/*.mjs,**/*.cjs}',
21
// '**/*.go',
22
// '{**/*.ps,**/*.ps1}',
23
// '{**/*.c,**/*.cpp,**/*.h}',
24
// '{**/*.fsx,**/*.fsi,**/*.fs,**/*.ml,**/*.mli}',
25
// '{**/*.js,**/*.jsx,**/*.es6,**/*.mjs,**/*.cjs}',
26
// '{**/*.ts,**/*.tsx}',
27
// '{**/*.php}',
28
// '{**/*.php}',
29
// '{**/*.php}',
30
// '{**/*.php}',
31
// '{**/*.py}',
32
// '{**/*.py}',
33
// '{**/*.py}',
34
// '{**/*.rs,**/*.rslib}',
35
// '{**/*.cpp,**/*.cc,**/*.h}',
36
// '{**/*.md}',
37
// '{**/*.md}',
38
// '{**/*.md}'
39
// ];
40
41
// let paths = [
42
// '/DNXConsoleApp/Program.cs',
43
// 'C:\\DNXConsoleApp\\foo\\Program.cs',
44
// 'test/qunit',
45
// 'test/test.txt',
46
// 'test/node_modules',
47
// '.hidden.txt',
48
// '/node_module/test/foo.js'
49
// ];
50
51
// let results = 0;
52
// let c = 1000;
53
// console.profile('glob.match');
54
// while (c-- > 0) {
55
// for (let path of paths) {
56
// for (let pattern of patterns) {
57
// let r = glob.match(pattern, path);
58
// if (r) {
59
// results += 42;
60
// }
61
// }
62
// }
63
// }
64
// console.profileEnd();
65
// });
66
67
function assertGlobMatch(pattern: string | glob.IRelativePattern, input: string, ignoreCase?: boolean) {
68
assert(glob.match(pattern, input, { ignoreCase }), `${JSON.stringify(pattern)} should match ${input}`);
69
assert(glob.match(pattern, nativeSep(input), { ignoreCase }), `${pattern} should match ${nativeSep(input)}`);
70
}
71
72
function assertNoGlobMatch(pattern: string | glob.IRelativePattern, input: string, ignoreCase?: boolean) {
73
assert(!glob.match(pattern, input, { ignoreCase }), `${pattern} should not match ${input}`);
74
assert(!glob.match(pattern, nativeSep(input), { ignoreCase }), `${pattern} should not match ${nativeSep(input)}`);
75
}
76
77
test('simple', () => {
78
let p = 'node_modules';
79
80
assertGlobMatch(p, 'node_modules');
81
assertNoGlobMatch(p, 'node_module');
82
assertNoGlobMatch(p, '/node_modules');
83
assertNoGlobMatch(p, 'test/node_modules');
84
85
p = 'test.txt';
86
assertGlobMatch(p, 'test.txt');
87
assertNoGlobMatch(p, 'test?txt');
88
assertNoGlobMatch(p, '/text.txt');
89
assertNoGlobMatch(p, 'test/test.txt');
90
91
p = 'test(.txt';
92
assertGlobMatch(p, 'test(.txt');
93
assertNoGlobMatch(p, 'test?txt');
94
95
p = 'qunit';
96
97
assertGlobMatch(p, 'qunit');
98
assertNoGlobMatch(p, 'qunit.css');
99
assertNoGlobMatch(p, 'test/qunit');
100
101
// Absolute
102
103
p = '/DNXConsoleApp/**/*.cs';
104
assertGlobMatch(p, '/DNXConsoleApp/Program.cs');
105
assertGlobMatch(p, '/DNXConsoleApp/foo/Program.cs');
106
107
p = 'C:/DNXConsoleApp/**/*.cs';
108
assertGlobMatch(p, 'C:\\DNXConsoleApp\\Program.cs');
109
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs');
110
111
p = '*';
112
assertGlobMatch(p, '');
113
});
114
115
test('dot hidden', function () {
116
let p = '.*';
117
118
assertGlobMatch(p, '.git');
119
assertGlobMatch(p, '.hidden.txt');
120
assertNoGlobMatch(p, 'git');
121
assertNoGlobMatch(p, 'hidden.txt');
122
assertNoGlobMatch(p, 'path/.git');
123
assertNoGlobMatch(p, 'path/.hidden.txt');
124
125
p = '**/.*';
126
assertGlobMatch(p, '.git');
127
assertGlobMatch(p, '/.git');
128
assertGlobMatch(p, '.hidden.txt');
129
assertNoGlobMatch(p, 'git');
130
assertNoGlobMatch(p, 'hidden.txt');
131
assertGlobMatch(p, 'path/.git');
132
assertGlobMatch(p, 'path/.hidden.txt');
133
assertGlobMatch(p, '/path/.git');
134
assertGlobMatch(p, '/path/.hidden.txt');
135
assertNoGlobMatch(p, 'path/git');
136
assertNoGlobMatch(p, 'pat.h/hidden.txt');
137
138
p = '._*';
139
140
assertGlobMatch(p, '._git');
141
assertGlobMatch(p, '._hidden.txt');
142
assertNoGlobMatch(p, 'git');
143
assertNoGlobMatch(p, 'hidden.txt');
144
assertNoGlobMatch(p, 'path/._git');
145
assertNoGlobMatch(p, 'path/._hidden.txt');
146
147
p = '**/._*';
148
assertGlobMatch(p, '._git');
149
assertGlobMatch(p, '._hidden.txt');
150
assertNoGlobMatch(p, 'git');
151
assertNoGlobMatch(p, 'hidden._txt');
152
assertGlobMatch(p, 'path/._git');
153
assertGlobMatch(p, 'path/._hidden.txt');
154
assertGlobMatch(p, '/path/._git');
155
assertGlobMatch(p, '/path/._hidden.txt');
156
assertNoGlobMatch(p, 'path/git');
157
assertNoGlobMatch(p, 'pat.h/hidden._txt');
158
});
159
160
test('file pattern', function () {
161
let p = '*.js';
162
163
assertGlobMatch(p, 'foo.js');
164
assertNoGlobMatch(p, 'folder/foo.js');
165
assertNoGlobMatch(p, '/node_modules/foo.js');
166
assertNoGlobMatch(p, 'foo.jss');
167
assertNoGlobMatch(p, 'some.js/test');
168
169
p = 'html.*';
170
assertGlobMatch(p, 'html.js');
171
assertGlobMatch(p, 'html.txt');
172
assertNoGlobMatch(p, 'htm.txt');
173
174
p = '*.*';
175
assertGlobMatch(p, 'html.js');
176
assertGlobMatch(p, 'html.txt');
177
assertGlobMatch(p, 'htm.txt');
178
assertNoGlobMatch(p, 'folder/foo.js');
179
assertNoGlobMatch(p, '/node_modules/foo.js');
180
181
p = 'node_modules/test/*.js';
182
assertGlobMatch(p, 'node_modules/test/foo.js');
183
assertNoGlobMatch(p, 'folder/foo.js');
184
assertNoGlobMatch(p, '/node_module/test/foo.js');
185
assertNoGlobMatch(p, 'foo.jss');
186
assertNoGlobMatch(p, 'some.js/test');
187
});
188
189
test('star', () => {
190
let p = 'node*modules';
191
192
assertGlobMatch(p, 'node_modules');
193
assertGlobMatch(p, 'node_super_modules');
194
assertNoGlobMatch(p, 'node_module');
195
assertNoGlobMatch(p, '/node_modules');
196
assertNoGlobMatch(p, 'test/node_modules');
197
198
p = '*';
199
assertGlobMatch(p, 'html.js');
200
assertGlobMatch(p, 'html.txt');
201
assertGlobMatch(p, 'htm.txt');
202
assertNoGlobMatch(p, 'folder/foo.js');
203
assertNoGlobMatch(p, '/node_modules/foo.js');
204
});
205
206
test('file / folder match', function () {
207
const p = '**/node_modules/**';
208
209
assertGlobMatch(p, 'node_modules');
210
assertGlobMatch(p, 'node_modules/');
211
assertGlobMatch(p, 'a/node_modules');
212
assertGlobMatch(p, 'a/node_modules/');
213
assertGlobMatch(p, 'node_modules/foo');
214
assertGlobMatch(p, 'foo/node_modules/foo/bar');
215
216
assertGlobMatch(p, '/node_modules');
217
assertGlobMatch(p, '/node_modules/');
218
assertGlobMatch(p, '/a/node_modules');
219
assertGlobMatch(p, '/a/node_modules/');
220
assertGlobMatch(p, '/node_modules/foo');
221
assertGlobMatch(p, '/foo/node_modules/foo/bar');
222
});
223
224
test('questionmark', () => {
225
let p = 'node?modules';
226
227
assertGlobMatch(p, 'node_modules');
228
assertNoGlobMatch(p, 'node_super_modules');
229
assertNoGlobMatch(p, 'node_module');
230
assertNoGlobMatch(p, '/node_modules');
231
assertNoGlobMatch(p, 'test/node_modules');
232
233
p = '?';
234
assertGlobMatch(p, 'h');
235
assertNoGlobMatch(p, 'html.txt');
236
assertNoGlobMatch(p, 'htm.txt');
237
assertNoGlobMatch(p, 'folder/foo.js');
238
assertNoGlobMatch(p, '/node_modules/foo.js');
239
});
240
241
test('globstar', () => {
242
let p = '**/*.js';
243
244
assertGlobMatch(p, 'foo.js');
245
assertGlobMatch(p, '/foo.js');
246
assertGlobMatch(p, 'folder/foo.js');
247
assertGlobMatch(p, '/node_modules/foo.js');
248
assertNoGlobMatch(p, 'foo.jss');
249
assertNoGlobMatch(p, 'some.js/test');
250
assertNoGlobMatch(p, '/some.js/test');
251
assertNoGlobMatch(p, '\\some.js\\test');
252
253
p = '**/project.json';
254
255
assertGlobMatch(p, 'project.json');
256
assertGlobMatch(p, '/project.json');
257
assertGlobMatch(p, 'some/folder/project.json');
258
assertGlobMatch(p, '/some/folder/project.json');
259
assertNoGlobMatch(p, 'some/folder/file_project.json');
260
assertNoGlobMatch(p, 'some/folder/fileproject.json');
261
assertNoGlobMatch(p, 'some/rrproject.json');
262
assertNoGlobMatch(p, 'some\\rrproject.json');
263
264
p = 'test/**';
265
assertGlobMatch(p, 'test');
266
assertGlobMatch(p, 'test/foo');
267
assertGlobMatch(p, 'test/foo/');
268
assertGlobMatch(p, 'test/foo.js');
269
assertGlobMatch(p, 'test/other/foo.js');
270
assertNoGlobMatch(p, 'est/other/foo.js');
271
272
p = '**';
273
assertGlobMatch(p, '/');
274
assertGlobMatch(p, 'foo.js');
275
assertGlobMatch(p, 'folder/foo.js');
276
assertGlobMatch(p, 'folder/foo/');
277
assertGlobMatch(p, '/node_modules/foo.js');
278
assertGlobMatch(p, 'foo.jss');
279
assertGlobMatch(p, 'some.js/test');
280
281
p = 'test/**/*.js';
282
assertGlobMatch(p, 'test/foo.js');
283
assertGlobMatch(p, 'test/other/foo.js');
284
assertGlobMatch(p, 'test/other/more/foo.js');
285
assertNoGlobMatch(p, 'test/foo.ts');
286
assertNoGlobMatch(p, 'test/other/foo.ts');
287
assertNoGlobMatch(p, 'test/other/more/foo.ts');
288
289
p = '**/**/*.js';
290
291
assertGlobMatch(p, 'foo.js');
292
assertGlobMatch(p, '/foo.js');
293
assertGlobMatch(p, 'folder/foo.js');
294
assertGlobMatch(p, '/node_modules/foo.js');
295
assertNoGlobMatch(p, 'foo.jss');
296
assertNoGlobMatch(p, 'some.js/test');
297
298
p = '**/node_modules/**/*.js';
299
300
assertNoGlobMatch(p, 'foo.js');
301
assertNoGlobMatch(p, 'folder/foo.js');
302
assertGlobMatch(p, 'node_modules/foo.js');
303
assertGlobMatch(p, '/node_modules/foo.js');
304
assertGlobMatch(p, 'node_modules/some/folder/foo.js');
305
assertGlobMatch(p, '/node_modules/some/folder/foo.js');
306
assertNoGlobMatch(p, 'node_modules/some/folder/foo.ts');
307
assertNoGlobMatch(p, 'foo.jss');
308
assertNoGlobMatch(p, 'some.js/test');
309
310
p = '{**/node_modules/**,**/.git/**,**/bower_components/**}';
311
312
assertGlobMatch(p, 'node_modules');
313
assertGlobMatch(p, '/node_modules');
314
assertGlobMatch(p, '/node_modules/more');
315
assertGlobMatch(p, 'some/test/node_modules');
316
assertGlobMatch(p, 'some\\test\\node_modules');
317
assertGlobMatch(p, '/some/test/node_modules');
318
assertGlobMatch(p, '\\some\\test\\node_modules');
319
assertGlobMatch(p, 'C:\\\\some\\test\\node_modules');
320
assertGlobMatch(p, 'C:\\\\some\\test\\node_modules\\more');
321
322
assertGlobMatch(p, 'bower_components');
323
assertGlobMatch(p, 'bower_components/more');
324
assertGlobMatch(p, '/bower_components');
325
assertGlobMatch(p, 'some/test/bower_components');
326
assertGlobMatch(p, 'some\\test\\bower_components');
327
assertGlobMatch(p, '/some/test/bower_components');
328
assertGlobMatch(p, '\\some\\test\\bower_components');
329
assertGlobMatch(p, 'C:\\\\some\\test\\bower_components');
330
assertGlobMatch(p, 'C:\\\\some\\test\\bower_components\\more');
331
332
assertGlobMatch(p, '.git');
333
assertGlobMatch(p, '/.git');
334
assertGlobMatch(p, 'some/test/.git');
335
assertGlobMatch(p, 'some\\test\\.git');
336
assertGlobMatch(p, '/some/test/.git');
337
assertGlobMatch(p, '\\some\\test\\.git');
338
assertGlobMatch(p, 'C:\\\\some\\test\\.git');
339
340
assertNoGlobMatch(p, 'tempting');
341
assertNoGlobMatch(p, '/tempting');
342
assertNoGlobMatch(p, 'some/test/tempting');
343
assertNoGlobMatch(p, 'some\\test\\tempting');
344
assertNoGlobMatch(p, '/some/test/tempting');
345
assertNoGlobMatch(p, '\\some\\test\\tempting');
346
assertNoGlobMatch(p, 'C:\\\\some\\test\\tempting');
347
348
p = '{**/package.json,**/project.json}';
349
assertGlobMatch(p, 'package.json');
350
assertGlobMatch(p, '/package.json');
351
assertNoGlobMatch(p, 'xpackage.json');
352
assertNoGlobMatch(p, '/xpackage.json');
353
});
354
355
test('issue 41724', function () {
356
let p = 'some/**/*.js';
357
358
assertGlobMatch(p, 'some/foo.js');
359
assertGlobMatch(p, 'some/folder/foo.js');
360
assertNoGlobMatch(p, 'something/foo.js');
361
assertNoGlobMatch(p, 'something/folder/foo.js');
362
363
p = 'some/**/*';
364
365
assertGlobMatch(p, 'some/foo.js');
366
assertGlobMatch(p, 'some/folder/foo.js');
367
assertNoGlobMatch(p, 'something/foo.js');
368
assertNoGlobMatch(p, 'something/folder/foo.js');
369
});
370
371
test('brace expansion', function () {
372
let p = '*.{html,js}';
373
374
assertGlobMatch(p, 'foo.js');
375
assertGlobMatch(p, 'foo.html');
376
assertNoGlobMatch(p, 'folder/foo.js');
377
assertNoGlobMatch(p, '/node_modules/foo.js');
378
assertNoGlobMatch(p, 'foo.jss');
379
assertNoGlobMatch(p, 'some.js/test');
380
381
p = '*.{html}';
382
383
assertGlobMatch(p, 'foo.html');
384
assertNoGlobMatch(p, 'foo.js');
385
assertNoGlobMatch(p, 'folder/foo.js');
386
assertNoGlobMatch(p, '/node_modules/foo.js');
387
assertNoGlobMatch(p, 'foo.jss');
388
assertNoGlobMatch(p, 'some.js/test');
389
390
p = '{node_modules,testing}';
391
assertGlobMatch(p, 'node_modules');
392
assertGlobMatch(p, 'testing');
393
assertNoGlobMatch(p, 'node_module');
394
assertNoGlobMatch(p, 'dtesting');
395
396
p = '**/{foo,bar}';
397
assertGlobMatch(p, 'foo');
398
assertGlobMatch(p, 'bar');
399
assertGlobMatch(p, 'test/foo');
400
assertGlobMatch(p, 'test/bar');
401
assertGlobMatch(p, 'other/more/foo');
402
assertGlobMatch(p, 'other/more/bar');
403
assertGlobMatch(p, '/foo');
404
assertGlobMatch(p, '/bar');
405
assertGlobMatch(p, '/test/foo');
406
assertGlobMatch(p, '/test/bar');
407
assertGlobMatch(p, '/other/more/foo');
408
assertGlobMatch(p, '/other/more/bar');
409
410
p = '{foo,bar}/**';
411
assertGlobMatch(p, 'foo');
412
assertGlobMatch(p, 'bar');
413
assertGlobMatch(p, 'bar/');
414
assertGlobMatch(p, 'foo/test');
415
assertGlobMatch(p, 'bar/test');
416
assertGlobMatch(p, 'bar/test/');
417
assertGlobMatch(p, 'foo/other/more');
418
assertGlobMatch(p, 'bar/other/more');
419
assertGlobMatch(p, 'bar/other/more/');
420
421
p = '{**/*.d.ts,**/*.js}';
422
423
assertGlobMatch(p, 'foo.js');
424
assertGlobMatch(p, 'testing/foo.js');
425
assertGlobMatch(p, 'testing\\foo.js');
426
assertGlobMatch(p, '/testing/foo.js');
427
assertGlobMatch(p, '\\testing\\foo.js');
428
assertGlobMatch(p, 'C:\\testing\\foo.js');
429
430
assertGlobMatch(p, 'foo.d.ts');
431
assertGlobMatch(p, 'testing/foo.d.ts');
432
assertGlobMatch(p, 'testing\\foo.d.ts');
433
assertGlobMatch(p, '/testing/foo.d.ts');
434
assertGlobMatch(p, '\\testing\\foo.d.ts');
435
assertGlobMatch(p, 'C:\\testing\\foo.d.ts');
436
437
assertNoGlobMatch(p, 'foo.d');
438
assertNoGlobMatch(p, 'testing/foo.d');
439
assertNoGlobMatch(p, 'testing\\foo.d');
440
assertNoGlobMatch(p, '/testing/foo.d');
441
assertNoGlobMatch(p, '\\testing\\foo.d');
442
assertNoGlobMatch(p, 'C:\\testing\\foo.d');
443
444
p = '{**/*.d.ts,**/*.js,path/simple.jgs}';
445
446
assertGlobMatch(p, 'foo.js');
447
assertGlobMatch(p, 'testing/foo.js');
448
assertGlobMatch(p, 'testing\\foo.js');
449
assertGlobMatch(p, '/testing/foo.js');
450
assertGlobMatch(p, 'path/simple.jgs');
451
assertNoGlobMatch(p, '/path/simple.jgs');
452
assertGlobMatch(p, '\\testing\\foo.js');
453
assertGlobMatch(p, 'C:\\testing\\foo.js');
454
455
p = '{**/*.d.ts,**/*.js,foo.[0-9]}';
456
457
assertGlobMatch(p, 'foo.5');
458
assertGlobMatch(p, 'foo.8');
459
assertNoGlobMatch(p, 'bar.5');
460
assertNoGlobMatch(p, 'foo.f');
461
assertGlobMatch(p, 'foo.js');
462
463
p = 'prefix/{**/*.d.ts,**/*.js,foo.[0-9]}';
464
465
assertGlobMatch(p, 'prefix/foo.5');
466
assertGlobMatch(p, 'prefix/foo.8');
467
assertNoGlobMatch(p, 'prefix/bar.5');
468
assertNoGlobMatch(p, 'prefix/foo.f');
469
assertGlobMatch(p, 'prefix/foo.js');
470
});
471
472
test('expression support (single)', function () {
473
const siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
474
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
475
476
// { "**/*.js": { "when": "$(basename).ts" } }
477
let expression: glob.IExpression = {
478
'**/*.js': {
479
when: '$(basename).ts'
480
}
481
};
482
483
assert.strictEqual('**/*.js', glob.parse(expression)('test.js', undefined, hasSibling));
484
assert.strictEqual(glob.parse(expression)('test.js', undefined, () => false), null);
485
assert.strictEqual(glob.parse(expression)('test.js', undefined, name => name === 'te.ts'), null);
486
assert.strictEqual(glob.parse(expression)('test.js', undefined), null);
487
488
expression = {
489
'**/*.js': {
490
when: ''
491
}
492
};
493
494
assert.strictEqual(glob.parse(expression)('test.js', undefined, hasSibling), null);
495
496
expression = {
497
// eslint-disable-next-line local/code-no-any-casts
498
'**/*.js': {
499
} as any
500
};
501
502
assert.strictEqual('**/*.js', glob.parse(expression)('test.js', undefined, hasSibling));
503
504
expression = {};
505
506
assert.strictEqual(glob.parse(expression)('test.js', undefined, hasSibling), null);
507
});
508
509
test('expression support (multiple)', function () {
510
const siblings = ['test.html', 'test.txt', 'test.ts', 'test.js'];
511
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
512
513
// { "**/*.js": { "when": "$(basename).ts" } }
514
const expression: glob.IExpression = {
515
'**/*.js': { when: '$(basename).ts' },
516
'**/*.as': true,
517
'**/*.foo': false,
518
// eslint-disable-next-line local/code-no-any-casts
519
'**/*.bananas': { bananas: true } as any
520
};
521
522
assert.strictEqual('**/*.js', glob.parse(expression)('test.js', undefined, hasSibling));
523
assert.strictEqual('**/*.as', glob.parse(expression)('test.as', undefined, hasSibling));
524
assert.strictEqual('**/*.bananas', glob.parse(expression)('test.bananas', undefined, hasSibling));
525
assert.strictEqual('**/*.bananas', glob.parse(expression)('test.bananas', undefined));
526
assert.strictEqual(glob.parse(expression)('test.foo', undefined, hasSibling), null);
527
});
528
529
test('brackets', () => {
530
let p = 'foo.[0-9]';
531
532
assertGlobMatch(p, 'foo.5');
533
assertGlobMatch(p, 'foo.8');
534
assertNoGlobMatch(p, 'bar.5');
535
assertNoGlobMatch(p, 'foo.f');
536
537
p = 'foo.[^0-9]';
538
539
assertNoGlobMatch(p, 'foo.5');
540
assertNoGlobMatch(p, 'foo.8');
541
assertNoGlobMatch(p, 'bar.5');
542
assertGlobMatch(p, 'foo.f');
543
544
p = 'foo.[!0-9]';
545
546
assertNoGlobMatch(p, 'foo.5');
547
assertNoGlobMatch(p, 'foo.8');
548
assertNoGlobMatch(p, 'bar.5');
549
assertGlobMatch(p, 'foo.f');
550
551
p = 'foo.[0!^*?]';
552
553
assertNoGlobMatch(p, 'foo.5');
554
assertNoGlobMatch(p, 'foo.8');
555
assertGlobMatch(p, 'foo.0');
556
assertGlobMatch(p, 'foo.!');
557
assertGlobMatch(p, 'foo.^');
558
assertGlobMatch(p, 'foo.*');
559
assertGlobMatch(p, 'foo.?');
560
561
p = 'foo[/]bar';
562
563
assertNoGlobMatch(p, 'foo/bar');
564
565
p = 'foo.[[]';
566
567
assertGlobMatch(p, 'foo.[');
568
569
p = 'foo.[]]';
570
571
assertGlobMatch(p, 'foo.]');
572
573
p = 'foo.[][!]';
574
575
assertGlobMatch(p, 'foo.]');
576
assertGlobMatch(p, 'foo.[');
577
assertGlobMatch(p, 'foo.!');
578
579
p = 'foo.[]-]';
580
581
assertGlobMatch(p, 'foo.]');
582
assertGlobMatch(p, 'foo.-');
583
});
584
585
test('full path', function () {
586
assertGlobMatch('testing/this/foo.txt', 'testing/this/foo.txt');
587
});
588
589
test('ending path', function () {
590
assertGlobMatch('**/testing/this/foo.txt', 'some/path/testing/this/foo.txt');
591
});
592
593
test('prefix agnostic', function () {
594
let p = '**/*.js';
595
596
assertGlobMatch(p, 'foo.js');
597
assertGlobMatch(p, '/foo.js');
598
assertGlobMatch(p, '\\foo.js');
599
assertGlobMatch(p, 'testing/foo.js');
600
assertGlobMatch(p, 'testing\\foo.js');
601
assertGlobMatch(p, '/testing/foo.js');
602
assertGlobMatch(p, '\\testing\\foo.js');
603
assertGlobMatch(p, 'C:\\testing\\foo.js');
604
605
assertNoGlobMatch(p, 'foo.ts');
606
assertNoGlobMatch(p, 'testing/foo.ts');
607
assertNoGlobMatch(p, 'testing\\foo.ts');
608
assertNoGlobMatch(p, '/testing/foo.ts');
609
assertNoGlobMatch(p, '\\testing\\foo.ts');
610
assertNoGlobMatch(p, 'C:\\testing\\foo.ts');
611
612
assertNoGlobMatch(p, 'foo.js.txt');
613
assertNoGlobMatch(p, 'testing/foo.js.txt');
614
assertNoGlobMatch(p, 'testing\\foo.js.txt');
615
assertNoGlobMatch(p, '/testing/foo.js.txt');
616
assertNoGlobMatch(p, '\\testing\\foo.js.txt');
617
assertNoGlobMatch(p, 'C:\\testing\\foo.js.txt');
618
619
assertNoGlobMatch(p, 'testing.js/foo');
620
assertNoGlobMatch(p, 'testing.js\\foo');
621
assertNoGlobMatch(p, '/testing.js/foo');
622
assertNoGlobMatch(p, '\\testing.js\\foo');
623
assertNoGlobMatch(p, 'C:\\testing.js\\foo');
624
625
p = '**/foo.js';
626
627
assertGlobMatch(p, 'foo.js');
628
assertGlobMatch(p, '/foo.js');
629
assertGlobMatch(p, '\\foo.js');
630
assertGlobMatch(p, 'testing/foo.js');
631
assertGlobMatch(p, 'testing\\foo.js');
632
assertGlobMatch(p, '/testing/foo.js');
633
assertGlobMatch(p, '\\testing\\foo.js');
634
assertGlobMatch(p, 'C:\\testing\\foo.js');
635
});
636
637
test('cached properly', function () {
638
const p = '**/*.js';
639
640
assertGlobMatch(p, 'foo.js');
641
assertGlobMatch(p, 'testing/foo.js');
642
assertGlobMatch(p, 'testing\\foo.js');
643
assertGlobMatch(p, '/testing/foo.js');
644
assertGlobMatch(p, '\\testing\\foo.js');
645
assertGlobMatch(p, 'C:\\testing\\foo.js');
646
647
assertNoGlobMatch(p, 'foo.ts');
648
assertNoGlobMatch(p, 'testing/foo.ts');
649
assertNoGlobMatch(p, 'testing\\foo.ts');
650
assertNoGlobMatch(p, '/testing/foo.ts');
651
assertNoGlobMatch(p, '\\testing\\foo.ts');
652
assertNoGlobMatch(p, 'C:\\testing\\foo.ts');
653
654
assertNoGlobMatch(p, 'foo.js.txt');
655
assertNoGlobMatch(p, 'testing/foo.js.txt');
656
assertNoGlobMatch(p, 'testing\\foo.js.txt');
657
assertNoGlobMatch(p, '/testing/foo.js.txt');
658
assertNoGlobMatch(p, '\\testing\\foo.js.txt');
659
assertNoGlobMatch(p, 'C:\\testing\\foo.js.txt');
660
661
assertNoGlobMatch(p, 'testing.js/foo');
662
assertNoGlobMatch(p, 'testing.js\\foo');
663
assertNoGlobMatch(p, '/testing.js/foo');
664
assertNoGlobMatch(p, '\\testing.js\\foo');
665
assertNoGlobMatch(p, 'C:\\testing.js\\foo');
666
667
// Run again and make sure the regex are properly reused
668
669
assertGlobMatch(p, 'foo.js');
670
assertGlobMatch(p, 'testing/foo.js');
671
assertGlobMatch(p, 'testing\\foo.js');
672
assertGlobMatch(p, '/testing/foo.js');
673
assertGlobMatch(p, '\\testing\\foo.js');
674
assertGlobMatch(p, 'C:\\testing\\foo.js');
675
676
assertNoGlobMatch(p, 'foo.ts');
677
assertNoGlobMatch(p, 'testing/foo.ts');
678
assertNoGlobMatch(p, 'testing\\foo.ts');
679
assertNoGlobMatch(p, '/testing/foo.ts');
680
assertNoGlobMatch(p, '\\testing\\foo.ts');
681
assertNoGlobMatch(p, 'C:\\testing\\foo.ts');
682
683
assertNoGlobMatch(p, 'foo.js.txt');
684
assertNoGlobMatch(p, 'testing/foo.js.txt');
685
assertNoGlobMatch(p, 'testing\\foo.js.txt');
686
assertNoGlobMatch(p, '/testing/foo.js.txt');
687
assertNoGlobMatch(p, '\\testing\\foo.js.txt');
688
assertNoGlobMatch(p, 'C:\\testing\\foo.js.txt');
689
690
assertNoGlobMatch(p, 'testing.js/foo');
691
assertNoGlobMatch(p, 'testing.js\\foo');
692
assertNoGlobMatch(p, '/testing.js/foo');
693
assertNoGlobMatch(p, '\\testing.js\\foo');
694
assertNoGlobMatch(p, 'C:\\testing.js\\foo');
695
});
696
697
test('invalid glob', function () {
698
const p = '**/*(.js';
699
700
assertNoGlobMatch(p, 'foo.js');
701
});
702
703
test('split glob aware', function () {
704
assert.deepStrictEqual(glob.splitGlobAware('foo,bar', ','), ['foo', 'bar']);
705
assert.deepStrictEqual(glob.splitGlobAware('foo', ','), ['foo']);
706
assert.deepStrictEqual(glob.splitGlobAware('{foo,bar}', ','), ['{foo,bar}']);
707
assert.deepStrictEqual(glob.splitGlobAware('foo,bar,{foo,bar}', ','), ['foo', 'bar', '{foo,bar}']);
708
assert.deepStrictEqual(glob.splitGlobAware('{foo,bar},foo,bar,{foo,bar}', ','), ['{foo,bar}', 'foo', 'bar', '{foo,bar}']);
709
710
assert.deepStrictEqual(glob.splitGlobAware('[foo,bar]', ','), ['[foo,bar]']);
711
assert.deepStrictEqual(glob.splitGlobAware('foo,bar,[foo,bar]', ','), ['foo', 'bar', '[foo,bar]']);
712
assert.deepStrictEqual(glob.splitGlobAware('[foo,bar],foo,bar,[foo,bar]', ','), ['[foo,bar]', 'foo', 'bar', '[foo,bar]']);
713
});
714
715
test('expression with disabled glob', function () {
716
const expr = { '**/*.js': false };
717
718
assert.strictEqual(glob.match(expr, 'foo.js'), null);
719
});
720
721
test('expression with two non-trivia globs', function () {
722
const expr = {
723
'**/*.j?': true,
724
'**/*.t?': true
725
};
726
727
assert.strictEqual(glob.match(expr, 'foo.js'), '**/*.j?');
728
assert.strictEqual(glob.match(expr, 'foo.as'), null);
729
});
730
731
test('expression with non-trivia glob (issue 144458)', function () {
732
const pattern = '**/p*';
733
734
assert.strictEqual(glob.match(pattern, 'foo/barp'), false);
735
assert.strictEqual(glob.match(pattern, 'foo/bar/ap'), false);
736
assert.strictEqual(glob.match(pattern, 'ap'), false);
737
738
assert.strictEqual(glob.match(pattern, 'foo/barp1'), false);
739
assert.strictEqual(glob.match(pattern, 'foo/bar/ap1'), false);
740
assert.strictEqual(glob.match(pattern, 'ap1'), false);
741
742
assert.strictEqual(glob.match(pattern, '/foo/barp'), false);
743
assert.strictEqual(glob.match(pattern, '/foo/bar/ap'), false);
744
assert.strictEqual(glob.match(pattern, '/ap'), false);
745
746
assert.strictEqual(glob.match(pattern, '/foo/barp1'), false);
747
assert.strictEqual(glob.match(pattern, '/foo/bar/ap1'), false);
748
assert.strictEqual(glob.match(pattern, '/ap1'), false);
749
750
assert.strictEqual(glob.match(pattern, 'foo/pbar'), true);
751
assert.strictEqual(glob.match(pattern, '/foo/pbar'), true);
752
assert.strictEqual(glob.match(pattern, 'foo/bar/pa'), true);
753
assert.strictEqual(glob.match(pattern, '/p'), true);
754
});
755
756
test('expression with empty glob', function () {
757
const expr = { '': true };
758
759
assert.strictEqual(glob.match(expr, 'foo.js'), null);
760
});
761
762
test('expression with other falsy value', function () {
763
// eslint-disable-next-line local/code-no-any-casts
764
const expr = { '**/*.js': 0 } as any;
765
766
assert.strictEqual(glob.match(expr, 'foo.js'), '**/*.js');
767
});
768
769
test('expression with two basename globs', function () {
770
const expr = {
771
'**/bar': true,
772
'**/baz': true
773
};
774
775
assert.strictEqual(glob.match(expr, 'bar'), '**/bar');
776
assert.strictEqual(glob.match(expr, 'foo'), null);
777
assert.strictEqual(glob.match(expr, 'foo/bar'), '**/bar');
778
assert.strictEqual(glob.match(expr, 'foo\\bar'), '**/bar');
779
assert.strictEqual(glob.match(expr, 'foo/foo'), null);
780
});
781
782
test('expression with two basename globs and a siblings expression', function () {
783
const expr = {
784
'**/bar': true,
785
'**/baz': true,
786
'**/*.js': { when: '$(basename).ts' }
787
};
788
789
const siblings = ['foo.ts', 'foo.js', 'foo', 'bar'];
790
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
791
792
assert.strictEqual(glob.parse(expr)('bar', undefined, hasSibling), '**/bar');
793
assert.strictEqual(glob.parse(expr)('foo', undefined, hasSibling), null);
794
assert.strictEqual(glob.parse(expr)('foo/bar', undefined, hasSibling), '**/bar');
795
if (isWindows) {
796
// backslash is a valid file name character on posix
797
assert.strictEqual(glob.parse(expr)('foo\\bar', undefined, hasSibling), '**/bar');
798
}
799
assert.strictEqual(glob.parse(expr)('foo/foo', undefined, hasSibling), null);
800
assert.strictEqual(glob.parse(expr)('foo.js', undefined, hasSibling), '**/*.js');
801
assert.strictEqual(glob.parse(expr)('bar.js', undefined, hasSibling), null);
802
});
803
804
test('expression with multipe basename globs', function () {
805
const expr = {
806
'**/bar': true,
807
'{**/baz,**/foo}': true
808
};
809
810
assert.strictEqual(glob.match(expr, 'bar'), '**/bar');
811
assert.strictEqual(glob.match(expr, 'foo'), '{**/baz,**/foo}');
812
assert.strictEqual(glob.match(expr, 'baz'), '{**/baz,**/foo}');
813
assert.strictEqual(glob.match(expr, 'abc'), null);
814
});
815
816
test('falsy expression/pattern', function () {
817
assert.strictEqual(glob.match(null!, 'foo'), false);
818
assert.strictEqual(glob.match('', 'foo'), false);
819
assert.strictEqual(glob.parse(null!)('foo'), false);
820
assert.strictEqual(glob.parse('')('foo'), false);
821
});
822
823
test('falsy path', function () {
824
assert.strictEqual(glob.parse('foo')(null!), false);
825
assert.strictEqual(glob.parse('foo')(''), false);
826
assert.strictEqual(glob.parse('**/*.j?')(null!), false);
827
assert.strictEqual(glob.parse('**/*.j?')(''), false);
828
assert.strictEqual(glob.parse('**/*.foo')(null!), false);
829
assert.strictEqual(glob.parse('**/*.foo')(''), false);
830
assert.strictEqual(glob.parse('**/foo')(null!), false);
831
assert.strictEqual(glob.parse('**/foo')(''), false);
832
assert.strictEqual(glob.parse('{**/baz,**/foo}')(null!), false);
833
assert.strictEqual(glob.parse('{**/baz,**/foo}')(''), false);
834
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(null!), false);
835
assert.strictEqual(glob.parse('{**/*.baz,**/*.foo}')(''), false);
836
});
837
838
test('expression/pattern basename', function () {
839
assert.strictEqual(glob.parse('**/foo')('bar/baz', 'baz'), false);
840
assert.strictEqual(glob.parse('**/foo')('bar/foo', 'foo'), true);
841
842
assert.strictEqual(glob.parse('{**/baz,**/foo}')('baz/bar', 'bar'), false);
843
assert.strictEqual(glob.parse('{**/baz,**/foo}')('baz/foo', 'foo'), true);
844
845
const expr = { '**/*.js': { when: '$(basename).ts' } };
846
const siblings = ['foo.ts', 'foo.js'];
847
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
848
849
assert.strictEqual(glob.parse(expr)('bar/baz.js', 'baz.js', hasSibling), null);
850
assert.strictEqual(glob.parse(expr)('bar/foo.js', 'foo.js', hasSibling), '**/*.js');
851
});
852
853
test('expression/pattern basename terms', function () {
854
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/*.foo')), []);
855
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo')), ['foo']);
856
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo/')), ['foo']);
857
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('{**/baz,**/foo}')), ['baz', 'foo']);
858
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('{**/baz/,**/foo/}')), ['baz', 'foo']);
859
860
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse({
861
'**/foo': true,
862
'{**/bar,**/baz}': true,
863
'{**/bar2/,**/baz2/}': true,
864
'**/bulb': false
865
})), ['foo', 'bar', 'baz', 'bar2', 'baz2']);
866
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse({
867
'**/foo': { when: '$(basename).zip' },
868
'**/bar': true
869
})), ['bar']);
870
});
871
872
test('expression/pattern optimization for basenames', function () {
873
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo/**')), []);
874
assert.deepStrictEqual(glob.getBasenameTerms(glob.parse('**/foo/**', { trimForExclusions: true })), ['foo']);
875
876
testOptimizationForBasenames('**/*.foo/**', [], [['baz/bar.foo/bar/baz', true]]);
877
testOptimizationForBasenames('**/foo/**', ['foo'], [['bar/foo', true], ['bar/foo/baz', false]]);
878
testOptimizationForBasenames('{**/baz/**,**/foo/**}', ['baz', 'foo'], [['bar/baz', true], ['bar/foo', true]]);
879
880
testOptimizationForBasenames({
881
'**/foo/**': true,
882
'{**/bar/**,**/baz/**}': true,
883
'**/bulb/**': false
884
}, ['foo', 'bar', 'baz'], [
885
['bar/foo', '**/foo/**'],
886
['foo/bar', '{**/bar/**,**/baz/**}'],
887
['bar/nope', null!]
888
]);
889
890
const siblings = ['baz', 'baz.zip', 'nope'];
891
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
892
testOptimizationForBasenames({
893
'**/foo/**': { when: '$(basename).zip' },
894
'**/bar/**': true
895
}, ['bar'], [
896
['bar/foo', null!],
897
['bar/foo/baz', null!],
898
['bar/foo/nope', null!],
899
['foo/bar', '**/bar/**'],
900
], [
901
null!,
902
hasSibling,
903
hasSibling
904
]);
905
});
906
907
function testOptimizationForBasenames(pattern: string | glob.IExpression, basenameTerms: string[], matches: [string, string | boolean][], siblingsFns: ((name: string) => boolean)[] = []) {
908
const parsed = glob.parse(<glob.IExpression>pattern, { trimForExclusions: true });
909
assert.deepStrictEqual(glob.getBasenameTerms(parsed), basenameTerms);
910
matches.forEach(([text, result], i) => {
911
assert.strictEqual(parsed(text, null!, siblingsFns[i]), result);
912
});
913
}
914
915
test('trailing slash', function () {
916
// Testing existing (more or less intuitive) behavior
917
assert.strictEqual(glob.parse('**/foo/')('bar/baz', 'baz'), false);
918
assert.strictEqual(glob.parse('**/foo/')('bar/foo', 'foo'), true);
919
assert.strictEqual(glob.parse('**/*.foo/')('bar/file.baz', 'file.baz'), false);
920
assert.strictEqual(glob.parse('**/*.foo/')('bar/file.foo', 'file.foo'), true);
921
assert.strictEqual(glob.parse('{**/foo/,**/abc/}')('bar/baz', 'baz'), false);
922
assert.strictEqual(glob.parse('{**/foo/,**/abc/}')('bar/foo', 'foo'), true);
923
assert.strictEqual(glob.parse('{**/foo/,**/abc/}')('bar/abc', 'abc'), true);
924
assert.strictEqual(glob.parse('{**/foo/,**/abc/}', { trimForExclusions: true })('bar/baz', 'baz'), false);
925
assert.strictEqual(glob.parse('{**/foo/,**/abc/}', { trimForExclusions: true })('bar/foo', 'foo'), true);
926
assert.strictEqual(glob.parse('{**/foo/,**/abc/}', { trimForExclusions: true })('bar/abc', 'abc'), true);
927
});
928
929
test('expression/pattern path', function () {
930
assert.strictEqual(glob.parse('**/foo/bar')(nativeSep('foo/baz'), 'baz'), false);
931
assert.strictEqual(glob.parse('**/foo/bar')(nativeSep('foo/bar'), 'bar'), true);
932
assert.strictEqual(glob.parse('**/foo/bar')(nativeSep('bar/foo/bar'), 'bar'), true);
933
assert.strictEqual(glob.parse('**/foo/bar/**')(nativeSep('bar/foo/bar'), 'bar'), true);
934
assert.strictEqual(glob.parse('**/foo/bar/**')(nativeSep('bar/foo/bar/baz'), 'baz'), true);
935
assert.strictEqual(glob.parse('**/foo/bar/**', { trimForExclusions: true })(nativeSep('bar/foo/bar'), 'bar'), true);
936
assert.strictEqual(glob.parse('**/foo/bar/**', { trimForExclusions: true })(nativeSep('bar/foo/bar/baz'), 'baz'), false);
937
938
assert.strictEqual(glob.parse('foo/bar')(nativeSep('foo/baz'), 'baz'), false);
939
assert.strictEqual(glob.parse('foo/bar')(nativeSep('foo/bar'), 'bar'), true);
940
assert.strictEqual(glob.parse('foo/bar/baz')(nativeSep('foo/bar/baz'), 'baz'), true); // #15424
941
assert.strictEqual(glob.parse('foo/bar')(nativeSep('bar/foo/bar'), 'bar'), false);
942
assert.strictEqual(glob.parse('foo/bar/**')(nativeSep('foo/bar/baz'), 'baz'), true);
943
assert.strictEqual(glob.parse('foo/bar/**', { trimForExclusions: true })(nativeSep('foo/bar'), 'bar'), true);
944
assert.strictEqual(glob.parse('foo/bar/**', { trimForExclusions: true })(nativeSep('foo/bar/baz'), 'baz'), false);
945
});
946
947
test('expression/pattern paths', function () {
948
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/*.foo')), []);
949
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo')), []);
950
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar')), ['*/foo/bar']);
951
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar/')), ['*/foo/bar']);
952
// Not supported
953
// assert.deepStrictEqual(glob.getPathTerms(glob.parse('{**/baz/bar,**/foo/bar,**/bar}')), ['*/baz/bar', '*/foo/bar']);
954
// assert.deepStrictEqual(glob.getPathTerms(glob.parse('{**/baz/bar/,**/foo/bar/,**/bar/}')), ['*/baz/bar', '*/foo/bar']);
955
956
const parsed = glob.parse({
957
'**/foo/bar': true,
958
'**/foo2/bar2': true,
959
// Not supported
960
// '{**/bar/foo,**/baz/foo}': true,
961
// '{**/bar2/foo/,**/baz2/foo/}': true,
962
'**/bulb': true,
963
'**/bulb2': true,
964
'**/bulb/foo': false
965
});
966
assert.deepStrictEqual(glob.getPathTerms(parsed), ['*/foo/bar', '*/foo2/bar2']);
967
assert.deepStrictEqual(glob.getBasenameTerms(parsed), ['bulb', 'bulb2']);
968
assert.deepStrictEqual(glob.getPathTerms(glob.parse({
969
'**/foo/bar': { when: '$(basename).zip' },
970
'**/bar/foo': true,
971
'**/bar2/foo2': true
972
})), ['*/bar/foo', '*/bar2/foo2']);
973
});
974
975
test('expression/pattern optimization for paths', function () {
976
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar/**')), []);
977
assert.deepStrictEqual(glob.getPathTerms(glob.parse('**/foo/bar/**', { trimForExclusions: true })), ['*/foo/bar']);
978
979
testOptimizationForPaths('**/*.foo/bar/**', [], [[nativeSep('baz/bar.foo/bar/baz'), true]]);
980
testOptimizationForPaths('**/foo/bar/**', ['*/foo/bar'], [[nativeSep('bar/foo/bar'), true], [nativeSep('bar/foo/bar/baz'), false]]);
981
// Not supported
982
// testOptimizationForPaths('{**/baz/bar/**,**/foo/bar/**}', ['*/baz/bar', '*/foo/bar'], [[nativeSep('bar/baz/bar'), true], [nativeSep('bar/foo/bar'), true]]);
983
984
testOptimizationForPaths({
985
'**/foo/bar/**': true,
986
// Not supported
987
// '{**/bar/bar/**,**/baz/bar/**}': true,
988
'**/bulb/bar/**': false
989
}, ['*/foo/bar'], [
990
[nativeSep('bar/foo/bar'), '**/foo/bar/**'],
991
// Not supported
992
// [nativeSep('foo/bar/bar'), '{**/bar/bar/**,**/baz/bar/**}'],
993
[nativeSep('/foo/bar/nope'), null!]
994
]);
995
996
const siblings = ['baz', 'baz.zip', 'nope'];
997
const hasSibling = (name: string) => siblings.indexOf(name) !== -1;
998
testOptimizationForPaths({
999
'**/foo/123/**': { when: '$(basename).zip' },
1000
'**/bar/123/**': true
1001
}, ['*/bar/123'], [
1002
[nativeSep('bar/foo/123'), null!],
1003
[nativeSep('bar/foo/123/baz'), null!],
1004
[nativeSep('bar/foo/123/nope'), null!],
1005
[nativeSep('foo/bar/123'), '**/bar/123/**'],
1006
], [
1007
null!,
1008
hasSibling,
1009
hasSibling
1010
]);
1011
});
1012
1013
function testOptimizationForPaths(pattern: string | glob.IExpression, pathTerms: string[], matches: [string, string | boolean][], siblingsFns: ((name: string) => boolean)[] = []) {
1014
const parsed = glob.parse(<glob.IExpression>pattern, { trimForExclusions: true });
1015
assert.deepStrictEqual(glob.getPathTerms(parsed), pathTerms);
1016
matches.forEach(([text, result], i) => {
1017
assert.strictEqual(parsed(text, null!, siblingsFns[i]), result);
1018
});
1019
}
1020
1021
function nativeSep(slashPath: string): string {
1022
return slashPath.replace(/\//g, sep);
1023
}
1024
1025
test('relative pattern - glob star', function () {
1026
if (isWindows) {
1027
const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: '**/*.cs' };
1028
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs');
1029
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\bar\\Program.cs');
1030
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.ts');
1031
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\Program.cs');
1032
assertNoGlobMatch(p, 'C:\\other\\DNXConsoleApp\\foo\\Program.ts');
1033
} else {
1034
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: '**/*.cs' };
1035
assertGlobMatch(p, '/DNXConsoleApp/foo/Program.cs');
1036
assertGlobMatch(p, '/DNXConsoleApp/foo/bar/Program.cs');
1037
assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.ts');
1038
assertNoGlobMatch(p, '/DNXConsoleApp/Program.cs');
1039
assertNoGlobMatch(p, '/other/DNXConsoleApp/foo/Program.ts');
1040
}
1041
});
1042
1043
test('relative pattern - single star', function () {
1044
if (isWindows) {
1045
const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: '*.cs' };
1046
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs');
1047
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\bar\\Program.cs');
1048
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.ts');
1049
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\Program.cs');
1050
assertNoGlobMatch(p, 'C:\\other\\DNXConsoleApp\\foo\\Program.ts');
1051
} else {
1052
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: '*.cs' };
1053
assertGlobMatch(p, '/DNXConsoleApp/foo/Program.cs');
1054
assertNoGlobMatch(p, '/DNXConsoleApp/foo/bar/Program.cs');
1055
assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.ts');
1056
assertNoGlobMatch(p, '/DNXConsoleApp/Program.cs');
1057
assertNoGlobMatch(p, '/other/DNXConsoleApp/foo/Program.ts');
1058
}
1059
});
1060
1061
test('relative pattern - single star with path', function () {
1062
if (isWindows) {
1063
const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'something/*.cs' };
1064
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\something\\Program.cs');
1065
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs');
1066
} else {
1067
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' };
1068
assertGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs');
1069
assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs');
1070
}
1071
});
1072
1073
test('relative pattern - single star alone', function () {
1074
if (isWindows) {
1075
const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo\\something\\Program.cs', pattern: '*' };
1076
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\something\\Program.cs');
1077
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs');
1078
} else {
1079
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo/something/Program.cs', pattern: '*' };
1080
assertGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs');
1081
assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs');
1082
}
1083
});
1084
1085
test('relative pattern - ignores case on macOS/Windows', function () {
1086
if (isWindows) {
1087
const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'something/*.cs' };
1088
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\something\\Program.cs'.toLowerCase());
1089
} else if (isMacintosh) {
1090
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' };
1091
assertGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs'.toLowerCase());
1092
} else if (isLinux) {
1093
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' };
1094
assertNoGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs'.toLowerCase());
1095
}
1096
});
1097
1098
test('relative pattern - trailing slash / backslash (#162498)', function () {
1099
if (isWindows) {
1100
let p: glob.IRelativePattern = { base: 'C:\\', pattern: 'foo.cs' };
1101
assertGlobMatch(p, 'C:\\foo.cs');
1102
1103
p = { base: 'C:\\bar\\', pattern: 'foo.cs' };
1104
assertGlobMatch(p, 'C:\\bar\\foo.cs');
1105
} else {
1106
let p: glob.IRelativePattern = { base: '/', pattern: 'foo.cs' };
1107
assertGlobMatch(p, '/foo.cs');
1108
1109
p = { base: '/bar/', pattern: 'foo.cs' };
1110
assertGlobMatch(p, '/bar/foo.cs');
1111
}
1112
});
1113
1114
test('pattern with "base" does not explode - #36081', function () {
1115
assert.ok(glob.match({ 'base': true }, 'base'));
1116
});
1117
1118
test('relative pattern - #57475', function () {
1119
if (isWindows) {
1120
const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'styles/style.css' };
1121
assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\styles\\style.css');
1122
assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs');
1123
} else {
1124
const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'styles/style.css' };
1125
assertGlobMatch(p, '/DNXConsoleApp/foo/styles/style.css');
1126
assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs');
1127
}
1128
});
1129
1130
test('URI match', () => {
1131
const p = 'scheme:/**/*.md';
1132
assertGlobMatch(p, URI.file('super/duper/long/some/file.md').with({ scheme: 'scheme' }).toString());
1133
});
1134
1135
test('expression fails when siblings use promises (https://github.com/microsoft/vscode/issues/146294)', async function () {
1136
const siblings = ['test.html', 'test.txt', 'test.ts'];
1137
const hasSibling = (name: string) => Promise.resolve(siblings.indexOf(name) !== -1);
1138
1139
// { "**/*.js": { "when": "$(basename).ts" } }
1140
const expression: glob.IExpression = {
1141
'**/test.js': { when: '$(basename).js' },
1142
'**/*.js': { when: '$(basename).ts' }
1143
};
1144
1145
const parsedExpression = glob.parse(expression);
1146
1147
assert.strictEqual('**/*.js', await parsedExpression('test.js', undefined, hasSibling));
1148
});
1149
1150
test('patternsEquals', () => {
1151
assert.ok(glob.patternsEquals(['a'], ['a']));
1152
assert.ok(!glob.patternsEquals(['a'], ['b']));
1153
1154
assert.ok(glob.patternsEquals(['a', 'b', 'c'], ['a', 'b', 'c']));
1155
assert.ok(!glob.patternsEquals(['1', '2'], ['1', '3']));
1156
1157
assert.ok(glob.patternsEquals([{ base: 'a', pattern: '*' }, 'b', 'c'], [{ base: 'a', pattern: '*' }, 'b', 'c']));
1158
1159
assert.ok(glob.patternsEquals(undefined, undefined));
1160
assert.ok(!glob.patternsEquals(undefined, ['b']));
1161
assert.ok(!glob.patternsEquals(['a'], undefined));
1162
});
1163
1164
test('isEmptyPattern', () => {
1165
assert.ok(glob.isEmptyPattern(glob.parse('')));
1166
assert.ok(glob.isEmptyPattern(glob.parse(undefined!)));
1167
assert.ok(glob.isEmptyPattern(glob.parse(null!)));
1168
1169
assert.ok(glob.isEmptyPattern(glob.parse({})));
1170
assert.ok(glob.isEmptyPattern(glob.parse({ '': true })));
1171
assert.ok(glob.isEmptyPattern(glob.parse({ '**/*.js': false })));
1172
});
1173
1174
test('caseInsensitiveMatch', () => {
1175
assertNoGlobMatch('PATH/FOO.js', 'path/foo.js');
1176
assertGlobMatch('PATH/FOO.js', 'path/foo.js', true);
1177
// T1
1178
assertNoGlobMatch('**/*.JS', 'bar/foo.js');
1179
assertGlobMatch('**/*.JS', 'bar/foo.js', true);
1180
// T2
1181
assertNoGlobMatch('**/package', 'bar/Package');
1182
assertGlobMatch('**/package', 'bar/Package', true);
1183
// T3
1184
assertNoGlobMatch('{**/*.JS,**/*.TS}', 'bar/foo.ts');
1185
assertNoGlobMatch('{**/*.JS,**/*.TS}', 'bar/foo.js');
1186
assertGlobMatch('{**/*.JS,**/*.TS}', 'bar/foo.ts', true);
1187
assertGlobMatch('{**/*.JS,**/*.TS}', 'bar/foo.js', true);
1188
// T4
1189
assertNoGlobMatch('**/FOO/Bar', 'bar/foo/bar');
1190
assertGlobMatch('**/FOO/Bar', 'bar/foo/bar', true);
1191
// T5
1192
assertNoGlobMatch('FOO/Bar', 'foo/bar');
1193
assertGlobMatch('FOO/Bar', 'foo/bar', true);
1194
// Other
1195
assertNoGlobMatch('some/*/Random/*/Path.FILE', 'some/very/random/unusual/path.file');
1196
assertGlobMatch('some/*/Random/*/Path.FILE', 'some/very/random/unusual/path.file', true);
1197
});
1198
1199
ensureNoDisposablesAreLeakedInTestSuite();
1200
});
1201
1202