11import { EventEmitter } from 'events'
22
3+ import {
4+ clearMockedModules ,
5+ mockModule ,
6+ } from '@codebuff/common/testing/mock-modules'
37import { describe , expect , it , mock , beforeEach , afterEach } from 'bun:test'
48
59import { codeSearch } from '../tools/code-search'
610
711import type { ChildProcess } from 'child_process'
8- import type { CodeSearchDeps } from '../tools/code-search'
912
1013// Helper to create a mock child process
1114function createMockChildProcess ( ) {
@@ -53,24 +56,25 @@ function createRgJsonContext(
5356describe ( 'codeSearch' , ( ) => {
5457 let mockSpawn : ReturnType < typeof mock >
5558 let mockProcess : ReturnType < typeof createMockChildProcess >
56- let deps : CodeSearchDeps
5759
58- beforeEach ( ( ) => {
60+ beforeEach ( async ( ) => {
5961 mockProcess = createMockChildProcess ( )
6062 mockSpawn = mock ( ( ) => mockProcess )
61- deps = { spawn : mockSpawn as CodeSearchDeps [ 'spawn' ] }
63+ await mockModule ( 'child_process' , ( ) => ( {
64+ spawn : mockSpawn ,
65+ } ) )
6266 } )
6367
6468 afterEach ( ( ) => {
6569 mock . restore ( )
70+ clearMockedModules ( )
6671 } )
6772
6873 describe ( 'basic search' , ( ) => {
6974 it ( 'should parse standard ripgrep output without context flags' , async ( ) => {
7075 const searchPromise = codeSearch ( {
7176 projectPath : '/test/project' ,
7277 pattern : 'import' ,
73- deps,
7478 } )
7579
7680 // Simulate ripgrep JSON output
@@ -97,7 +101,6 @@ describe('codeSearch', () => {
97101 projectPath : '/test/project' ,
98102 pattern : 'import.*env' ,
99103 flags : '-A 2' ,
100- deps,
101104 } )
102105
103106 // Ripgrep JSON output with -A 2 includes match + 2 context lines after
@@ -133,7 +136,6 @@ describe('codeSearch', () => {
133136 projectPath : '/test/project' ,
134137 pattern : 'export' ,
135138 flags : '-B 2' ,
136- deps,
137139 } )
138140
139141 // Ripgrep JSON output with -B 2 includes 2 context lines before + match
@@ -167,7 +169,6 @@ describe('codeSearch', () => {
167169 projectPath : '/test/project' ,
168170 pattern : 'TODO' ,
169171 flags : '-C 1' ,
170- deps,
171172 } )
172173
173174 // Ripgrep JSON output with -C 1 includes 1 line before + match + 1 line after
@@ -196,7 +197,6 @@ describe('codeSearch', () => {
196197 projectPath : '/test/project' ,
197198 pattern : 'import' ,
198199 flags : '-A 1' ,
199- deps,
200200 } )
201201
202202 const output = [
@@ -225,7 +225,6 @@ describe('codeSearch', () => {
225225 projectPath : '/test/project' ,
226226 pattern : 'import' ,
227227 flags : '-B 2' ,
228- deps,
229228 } )
230229
231230 // First line match has no before context
@@ -246,7 +245,6 @@ describe('codeSearch', () => {
246245 projectPath : '/test/project' ,
247246 pattern : 'test' ,
248247 flags : '-A 1' ,
249- deps,
250248 } )
251249
252250 const output = [
@@ -271,7 +269,6 @@ describe('codeSearch', () => {
271269 projectPath : '/test/project' ,
272270 pattern : 'import' ,
273271 flags : '-A 1' ,
274- deps,
275272 } )
276273
277274 const output = [
@@ -297,7 +294,6 @@ describe('codeSearch', () => {
297294 projectPath : '/test/project' ,
298295 pattern : 'test' ,
299296 flags : '-A 1' ,
300- deps,
301297 } )
302298
303299 const output = createRgJsonMatch (
@@ -323,7 +319,6 @@ describe('codeSearch', () => {
323319 pattern : 'import.*env' ,
324320 flags : '-A 2' ,
325321 maxOutputStringLength : 20000 ,
326- deps,
327322 } )
328323
329324 const output = [
@@ -353,7 +348,6 @@ describe('codeSearch', () => {
353348 pattern : 'test' ,
354349 flags : '-A 1' ,
355350 maxResults : 2 ,
356- deps,
357351 } )
358352
359353 const output = [
@@ -394,7 +388,6 @@ describe('codeSearch', () => {
394388 pattern : 'test' ,
395389 flags : '-A 1' ,
396390 globalMaxResults : 3 ,
397- deps,
398391 } )
399392
400393 const output = [
@@ -430,7 +423,6 @@ describe('codeSearch', () => {
430423 pattern : 'match' ,
431424 flags : '-A 2 -B 2' ,
432425 maxResults : 1 ,
433- deps,
434426 } )
435427
436428 const output = [
@@ -463,7 +455,6 @@ describe('codeSearch', () => {
463455 const searchPromise = codeSearch ( {
464456 projectPath : '/test/project' ,
465457 pattern : 'test' ,
466- deps,
467458 } )
468459
469460 const output = [
@@ -487,7 +478,6 @@ describe('codeSearch', () => {
487478 const searchPromise = codeSearch ( {
488479 projectPath : '/test/project' ,
489480 pattern : 'nonexistent' ,
490- deps,
491481 } )
492482
493483 mockProcess . stdout . emit ( 'data' , Buffer . from ( '' ) )
@@ -508,7 +498,6 @@ describe('codeSearch', () => {
508498 const searchPromise = codeSearch ( {
509499 projectPath : '/test/project' ,
510500 pattern : '-foo' ,
511- deps,
512501 } )
513502
514503 const output = createRgJsonMatch ( 'file.ts' , 1 , 'const x = -foo' )
@@ -529,7 +518,6 @@ describe('codeSearch', () => {
529518 const searchPromise = codeSearch ( {
530519 projectPath : '/test/project' ,
531520 pattern : 'import' ,
532- deps,
533521 } )
534522
535523 // Simulate ripgrep JSON with trailing newlines in lineText
@@ -559,7 +547,6 @@ describe('codeSearch', () => {
559547 const searchPromise = codeSearch ( {
560548 projectPath : '/test/project' ,
561549 pattern : 'test' ,
562- deps,
563550 } )
564551
565552 // Send partial JSON chunks that will be completed in remainder
@@ -589,7 +576,6 @@ describe('codeSearch', () => {
589576 projectPath : '/test/project' ,
590577 pattern : 'test' ,
591578 maxOutputStringLength : 500 , // Small limit
592- deps,
593579 } )
594580
595581 // Generate many matches that would exceed the limit
@@ -617,7 +603,6 @@ describe('codeSearch', () => {
617603 const searchPromise = codeSearch ( {
618604 projectPath : '/test/project' ,
619605 pattern : 'test' ,
620- deps,
621606 } )
622607
623608 // Simulate ripgrep JSON with path.bytes instead of path.text
@@ -648,7 +633,6 @@ describe('codeSearch', () => {
648633 projectPath : '/test/project' ,
649634 pattern : 'import' ,
650635 flags : '-g *.ts' ,
651- deps,
652636 } )
653637
654638 const output = [
@@ -676,7 +660,6 @@ describe('codeSearch', () => {
676660 projectPath : '/test/project' ,
677661 pattern : 'import' ,
678662 flags : '-g *.ts -g *.tsx' ,
679- deps,
680663 } )
681664
682665 const output = createRgJsonMatch ( 'file.tsx' , 1 , 'import React from "react"' )
@@ -703,7 +686,6 @@ describe('codeSearch', () => {
703686 projectPath : '/test/project' ,
704687 pattern : 'import' ,
705688 flags : '-g *.ts -i -g *.tsx' ,
706- deps,
707689 } )
708690
709691 const output = createRgJsonMatch ( 'file.tsx' , 1 , 'import React from "react"' )
@@ -733,7 +715,6 @@ describe('codeSearch', () => {
733715 projectPath : '/test/project' ,
734716 pattern : 'test' ,
735717 timeoutSeconds : 1 ,
736- deps,
737718 } )
738719
739720 // Don't emit any data or close event to simulate hanging
@@ -756,7 +737,6 @@ describe('codeSearch', () => {
756737 projectPath : '/test/project' ,
757738 pattern : 'test' ,
758739 cwd : '.' ,
759- deps,
760740 } )
761741
762742 const output = createRgJsonMatch ( 'file.ts' , 1 , 'test content' )
@@ -784,7 +764,6 @@ describe('codeSearch', () => {
784764 projectPath : '/test/project' ,
785765 pattern : 'test' ,
786766 cwd : 'subdir' ,
787- deps,
788767 } )
789768
790769 const output = createRgJsonMatch ( 'file.ts' , 1 , 'test content' )
@@ -809,7 +788,6 @@ describe('codeSearch', () => {
809788 projectPath : '/test/project' ,
810789 pattern : 'test' ,
811790 cwd : '../outside' ,
812- deps,
813791 } )
814792
815793 const result = await searchPromise
0 commit comments