1
1
import assert from 'assert' ;
2
+ import { existsSync } from 'fs' ;
2
3
import { suite , test } from 'mocha' ;
3
4
import * as vscode from 'vscode' ;
4
5
import { adaExtState } from '../../../src/extension' ;
6
+ import { getProjectFile } from '../../../src/helpers' ;
5
7
import {
6
8
CustomTaskDefinition ,
7
9
PROJECT_FROM_CONFIG ,
8
10
createAdaTaskProvider ,
9
11
createSparkTaskProvider ,
10
12
} from '../../../src/taskProviders' ;
11
- import { activate } from '../utils' ;
13
+ import { activate , exe } from '../utils' ;
12
14
13
15
suite ( 'GPR Tasks Provider' , function ( ) {
16
+ let projectPath : string ;
17
+
14
18
this . beforeAll ( async ( ) => {
15
19
await activate ( ) ;
20
+ projectPath = await getProjectFile ( ) ;
16
21
} ) ;
17
22
23
+ /**
24
+ * Check that the list of offered Ada tasks is expected.
25
+ */
18
26
test ( 'Ada tasks list' , async ( ) => {
19
27
const prov = createAdaTaskProvider ( ) ;
20
28
const tasks = await prov . provideTasks ( ) ;
21
29
assert . notStrictEqual ( tasks , undefined ) ;
22
30
23
- const expectedTasksNames : string [ ] = [
24
- 'ada: Build current project - kind: buildProject' ,
25
- 'ada: Check current file - kind: checkFile' ,
26
- 'ada: Clean current project - kind: cleanProject' ,
27
- 'ada: Build main - main1.adb - kind: buildMain' ,
28
- 'ada: Build and run main - main1.adb - kind: buildAndRunMain' ,
29
- 'ada: Build main - test.adb - kind: buildMain' ,
30
- 'ada: Build and run main - test.adb - kind: buildAndRunMain' ,
31
- ] ;
31
+ const expectedTasksList = `
32
+ ada: Build current project - kind: buildProject
33
+ ada: Check current file - kind: checkFile
34
+ ada: Clean current project - kind: cleanProject
35
+ ada: Build main - src/main1.adb - kind: buildMain
36
+ ada: Run main - src/main1.adb - kind: runMain
37
+ ada: Build and run main - src/main1.adb - kind: buildAndRunMain
38
+ ada: Build main - src/test.adb - kind: buildMain
39
+ ada: Run main - src/test.adb - kind: runMain
40
+ ada: Build and run main - src/test.adb - kind: buildAndRunMain` . trim ( ) ;
32
41
33
- assert . strictEqual (
34
- tasks
35
- . map (
36
- ( t ) =>
37
- `${ t . source } : ${ t . name } - kind: ${
38
- ( t . definition as CustomTaskDefinition ) . configuration . kind
39
- } `
40
- )
41
- . join ( '\n' ) ,
42
- expectedTasksNames . join ( '\n' )
43
- ) ;
42
+ const actualTaskList = tasks
43
+ . map (
44
+ ( t ) =>
45
+ `${ t . source } : ${ t . name } - kind: ${
46
+ ( t . definition as CustomTaskDefinition ) . configuration . kind
47
+ } `
48
+ )
49
+ . join ( '\n' ) ;
50
+ assert . strictEqual ( actualTaskList , expectedTasksList ) ;
44
51
} ) ;
45
52
53
+ /**
54
+ * Check that the list of offered SPARK tasks is expected.
55
+ */
46
56
test ( 'Spark tasks list' , async ( ) => {
47
57
await adaExtState . adaClient . onReady ( ) ;
48
58
const prov = createSparkTaskProvider ( ) ;
@@ -65,6 +75,71 @@ suite('GPR Tasks Provider', function () {
65
75
) ;
66
76
} ) ;
67
77
78
+ test ( 'Automatic clean command' , async ( ) => {
79
+ const task = ( await vscode . tasks . fetchTasks ( { type : 'ada' } ) ) . find (
80
+ ( t ) => t . name == 'Clean current project'
81
+ ) ;
82
+ assert ( task ) ;
83
+
84
+ /**
85
+ * Check the command line of the clean task.
86
+ */
87
+ const actualCmd = getCmdLine ( task . execution as vscode . ShellExecution ) ;
88
+ /**
89
+ * The workspace doesn't define an ada.projectFile setting, so the full
90
+ * path of the project file is obtained from ALS and used in the command
91
+ * line.
92
+ */
93
+ const expectedCmd = `gprclean -P ${ projectPath } ` ;
94
+ assert . equal ( actualCmd , expectedCmd ) ;
95
+
96
+ /**
97
+ * Now try running the task.
98
+ */
99
+ const status = await runTaskAndGetResult ( task ) ;
100
+ assert . equal ( status , 0 ) ;
101
+ assert ( ! existsSync ( 'obj/main1' + exe ) ) ;
102
+ } ) ;
103
+
104
+ test ( 'Automatic buildMain command' , async ( ) => {
105
+ const task = ( await vscode . tasks . fetchTasks ( { type : 'ada' } ) ) . find (
106
+ ( t ) => t . name == 'Build main - src/main1.adb'
107
+ ) ;
108
+ assert ( task ) ;
109
+
110
+ /**
111
+ * Check the command line of the build task.
112
+ */
113
+ const actualCmd = getCmdLine ( task . execution as vscode . ShellExecution ) ;
114
+ /**
115
+ * The workspace doesn't define an ada.projectFile setting, so the full
116
+ * path of the project file is obtained from ALS and used in the command
117
+ * line.
118
+ */
119
+ const expectedCmd = `gprbuild -P ${ projectPath } src/main1.adb -cargs:ada -gnatef` ;
120
+ assert . equal ( actualCmd , expectedCmd ) ;
121
+
122
+ /**
123
+ * Now try running the task.
124
+ */
125
+ const status = await runTaskAndGetResult ( task ) ;
126
+ assert . equal ( status , 0 ) ;
127
+
128
+ console . info ( `cwd=${ process . cwd ( ) } ` ) ;
129
+ /**
130
+ * Check that the executable is produced. The project defines a
131
+ * different name for the executable produced by main1.adb.
132
+ */
133
+ assert ( vscode . workspace . workspaceFolders ) ;
134
+ assert (
135
+ existsSync ( `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath } /obj/main1exec` + exe )
136
+ ) ;
137
+ } ) ;
138
+
139
+ /**
140
+ * Check that starting from a User-defined task, the task provider is able
141
+ * to resolve it into a complete task with the expected command line.
142
+ */
68
143
test ( 'Resolving task' , async ( ) => {
69
144
const prov = createAdaTaskProvider ( ) ;
70
145
@@ -73,6 +148,7 @@ suite('GPR Tasks Provider', function () {
73
148
configuration : {
74
149
kind : 'buildProject' ,
75
150
projectFile : PROJECT_FROM_CONFIG ,
151
+ args : [ '-d' ] ,
76
152
} ,
77
153
} ;
78
154
const task = new vscode . Task ( def , vscode . TaskScope . Workspace , 'My Task' , 'ada' ) ;
@@ -82,14 +158,28 @@ suite('GPR Tasks Provider', function () {
82
158
assert ( resolved . execution ) ;
83
159
84
160
const exec = resolved . execution as vscode . ShellExecution ;
85
- const actualCmd = [ exec . command ] . concat ( exec . args ) . join ( ' ' ) ;
86
161
87
- const expectedCmd = `gprbuild -P ${ def . configuration . projectFile } "-cargs:ada" -gnatef` ;
162
+ const actualCmd = getCmdLine ( exec ) ;
163
+
164
+ /**
165
+ * This task defines the projectFile field as config:ada.projectFile so
166
+ * this is reflected as is in the command line. However running this
167
+ * task will fail because the workspace doesn't define the
168
+ * ada.projectFile setting.
169
+ */
170
+ const expectedCmd = 'gprbuild -P ${config:ada.projectFile} -d -cargs:ada -gnatef' ;
88
171
89
172
assert . strictEqual ( actualCmd , expectedCmd ) ;
173
+
174
+ const status = runTaskAndGetResult ( resolved ) ;
175
+ /**
176
+ * The task should fail because the ada.projectFile is not set so the
177
+ * command line cannot be resolved.
178
+ */
179
+ assert . notEqual ( status , 0 ) ;
90
180
} ) ;
91
181
92
- test ( 'Resolving task with main ' , async ( ) => {
182
+ test ( 'Resolving task buildMain ' , async ( ) => {
93
183
const prov = createAdaTaskProvider ( ) ;
94
184
95
185
const def : CustomTaskDefinition = {
@@ -107,24 +197,26 @@ suite('GPR Tasks Provider', function () {
107
197
assert ( resolved . execution ) ;
108
198
109
199
const exec = resolved . execution as vscode . ShellExecution ;
110
- const actualCmd = [ exec . command ] . concat ( exec . args ) . join ( ' ' ) ;
200
+ const actualCmd = getCmdLine ( exec ) ;
111
201
112
- const expectedCmd = `gprbuild -P ${ def . configuration . projectFile } ${
113
- def . configuration . main ?? ''
114
- } "-cargs:ada" -gnatef`;
202
+ assert ( def . configuration . main ) ;
203
+ const expectedCmd =
204
+ `gprbuild -P \${config:ada.projectFile} ${ def . configuration . main } ` +
205
+ `-cargs:ada -gnatef` ;
115
206
116
207
assert . strictEqual ( actualCmd , expectedCmd ) ;
117
208
} ) ;
118
209
119
- test ( 'Resolving task with run main ' , async ( ) => {
210
+ test ( 'Resolving task runMain ' , async ( ) => {
120
211
const prov = createAdaTaskProvider ( ) ;
121
212
122
213
const def : CustomTaskDefinition = {
123
214
type : 'ada' ,
124
215
configuration : {
125
- kind : 'buildAndRunMain ' ,
216
+ kind : 'runMain ' ,
126
217
projectFile : PROJECT_FROM_CONFIG ,
127
218
main : 'src/main1.adb' ,
219
+ mainArgs : [ 'arg1' , 'arg2' ] ,
128
220
} ,
129
221
} ;
130
222
const task = new vscode . Task ( def , vscode . TaskScope . Workspace , 'My Task' , 'ada' ) ;
@@ -134,14 +226,84 @@ suite('GPR Tasks Provider', function () {
134
226
assert ( resolved . execution ) ;
135
227
136
228
const exec = resolved . execution as vscode . ShellExecution ;
137
- const actualCmd = [ exec . command ] . concat ( exec . args ) . join ( ' ' ) ;
229
+ const actualCmd = getCmdLine ( exec ) ;
138
230
139
231
// Note that the executable is named differently than the source file
140
232
// via project attributes
141
- const expectedCmd = `gprbuild -P ${ def . configuration . projectFile } ${
142
- def . configuration . main ?? ''
143
- } "-cargs:ada" -gnatef && obj/main1exec${ process . platform == 'win32' ? '.exe' : '' } `;
233
+ assert ( def . configuration . main ) ;
234
+ const expectedCmd = `obj/main1exec${ exe } arg1 arg2` ;
144
235
145
236
assert . strictEqual ( actualCmd , expectedCmd ) ;
146
237
} ) ;
238
+
239
+ test ( 'buildAndRunMain task' , async ( ) => {
240
+ const adaTasks = await vscode . tasks . fetchTasks ( { type : 'ada' } ) ;
241
+ const task = adaTasks . find ( ( v ) => v . name == 'Build and run main - src/main1.adb' ) ;
242
+ assert ( task ) ;
243
+
244
+ const execStatus : number | undefined = await runTaskAndGetResult ( task ) ;
245
+
246
+ assert . equal ( execStatus , 0 ) ;
247
+ } ) ;
248
+
249
+ /**
250
+ * Test that buildAndRunMain fails when configured with non-existing tasks
251
+ */
252
+ test ( 'buildAndRunMain failure' , async ( ) => {
253
+ const prov = createAdaTaskProvider ( ) ;
254
+ let def : CustomTaskDefinition = {
255
+ type : 'ada' ,
256
+ configuration : {
257
+ kind : 'buildAndRunMain' ,
258
+ buildTask : 'non existing task' ,
259
+ } ,
260
+ } ;
261
+ let task = new vscode . Task ( def , vscode . TaskScope . Workspace , 'Task 1' , 'ada' ) ;
262
+ let resolved = await prov . resolveTask ( task ) ;
263
+ assert ( resolved ) ;
264
+ /**
265
+ * The expected code when errors occur before the invocation of the
266
+ * build and run tasks is 2.
267
+ */
268
+ assert . equal ( await runTaskAndGetResult ( resolved ) , 2 ) ;
269
+
270
+ def = {
271
+ type : 'ada' ,
272
+ configuration : {
273
+ kind : 'buildAndRunMain' ,
274
+ buildTask : 'ada: Build current project' , // Existing build task
275
+ runTask : 'non existing task' ,
276
+ } ,
277
+ } ;
278
+ task = new vscode . Task ( def , vscode . TaskScope . Workspace , 'Task 2' , 'ada' ) ;
279
+ resolved = await prov . resolveTask ( task ) ;
280
+ assert ( resolved ) ;
281
+ assert . equal ( await runTaskAndGetResult ( resolved ) , 2 ) ;
282
+ } ) ;
147
283
} ) ;
284
+
285
+ async function runTaskAndGetResult ( task : vscode . Task ) : Promise < number | undefined > {
286
+ return await new Promise ( ( resolve ) => {
287
+ const disposable = vscode . tasks . onDidEndTaskProcess ( ( e ) => {
288
+ if ( e . execution . task == task ) {
289
+ disposable . dispose ( ) ;
290
+ resolve ( e . exitCode ) ;
291
+ }
292
+ } ) ;
293
+
294
+ void vscode . tasks . executeTask ( task ) ;
295
+ } ) ;
296
+ }
297
+
298
+ function getCmdLine ( exec : vscode . ShellExecution ) {
299
+ return [ exec . command ]
300
+ . concat ( exec . args )
301
+ . map ( ( s ) => {
302
+ if ( typeof s == 'object' ) {
303
+ return s . value ;
304
+ } else {
305
+ return s ;
306
+ }
307
+ } )
308
+ . join ( ' ' ) ;
309
+ }
0 commit comments