@@ -30,15 +30,20 @@ import type { CTreeItem } from '../../../generic/tree-item';
3030import type { CSolution } from '../../../solutions/csolution' ;
3131import { README_FILE_PATH } from '../../../manifest' ;
3232import { faker } from '@faker-js/faker' ;
33+ import { ConfigWizardAnnotationChecker } from '../../../utils/config-wizard-checker' ;
3334
3435describe ( 'OpenCommand' , ( ) => {
3536 let commandsProvider : MockCommandsProvider ;
3637 const mockOpenFileExternal : IOpenFileExternal = openFileExternalFactory ( ) ;
38+ let mockAnnotationChecker : ConfigWizardAnnotationChecker ;
3739 let testFolder : string ;
3840 let testFile : string ;
3941
4042 beforeEach ( async ( ) => {
4143 commandsProvider = commandsProviderFactory ( ) ;
44+ mockAnnotationChecker = {
45+ hasAnnotations : jest . fn ( ) . mockResolvedValue ( false ) ,
46+ } ;
4247 testFolder = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'jest-' ) ) ;
4348 testFile = `${ testFolder } /jtest.txt` ;
4449 fs . writeFileSync ( testFile , 'test content' ) ;
@@ -50,12 +55,12 @@ describe('OpenCommand', () => {
5055 } ) ;
5156
5257 it ( 'registers the command on activation' , async ( ) => {
53- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
58+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
5459
5560 await openCommand . activate ( extensionContextFactory ( ) ) ;
5661
5762 const expectedCommands = [ OpenCommand . openSolutionCommandId , OpenCommand . openProjectCommandId , OpenCommand . openPrjConfCommandId ,
58- OpenCommand . openLayerCommandId , OpenCommand . openLinkerCommandId , OpenCommand . openDocCommandId , OpenCommand . openHelpCommandId ,
63+ OpenCommand . openLayerCommandId , OpenCommand . openLinkerCommandId , OpenCommand . openDocCommandId , OpenCommand . openSourceSmartCommandId , OpenCommand . openHelpCommandId ,
5964 OpenCommand . openZephyrTerminalCommandId ] ;
6065
6166 expect ( commandsProvider . registerCommand ) . toHaveBeenCalledTimes ( expectedCommands . length ) ;
@@ -69,7 +74,7 @@ describe('OpenCommand', () => {
6974 const mockSolutionManager = solutionManagerFactory ( {
7075 loadState : activeSolutionLoadStateFactory ( { solutionPath : solutionPath } ) ,
7176 } ) ;
72- const openCommand = new OpenCommand ( mockSolutionManager , commandsProvider , mockOpenFileExternal ) ;
77+ const openCommand = new OpenCommand ( mockSolutionManager , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
7378 await openCommand . activate ( extensionContextFactory ( ) ) ;
7479
7580 await commandsProvider . mockRunRegistered ( OpenCommand . openSolutionCommandId , solutionPath ) ;
@@ -78,7 +83,7 @@ describe('OpenCommand', () => {
7883 } ) ;
7984
8085 it ( 'opens and shows the cproject file from the path' , async ( ) => {
81- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
86+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
8287 await openCommand . activate ( extensionContextFactory ( ) ) ;
8388 const TEST_PROJECT_PATH = path . join ( 'some' , 'path' , 'to' , 'Test.cproject.yml' ) ;
8489
@@ -93,7 +98,7 @@ describe('OpenCommand', () => {
9398 } ) ;
9499
95100 it ( 'opens and shows the clayer file from the path' , async ( ) => {
96- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
101+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
97102 await openCommand . activate ( extensionContextFactory ( ) ) ;
98103 const TEST_LAYER_PATH = path . join ( 'some' , 'path' , 'to' , 'Test.clayer.yml' ) ;
99104
@@ -108,7 +113,7 @@ describe('OpenCommand', () => {
108113 } ) ;
109114
110115 it ( 'opens and shows the linker map file from the path' , async ( ) => {
111- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
116+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
112117 await openCommand . activate ( extensionContextFactory ( ) ) ;
113118 const TEST_LINKER_PATH = path . join ( 'some' , 'path' , 'to' , 'myFile.axf.map' ) ;
114119
@@ -123,7 +128,7 @@ describe('OpenCommand', () => {
123128 } ) ;
124129
125130 it ( 'opens and shows the prj.conf file for West project' , async ( ) => {
126- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
131+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
127132 await openCommand . activate ( extensionContextFactory ( ) ) ;
128133 const TEST_PRJ_CONF_PATH = path . join ( 'some' , 'path' , 'to' , 'zephyr-app' , 'prj.conf' ) ;
129134
@@ -138,7 +143,7 @@ describe('OpenCommand', () => {
138143 } ) ;
139144
140145 it ( 'opens and shows a doc file from the path' , async ( ) => {
141- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
146+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
142147 await openCommand . activate ( extensionContextFactory ( ) ) ;
143148
144149 const fileItem = new COutlineItem ( 'file' ) ;
@@ -209,7 +214,7 @@ describe('OpenCommand', () => {
209214 jest . spyOn ( vscode . extensions , 'getExtension' ) . mockReturnValue ( { extensionPath } as unknown as vscode . Extension < void > ) ;
210215 jest . spyOn ( fs , 'existsSync' ) . mockReturnValue ( true ) ;
211216
212- const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal ) ;
217+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
213218 await openCommand . activate ( extensionContextFactory ( ) ) ;
214219
215220 jest . spyOn ( mockOpenFileExternal , 'openFile' ) ;
@@ -228,7 +233,7 @@ describe('OpenCommand', () => {
228233 const mockSolutionManager = solutionManagerFactory ( ) ;
229234 jest . spyOn ( mockSolutionManager , 'getCsolution' ) . mockReturnValue ( { cbuildYmlRoot : mockCbuildMap } as Partial < CSolution > as CSolution ) ;
230235
231- const openCommand = new OpenCommand ( mockSolutionManager , commandsProvider , mockOpenFileExternal ) ;
236+ const openCommand = new OpenCommand ( mockSolutionManager , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
232237 await openCommand . activate ( extensionContextFactory ( ) ) ;
233238
234239 const node = new COutlineItem ( 'project' ) ;
@@ -242,4 +247,57 @@ describe('OpenCommand', () => {
242247 } ) ;
243248 expect ( mockTerminal . show ) . toHaveBeenCalled ( ) ;
244249 } ) ;
250+
251+ it ( 'opens candidate source file in configuration wizard when annotations are found' , async ( ) => {
252+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
253+ await openCommand . activate ( extensionContextFactory ( ) ) ;
254+ ( mockAnnotationChecker . hasAnnotations as jest . Mock ) . mockResolvedValue ( true ) ;
255+
256+ const uri = Uri . file ( path . join ( testFolder , 'config.h' ) ) ;
257+ await commandsProvider . mockRunRegistered ( OpenCommand . openSourceSmartCommandId , uri ) ;
258+
259+ const lastCall = commandsProvider . executeCommand . mock . lastCall ;
260+ expect ( lastCall ?. [ 0 ] ) . toBe ( 'vscode.openWith' ) ;
261+ expect ( ( lastCall ?. [ 1 ] as Uri ) . fsPath ) . toBe ( uri . fsPath ) ;
262+ expect ( lastCall ?. [ 2 ] ) . toBe ( 'cmsis-csolution.configWizard' ) ;
263+ } ) ;
264+
265+ it ( 'opens candidate source file in text editor when annotations are missing' , async ( ) => {
266+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
267+ await openCommand . activate ( extensionContextFactory ( ) ) ;
268+ ( mockAnnotationChecker . hasAnnotations as jest . Mock ) . mockResolvedValue ( false ) ;
269+
270+ const uri = Uri . file ( path . join ( testFolder , 'config.h' ) ) ;
271+ await commandsProvider . mockRunRegistered ( OpenCommand . openSourceSmartCommandId , uri ) ;
272+
273+ const lastCall = commandsProvider . executeCommand . mock . lastCall ;
274+ expect ( lastCall ?. [ 0 ] ) . toBe ( 'vscode.open' ) ;
275+ expect ( ( lastCall ?. [ 1 ] as Uri ) . fsPath ) . toBe ( uri . fsPath ) ;
276+ } ) ;
277+
278+ it ( 'falls back to text editor when annotation detection fails' , async ( ) => {
279+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
280+ await openCommand . activate ( extensionContextFactory ( ) ) ;
281+ ( mockAnnotationChecker . hasAnnotations as jest . Mock ) . mockRejectedValue ( new Error ( 'parse failure' ) ) ;
282+
283+ const uri = Uri . file ( path . join ( testFolder , 'config.h' ) ) ;
284+ await commandsProvider . mockRunRegistered ( OpenCommand . openSourceSmartCommandId , uri ) ;
285+
286+ const lastCall = commandsProvider . executeCommand . mock . lastCall ;
287+ expect ( lastCall ?. [ 0 ] ) . toBe ( 'vscode.open' ) ;
288+ expect ( ( lastCall ?. [ 1 ] as Uri ) . fsPath ) . toBe ( uri . fsPath ) ;
289+ } ) ;
290+
291+ it ( 'opens non-candidate source file in text editor without annotation checks' , async ( ) => {
292+ const openCommand = new OpenCommand ( solutionManagerFactory ( ) , commandsProvider , mockOpenFileExternal , mockAnnotationChecker ) ;
293+ await openCommand . activate ( extensionContextFactory ( ) ) ;
294+
295+ const uri = Uri . file ( path . join ( testFolder , 'build.txt' ) ) ;
296+ await commandsProvider . mockRunRegistered ( OpenCommand . openSourceSmartCommandId , uri ) ;
297+
298+ expect ( mockAnnotationChecker . hasAnnotations ) . not . toHaveBeenCalled ( ) ;
299+ const lastCall = commandsProvider . executeCommand . mock . lastCall ;
300+ expect ( lastCall ?. [ 0 ] ) . toBe ( 'vscode.open' ) ;
301+ expect ( ( lastCall ?. [ 1 ] as Uri ) . fsPath ) . toBe ( uri . fsPath ) ;
302+ } ) ;
245303} ) ;
0 commit comments