1- jest . mock ( 'node-pty' , ( ) => ( {
2- spawn : jest . fn ( ( ) => ( {
3- pid : 1234 ,
4- onData : jest . fn ( ) ,
5- onExit : jest . fn ( ) ,
6- kill : jest . fn ( )
7- } ) )
8- } ) , { virtual : true } ) ;
9-
10- jest . mock ( 'winston' , ( ) => ( {
11- createLogger : jest . fn ( ( ) => ( {
12- info : jest . fn ( ) ,
13- warn : jest . fn ( ) ,
14- error : jest . fn ( ) ,
15- debug : jest . fn ( )
16- } ) ) ,
17- format : {
18- combine : jest . fn ( ( ) => ( { } ) ) ,
19- timestamp : jest . fn ( ( ) => ( { } ) ) ,
20- json : jest . fn ( ( ) => ( { } ) ) ,
21- simple : jest . fn ( ( ) => ( { } ) ) ,
22- errors : jest . fn ( ( ) => ( { } ) )
23- } ,
24- transports : {
25- File : jest . fn ( ) ,
26- Console : jest . fn ( )
27- }
28- } ) , { virtual : true } ) ;
29-
30- jest . mock ( '../../server/sessionRecoveryService' , ( ) => ( {
31- clearSession : jest . fn ( ) ,
32- updateSession : jest . fn ( ) ,
33- updateAgent : jest . fn ( ) ,
34- updateCwd : jest . fn ( ) ,
35- updateConversation : jest . fn ( ) ,
36- updateServer : jest . fn ( ) ,
37- getSession : jest . fn ( ) ,
38- getAllSessions : jest . fn ( ) ,
39- init : jest . fn ( ) ,
40- loadWorkspaceState : jest . fn ( ) ,
41- getRecoveryInfo : jest . fn ( ) ,
42- clearWorkspace : jest . fn ( ) ,
43- markAgentInactive : jest . fn ( )
44- } ) ) ;
45-
46- const nodePty = require ( 'node-pty' ) ;
47- const { SessionManager } = require ( '../../server/sessionManager' ) ;
481const fs = require ( 'fs' ) ;
492const path = require ( 'path' ) ;
503const { patchNodePtyStartProcessCompat } = require ( '../../server/utils/processUtils' ) ;
514
52- describe ( 'SessionManager Windows PTY options' , ( ) => {
53- const platformDescriptor = Object . getOwnPropertyDescriptor ( process , 'platform' ) ;
5+ const platformDescriptor = Object . getOwnPropertyDescriptor ( process , 'platform' ) ;
6+
7+ function createNodePtyMock ( ) {
8+ return {
9+ spawn : jest . fn ( ( ) => ( {
10+ pid : 1234 ,
11+ onData : jest . fn ( ) ,
12+ onExit : jest . fn ( ) ,
13+ kill : jest . fn ( )
14+ } ) )
15+ } ;
16+ }
17+
18+ function mockWinston ( ) {
19+ return {
20+ createLogger : jest . fn ( ( ) => ( {
21+ info : jest . fn ( ) ,
22+ warn : jest . fn ( ) ,
23+ error : jest . fn ( ) ,
24+ debug : jest . fn ( )
25+ } ) ) ,
26+ format : {
27+ combine : jest . fn ( ( ) => ( { } ) ) ,
28+ timestamp : jest . fn ( ( ) => ( { } ) ) ,
29+ json : jest . fn ( ( ) => ( { } ) ) ,
30+ simple : jest . fn ( ( ) => ( { } ) ) ,
31+ errors : jest . fn ( ( ) => ( { } ) )
32+ } ,
33+ transports : {
34+ File : jest . fn ( ) ,
35+ Console : jest . fn ( )
36+ }
37+ } ;
38+ }
39+
40+ function mockSessionRecoveryService ( ) {
41+ return {
42+ clearSession : jest . fn ( ) ,
43+ updateSession : jest . fn ( ) ,
44+ updateAgent : jest . fn ( ) ,
45+ updateCwd : jest . fn ( ) ,
46+ updateConversation : jest . fn ( ) ,
47+ updateServer : jest . fn ( ) ,
48+ getSession : jest . fn ( ) ,
49+ getAllSessions : jest . fn ( ) ,
50+ init : jest . fn ( ) ,
51+ loadWorkspaceState : jest . fn ( ) ,
52+ getRecoveryInfo : jest . fn ( ) ,
53+ clearWorkspace : jest . fn ( ) ,
54+ markAgentInactive : jest . fn ( )
55+ } ;
56+ }
57+
58+ function loadSessionManagerForWindows ( ) {
59+ jest . resetModules ( ) ;
60+ Object . defineProperty ( process , 'platform' , { configurable : true , value : 'win32' } ) ;
61+
62+ let nodePty = null ;
63+ let SessionManager = null ;
64+
65+ jest . doMock ( 'node-pty' , ( ) => {
66+ nodePty = createNodePtyMock ( ) ;
67+ return nodePty ;
68+ } ) ;
69+ jest . doMock ( 'winston' , ( ) => mockWinston ( ) , { virtual : true } ) ;
70+ jest . doMock ( '../../server/sessionRecoveryService' , ( ) => mockSessionRecoveryService ( ) ) ;
5471
55- beforeEach ( ( ) => {
56- jest . clearAllMocks ( ) ;
72+ jest . isolateModules ( ( ) => {
73+ ( { SessionManager } = require ( '../../server/sessionManager' ) ) ;
5774 } ) ;
5875
76+ return {
77+ SessionManager,
78+ nodePty
79+ } ;
80+ }
81+
82+ describe ( 'SessionManager Windows PTY options' , ( ) => {
5983 afterEach ( ( ) => {
84+ jest . resetModules ( ) ;
85+ jest . clearAllMocks ( ) ;
6086 Object . defineProperty ( process , 'platform' , platformDescriptor ) ;
6187 } ) ;
6288
6389 it ( 'enables ConPTY for Windows sessions and cleans up workspace-specific sessions' , ( ) => {
64- Object . defineProperty ( process , 'platform' , { value : 'win32' } ) ;
90+ const { SessionManager , nodePty } = loadSessionManagerForWindows ( ) ;
6591
6692 const io = { emit : jest . fn ( ) } ;
6793 const sessionManager = new SessionManager ( io , null ) ;
@@ -82,7 +108,6 @@ describe('SessionManager Windows PTY options', () => {
82108 cwd : 'C:\\repo'
83109 } )
84110 ) ;
85- // useConpty must NOT be passed — it causes native arg-count mismatches
86111 const passedOpts = nodePty . spawn . mock . calls [ 0 ] [ 2 ] ;
87112 expect ( passedOpts ) . not . toHaveProperty ( 'useConpty' ) ;
88113
@@ -105,9 +130,9 @@ describe('SessionManager Windows PTY options', () => {
105130 } ) ;
106131
107132 it ( 'patches the broken Windows node-pty startProcess wrapper' , ( ) => {
108- const existsSpy = jest . spyOn ( fs , 'existsSync' ) . mockImplementation ( ( targetPath ) => {
109- return targetPath === path . join ( 'C:\\node_modules\\node-pty' , 'lib' , 'windowsPtyAgent.js' ) ;
110- } ) ;
133+ const existsSpy = jest . spyOn ( fs , 'existsSync' ) . mockImplementation ( ( targetPath ) => (
134+ targetPath === path . join ( 'C:\\node_modules\\node-pty' , 'lib' , 'windowsPtyAgent.js' )
135+ ) ) ;
111136 const readSpy = jest . spyOn ( fs , 'readFileSync' ) . mockReturnValue (
112137 'before conptyNative.startProcess(file, cols, rows, debug, this._generatePipeName(), conptyInheritCursor, this._useConptyDll) after'
113138 ) ;
0 commit comments