|
| 1 | +import '../common/index.mjs'; |
| 2 | +import { describe, it } from 'node:test'; |
| 3 | +import * as assert from 'node:assert'; |
| 4 | +import * as path from 'node:path'; |
| 5 | + |
| 6 | + |
| 7 | +// https://github.com/torvalds/linux/blob/cdc9718d5e590d6905361800b938b93f2b66818e/lib/globtest.c |
| 8 | +const patterns = [ |
| 9 | + { expected: true, pattern: 'a', name: 'a' }, |
| 10 | + { expected: false, pattern: 'a', name: 'b' }, |
| 11 | + { expected: false, pattern: 'a', name: 'aa' }, |
| 12 | + { expected: false, pattern: 'a', name: '' }, |
| 13 | + { expected: true, pattern: '', name: '' }, |
| 14 | + { expected: false, pattern: '', name: 'a' }, |
| 15 | + /* Simple character class tests */ |
| 16 | + { expected: true, pattern: '[a]', name: 'a' }, |
| 17 | + { expected: false, pattern: '[a]', name: 'b' }, |
| 18 | + { expected: false, pattern: '[!a]', name: 'a' }, |
| 19 | + { expected: true, pattern: '[!a]', name: 'b' }, |
| 20 | + { expected: true, pattern: '[ab]', name: 'a' }, |
| 21 | + { expected: true, pattern: '[ab]', name: 'b' }, |
| 22 | + { expected: false, pattern: '[ab]', name: 'c' }, |
| 23 | + { expected: true, pattern: '[!ab]', name: 'c' }, |
| 24 | + { expected: true, pattern: '[a-c]', name: 'b' }, |
| 25 | + { expected: false, pattern: '[a-c]', name: 'd' }, |
| 26 | + /* Corner cases in character class parsing */ |
| 27 | + { expected: true, pattern: '[a-c-e-g]', name: '-' }, |
| 28 | + { expected: false, pattern: '[a-c-e-g]', name: 'd' }, |
| 29 | + { expected: true, pattern: '[a-c-e-g]', name: 'f' }, |
| 30 | + { expected: true, pattern: '[]a-ceg-ik[]', name: 'a' }, |
| 31 | + { expected: true, pattern: '[]a-ceg-ik[]', name: ']' }, |
| 32 | + { expected: true, pattern: '[]a-ceg-ik[]', name: '[' }, |
| 33 | + { expected: true, pattern: '[]a-ceg-ik[]', name: 'h' }, |
| 34 | + { expected: false, pattern: '[]a-ceg-ik[]', name: 'f' }, |
| 35 | + { expected: false, pattern: '[!]a-ceg-ik[]', name: 'h' }, |
| 36 | + { expected: false, pattern: '[!]a-ceg-ik[]', name: ']' }, |
| 37 | + { expected: true, pattern: '[!]a-ceg-ik[]', name: 'f' }, |
| 38 | + /* Simple wild cards */ |
| 39 | + { expected: true, pattern: '?', name: 'a' }, |
| 40 | + { expected: false, pattern: '?', name: 'aa' }, |
| 41 | + { expected: false, pattern: '??', name: 'a' }, |
| 42 | + { expected: true, pattern: '?x?', name: 'axb' }, |
| 43 | + { expected: false, pattern: '?x?', name: 'abx' }, |
| 44 | + { expected: false, pattern: '?x?', name: 'xab' }, |
| 45 | + /* Asterisk wild cards (backtracking) */ |
| 46 | + { expected: false, pattern: '*??', name: 'a' }, |
| 47 | + { expected: true, pattern: '*??', name: 'ab' }, |
| 48 | + { expected: true, pattern: '*??', name: 'abc' }, |
| 49 | + { expected: true, pattern: '*??', name: 'abcd' }, |
| 50 | + { expected: false, pattern: '??*', name: 'a' }, |
| 51 | + { expected: true, pattern: '??*', name: 'ab' }, |
| 52 | + { expected: true, pattern: '??*', name: 'abc' }, |
| 53 | + { expected: true, pattern: '??*', name: 'abcd' }, |
| 54 | + { expected: false, pattern: '?*?', name: 'a' }, |
| 55 | + { expected: true, pattern: '?*?', name: 'ab' }, |
| 56 | + { expected: true, pattern: '?*?', name: 'abc' }, |
| 57 | + { expected: true, pattern: '?*?', name: 'abcd' }, |
| 58 | + { expected: true, pattern: '*b', name: 'b' }, |
| 59 | + { expected: true, pattern: '*b', name: 'ab' }, |
| 60 | + { expected: false, pattern: '*b', name: 'ba' }, |
| 61 | + { expected: true, pattern: '*b', name: 'bb' }, |
| 62 | + { expected: true, pattern: '*b', name: 'abb' }, |
| 63 | + { expected: true, pattern: '*b', name: 'bab' }, |
| 64 | + { expected: true, pattern: '*bc', name: 'abbc' }, |
| 65 | + { expected: true, pattern: '*bc', name: 'bc' }, |
| 66 | + { expected: true, pattern: '*bc', name: 'bbc' }, |
| 67 | + { expected: true, pattern: '*bc', name: 'bcbc' }, |
| 68 | + /* Multiple asterisks (complex backtracking) */ |
| 69 | + { expected: true, pattern: '*ac*', name: 'abacadaeafag' }, |
| 70 | + { expected: true, pattern: '*ac*ae*ag*', name: 'abacadaeafag' }, |
| 71 | + { expected: true, pattern: '*a*b*[bc]*[ef]*g*', name: 'abacadaeafag' }, |
| 72 | + { expected: false, pattern: '*a*b*[ef]*[cd]*g*', name: 'abacadaeafag' }, |
| 73 | + { expected: true, pattern: '*abcd*', name: 'abcabcabcabcdefg' }, |
| 74 | + { expected: true, pattern: '*ab*cd*', name: 'abcabcabcabcdefg' }, |
| 75 | + { expected: true, pattern: '*abcd*abcdef*', name: 'abcabcdabcdeabcdefg' }, |
| 76 | + { expected: false, pattern: '*abcd*', name: 'abcabcabcabcefg' }, |
| 77 | + { expected: false, pattern: '*ab*cd*', name: 'abcabcabcabcefg' }, |
| 78 | +]; |
| 79 | + |
| 80 | +const invalid = [null, undefined, 1, Number.MAX_SAFE_INTEGER, true, false, Symbol(), {}, [], () => {}]; |
| 81 | + |
| 82 | +describe('path.glob', () => { |
| 83 | + for (const { expected, pattern, name } of patterns) { |
| 84 | + it(`pattern "${pattern}" should ${expected ? '' : 'not '}match "${name}"`, () => { |
| 85 | + assert.strictEqual(path.glob(pattern, name), expected); |
| 86 | + }); |
| 87 | + } |
| 88 | + |
| 89 | + for (const x of invalid) { |
| 90 | + const name = typeof x === 'symbol' ? 'Symnol()' : x; |
| 91 | + it(`${name} should throw as a parameter`, () => { |
| 92 | + assert.throws(() => path.glob(x, ''), { code: 'ERR_INVALID_ARG_TYPE' }); |
| 93 | + assert.throws(() => path.glob('', x), { code: 'ERR_INVALID_ARG_TYPE' }); |
| 94 | + }); |
| 95 | + } |
| 96 | +}); |
0 commit comments