@@ -34,12 +34,14 @@ test.serial(
3434 "writeOverlayChangesFile generates correct changes file" ,
3535 async ( t ) => {
3636 await withTmpDir ( async ( tmpDir ) => {
37- const dbLocation = path . join ( tmpDir , "db" ) ;
38- await fs . promises . mkdir ( dbLocation , { recursive : true } ) ;
39- const sourceRoot = path . join ( tmpDir , "src" ) ;
40- await fs . promises . mkdir ( sourceRoot , { recursive : true } ) ;
41- const tempDir = path . join ( tmpDir , "temp" ) ;
42- await fs . promises . mkdir ( tempDir , { recursive : true } ) ;
37+ const [ dbLocation , sourceRoot , tempDir ] = [ "db" , "src" , "temp" ] . map ( ( d ) =>
38+ path . join ( tmpDir , d ) ,
39+ ) ;
40+ await Promise . all (
41+ [ dbLocation , sourceRoot , tempDir ] . map ( ( d ) =>
42+ fs . promises . mkdir ( d , { recursive : true } ) ,
43+ ) ,
44+ ) ;
4345
4446 const logger = getRunnerLogger ( true ) ;
4547 const config = createTestConfig ( { dbLocation } ) ;
@@ -93,6 +95,146 @@ test.serial(
9395 } ,
9496) ;
9597
98+ test . serial (
99+ "writeOverlayChangesFile merges additional diff files into overlay changes" ,
100+ async ( t ) => {
101+ await withTmpDir ( async ( tmpDir ) => {
102+ const [ dbLocation , sourceRoot , tempDir ] = [ "db" , "src" , "temp" ] . map ( ( d ) =>
103+ path . join ( tmpDir , d ) ,
104+ ) ;
105+ await Promise . all (
106+ [ dbLocation , sourceRoot , tempDir ] . map ( ( d ) =>
107+ fs . promises . mkdir ( d , { recursive : true } ) ,
108+ ) ,
109+ ) ;
110+
111+ const logger = getRunnerLogger ( true ) ;
112+ const config = createTestConfig ( { dbLocation } ) ;
113+
114+ // Mock the getFileOidsUnderPath function to return base OIDs
115+ // "reverted.js" has the same OID in both base and current, simulating
116+ // a revert PR where the file content matches the overlay-base
117+ const baseOids = {
118+ "unchanged.js" : "aaa111" ,
119+ "modified.js" : "bbb222" ,
120+ "reverted.js" : "eee555" ,
121+ } ;
122+ const getFileOidsStubForBase = sinon
123+ . stub ( gitUtils , "getFileOidsUnderPath" )
124+ . resolves ( baseOids ) ;
125+
126+ // Write the base database OIDs file
127+ await writeBaseDatabaseOidsFile ( config , sourceRoot ) ;
128+ getFileOidsStubForBase . restore ( ) ;
129+
130+ // Mock the getFileOidsUnderPath function to return overlay OIDs
131+ // "reverted.js" has the same OID as the base -- OID comparison alone
132+ // would NOT include it, only additionalChangedFiles causes it to appear
133+ const currentOids = {
134+ "unchanged.js" : "aaa111" ,
135+ "modified.js" : "ddd444" , // Changed OID
136+ "reverted.js" : "eee555" , // Same OID as base -- not detected by OID comparison
137+ } ;
138+ const getFileOidsStubForOverlay = sinon
139+ . stub ( gitUtils , "getFileOidsUnderPath" )
140+ . resolves ( currentOids ) ;
141+
142+ const getTempDirStub = sinon
143+ . stub ( actionsUtil , "getTemporaryDirectory" )
144+ . returns ( tempDir ) ;
145+
146+ // Write a pr-diff-range.json file with diff ranges including
147+ // "reverted.js" (unchanged OIDs) and "modified.js" (already in OID changes)
148+ await fs . promises . writeFile (
149+ path . join ( tempDir , "pr-diff-range.json" ) ,
150+ JSON . stringify ( [
151+ { path : "reverted.js" , startLine : 1 , endLine : 10 } ,
152+ { path : "modified.js" , startLine : 1 , endLine : 5 } ,
153+ { path : "diff-only.js" , startLine : 1 , endLine : 3 } ,
154+ ] ) ,
155+ ) ;
156+
157+ const changesFilePath = await writeOverlayChangesFile (
158+ config ,
159+ sourceRoot ,
160+ logger ,
161+ ) ;
162+ getFileOidsStubForOverlay . restore ( ) ;
163+ getTempDirStub . restore ( ) ;
164+
165+ const fileContent = await fs . promises . readFile ( changesFilePath , "utf-8" ) ;
166+ const parsedContent = JSON . parse ( fileContent ) as { changes : string [ ] } ;
167+
168+ t . deepEqual (
169+ parsedContent . changes . sort ( ) ,
170+ [ "diff-only.js" , "modified.js" , "reverted.js" ] ,
171+ "Should include OID-changed files, diff-only files, and deduplicate overlapping files" ,
172+ ) ;
173+ } ) ;
174+ } ,
175+ ) ;
176+
177+ test . serial (
178+ "writeOverlayChangesFile works without additional diff files" ,
179+ async ( t ) => {
180+ await withTmpDir ( async ( tmpDir ) => {
181+ const [ dbLocation , sourceRoot , tempDir ] = [ "db" , "src" , "temp" ] . map ( ( d ) =>
182+ path . join ( tmpDir , d ) ,
183+ ) ;
184+ await Promise . all (
185+ [ dbLocation , sourceRoot , tempDir ] . map ( ( d ) =>
186+ fs . promises . mkdir ( d , { recursive : true } ) ,
187+ ) ,
188+ ) ;
189+
190+ const logger = getRunnerLogger ( true ) ;
191+ const config = createTestConfig ( { dbLocation } ) ;
192+
193+ // Mock the getFileOidsUnderPath function to return base OIDs
194+ const baseOids = {
195+ "unchanged.js" : "aaa111" ,
196+ "modified.js" : "bbb222" ,
197+ } ;
198+ const getFileOidsStubForBase = sinon
199+ . stub ( gitUtils , "getFileOidsUnderPath" )
200+ . resolves ( baseOids ) ;
201+
202+ await writeBaseDatabaseOidsFile ( config , sourceRoot ) ;
203+ getFileOidsStubForBase . restore ( ) ;
204+
205+ const currentOids = {
206+ "unchanged.js" : "aaa111" ,
207+ "modified.js" : "ddd444" ,
208+ } ;
209+ const getFileOidsStubForOverlay = sinon
210+ . stub ( gitUtils , "getFileOidsUnderPath" )
211+ . resolves ( currentOids ) ;
212+
213+ const getTempDirStub = sinon
214+ . stub ( actionsUtil , "getTemporaryDirectory" )
215+ . returns ( tempDir ) ;
216+
217+ // No pr-diff-range.json file exists - should work the same as before
218+ const changesFilePath = await writeOverlayChangesFile (
219+ config ,
220+ sourceRoot ,
221+ logger ,
222+ ) ;
223+ getFileOidsStubForOverlay . restore ( ) ;
224+ getTempDirStub . restore ( ) ;
225+
226+ const fileContent = await fs . promises . readFile ( changesFilePath , "utf-8" ) ;
227+ const parsedContent = JSON . parse ( fileContent ) as { changes : string [ ] } ;
228+
229+ t . deepEqual (
230+ parsedContent . changes . sort ( ) ,
231+ [ "modified.js" ] ,
232+ "Should only include OID-changed files when no additional files provided" ,
233+ ) ;
234+ } ) ;
235+ } ,
236+ ) ;
237+
96238interface DownloadOverlayBaseDatabaseTestCase {
97239 overlayDatabaseMode : OverlayDatabaseMode ;
98240 useOverlayDatabaseCaching : boolean ;
0 commit comments