1- import * as fsSync from "fs" ;
2- import * as fs from "fs/promises" ;
1+ import * as fs from "fs" ;
2+ import * as fsp from "fs/promises" ;
33import ignore from "ignore" ;
4+ import * as path from "path" ;
45import { Filesystem } from "../../src/services/filesystem" ;
56import { Synapse } from "../../src/synapse" ;
67
@@ -19,29 +20,39 @@ jest.mock("ignore");
1920describe ( "Filesystem" , ( ) => {
2021 let filesystem : Filesystem ;
2122 let mockSynapse : jest . Mocked < Synapse > ;
23+ const tempDir = path . join ( process . cwd ( ) , "tmp" , "test" ) ;
2224
2325 beforeEach ( ( ) => {
26+ if ( ! fs . existsSync ( tempDir ) ) {
27+ fs . mkdirSync ( tempDir , { recursive : true } ) ;
28+ }
2429 mockSynapse = jest . mocked ( {
2530 logger : jest . fn ( ) ,
26- workDir : "/test" ,
31+ workDir : tempDir ,
2732 setFilesystem : jest . fn ( ) ,
2833 } as unknown as Synapse ) ;
2934
30- filesystem = new Filesystem ( mockSynapse , "/test" ) ;
35+ filesystem = new Filesystem ( mockSynapse , tempDir ) ;
3136 jest . clearAllMocks ( ) ;
3237 } ) ;
3338
39+ afterAll ( ( ) => {
40+ if ( fs . existsSync ( tempDir ) ) {
41+ fs . rmSync ( tempDir , { recursive : true , force : true } ) ;
42+ }
43+ } ) ;
44+
3445 describe ( "createFile" , ( ) => {
3546 it ( "should successfully create a file" , async ( ) => {
36- const filePath = "/ file.txt";
47+ const filePath = path . join ( tempDir , " file.txt") ;
3748 const content = "test content" ;
3849
3950 // Mock access to indicate file does NOT exist initially
4051 const accessError = new Error ( "ENOENT" ) as NodeJS . ErrnoException ;
4152 accessError . code = "ENOENT" ;
42- ( fs . access as jest . Mock ) . mockRejectedValue ( accessError ) ;
43- ( fs . mkdir as jest . Mock ) . mockResolvedValue ( undefined ) ; // Assuming createFolder is called
44- ( fs . writeFile as jest . Mock ) . mockResolvedValue ( undefined ) ;
53+ ( fsp . access as jest . Mock ) . mockRejectedValue ( accessError ) ;
54+ ( fsp . mkdir as jest . Mock ) . mockResolvedValue ( undefined ) ; // Assuming createFolder is called
55+ ( fsp . writeFile as jest . Mock ) . mockResolvedValue ( undefined ) ;
4556
4657 const result = await filesystem . createFile ( filePath , content ) ;
4758 expect ( result ) . toEqual ( {
@@ -51,30 +62,30 @@ describe("Filesystem", () => {
5162 } ) ;
5263
5364 it ( "should return error if file already exists" , async ( ) => {
54- const filePath = "/ existing.txt";
65+ const filePath = path . join ( tempDir , " existing.txt") ;
5566 const content = "test content" ;
5667
5768 // Mock access to indicate file DOES exist
58- ( fs . access as jest . Mock ) . mockResolvedValue ( undefined ) ;
69+ ( fsp . access as jest . Mock ) . mockResolvedValue ( undefined ) ;
5970
6071 const result = await filesystem . createFile ( filePath , content ) ;
61- expect ( fs . writeFile ) . not . toHaveBeenCalled ( ) ; // Should not attempt to write
72+ expect ( fsp . writeFile ) . not . toHaveBeenCalled ( ) ; // Should not attempt to write
6273 expect ( result ) . toEqual ( {
6374 success : false ,
6475 error : `File already exists at path: ${ filePath } ` ,
6576 } ) ;
6677 } ) ;
6778
6879 it ( "should handle file creation errors during write" , async ( ) => {
69- const filePath = "/test/ error.txt";
80+ const filePath = path . join ( tempDir , " error.txt") ;
7081 const content = "test content" ;
7182
7283 // Mock access to indicate file does NOT exist initially
7384 const accessError = new Error ( "ENOENT" ) as NodeJS . ErrnoException ;
7485 accessError . code = "ENOENT" ;
75- ( fs . access as jest . Mock ) . mockRejectedValue ( accessError ) ;
76- ( fs . mkdir as jest . Mock ) . mockResolvedValue ( undefined ) ; // Mock directory creation
77- ( fs . writeFile as jest . Mock ) . mockRejectedValue (
86+ ( fsp . access as jest . Mock ) . mockRejectedValue ( accessError ) ;
87+ ( fsp . mkdir as jest . Mock ) . mockResolvedValue ( undefined ) ; // Mock directory creation
88+ ( fsp . writeFile as jest . Mock ) . mockRejectedValue (
7889 new Error ( "Failed to write file" ) ,
7990 ) ;
8091
@@ -88,10 +99,10 @@ describe("Filesystem", () => {
8899
89100 describe ( "getFile" , ( ) => {
90101 it ( "should successfully read file content" , async ( ) => {
91- const filePath = "/ file.txt";
102+ const filePath = path . join ( tempDir , " file.txt") ;
92103 const content = "test content" ;
93104
94- ( fs . readFile as jest . Mock ) . mockResolvedValue ( content ) ;
105+ ( fsp . readFile as jest . Mock ) . mockResolvedValue ( content ) ;
95106
96107 const result = await filesystem . getFile ( filePath ) ;
97108 expect ( result ) . toEqual ( {
@@ -101,9 +112,11 @@ describe("Filesystem", () => {
101112 } ) ;
102113
103114 it ( "should handle file reading errors" , async ( ) => {
104- const filePath = "/test/ nonexistent.txt";
115+ const filePath = path . join ( tempDir , " nonexistent.txt") ;
105116
106- ( fs . readFile as jest . Mock ) . mockRejectedValue ( new Error ( "File not found" ) ) ;
117+ ( fsp . readFile as jest . Mock ) . mockRejectedValue (
118+ new Error ( "File not found" ) ,
119+ ) ;
107120
108121 const result = await filesystem . getFile ( filePath ) ;
109122 expect ( result ) . toEqual ( {
@@ -120,11 +133,9 @@ describe("Filesystem", () => {
120133 } ;
121134
122135 // Mock the filesystem functions
123- ( fsSync . watch as jest . Mock ) . mockReturnValue ( mockWatcher ) ;
124- ( fsSync . existsSync as jest . Mock ) . mockReturnValue ( true ) ;
125- ( fsSync . readFileSync as jest . Mock ) . mockReturnValue (
126- "*.env\nnode_modules/" ,
127- ) ;
136+ ( fs . watch as jest . Mock ) . mockReturnValue ( mockWatcher ) ;
137+ ( fs . existsSync as jest . Mock ) . mockReturnValue ( true ) ;
138+ ( fs . readFileSync as jest . Mock ) . mockReturnValue ( "*.env\nnode_modules/" ) ;
128139
129140 // Mock ignore implementation
130141 const mockIgnore = {
@@ -137,18 +148,16 @@ describe("Filesystem", () => {
137148 let watchCallback :
138149 | ( ( eventType : string , filename : string ) => void )
139150 | null = null ;
140- ( fsSync . watch as jest . Mock ) . mockImplementation (
141- ( path , options , callback ) => {
142- watchCallback = callback ;
143- return mockWatcher ;
144- } ,
145- ) ;
151+ ( fs . watch as jest . Mock ) . mockImplementation ( ( path , options , callback ) => {
152+ watchCallback = callback ;
153+ return mockWatcher ;
154+ } ) ;
146155
147156 // Mock fs.lstat and fs.readFile for the file change event
148- ( fs . lstat as jest . Mock ) . mockResolvedValue ( {
157+ ( fsp . lstat as unknown as jest . Mock ) . mockResolvedValue ( {
149158 isFile : jest . fn ( ) . mockReturnValue ( true ) ,
150159 } ) ;
151- ( fs . readFile as jest . Mock ) . mockResolvedValue ( "file content" ) ;
160+ ( fsp . readFile as unknown as jest . Mock ) . mockResolvedValue ( "file content" ) ;
152161
153162 // Set up the callback spy
154163 const onChangeMock = jest . fn ( ) ;
@@ -157,8 +166,8 @@ describe("Filesystem", () => {
157166 filesystem . watchWorkDir ( onChangeMock ) ;
158167
159168 // Verify watch was called with correct path
160- expect ( fsSync . watch ) . toHaveBeenCalledWith (
161- mockSynapse . workDir ,
169+ expect ( fs . watch ) . toHaveBeenCalledWith (
170+ tempDir ,
162171 { recursive : true } ,
163172 expect . any ( Function ) ,
164173 ) ;
@@ -196,12 +205,12 @@ describe("Filesystem", () => {
196205
197206 describe ( "appendFile" , ( ) => {
198207 it ( "should append content to a file" , async ( ) => {
199- const filePath = "/ file.txt";
208+ const filePath = path . join ( tempDir , " file.txt") ;
200209 const content = "appended content" ;
201- ( fs . appendFile as jest . Mock ) . mockResolvedValue ( undefined ) ;
210+ ( fsp . appendFile as unknown as jest . Mock ) . mockResolvedValue ( undefined ) ;
202211
203212 const result = await filesystem . appendFile ( filePath , content ) ;
204- expect ( fs . appendFile ) . toHaveBeenCalledWith (
213+ expect ( fsp . appendFile ) . toHaveBeenCalledWith (
205214 expect . stringContaining ( filePath ) ,
206215 content ,
207216 ) ;
0 commit comments