1515 */
1616
1717import { GDBTargetConfiguration , GDBTargetConfigurationProvider } from '.' ; // use index.ts to cover it in one test
18- import { extensionContextFactory } from '../__test__/vscode.factory' ;
18+ import { debugSessionFactory , extensionContextFactory } from '../__test__/vscode.factory' ;
1919
2020import * as vscode from 'vscode' ;
2121import { URI } from 'vscode-uri' ;
22- import { debugConfigurationFactory } from './debug-configuration.factory' ;
22+ import { debugConfigurationFactory , gdbTargetConfiguration } from './debug-configuration.factory' ;
2323import { BuiltinToolPath } from '../desktop/builtin-tool-path' ;
24- import { isWindows } from '../utils' ;
24+ import { isWindows , waitForMs } from '../utils' ;
25+ import { GDBTargetDebugSession , GDBTargetDebugTracker } from '../debug-session' ;
2526
2627jest . mock ( '../desktop/builtin-tool-path' ) ;
2728const BuiltinToolPathMock = BuiltinToolPath as jest . MockedClass < typeof BuiltinToolPath > ;
2829
2930describe ( 'GDBTargetConfigurationProvider' , ( ) => {
3031
31- it ( 'should activate' , async ( ) => {
32+ it ( 'should activate' , ( ) => {
3233 const configProvider = new GDBTargetConfigurationProvider ( [ ] ) ;
3334 const contextMock = extensionContextFactory ( ) ;
3435
@@ -38,6 +39,18 @@ describe('GDBTargetConfigurationProvider', () => {
3839 expect ( vscode . debug . registerDebugConfigurationProvider as jest . Mock ) . toHaveBeenCalledWith ( 'gdbtarget' , configProvider ) ;
3940 } ) ;
4041
42+ it ( 'should activate with debug tracker' , ( ) => {
43+ const debugTracker = new GDBTargetDebugTracker ( ) ;
44+ const configProvider = new GDBTargetConfigurationProvider ( [ ] ) ;
45+ const contextMock = extensionContextFactory ( ) ;
46+
47+ configProvider . activate ( contextMock , debugTracker ) ;
48+
49+ // 1 for the config provider, 2 for the debug tracker
50+ expect ( contextMock . subscriptions ) . toHaveLength ( 1 + 2 ) ;
51+ expect ( vscode . debug . registerDebugConfigurationProvider as jest . Mock ) . toHaveBeenCalledWith ( 'gdbtarget' , configProvider ) ;
52+ } ) ;
53+
4154 it ( 'resolveDebugConfiguration' , async ( ) => {
4255 const configProvider = new GDBTargetConfigurationProvider ( [ ] ) ;
4356 const debugConfig = debugConfigurationFactory ( ) ;
@@ -97,4 +110,112 @@ describe('GDBTargetConfigurationProvider', () => {
97110 expect ( resolvedDebugConfig ) . toBeDefined ( ) ;
98111 expect ( resolvedDebugConfig . gdb ) . toEqual ( expectedGdbPath ) ;
99112 } ) ;
113+
114+ describe ( 'tests with sessions' , ( ) => {
115+ let debugTracker : GDBTargetDebugTracker ;
116+ let configProvider : GDBTargetConfigurationProvider ;
117+ let contextMock : vscode . ExtensionContext ;
118+
119+ const createLaunchConfig = ( name : string ) => gdbTargetConfiguration ( {
120+ name,
121+ request : 'launch'
122+ } ) ;
123+
124+ const createAttachConfig = ( name : string ) => gdbTargetConfiguration ( {
125+ name,
126+ request : 'attach'
127+ } ) ;
128+
129+ const createLaunchSession = ( name : string ) => new GDBTargetDebugSession (
130+ debugSessionFactory ( createLaunchConfig ( name ) )
131+ ) ;
132+
133+ const createAttachSession = ( name : string ) => new GDBTargetDebugSession (
134+ debugSessionFactory ( createAttachConfig ( name ) )
135+ ) ;
136+
137+ beforeEach ( ( ) => {
138+ debugTracker = new GDBTargetDebugTracker ( ) ;
139+ configProvider = new GDBTargetConfigurationProvider ( [ ] ) ;
140+ contextMock = extensionContextFactory ( ) ;
141+
142+ configProvider . activate ( contextMock , debugTracker ) ;
143+
144+ ( vscode . window . showInformationMessage as jest . Mock ) . mockClear ( ) ;
145+ } ) ;
146+
147+ it ( 'can add and remove sessions' , async ( ) => {
148+ const debugSession = createLaunchSession ( 'testSession' ) ;
149+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
150+ ( debugTracker as any ) . _onWillStartSession . fire ( debugSession ) ;
151+ await waitForMs ( 0 ) ;
152+ expect ( configProvider [ 'activeSessions' ] . size ) . toBe ( 1 ) ;
153+
154+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
155+ ( debugTracker as any ) . _onWillStopSession . fire ( debugSession ) ;
156+ await waitForMs ( 0 ) ;
157+ expect ( configProvider [ 'activeSessions' ] . size ) . toBe ( 0 ) ;
158+ } ) ;
159+
160+ it ( 'starts independent sessions' , async ( ) => {
161+ const launchSession = createLaunchSession ( 'pname session@1 (launch)' ) ;
162+ const attachSession = createAttachSession ( 'pname session@2 (attach)' ) ;
163+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164+ ( debugTracker as any ) . _onWillStartSession . fire ( launchSession ) ;
165+ await waitForMs ( 0 ) ;
166+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
167+ ( debugTracker as any ) . _onWillStartSession . fire ( attachSession ) ;
168+ await waitForMs ( 0 ) ;
169+ } ) ;
170+
171+ it . each ( [
172+ { dialogResponse : undefined , undefinedResult : true } ,
173+ { dialogResponse : 'Yes' , undefinedResult : false } ,
174+ ] ) ( 'asks for confirmation if starting sessions with same config base name (dialog response $dialogResponse)' , async ( { dialogResponse, undefinedResult } ) => {
175+ ( vscode . window . showInformationMessage as jest . Mock ) . mockResolvedValueOnce ( dialogResponse ) ;
176+ const launchSession = createLaunchSession ( 'pname session@1 (launch)' ) ;
177+ const attachConfig = createAttachConfig ( 'pname session@1 (attach)' ) ;
178+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
179+ ( debugTracker as any ) . _onWillStartSession . fire ( launchSession ) ;
180+ await waitForMs ( 0 ) ;
181+ expect ( vscode . window . showInformationMessage ) . not . toHaveBeenCalled ( ) ;
182+ const result = await configProvider . resolveDebugConfigurationWithSubstitutedVariables (
183+ undefined ,
184+ attachConfig
185+ ) ;
186+ expect ( vscode . window . showInformationMessage ) . toHaveBeenCalledTimes ( 1 ) ;
187+ if ( undefinedResult ) {
188+ expect ( result ) . toBeUndefined ( ) ;
189+ } else {
190+ expect ( result ) . toBeDefined ( ) ;
191+ }
192+ } ) ;
193+
194+ it ( 'does not ask for confirmation if same config starts again (VS Code will do later)' , async ( ) => {
195+ const launchSession = createLaunchSession ( 'pname session@1 (launch)' ) ;
196+ const otherLaunchConfig = createLaunchConfig ( 'pname session@1 (launch)' ) ;
197+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
198+ ( debugTracker as any ) . _onWillStartSession . fire ( launchSession ) ;
199+ await waitForMs ( 0 ) ;
200+ expect ( vscode . window . showInformationMessage ) . not . toHaveBeenCalled ( ) ;
201+ const result = await configProvider . resolveDebugConfigurationWithSubstitutedVariables (
202+ undefined ,
203+ otherLaunchConfig
204+ ) ;
205+ expect ( vscode . window . showInformationMessage ) . not . toHaveBeenCalled ( ) ;
206+ expect ( result ) . toBeDefined ( ) ;
207+ } ) ;
208+
209+ it ( 'does not ask for confirmation if no other session running' , async ( ) => {
210+ const launchConfig = createLaunchConfig ( 'pname session@1 (launch)' ) ;
211+ expect ( vscode . window . showInformationMessage ) . not . toHaveBeenCalled ( ) ;
212+ const result = await configProvider . resolveDebugConfigurationWithSubstitutedVariables (
213+ undefined ,
214+ launchConfig
215+ ) ;
216+ expect ( vscode . window . showInformationMessage ) . not . toHaveBeenCalled ( ) ;
217+ expect ( result ) . toBeDefined ( ) ;
218+ } ) ;
219+ } ) ;
220+
100221} ) ;
0 commit comments