|
1 | 1 | import { execFileSync } from 'node:child_process' |
2 | | -import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' |
| 2 | +import { |
| 3 | + mkdir, |
| 4 | + mkdtemp, |
| 5 | + readFile, |
| 6 | + rm, |
| 7 | + symlink, |
| 8 | + writeFile, |
| 9 | +} from 'node:fs/promises' |
3 | 10 | import { tmpdir } from 'node:os' |
4 | 11 | import path from 'node:path' |
5 | 12 | import { describe, expect, it } from 'vitest' |
@@ -31,39 +38,78 @@ describe('formatFiles', () => { |
31 | 38 | } |
32 | 39 | }) |
33 | 40 |
|
34 | | - it('honors Git ignores and exclusions while collecting errors and formatting other files', async () => { |
35 | | - const cwd = await mkdtemp(path.join(tmpdir(), 'purestack-format-')) |
| 41 | + const caseInsensitivePaths = |
| 42 | + process.platform === 'win32' || process.platform === 'darwin' |
| 43 | + |
| 44 | + it.each(caseInsensitivePaths ? [false, true] : [false])( |
| 45 | + 'honors Git ignores and exclusions while collecting errors (uppercase path: %s)', |
| 46 | + async (uppercase) => { |
| 47 | + const directory = await mkdtemp(path.join(tmpdir(), 'purestack-format-')) |
| 48 | + const cwd = uppercase ? directory.toUpperCase() : directory |
| 49 | + try { |
| 50 | + execFileSync('git', ['init', cwd], { stdio: 'ignore' }) |
| 51 | + await writeFile(path.join(cwd, '.gitignore'), 'ignored.mdx\n') |
| 52 | + await writeFile( |
| 53 | + path.join(cwd, 'ignored.mdx'), |
| 54 | + '<Panel><Badge /></Panel>', |
| 55 | + ) |
| 56 | + await writeFile( |
| 57 | + path.join(cwd, 'excluded.mdx'), |
| 58 | + '<Panel><Badge /></Panel>', |
| 59 | + ) |
| 60 | + await writeFile(path.join(cwd, 'good.mdx'), '<Panel><Badge /></Panel>') |
| 61 | + await writeFile( |
| 62 | + path.join(cwd, 'bad.mdx'), |
| 63 | + '<Panel title="broken></Panel>', |
| 64 | + ) |
| 65 | + const result = await formatFiles(['.', 'missing.mdx'], { |
| 66 | + cwd, |
| 67 | + write: true, |
| 68 | + exclude: [uppercase ? 'EXCLUDED.mdx' : 'excluded.mdx'], |
| 69 | + }) |
| 70 | + expect(result.checked).toBe(2) |
| 71 | + expect(result.changed).toEqual([path.join(cwd, 'good.mdx')]) |
| 72 | + expect( |
| 73 | + result.errors.map((error) => path.basename(error.filePath)).sort(), |
| 74 | + ).toEqual(['bad.mdx', 'missing.mdx']) |
| 75 | + expect(await readFile(path.join(cwd, 'bad.mdx'), 'utf8')).toBe( |
| 76 | + '<Panel title="broken></Panel>', |
| 77 | + ) |
| 78 | + expect(await readFile(path.join(cwd, 'ignored.mdx'), 'utf8')).toBe( |
| 79 | + '<Panel><Badge /></Panel>', |
| 80 | + ) |
| 81 | + } finally { |
| 82 | + await rm(directory, { recursive: true, force: true }) |
| 83 | + } |
| 84 | + }, |
| 85 | + ) |
| 86 | + |
| 87 | + it('honors Git ignores and exclusions through a directory alias', async () => { |
| 88 | + const directory = await mkdtemp(path.join(tmpdir(), 'purestack-format-')) |
| 89 | + const projects = path.join(directory, 'projects') |
| 90 | + const repository = path.join(projects, 'project with spaces') |
| 91 | + const alias = path.join(directory, 'projects-alias') |
| 92 | + const cwd = path.join(alias, 'project with spaces') |
36 | 93 | try { |
37 | | - execFileSync('git', ['init', cwd], { stdio: 'ignore' }) |
38 | | - await writeFile(path.join(cwd, '.gitignore'), 'ignored.mdx\n') |
39 | | - await writeFile(path.join(cwd, 'ignored.mdx'), '<Panel><Badge /></Panel>') |
40 | | - await writeFile( |
41 | | - path.join(cwd, 'excluded.mdx'), |
42 | | - '<Panel><Badge /></Panel>', |
43 | | - ) |
44 | | - await writeFile(path.join(cwd, 'good.mdx'), '<Panel><Badge /></Panel>') |
45 | | - await writeFile( |
46 | | - path.join(cwd, 'bad.mdx'), |
47 | | - '<Panel title="broken></Panel>', |
| 94 | + await mkdir(repository, { recursive: true }) |
| 95 | + execFileSync('git', ['init', repository], { stdio: 'ignore' }) |
| 96 | + await writeFile(path.join(repository, '.gitignore'), 'ignored.mdx\n') |
| 97 | + for (const file of ['good.mdx', 'excluded.mdx', 'ignored.mdx']) |
| 98 | + await writeFile(path.join(repository, file), '<Panel><Badge /></Panel>') |
| 99 | + await symlink( |
| 100 | + projects, |
| 101 | + alias, |
| 102 | + process.platform === 'win32' ? 'junction' : 'dir', |
48 | 103 | ) |
49 | | - const result = await formatFiles(['.', 'missing.mdx'], { |
| 104 | + const result = await formatFiles(['.'], { |
50 | 105 | cwd, |
51 | | - write: true, |
52 | 106 | exclude: ['excluded.mdx'], |
53 | 107 | }) |
54 | | - expect(result.checked).toBe(2) |
| 108 | + expect(result.errors).toEqual([]) |
| 109 | + expect(result.checked).toBe(1) |
55 | 110 | expect(result.changed).toEqual([path.join(cwd, 'good.mdx')]) |
56 | | - expect( |
57 | | - result.errors.map((error) => path.basename(error.filePath)).sort(), |
58 | | - ).toEqual(['bad.mdx', 'missing.mdx']) |
59 | | - expect(await readFile(path.join(cwd, 'bad.mdx'), 'utf8')).toBe( |
60 | | - '<Panel title="broken></Panel>', |
61 | | - ) |
62 | | - expect(await readFile(path.join(cwd, 'ignored.mdx'), 'utf8')).toBe( |
63 | | - '<Panel><Badge /></Panel>', |
64 | | - ) |
65 | 111 | } finally { |
66 | | - await rm(cwd, { recursive: true, force: true }) |
| 112 | + await rm(directory, { recursive: true, force: true }) |
67 | 113 | } |
68 | 114 | }) |
69 | 115 | }) |
0 commit comments