wip library to store cold objects in s3, warm objects on disk, and hot objects in memory
nodejs typescript
at main 3.8 kB view raw
1import { describe, it, expect } from 'vitest'; 2import { matchGlob } from '../src/utils/glob.js'; 3 4describe('matchGlob', () => { 5 describe('exact matches', () => { 6 it('should match exact strings', () => { 7 expect(matchGlob('index.html', 'index.html')).toBe(true); 8 expect(matchGlob('index.html', 'about.html')).toBe(false); 9 }); 10 11 it('should match paths exactly', () => { 12 expect(matchGlob('site/index.html', 'site/index.html')).toBe(true); 13 expect(matchGlob('site/index.html', 'other/index.html')).toBe(false); 14 }); 15 }); 16 17 describe('* wildcard', () => { 18 it('should match any characters except /', () => { 19 expect(matchGlob('*.html', 'index.html')).toBe(true); 20 expect(matchGlob('*.html', 'about.html')).toBe(true); 21 expect(matchGlob('*.html', 'style.css')).toBe(false); 22 }); 23 24 it('should not match across path separators', () => { 25 expect(matchGlob('*.html', 'dir/index.html')).toBe(false); 26 }); 27 28 it('should work with prefix and suffix', () => { 29 expect(matchGlob('index.*', 'index.html')).toBe(true); 30 expect(matchGlob('index.*', 'index.css')).toBe(true); 31 expect(matchGlob('index.*', 'about.html')).toBe(false); 32 }); 33 }); 34 35 describe('** wildcard', () => { 36 it('should match any characters including /', () => { 37 expect(matchGlob('**', 'anything')).toBe(true); 38 expect(matchGlob('**', 'path/to/file.txt')).toBe(true); 39 }); 40 41 it('should match deeply nested paths', () => { 42 expect(matchGlob('**/index.html', 'index.html')).toBe(true); 43 expect(matchGlob('**/index.html', 'site/index.html')).toBe(true); 44 expect(matchGlob('**/index.html', 'a/b/c/index.html')).toBe(true); 45 expect(matchGlob('**/index.html', 'a/b/c/about.html')).toBe(false); 46 }); 47 48 it('should match directory prefixes', () => { 49 expect(matchGlob('assets/**', 'assets/style.css')).toBe(true); 50 expect(matchGlob('assets/**', 'assets/images/logo.png')).toBe(true); 51 expect(matchGlob('assets/**', 'other/style.css')).toBe(false); 52 }); 53 54 it('should match in the middle of a path', () => { 55 expect(matchGlob('site/**/index.html', 'site/index.html')).toBe(true); 56 expect(matchGlob('site/**/index.html', 'site/pages/index.html')).toBe(true); 57 expect(matchGlob('site/**/index.html', 'site/a/b/c/index.html')).toBe(true); 58 }); 59 }); 60 61 describe('{a,b,c} alternation', () => { 62 it('should match any of the alternatives', () => { 63 expect(matchGlob('*.{html,css,js}', 'index.html')).toBe(true); 64 expect(matchGlob('*.{html,css,js}', 'style.css')).toBe(true); 65 expect(matchGlob('*.{html,css,js}', 'app.js')).toBe(true); 66 expect(matchGlob('*.{html,css,js}', 'image.png')).toBe(false); 67 }); 68 69 it('should work with ** and alternation', () => { 70 expect(matchGlob('**/*.{jpg,png,gif}', 'logo.png')).toBe(true); 71 expect(matchGlob('**/*.{jpg,png,gif}', 'images/logo.png')).toBe(true); 72 expect(matchGlob('**/*.{jpg,png,gif}', 'a/b/photo.jpg')).toBe(true); 73 expect(matchGlob('**/*.{jpg,png,gif}', 'style.css')).toBe(false); 74 }); 75 }); 76 77 describe('edge cases', () => { 78 it('should handle empty strings', () => { 79 expect(matchGlob('', '')).toBe(true); 80 expect(matchGlob('', 'something')).toBe(false); 81 expect(matchGlob('**', '')).toBe(true); 82 }); 83 84 it('should escape regex special characters', () => { 85 expect(matchGlob('file.txt', 'file.txt')).toBe(true); 86 expect(matchGlob('file.txt', 'filextxt')).toBe(false); 87 expect(matchGlob('file[1].txt', 'file[1].txt')).toBe(true); 88 }); 89 90 it('should handle keys with colons (common in storage)', () => { 91 expect(matchGlob('site:*/index.html', 'site:abc/index.html')).toBe(true); 92 expect(matchGlob('site:**/index.html', 'site:abc/pages/index.html')).toBe(true); 93 }); 94 }); 95});