|
| 1 | +import { execFileSync } from 'node:child_process'; |
| 2 | +import { mkdtemp, rm, writeFile } from 'node:fs/promises'; |
| 3 | +import path from 'node:path'; |
| 4 | +import { test } from '#test-helpers'; |
| 5 | + |
| 6 | +const git = (cwd: string, args: string[]): void => { |
| 7 | + execFileSync('git', args, { cwd, stdio: 'ignore' }); |
| 8 | +}; |
| 9 | + |
| 10 | +const createGitFixture = async (): Promise<string> => { |
| 11 | + const cwd = await mkdtemp(path.join(import.meta.dirname, 'fixture-')); |
| 12 | + |
| 13 | + await Promise.all([ |
| 14 | + writeFile( |
| 15 | + path.join(cwd, 'rstack.config.ts'), |
| 16 | + `import { define } from 'rstack'; |
| 17 | +
|
| 18 | +define.staged({ '*.txt': 'node revert.mjs' }); |
| 19 | +`, |
| 20 | + ), |
| 21 | + writeFile( |
| 22 | + path.join(cwd, 'revert.mjs'), |
| 23 | + `import { writeFileSync } from 'node:fs'; |
| 24 | +
|
| 25 | +for (const file of process.argv.slice(2)) { |
| 26 | + writeFileSync(file, 'initial\\n'); |
| 27 | +} |
| 28 | +`, |
| 29 | + ), |
| 30 | + writeFile(path.join(cwd, 'file.txt'), 'initial\n'), |
| 31 | + ]); |
| 32 | + |
| 33 | + git(cwd, ['init', '--quiet']); |
| 34 | + git(cwd, ['add', '.']); |
| 35 | + git(cwd, [ |
| 36 | + '-c', |
| 37 | + 'user.name=Rstack Test', |
| 38 | + '-c', |
| 39 | + 'user.email=rstack@example.com', |
| 40 | + 'commit', |
| 41 | + '--quiet', |
| 42 | + '-m', |
| 43 | + 'initial', |
| 44 | + ]); |
| 45 | + |
| 46 | + await writeFile(path.join(cwd, 'file.txt'), 'changed\n'); |
| 47 | + git(cwd, ['add', 'file.txt']); |
| 48 | + |
| 49 | + return cwd; |
| 50 | +}; |
| 51 | + |
| 52 | +const withGitFixture = async (callback: (cwd: string) => Promise<void> | void): Promise<void> => { |
| 53 | + const cwd = await createGitFixture(); |
| 54 | + |
| 55 | + try { |
| 56 | + await callback(cwd); |
| 57 | + } finally { |
| 58 | + await rm(cwd, { recursive: true, force: true }); |
| 59 | + } |
| 60 | +}; |
| 61 | + |
| 62 | +test('should display the staged help message', ({ execCli, expect }) => { |
| 63 | + const output = execCli('staged --help'); |
| 64 | + |
| 65 | + expect(output).toContain('Rstack v'); |
| 66 | + expect(output).toContain('Usage:\n $ rs staged [options]'); |
| 67 | + expect(output).toContain('Runs lint-staged with tasks from define.staged in rstack.config.'); |
| 68 | + expect(output).toContain('--allow-empty'); |
| 69 | + expect(output).toContain('-h, --help'); |
| 70 | +}); |
| 71 | + |
| 72 | +test('should reject unknown staged options', ({ execCli, expect }) => { |
| 73 | + expect(() => execCli('staged --unknown')).toThrow(); |
| 74 | +}); |
| 75 | + |
| 76 | +test('should prevent an empty commit by default', async ({ execCli, expect }) => { |
| 77 | + await withGitFixture((cwd) => { |
| 78 | + expect(() => execCli('staged', { cwd })).toThrow(); |
| 79 | + }); |
| 80 | +}); |
| 81 | + |
| 82 | +test(`should allow an empty commit with --allow-empty`, async ({ execCli }) => { |
| 83 | + await withGitFixture((cwd) => { |
| 84 | + execCli(`staged --allow-empty`, { cwd }); |
| 85 | + }); |
| 86 | +}); |
0 commit comments