Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/inline/inlineEditCode.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 { EditCodeIntent } from '../../src/extension/intents/node/editCodeIntent';
7
import { TestingServiceCollection } from '../../src/platform/test/node/services';
8
import { Selection } from '../../src/vscodeTypes';
9
import { NonExtensionConfiguration, ssuite, stest } from '../base/stest';
10
import { KnownDiagnosticProviders } from '../simulation/diagnosticProviders';
11
import { simulateInlineChat, simulateInlineChatIntent } from '../simulation/inlineChatSimulator';
12
import { assertContainsAllSnippets, assertNoDiagnosticsAsync, assertNoElidedCodeComments, assertNoSyntacticDiagnosticsAsync, findTextBetweenMarkersFromTop } from '../simulation/outcomeValidators';
13
import { simulatePanelCodeMapper } from '../simulation/panelCodeMapperSimulator';
14
import { assertInlineEdit, assertInlineEditShape, assertNoOccurrence, assertOccursOnce, assertSomeStrings, extractInlineReplaceEdits, fromFixture, toFile } from '../simulation/stestUtil';
15
import { EditTestStrategy, IScenario } from '../simulation/types';
16
17
function executeEditTest(
18
strategy: EditTestStrategy,
19
testingServiceCollection: TestingServiceCollection,
20
scenario: IScenario
21
): Promise<void> {
22
if (strategy === EditTestStrategy.Inline) {
23
return simulateInlineChat(testingServiceCollection, scenario);
24
} else if (strategy === EditTestStrategy.InlineChatIntent) {
25
return simulateInlineChatIntent(testingServiceCollection, scenario);
26
} else {
27
return simulatePanelCodeMapper(testingServiceCollection, scenario, strategy);
28
}
29
}
30
31
function forInlineChatIntent(callback: (strategy: EditTestStrategy, location: 'inline' | 'panel', variant: string | undefined, configurations?: NonExtensionConfiguration[]) => void): void {
32
callback(EditTestStrategy.InlineChatIntent, 'inline', '-InlineChatIntent', [['chat.agent.autoFix', false]]);
33
}
34
35
forInlineChatIntent((strategy, location, variant, nonExtensionConfigurations) => {
36
37
ssuite({ title: `edit${variant}`, location }, () => {
38
stest({ description: 'Context Outline: TypeScript between methods', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
39
return executeEditTest(strategy, testingServiceCollection, {
40
files: [fromFixture('vscode/codeEditorWidget.ts')],
41
queries: [
42
{
43
file: 'codeEditorWidget.ts',
44
selection: [211, 0, 213, 0],
45
query: 'convert private property to lowercase',
46
expectedIntent: EditCodeIntent.ID,
47
validate: async (outcome, workspace, accessor) => {
48
assertInlineEdit(outcome);
49
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
50
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
51
const edit = assertInlineEditShape(outcome, {
52
line: 211,
53
originalLength: 2,
54
modifiedLength: 2,
55
});
56
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['_onkeyup']);
57
assertNoElidedCodeComments(outcome.fileContents);
58
}
59
}
60
]
61
});
62
});
63
64
stest({ description: 'Context Outline: TypeScript in method', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
65
return executeEditTest(strategy, testingServiceCollection, {
66
files: [fromFixture('vscode/codeEditorWidget.ts')],
67
queries: [
68
{
69
file: 'codeEditorWidget.ts',
70
selection: [1085, 2, 1089, 3],
71
query: 'log to console in case the action is missing',
72
expectedIntent: EditCodeIntent.ID,
73
validate: async (outcome, workspace, accessor) => {
74
assertInlineEdit(outcome);
75
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
76
const edit = assertInlineEditShape(outcome, [{
77
line: 1089,
78
originalLength: 0,
79
modifiedLength: 2,
80
}, {
81
line: 1090,
82
originalLength: 0,
83
modifiedLength: 1,
84
}, {
85
line: 1090,
86
originalLength: 9,
87
modifiedLength: 1,
88
}, {
89
line: 1091,
90
originalLength: 0,
91
modifiedLength: 2,
92
}, {
93
line: 1091,
94
originalLength: 8,
95
modifiedLength: 1,
96
}]);
97
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['console']);
98
assertNoElidedCodeComments(outcome.fileContents);
99
}
100
}
101
]
102
});
103
});
104
105
stest({ description: 'issue #404: Add a cat to a comment', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
106
return executeEditTest(strategy, testingServiceCollection, {
107
files: [fromFixture('ghpr/commands.ts')],
108
queries: [
109
{
110
file: 'commands.ts',
111
selection: [45, 0, 45, 79],
112
query: 'Add a cat to this comment',
113
expectedIntent: EditCodeIntent.ID,
114
validate: async (outcome, workspace, accessor) => {
115
if (outcome.type === 'conversational') {
116
// ok
117
assert.ok(true);
118
return;
119
}
120
assertInlineEdit(outcome);
121
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
122
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
123
const edit = assertInlineEditShape(outcome, [{
124
line: 45,
125
originalLength: 1,
126
modifiedLength: 1,
127
}, {
128
line: 46,
129
originalLength: 0,
130
modifiedLength: undefined,
131
}]);
132
assertSomeStrings(edit.changedModifiedLines.join('\n'), ['🐱', '( o.o )']);
133
assertNoElidedCodeComments(outcome.fileContents);
134
}
135
}
136
]
137
});
138
});
139
140
141
stest({ description: 'issue #405: "make simpler" query is surprising', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
142
// SKIPPED because of the error below
143
// <NO REPLY> {"type":"failed","reason":"Request Failed: 400 {\"error\":{\"message\":\"prompt token count of 13613 exceeds the limit of 12288\",\"code\":\"model_max_prompt_tokens_exceeded\"}}\n","requestId":"2e91a4a5-366b-4cae-b9c8-cce59d06a7bb","serverRequestId":"EA6B:3DFF07:151BC22:18DE2D8:68F22ED4","isCacheHit":false,"copilotFunctionCalls":[]}
144
if (1) {
145
throw new Error('SKIPPED');
146
}
147
148
return executeEditTest(strategy, testingServiceCollection, {
149
files: [fromFixture('vscode/extHost.api.impl.ts')],
150
queries: [
151
{
152
file: 'extHost.api.impl.ts',
153
selection: [696, 0, 711, 0],
154
query: 'make simpler',
155
expectedIntent: EditCodeIntent.ID,
156
validate: async (outcome, workspace, accessor) => {
157
if (outcome.type === 'conversational') {
158
// acceptable
159
assert.ok(true);
160
return;
161
}
162
assertInlineEdit(outcome);
163
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
164
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
165
assertNoElidedCodeComments(outcome.fileContents);
166
}
167
}
168
]
169
});
170
});
171
172
stest({ description: 'issue #246: Add comment sends request to sidebar', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
173
return executeEditTest(strategy, testingServiceCollection, {
174
files: [fromFixture('vscode/vscode.proposed.notebookDocumentWillSave.d.ts')],
175
queries: [
176
{
177
file: 'vscode.proposed.notebookDocumentWillSave.d.ts',
178
selection: [52, 5, 52, 5],
179
visibleRanges: [[0, 65]],
180
query: 'add comment',
181
expectedIntent: EditCodeIntent.ID,
182
validate: async (outcome, workspace, accessor) => {
183
assertInlineEdit(outcome);
184
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
185
assertNoElidedCodeComments(outcome.fileContents);
186
}
187
}
188
]
189
});
190
});
191
192
stest({ description: 'issue #4151: Rewrite the selection to use async/await', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
193
return executeEditTest(strategy, testingServiceCollection, {
194
files: [fromFixture('edit-asyncawait-4151/index.ts')],
195
queries: [
196
{
197
file: 'index.ts',
198
selection: [47, 0, 57, 3],
199
query: 'Rewrite the selection to use async/await',
200
expectedIntent: EditCodeIntent.ID,
201
validate: async (outcome, workspace, accessor) => {
202
assertInlineEdit(outcome);
203
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
204
const edit = assertInlineEditShape(outcome, {
205
line: 47,
206
originalLength: 10,
207
modifiedLength: 10,
208
});
209
assert.deepStrictEqual(
210
edit.changedModifiedLines.join('\n'),
211
`app.get('/episodes/:id/summary', async (req: Request, res: Response) => {\n` +
212
' try {\n' +
213
' const response = await fetch(`${process.env.PODCAST_URL}episodes/${req.params.id}`);\n' +
214
' const json: Episode = await response.json();\n' +
215
' const summary = json.description;\n' +
216
' res.send({ summary });\n' +
217
' } catch (error) {\n' +
218
' console.log(error);\n' +
219
' res.status(500).send({ error });\n' +
220
' }'
221
);
222
assertNoElidedCodeComments(outcome.fileContents);
223
},
224
},
225
],
226
});
227
});
228
229
stest({ description: 'issue #4149: If ChatGPT makes the request, send only the first 20 episodes', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
230
return executeEditTest(strategy, testingServiceCollection, {
231
files: [
232
fromFixture('edit-slice-4149/index.ts'),
233
],
234
queries: [
235
{
236
file: 'index.ts',
237
selection: [44, 1],
238
visibleRanges: [[24, 64]],
239
query: 'If ChatGPT user agent makes the request, send only the first 20 episodes',
240
expectedIntent: EditCodeIntent.ID,
241
validate: async (outcome, workspace, accessor) => {
242
assertInlineEdit(outcome);
243
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
244
const edit = extractInlineReplaceEdits(outcome);
245
assert.ok(edit, 'unexpected identical files');
246
const newText = edit.allModifiedLines.join('\n');
247
assert.ok(
248
newText.includes('\'user-agent\'')
249
|| newText.includes('\'User-Agent\'')
250
);
251
assert.ok(!newText.includes('limit: \'20\''));
252
assert.ok(newText.includes('slice(0, 20)'));
253
assert.ok(newText.includes('\'ChatGPT\''));
254
assertNoElidedCodeComments(outcome.fileContents);
255
},
256
},
257
],
258
});
259
});
260
261
stest({ description: 'issue #3759: add type', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
262
// SKIPPED because of the error below
263
// <NO REPLY> {"type":"failed","reason":"Request Failed: 400 {\"error\":{\"message\":\"prompt token count of 13613 exceeds the limit of 12288\",\"code\":\"model_max_prompt_tokens_exceeded\"}}\n","requestId":"2e91a4a5-366b-4cae-b9c8-cce59d06a7bb","serverRequestId":"EA6B:3DFF07:151BC22:18DE2D8:68F22ED4","isCacheHit":false,"copilotFunctionCalls":[]}
264
if (1) {
265
throw new Error('SKIPPED');
266
}
267
return executeEditTest(strategy, testingServiceCollection, {
268
files: [
269
fromFixture('edit-add-explicit-type-issue-3759/pullRequestModel.ts'),
270
],
271
queries: [
272
{
273
file: 'pullRequestModel.ts',
274
selection: [1071, 0],
275
visibleRanges: [[1051, 1091]],
276
query: 'Add types to `reviewRequiredCheck`',
277
expectedIntent: EditCodeIntent.ID,
278
validate: async (outcome, workspace, accessor) => {
279
assertInlineEdit(outcome);
280
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
281
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
282
const edit = assertInlineEditShape(outcome, {
283
line: 1071,
284
originalLength: 1,
285
modifiedLength: 1,
286
});
287
let text = findTextBetweenMarkersFromTop(edit.changedModifiedLines.join('\n'), 'const reviewRequiredCheck', '= await this._getReviewRequiredCheck();');
288
assert(text);
289
text = text.trim();
290
assert(text.length > 3);
291
assertNoElidedCodeComments(outcome.fileContents);
292
},
293
},
294
],
295
});
296
});
297
298
stest({ description: 'issue #1198: Multi-lingual queries throw off the inline response formatting', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
299
return executeEditTest(strategy, testingServiceCollection, {
300
files: [fromFixture('edit-issue-1198/main.py')],
301
queries: [
302
{
303
file: 'main.py',
304
selection: [1, 0, 7, 0],
305
query: 'Translate to German',
306
fileIndentInfo: { insertSpaces: true, tabSize: 4 },
307
expectedIntent: EditCodeIntent.ID,
308
validate: async (outcome, workspace, accessor) => {
309
if (outcome.type === 'conversational') {
310
// This is acceptable because translating is not strictly a development action
311
assert.ok(true);
312
return;
313
}
314
assertInlineEdit(outcome);
315
const expectedLines = [
316
`{"id": "1", "text": "Roter Karabiner, groß, Edelstahl", "url": None},`,
317
`{"id": "2", "text": "Blauer kleiner Karabiner", "url": None},`,
318
[
319
`{"id": "3", "text": "Ganzjahres-Wanderhose", "url": None},`,
320
`{"id": "3", "text": "Ganzjahreshose zum Wandern", "url": None},`,
321
],
322
[
323
`{"id": "4", "text": "Schwarze Lederschuhe, Größe 10", "url": None},`,
324
`{"id": "4", "text": "Schwarze Lederstiefel, Größe 10", "url": None},`,
325
`{"id": "4", "text": "Schwarze Lederstiefel, Größe 44", "url": None},`,
326
],
327
[
328
`{"id": "5", "text": "Gelbe wasserdichte Jacke, mittelgroß", "url": None},`,
329
`{"id": "5", "text": "Gelbe wasserdichte Jacke, mittel", "url": None},`,
330
`{"id": "5", "text": "Gelbe wasserdichte Jacke, Größe M", "url": None},`,
331
`{"id": "5", "text": "Gelbe wasserdichte Jacke, Medium", "url": None},`,
332
],
333
[
334
`{"id": "6", "text": "Grünes Campingzelt, 4 Personen", "url": None}`,
335
`{"id": "6", "text": "Grünes Campingzelt, 4-Personen", "url": None}`,
336
`{"id": "6", "text": "Grünes Campingzelt, für 4 Personen", "url": None}`,
337
]
338
];
339
const actualLines = outcome.fileContents.split('\n').map(s => s.trim()).slice(1, 7);
340
for (let i = 0; i < expectedLines.length; i++) {
341
const expected = expectedLines[i];
342
const actual = actualLines[i];
343
if (Array.isArray(expected)) {
344
assert.ok(expected.includes(actual), `Line ${i + 2} does not match any expected variant. Actual: "${actual}"`);
345
} else {
346
assert.strictEqual(actual, expected);
347
}
348
}
349
assertNoElidedCodeComments(outcome.fileContents);
350
},
351
},
352
],
353
});
354
});
355
356
stest({ description: 'refactor forloop, but only selected one', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
357
const selection: [number, number, number, number] = [109, 8, 125, 9];
358
return executeEditTest(strategy, testingServiceCollection, {
359
files: [fromFixture('edit-refactor-loop/index.ts')],
360
queries: [{
361
file: 'index.ts',
362
selection: selection,
363
query: 'change for-of loop to use an index',
364
expectedIntent: EditCodeIntent.ID,
365
validate: async (outcome, workspace, accessor) => {
366
assertInlineEdit(outcome);
367
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
368
const edit = assertInlineEditShape(outcome, [{
369
line: 109,
370
originalLength: 16,
371
modifiedLength: 16,
372
}, {
373
line: 109,
374
originalLength: 14,
375
modifiedLength: 14,
376
}, {
377
line: 109,
378
originalLength: 1,
379
modifiedLength: 2,
380
}]);
381
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['for (let i = 0; i < groups.length; i++)']);
382
assertNoElidedCodeComments(outcome.fileContents);
383
}
384
}]
385
});
386
});
387
388
stest({ description: 'convert ternary to if/else in short function', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
389
return executeEditTest(strategy, testingServiceCollection, {
390
files: [
391
fromFixture('edit-convert-ternary-to-if-else/index.ts'),
392
],
393
queries: [
394
{
395
file: 'index.ts',
396
selection: [4, 28],
397
visibleRanges: [[0, 14]],
398
query: 'convert to if/else',
399
expectedIntent: EditCodeIntent.ID,
400
validate: async (outcome, workspace, accessor) => {
401
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
402
assertInlineEdit(outcome);
403
// Only the ternary expression should be replaced
404
const edit = assertInlineEditShape(outcome, [{
405
line: 4,
406
originalLength: 1,
407
modifiedLength: undefined,
408
}, {
409
line: 4,
410
originalLength: 3,
411
modifiedLength: undefined,
412
}]);
413
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['if', 'else']);
414
assertNoElidedCodeComments(outcome.fileContents);
415
}
416
}
417
]
418
});
419
});
420
421
stest({ description: 'edit: add toString1', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
422
return executeEditTest(strategy, testingServiceCollection, {
423
files: [
424
fromFixture('edit-add-toString/index.ts'),
425
],
426
queries: [
427
{
428
file: 'index.ts',
429
selection: [53, 1],
430
visibleRanges: [[33, 73]],
431
query: 'add toString',
432
expectedIntent: EditCodeIntent.ID,
433
validate: async (outcome, workspace, accessor) => {
434
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
435
assertInlineEdit(outcome);
436
assertNoElidedCodeComments(outcome.fileContents);
437
}
438
}
439
]
440
});
441
});
442
443
stest({ description: 'edit: add toString2', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
444
return executeEditTest(strategy, testingServiceCollection, {
445
files: [
446
fromFixture('edit-add-toString2/index.ts')
447
],
448
queries: [
449
{
450
file: 'index.ts',
451
selection: [54, 1],
452
visibleRanges: [[34, 74]],
453
query: 'add toString()',
454
expectedIntent: EditCodeIntent.ID,
455
validate: async (outcome, workspace, accessor) => {
456
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
457
assertInlineEdit(outcome);
458
assertNoElidedCodeComments(outcome.fileContents);
459
}
460
}
461
]
462
});
463
});
464
465
stest({ description: 'edit: add enum variant', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
466
return executeEditTest(strategy, testingServiceCollection, {
467
files: [
468
fromFixture('edit-add-enum-variant/index.ts'),
469
],
470
queries: [
471
{
472
file: 'index.ts',
473
selection: [8, 9],
474
visibleRanges: [[0, 32]],
475
query: 'add enum variant NearBottom',
476
expectedIntent: EditCodeIntent.ID,
477
validate: async (outcome, workspace, accessor) => {
478
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
479
assertInlineEdit(outcome);
480
assertNoElidedCodeComments(outcome.fileContents);
481
}
482
}
483
]
484
});
485
});
486
487
function verifyTsImportStatementsAreTogether(fileContents: string): boolean {
488
const lines = fileContents.split('\n');
489
let i = 0;
490
while (i < lines.length && !lines[i].trim().startsWith('import ')) {
491
i++;
492
}
493
while (i < lines.length && lines[i].trim().startsWith('import ')) {
494
i++;
495
}
496
while (i < lines.length && !lines[i].trim().startsWith('import ')) {
497
i++;
498
}
499
if (lines.length !== i) {
500
return false;
501
}
502
return true;
503
}
504
505
stest({ description: 'edit: import assert', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
506
return executeEditTest(strategy, testingServiceCollection, {
507
files: [
508
fromFixture('edit-import-assert/index.ts'),
509
],
510
queries: [
511
{
512
file: 'index.ts',
513
selection: [47, 14],
514
query: 'use the assert library to check that element is defined',
515
expectedIntent: EditCodeIntent.ID,
516
validate: async (outcome, workspace, accessor) => {
517
assertInlineEdit(outcome);
518
assert(verifyTsImportStatementsAreTogether(outcome.fileContents));
519
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
520
assertNoElidedCodeComments(outcome.fileContents);
521
}
522
}
523
]
524
});
525
});
526
527
stest({ description: 'edit: import assert 2', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
528
return executeEditTest(strategy, testingServiceCollection, {
529
files: [
530
fromFixture('edit-import-assert2/index.ts'),
531
],
532
queries: [
533
{
534
file: 'index.ts',
535
selection: [5, 0],
536
query: 'use assert to check that file is defined',
537
expectedIntent: EditCodeIntent.ID,
538
validate: async (outcome, workspace, accessor) => {
539
assertInlineEdit(outcome);
540
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
541
542
function countOccurences(str: string, substr: string): number {
543
return str.split(substr).length - 1;
544
}
545
546
assert.deepStrictEqual(
547
countOccurences(outcome.fileContents, 'ises'),
548
countOccurences(outcome.fileContents, 'promises')
549
);
550
assertNoElidedCodeComments(outcome.fileContents);
551
}
552
}
553
]
554
});
555
});
556
557
stest({ description: 'issue #2431: Inline Chat follow-up tweak ends up in noop text-only answer', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
558
return executeEditTest(strategy, testingServiceCollection, {
559
files: [
560
fromFixture('vscode/editorGroupWatermark.ts'),
561
],
562
queries: [
563
{
564
file: 'editorGroupWatermark.ts',
565
selection: [24, 0],
566
query: 'Add a title to each entry, expanding what the feature does',
567
expectedIntent: EditCodeIntent.ID,
568
validate: async (outcome, workspace, accessor) => {
569
assertInlineEdit(outcome);
570
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
571
assertNoElidedCodeComments(outcome.fileContents);
572
},
573
},
574
{
575
query: 'use localize and ALL CAPS for the title',
576
expectedIntent: EditCodeIntent.ID,
577
validate: async (outcome, workspace, accessor) => {
578
assertInlineEdit(outcome);
579
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
580
assertNoElidedCodeComments(outcome.fileContents);
581
},
582
}
583
],
584
});
585
});
586
587
stest({ description: 'Inline chat does not leak system prompt', language: 'json', nonExtensionConfigurations }, (testingServiceCollection) => {
588
return executeEditTest(strategy, testingServiceCollection, {
589
files: [
590
fromFixture('gen-json/test.json'),
591
],
592
queries: [
593
{
594
file: 'test.json',
595
selection: [0, 0],
596
query: 'edit this file to contain json, use tabs',
597
expectedIntent: EditCodeIntent.ID,
598
validate: async (outcome, workspace, accessor) => {
599
assertInlineEdit(outcome);
600
['assistant', 'Microsoft', 'AI'].forEach((text) => {
601
assert.strictEqual(outcome.fileContents.includes(text), false);
602
});
603
assertNoElidedCodeComments(outcome.fileContents);
604
},
605
}
606
],
607
});
608
});
609
610
stest({ description: 'Inline chat touching code outside of my selection #2988', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
611
612
const selection = new Selection(107, 1, 132, 7);
613
614
return executeEditTest(strategy, testingServiceCollection, {
615
files: [
616
fromFixture('edit/issue-2988/pseudoStartStopConversationCallback.test.ts'),
617
],
618
queries: [
619
{
620
file: 'pseudoStartStopConversationCallback.test.ts',
621
selection: [selection.start.line, selection.start.character, selection.end.line, selection.end.character],
622
query: 'rewrite these asserts as one assert on an array',
623
expectedIntent: EditCodeIntent.ID,
624
validate: async (outcome, workspace, accessor) => {
625
assertInlineEdit(outcome);
626
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
627
628
assertInlineEditShape(outcome, [{
629
line: 123,
630
originalLength: 9,
631
modifiedLength: undefined,
632
}, {
633
line: 125,
634
originalLength: 7,
635
modifiedLength: undefined,
636
}, {
637
line: 125,
638
originalLength: 9,
639
modifiedLength: undefined,
640
}]);
641
assertNoElidedCodeComments(outcome.fileContents);
642
}
643
}
644
]
645
});
646
});
647
648
stest({ description: 'Inline chat touching code outside of my selection #2988 with good selection', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
649
650
const selection = new Selection(125, 0, 132, 0);
651
652
return executeEditTest(strategy, testingServiceCollection, {
653
files: [
654
fromFixture('edit/issue-2988/pseudoStartStopConversationCallback.test.ts'),
655
],
656
queries: [
657
{
658
file: 'pseudoStartStopConversationCallback.test.ts',
659
selection: [selection.start.line, selection.start.character, selection.end.line, selection.end.character],
660
query: 'rewrite these asserts as one assert on an array',
661
expectedIntent: EditCodeIntent.ID,
662
validate: async (outcome, workspace, accessor) => {
663
assertInlineEdit(outcome);
664
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
665
666
const edit = assertInlineEditShape(outcome, [{
667
line: 125,
668
originalLength: 7,
669
modifiedLength: undefined,
670
}, {
671
line: 125,
672
originalLength: 9,
673
modifiedLength: undefined,
674
}]);
675
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['assert.deepStrictEqual', '[', ']']);
676
assertNoElidedCodeComments(outcome.fileContents);
677
}
678
}
679
]
680
});
681
});
682
683
stest({ description: 'issue #2946: Inline chat markers don\'t work', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
684
return executeEditTest(strategy, testingServiceCollection, {
685
files: [
686
fromFixture('editing/math.js'),
687
],
688
queries: [
689
{
690
file: 'math.js',
691
selection: [17, 0, 32, 1],
692
query: 'use recursion',
693
expectedIntent: EditCodeIntent.ID,
694
validate: async (outcome, workspace, accessor) => {
695
const edit = assertInlineEditShape(outcome, [{
696
line: 21,
697
originalLength: 11,
698
modifiedLength: 1,
699
}, {
700
line: 22,
701
originalLength: 10,
702
modifiedLength: 1,
703
}]);
704
assertContainsAllSnippets(edit.changedModifiedLines[0], ['return', 'doSomething', 'n - 1', 'n - 2']);
705
assertInlineEdit(outcome);
706
assertNoElidedCodeComments(outcome.fileContents);
707
}
708
}
709
],
710
});
711
});
712
713
stest({ description: 'issue #3257: Inline chat ends up duplicating code', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
714
return executeEditTest(strategy, testingServiceCollection, {
715
files: [
716
fromFixture('editing/mainThreadChatAgents2.ts'),
717
],
718
queries: [
719
{
720
file: 'mainThreadChatAgents2.ts',
721
selection: [100, 3],
722
visibleRanges: [[80, 120]],
723
query: 'add a function for welcome message',
724
expectedIntent: EditCodeIntent.ID,
725
validate: async (outcome, workspace, accessor) => {
726
const edit = assertInlineEditShape(outcome, {
727
line: 100,
728
originalLength: 1,
729
modifiedLength: undefined,
730
});
731
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), [': async']);
732
assertInlineEdit(outcome);
733
assertNoElidedCodeComments(outcome.fileContents);
734
}
735
}
736
],
737
});
738
});
739
740
stest({ description: 'issue release#275: Inline Diff refinement causes massive duplication of code', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
741
return executeEditTest(strategy, testingServiceCollection, {
742
files: [
743
fromFixture('edit/issue-release-275/BasketService.cs')
744
],
745
queries: [
746
{
747
file: 'BasketService.cs',
748
selection: [0, 0, 83, 1],
749
query: 'replace ardalis guard classes with vanilla null checking and remove dependency on ardalis throughout the class',
750
expectedIntent: EditCodeIntent.ID,
751
validate: async (outcome, workspace, accessor) => {
752
assertInlineEdit(outcome);
753
754
assertOccursOnce(outcome.fileContents, 'public class BasketService');
755
const fileContentsWithoutComments = outcome.fileContents.replace(/\/\/.*/g, '');
756
assertNoOccurrence(fileContentsWithoutComments, 'using Ardalis.GuardClauses;');
757
assertNoOccurrence(fileContentsWithoutComments, 'using Ardalis.Result;');
758
assert.ok(outcome.fileContents.split(/\r\n|\r|\n/g).length < 95, 'file stays under 95 lines');
759
assertNoElidedCodeComments(outcome.fileContents);
760
}
761
}
762
],
763
});
764
});
765
766
stest({ description: 'issue #5755: Inline edits go outside the selection', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
767
return executeEditTest(strategy, testingServiceCollection, {
768
files: [
769
fromFixture('edit/issue-5755/vscode.proposed.chatParticipantAdditions.d.ts')
770
],
771
queries: [
772
{
773
file: 'vscode.proposed.chatParticipantAdditions.d.ts',
774
selection: [158, 0, 166, 0],
775
query: 'make the comment more readable',
776
expectedIntent: EditCodeIntent.ID,
777
validate: async (outcome, workspace, accessor) => {
778
assertInlineEdit(outcome);
779
assertInlineEditShape(outcome, [{
780
line: 159,
781
originalLength: 2,
782
modifiedLength: 2,
783
}, {
784
line: 159,
785
originalLength: 4,
786
modifiedLength: 4,
787
}, {
788
line: 159,
789
originalLength: 5,
790
modifiedLength: 4,
791
}, {
792
line: 159,
793
originalLength: 4,
794
modifiedLength: 5,
795
}, {
796
line: 162,
797
originalLength: 1,
798
modifiedLength: 1,
799
}]);
800
assertNoElidedCodeComments(outcome.fileContents);
801
}
802
}
803
],
804
});
805
});
806
807
stest({ description: 'issue #4302: Code doesn\'t come with backticks', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
808
return executeEditTest(strategy, testingServiceCollection, {
809
files: [
810
fromFixture('edit/4302.ts')
811
],
812
queries: [
813
{
814
file: '4302.ts',
815
selection: [12, 0, 23, 0],
816
query: 'put it all in one line',
817
expectedIntent: EditCodeIntent.ID,
818
validate: async (outcome, workspace, accessor) => {
819
assertInlineEdit(outcome);
820
const edit = assertInlineEditShape(outcome, {
821
line: 12,
822
originalLength: 11,
823
modifiedLength: undefined,
824
});
825
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['clojure', 'coffeescript', 'fsharp', 'latex', 'markdown', 'pug', 'python', 'sql', 'yaml']);
826
assertNoElidedCodeComments(outcome.fileContents);
827
}
828
}
829
],
830
});
831
});
832
833
stest({ description: 'issue #5710: Code doesn\'t come with backticks', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
834
return executeEditTest(strategy, testingServiceCollection, {
835
files: [
836
fromFixture('edit/5710.ts')
837
],
838
queries: [
839
{
840
file: '5710.ts',
841
selection: [7, 66, 10, 5],
842
query: 'Implement the stubbed-out class members for BinaryExpression with a useful implementation.',
843
expectedIntent: EditCodeIntent.ID,
844
validate: async (outcome, workspace, accessor) => {
845
assertInlineEdit(outcome);
846
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
847
const edit = assertInlineEditShape(outcome, {
848
line: 9,
849
originalLength: 1,
850
modifiedLength: 1,
851
});
852
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['this.left', 'this.operator', 'this.right']);
853
assertNoElidedCodeComments(outcome.fileContents);
854
}
855
}
856
],
857
});
858
});
859
860
stest({ description: 'issue #3575: Inline Chat in function expands to delete whole file', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
861
return executeEditTest(strategy, testingServiceCollection, {
862
files: [
863
fromFixture('edit/3575.ts')
864
],
865
queries: [
866
{
867
file: '3575.ts',
868
selection: [51, 9, 51, 9],
869
visibleRanges: [[14, 54]],
870
query: 'make faster',
871
expectedIntent: EditCodeIntent.ID,
872
validate: async (outcome, workspace, accessor) => {
873
assertInlineEdit(outcome);
874
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
875
assertInlineEditShape(outcome, [{
876
line: 47,
877
originalLength: 4,
878
modifiedLength: undefined,
879
}, {
880
line: 47,
881
originalLength: 5,
882
modifiedLength: undefined,
883
}, {
884
line: 45,
885
originalLength: 9,
886
modifiedLength: 1,
887
}, {
888
line: 39,
889
originalLength: 13,
890
modifiedLength: undefined,
891
}, {
892
line: 39,
893
originalLength: 15,
894
modifiedLength: undefined,
895
}, {
896
line: 46,
897
originalLength: 6,
898
modifiedLength: undefined,
899
}]);
900
// assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['break']);
901
assertNoElidedCodeComments(outcome.fileContents);
902
}
903
}
904
],
905
});
906
});
907
908
stest({ description: 'edit for cpp', language: 'cpp', nonExtensionConfigurations }, (testingServiceCollection) => {
909
return executeEditTest(strategy, testingServiceCollection, {
910
files: [
911
fromFixture('cpp/basic/main.cpp')
912
],
913
queries: [
914
{
915
file: 'main.cpp',
916
selection: [4, 0, 17, 0],
917
query: 'add a parameter to getName that controls whether or not to ask for a last name',
918
expectedIntent: EditCodeIntent.ID,
919
validate: async (outcome, workspace, accessor) => {
920
assertInlineEdit(outcome);
921
assertContainsAllSnippets(outcome.fileContents, ['bool', 'lastName', 'if']);
922
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'cpp');
923
assertNoElidedCodeComments(outcome.fileContents);
924
}
925
}
926
],
927
});
928
});
929
930
stest({ description: 'edit for macro', language: 'cpp', nonExtensionConfigurations }, (testingServiceCollection) => {
931
return executeEditTest(strategy, testingServiceCollection, {
932
files: [
933
fromFixture('cpp/headers/abi_macros.hpp'),
934
],
935
queries: [
936
{
937
file: 'abi_macros.hpp',
938
selection: [0, 0, 100, 0],
939
query: 'Update the version to 4.2.4',
940
expectedIntent: EditCodeIntent.ID,
941
validate: async (outcome, workspace, accessor) => {
942
assertInlineEdit(outcome);
943
assertContainsAllSnippets(outcome.fileContents, ['#define NLOHMANN_JSON_VERSION_MAJOR 4', '#define NLOHMANN_JSON_VERSION_MINOR 2', '#define NLOHMANN_JSON_VERSION_PATCH 4']);
944
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'cpp');
945
assertNoElidedCodeComments(outcome.fileContents);
946
}
947
}
948
],
949
});
950
});
951
952
stest({ description: 'merge markdown sections', language: 'markdown', nonExtensionConfigurations }, (testingServiceCollection) => {
953
return executeEditTest(strategy, testingServiceCollection, {
954
files: [
955
fromFixture('edit/markdown/README.md')
956
],
957
queries: [
958
{
959
file: 'README.md',
960
selection: [11, 0, 32, 0],
961
query: 'merge these two sections in a single one',
962
expectedIntent: EditCodeIntent.ID,
963
validate: async (outcome, workspace, accessor) => {
964
assertInlineEdit(outcome);
965
assertContainsAllSnippets(outcome.fileContents, ['npm install monaco-editor\n```']);
966
assertNoElidedCodeComments(outcome.fileContents);
967
}
968
}
969
],
970
});
971
});
972
973
stest({ description: 'issue #5899: make this code more efficient inside markdown', language: 'markdown', nonExtensionConfigurations }, (testingServiceCollection) => {
974
return executeEditTest(strategy, testingServiceCollection, {
975
files: [
976
fromFixture('edit/markdown/explanation.md')
977
],
978
queries: [
979
{
980
file: 'explanation.md',
981
selection: [4, 0, 17, 0],
982
visibleRanges: [[0, 23]],
983
query: 'make this code more efficient',
984
expectedIntent: EditCodeIntent.ID,
985
validate: async (outcome, workspace, accessor) => {
986
assertInlineEdit(outcome);
987
assertOccursOnce(outcome.fileContents, 'Here is an example');
988
assertNoElidedCodeComments(outcome.fileContents);
989
}
990
}
991
],
992
});
993
});
994
995
stest({ description: 'issue #6276', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
996
return executeEditTest(strategy, testingServiceCollection, {
997
files: [
998
fromFixture('edit/6276.ts')
999
],
1000
queries: [
1001
{
1002
file: '6276.ts',
1003
selection: [162, 0, 163, 39],
1004
query: 'declare as fields',
1005
expectedIntent: 'edit',
1006
validate: async (outcome, workspace, accessor) => {
1007
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
1008
assertInlineEdit(outcome);
1009
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
1010
assertNoElidedCodeComments(outcome.fileContents);
1011
}
1012
}
1013
]
1014
});
1015
});
1016
1017
stest({ description: 'issue #7487', language: 'typescriptreact', nonExtensionConfigurations }, (testingServiceCollection) => {
1018
return executeEditTest(strategy, testingServiceCollection, {
1019
files: [
1020
fromFixture('edit/issue-7487/EditForm.tsx')
1021
],
1022
queries: [
1023
{
1024
file: 'EditForm.tsx',
1025
selection: [138, 0, 147, 17],
1026
query: 'smaller lighter text with more padding',
1027
diagnostics: 'tsc',
1028
expectedIntent: 'edit',
1029
validate: async (outcome, workspace, accessor) => {
1030
assertInlineEdit(outcome);
1031
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
1032
assertInlineEditShape(outcome, [{
1033
line: 142,
1034
originalLength: 1,
1035
modifiedLength: 1,
1036
}]);
1037
assertNoElidedCodeComments(outcome.fileContents);
1038
}
1039
}
1040
]
1041
});
1042
});
1043
1044
stest({ description: 'issue #6329', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
1045
return executeEditTest(strategy, testingServiceCollection, {
1046
files: [toFile({
1047
filePath: fromFixture('edit/issue-6329/math.js')
1048
})],
1049
queries: [
1050
{
1051
file: 'math.js',
1052
selection: [36, 0, 36, 0],
1053
query: 'use assert lib from nodejs to check that N is positive',
1054
diagnostics: 'tsc',
1055
expectedIntent: 'edit',
1056
validate: async (outcome, workspace, accessor) => {
1057
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
1058
assertInlineEdit(outcome);
1059
assertOccursOnce(outcome.fileContents, 'isPrime');
1060
assertNoElidedCodeComments(outcome.fileContents);
1061
}
1062
}
1063
]
1064
});
1065
});
1066
1067
stest({ description: 'issue #7202', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1068
return executeEditTest(strategy, testingServiceCollection, {
1069
files: [
1070
fromFixture('edit/issue-7202/languageModelToolsContribution.ts')
1071
],
1072
queries: [
1073
{
1074
file: 'languageModelToolsContribution.ts',
1075
selection: [112, 127, 112, 127],
1076
visibleRanges: [[92, 132]],
1077
query: 'make this message match the format of the log message below',
1078
diagnostics: 'tsc',
1079
expectedIntent: 'edit',
1080
validate: async (outcome, workspace, accessor) => {
1081
assertInlineEdit(outcome);
1082
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
1083
1084
const edit = assertInlineEditShape(outcome, {
1085
line: 112,
1086
originalLength: 1,
1087
modifiedLength: 1,
1088
});
1089
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['Extension', 'CANNOT register']);
1090
assertNoElidedCodeComments(outcome.fileContents);
1091
}
1092
}
1093
]
1094
});
1095
});
1096
1097
stest({ description: 'issue #6469', language: 'css', nonExtensionConfigurations }, (testingServiceCollection) => {
1098
return executeEditTest(strategy, testingServiceCollection, {
1099
files: [fromFixture('edit/issue-6469/inlineChat.css')],
1100
queries: [
1101
{
1102
file: 'inlineChat.css',
1103
selection: [80, 0, 81, 17],
1104
query: 'combine this',
1105
expectedIntent: 'edit',
1106
validate: async (outcome, workspace, accessor) => {
1107
assertInlineEdit(outcome);
1108
assertInlineEditShape(outcome, [{
1109
line: 80,
1110
originalLength: 2,
1111
modifiedLength: 1,
1112
}]);
1113
assertNoElidedCodeComments(outcome.fileContents);
1114
}
1115
}
1116
]
1117
});
1118
});
1119
1120
stest({ description: 'issue #6956', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
1121
return executeEditTest(strategy, testingServiceCollection, {
1122
files: [fromFixture('generate/issue-6956/.eslintrc.js')],
1123
queries: [
1124
{
1125
file: '.eslintrc.js',
1126
selection: [23, 6, 23, 6],
1127
query: 'turn prefer-const off for destructured variables',
1128
diagnostics: 'tsc',
1129
expectedIntent: 'generate',
1130
validate: async (outcome, workspace, accessor) => {
1131
assertInlineEdit(outcome);
1132
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
1133
assertNoElidedCodeComments(outcome.fileContents);
1134
}
1135
}
1136
]
1137
});
1138
});
1139
1140
stest({ description: 'Issue #7282', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
1141
return executeEditTest(strategy, testingServiceCollection, {
1142
files: [fromFixture('edit/issue-7282/math.js')],
1143
queries: [
1144
{
1145
file: 'math.js',
1146
selection: [1, 0, 8, 0],
1147
query: 'avoid recursion',
1148
diagnostics: 'tsc',
1149
expectedIntent: 'edit',
1150
validate: async (outcome, workspace, accessor) => {
1151
assertInlineEdit(outcome);
1152
assertNoElidedCodeComments(outcome.fileContents);
1153
}
1154
}
1155
]
1156
});
1157
});
1158
1159
stest({ description: 'issue #6973', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1160
return executeEditTest(strategy, testingServiceCollection, {
1161
files: [
1162
fromFixture('edit/issue-6973/utils.ts')
1163
],
1164
queries: [
1165
{
1166
file: 'utils.ts',
1167
selection: [7, 0, 17, 0],
1168
query: 'implement logging',
1169
diagnostics: 'tsc',
1170
expectedIntent: 'edit',
1171
validate: async (outcome, workspace, accessor) => {
1172
assertInlineEdit(outcome);
1173
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
1174
assertNoElidedCodeComments(outcome.fileContents);
1175
}
1176
}
1177
]
1178
});
1179
});
1180
1181
stest({ description: 'issue #7660', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1182
return executeEditTest(strategy, testingServiceCollection, {
1183
files: [fromFixture('unknown/issue-7660/positionOffsetTransformer.spec.ts')],
1184
queries: [
1185
{
1186
file: 'positionOffsetTransformer.spec.ts',
1187
selection: [0, 0, 77, 0],
1188
query: 'convert to suite, test and assert',
1189
diagnostics: 'tsc',
1190
expectedIntent: 'unknown',
1191
validate: async (outcome, workspace, accessor) => {
1192
assertInlineEdit(outcome);
1193
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
1194
const firstLine = outcome.fileContents.split('\n')[0];
1195
assert.ok(!firstLine.includes('import'), 'First line should not contain an import statement');
1196
assertNoElidedCodeComments(outcome.fileContents);
1197
}
1198
}
1199
]
1200
});
1201
});
1202
1203
stest({ description: 'issue #6614', language: 'html', nonExtensionConfigurations }, (testingServiceCollection) => {
1204
return executeEditTest(strategy, testingServiceCollection, {
1205
files: [fromFixture('edit/issue-6614/workbench-dev.html')],
1206
queries: [
1207
{
1208
file: 'workbench-dev.html',
1209
selection: [75, 4, 75, 4],
1210
visibleRanges: [[37, 77]],
1211
query: 'add a style sheel from out/vs/workbench/workbench.web.main.css',
1212
expectedIntent: 'edit',
1213
validate: async (outcome, workspace, accessor) => {
1214
assertInlineEdit(outcome);
1215
assertInlineEditShape(outcome, [{
1216
line: 76,
1217
originalLength: 0,
1218
modifiedLength: 1,
1219
}, {
1220
line: 75,
1221
originalLength: 0,
1222
modifiedLength: 1,
1223
}, {
1224
line: 71,
1225
originalLength: 0,
1226
modifiedLength: 1,
1227
}, {
1228
line: 72,
1229
originalLength: 0,
1230
modifiedLength: 1,
1231
}, {
1232
line: 66,
1233
originalLength: 0,
1234
modifiedLength: 1,
1235
}]);
1236
assertNoElidedCodeComments(outcome.fileContents);
1237
}
1238
}
1239
]
1240
});
1241
});
1242
1243
stest({ description: 'issue #6059', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1244
return executeEditTest(strategy, testingServiceCollection, {
1245
files: [fromFixture('edit/issue-6059/serializers.ts')],
1246
queries: [
1247
{
1248
file: 'serializers.ts',
1249
selection: [202, 0, 211, 5],
1250
query: 'sort properties',
1251
diagnostics: 'tsc',
1252
expectedIntent: 'edit',
1253
validate: async (outcome, workspace, accessor) => {
1254
assertInlineEdit(outcome);
1255
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
1256
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
1257
assertNoElidedCodeComments(outcome.fileContents);
1258
}
1259
}
1260
]
1261
});
1262
});
1263
1264
1265
stest({ description: 'Issue #7996 - use entire context window', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1266
return executeEditTest(strategy, testingServiceCollection, {
1267
files: [fromFixture('edit/issue-7996/codeEditorWidget.ts')],
1268
queries: [
1269
{
1270
file: 'codeEditorWidget.ts',
1271
selection: [1666, 0, 1757, 0],
1272
query: 'convert this to if/else',
1273
diagnostics: 'tsc',
1274
expectedIntent: 'edit',
1275
validate: async (outcome, workspace) => {
1276
assertInlineEdit(outcome);
1277
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
1278
assertNoElidedCodeComments(outcome.fileContents);
1279
}
1280
}
1281
]
1282
});
1283
});
1284
1285
1286
stest({ description: 'Issue #8129 (no errors)', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1287
return executeEditTest(strategy, testingServiceCollection, {
1288
files: [fromFixture('edit/issue-8129/optimize.ts')],
1289
queries: [
1290
{
1291
file: 'optimize.ts',
1292
selection: [365, 6, 376, 79],
1293
query: 'adjust the sourcemaps if we have a filecontentmapper',
1294
diagnostics: 'tsc',
1295
expectedIntent: 'edit',
1296
validate: async (outcome, workspace, accessor) => {
1297
assertInlineEdit(outcome);
1298
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
1299
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
1300
assertNoElidedCodeComments(outcome.fileContents);
1301
}
1302
}
1303
]
1304
});
1305
});
1306
1307
stest({ description: 'Issue #8129 (no syntax errors)', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
1308
return executeEditTest(strategy, testingServiceCollection, {
1309
files: [fromFixture('edit/issue-8129/optimize.ts')],
1310
queries: [
1311
{
1312
file: 'optimize.ts',
1313
selection: [365, 6, 376, 79],
1314
query: 'adjust the sourcemaps if we have a filecontentmapper',
1315
diagnostics: 'tsc',
1316
expectedIntent: 'edit',
1317
validate: async (outcome, workspace, accessor) => {
1318
assertInlineEdit(outcome);
1319
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
1320
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
1321
assertNoElidedCodeComments(outcome.fileContents);
1322
}
1323
}
1324
]
1325
});
1326
});
1327
});
1328
});
1329
1330