@@ -175,3 +175,73 @@ test("parses unicode filenames and .kts frames", () => {
175175 assert . equal ( reports [ 1 ] . culprit ?. file , "構建.kts" ) ;
176176 assert . equal ( reports [ 1 ] . culprit ?. line , 9 ) ;
177177} ) ;
178+
179+ test ( "deduplicates the culprit location in text and st-json/1 reports" , ( ) => {
180+ const textContent = [
181+ "━━━ ERROR #dedupe-text ━━━ 2026-07-10 20:24:00.000 thread=main ━━━" ,
182+ "IllegalStateException: payment gateway refused" ,
183+ "at PaymentService.charge(PaymentService.java:118) ← YOUR CODE" ,
184+ "stack (distilled, 1 of 1 frames):" ,
185+ " PaymentService.charge(PaymentService.java:118) ← culprit" ,
186+ "━━━ END #dedupe-text ━━━" ,
187+ ] . join ( "\n" ) ;
188+
189+ const jsonContent = JSON . stringify ( {
190+ type : "report" ,
191+ id : "dedupe-json" ,
192+ ts : "2026-07-10T20:24:00.000Z" ,
193+ error : {
194+ type : "IllegalStateException" ,
195+ message : "payment gateway refused" ,
196+ culprit : {
197+ frame : "PaymentService.charge(PaymentService.java:118)" ,
198+ appCode : true ,
199+ } ,
200+ } ,
201+ stack : {
202+ shown : 1 ,
203+ total : 1 ,
204+ frames : [ "PaymentService.charge(PaymentService.java:118)" ] ,
205+ } ,
206+ } ) ;
207+
208+ const textReport = parseReports ( textContent ) [ 0 ] ;
209+ const jsonReport = parseReports ( jsonContent ) [ 0 ] ;
210+
211+ const textLocations = textReport . frames . map (
212+ ( frame ) => `${ frame . file } :${ frame . line } ` ,
213+ ) ;
214+ const jsonLocations = jsonReport . frames . map (
215+ ( frame ) => `${ frame . file } :${ frame . line } ` ,
216+ ) ;
217+
218+ assert . deepEqual ( textLocations , [ "PaymentService.java:118" ] ) ;
219+ assert . deepEqual ( jsonLocations , textLocations ) ;
220+ assert . match ( textReport . frames [ 0 ] . text , / ← Y O U R C O D E / ) ;
221+ assert . match ( jsonReport . frames [ 0 ] . text , / ← Y O U R C O D E / ) ;
222+ } ) ;
223+
224+ test ( "keeps distinct frames when the culprit is not the top stack frame" , ( ) => {
225+ const content = [
226+ "━━━ ERROR #non-top ━━━ 2026-07-10 20:25:00.000 thread=main ━━━" ,
227+ "IllegalStateException: payment gateway refused" ,
228+ "at PaymentService.charge(PaymentService.java:118) ← YOUR CODE" ,
229+ "stack (distilled, 3 of 3 frames):" ,
230+ " CheckoutController.submit(CheckoutController.java:31)" ,
231+ " PaymentService.charge(PaymentService.java:118) ← culprit" ,
232+ " Worker.run(Worker.java:9)" ,
233+ "━━━ END #non-top ━━━" ,
234+ ] . join ( "\n" ) ;
235+
236+ const report = parseReports ( content ) [ 0 ] ;
237+
238+ assert . deepEqual (
239+ report . frames . map ( ( frame ) => `${ frame . file } :${ frame . line } ` ) ,
240+ [
241+ "PaymentService.java:118" ,
242+ "CheckoutController.java:31" ,
243+ "Worker.java:9" ,
244+ ] ,
245+ ) ;
246+ assert . match ( report . frames [ 0 ] . text , / ← Y O U R C O D E / ) ;
247+ } ) ;
0 commit comments