11import assert from 'node:assert/strict' ;
22import { createRequire } from 'node:module' ;
3- import type { Configs } from '../../src/config.ts' ;
43import { expect , rs , test } from 'rstack/test' ;
54import {
65 composeConfigLayers ,
@@ -19,60 +18,29 @@ rs.mock(
1918 ) as typeof import ( '../../src/rstestConfig.ts' ) ,
2019) ;
2120
22- const params = { command : 'build' , env : 'production' } as const ;
23-
2421test ( 'preserves single definitions and leaves missing tools absent' , async ( ) => {
2522 const app = rs . fn ( ( ) => ( { } ) ) ;
26- const base : Configs = { app, lint : [ ] } ;
27- const project : Configs = { fmt : { } } ;
23+ const base = { app } ;
24+ const fmt = { } ;
2825
2926 expect ( await composeConfigLayers ( [ ] ) ) . toEqual ( { } ) ;
3027 expect ( await composeConfigLayers ( [ base ] ) ) . toBe ( base ) ;
31- const configs = await composeConfigLayers ( [ base , project ] ) ;
32- expect ( configs ) . toEqual ( { app, lint : base . lint , fmt : project . fmt } ) ;
33- expect ( configs . lint ) . toBe ( base . lint ) ;
34- expect ( configs . fmt ) . toBe ( project . fmt ) ;
28+ const configs = await composeConfigLayers ( [ base , { fmt } ] ) ;
29+ expect ( configs ) . toEqual ( { app, fmt } ) ;
30+ expect ( configs . fmt ) . toBe ( fmt ) ;
3531 expect ( app ) . not . toHaveBeenCalled ( ) ;
3632} ) ;
3733
38- test ( 'composes tool definitions lazily and resolves each factory once' , async ( ) => {
39- const app = rs . fn ( ( ) => ( { source : { define : { APP : true } } } ) ) ;
40- const lib = rs . fn ( ( ) => ( { lib : [ { format : 'esm' as const } ] } ) ) ;
41- const doc = rs . fn ( ( ) => Promise . resolve ( { title : 'Shared' } ) ) ;
42- const lint = rs . fn ( ( ) =>
43- Promise . resolve ( [ { rules : { 'no-debugger' : 'error' as const } } ] ) ,
44- ) ;
34+ test ( 'resolves only the requested tool and preserves staged task generators' , async ( ) => {
35+ const app = rs . fn ( ( ) => ( { } ) ) ;
4536 const fmt = rs . fn ( ( ) => ( { semi : false } ) ) ;
4637 const staged = rs . fn ( ( ) => 'rs check' ) ;
4738 const configs = await composeConfigLayers ( [
48- { app, lib, doc, lint, fmt, staged : { '*.ts' : 'rs lint' } } ,
49- {
50- app : { } ,
51- lib : { } ,
52- doc : { title : 'Project' } ,
53- lint : [ ] ,
54- fmt : { singleQuote : true } ,
55- staged,
56- } ,
39+ { app, fmt, staged : { '*.ts' : 'rs lint' } } ,
40+ { app : { } , fmt : { singleQuote : true } , staged } ,
5741 ] ) ;
5842
59- for ( const factory of [ app , lib , doc , lint , fmt , staged ] ) {
60- expect ( factory ) . not . toHaveBeenCalled ( ) ;
61- }
62- expect ( await resolveConfigLayers ( [ configs ] , 'app' , params ) ) . toEqual ( [
63- { source : { define : { APP : true } } } ,
64- ] ) ;
65- expect ( lib ) . not . toHaveBeenCalled ( ) ;
66- expect ( doc ) . not . toHaveBeenCalled ( ) ;
67- expect ( await resolveConfigLayers ( [ configs ] , 'lib' , params ) ) . toEqual ( [
68- { lib : [ { format : 'esm' } ] } ,
69- ] ) ;
70- expect ( await resolveConfigLayers ( [ configs ] , 'doc' ) ) . toEqual ( [
71- { title : 'Project' } ,
72- ] ) ;
73- expect ( await resolveConfigLayers ( [ configs ] , 'lint' ) ) . toEqual ( [
74- [ { rules : { 'no-debugger' : 'error' } } ] ,
75- ] ) ;
43+ expect ( fmt ) . not . toHaveBeenCalled ( ) ;
7644 expect (
7745 await resolveFmtConfig ( {
7846 layers : [ configs ] ,
@@ -85,41 +53,36 @@ test('composes tool definitions lazily and resolves each factory once', async ()
8553 overrides : [ ] ,
8654 ignorePatterns : [ ] ,
8755 } ) ;
56+ expect ( fmt ) . toHaveBeenCalledExactlyOnceWith ( ) ;
57+ expect ( app ) . not . toHaveBeenCalled ( ) ;
8858 expect ( configs . staged ) . toBe ( staged ) ;
8959 expect ( staged ) . not . toHaveBeenCalled ( ) ;
90- expect ( app ) . toHaveBeenCalledExactlyOnceWith ( params ) ;
91- expect ( lib ) . toHaveBeenCalledExactlyOnceWith ( params ) ;
92- for ( const factory of [ doc , lint , fmt ] ) {
93- expect ( factory ) . toHaveBeenCalledExactlyOnceWith ( ) ;
94- }
9560} ) ;
9661
97- test ( 'defers test inheritance until the consumer resolves the composed config ' , async ( ) => {
62+ test ( 'applies automatic inheritance after merging test definitions ' , async ( ) => {
9863 const app = rs . fn ( ( ) => ( { source : { define : { SHARED : true } } } ) ) ;
9964 const configs = await composeConfigLayers ( [
10065 { app, test : { retry : 1 } } ,
10166 {
10267 app : { source : { define : { PROJECT : true } } } ,
103- test : { projects : [ { name : 'a' } , { name : 'b' } ] } ,
68+ test : { testTimeout : 5000 } ,
10469 } ,
10570 ] ) ;
106- const raw = await resolveConfigLayers ( [ configs ] , 'test' ) ;
107- expect ( raw ) . toEqual ( [ { retry : 1 , projects : [ { name : 'a' } , { name : 'b' } ] } ] ) ;
71+
72+ expect ( await resolveConfigLayers ( [ configs ] , 'test' ) ) . toEqual ( [
73+ { retry : 1 , testTimeout : 5000 } ,
74+ ] ) ;
10875 expect ( app ) . not . toHaveBeenCalled ( ) ;
10976
77+ const params = { command : 'build' , env : 'production' } as const ;
11078 const config = await resolveRstestConfig ( [ configs ] , params ) ;
111- const first = config . projects ?. [ 0 ] ;
112- assert (
113- first && typeof first !== 'string' && typeof first . extends === 'function' ,
114- ) ;
79+ assert ( typeof config . extends === 'function' ) ;
11580 expect ( config ) . toEqual ( {
11681 retry : 1 ,
117- projects : [
118- { name : 'a' , extends : first . extends } ,
119- { name : 'b' , extends : first . extends } ,
120- ] ,
82+ testTimeout : 5000 ,
83+ extends : config . extends ,
12184 } ) ;
122- expect ( await first . extends ( first ) ) . toMatchObject ( {
85+ expect ( await config . extends ( config ) ) . toMatchObject ( {
12386 source : { define : { SHARED : true , PROJECT : true } } ,
12487 } ) ;
12588 expect ( app ) . toHaveBeenCalledExactlyOnceWith ( params ) ;
0 commit comments