1- import { execFileSync } from 'node:child_process' ;
2- import { mkdtemp , rm , writeFile } from 'node:fs/promises' ;
3- import path from 'node:path' ;
1+ import lintStaged from 'lint-staged' ;
2+ import { beforeEach , rs } from 'rstack/test' ;
43import { test } from '#test-helpers' ;
4+ import { loadRstackConfig } from '../../../src/config.ts' ;
5+ import { runStagedCLI , type StagedConfig } from '../../../src/staged.ts' ;
56
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';
7+ rs . mock ( 'lint-staged' ) ;
8+ rs . mock ( '../../../src/config.ts' ) ;
249
25- for (const file of process.argv.slice(2)) {
26- writeFileSync(file, 'initial\\n');
27- }
28-
29- console.log('staged task output');
30- console.log('staged file:', process.argv[2]);
31- ` ,
32- ) ,
33- writeFile ( path . join ( cwd , 'file.txt' ) , 'initial\n' ) ,
34- ] ) ;
35-
36- git ( cwd , [ 'init' , '--quiet' ] ) ;
37- git ( cwd , [ 'add' , '.' ] ) ;
38- git ( cwd , [
39- '-c' ,
40- 'user.name=Rstack Test' ,
41- '-c' ,
42- 'user.email=rstack@example.com' ,
43- 'commit' ,
44- '--quiet' ,
45- '-m' ,
46- 'initial' ,
47- ] ) ;
48-
49- await writeFile ( path . join ( cwd , 'file.txt' ) , 'changed\n' ) ;
50- git ( cwd , [ 'add' , 'file.txt' ] ) ;
51-
52- return cwd ;
10+ const mocks = {
11+ lintStaged : rs . mocked ( lintStaged ) ,
12+ loadRstackConfig : rs . mocked ( loadRstackConfig ) ,
5313} ;
5414
55- const withGitFixture = async ( callback : ( cwd : string ) => Promise < void > | void ) : Promise < void > => {
56- const cwd = await createGitFixture ( ) ;
57-
58- try {
59- await callback ( cwd ) ;
60- } finally {
61- await rm ( cwd , { recursive : true , force : true } ) ;
62- }
15+ const stagedConfig : StagedConfig = {
16+ '*.txt' : 'echo test' ,
6317} ;
6418
19+ beforeEach ( ( ) => {
20+ rs . resetAllMocks ( ) ;
21+ mocks . lintStaged . mockResolvedValue ( true ) ;
22+ mocks . loadRstackConfig . mockResolvedValue ( {
23+ configs : { staged : stagedConfig } ,
24+ filePath : null ,
25+ dependencies : [ ] ,
26+ } ) ;
27+ } ) ;
28+
6529test ( 'should display the staged help message' , ( { execCli, expect } ) => {
6630 const output = execCli ( 'staged --help' ) ;
6731
@@ -82,76 +46,61 @@ test('should reject unknown staged options', ({ execCli, expect }) => {
8246 expect ( ( ) => execCli ( 'staged --unknown' ) ) . toThrow ( ) ;
8347} ) ;
8448
85- test ( 'should prevent an empty commit by default' , async ( { execCli, expect } ) => {
86- await withGitFixture ( ( cwd ) => {
87- expect ( ( ) => execCli ( 'staged' , { cwd } ) ) . toThrow ( ) ;
49+ test ( 'should pass default options to lint-staged' , async ( { expect } ) => {
50+ await runStagedCLI ( [ ] ) ;
51+
52+ expect ( mocks . lintStaged ) . toHaveBeenCalledWith ( {
53+ allowEmpty : undefined ,
54+ concurrent : undefined ,
55+ config : stagedConfig ,
56+ cwd : undefined ,
57+ debug : undefined ,
58+ quiet : undefined ,
59+ relative : undefined ,
60+ stash : undefined ,
61+ verbose : undefined ,
8862 } ) ;
8963} ) ;
9064
91- test ( 'should allow an empty commit with --allow-empty' , async ( { execCli } ) => {
92- await withGitFixture ( ( cwd ) => {
93- execCli ( `staged --allow-empty` , { cwd } ) ;
94- } ) ;
95- } ) ;
96-
97- for ( const option of [ '--concurrent false' , '-p 1' ] ) {
98- test ( `should run staged tasks with ${ option } ` , async ( { execCli } ) => {
99- await withGitFixture ( ( cwd ) => {
100- execCli ( `staged --allow-empty ${ option } ` , { cwd } ) ;
101- } ) ;
102- } ) ;
103- }
104-
105- for ( const option of [ '--debug' , '-d' ] ) {
106- test ( `should print debug output with ${ option } ` , async ( { execCli, expect } ) => {
107- await withGitFixture ( ( cwd ) => {
108- const output = execCli ( `staged --allow-empty ${ option } 2>&1` , { cwd } ) ;
109- expect ( output ) . toContain ( 'lint-staged:' ) ;
110- } ) ;
111- } ) ;
112- }
113-
114- for ( const option of [ '--verbose' , '-v' ] ) {
115- test ( `should show successful task output with ${ option } ` , async ( { execCli, expect } ) => {
116- await withGitFixture ( ( cwd ) => {
117- const output = execCli ( `staged --allow-empty ${ option } ` , { cwd } ) ;
118- expect ( output ) . toContain ( 'staged task output' ) ;
119- } ) ;
120- } ) ;
121- }
65+ test ( 'should pass long options to lint-staged' , async ( { expect } ) => {
66+ await runStagedCLI ( [
67+ '--allow-empty' ,
68+ '--concurrent' ,
69+ 'false' ,
70+ '--cwd' ,
71+ 'fixture' ,
72+ '--debug' ,
73+ '--no-stash' ,
74+ '--quiet' ,
75+ '--relative' ,
76+ '--verbose' ,
77+ ] ) ;
12278
123- test ( 'should run staged tasks without a backup stash' , async ( { execCli, expect } ) => {
124- await withGitFixture ( ( cwd ) => {
125- const output = execCli ( 'staged --allow-empty --no-stash 2>&1' , { cwd } ) ;
126- expect ( output ) . toContain ( 'Skipping backup because `--no-stash` was used' ) ;
79+ expect ( mocks . lintStaged ) . toHaveBeenCalledWith ( {
80+ allowEmpty : true ,
81+ concurrent : false ,
82+ config : stagedConfig ,
83+ cwd : 'fixture' ,
84+ debug : true ,
85+ quiet : true ,
86+ relative : true ,
87+ stash : false ,
88+ verbose : true ,
12789 } ) ;
12890} ) ;
12991
130- for ( const option of [ '--quiet' , '-q' ] ) {
131- test ( `should suppress lint-staged output with ${ option } ` , async ( { execCli, expect } ) => {
132- await withGitFixture ( ( cwd ) => {
133- const output = execCli ( `staged --allow-empty ${ option } ` , { cwd } ) ;
134- expect ( output ) . toBe ( '' ) ;
135- } ) ;
136- } ) ;
137- }
138-
139- for ( const option of [ '--relative' , '-r' ] ) {
140- test ( `should pass relative filepaths with ${ option } ` , async ( { execCli, expect } ) => {
141- await withGitFixture ( ( cwd ) => {
142- const output = execCli ( `staged --allow-empty --verbose ${ option } ` , { cwd } ) ;
143- expect ( output ) . toContain ( 'staged file: file.txt' ) ;
144- } ) ;
145- } ) ;
146- }
147-
148- test ( 'should run staged tasks in the specified cwd' , async ( { execCli, expect } ) => {
149- await withGitFixture ( ( cwd ) => {
150- const configPath = path . join ( cwd , 'rstack.config.ts' ) ;
151- const output = execCli (
152- `--config ${ JSON . stringify ( configPath ) } staged --allow-empty --cwd ${ JSON . stringify ( cwd ) } --relative --verbose` ,
153- { cwd : path . dirname ( cwd ) } ,
154- ) ;
155- expect ( output ) . toContain ( 'staged file: file.txt' ) ;
92+ test ( 'should pass short options and aliases to lint-staged' , async ( { expect } ) => {
93+ await runStagedCLI ( [ '--allowEmpty' , '-p' , '1' , '-d' , '-q' , '-r' , '-v' ] ) ;
94+
95+ expect ( mocks . lintStaged ) . toHaveBeenCalledWith ( {
96+ allowEmpty : true ,
97+ concurrent : 1 ,
98+ config : stagedConfig ,
99+ cwd : undefined ,
100+ debug : true ,
101+ quiet : true ,
102+ relative : true ,
103+ stash : undefined ,
104+ verbose : true ,
156105 } ) ;
157106} ) ;
0 commit comments