44 subtractRange ,
55 subtractRanges ,
66 ConversationMessage ,
7+ mtimeCache ,
78} from "../fileReadCacheService"
89import { stat } from "fs/promises"
910import { lruCache } from "../../utils/lruCache"
@@ -60,25 +61,41 @@ describe("fileReadCacheService", () => {
6061 } )
6162 describe ( "processAndFilterReadRequest" , ( ) => {
6263 const MOCK_FILE_PATH = "/test/file.txt"
63- const CURRENT_MTIME = new Date ( ) . toISOString ( )
64+ const CURRENT_MTIME = new Date ( "2025-01-01T12:00:00.000Z" )
65+
6466 beforeEach ( ( ) => {
6567 vi . clearAllMocks ( )
66- mockedStat . mockResolvedValue ( { mtime : { toISOString : ( ) => CURRENT_MTIME } } as any )
68+ mtimeCache . clear ( )
69+ vi . useFakeTimers ( ) . setSystemTime ( CURRENT_MTIME )
70+ mockedStat . mockResolvedValue ( {
71+ mtime : CURRENT_MTIME ,
72+ size : 1024 , // Add size for the new cache implementation
73+ } as any )
6774 } )
75+
76+ afterEach ( ( ) => {
77+ vi . useRealTimers ( )
78+ } )
79+
80+ afterAll ( ( ) => {
81+ vi . clearAllMocks ( )
82+ } )
83+
6884 it ( "should allow all when history is empty" , async ( ) => {
6985 const requestedRanges = [ { start : 1 , end : 10 } ]
7086 const result = await processAndFilterReadRequest ( MOCK_FILE_PATH , requestedRanges , [ ] )
7187 expect ( result . status ) . toBe ( "ALLOW_ALL" )
7288 expect ( result . rangesToRead ) . toEqual ( requestedRanges )
7389 } )
90+
7491 it ( "should reject all when a full cache hit occurs" , async ( ) => {
7592 const requestedRanges = [ { start : 1 , end : 10 } ]
7693 const conversationHistory : ConversationMessage [ ] = [
7794 {
7895 files : [
7996 {
8097 fileName : MOCK_FILE_PATH ,
81- mtime : new Date ( CURRENT_MTIME ) . getTime ( ) ,
98+ mtime : CURRENT_MTIME . getTime ( ) ,
8299 lineRanges : [ { start : 1 , end : 10 } ] ,
83100 } ,
84101 ] ,
@@ -88,14 +105,15 @@ describe("fileReadCacheService", () => {
88105 expect ( result . status ) . toBe ( "REJECT_ALL" )
89106 expect ( result . rangesToRead ) . toEqual ( [ ] )
90107 } )
108+
91109 it ( "should allow partial when a partial cache hit occurs" , async ( ) => {
92110 const requestedRanges = [ { start : 1 , end : 20 } ]
93111 const conversationHistory : ConversationMessage [ ] = [
94112 {
95113 files : [
96114 {
97115 fileName : MOCK_FILE_PATH ,
98- mtime : new Date ( CURRENT_MTIME ) . getTime ( ) ,
116+ mtime : CURRENT_MTIME . getTime ( ) ,
99117 lineRanges : [ { start : 1 , end : 10 } ] ,
100118 } ,
101119 ] ,
@@ -105,14 +123,15 @@ describe("fileReadCacheService", () => {
105123 expect ( result . status ) . toBe ( "ALLOW_PARTIAL" )
106124 expect ( result . rangesToRead ) . toEqual ( [ { start : 11 , end : 20 } ] )
107125 } )
126+
108127 it ( "should allow all when mtime is older in history" , async ( ) => {
109128 const requestedRanges = [ { start : 1 , end : 10 } ]
110129 const conversationHistory : ConversationMessage [ ] = [
111130 {
112131 files : [
113132 {
114133 fileName : MOCK_FILE_PATH ,
115- mtime : new Date ( CURRENT_MTIME ) . getTime ( ) - 100 , // Older mtime
134+ mtime : CURRENT_MTIME . getTime ( ) - 100 , // Older mtime
116135 lineRanges : [ { start : 1 , end : 10 } ] ,
117136 } ,
118137 ] ,
@@ -122,13 +141,15 @@ describe("fileReadCacheService", () => {
122141 expect ( result . status ) . toBe ( "ALLOW_ALL" )
123142 expect ( result . rangesToRead ) . toEqual ( requestedRanges )
124143 } )
144+
125145 it ( "should allow all when file does not exist" , async ( ) => {
126146 mockedStat . mockRejectedValue ( { code : "ENOENT" } )
127147 const requestedRanges = [ { start : 1 , end : 10 } ]
128148 const result = await processAndFilterReadRequest ( MOCK_FILE_PATH , requestedRanges , [ ] )
129149 expect ( result . status ) . toBe ( "ALLOW_ALL" )
130150 expect ( result . rangesToRead ) . toEqual ( requestedRanges )
131151 } )
152+
132153 it ( "should throw an error for non-ENOENT stat errors" , async ( ) => {
133154 const error = new Error ( "EPERM" )
134155 mockedStat . mockRejectedValue ( error )
0 commit comments