1
1
import * as vscode from "vscode"
2
+ import { CompletionItem , Position } from "vscode"
2
3
import * as assert from "node:assert"
3
4
import { BaseTestSuite } from "./BaseTestSuite"
4
5
import type { TestCase } from "./TestParser"
5
- import { CompletionItem } from "vscode"
6
6
7
7
suite ( "Completion Test Suite" , ( ) => {
8
8
const testSuite = new ( class extends BaseTestSuite {
@@ -25,20 +25,20 @@ suite("Completion Test Suite", () => {
25
25
position ,
26
26
)
27
27
28
- const line = this . document . lineAt ( position . line )
29
- const textBeforeCursor = line . text . slice ( 0 , position . character )
28
+ const textBeforeCursor = this . findWordBeforeCursor ( position )
29
+
30
30
// Filtering items to match better completion for this test
31
- let items = completions . items . filter ( item => {
31
+ const items = completions . items . filter ( item => {
32
32
const label = typeof item . label === "object" ? item . label . label : item . label
33
33
return label . includes ( textBeforeCursor . trim ( ) )
34
34
} )
35
35
36
- if ( completions . items . length < = 0 ) {
36
+ if ( completions . items . length == = 0 ) {
37
37
throw new Error ( "No completions available for this test" )
38
38
}
39
39
40
40
if ( items . length <= 0 ) {
41
- items = completions . items
41
+ return completions . items [ 0 ]
42
42
}
43
43
44
44
return items [ 0 ]
@@ -76,20 +76,51 @@ suite("Completion Test Suite", () => {
76
76
test ( `Completion Select: ${ testCase . name } ` , async ( ) => {
77
77
const completion = await this . getFilteredCompletion ( testCase . input )
78
78
await this . applyCompletionItem ( completion )
79
+
80
+ const cursor = this . editor . selection . active
79
81
const editorText = this . document . getText ( )
82
+ const editorTextWithCursor = this . insertCursor ( editorText , cursor )
83
+
80
84
const expected = testCase . expected
81
85
82
86
if ( BaseTestSuite . UPDATE_SNAPSHOTS ) {
83
87
this . updates . push ( {
84
88
filePath : testFile ,
85
89
testName : testCase . name ,
86
- actual : editorText ,
90
+ actual : editorTextWithCursor ,
87
91
} )
88
92
} else {
89
- assert . deepStrictEqual ( editorText , expected )
93
+ assert . deepStrictEqual ( editorTextWithCursor , expected )
90
94
}
91
95
} )
92
96
}
97
+
98
+ protected findWordBeforeCursor ( position : Position ) : string {
99
+ const line = this . document . lineAt ( position . line )
100
+ const textBeforeCursor = line . text . slice ( 0 , position . character )
101
+
102
+ const letterRe = new RegExp ( / [ a - z ] / i)
103
+
104
+ for ( let i = textBeforeCursor . length ; i >= 0 ; i -- ) {
105
+ const symbol = textBeforeCursor [ i ]
106
+ if ( ! letterRe . test ( symbol ) ) {
107
+ return textBeforeCursor . slice ( i + 1 , line . text . length )
108
+ }
109
+ }
110
+
111
+ return line . text
112
+ }
113
+
114
+ protected insertCursor ( text : string , position : Position ) : string {
115
+ const lines = text . split ( / \r ? \n / )
116
+ if ( position . line >= lines . length ) return text
117
+
118
+ const line = lines [ position . line ]
119
+ lines [ position . line ] =
120
+ line . slice ( 0 , position . character ) + "<caret>" + line . slice ( position . character )
121
+
122
+ return lines . join ( "\n" )
123
+ }
93
124
} ) ( )
94
125
95
126
suiteSetup ( async function ( ) {
0 commit comments