@@ -7,13 +7,18 @@ import { default as assert } from 'assert';
77import * as vscode from 'vscode' ;
88import { IssueTodoProvider } from '../../issues/issueTodoProvider' ;
99
10+ // Simple factory for a CopilotRemoteAgentManager mock that always reports availability.
11+ function createAvailableCopilotManager ( ) {
12+ return { isAvailable : async ( ) => true } as any ;
13+ }
14+
1015describe ( 'IssueTodoProvider' , function ( ) {
1116 it ( 'should provide both actions when CopilotRemoteAgentManager is available' , async function ( ) {
1217 const mockContext = {
1318 subscriptions : [ ]
1419 } as any as vscode . ExtensionContext ;
1520
16- const mockCopilotManager = { } as any ; // Mock CopilotRemoteAgentManager
21+ const mockCopilotManager = createAvailableCopilotManager ( ) ;
1722
1823 // Mock configuration for triggers and prefixes
1924 const originalGetConfiguration = vscode . workspace . getConfiguration ;
@@ -34,7 +39,7 @@ describe('IssueTodoProvider', function () {
3439
3540 // Create a mock document with TODO comment
3641 const document = {
37- lineAt : ( line : number ) => ( { text : line === 1 ? ' // TODO: Fix this' : 'function test() {' } ) ,
42+ lineAt : ( line : number ) => ( { text : line === 1 ? ' // TODO: Fix this' : '// DEBUG: function test() {' } ) ,
3843 lineCount : 4
3944 } as vscode . TextDocument ;
4045
@@ -58,156 +63,26 @@ describe('IssueTodoProvider', function () {
5863 assert . strictEqual ( startAgentAction ?. command ?. command , 'issue.startCodingAgentFromTodo' ) ;
5964 } ) ;
6065
61- it ( 'should provide code lenses for TODO comments' , async function ( ) {
62- const mockContext = {
63- subscriptions : [ ]
64- } as any as vscode . ExtensionContext ;
65-
66- const mockCopilotManager = { } as any ; // Mock CopilotRemoteAgentManager
67-
68- const originalGetConfiguration = vscode . workspace . getConfiguration ;
69- vscode . workspace . getConfiguration = ( section ?: string ) => {
70- if ( section === 'githubIssues' ) {
71- return {
72- get : ( key : string , defaultValue ?: any ) => {
73- if ( key === 'createIssueTriggers' ) { return [ 'TODO' ] ; }
74- if ( key === 'createIssueCommentPrefixes' ) { return [ '//' , '#' ] ; }
75- return defaultValue ;
76- }
77- } as any ;
78- }
79- return originalGetConfiguration ( section ) ;
80- } ;
81- const provider = new IssueTodoProvider ( mockContext , mockCopilotManager ) ;
82-
83- // Create a mock document with TODO comment
84- const document = {
85- lineAt : ( line : number ) => ( {
86- text : line === 1 ? ' // TODO: Fix this' : 'function test() {}'
87- } ) ,
88- lineCount : 4
89- } as vscode . TextDocument ;
90-
91- const codeLenses = await provider . provideCodeLenses ( document , new vscode . CancellationTokenSource ( ) . token ) ;
92-
93- assert . strictEqual ( codeLenses . length , 2 ) ;
94-
95- // Verify the code lenses
96- const createIssueLens = codeLenses . find ( cl => cl . command ?. title === 'Create GitHub Issue' ) ;
97- const startAgentLens = codeLenses . find ( cl => cl . command ?. title === 'Delegate to coding agent' ) ;
98-
99- assert . ok ( createIssueLens , 'Should have Create GitHub Issue CodeLens' ) ;
100- assert . ok ( startAgentLens , 'Should have Delegate to coding agent CodeLens' ) ;
101-
102- assert . strictEqual ( createIssueLens ?. command ?. command , 'issue.createIssueFromSelection' ) ;
103- assert . strictEqual ( startAgentLens ?. command ?. command , 'issue.startCodingAgentFromTodo' ) ;
104-
105- // Verify the range points to the TODO text
106- assert . strictEqual ( createIssueLens ?. range . start . line , 1 ) ;
107- assert . strictEqual ( startAgentLens ?. range . start . line , 1 ) ;
108- } ) ;
109-
110- it ( 'should respect the createIssueCodeLens setting' , async function ( ) {
111- const mockContext = {
112- subscriptions : [ ]
113- } as any as vscode . ExtensionContext ;
114-
115- const mockCopilotManager = { } as any ; // Mock CopilotRemoteAgentManager
116-
117- const provider = new IssueTodoProvider ( mockContext , mockCopilotManager ) ;
118-
119- // Create a mock document with TODO comment
120- const document = {
121- lineAt : ( line : number ) => ( {
122- text : line === 1 ? ' // TODO: Fix this' : 'function test() {}'
123- } ) ,
124- lineCount : 4
125- } as vscode . TextDocument ;
126-
127- // Mock the workspace configuration to return false for createIssueCodeLens
128- const originalGetConfiguration = vscode . workspace . getConfiguration ;
129- vscode . workspace . getConfiguration = ( section ?: string ) => {
130- if ( section === 'githubIssues' ) {
131- return {
132- get : ( key : string , defaultValue ?: any ) => {
133- if ( key === 'createIssueCodeLens' ) {
134- return false ;
135- }
136- if ( key === 'createIssueTriggers' ) {
137- return [ 'TODO' , 'todo' , 'BUG' , 'FIXME' , 'ISSUE' , 'HACK' ] ;
138- }
139- return defaultValue ;
140- }
141- } as any ;
142- }
143- return originalGetConfiguration ( section ) ;
144- } ;
145-
146- try {
147- // Update triggers to ensure the expression is set
148- ( provider as any ) . updateTriggers ( ) ;
149-
150- const codeLenses = await provider . provideCodeLenses ( document , new vscode . CancellationTokenSource ( ) . token ) ;
151-
152- // Should return empty array when CodeLens is disabled
153- assert . strictEqual ( codeLenses . length , 0 , 'Should not provide code lenses when setting is disabled' ) ;
154- } finally {
155- // Restore original configuration
156- vscode . workspace . getConfiguration = originalGetConfiguration ;
157- }
158- } ) ;
159-
160- it ( 'should not trigger on line without comment prefix' , async function ( ) {
161- const mockContext = { subscriptions : [ ] } as any as vscode . ExtensionContext ;
162- const mockCopilotManager = { } as any ;
163-
164- const originalGetConfiguration = vscode . workspace . getConfiguration ;
165- vscode . workspace . getConfiguration = ( section ?: string ) => {
166- if ( section === 'githubIssues' ) {
167- return {
168- get : ( key : string , defaultValue ?: any ) => {
169- if ( key === 'createIssueTriggers' ) { return [ 'DEBUG_RUN' ] ; }
170- if ( key === 'createIssueCommentPrefixes' ) { return [ '//' ] ; }
171- return defaultValue ;
172- }
173- } as any ;
174- }
175- return originalGetConfiguration ( section ) ;
176- } ;
177-
178- const provider = new IssueTodoProvider ( mockContext , mockCopilotManager ) ;
179-
180- const testLine = "\tregisterTouchBarEntry(DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, 0, CONTEXT_IN_DEBUG_MODE.toNegated(), FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/continue-tb.png'));" ;
181- const document = {
182- lineAt : ( _line : number ) => ( { text : testLine } ) ,
183- lineCount : 1
184- } as vscode . TextDocument ;
185-
186- const codeLenses = await provider . provideCodeLenses ( document , new vscode . CancellationTokenSource ( ) . token ) ;
187- assert . strictEqual ( codeLenses . length , 0 , 'Should not create CodeLens for trigger inside code without prefix' ) ;
188-
189- vscode . workspace . getConfiguration = originalGetConfiguration ; // restore
190- } ) ;
191-
19266 it ( 'prefix matrix detection' , async function ( ) {
19367 const mockContext = { subscriptions : [ ] } as any as vscode . ExtensionContext ;
194- const mockCopilotManager = { isAvailable : async ( ) => true } as any ;
68+ const mockCopilotManager = createAvailableCopilotManager ( ) ;
19569
19670 const testCases : { testLine : string ; expected : boolean ; note ?: string } [ ] = [
19771 { testLine : ' // TODO implement feature' , expected : true } ,
19872 { testLine : '\t//TODO implement feature' , expected : true } ,
19973 { testLine : ' # TODO spaced hash' , expected : true } ,
20074 { testLine : '-- TODO dash dash' , expected : true } ,
20175 { testLine : ' * TODO docblock star' , expected : true } ,
202- { testLine : '\t* TODO extra spaces after star' , expected : true } ,
76+ { testLine : ' * TODO extra spaces after star' , expected : true } ,
20377 { testLine : '/// TODO rust style' , expected : true } ,
20478 { testLine : '///TODO rust tight' , expected : true } ,
205- { testLine : 'let x = 0; // TODO not at line start so should not match' , expected : false } ,
79+ { testLine : 'let x = 0; // TODO not at line start so should not match' , expected : false } , // TODO: Detect inline TODO comments
20680 { testLine : ' *TODO (no space after star)' , expected : false } ,
20781 { testLine : ' * NotATrigger word' , expected : false } ,
20882 { testLine : '/* TODO inside block start should not (prefix not configured)' , expected : false } ,
20983 { testLine : 'random text TODO (no prefix)' , expected : false } ,
21084 { testLine : '#TODO tight hash' , expected : true } ,
85+ { testLine : 'registerTouchBarEntry(DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, 0, CONTEXT_IN_DEBUG_MODE.toNegated(), FileAccess.asFileUri(\'vs/workbench/contrib/debug/browser/media/continue-tb.png\')' , expected : false }
21186 ] ;
21287
21388 const originalGetConfiguration = vscode . workspace . getConfiguration ;
@@ -236,7 +111,7 @@ describe('IssueTodoProvider', function () {
236111 } as vscode . TextDocument ;
237112 const codeLenses = await provider . provideCodeLenses ( document , new vscode . CancellationTokenSource ( ) . token ) ;
238113 const detected = codeLenses . length > 0 ;
239- assert . strictEqual ( detected , tc . expected , `Mismatch for line: "${ tc . testLine } "` ) ;
114+ assert . strictEqual ( detected , tc . expected , `Unexpected result (expected= ${ tc . expected } ) for line: "${ tc . testLine } "` ) ;
240115 }
241116 } finally {
242117 vscode . workspace . getConfiguration = originalGetConfiguration ;
0 commit comments