11import * as vscode from "vscode"
22import { EditorUtils } from "../EditorUtils"
33
4- // Mock VSCode API
5- jest . mock ( "vscode" , ( ) => ( {
6- Range : jest . fn ( ) . mockImplementation ( ( startLine , startChar , endLine , endChar ) => ( {
7- start : { line : startLine , character : startChar } ,
8- end : { line : endLine , character : endChar } ,
9- } ) ) ,
10- Position : jest . fn ( ) . mockImplementation ( ( line , character ) => ( {
11- line,
12- character,
13- } ) ) ,
14- workspace : {
15- getWorkspaceFolder : jest . fn ( ) ,
16- } ,
17- } ) )
4+ // Use simple classes to simulate VSCode's Range and Position behavior.
5+ jest . mock ( "vscode" , ( ) => {
6+ class MockPosition {
7+ constructor (
8+ public line : number ,
9+ public character : number ,
10+ ) { }
11+ }
12+ class MockRange {
13+ start : MockPosition
14+ end : MockPosition
15+ constructor ( start : MockPosition , end : MockPosition ) {
16+ this . start = start
17+ this . end = end
18+ }
19+ }
20+
21+ return {
22+ Range : MockRange ,
23+ Position : MockPosition ,
24+ workspace : {
25+ getWorkspaceFolder : jest . fn ( ) ,
26+ } ,
27+ window : { activeTextEditor : undefined } ,
28+ languages : {
29+ getDiagnostics : jest . fn ( ( ) => [ ] ) ,
30+ } ,
31+ }
32+ } )
1833
1934describe ( "EditorUtils" , ( ) => {
2035 let mockDocument : any
@@ -30,7 +45,7 @@ describe("EditorUtils", () => {
3045
3146 describe ( "getEffectiveRange" , ( ) => {
3247 it ( "should return selected text when available" , ( ) => {
33- const mockRange = new vscode . Range ( 0 , 0 , 0 , 10 )
48+ const mockRange = new vscode . Range ( new vscode . Position ( 0 , 0 ) , new vscode . Position ( 0 , 10 ) )
3449 mockDocument . getText . mockReturnValue ( "selected text" )
3550
3651 const result = EditorUtils . getEffectiveRange ( mockDocument , mockRange )
@@ -42,14 +57,66 @@ describe("EditorUtils", () => {
4257 } )
4358
4459 it ( "should return null for empty line" , ( ) => {
45- const mockRange = new vscode . Range ( 0 , 0 , 0 , 10 )
60+ const mockRange = new vscode . Range ( new vscode . Position ( 0 , 0 ) , new vscode . Position ( 0 , 10 ) )
4661 mockDocument . getText . mockReturnValue ( "" )
4762 mockDocument . lineAt . mockReturnValue ( { text : "" , lineNumber : 0 } )
4863
4964 const result = EditorUtils . getEffectiveRange ( mockDocument , mockRange )
5065
5166 expect ( result ) . toBeNull ( )
5267 } )
68+
69+ it ( "should expand empty selection to full lines" , ( ) => {
70+ // Simulate a caret (empty selection) on line 2 at character 5.
71+ const initialRange = new vscode . Range ( new vscode . Position ( 2 , 5 ) , new vscode . Position ( 2 , 5 ) )
72+ // Return non-empty text for any line with text (lines 1, 2, and 3).
73+ mockDocument . lineAt . mockImplementation ( ( line : number ) => {
74+ return { text : `Line ${ line } text` , lineNumber : line }
75+ } )
76+ mockDocument . getText . mockImplementation ( ( range : any ) => {
77+ // If the range is exactly the empty initial selection, return an empty string.
78+ if (
79+ range . start . line === initialRange . start . line &&
80+ range . start . character === initialRange . start . character &&
81+ range . end . line === initialRange . end . line &&
82+ range . end . character === initialRange . end . character
83+ ) {
84+ return ""
85+ }
86+ return "expanded text"
87+ } )
88+
89+ const result = EditorUtils . getEffectiveRange ( mockDocument , initialRange )
90+
91+ expect ( result ) . not . toBeNull ( )
92+ // Expected effective range: from the beginning of line 1 to the end of line 3.
93+ expect ( result ?. range . start ) . toEqual ( { line : 1 , character : 0 } )
94+ expect ( result ?. range . end ) . toEqual ( { line : 3 , character : 11 } )
95+ expect ( result ?. text ) . toBe ( "expanded text" )
96+ } )
97+ } )
98+
99+ describe ( "hasIntersectingRange" , ( ) => {
100+ it ( "should return false for ranges that only touch boundaries" , ( ) => {
101+ // Range1: [0, 0) - [0, 10) and Range2: [0, 10) - [0, 20)
102+ const range1 = new vscode . Range ( new vscode . Position ( 0 , 0 ) , new vscode . Position ( 0 , 10 ) )
103+ const range2 = new vscode . Range ( new vscode . Position ( 0 , 10 ) , new vscode . Position ( 0 , 20 ) )
104+ expect ( EditorUtils . hasIntersectingRange ( range1 , range2 ) ) . toBe ( false )
105+ } )
106+
107+ it ( "should return true for overlapping ranges" , ( ) => {
108+ // Range1: [0, 0) - [0, 15) and Range2: [0, 10) - [0, 20)
109+ const range1 = new vscode . Range ( new vscode . Position ( 0 , 0 ) , new vscode . Position ( 0 , 15 ) )
110+ const range2 = new vscode . Range ( new vscode . Position ( 0 , 10 ) , new vscode . Position ( 0 , 20 ) )
111+ expect ( EditorUtils . hasIntersectingRange ( range1 , range2 ) ) . toBe ( true )
112+ } )
113+
114+ it ( "should return false for non-overlapping ranges" , ( ) => {
115+ // Range1: [0, 0) - [0, 10) and Range2: [1, 0) - [1, 5)
116+ const range1 = new vscode . Range ( new vscode . Position ( 0 , 0 ) , new vscode . Position ( 0 , 10 ) )
117+ const range2 = new vscode . Range ( new vscode . Position ( 1 , 0 ) , new vscode . Position ( 1 , 5 ) )
118+ expect ( EditorUtils . hasIntersectingRange ( range1 , range2 ) ) . toBe ( false )
119+ } )
53120 } )
54121
55122 describe ( "getFilePath" , ( ) => {
0 commit comments