@@ -100,6 +100,25 @@ export class RecipeSpec {
100100 allParsed . push ( ...parsed ) ;
101101 }
102102
103+ // Apply beforeRecipe hooks (after idempotence check, before recipe execution)
104+ for ( let i = 0 ; i < allParsed . length ; i ++ ) {
105+ const [ spec , sourceFile ] = allParsed [ i ] ;
106+ if ( spec . beforeRecipe ) {
107+ const b = spec . beforeRecipe ( sourceFile ) ;
108+ if ( b !== undefined ) {
109+ if ( b instanceof Promise ) {
110+ const mapped = await b ;
111+ if ( mapped === undefined ) {
112+ throw new Error ( "Expected beforeRecipe to return a SourceFile, but got undefined. Did you forget a return statement?" ) ;
113+ }
114+ allParsed [ i ] = [ spec , mapped ] ;
115+ } else {
116+ allParsed [ i ] = [ spec , b as SourceFile ] ;
117+ }
118+ }
119+ }
120+ }
121+
103122 const changeset = ( await scheduleRun ( this . recipe ,
104123 allParsed . map ( ( [ _ , sourceFile ] ) => sourceFile ) ,
105124 this . recipeExecutionContext ) ) . changeset ;
@@ -131,17 +150,18 @@ export class RecipeSpec {
131150 private async expectResultsToMatchAfter ( specs : SourceSpec < any > [ ] , changeset : Result [ ] , parsed : [ SourceSpec < any > , SourceFile ] [ ] ) {
132151 for ( const spec of specs ) {
133152 const matchingSpec = parsed . find ( ( [ s , _ ] ) => s === spec ) ;
134- const after = changeset . find ( c => {
153+ const result = changeset . find ( c => {
135154 if ( c . before ) {
136155 return c . before === matchingSpec ! [ 1 ] ;
137156 } else if ( c . after ) {
138157 const matchingSpec = specs . find ( s => s . path === c . after ! . sourcePath ) ;
139158 return ! ! matchingSpec ;
140159 }
141- } ) ?. after ;
160+ } ) ;
161+ const after = result ?. after ;
142162
143163 if ( ! spec . after ) {
144- if ( after ) {
164+ if ( after && after !== result ?. before ) {
145165 expect ( await TreePrinters . print ( after ) ) . toEqual ( dedent ( spec . before ! ) ) ;
146166 // TODO: Consider throwing an error, as there should typically have been no change to the LST
147167 // fail("Expected after to be undefined.");
@@ -200,21 +220,7 @@ export class RecipeSpec {
200220 for await ( const sourceFile of parser . parse ( ...before . map ( ( [ _ , parserInput ] ) => parserInput ) ) ) {
201221 parsed . push ( sourceFile ) ;
202222 }
203- const specToParsed : [ SourceSpec < any > , SourceFile ] [ ] = before . map ( ( [ spec , _ ] , i ) => [ spec , parsed [ i ] ] ) ;
204- return await mapAsync ( specToParsed , async ( [ spec , sourceFile ] ) => {
205- const b = spec . beforeRecipe ? spec . beforeRecipe ( sourceFile ) : sourceFile ;
206- if ( b !== undefined ) {
207- if ( b instanceof Promise ) {
208- const mapped = await b ;
209- if ( mapped === undefined ) {
210- throw new Error ( "Expected beforeRecipe to return a SourceFile, but got undefined. Did you forget a return statement?" ) ;
211- }
212- return [ spec , mapped ] ;
213- }
214- return [ spec , b as SourceFile ] ;
215- }
216- return [ spec , sourceFile ] ;
217- } ) ;
223+ return before . map ( ( [ spec , _ ] , i ) : [ SourceSpec < any > , SourceFile ] => [ spec , parsed [ i ] ] ) ;
218224 }
219225
220226 private async expectWhitespaceNotToContainNonwhitespaceCharacters ( parsed : [ SourceSpec < any > , SourceFile ] [ ] ) {
0 commit comments