Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/inline/fixing.stest.ts
13388 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
import assert from 'assert';
6
import { Intent } from '../../src/extension/common/constants';
7
import '../../src/extension/intents/node/allIntents';
8
import { ssuite, stest } from '../base/stest';
9
import { KnownDiagnosticProviders } from '../simulation/diagnosticProviders';
10
import { forInlineChatIntent, simulateInlineChatWithStrategy } from '../simulation/inlineChatSimulator';
11
import { assertLessDiagnosticsAsync, assertNoDiagnosticsAsync, getWorkspaceDiagnostics } from '../simulation/outcomeValidators';
12
import { assertConversationalOutcome, assertInlineEdit, assertNoOccurrence, assertOccursOnce, fromFixture, toFile } from '../simulation/stestUtil';
13
14
15
forInlineChatIntent((strategy, nonExtensionConfigurations, suffix) => {
16
17
ssuite({ title: `fix${suffix}`, subtitle: 'ruff', location: 'inline' }, () => {
18
stest({ description: `Ruff(E231) Missing whitespace after ':'`, language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
19
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
20
files: [fromFixture('fixing/ruff/ruff_error_E231.py')],
21
queries: [
22
{
23
file: 'ruff_error_E231.py',
24
selection: [5, 1, 5, 10],
25
query: [
26
`/fix Missing whitespace after ':'`,
27
`To fix the problem.`
28
].join('\n'),
29
expectedIntent: Intent.Fix,
30
diagnostics: 'ruff',
31
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'ruff')
32
}
33
]
34
});
35
});
36
});
37
38
ssuite({ title: `fix${suffix}`, subtitle: 'TSC', location: 'inline' }, () => {
39
stest({ description: 'Error 2322 - type undefined is not assignable to type', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
40
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
41
files: [fromFixture('fixing/typescript/tsc_error_2322.ts')],
42
queries: [
43
{
44
file: 'tsc_error_2322.ts',
45
selection: [37, 10, 37, 10],
46
query: [
47
`/fix Type 'RangeMapping[] | undefined' is not assignable to type 'RangeMapping[]'. `,
48
` Type 'undefined' is not assignable to type 'RangeMapping[]'.`
49
].join('\n'),
50
expectedIntent: Intent.Fix,
51
diagnostics: 'tsc',
52
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
53
}
54
]
55
});
56
});
57
58
stest({ description: '22222 Error 2322 - type undefined is not assignable to type', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
59
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
60
files: [fromFixture('fixing/typescript/tsc_error_2322.ts')],
61
queries: [
62
{
63
file: 'tsc_error_2322.ts',
64
selection: [37, 10, 37, 10],
65
query: [
66
`/fix Type 'RangeMapping[] | undefined' is not assignable to type 'RangeMapping[]'. `,
67
` Type 'undefined' is not assignable to type 'RangeMapping[]'.`
68
].join('\n'),
69
expectedIntent: Intent.Fix,
70
diagnostics: 'tsc',
71
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
72
}
73
]
74
});
75
});
76
77
stest({ description: 'Error 1015 - parameter cannot have question mark and initializer, with corresponding diagnostics', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
78
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
79
files: [fromFixture('fixing/typescript/tsc_error_1015.ts')],
80
queries: [
81
{
82
file: 'tsc_error_1015.ts',
83
selection: [0, 24, 0, 24],
84
query: `/fix Parameter cannot have question mark and initializer.`,
85
expectedIntent: Intent.Fix,
86
diagnostics: 'tsc',
87
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
88
}
89
]
90
});
91
});
92
93
stest({ description: 'Error 1015 - parameter cannot have question mark and initializer, without corresponding diagnostics', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
94
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
95
files: [fromFixture('fixing/typescript/tsc_error_1015.ts')],
96
queries: [
97
{
98
file: 'tsc_error_1015.ts',
99
selection: [0, 24, 0, 24],
100
query: `/fix Parameter cannot have question mark and initializer.`,
101
expectedIntent: Intent.Fix,
102
diagnostics: 'tsc',
103
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
104
}
105
]
106
});
107
});
108
109
stest({ description: 'Error 2420 - incorrect interface implementation', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
110
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
111
files: [
112
fromFixture('fixing/typescript/tsc_error_2420/file0.ts'),
113
fromFixture('fixing/typescript/tsc_error_2420/file1.ts')
114
],
115
queries: [
116
{
117
file: 'file0.ts',
118
selection: [2, 6, 2, 6],
119
query: [
120
`/fix Class 'Far' incorrectly implements interface 'IFar'.`,
121
` Property 'foo' is missing in type 'Far' but required in type 'IFar'.`
122
].join('\n'),
123
expectedIntent: Intent.Fix,
124
diagnostics: 'tsc',
125
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
126
}
127
]
128
});
129
});
130
131
stest({ description: 'Error 2420 - incorrect interface implementation, with related information', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
132
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
133
files: [
134
fromFixture('fixing/typescript/tsc_error_2420/file0.ts'),
135
fromFixture('fixing/typescript/tsc_error_2420/file1.ts')
136
],
137
queries: [
138
{
139
file: 'file0.ts',
140
selection: [2, 6, 9, 1],
141
query: [
142
`/fix Class 'Far' incorrectly implements interface 'IFar'.`,
143
` Property 'foo' is missing in type 'Far' but required in type 'IFar'.`
144
].join('\n'),
145
expectedIntent: Intent.Fix,
146
diagnostics: 'tsc',
147
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
148
}
149
]
150
});
151
});
152
153
stest({ description: 'Error 2391 - function implementation is missing or not immediately following the declaration', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
154
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
155
files: [fromFixture('fixing/typescript/tsc_error_2391.ts')],
156
queries: [
157
{
158
file: 'tsc_error_2391.ts',
159
selection: [6, 4, 6, 13],
160
query: [
161
`/fix Function implementation is missing or not immediately following the declaration.`,
162
`'function1', which lacks return-type annotation, implicitly has an 'any' return type.`
163
].join('\n'),
164
expectedIntent: Intent.Fix,
165
diagnostics: 'tsc',
166
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
167
}
168
]
169
});
170
});
171
172
stest({ description: 'Error 2454 - variable is used before being assigned', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
173
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
174
files: [fromFixture('fixing/typescript/tsc_error_2454.ts')],
175
queries: [
176
{
177
file: 'tsc_error_2454.ts',
178
selection: [21, 6, 21, 24],
179
query: `/fix Variable 'telemetryEventName' is used before being assigned.`,
180
expectedIntent: Intent.Fix,
181
diagnostics: 'tsc',
182
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
183
}
184
]
185
});
186
});
187
188
stest({ description: 'Error 2339 - property does not exist on type 1', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
189
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
190
files: [fromFixture('fixing/typescript/tsc_error_2339_1.ts')],
191
queries: [
192
{
193
file: 'tsc_error_2339_1.ts',
194
selection: [16, 21, 16, 29],
195
query: `/fix Property 'response' does not exist on type 'DocContext'.`,
196
expectedIntent: Intent.Fix,
197
diagnostics: 'tsc',
198
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
199
}
200
]
201
});
202
});
203
204
stest({ description: 'Error 2554 - expected m arguments, but got n.', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
205
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
206
files: [fromFixture('fixing/typescript/tsc_error_2554.ts')],
207
queries: [
208
{
209
file: 'tsc_error_2554.ts',
210
selection: [8, 7, 8, 21],
211
query: `/fix Expected 1 arguments, but got 0.`,
212
expectedIntent: Intent.Fix,
213
diagnostics: 'tsc',
214
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
215
}
216
]
217
});
218
});
219
220
stest({ description: 'Error 2341 - property is private and only accessible within class', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
221
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
222
files: [fromFixture('fixing/typescript/tsc_error_2341.ts')],
223
queries: [
224
{
225
file: 'tsc_error_2341.ts',
226
selection: [7, 8, 7, 10],
227
query: `/fix Property 'hi' is private and only accessible within class 'Bar'.`,
228
expectedIntent: Intent.Fix,
229
diagnostics: 'tsc',
230
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
231
}
232
]
233
});
234
});
235
236
stest({ description: 'Error 2355 - a function whose declared type is neither undefined, void, nor any must return a value.', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
237
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
238
files: [fromFixture('fixing/typescript/tsc_error_2355.ts')],
239
queries: [
240
{
241
file: 'tsc_error_2355.ts',
242
selection: [2, 37, 2, 44],
243
query: `/fix A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.`,
244
expectedIntent: Intent.Fix,
245
diagnostics: 'tsc',
246
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
247
}
248
]
249
});
250
});
251
252
// Inspired by case 55 in /fix dataset version 10
253
// The fix in nice_egg_479lg7cb9q was too big, it was not a minimal change, and it was incorrect
254
stest({ description: 'Error 2339 - (AML-10-55) property does not exist on type 2', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
255
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
256
files: [fromFixture('fixing/typescript/tsc_error_2339_2.ts')],
257
queries: [
258
{
259
file: 'tsc_error_2339_2.ts',
260
selection: [5, 8, 5, 8],
261
query: `/fix Property 'send' does not exist on type 'AutoUpdater'.`,
262
expectedIntent: Intent.Fix,
263
diagnostics: 'tsc',
264
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
265
}
266
]
267
});
268
});
269
270
// Inspired by case 98 in /fix dataset version 10
271
// Copilot proposed an incorrect fix, it should have added an additional method, instead it added a catch statement
272
stest({ description: 'Error 2339 - (AML-10-98) property does not exist on type 3', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
273
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
274
files: [fromFixture('fixing/typescript/tsc_error_2339_3.ts')],
275
queries: [
276
{
277
file: 'tsc_error_2339_3.ts',
278
selection: [65, 11, 65, 11],
279
query: `/fix Property 'send' does not exist on type 'IpcRendererWithCommands'.`,
280
expectedIntent: Intent.Fix,
281
diagnostics: 'tsc',
282
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
283
}
284
]
285
});
286
});
287
288
289
// Add a missing impor at the right place
290
stest({ description: 'Error 2304 - can not find name', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
291
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
292
files: [
293
fromFixture('fixing/typescript/tsc_error_2304/file0.ts'),
294
fromFixture('fixing/typescript/tsc_error_2304/file1.ts')
295
],
296
queries: [
297
{
298
file: 'file0.ts',
299
selection: [10, 26, 10, 26],
300
query: `/fix Cannot find name 'readFileSync'.`,
301
expectedIntent: Intent.Fix,
302
diagnostics: 'tsc',
303
validate: async (outcome, workspace, accessor) => {
304
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
305
if (outcome.type === 'inlineEdit') {
306
const indexOfFsImport = outcome.fileContents.indexOf(`import { readFileSync } from 'fs';`);
307
assert.ok(indexOfFsImport >= 0, 'contains readFileSync import');
308
const indexOfDeclare = outcome.fileContents.indexOf(`declare function`);
309
assert.ok(indexOfFsImport < indexOfDeclare, 'is before declare function');
310
}
311
}
312
}
313
]
314
});
315
});
316
317
stest({ description: 'Error 2304 - (AML-10-14) can not find module', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
318
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
319
files: [fromFixture('fixing/typescript/tsc_error_2304_1.ts')],
320
queries: [
321
{
322
file: 'tsc_error_2304_1.ts',
323
selection: [25, 1, 25, 1],
324
query: `/fix Cannot find name 'expect'.`,
325
expectedIntent: Intent.Fix,
326
diagnostics: 'tsc',
327
validate: async (outcome, workspace, accessor) => {
328
assert.strictEqual(outcome.type, 'inlineEdit');
329
const diagnostics = await getWorkspaceDiagnostics(accessor, workspace, 'tsc');
330
const filtered = diagnostics.filter(d => d.code !== 2307 && d.code !== 2305); // filter module not found, module has not exported member
331
assert.equal(filtered.length, 0, 'only module not found diagnostics');
332
}
333
}
334
]
335
});
336
});
337
338
stest({ description: 'Error 2307 - can not find module', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
339
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
340
files: [fromFixture('fixing/typescript/tsc_error_2307_can_not_find_module.ts')],
341
queries: [
342
{
343
file: 'tsc_error_2307_can_not_find_module.ts',
344
selection: [0, 25, 0, 40],
345
query: [
346
`/fix Cannot find module '@angular/core' or its corresponding type declarations..`,
347
].join('\n'),
348
expectedIntent: Intent.Fix,
349
diagnostics: 'tsc',
350
validate: async (outcome, workspace, accessor) => {
351
assertConversationalOutcome(outcome);
352
const match = outcome.chatResponseMarkdown.match(/```(ps|bash)[.\n\r]*npm install.*@angular\/core/);
353
assert.ok(match, 'contains npm install @angular/core');
354
}
355
}
356
]
357
});
358
});
359
360
// Inspired by case 64 of /fix dataset version 10
361
// The fix was not correct, it just added a new line and did not resolve the error
362
stest({ description: 'Error 18047 - (AML-10-64) possibly null', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
363
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
364
files: [fromFixture('fixing/typescript/tsc_error_18047.ts')],
365
queries: [
366
{
367
file: 'tsc_error_18047.ts',
368
selection: [4, 4, 4, 4],
369
query: `/fix 'measurementSpan' is possibly 'null'.`,
370
expectedIntent: Intent.Fix,
371
diagnostics: 'tsc',
372
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
373
}
374
]
375
});
376
});
377
378
// Inspired by case 23 of /fix dataset version 10
379
stest({ description: 'Error 7006 - (AML-10-23) implicitly has any type', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
380
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
381
files: [fromFixture('fixing/typescript/tsc_error_7006.ts')],
382
queries: [
383
{
384
file: 'tsc_error_7006.ts',
385
selection: [1, 53, 1, 53],
386
query: `/fix Parameter 'data' implicitly has an 'any' type.`,
387
expectedIntent: Intent.Fix,
388
diagnostics: 'tsc',
389
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
390
}
391
]
392
});
393
});
394
395
// Inspired by case 1 of /fix dataset version 8
396
stest({ description: 'Error 18047 - (AML-8-1) property does not exist on type window', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
397
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
398
files: [fromFixture('fixing/typescript/tsc_error_2339_4.ts')],
399
queries: [
400
{
401
file: 'tsc_error_2339_4.ts',
402
selection: [1, 12, 1, 12],
403
query: `/fix Property 'lx' does not exist on type 'Window & typeof globalThis'.`,
404
expectedIntent: Intent.Fix,
405
diagnostics: 'tsc',
406
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
407
}
408
]
409
});
410
});
411
412
// Inspired by case 86 of /fix dataset version 10
413
stest({ description: 'Error 18048 - (AML-10-86) possibly undefined', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
414
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
415
files: [fromFixture('fixing/typescript/tsc_error_18048.ts')],
416
queries: [
417
{
418
file: 'tsc_error_18048.ts',
419
selection: [3, 20, 3, 20],
420
query: `/fix 'poppedElement' is possibly 'undefined'`,
421
expectedIntent: Intent.Fix,
422
diagnostics: 'tsc',
423
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
424
}
425
]
426
});
427
});
428
429
// Inspired by case 125 of /fix dataset version 8
430
stest({ description: 'Error 2304 - (AML-8-125) can not find name', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
431
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
432
files: [fromFixture('fixing/typescript/tsc_error_2304_2.ts')],
433
queries: [
434
{
435
file: 'tsc_error_2304_2.ts',
436
selection: [7, 2, 7, 2],
437
query: `/fix Cannot find name 'cy'.`,
438
expectedIntent: Intent.Fix,
439
diagnostics: 'tsc',
440
validate: async (outcome, workspace, accessor) => {
441
if (outcome.type === 'conversational') {
442
const match = outcome.chatResponseMarkdown.match(/```(ps|bash)[.\n\r]*npm install.*cypress/);
443
assert.ok(match, 'contains npm install cypress');
444
} else if (outcome.type === 'inlineEdit') {
445
const diagnostics = await getWorkspaceDiagnostics(accessor, workspace, 'tsc');
446
const filtered = diagnostics.filter(d => d.code !== 2307 && d.code !== 2305); // filter module not found, module has not exported member
447
assert.equal(filtered.length, 0, 'only module not found diagnostics');
448
} else {
449
assert.fail('unexpected outcome type');
450
}
451
}
452
}
453
]
454
});
455
});
456
457
stest({ description: 'Error 2304 - (AML-8-125) can not find name 2', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
458
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
459
files: [fromFixture('fixing/typescript/tsc_error_2304_3.ts')],
460
queries: [
461
{
462
file: 'tsc_error_2304_3.ts',
463
selection: [1, 10, 1, 10],
464
query: `/fix Cannot find name 'promises'. Did you mean 'Promise'?.`,
465
expectedIntent: Intent.Fix,
466
diagnostics: 'tsc',
467
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
468
}
469
]
470
});
471
});
472
473
// Inspired by case 25 of /fix dataset version 10
474
// The fix was not correct, it just added a new line and did not resolve the error
475
stest({ description: `Error 7053 - (AML-10-25) expression of type can't be used to index`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
476
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
477
files: [fromFixture('fixing/typescript/tsc_error_7053.ts')],
478
queries: [
479
{
480
file: 'tsc_error_7053.ts',
481
selection: [9, 2, 9, 2],
482
query: [
483
`/fix Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ Pi: number; PiTimes2: number; PiOn2: number; PiOn4: number; E: number; }.`,
484
` No index signature with a parameter of type 'string' was found on type '{ Pi: number; PiTimes2: number; PiOn2: number; PiOn4: number; E: number; }'.`
485
].join('\n'),
486
expectedIntent: Intent.Fix,
487
diagnostics: 'tsc',
488
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
489
}
490
]
491
});
492
});
493
494
// Inspired by case 31 in /fix dataset version 10
495
stest({ description: '(AML-10-31) Parameter data implicitly has an any type.', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
496
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
497
files: [fromFixture('fixing/typescript/tsc_implicit_any.ts')],
498
queries: [
499
{
500
file: 'tsc_implicit_any.ts',
501
selection: [7, 38, 7, 42],
502
query: `/fix Parameter 'data' implicitly has an 'any' type`,
503
expectedIntent: Intent.Fix,
504
diagnostics: 'tsc',
505
validate: async (outcome, workspace, accessor) => {
506
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
507
}
508
}
509
]
510
});
511
});
512
513
stest({ description: 'declaration or statement expected', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
514
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
515
files: [fromFixture('fixing/typescript/tsc_error_1128.ts')],
516
queries: [
517
{
518
file: 'tsc_error_1128.ts',
519
selection: [8, 0, 8, 1],
520
query: `/fix Declaration or statement expected.`,
521
expectedIntent: Intent.Fix,
522
diagnostics: 'tsc',
523
validate: async (outcome, workspace, accessor) => {
524
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
525
}
526
}
527
]
528
});
529
});
530
531
stest({ description: 'left side of comma operator is unused', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
532
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
533
files: [fromFixture('fixing/typescript/tsc_error_2695.ts')],
534
queries: [
535
{
536
file: 'tsc_error_2695.ts',
537
selection: [3, 9, 3, 10],
538
query: `/fix Left side of comma operator is unused and has no side effects.`,
539
expectedIntent: Intent.Fix,
540
diagnostics: 'tsc',
541
validate: async (outcome, workspace, accessor) => {
542
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
543
}
544
}
545
]
546
});
547
});
548
549
stest({ description: 'object is possibly undefined', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
550
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
551
files: [fromFixture('fixing/typescript/tsc_error_2532.ts')],
552
queries: [
553
{
554
file: 'tsc_error_2532.ts',
555
selection: [2, 12, 2, 15],
556
query: `/fix 'obj' is possibly 'undefined'.`,
557
expectedIntent: Intent.Fix,
558
diagnostics: 'tsc',
559
validate: async (outcome, workspace, accessor) => {
560
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
561
}
562
}
563
]
564
});
565
});
566
567
stest({ description: 'duplicate identifier', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
568
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
569
files: [fromFixture('fixing/typescript/tsc_error_2300.ts')],
570
queries: [
571
{
572
file: 'tsc_error_2300.ts',
573
selection: [1, 6, 1, 13],
574
query: `/fix Duplicate identifier 'MyArray'.`,
575
expectedIntent: Intent.Fix,
576
diagnostics: 'tsc',
577
validate: async (outcome, workspace, accessor) => {
578
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
579
}
580
}
581
]
582
});
583
});
584
585
stest({ description: 'Error 2802 - large file - Type Uint32Array can only be iterated through', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
586
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
587
files: [fromFixture('fixing/typescript/tsc_large_onigscanner/tsc_error_2802.ts')],
588
queries: [
589
{
590
file: 'tsc_error_2802.ts',
591
selection: [442, 16, 454, 10],
592
query: `/fix Type 'Uint32Array' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.`,
593
expectedIntent: Intent.Fix,
594
diagnostics: 'tsc',
595
validate: async (outcome, workspace, accessor) => {
596
if (outcome.type === 'conversational') {
597
// change to tsconfig.json
598
} else {
599
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
600
}
601
}
602
}
603
]
604
});
605
});
606
607
stest({ description: 'can not assign to parameter of type', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
608
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
609
files: [fromFixture('fixing/typescript/tsc_error_2345.ts')],
610
queries: [
611
{
612
file: 'tsc_error_2345.ts',
613
selection: [1, 22, 1, 31],
614
query: `/fix Argument of type 'T' is not assignable to parameter of type 'object | null'.`,
615
expectedIntent: Intent.Fix,
616
diagnostics: 'tsc',
617
validate: async (outcome, workspace, accessor) => {
618
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
619
}
620
}
621
]
622
});
623
});
624
625
stest({ description: 'Error 2345 - Last two arguments swapped', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
626
const files = [
627
fromFixture('fixing/typescript/tsc_error_2345_2/file0.ts'),
628
fromFixture('fixing/typescript/tsc_error_2345_2/file1.ts'),
629
fromFixture('fixing/typescript/tsc_error_2345_2/database_mock.ts')
630
];
631
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
632
files,
633
queries: [
634
{
635
file: 'file0.ts',
636
selection: [3, 35, 3, 40],
637
query: [
638
`/fix Argument of type 'boolean' is not assignable to parameter of type 'number'.`,
639
].join('\n'),
640
expectedIntent: Intent.Fix,
641
diagnostics: 'tsc',
642
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
643
}
644
]
645
});
646
});
647
648
stest({ description: 'Error 2345 - Got boolean but expected options bag', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
649
const files = [
650
fromFixture('fixing/typescript/tsc_error_2345_3/file0.ts'),
651
fromFixture('fixing/typescript/tsc_error_2345_3/database_mock.ts')
652
];
653
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
654
files,
655
queries: [
656
{
657
file: 'file0.ts',
658
selection: [3, 41, 3, 46],
659
query: [
660
`/fix Argument of type 'boolean' is not assignable to parameter of type '{ timeout?: number | undefined; loose: boolean; }'.`,
661
].join('\n'),
662
expectedIntent: Intent.Fix,
663
diagnostics: 'tsc',
664
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
665
}
666
]
667
});
668
});
669
670
stest({ description: 'Error 2554 - Got two args but expected options bag', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
671
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
672
files: [
673
fromFixture('fixing/typescript/tsc_error_2554/legacy_database.ts'),
674
fromFixture('fixing/typescript/tsc_error_2554/file1.ts'),
675
fromFixture('fixing/typescript/tsc_error_2554/database_mock.ts')
676
],
677
queries: [
678
{
679
file: 'legacy_database.ts',
680
selection: [9, 37, 9, 42],
681
query: `/fix Expected 1-2 arguments, but got 3.`,
682
expectedIntent: Intent.Fix,
683
diagnostics: 'tsc',
684
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
685
}
686
]
687
});
688
});
689
690
stest({ description: 'Issue 6571', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
691
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
692
files: [fromFixture('fixing/typescript/inlineChatSimulator.ts')],
693
queries: [
694
{
695
file: 'inlineChatSimulator.ts',
696
selection: [302, 16, 302, 27],
697
query: `/fix Cannot find name 'startOffset'.`,
698
diagnostics: 'tsc',
699
expectedIntent: 'fix',
700
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc')
701
}
702
]
703
});
704
});
705
706
stest({ description: 'Issue #7300', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
707
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
708
files: [toFile({
709
fileName: 'textureAtlasAllocator.test.ts',
710
fileContents: `/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\n\r\nimport { deepStrictEqual, strictEqual } from 'assert';\r\nimport { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';\r\nimport { TextureAtlasShelfAllocator } from 'vs/editor/browser/view/gpu/atlas/textureAtlasAllocator';\r\nimport { ensureNonNullable } from 'vs/editor/browser/view/gpu/gpuUtils';\r\nimport type { IRasterizedGlyph } from 'vs/editor/browser/view/gpu/raster/glyphRasterizer';\r\n\r\nconst blackInt = 0x000000FF;\r\nconst blackArr = [0x00, 0x00, 0x00, 0xFF];\r\n\r\nconst pixel1x1 = createRasterizedGlyph(1, 1, [...blackArr]);\r\nconst pixel2x1 = createRasterizedGlyph(2, 1, [...blackArr, ...blackArr]);\r\nconst pixel1x2 = createRasterizedGlyph(1, 2, [...blackArr, ...blackArr]);\r\n\r\nfunction initAllocator(w: number, h: number): { canvas: OffscreenCanvas; ctx: OffscreenCanvasRenderingContext2D; allocator: TextureAtlasShelfAllocator } {\r\n\tconst canvas = new OffscreenCanvas(w, h);\r\n\tconst ctx = ensureNonNullable(canvas.getContext('2d'));\r\n\tconst allocator = new TextureAtlasShelfAllocator(canvas, ctx);\r\n\treturn { canvas, ctx, allocator };\r\n}\r\n\r\nfunction createRasterizedGlyph(w: number, h: number, data: ArrayLike<number>): IRasterizedGlyph {\r\n\tstrictEqual(w * h * 4, data.length);\r\n\tconst source = new OffscreenCanvas(w, h);\r\n\tconst imageData = new ImageData(w, h);\r\n\timageData.data.set(data);\r\n\tensureNonNullable(source.getContext('2d')).putImageData(imageData, 0, 0);\r\n\treturn {\r\n\t\tsource,\r\n\t\tboundingBox: { top: 0, left: 0, bottom: h - 1, right: w - 1 },\r\n\t\toriginOffset: { x: 0, y: 0 },\r\n\t};\r\n}\r\n\r\nsuite('TextureAtlasShelfAllocator', () => {\r\n\tensureNoDisposablesAreLeakedInTestSuite();\r\n\r\n\tlet lastUniqueGlyph: string | undefined;\r\n\tfunction getUniqueGlyphId(): [string, number] {\r\n\t\tif (!lastUniqueGlyph) {\r\n\t\t\tlastUniqueGlyph = 'a';\r\n\t\t} else {\r\n\t\t\tlastUniqueGlyph = String.fromCharCode(lastUniqueGlyph.charCodeAt(0) + 1);\r\n\t\t}\r\n\t\treturn [lastUniqueGlyph, blackInt];\r\n\t}\r\n\r\n\tsuiteSetup(() => {\r\n\t\tlastUniqueGlyph = undefined;\r\n\t});\r\n\r\n\ttest('single allocation', () => {\r\n\t\tconst { allocator } = initAllocator(2, 2);\r\n\t\t// 1o\r\n\t\t// oo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x1), {\r\n\t\t\tindex: 0,\r\n\t\t\tx: 0, y: 0,\r\n\t\t\tw: 1, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t});\r\n\ttest('wrapping', () => {\r\n\t\tconst { allocator } = initAllocator(5, 4);\r\n\t\t// 1oooo\r\n\t\t// ooooo\r\n\t\t// ooooo\r\n\t\t// ooooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x1), {\r\n\t\t\tindex: 0,\r\n\t\t\tx: 0, y: 0,\r\n\t\t\tw: 1, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\t// 12ooo\r\n\t\t// o2ooo\r\n\t\t// ooooo\r\n\t\t// ooooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x2), {\r\n\t\t\tindex: 1,\r\n\t\t\tx: 1, y: 0,\r\n\t\t\tw: 1, h: 2,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\t// 1233o\r\n\t\t// o2ooo\r\n\t\t// ooooo\r\n\t\t// ooooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel2x1), {\r\n\t\t\tindex: 2,\r\n\t\t\tx: 2, y: 0,\r\n\t\t\tw: 2, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\t// 1233x\r\n\t\t// x2xxx\r\n\t\t// 44ooo\r\n\t\t// ooooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel2x1), {\r\n\t\t\tindex: 3,\r\n\t\t\tx: 0, y: 2,\r\n\t\t\tw: 2, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t}, 'should wrap to next line as there\\'s no room left');\r\n\t\t// 1233x\r\n\t\t// x2xxx\r\n\t\t// 4455o\r\n\t\t// ooooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel2x1), {\r\n\t\t\tindex: 4,\r\n\t\t\tx: 2, y: 2,\r\n\t\t\tw: 2, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\t// 1233x\r\n\t\t// x2xxx\r\n\t\t// 44556\r\n\t\t// ooooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x1), {\r\n\t\t\tindex: 5,\r\n\t\t\tx: 4, y: 2,\r\n\t\t\tw: 1, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\t// 1233x\r\n\t\t// x2xxx\r\n\t\t// 44556\r\n\t\t// 7oooo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x1), {\r\n\t\t\tindex: 6,\r\n\t\t\tx: 0, y: 3,\r\n\t\t\tw: 1, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t}, 'should wrap to next line as there\\'s no room left');\r\n\t});\r\n\ttest('full', () => {\r\n\t\tconst { allocator } = initAllocator(3, 2);\r\n\t\t// 1oo\r\n\t\t// 1oo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x2), {\r\n\t\t\tindex: 0,\r\n\t\t\tx: 0, y: 0,\r\n\t\t\tw: 1, h: 2,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\t// 122\r\n\t\t// 1oo\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel2x1), {\r\n\t\t\tindex: 1,\r\n\t\t\tx: 1, y: 0,\r\n\t\t\tw: 2, h: 1,\r\n\t\t\toriginOffsetX: 0, originOffsetY: 0,\r\n\t\t});\r\n\t\tdeepStrictEqual(allocator.allocate(...getUniqueGlyphId(), pixel1x1), undefined, 'should return undefined when the canvas is full');\r\n\t});\r\n});\r\n\r\nsuite('TextureAtlasSlabAllocator', () => {\r\n\ttest('a', () => {\r\n\t});\r\n});\r\n`
711
})],
712
queries: [
713
{
714
file: 'textureAtlasAllocator.test.ts',
715
selection: [161, 0, 164, 2],
716
query: '/fix Suites should include a call to `ensureNoDisposablesAreLeakedInTestSuite()` to ensure no disposables are leaked in tests.',
717
diagnostics: 'tsc',
718
expectedIntent: 'fix',
719
validate: async (outcome, workspace, accessor) => {
720
assertInlineEdit(outcome);
721
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
722
}
723
}
724
]
725
});
726
});
727
});
728
729
ssuite({ title: `fix${suffix}`, subtitle: 'eslint', location: 'inline' }, () => {
730
stest({ description: 'unexpected token', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
731
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
732
files: [fromFixture('fixing/typescript/eslint_unexpected_token.ts')],
733
queries: [
734
{
735
file: 'eslint_unexpected_token.ts',
736
selection: [14, 4, 14, 4],
737
query: `/fix Parsing error: Expression expected.`,
738
expectedIntent: Intent.Fix,
739
diagnostics: 'eslint',
740
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
741
}
742
]
743
});
744
});
745
746
// Inspired by case 52 of /fix dataset version 10
747
// The fix was not correct, it just added a new line and did not resolve the error
748
stest({ description: '(AML-10-52) expected conditional expression', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
749
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
750
files: [fromFixture('fixing/typescript/eslint_expected_conditional_expression.ts')],
751
queries: [
752
{
753
file: 'eslint_expected_conditional_expression.ts',
754
selection: [8, 6, 8, 6],
755
query: `/fix`,
756
expectedIntent: Intent.Fix,
757
diagnostics: 'eslint',
758
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
759
}
760
]
761
});
762
});
763
764
// Inspired by case 1 in /fix dataset version 10
765
stest({ description: '(AML-10-1) do not access hasOwnProperty', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
766
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
767
files: [fromFixture('fixing/typescript/eslint_do_not_access_hasOwnProperty.ts')],
768
queries: [
769
{
770
file: 'eslint_do_not_access_hasOwnProperty.ts',
771
selection: [9, 23, 9, 23],
772
query: `/fix Do not access Object.prototype method 'hasOwnProperty' from target object.`,
773
expectedIntent: Intent.Fix,
774
diagnostics: 'eslint',
775
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
776
}
777
]
778
});
779
});
780
781
stest({ description: `comma expected`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
782
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
783
files: [fromFixture('fixing/typescript/eslint_comma_expected.ts')],
784
queries: [
785
{
786
file: 'eslint_comma_expected.ts',
787
selection: [8, 2, 8, 2],
788
query: [
789
`/fix Parsing error: ',' expected.`
790
].join('\n'),
791
expectedIntent: Intent.Fix,
792
diagnostics: 'eslint',
793
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
794
}
795
]
796
});
797
});
798
799
// Inspired by case 10 of /fix dataset version 17
800
stest({ description: `(AML-17-10) unexpected constant condition 1`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
801
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
802
files: [fromFixture('fixing/typescript/eslint_unexpected_constant_condition_1.ts')],
803
queries: [
804
{
805
file: 'eslint_unexpected_constant_condition_1.ts',
806
selection: [1, 4, 1, 4],
807
query: [
808
`/fix Unexpected constant condition.`
809
].join('\n'),
810
expectedIntent: Intent.Fix,
811
diagnostics: 'eslint',
812
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
813
}
814
]
815
});
816
});
817
818
// Inspired by case 152 of /fix dataset version 17
819
stest({ description: `(AML-17-152) unreachable code`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
820
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
821
files: [fromFixture('fixing/typescript/eslint_unreachable_code.ts')],
822
queries: [
823
{
824
file: 'eslint_unreachable_code.ts',
825
selection: [5, 3, 5, 3],
826
query: [
827
`/fix Unreachable code.`
828
].join('\n'),
829
expectedIntent: Intent.Fix,
830
diagnostics: 'eslint',
831
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
832
}
833
]
834
});
835
});
836
837
// Inspired by case 166 of /fix dataset version 17
838
stest({ description: `(AML-17-166) unexpected control character`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
839
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
840
files: [fromFixture('fixing/typescript/eslint_unexpected_control_character.ts')],
841
queries: [
842
{
843
file: 'eslint_unexpected_control_character.ts',
844
selection: [0, 11, 0, 11],
845
query: [
846
`/fix Unexpected control character(s) in regular expression: \\x00.`
847
].join('\n'),
848
expectedIntent: Intent.Fix,
849
diagnostics: 'eslint',
850
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
851
}
852
]
853
});
854
});
855
856
// Inspired by case 243 of /fix dataset version 17
857
stest({ description: `(AML-17-243) unexpected constant condition 2`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
858
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
859
files: [fromFixture('fixing/typescript/eslint_unexpected_constant_condition_2.ts')],
860
queries: [
861
{
862
file: 'eslint_unexpected_constant_condition_2.ts',
863
selection: [4, 9, 4, 9],
864
query: [
865
`/fix Unexpected constant condition.`
866
].join('\n'),
867
expectedIntent: Intent.Fix,
868
diagnostics: 'eslint',
869
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
870
}
871
]
872
});
873
});
874
875
stest({ description: `class-methods-use-this with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
876
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
877
files: [fromFixture('fixing/typescript/eslint_class_methods_use_this.ts')],
878
queries: [
879
{
880
file: 'eslint_class_methods_use_this.ts',
881
selection: [14, 1, 14, 7],
882
query: [
883
`/fix Expected 'this' to be used by class method 'append'.`,
884
].join('\n'),
885
expectedIntent: Intent.Fix,
886
diagnostics: 'eslint',
887
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
888
}
889
]
890
});
891
});
892
893
stest({ description: `consistent-this with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
894
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
895
files: [fromFixture('fixing/typescript/eslint_consistent_this.ts')],
896
queries: [
897
{
898
file: 'eslint_consistent_this.ts',
899
selection: [8, 8, 8, 19],
900
query: [
901
`/fix Unexpected alias 'self' for 'this'.`,
902
].join('\n'),
903
expectedIntent: Intent.Fix,
904
diagnostics: 'eslint',
905
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
906
}
907
]
908
});
909
});
910
911
stest({ description: `constructor-super with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
912
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
913
files: [fromFixture('fixing/typescript/eslint_constructor_super.ts')],
914
queries: [
915
{
916
file: 'eslint_constructor_super.ts',
917
selection: [22, 1, 25, 2],
918
query: [
919
`/fix Expected to call 'super()'.`,
920
`Constructors for derived classes must contain a 'super' call.`
921
].join('\n'),
922
expectedIntent: Intent.Fix,
923
diagnostics: 'eslint',
924
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
925
}
926
]
927
});
928
});
929
930
stest({ description: `func-names with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
931
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
932
files: [fromFixture('fixing/typescript/eslint_func_names.ts')],
933
queries: [
934
{
935
file: 'eslint_func_names.ts',
936
selection: [4, 25, 4, 34],
937
query: [
938
`/fix Unexpected unnamed function.`,
939
].join('\n'),
940
expectedIntent: Intent.Fix,
941
diagnostics: 'eslint',
942
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
943
}
944
]
945
});
946
});
947
948
stest({ description: `func-style with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
949
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
950
files: [fromFixture('fixing/typescript/eslint_func_style.ts')],
951
queries: [
952
{
953
file: 'eslint_func_style.ts',
954
selection: [4, 7, 10, 1],
955
query: [
956
`/fix Expected a function expression.`,
957
].join('\n'),
958
expectedIntent: Intent.Fix,
959
diagnostics: 'eslint',
960
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
961
}
962
]
963
});
964
});
965
stest({ description: `max-lines-per-function with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
966
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
967
files: [fromFixture('fixing/typescript/eslint_max_lines_per_function.ts')],
968
queries: [
969
{
970
file: 'eslint_max_lines_per_function.ts',
971
selection: [4, 7, 58, 1],
972
query: [
973
`/fix Function 'fastMark' has too many lines (55). Maximum allowed is 50.`,
974
].join('\n'),
975
expectedIntent: Intent.Fix,
976
diagnostics: 'eslint',
977
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
978
}
979
]
980
});
981
});
982
983
stest({ description: `max-params with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
984
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
985
files: [fromFixture('fixing/typescript/eslint_max_params.ts')],
986
queries: [
987
{
988
file: 'eslint_max_params.ts',
989
selection: [10, 1, 10, 12],
990
query: [
991
`/fix Constructor has too many parameters (5). Maximum allowed is 3.`,
992
].join('\n'),
993
expectedIntent: Intent.Fix,
994
diagnostics: 'eslint',
995
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
996
}
997
]
998
});
999
});
1000
stest({ description: `max-statements with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1001
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1002
files: [fromFixture('fixing/typescript/eslint_max_statements.ts')],
1003
queries: [
1004
{
1005
file: 'eslint_max_statements.ts',
1006
selection: [5, 7, 59, 1],
1007
query: [
1008
`/fix Function 'fastMark' has too many statements (34). Maximum allowed is 10.`,
1009
].join('\n'),
1010
expectedIntent: Intent.Fix,
1011
diagnostics: 'eslint',
1012
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1013
}
1014
]
1015
});
1016
});
1017
1018
stest({ description: `no-case-declarations with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1019
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1020
files: [fromFixture('fixing/typescript/eslint_no_case_declarations.ts')],
1021
queries: [
1022
{
1023
file: 'eslint_no_case_declarations.ts',
1024
selection: [9, 3, 9, 61],
1025
query: [
1026
`/fix Unexpected lexical declaration in case block.`,
1027
].join('\n'),
1028
expectedIntent: Intent.Fix,
1029
diagnostics: 'eslint',
1030
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1031
}
1032
]
1033
});
1034
});
1035
1036
stest({ description: `no-dupe-else-if with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1037
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1038
files: [fromFixture('fixing/typescript/eslint_no_dupe_else_if.ts')],
1039
queries: [
1040
{
1041
file: 'eslint_no_dupe_else_if.ts',
1042
selection: [11, 13, 11, 34],
1043
query: [
1044
`/fix This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain.`,
1045
].join('\n'),
1046
expectedIntent: Intent.Fix,
1047
diagnostics: 'eslint',
1048
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1049
}
1050
]
1051
});
1052
});
1053
stest({ description: `no-duplicate-case with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1054
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1055
files: [fromFixture('fixing/typescript/eslint_no_duplicate_case.ts')],
1056
queries: [
1057
{
1058
file: 'eslint_no_duplicate_case.ts',
1059
selection: [20, 1, 21, 137],
1060
query: [
1061
`/fix Please fix the problem at the location`,
1062
].join('\n'),
1063
expectedIntent: Intent.Fix,
1064
diagnostics: 'eslint',
1065
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1066
}
1067
]
1068
});
1069
});
1070
1071
stest({ description: `no-duplicate-imports with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1072
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1073
files: [fromFixture('fixing/typescript/eslint_no_duplicate_imports.ts')],
1074
queries: [
1075
{
1076
file: 'eslint_no_duplicate_imports.ts',
1077
selection: [7, 0, 7, 55],
1078
query: [
1079
`/fix './eslint_no_duplicate_case'' import is duplicated.`,
1080
].join('\n'),
1081
expectedIntent: Intent.Fix,
1082
diagnostics: 'eslint',
1083
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1084
}
1085
]
1086
});
1087
});
1088
stest({ description: `no-fallthrough with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1089
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1090
files: [fromFixture('fixing/typescript/eslint_no_fallthrough.ts')],
1091
queries: [
1092
{
1093
file: 'eslint_no_fallthrough.ts',
1094
selection: [9, 2, 9, 9],
1095
query: [
1096
`/fix Expected a 'break' statement before 'case'.`,
1097
`Constructors for derived classes must contain a 'super' call.`
1098
].join('\n'),
1099
expectedIntent: Intent.Fix,
1100
diagnostics: 'eslint',
1101
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1102
}
1103
]
1104
});
1105
});
1106
1107
stest({ description: `no-inner-declarations with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1108
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1109
files: [fromFixture('fixing/typescript/eslint_no_inner_declarations.ts')],
1110
queries: [
1111
{
1112
file: 'eslint_no_inner_declarations.ts',
1113
selection: [11, 2, 15, 3],
1114
query: [
1115
`/fix Move function declaration to function body root.`,
1116
].join('\n'),
1117
expectedIntent: Intent.Fix,
1118
diagnostics: 'eslint',
1119
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1120
}
1121
]
1122
});
1123
});
1124
1125
stest({ description: `no-multi-assign with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1126
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1127
files: [fromFixture('fixing/typescript/eslint_no_multi_assign.ts')],
1128
queries: [
1129
{
1130
file: 'eslint_no_multi_assign.ts',
1131
selection: [10, 8, 10, 8],
1132
query: [
1133
`/fix Unexpected chained assignment.`,
1134
].join('\n'),
1135
expectedIntent: Intent.Fix,
1136
diagnostics: 'eslint',
1137
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1138
}
1139
]
1140
});
1141
});
1142
1143
stest({ description: `no-negated-condition with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1144
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1145
files: [fromFixture('fixing/typescript/eslint_no_negated_condition.ts')],
1146
queries: [
1147
{
1148
file: 'eslint_no_negated_condition.ts',
1149
selection: [8, 8, 8, 53],
1150
query: [
1151
`/fix Unexpected negated condition.`,
1152
].join('\n'),
1153
expectedIntent: Intent.Fix,
1154
diagnostics: 'eslint',
1155
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1156
}
1157
]
1158
});
1159
});
1160
1161
stest({ description: `no-negated-condition 2 with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1162
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1163
files: [fromFixture('fixing/typescript/eslint_no_negated_condition_2.ts')],
1164
queries: [
1165
{
1166
file: 'eslint_no_negated_condition_2.ts',
1167
selection: [6, 2, 11, 3],
1168
query: [
1169
`/fix Unexpected negated condition.`,
1170
].join('\n'),
1171
expectedIntent: Intent.Fix,
1172
diagnostics: 'eslint',
1173
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1174
}
1175
]
1176
});
1177
});
1178
1179
stest({ description: `no-new with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1180
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1181
files: [fromFixture('fixing/typescript/eslint_no_new.ts')],
1182
queries: [
1183
{
1184
file: 'eslint_no_new.ts',
1185
selection: [38, 0, 38, 30],
1186
query: [
1187
`/fix Please fix the problem at the location`,
1188
].join('\n'),
1189
expectedIntent: Intent.Fix,
1190
diagnostics: 'eslint',
1191
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1192
}
1193
]
1194
});
1195
});
1196
stest({ description: `no-sequences with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1197
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1198
files: [fromFixture('fixing/typescript/eslint_no_sequences.ts')],
1199
queries: [
1200
{
1201
file: 'eslint_no_sequences.ts',
1202
selection: [16, 26, 16, 27],
1203
query: [
1204
`/fix Please fix the problem at the location`,
1205
].join('\n'),
1206
expectedIntent: Intent.Fix,
1207
diagnostics: 'eslint',
1208
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1209
}
1210
]
1211
});
1212
});
1213
1214
stest({ description: `no-sparse-arrays with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1215
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1216
files: [fromFixture('fixing/typescript/eslint_no_sparse_arrays.ts')],
1217
queries: [
1218
{
1219
file: 'eslint_no_sparse_arrays.ts',
1220
selection: [4, 25, 4, 30],
1221
query: [
1222
`/fix Unexpected comma in middle of array.`,
1223
].join('\n'),
1224
expectedIntent: Intent.Fix,
1225
diagnostics: 'eslint',
1226
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1227
}
1228
]
1229
});
1230
});
1231
stest({ description: `no-sparse-arrays 2 with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1232
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1233
files: [fromFixture('fixing/typescript/eslint_no_sparse_arrays_2.ts')],
1234
queries: [
1235
{
1236
file: 'eslint_no_sparse_arrays_2.ts',
1237
selection: [4, 29, 4, 66],
1238
query: [
1239
`/fix Unexpected comma in middle of array.`,
1240
].join('\n'),
1241
expectedIntent: Intent.Fix,
1242
diagnostics: 'eslint',
1243
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1244
}
1245
]
1246
});
1247
});
1248
1249
stest({ description: `no-sparse-arrays 3 with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1250
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1251
files: [fromFixture('fixing/typescript/eslint_no_sparse_arrays_3.ts')],
1252
queries: [
1253
{
1254
file: 'eslint_no_sparse_arrays_3.ts',
1255
selection: [4, 26, 4, 56],
1256
query: [
1257
`/fix Unexpected comma in middle of array.`,
1258
].join('\n'),
1259
expectedIntent: Intent.Fix,
1260
diagnostics: 'eslint',
1261
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1262
}
1263
]
1264
});
1265
});
1266
1267
stest({ description: `require-await with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1268
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1269
files: [fromFixture('fixing/typescript/eslint_require_await.ts')],
1270
queries: [
1271
{
1272
file: 'eslint_require_await.ts',
1273
selection: [6, 7, 6, 32],
1274
query: [
1275
`/fix Async function 'readConfig' has no 'await' expression.`,
1276
].join('\n'),
1277
expectedIntent: Intent.Fix,
1278
diagnostics: 'eslint',
1279
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1280
}
1281
]
1282
});
1283
});
1284
stest({ description: `sort-keys with cookbook`, language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1285
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1286
files: [fromFixture('fixing/typescript/eslint_sort_keys.ts')],
1287
queries: [
1288
{
1289
file: 'eslint_sort_keys.ts',
1290
selection: [21, 2, 21, 10],
1291
query: [
1292
`/fix Expected object keys to be in ascending order. 'extended' should be before 'value'.`,
1293
].join('\n'),
1294
expectedIntent: Intent.Fix,
1295
diagnostics: 'eslint',
1296
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'eslint')
1297
}
1298
]
1299
});
1300
});
1301
1302
stest({ description: 'Issue #7544', language: 'typescript', nonExtensionConfigurations }, (accessor) => {
1303
return simulateInlineChatWithStrategy(strategy, accessor, {
1304
files: [toFile({
1305
filePath: fromFixture('fix/issue-7544/notebookMulticursor.ts')
1306
})],
1307
queries: [
1308
{
1309
file: 'notebookMulticursor.ts',
1310
selection: [262, 41, 262, 41],
1311
query: 'fix the error',
1312
diagnostics: 'tsc',
1313
expectedIntent: 'fix',
1314
validate: async (outcome, workspace, accessor) => {
1315
assertInlineEdit(outcome);
1316
assertOccursOnce(outcome.fileContents, '\tundoRedo?: {\n\t\telements: IPastFutureElements;\n\t};');
1317
}
1318
}
1319
]
1320
});
1321
});
1322
});
1323
1324
ssuite({ title: `fix${suffix}`, subtitle: 'pylint', location: 'inline' }, () => {
1325
1326
stest({ description: 'unecessary parenthesis', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1327
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1328
files: [fromFixture('fixing/python/pylint_unecessary_parenthesis.py')],
1329
queries: [
1330
{
1331
file: 'pylint_unecessary_parenthesis.py',
1332
selection: [7, 0, 7, 0],
1333
query: `/fix Unnecessary parens after 'if' keyword`,
1334
expectedIntent: Intent.Fix,
1335
diagnostics: 'pylint',
1336
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1337
}
1338
]
1339
});
1340
});
1341
1342
stest({ description: 'unused module imported', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1343
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1344
files: [fromFixture('fixing/python/pylint_unused_import.py')],
1345
queries: [
1346
{
1347
file: 'pylint_unused_import.py',
1348
selection: [0, 0, 0, 0],
1349
query: `/fix Unused Path imported from pathlib`,
1350
expectedIntent: Intent.Fix,
1351
diagnostics: 'pylint',
1352
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1353
}
1354
]
1355
});
1356
});
1357
1358
stest({ description: `line-too-long cookbook 1 function definition with long parameters`, language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1359
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1360
files: [fromFixture('fixing/python/pylint_line_too_long_1.py')],
1361
queries: [
1362
{
1363
file: 'pylint_line_too_long_1.py',
1364
selection: [8, 0, 8, 2],
1365
query: [
1366
`/fix`,
1367
].join('\n'),
1368
expectedIntent: Intent.Fix,
1369
diagnostics: 'pylint',
1370
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1371
}
1372
]
1373
});
1374
});
1375
1376
stest({ description: `line-too-long cookbook 2 long print statememt`, language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1377
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1378
files: [fromFixture('fixing/python/pylint_line_too_long_2.py')],
1379
queries: [
1380
{
1381
file: 'pylint_line_too_long_2.py',
1382
selection: [7, 0, 7, 0],
1383
query: [
1384
`/fix`,
1385
].join('\n'),
1386
expectedIntent: Intent.Fix,
1387
diagnostics: 'pylint',
1388
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1389
}
1390
]
1391
});
1392
});
1393
1394
stest({ description: `line-too-long cookbook 3 long dictionary / list`, language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1395
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1396
files: [fromFixture('fixing/python/pylint_line_too_long_3.py')],
1397
queries: [
1398
{
1399
file: 'pylint_line_too_long_3.py',
1400
selection: [8, 0, 8, 0],
1401
query: [
1402
`/fix`,
1403
].join('\n'),
1404
expectedIntent: Intent.Fix,
1405
diagnostics: 'pylint',
1406
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1407
}
1408
]
1409
});
1410
});
1411
1412
stest({ description: `line-too-long cookbook 4 long if condition and function call`, language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1413
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1414
files: [fromFixture('fixing/python/pylint_line_too_long_4.py')],
1415
queries: [
1416
{
1417
file: 'pylint_line_too_long_4.py',
1418
selection: [15, 0, 15, 2],
1419
query: [
1420
`/fix`,
1421
].join('\n'),
1422
expectedIntent: Intent.Fix,
1423
diagnostics: 'pylint',
1424
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1425
}
1426
]
1427
});
1428
});
1429
1430
stest({ description: `line-too-long cookbook 5 multi-line docstring`, language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1431
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1432
files: [fromFixture('fixing/python/pylint_line_too_long_5.py')],
1433
queries: [
1434
{
1435
file: 'pylint_line_too_long_5.py',
1436
selection: [7, 8, 9, 8],
1437
query: [
1438
`/fix`,
1439
].join('\n'),
1440
expectedIntent: Intent.Fix,
1441
diagnostics: 'pylint',
1442
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pylint')
1443
}
1444
]
1445
});
1446
});
1447
1448
});
1449
1450
ssuite({ title: `fix${suffix}`, subtitle: 'pyright', location: 'inline' }, () => {
1451
1452
stest({ description: 'cannot instantiate abstract class', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1453
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1454
files: [fromFixture('fixing/python/pyright_no_abstract_class_instantiation.py')],
1455
queries: [
1456
{
1457
file: 'pyright_no_abstract_class_instantiation.py',
1458
selection: [9, 4, 9, 4],
1459
query: `/fix Cannot instantiate abstract class "Base"\n "Base.foo" is abstract`,
1460
expectedIntent: Intent.Fix,
1461
diagnostics: 'pyright',
1462
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1463
}
1464
]
1465
});
1466
});
1467
1468
stest({ description: 'all Annotated types should include at least two type arguments', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1469
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1470
files: [fromFixture('fixing/python/pyright_annotated_types_missing_argument.py')],
1471
queries: [
1472
{
1473
file: 'pyright_annotated_types_missing_argument.py',
1474
selection: [4, 3, 4, 3],
1475
query: `/fix Expected one type argument and one or more annotations for "Annotated"`,
1476
expectedIntent: Intent.Fix,
1477
diagnostics: 'pyright',
1478
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1479
}
1480
]
1481
});
1482
});
1483
1484
stest({ description: 'should not generate an error for variables declared in outer scopes', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1485
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1486
files: [fromFixture('fixing/python/pyright_assignment_scopes.py')],
1487
queries: [
1488
{
1489
file: 'pyright_assignment_scopes.py',
1490
selection: [24, 8, 24, 8],
1491
query: `/fix "d" is not defined`,
1492
expectedIntent: Intent.Fix,
1493
diagnostics: 'pyright',
1494
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1495
}
1496
]
1497
});
1498
});
1499
1500
stest({ description: 'async cannot be used in a non-async function', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1501
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1502
files: [fromFixture('fixing/python/pyright_async_in_non_async_function.py')],
1503
queries: [
1504
{
1505
file: 'pyright_async_in_non_async_function.py',
1506
selection: [17, 4, 17, 4],
1507
query: `/fix Use of "async" not allowed outside of async function`,
1508
expectedIntent: Intent.Fix,
1509
diagnostics: 'pyright',
1510
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1511
}
1512
]
1513
});
1514
});
1515
1516
stest({ description: 'await cannot be used in a non-async function', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1517
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1518
files: [fromFixture('fixing/python/pyright_await_in_non_async_function.py')],
1519
queries: [
1520
{
1521
file: 'pyright_await_in_non_async_function.py',
1522
selection: [14, 0, 14, 0],
1523
query: `/fix "await" allowed only within async function`,
1524
expectedIntent: Intent.Fix,
1525
diagnostics: 'pyright',
1526
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1527
}
1528
]
1529
});
1530
});
1531
1532
stest({ description: 'bad token', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1533
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1534
files: [fromFixture('fixing/python/pyright_badtoken.py')],
1535
queries: [
1536
{
1537
file: 'pyright_badtoken.py',
1538
selection: [4, 7, 4, 7],
1539
query: `/fix Invalid character in identifier`,
1540
expectedIntent: Intent.Fix,
1541
diagnostics: 'pyright',
1542
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1543
}
1544
]
1545
});
1546
});
1547
1548
stest({ description: 'Bar does not define a do_something2 method', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1549
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1550
files: [fromFixture('fixing/python/pyright_missing_method.py')],
1551
queries: [
1552
{
1553
file: 'pyright_missing_method.py',
1554
selection: [28, 0, 28, 0],
1555
query: [
1556
`/fix Cannot access member "do_something2" for type "Bar"`,
1557
` Member "do_something2" is unknown`
1558
].join('\n'),
1559
expectedIntent: Intent.Fix,
1560
diagnostics: 'pyright',
1561
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1562
}
1563
]
1564
});
1565
});
1566
1567
// Inspired by case 2 in /fix dataset version 10
1568
// Copilot misunderstood the directive and did a non-null check on the wrong variable
1569
stest({ description: '(AML-10-2) can not be assigned 1', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1570
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1571
files: [fromFixture('fixing/python/pyright_can_not_be_assigned_to_1.py')],
1572
queries: [
1573
{
1574
file: 'pyright_can_not_be_assigned_to_1.py',
1575
selection: [13, 15, 13, 15],
1576
query: [
1577
`/fix Expression of type "tuple[str | None, Path]" cannot be assigned to return type "Tuple[str, Path]`,
1578
` Type "str | None" cannot be assigned to type "str"`,
1579
` Type "None" cannot be assigned to type "str"`,
1580
].join('\n'),
1581
expectedIntent: Intent.Fix,
1582
diagnostics: 'pyright',
1583
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1584
}
1585
]
1586
});
1587
});
1588
1589
// Inspired by case 15 in /fix dataset version 10
1590
// The error was that Copilot was not able to localize exactly the code that is causing the error and it didn't provide any edit
1591
// This test has three times the error
1592
stest({ description: '(AML-10-15) object not subscriptable', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1593
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1594
files: [fromFixture('fixing/python/pyright_object_not_subscriptable.py')],
1595
queries: [
1596
{
1597
file: 'pyright_object_not_subscriptable.py',
1598
selection: [17, 8, 17, 8],
1599
query: `/fix Object of type "None" is not subscriptable`,
1600
expectedIntent: Intent.Fix,
1601
diagnostics: 'pyright',
1602
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1603
}
1604
]
1605
});
1606
});
1607
1608
// Inspired by case 35 of /fix dataset version 10
1609
// In the AML run, copilot did not understand the error and did not fix it
1610
stest({ description: '(AML-10-35) can not access member', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1611
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1612
files: [fromFixture('fixing/python/pyright_can_not_access_member.py')],
1613
queries: [
1614
{
1615
file: 'pyright_can_not_access_member.py',
1616
selection: [2, 23, 2, 23],
1617
query: [
1618
`/fix Cannot access member "includes" for type "set[Unknown]"`,
1619
` Member "includes" is unknown`
1620
].join('\n'),
1621
expectedIntent: Intent.Fix,
1622
diagnostics: 'pyright',
1623
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1624
}
1625
]
1626
});
1627
});
1628
1629
// Inspired by case 36 of /fix dataset version 10
1630
// In the AML run, copilot did not understand the error and did not fix it
1631
stest({ description: '(AML-10-36) can not be assigned 2', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1632
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1633
files: [fromFixture('fixing/python/pyright_can_not_be_assigned_to_2.py')],
1634
queries: [
1635
{
1636
file: 'pyright_can_not_be_assigned_to_2.py',
1637
selection: [4, 19, 4, 19],
1638
query: `/fix Expression of type "list[None]" cannot be assigned to declared type "List[int] | None"`,
1639
expectedIntent: Intent.Fix,
1640
diagnostics: 'pyright',
1641
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1642
}
1643
]
1644
});
1645
});
1646
1647
// Inspired by case 4 of /fix dataset version 10
1648
// In the AML run, copilot did not understand the error and did not fix it
1649
stest({ description: '(AML-10-4) parameter already assigned', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1650
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1651
files: [fromFixture('fixing/python/pyright_parameter_already_assigned.py')],
1652
queries: [
1653
{
1654
file: 'pyright_parameter_already_assigned.py',
1655
selection: [7, 33, 7, 33],
1656
query: `/fix Parameter "input_shape" is already assigned`,
1657
expectedIntent: Intent.Fix,
1658
diagnostics: 'pyright',
1659
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1660
}
1661
]
1662
});
1663
});
1664
1665
// Inspired by case 48 of /fix dataset version 10
1666
// In the AML run, copilot did not understand the error and did not fix it
1667
stest({ description: '(AML-10-48) can not be assigned 3', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1668
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1669
files: [fromFixture('fixing/python/pyright_can_not_be_assigned_to_3.py')],
1670
queries: [
1671
{
1672
file: 'pyright_can_not_be_assigned_to_3.py',
1673
selection: [9, 14, 9, 14],
1674
query: [
1675
`/fix Argument of type "dict[str, int]" cannot be assigned to parameter "platforms" of type "list[str] | str" in function "setup"`,
1676
` Type "dict[str, int]" cannot be assigned to type "list[str] | str"`,
1677
` "dict[str, int]" is incompatible with "list[str]"`,
1678
` "dict[str, int]" is incompatible with "str"`,
1679
].join('\n'),
1680
expectedIntent: Intent.Fix,
1681
diagnostics: 'pyright',
1682
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1683
}
1684
]
1685
});
1686
});
1687
1688
// Inspired by case 58 of /fix dataset version 10
1689
// The AML run has removed a big part of the code and replaced with non-minimal edits, this initial issue was not resolved
1690
stest({ description: '(AML-10-58) not defined', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1691
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1692
files: [fromFixture('fixing/python/pyright_not_defined.py')],
1693
queries: [
1694
{
1695
file: 'pyright_not_defined.py',
1696
selection: [7, 20, 7, 20],
1697
query: `/fix "T_Or" is not defined`,
1698
expectedIntent: Intent.Fix,
1699
diagnostics: 'pyright',
1700
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1701
}
1702
]
1703
});
1704
});
1705
1706
// Inspired by case 29 of /fix dataset version 10
1707
stest({ description: '(AML-10-29) instance of bool has no to_string member', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1708
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1709
files: [fromFixture('fixing/python/pyright_no_to_string_member.py')],
1710
queries: [
1711
{
1712
file: 'pyright_no_to_string_member.py',
1713
selection: [1, 19, 1, 19],
1714
query: `/fix`,
1715
expectedIntent: Intent.Fix,
1716
diagnostics: 'pyright',
1717
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1718
}
1719
]
1720
});
1721
});
1722
1723
// Inspired by case 110 of /fix dataset version 8
1724
stest({ description: '(AML-8-110) not defined', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1725
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1726
files: [fromFixture('fixing/python/pyright_self_as_first_argument.py')],
1727
queries: [
1728
{
1729
file: 'pyright_self_as_first_argument.py',
1730
selection: [7, 20, 7, 20],
1731
query: `/fix Instance methods should take a "self" parameter`,
1732
expectedIntent: Intent.Fix,
1733
diagnostics: 'pyright',
1734
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1735
}
1736
]
1737
});
1738
});
1739
1740
1741
// Inspired by case 73 of /fix dataset version 8
1742
stest({ description: '(AML-8-73) no value for argument in function call', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1743
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1744
files: [fromFixture('fixing/python/pyright_no_value_for_argument.py')],
1745
queries: [
1746
{
1747
file: 'pyright_no_value_for_argument.py',
1748
selection: [12, 16, 12, 16],
1749
query: `/fix Argument missing for parameter "error_message"`,
1750
expectedIntent: Intent.Fix,
1751
diagnostics: 'pyright',
1752
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1753
}
1754
]
1755
});
1756
});
1757
1758
stest({ description: 'undefined variable', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1759
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1760
files: [fromFixture('fixing/python/pyright_undefined_variable.py')],
1761
queries: [
1762
{
1763
file: 'pyright_undefined_variable.py',
1764
selection: [0, 0, 0, 4],
1765
query: `/fix "Play" is not defined`,
1766
expectedIntent: Intent.Fix,
1767
diagnostics: 'pyright',
1768
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1769
}
1770
]
1771
});
1772
});
1773
1774
stest({ description: 'import missing', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1775
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1776
files: [fromFixture('fixing/python/pyright_missing_import.py')],
1777
queries: [
1778
{
1779
file: 'pyright_missing_import.py',
1780
selection: [3, 26, 3, 34],
1781
query: `/fix "unittest" is not defined`,
1782
expectedIntent: Intent.Fix,
1783
diagnostics: 'pyright',
1784
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1785
}
1786
]
1787
});
1788
});
1789
1790
stest({ description: 'general type issue', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1791
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1792
files: [fromFixture('fixing/python/pyright_general_type_issue.py')],
1793
queries: [
1794
{
1795
file: 'pyright_general_type_issue.py',
1796
selection: [29, 22, 29, 25],
1797
query: [
1798
`/fix Argument of type "Msg[Foo]" cannot be assigned to parameter "msg" of type "Msg[FooBar]" in function "handle"`,
1799
` "Msg[Foo]" is incompatible with "Msg[FooBar]"`,
1800
` Type parameter "T@Msg" is invariant, but "Foo" is not the same as "FooBar"`
1801
].join('\n'),
1802
expectedIntent: Intent.Fix,
1803
diagnostics: 'pyright',
1804
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1805
}
1806
]
1807
});
1808
});
1809
1810
stest({ description: 'optional member access', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1811
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1812
files: [fromFixture('fixing/python/pyright_optional_member_access.py')],
1813
queries: [
1814
{
1815
file: 'pyright_optional_member_access.py',
1816
selection: [12, 23, 12, 28],
1817
query: `/fix "upper" is not a known member of "None"`,
1818
expectedIntent: Intent.Fix,
1819
diagnostics: 'pyright',
1820
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1821
}
1822
]
1823
});
1824
});
1825
1826
stest({ description: 'unbound variable', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
1827
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1828
files: [fromFixture('fixing/python/pyright_unbound_variable.py')],
1829
queries: [
1830
{
1831
file: 'pyright_unbound_variable.py',
1832
selection: [4, 11, 4, 12],
1833
query: `/fix "a" is possibly unbound`,
1834
expectedIntent: Intent.Fix,
1835
diagnostics: 'pyright',
1836
validate: async (outcome, workspace, accessor) => assertNoDiagnosticsAsync(accessor, outcome, workspace, 'pyright')
1837
}
1838
]
1839
});
1840
});
1841
});
1842
1843
ssuite({ title: `fix${suffix}`, subtitle: 'cpp', location: 'inline' }, () => {
1844
stest({ description: 'code fix for C++', language: 'cpp', nonExtensionConfigurations }, (testingServiceCollection) => {
1845
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1846
files: [
1847
fromFixture('fixing/cpp/basic/main.cpp'),
1848
],
1849
queries: [
1850
{
1851
file: 'main.cpp',
1852
selection: [5, 32],
1853
query: '/fix too few arguments in function call',
1854
expectedIntent: Intent.Fix,
1855
diagnostics: 'cpp',
1856
validate: async (outcome, workspace, accessor) => {
1857
assert.strictEqual(outcome.type, 'inlineEdit');
1858
assertNoOccurrence(outcome.fileContents, 'getName();');
1859
await assertLessDiagnosticsAsync(accessor, outcome, workspace, 'cpp');
1860
},
1861
},
1862
],
1863
});
1864
});
1865
});
1866
1867
/**
1868
* This method validates the outcome by finding if after the edit, there remain errors
1869
*/
1870
ssuite({ title: `fix${suffix}`, subtitle: 'roslyn', location: 'inline' }, () => {
1871
1872
// Inspired by case 28 of /fix dataset version 10
1873
// Final edit does not correspond to fetched response
1874
stest({ description: '(AML-10-28) field is never used', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1875
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1876
files: [fromFixture('fixing/csharp/roslyn_field_never_used.cs')],
1877
queries: [
1878
{
1879
file: 'roslyn_field_never_used.cs',
1880
selection: [29, 37, 29, 37],
1881
query: `/fix "The event 'Class3.event3' is never used"`,
1882
expectedIntent: Intent.Fix,
1883
diagnostics: 'roslyn',
1884
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1885
}
1886
]
1887
});
1888
});
1889
1890
// Inspired by case 57 of /fix dataset version 10
1891
stest({ description: '(AML-10-57) call is not awaited, execution continues', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1892
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1893
files: [fromFixture('fixing/csharp/roslyn_call_not_awaited.cs')],
1894
queries: [
1895
{
1896
file: 'roslyn_call_not_awaited.cs',
1897
selection: [5, 12, 5, 12],
1898
query: `/fix Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.`,
1899
expectedIntent: Intent.Fix,
1900
diagnostics: 'roslyn',
1901
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1902
}
1903
]
1904
});
1905
});
1906
1907
// Inspired by case 3523 of /fix dataset version 17
1908
stest({ description: '(AML-17-3523) has same name as', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1909
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1910
files: [fromFixture('fixing/csharp/roslyn_has_same_name_as.cs')],
1911
queries: [
1912
{
1913
file: 'roslyn_has_same_name_as.cs',
1914
selection: [3, 23, 3, 24],
1915
query: `/fix Type parameter 'W' has the same name as the type parameter from outer type 'Class1<T, U>.Class11<V, W, X, Y>'.`,
1916
expectedIntent: Intent.Fix,
1917
diagnostics: 'roslyn',
1918
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1919
}
1920
]
1921
});
1922
});
1923
1924
stest({ description: 'does not exist', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1925
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1926
files: [fromFixture('fixing/csharp/roslyn_does_not_exist.cs')],
1927
queries: [
1928
{
1929
file: 'roslyn_does_not_exist.cs',
1930
selection: [3, 26, 3, 32],
1931
query: `/fix The name 'mesage' does not exist in the current context`,
1932
expectedIntent: Intent.Fix,
1933
diagnostics: 'roslyn',
1934
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1935
}
1936
]
1937
});
1938
});
1939
1940
stest({ description: 'does not contain a definition', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1941
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1942
files: [fromFixture('fixing/csharp/roslyn_does_not_contain_definition_for.cs')],
1943
queries: [
1944
{
1945
file: 'roslyn_does_not_contain_definition_for.cs',
1946
selection: [4, 23, 4, 28],
1947
query: `/fix 'C' does not contain a definition for 'Field'`,
1948
expectedIntent: Intent.Fix,
1949
diagnostics: 'roslyn',
1950
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1951
}
1952
]
1953
});
1954
});
1955
1956
stest({ description: 'no argument given', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1957
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1958
files: [fromFixture('fixing/csharp/roslyn_no_argument_given.cs')],
1959
queries: [
1960
{
1961
file: 'roslyn_no_argument_given.cs',
1962
selection: [6, 19, 6, 20],
1963
query: `/fix There is no argument given that corresponds to the required parameter 'count' of 'C.C(int)'`,
1964
expectedIntent: Intent.Fix,
1965
diagnostics: 'roslyn',
1966
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1967
}
1968
]
1969
});
1970
});
1971
1972
stest({ description: 'missing using directive', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1973
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1974
files: [fromFixture('fixing/csharp/roslyn_missing_using_directive.cs')],
1975
queries: [
1976
{
1977
file: 'roslyn_missing_using_directive.cs',
1978
selection: [2, 5, 2, 16],
1979
query: `/fix The type or namespace name 'ConditionalAttribute' could not be found (are you missing a using directive or an assembly reference?)`,
1980
expectedIntent: Intent.Fix,
1981
diagnostics: 'roslyn',
1982
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1983
}
1984
]
1985
});
1986
});
1987
1988
stest({ description: 'semi-colon expected', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
1989
return simulateInlineChatWithStrategy(strategy, testingServiceCollection, {
1990
files: [fromFixture('fixing/csharp/roslyn_semi_colon_expected.cs')],
1991
queries: [
1992
{
1993
file: 'roslyn_semi_colon_expected.cs',
1994
selection: [4, 11, 4, 11],
1995
query: `/fix ; expected`,
1996
expectedIntent: Intent.Fix,
1997
diagnostics: 'roslyn',
1998
validate: async (outcome, workspace, accessor) => assertLessDiagnosticsAsync(accessor, outcome, workspace, 'roslyn')
1999
}
2000
]
2001
});
2002
});
2003
2004
2005
});
2006
2007
ssuite({ title: `fix${suffix}`, subtitle: 'powershell', location: 'inline' }, () => {
2008
stest({ description: 'Issue #7894', language: 'powershell', nonExtensionConfigurations }, (accessor) => {
2009
return simulateInlineChatWithStrategy(strategy, accessor, {
2010
files: [toFile({
2011
filePath: fromFixture('fix/issue-7894/shellIntegration.ps1')
2012
})],
2013
queries: [
2014
{
2015
file: 'shellIntegration.ps1',
2016
selection: [175, 0, 175, 3],
2017
query: '[psscriptanalyzer:Error]: MissingEndCurlyBrace: MissingEndCurlyBrace (in fix/issue-7894/shellIntegration.ps1)',
2018
expectedIntent: 'fix',
2019
validate: async (outcome, workspace) => {
2020
assertInlineEdit(outcome);
2021
const newText = outcome.appliedEdits.map(e => e.newText).join('');
2022
assert.strictEqual(newText.includes('param'), true);
2023
}
2024
}
2025
]
2026
});
2027
});
2028
});
2029
2030
});
2031
2032