@@ -2,7 +2,12 @@ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
22import * as fs from "fs" ;
33import * as path from "path" ;
44import * as os from "os" ;
5- import { FileWatcher , GitHeadWatcher , FileChange } from "../src/watcher/index.js" ;
5+ import {
6+ FileWatcher ,
7+ GitHeadWatcher ,
8+ FileChange ,
9+ createWatcherWithIndexer ,
10+ } from "../src/watcher/index.js" ;
611import { ParsedCodebaseIndexConfig } from "../src/config/schema.js" ;
712
813const createTestConfig = ( overrides : Partial < ParsedCodebaseIndexConfig > = { } ) : ParsedCodebaseIndexConfig => ( {
@@ -119,6 +124,73 @@ describe("FileWatcher", () => {
119124 expect ( tsChanges . length ) . toBeGreaterThanOrEqual ( 0 ) ;
120125 expect ( mdChanges . length ) . toBe ( 0 ) ;
121126 } ) ;
127+
128+ it ( "should include matching root-level files" , async ( ) => {
129+ const changes : FileChange [ ] = [ ] ;
130+ watcher = new FileWatcher ( tempDir , createTestConfig ( { include : [ "**/*.ts" ] } ) ) ;
131+
132+ watcher . start ( async ( c ) => {
133+ changes . push ( ...c ) ;
134+ } ) ;
135+
136+ await new Promise ( ( r ) => setTimeout ( r , 100 ) ) ;
137+
138+ fs . writeFileSync ( path . join ( tempDir , "root.ts" ) , "export const root = 1;" ) ;
139+
140+ await new Promise ( ( r ) => setTimeout ( r , 1500 ) ) ;
141+
142+ expect ( changes . some ( ( c ) => c . path . endsWith ( "root.ts" ) ) ) . toBe ( true ) ;
143+ } ) ;
144+ } ) ;
145+
146+ describe ( "createWatcherWithIndexer" , ( ) => {
147+ it ( "uses the latest indexer instance for file-triggered reindexing" , async ( ) => {
148+ const staleIndexer = {
149+ index : vi . fn ( ) . mockResolvedValue ( undefined ) ,
150+ } ;
151+ const refreshedIndexer = {
152+ index : vi . fn ( ) . mockResolvedValue ( undefined ) ,
153+ } ;
154+
155+ let currentIndexer = staleIndexer ;
156+ const combinedWatcher = createWatcherWithIndexer (
157+ ( ) => currentIndexer ,
158+ tempDir ,
159+ createTestConfig ( )
160+ ) ;
161+
162+ await new Promise ( ( r ) => setTimeout ( r , 100 ) ) ;
163+ currentIndexer = refreshedIndexer ;
164+
165+ fs . writeFileSync ( path . join ( tempDir , "src" , "reindex-me.ts" ) , "export const value = 1;" ) ;
166+
167+ await new Promise ( ( r ) => setTimeout ( r , 1500 ) ) ;
168+
169+ expect ( refreshedIndexer . index ) . toHaveBeenCalledTimes ( 1 ) ;
170+ expect ( staleIndexer . index ) . not . toHaveBeenCalled ( ) ;
171+
172+ combinedWatcher . stop ( ) ;
173+ } ) ;
174+
175+ it ( "stops the watcher cleanly after start" , ( ) => {
176+ const indexer = {
177+ index : vi . fn ( ) . mockResolvedValue ( undefined ) ,
178+ } ;
179+
180+ const combinedWatcher = createWatcherWithIndexer (
181+ ( ) => indexer ,
182+ tempDir ,
183+ createTestConfig ( )
184+ ) ;
185+
186+ expect ( combinedWatcher . fileWatcher . isRunning ( ) ) . toBe ( true ) ;
187+ expect ( combinedWatcher . gitWatcher ?. isRunning ( ) ?? false ) . toBe ( false ) ;
188+
189+ combinedWatcher . stop ( ) ;
190+
191+ expect ( combinedWatcher . fileWatcher . isRunning ( ) ) . toBe ( false ) ;
192+ expect ( combinedWatcher . gitWatcher ?. isRunning ( ) ?? false ) . toBe ( false ) ;
193+ } ) ;
122194 } ) ;
123195} ) ;
124196
0 commit comments