1111 * Converted to pure dependency injection without vitest mocking.
1212 */
1313
14- import { describe , it , expect , beforeEach } from 'vitest' ;
14+ import { describe , it , expect } from 'vitest' ;
1515import * as z from 'zod' ;
1616import stopSimLogCap , { stop_sim_log_capLogic } from '../stop_sim_log_cap.ts' ;
17- import { activeLogSessions } from '../../../../utils/log_capture.ts' ;
18- import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.ts' ;
17+ import {
18+ createMockExecutor ,
19+ createMockFileSystemExecutor ,
20+ } from '../../../../test-utils/mock-executors.ts' ;
1921
2022describe ( 'stop_sim_log_cap plugin' , ( ) => {
21- beforeEach ( ( ) => {
22- // Clear any active sessions before each test
23- activeLogSessions . clear ( ) ;
24- } ) ;
25-
26- // Helper function to create a test log session
27- async function createTestLogSession ( sessionId : string , logContent : string = '' ) {
28- const mockProcess = {
29- pid : 12345 ,
30- killed : false ,
31- exitCode : null ,
32- kill : ( ) => { } ,
33- } ;
34-
35- const logFilePath = `/tmp/xcodemcp_sim_log_test_${ sessionId } .log` ;
36- const fileSystem = createMockFileSystemExecutor ( {
37- existsSync : ( path ) => path === logFilePath ,
38- readFile : async ( path , _encoding ) => {
39- if ( path !== logFilePath ) {
40- throw new Error ( `ENOENT: no such file or directory, open '${ path } '` ) ;
41- }
42- return logContent ;
43- } ,
44- } ) ;
45-
46- activeLogSessions . set ( sessionId , {
47- processes : [ mockProcess as any ] ,
48- logFilePath : logFilePath ,
49- simulatorUuid : 'test-simulator-uuid' ,
50- bundleId : 'com.example.TestApp' ,
51- } ) ;
52-
53- return { fileSystem, logFilePath } ;
54- }
23+ const mockExecutor = createMockExecutor ( { success : true , output : '' } ) ;
24+ const mockFileSystem = createMockFileSystemExecutor ( ) ;
5525
5626 describe ( 'Export Field Validation (Literal)' , ( ) => {
5727 it ( 'should have correct plugin structure' , ( ) => {
@@ -95,13 +65,18 @@ describe('stop_sim_log_cap plugin', () => {
9565 it ( 'should handle null logSessionId (validation handled by framework)' , async ( ) => {
9666 // With typed tool factory, invalid params won't reach the logic function
9767 // This test now validates that the logic function works with valid empty strings
98- const { fileSystem } = await createTestLogSession ( '' , 'Log content for empty session' ) ;
68+ const stopLogCaptureStub = async ( ) => ( {
69+ logContent : 'Log content for empty session' ,
70+ error : undefined ,
71+ } ) ;
9972
10073 const result = await stop_sim_log_capLogic (
10174 {
10275 logSessionId : '' ,
10376 } ,
104- fileSystem ,
77+ mockExecutor ,
78+ stopLogCaptureStub ,
79+ mockFileSystem ,
10580 ) ;
10681
10782 expect ( result . isError ) . toBeUndefined ( ) ;
@@ -113,13 +88,18 @@ describe('stop_sim_log_cap plugin', () => {
11388 it ( 'should handle undefined logSessionId (validation handled by framework)' , async ( ) => {
11489 // With typed tool factory, invalid params won't reach the logic function
11590 // This test now validates that the logic function works with valid empty strings
116- const { fileSystem } = await createTestLogSession ( '' , 'Log content for empty session' ) ;
91+ const stopLogCaptureStub = async ( ) => ( {
92+ logContent : 'Log content for empty session' ,
93+ error : undefined ,
94+ } ) ;
11795
11896 const result = await stop_sim_log_capLogic (
11997 {
12098 logSessionId : '' ,
12199 } ,
122- fileSystem ,
100+ mockExecutor ,
101+ stopLogCaptureStub ,
102+ mockFileSystem ,
123103 ) ;
124104
125105 expect ( result . isError ) . toBeUndefined ( ) ;
@@ -129,13 +109,18 @@ describe('stop_sim_log_cap plugin', () => {
129109 } ) ;
130110
131111 it ( 'should handle empty string logSessionId' , async ( ) => {
132- const { fileSystem } = await createTestLogSession ( '' , 'Log content for empty session' ) ;
112+ const stopLogCaptureStub = async ( ) => ( {
113+ logContent : 'Log content for empty session' ,
114+ error : undefined ,
115+ } ) ;
133116
134117 const result = await stop_sim_log_capLogic (
135118 {
136119 logSessionId : '' ,
137120 } ,
138- fileSystem ,
121+ mockExecutor ,
122+ stopLogCaptureStub ,
123+ mockFileSystem ,
139124 ) ;
140125
141126 expect ( result . isError ) . toBeUndefined ( ) ;
@@ -147,37 +132,45 @@ describe('stop_sim_log_cap plugin', () => {
147132
148133 describe ( 'Function Call Generation' , ( ) => {
149134 it ( 'should call stopLogCapture with correct parameters' , async ( ) => {
150- const { fileSystem } = await createTestLogSession (
151- 'test-session-id' ,
152- 'Mock log content from file' ,
153- ) ;
135+ let capturedSessionId = '' ;
136+ const stopLogCaptureStub = async ( logSessionId : string ) => {
137+ capturedSessionId = logSessionId ;
138+ return { logContent : 'Mock log content from file' , error : undefined } ;
139+ } ;
154140
155141 const result = await stop_sim_log_capLogic (
156142 {
157143 logSessionId : 'test-session-id' ,
158144 } ,
159- fileSystem ,
145+ mockExecutor ,
146+ stopLogCaptureStub ,
147+ mockFileSystem ,
160148 ) ;
161149
150+ expect ( capturedSessionId ) . toBe ( 'test-session-id' ) ;
162151 expect ( result . isError ) . toBeUndefined ( ) ;
163152 expect ( result . content [ 0 ] . text ) . toBe (
164153 'Log capture session test-session-id stopped successfully. Log content follows:\n\nMock log content from file' ,
165154 ) ;
166155 } ) ;
167156
168157 it ( 'should call stopLogCapture with different session ID' , async ( ) => {
169- const { fileSystem } = await createTestLogSession (
170- 'different-session-id' ,
171- 'Different log content' ,
172- ) ;
158+ let capturedSessionId = '' ;
159+ const stopLogCaptureStub = async ( logSessionId : string ) => {
160+ capturedSessionId = logSessionId ;
161+ return { logContent : 'Different log content' , error : undefined } ;
162+ } ;
173163
174164 const result = await stop_sim_log_capLogic (
175165 {
176166 logSessionId : 'different-session-id' ,
177167 } ,
178- fileSystem ,
168+ mockExecutor ,
169+ stopLogCaptureStub ,
170+ mockFileSystem ,
179171 ) ;
180172
173+ expect ( capturedSessionId ) . toBe ( 'different-session-id' ) ;
181174 expect ( result . isError ) . toBeUndefined ( ) ;
182175 expect ( result . content [ 0 ] . text ) . toBe (
183176 'Log capture session different-session-id stopped successfully. Log content follows:\n\nDifferent log content' ,
@@ -187,16 +180,18 @@ describe('stop_sim_log_cap plugin', () => {
187180
188181 describe ( 'Response Processing' , ( ) => {
189182 it ( 'should handle successful log capture stop' , async ( ) => {
190- const { fileSystem } = await createTestLogSession (
191- 'test-session-id ',
192- 'Mock log content from file' ,
193- ) ;
183+ const stopLogCaptureStub = async ( ) => ( {
184+ logContent : 'Mock log content from file ',
185+ error : undefined ,
186+ } ) ;
194187
195188 const result = await stop_sim_log_capLogic (
196189 {
197190 logSessionId : 'test-session-id' ,
198191 } ,
199- fileSystem ,
192+ mockExecutor ,
193+ stopLogCaptureStub ,
194+ mockFileSystem ,
200195 ) ;
201196
202197 expect ( result . isError ) . toBeUndefined ( ) ;
@@ -206,13 +201,18 @@ describe('stop_sim_log_cap plugin', () => {
206201 } ) ;
207202
208203 it ( 'should handle empty log content' , async ( ) => {
209- const { fileSystem } = await createTestLogSession ( 'test-session-id' , '' ) ;
204+ const stopLogCaptureStub = async ( ) => ( {
205+ logContent : '' ,
206+ error : undefined ,
207+ } ) ;
210208
211209 const result = await stop_sim_log_capLogic (
212210 {
213211 logSessionId : 'test-session-id' ,
214212 } ,
215- fileSystem ,
213+ mockExecutor ,
214+ stopLogCaptureStub ,
215+ mockFileSystem ,
216216 ) ;
217217
218218 expect ( result . isError ) . toBeUndefined ( ) ;
@@ -222,16 +222,18 @@ describe('stop_sim_log_cap plugin', () => {
222222 } ) ;
223223
224224 it ( 'should handle multiline log content' , async ( ) => {
225- const { fileSystem } = await createTestLogSession (
226- 'test-session-id ',
227- 'Line 1\nLine 2\nLine 3' ,
228- ) ;
225+ const stopLogCaptureStub = async ( ) => ( {
226+ logContent : 'Line 1\nLine 2\nLine 3 ',
227+ error : undefined ,
228+ } ) ;
229229
230230 const result = await stop_sim_log_capLogic (
231231 {
232232 logSessionId : 'test-session-id' ,
233233 } ,
234- fileSystem ,
234+ mockExecutor ,
235+ stopLogCaptureStub ,
236+ mockFileSystem ,
235237 ) ;
236238
237239 expect ( result . isError ) . toBeUndefined ( ) ;
@@ -241,11 +243,18 @@ describe('stop_sim_log_cap plugin', () => {
241243 } ) ;
242244
243245 it ( 'should handle log capture stop errors for non-existent session' , async ( ) => {
246+ const stopLogCaptureStub = async ( ) => ( {
247+ logContent : '' ,
248+ error : 'Log capture session not found: non-existent-session' ,
249+ } ) ;
250+
244251 const result = await stop_sim_log_capLogic (
245252 {
246253 logSessionId : 'non-existent-session' ,
247254 } ,
248- createMockFileSystemExecutor ( ) ,
255+ mockExecutor ,
256+ stopLogCaptureStub ,
257+ mockFileSystem ,
249258 ) ;
250259
251260 expect ( result . isError ) . toBe ( true ) ;
@@ -255,26 +264,18 @@ describe('stop_sim_log_cap plugin', () => {
255264 } ) ;
256265
257266 it ( 'should handle file read errors' , async ( ) => {
258- // Create session but make file reading fail in the log_capture utility
259- const mockProcess = {
260- pid : 12345 ,
261- killed : false ,
262- exitCode : null ,
263- kill : ( ) => { } ,
264- } ;
265-
266- activeLogSessions . set ( 'test-session-id' , {
267- processes : [ mockProcess as any ] ,
268- logFilePath : `/tmp/test_file_not_found.log` ,
269- simulatorUuid : 'test-simulator-uuid' ,
270- bundleId : 'com.example.TestApp' ,
267+ const stopLogCaptureStub = async ( ) => ( {
268+ logContent : '' ,
269+ error : 'ENOENT: no such file or directory' ,
271270 } ) ;
272271
273272 const result = await stop_sim_log_capLogic (
274- { logSessionId : 'test-session-id' } ,
275- createMockFileSystemExecutor ( {
276- existsSync : ( ) => false ,
277- } ) ,
273+ {
274+ logSessionId : 'test-session-id' ,
275+ } ,
276+ mockExecutor ,
277+ stopLogCaptureStub ,
278+ mockFileSystem ,
278279 ) ;
279280
280281 expect ( result . isError ) . toBe ( true ) ;
@@ -284,29 +285,18 @@ describe('stop_sim_log_cap plugin', () => {
284285 } ) ;
285286
286287 it ( 'should handle permission errors' , async ( ) => {
287- // Create session but make file reading fail in the log_capture utility
288- const mockProcess = {
289- pid : 12345 ,
290- killed : false ,
291- exitCode : null ,
292- kill : ( ) => { } ,
293- } ;
294-
295- activeLogSessions . set ( 'test-session-id' , {
296- processes : [ mockProcess as any ] ,
297- logFilePath : `/tmp/test_permission_denied.log` ,
298- simulatorUuid : 'test-simulator-uuid' ,
299- bundleId : 'com.example.TestApp' ,
288+ const stopLogCaptureStub = async ( ) => ( {
289+ logContent : '' ,
290+ error : 'EACCES: permission denied' ,
300291 } ) ;
301292
302293 const result = await stop_sim_log_capLogic (
303- { logSessionId : 'test-session-id' } ,
304- createMockFileSystemExecutor ( {
305- existsSync : ( ) => true ,
306- readFile : async ( ) => {
307- throw new Error ( 'Permission denied' ) ;
308- } ,
309- } ) ,
294+ {
295+ logSessionId : 'test-session-id' ,
296+ } ,
297+ mockExecutor ,
298+ stopLogCaptureStub ,
299+ mockFileSystem ,
310300 ) ;
311301
312302 expect ( result . isError ) . toBe ( true ) ;
@@ -316,29 +306,18 @@ describe('stop_sim_log_cap plugin', () => {
316306 } ) ;
317307
318308 it ( 'should handle various error types' , async ( ) => {
319- // Create session but make file reading fail in the log_capture utility
320- const mockProcess = {
321- pid : 12345 ,
322- killed : false ,
323- exitCode : null ,
324- kill : ( ) => { } ,
325- } ;
326-
327- activeLogSessions . set ( 'test-session-id' , {
328- processes : [ mockProcess as any ] ,
329- logFilePath : `/tmp/test_generic_error.log` ,
330- simulatorUuid : 'test-simulator-uuid' ,
331- bundleId : 'com.example.TestApp' ,
309+ const stopLogCaptureStub = async ( ) => ( {
310+ logContent : '' ,
311+ error : 'Unexpected error' ,
332312 } ) ;
333313
334314 const result = await stop_sim_log_capLogic (
335- { logSessionId : 'test-session-id' } ,
336- createMockFileSystemExecutor ( {
337- existsSync : ( ) => true ,
338- readFile : async ( ) => {
339- throw new Error ( 'Something went wrong' ) ;
340- } ,
341- } ) ,
315+ {
316+ logSessionId : 'test-session-id' ,
317+ } ,
318+ mockExecutor ,
319+ stopLogCaptureStub ,
320+ mockFileSystem ,
342321 ) ;
343322
344323 expect ( result . isError ) . toBe ( true ) ;
0 commit comments