11import * as vscode from "vscode"
22import { CodeActionProvider , ACTION_NAMES } from "../CodeActionProvider"
3+ import { EditorUtils } from "../EditorUtils"
34
45// Mock VSCode API
56jest . mock ( "vscode" , ( ) => ( {
@@ -16,13 +17,6 @@ jest.mock("vscode", () => ({
1617 start : { line : startLine , character : startChar } ,
1718 end : { line : endLine , character : endChar } ,
1819 } ) ) ,
19- Position : jest . fn ( ) . mockImplementation ( ( line , character ) => ( {
20- line,
21- character,
22- } ) ) ,
23- workspace : {
24- getWorkspaceFolder : jest . fn ( ) ,
25- } ,
2620 DiagnosticSeverity : {
2721 Error : 0 ,
2822 Warning : 1 ,
@@ -31,6 +25,16 @@ jest.mock("vscode", () => ({
3125 } ,
3226} ) )
3327
28+ // Mock EditorUtils
29+ jest . mock ( "../EditorUtils" , ( ) => ( {
30+ EditorUtils : {
31+ getEffectiveRange : jest . fn ( ) ,
32+ getFilePath : jest . fn ( ) ,
33+ hasIntersectingRange : jest . fn ( ) ,
34+ createDiagnosticData : jest . fn ( ) ,
35+ } ,
36+ } ) )
37+
3438describe ( "CodeActionProvider" , ( ) => {
3539 let provider : CodeActionProvider
3640 let mockDocument : any
@@ -55,68 +59,32 @@ describe("CodeActionProvider", () => {
5559 mockContext = {
5660 diagnostics : [ ] ,
5761 }
58- } )
59-
60- describe ( "getEffectiveRange" , ( ) => {
61- it ( "should return selected text when available" , ( ) => {
62- mockDocument . getText . mockReturnValue ( "selected text" )
63-
64- const result = ( provider as any ) . getEffectiveRange ( mockDocument , mockRange )
65-
66- expect ( result ) . toEqual ( {
67- range : mockRange ,
68- text : "selected text" ,
69- } )
70- } )
71-
72- it ( "should return null for empty line" , ( ) => {
73- mockDocument . getText . mockReturnValue ( "" )
74- mockDocument . lineAt . mockReturnValue ( { text : "" , lineNumber : 0 } )
75-
76- const result = ( provider as any ) . getEffectiveRange ( mockDocument , mockRange )
77-
78- expect ( result ) . toBeNull ( )
79- } )
80- } )
81-
82- describe ( "getFilePath" , ( ) => {
83- it ( "should return relative path when in workspace" , ( ) => {
84- const mockWorkspaceFolder = {
85- uri : { fsPath : "/test" } ,
86- }
87- ; ( vscode . workspace . getWorkspaceFolder as jest . Mock ) . mockReturnValue ( mockWorkspaceFolder )
88-
89- const result = ( provider as any ) . getFilePath ( mockDocument )
90-
91- expect ( result ) . toBe ( "file.ts" )
92- } )
93-
94- it ( "should return absolute path when not in workspace" , ( ) => {
95- ; ( vscode . workspace . getWorkspaceFolder as jest . Mock ) . mockReturnValue ( null )
9662
97- const result = ( provider as any ) . getFilePath ( mockDocument )
98-
99- expect ( result ) . toBe ( "/test/file.ts" )
63+ // Setup default EditorUtils mocks
64+ ; ( EditorUtils . getEffectiveRange as jest . Mock ) . mockReturnValue ( {
65+ range : mockRange ,
66+ text : "test code" ,
10067 } )
68+ ; ( EditorUtils . getFilePath as jest . Mock ) . mockReturnValue ( "/test/file.ts" )
69+ ; ( EditorUtils . hasIntersectingRange as jest . Mock ) . mockReturnValue ( true )
70+ ; ( EditorUtils . createDiagnosticData as jest . Mock ) . mockImplementation ( ( d ) => d )
10171 } )
10272
10373 describe ( "provideCodeActions" , ( ) => {
104- beforeEach ( ( ) => {
105- mockDocument . getText . mockReturnValue ( "test code" )
106- mockDocument . lineAt . mockReturnValue ( { text : "test code" , lineNumber : 0 } )
107- } )
108-
109- it ( "should provide explain and improve actions by default" , ( ) => {
74+ it ( "should provide explain, improve, fix logic, and add to context actions by default" , ( ) => {
11075 const actions = provider . provideCodeActions ( mockDocument , mockRange , mockContext )
11176
112- expect ( actions ) . toHaveLength ( 4 )
77+ expect ( actions ) . toHaveLength ( 7 ) // 2 explain + 2 fix logic + 2 improve + 1 add to context
11378 expect ( ( actions as any ) [ 0 ] . title ) . toBe ( `${ ACTION_NAMES . EXPLAIN } in New Task` )
11479 expect ( ( actions as any ) [ 1 ] . title ) . toBe ( `${ ACTION_NAMES . EXPLAIN } in Current Task` )
115- expect ( ( actions as any ) [ 2 ] . title ) . toBe ( `${ ACTION_NAMES . IMPROVE } in New Task` )
116- expect ( ( actions as any ) [ 3 ] . title ) . toBe ( `${ ACTION_NAMES . IMPROVE } in Current Task` )
80+ expect ( ( actions as any ) [ 2 ] . title ) . toBe ( `${ ACTION_NAMES . FIX_LOGIC } in New Task` )
81+ expect ( ( actions as any ) [ 3 ] . title ) . toBe ( `${ ACTION_NAMES . FIX_LOGIC } in Current Task` )
82+ expect ( ( actions as any ) [ 4 ] . title ) . toBe ( `${ ACTION_NAMES . IMPROVE } in New Task` )
83+ expect ( ( actions as any ) [ 5 ] . title ) . toBe ( `${ ACTION_NAMES . IMPROVE } in Current Task` )
84+ expect ( ( actions as any ) [ 6 ] . title ) . toBe ( ACTION_NAMES . ADD_TO_CONTEXT )
11785 } )
11886
119- it ( "should provide fix action when diagnostics exist" , ( ) => {
87+ it ( "should provide fix action instead of fix logic when diagnostics exist" , ( ) => {
12088 mockContext . diagnostics = [
12189 {
12290 message : "test error" ,
@@ -127,22 +95,33 @@ describe("CodeActionProvider", () => {
12795
12896 const actions = provider . provideCodeActions ( mockDocument , mockRange , mockContext )
12997
130- expect ( actions ) . toHaveLength ( 6 )
98+ expect ( actions ) . toHaveLength ( 7 ) // 2 explain + 2 fix + 2 improve + 1 add to context
13199 expect ( ( actions as any ) . some ( ( a : any ) => a . title === `${ ACTION_NAMES . FIX } in New Task` ) ) . toBe ( true )
132100 expect ( ( actions as any ) . some ( ( a : any ) => a . title === `${ ACTION_NAMES . FIX } in Current Task` ) ) . toBe ( true )
101+ expect ( ( actions as any ) . some ( ( a : any ) => a . title === `${ ACTION_NAMES . FIX_LOGIC } in New Task` ) ) . toBe ( false )
102+ expect ( ( actions as any ) . some ( ( a : any ) => a . title === `${ ACTION_NAMES . FIX_LOGIC } in Current Task` ) ) . toBe (
103+ false ,
104+ )
105+ } )
106+
107+ it ( "should return empty array when no effective range" , ( ) => {
108+ ; ( EditorUtils . getEffectiveRange as jest . Mock ) . mockReturnValue ( null )
109+
110+ const actions = provider . provideCodeActions ( mockDocument , mockRange , mockContext )
111+
112+ expect ( actions ) . toEqual ( [ ] )
133113 } )
134114
135115 it ( "should handle errors gracefully" , ( ) => {
136116 const consoleErrorSpy = jest . spyOn ( console , "error" ) . mockImplementation ( ( ) => { } )
137- mockDocument . getText . mockImplementation ( ( ) => {
117+ ; ( EditorUtils . getEffectiveRange as jest . Mock ) . mockImplementation ( ( ) => {
138118 throw new Error ( "Test error" )
139119 } )
140- mockDocument . lineAt . mockReturnValue ( { text : "test" , lineNumber : 0 } )
141120
142121 const actions = provider . provideCodeActions ( mockDocument , mockRange , mockContext )
143122
144123 expect ( actions ) . toEqual ( [ ] )
145- expect ( consoleErrorSpy ) . toHaveBeenCalledWith ( "Error getting effective range :" , expect . any ( Error ) )
124+ expect ( consoleErrorSpy ) . toHaveBeenCalledWith ( "Error providing code actions :" , expect . any ( Error ) )
146125
147126 consoleErrorSpy . mockRestore ( )
148127 } )
0 commit comments