@@ -4,7 +4,6 @@ import * as path from "path";
4
4
import * as yaml from "js-yaml" ;
5
5
import * as vscode from "vscode" ;
6
6
import { TestCaseFixture } from "../../TestCase" ;
7
- import { ThatMark } from "../../ThatMark" ;
8
7
import NavigationMap from "../../NavigationMap" ;
9
8
import * as sinon from "sinon" ;
10
9
import { Clipboard } from "../../Clipboard" ;
@@ -16,6 +15,7 @@ import {
16
15
} from "../../toPlainObject" ;
17
16
import { walkFilesSync } from "./walkSync" ;
18
17
import { enableDebugLog } from "../../debug" ;
18
+ import { getCursorlessApi , getParseTreeApi } from "../../getExtensionApi" ;
19
19
20
20
function createPosition ( position : PositionPlainObject ) {
21
21
return new vscode . Position ( position . line , position . character ) ;
@@ -28,6 +28,8 @@ function createSelection(selection: SelectionPlainObject): vscode.Selection {
28
28
}
29
29
30
30
suite ( "recorded test cases" , async function ( ) {
31
+ this . timeout ( "100s" ) ;
32
+ this . retries ( 3 ) ;
31
33
const directory = path . join (
32
34
__dirname ,
33
35
"../../../src/test/suite/fixtures/recorded"
@@ -39,139 +41,89 @@ suite("recorded test cases", async function () {
39
41
sinon . restore ( ) ;
40
42
} ) ;
41
43
42
- let lastLanguageId : string ;
43
-
44
- files . forEach ( async ( file ) => {
45
- test ( file . split ( "." ) [ 0 ] , async function ( ) {
46
- this . timeout ( 100000 ) ;
47
- const cursorless = vscode . extensions . getExtension ( "pokey.cursorless" ) ;
48
-
49
- if ( cursorless == null ) {
50
- throw new Error ( "Could not get cursorless extension" ) ;
51
- }
52
-
53
- const cursorlessApi : {
54
- thatMark : ThatMark ;
55
- sourceMark : ThatMark ;
56
- navigationMap : NavigationMap ;
57
- addDecorations : ( ) => void ;
58
- } = await cursorless . activate ( ) ;
59
- const buffer = await fsp . readFile ( file ) ;
60
- const fixture = yaml . load ( buffer . toString ( ) ) as TestCaseFixture ;
61
- const excludeFields : string [ ] = [ ] ;
62
-
63
- await vscode . commands . executeCommand ( "workbench.action.closeAllEditors" ) ;
64
- const document = await vscode . workspace . openTextDocument ( {
65
- language : fixture . languageId ,
66
- content : fixture . initialState . documentContents ,
67
- } ) ;
68
- const editor = await vscode . window . showTextDocument ( document ) ;
69
-
70
- // Sleep on changing language is necessary otherwise the tree sitter
71
- // will throw an exception on getNodeAtLocation()
72
- if ( lastLanguageId !== document . languageId ) {
73
- if ( lastLanguageId != null ) {
74
- await new Promise ( ( resolve ) => setTimeout ( resolve , 200 ) ) ;
75
- }
76
- lastLanguageId = document . languageId ;
77
- }
78
-
79
- editor . selections = fixture . initialState . selections . map ( createSelection ) ;
80
-
81
- if ( fixture . initialState . thatMark ) {
82
- const initialThatMark = fixture . initialState . thatMark . map ( ( mark ) => ( {
83
- selection : createSelection ( mark ) ,
84
- editor,
85
- } ) ) ;
86
- cursorlessApi . thatMark . set ( initialThatMark ) ;
87
- }
88
- if ( fixture . initialState . sourceMark ) {
89
- const initialSourceMark = fixture . initialState . sourceMark . map (
90
- ( mark ) => ( {
91
- selection : createSelection ( mark ) ,
92
- editor,
93
- } )
94
- ) ;
95
- cursorlessApi . sourceMark . set ( initialSourceMark ) ;
96
- }
97
-
98
- if ( fixture . initialState . clipboard ) {
99
- let mockClipboard = fixture . initialState . clipboard ;
100
- sinon . replace ( Clipboard , "readText" , async ( ) => mockClipboard ) ;
101
- sinon . replace ( Clipboard , "writeText" , async ( value : string ) => {
102
- mockClipboard = value ;
103
- } ) ;
104
- } else {
105
- excludeFields . push ( "clipboard" ) ;
106
- }
107
-
108
- // Wait for cursorless to set up decorations
109
- cursorlessApi . addDecorations ( ) ;
110
-
111
- // Assert that recorded decorations are present
112
- const assertDecorations = ( ) => {
113
- Object . entries ( fixture . marks ) . forEach ( ( [ key , token ] ) => {
114
- const { color, character } = NavigationMap . splitKey ( key ) ;
115
- const currentToken = cursorlessApi . navigationMap . getToken (
116
- color ,
117
- character
118
- ) ;
119
- assert (
120
- currentToken != null ,
121
- `Mark "${ color } ${ character } " not found`
122
- ) ;
123
- assert . deepStrictEqual ( rangeToPlainObject ( currentToken . range ) , token ) ;
124
- } ) ;
125
- } ;
126
-
127
- // Tried three times, sleep 100ms between each
128
- await tryAndRetry ( assertDecorations , 3 , 100 ) ;
129
-
130
- const returnValue = await vscode . commands . executeCommand (
131
- "cursorless.command" ,
132
- fixture . spokenForm ,
133
- fixture . command . actionName ,
134
- fixture . command . partialTargets ,
135
- ...fixture . command . extraArgs
136
- ) ;
137
-
138
- // TODO Visible ranges are not asserted, see:
139
- // https://github.com/pokey/cursorless-vscode/issues/160
140
- const { visibleRanges, ...resultState } = await takeSnapshot (
141
- cursorlessApi . thatMark ,
142
- cursorlessApi . sourceMark ,
143
- excludeFields
144
- ) ;
145
-
146
- assert . deepStrictEqual (
147
- resultState ,
148
- fixture . finalState ,
149
- "Unexpected final state"
150
- ) ;
151
-
152
- assert . deepStrictEqual (
153
- returnValue ,
154
- fixture . returnValue ,
155
- "Unexpected return value"
156
- ) ;
157
- } ) ;
158
- } ) ;
44
+ files . forEach ( ( file ) => test ( file . split ( "." ) [ 0 ] , ( ) => runTest ( file ) ) ) ;
159
45
} ) ;
160
46
161
- async function tryAndRetry (
162
- callback : ( ) => void ,
163
- numberOfThries : number ,
164
- sleepTime : number
165
- ) {
166
- while ( true ) {
167
- try {
168
- return callback ( ) ;
169
- } catch ( error ) {
170
- if ( numberOfThries === 0 ) {
171
- throw error ;
172
- }
173
- numberOfThries -- ;
174
- await new Promise ( ( resolve ) => setTimeout ( resolve , sleepTime ) ) ;
175
- }
47
+ async function runTest ( file : string ) {
48
+ const buffer = await fsp . readFile ( file ) ;
49
+ const fixture = yaml . load ( buffer . toString ( ) ) as TestCaseFixture ;
50
+ const excludeFields : string [ ] = [ ] ;
51
+
52
+ const cursorlessApi = await getCursorlessApi ( ) ;
53
+ const parseTreeApi = await getParseTreeApi ( ) ;
54
+
55
+ await vscode . commands . executeCommand ( "workbench.action.closeAllEditors" ) ;
56
+ const document = await vscode . workspace . openTextDocument ( {
57
+ language : fixture . languageId ,
58
+ content : fixture . initialState . documentContents ,
59
+ } ) ;
60
+ const editor = await vscode . window . showTextDocument ( document ) ;
61
+
62
+ await parseTreeApi . loadLanguage ( document . languageId ) ;
63
+
64
+ editor . selections = fixture . initialState . selections . map ( createSelection ) ;
65
+
66
+ if ( fixture . initialState . thatMark ) {
67
+ const initialThatMark = fixture . initialState . thatMark . map ( ( mark ) => ( {
68
+ selection : createSelection ( mark ) ,
69
+ editor,
70
+ } ) ) ;
71
+ cursorlessApi . thatMark . set ( initialThatMark ) ;
72
+ }
73
+ if ( fixture . initialState . sourceMark ) {
74
+ const initialSourceMark = fixture . initialState . sourceMark . map ( ( mark ) => ( {
75
+ selection : createSelection ( mark ) ,
76
+ editor,
77
+ } ) ) ;
78
+ cursorlessApi . sourceMark . set ( initialSourceMark ) ;
79
+ }
80
+
81
+ if ( fixture . initialState . clipboard ) {
82
+ let mockClipboard = fixture . initialState . clipboard ;
83
+ sinon . replace ( Clipboard , "readText" , async ( ) => mockClipboard ) ;
84
+ sinon . replace ( Clipboard , "writeText" , async ( value : string ) => {
85
+ mockClipboard = value ;
86
+ } ) ;
87
+ } else {
88
+ excludeFields . push ( "clipboard" ) ;
176
89
}
90
+
91
+ // Wait for cursorless to set up decorations
92
+ cursorlessApi . addDecorations ( ) ;
93
+
94
+ // Assert that recorded decorations are present
95
+ Object . entries ( fixture . marks ) . forEach ( ( [ key , token ] ) => {
96
+ const { color, character } = NavigationMap . splitKey ( key ) ;
97
+ const currentToken = cursorlessApi . navigationMap . getToken ( color , character ) ;
98
+ assert ( currentToken != null , `Mark "${ color } ${ character } " not found` ) ;
99
+ assert . deepStrictEqual ( rangeToPlainObject ( currentToken . range ) , token ) ;
100
+ } ) ;
101
+
102
+ const returnValue = await vscode . commands . executeCommand (
103
+ "cursorless.command" ,
104
+ fixture . spokenForm ,
105
+ fixture . command . actionName ,
106
+ fixture . command . partialTargets ,
107
+ ...fixture . command . extraArgs
108
+ ) ;
109
+
110
+ // TODO Visible ranges are not asserted, see:
111
+ // https://github.com/pokey/cursorless-vscode/issues/160
112
+ const { visibleRanges, ...resultState } = await takeSnapshot (
113
+ cursorlessApi . thatMark ,
114
+ cursorlessApi . sourceMark ,
115
+ excludeFields
116
+ ) ;
117
+
118
+ assert . deepStrictEqual (
119
+ resultState ,
120
+ fixture . finalState ,
121
+ "Unexpected final state"
122
+ ) ;
123
+
124
+ assert . deepStrictEqual (
125
+ returnValue ,
126
+ fixture . returnValue ,
127
+ "Unexpected return value"
128
+ ) ;
177
129
}
0 commit comments