@@ -4,13 +4,18 @@ import * as os from "os";
44import * as path from "path" ;
55import { clearTodosForTempDir , getTodosForTempDir , setTodosForTempDir } from "./todo" ;
66import type { TodoItem } from "@/types/tools" ;
7+ import type { Runtime } from "@/runtime/Runtime" ;
8+ import { createRuntime } from "@/runtime/runtimeFactory" ;
79
810describe ( "Todo Storage" , ( ) => {
911 let runtimeTempDir : string ;
12+ let runtime : Runtime ;
1013
1114 beforeEach ( async ( ) => {
1215 // Create a temporary directory for each test
1316 runtimeTempDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , "todo-test-" ) ) ;
17+ // Create a local runtime for testing
18+ runtime = createRuntime ( { type : "local" , srcBaseDir : "/tmp" } ) ;
1419 } ) ;
1520
1621 afterEach ( async ( ) => {
@@ -35,9 +40,9 @@ describe("Todo Storage", () => {
3540 } ,
3641 ] ;
3742
38- await setTodosForTempDir ( runtimeTempDir , todos ) ;
43+ await setTodosForTempDir ( runtime , runtimeTempDir , todos ) ;
3944
40- const storedTodos = await getTodosForTempDir ( runtimeTempDir ) ;
45+ const storedTodos = await getTodosForTempDir ( runtime , runtimeTempDir ) ;
4146 expect ( storedTodos ) . toEqual ( todos ) ;
4247 } ) ;
4348
@@ -54,7 +59,7 @@ describe("Todo Storage", () => {
5459 } ,
5560 ] ;
5661
57- await setTodosForTempDir ( runtimeTempDir , initialTodos ) ;
62+ await setTodosForTempDir ( runtime , runtimeTempDir , initialTodos ) ;
5863
5964 // Replace with updated list
6065 const updatedTodos : TodoItem [ ] = [
@@ -72,26 +77,26 @@ describe("Todo Storage", () => {
7277 } ,
7378 ] ;
7479
75- await setTodosForTempDir ( runtimeTempDir , updatedTodos ) ;
80+ await setTodosForTempDir ( runtime , runtimeTempDir , updatedTodos ) ;
7681
7782 // Verify list was replaced, not merged
78- const storedTodos = await getTodosForTempDir ( runtimeTempDir ) ;
83+ const storedTodos = await getTodosForTempDir ( runtime , runtimeTempDir ) ;
7984 expect ( storedTodos ) . toEqual ( updatedTodos ) ;
8085 } ) ;
8186
8287 it ( "should handle empty todo list" , async ( ) => {
8388 // Create initial list
84- await setTodosForTempDir ( runtimeTempDir , [
89+ await setTodosForTempDir ( runtime , runtimeTempDir , [
8590 {
8691 content : "Task 1" ,
8792 status : "pending" ,
8893 } ,
8994 ] ) ;
9095
9196 // Clear list
92- await setTodosForTempDir ( runtimeTempDir , [ ] ) ;
97+ await setTodosForTempDir ( runtime , runtimeTempDir , [ ] ) ;
9398
94- const storedTodos = await getTodosForTempDir ( runtimeTempDir ) ;
99+ const storedTodos = await getTodosForTempDir ( runtime , runtimeTempDir ) ;
95100 expect ( storedTodos ) . toEqual ( [ ] ) ;
96101 } ) ;
97102
@@ -108,10 +113,10 @@ describe("Todo Storage", () => {
108113 { content : "Task 8" , status : "pending" } ,
109114 ] ;
110115
111- await expect ( setTodosForTempDir ( runtimeTempDir , tooManyTodos ) ) . rejects . toThrow (
116+ await expect ( setTodosForTempDir ( runtime , runtimeTempDir , tooManyTodos ) ) . rejects . toThrow (
112117 / T o o m a n y T O D O s \( 8 \/ 7 \) / i
113118 ) ;
114- await expect ( setTodosForTempDir ( runtimeTempDir , tooManyTodos ) ) . rejects . toThrow (
119+ await expect ( setTodosForTempDir ( runtime , runtimeTempDir , tooManyTodos ) ) . rejects . toThrow (
115120 / K e e p h i g h p r e c i s i o n a t t h e c e n t e r / i
116121 ) ;
117122 } ) ;
@@ -127,8 +132,8 @@ describe("Todo Storage", () => {
127132 { content : "Future work (5 items)" , status : "pending" } ,
128133 ] ;
129134
130- await setTodosForTempDir ( runtimeTempDir , maxTodos ) ;
131- expect ( await getTodosForTempDir ( runtimeTempDir ) ) . toEqual ( maxTodos ) ;
135+ await setTodosForTempDir ( runtime , runtimeTempDir , maxTodos ) ;
136+ expect ( await getTodosForTempDir ( runtime , runtimeTempDir ) ) . toEqual ( maxTodos ) ;
132137 } ) ;
133138
134139 it ( "should reject multiple in_progress tasks" , async ( ) => {
@@ -139,7 +144,7 @@ describe("Todo Storage", () => {
139144 } ,
140145 ] ;
141146
142- await setTodosForTempDir ( runtimeTempDir , validTodos ) ;
147+ await setTodosForTempDir ( runtime , runtimeTempDir , validTodos ) ;
143148
144149 const invalidTodos : TodoItem [ ] = [
145150 {
@@ -152,12 +157,12 @@ describe("Todo Storage", () => {
152157 } ,
153158 ] ;
154159
155- await expect ( setTodosForTempDir ( runtimeTempDir , invalidTodos ) ) . rejects . toThrow (
160+ await expect ( setTodosForTempDir ( runtime , runtimeTempDir , invalidTodos ) ) . rejects . toThrow (
156161 / o n l y o n e t a s k c a n b e m a r k e d a s i n _ p r o g r e s s / i
157162 ) ;
158163
159164 // Original todos should remain unchanged on failure
160- expect ( await getTodosForTempDir ( runtimeTempDir ) ) . toEqual ( validTodos ) ;
165+ expect ( await getTodosForTempDir ( runtime , runtimeTempDir ) ) . toEqual ( validTodos ) ;
161166 } ) ;
162167
163168 it ( "should reject when in_progress tasks appear after pending" , async ( ) => {
@@ -172,7 +177,7 @@ describe("Todo Storage", () => {
172177 } ,
173178 ] ;
174179
175- await expect ( setTodosForTempDir ( runtimeTempDir , invalidTodos ) ) . rejects . toThrow (
180+ await expect ( setTodosForTempDir ( runtime , runtimeTempDir , invalidTodos ) ) . rejects . toThrow (
176181 / i n - p r o g r e s s t a s k s m u s t a p p e a r b e f o r e p e n d i n g t a s k s / i
177182 ) ;
178183 } ) ;
@@ -189,7 +194,7 @@ describe("Todo Storage", () => {
189194 } ,
190195 ] ;
191196
192- await expect ( setTodosForTempDir ( runtimeTempDir , invalidTodos ) ) . rejects . toThrow (
197+ await expect ( setTodosForTempDir ( runtime , runtimeTempDir , invalidTodos ) ) . rejects . toThrow (
193198 / c o m p l e t e d t a s k s m u s t a p p e a r b e f o r e i n - p r o g r e s s o r p e n d i n g t a s k s / i
194199 ) ;
195200 } ) ;
@@ -206,14 +211,45 @@ describe("Todo Storage", () => {
206211 } ,
207212 ] ;
208213
209- await setTodosForTempDir ( runtimeTempDir , todos ) ;
210- expect ( await getTodosForTempDir ( runtimeTempDir ) ) . toEqual ( todos ) ;
214+ await setTodosForTempDir ( runtime , runtimeTempDir , todos ) ;
215+ expect ( await getTodosForTempDir ( runtime , runtimeTempDir ) ) . toEqual ( todos ) ;
216+ } ) ;
217+
218+ it ( "should create directory if it doesn't exist" , async ( ) => {
219+ // Use a non-existent nested directory path
220+ const nonExistentDir = path . join ( os . tmpdir ( ) , "todo-nonexistent-test" , "nested" , "path" ) ;
221+
222+ try {
223+ const todos : TodoItem [ ] = [
224+ {
225+ content : "Test task" ,
226+ status : "pending" ,
227+ } ,
228+ ] ;
229+
230+ // Should not throw even though directory doesn't exist
231+ await setTodosForTempDir ( runtime , nonExistentDir , todos ) ;
232+
233+ // Verify the file was created and is readable
234+ const retrievedTodos = await getTodosForTempDir ( runtime , nonExistentDir ) ;
235+ expect ( retrievedTodos ) . toEqual ( todos ) ;
236+
237+ // Verify the directory was actually created
238+ const dirStats = await fs . stat ( nonExistentDir ) ;
239+ expect ( dirStats . isDirectory ( ) ) . toBe ( true ) ;
240+ } finally {
241+ // Clean up the created directory
242+ await fs . rm ( path . join ( os . tmpdir ( ) , "todo-nonexistent-test" ) , {
243+ recursive : true ,
244+ force : true ,
245+ } ) ;
246+ }
211247 } ) ;
212248 } ) ;
213249
214250 describe ( "getTodosForTempDir" , ( ) => {
215251 it ( "should return empty array when no todos exist" , async ( ) => {
216- const todos = await getTodosForTempDir ( runtimeTempDir ) ;
252+ const todos = await getTodosForTempDir ( runtime , runtimeTempDir ) ;
217253 expect ( todos ) . toEqual ( [ ] ) ;
218254 } ) ;
219255
@@ -229,9 +265,9 @@ describe("Todo Storage", () => {
229265 } ,
230266 ] ;
231267
232- await setTodosForTempDir ( runtimeTempDir , todos ) ;
268+ await setTodosForTempDir ( runtime , runtimeTempDir , todos ) ;
233269
234- const retrievedTodos = await getTodosForTempDir ( runtimeTempDir ) ;
270+ const retrievedTodos = await getTodosForTempDir ( runtime , runtimeTempDir ) ;
235271 expect ( retrievedTodos ) . toEqual ( todos ) ;
236272 } ) ;
237273 } ) ;
@@ -257,12 +293,12 @@ describe("Todo Storage", () => {
257293 } ,
258294 ] ;
259295
260- await setTodosForTempDir ( tempDir1 , todos1 ) ;
261- await setTodosForTempDir ( tempDir2 , todos2 ) ;
296+ await setTodosForTempDir ( runtime , tempDir1 , todos1 ) ;
297+ await setTodosForTempDir ( runtime , tempDir2 , todos2 ) ;
262298
263299 // Verify each temp directory has its own todos
264- const retrievedTodos1 = await getTodosForTempDir ( tempDir1 ) ;
265- const retrievedTodos2 = await getTodosForTempDir ( tempDir2 ) ;
300+ const retrievedTodos1 = await getTodosForTempDir ( runtime , tempDir1 ) ;
301+ const retrievedTodos2 = await getTodosForTempDir ( runtime , tempDir2 ) ;
266302
267303 expect ( retrievedTodos1 ) . toEqual ( todos1 ) ;
268304 expect ( retrievedTodos2 ) . toEqual ( todos2 ) ;
@@ -283,11 +319,11 @@ describe("Todo Storage", () => {
283319 } ,
284320 ] ;
285321
286- await setTodosForTempDir ( runtimeTempDir , todos ) ;
287- expect ( await getTodosForTempDir ( runtimeTempDir ) ) . toEqual ( todos ) ;
322+ await setTodosForTempDir ( runtime , runtimeTempDir , todos ) ;
323+ expect ( await getTodosForTempDir ( runtime , runtimeTempDir ) ) . toEqual ( todos ) ;
288324
289- await clearTodosForTempDir ( runtimeTempDir ) ;
290- expect ( await getTodosForTempDir ( runtimeTempDir ) ) . toEqual ( [ ] ) ;
325+ await clearTodosForTempDir ( runtime , runtimeTempDir ) ;
326+ expect ( await getTodosForTempDir ( runtime , runtimeTempDir ) ) . toEqual ( [ ] ) ;
291327 } ) ;
292328 } ) ;
293329} ) ;
0 commit comments