mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-12 09:50:11 -05:00
Enables the same `no-unexternalized-strings` with have in `vscode` in this repo. This make sure we have a more consistent style across repos and when generating edits
1330 lines
48 KiB
TypeScript
1330 lines
48 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
import assert from 'assert';
|
|
import { EditCodeIntent } from '../../src/extension/intents/node/editCodeIntent';
|
|
import { TestingServiceCollection } from '../../src/platform/test/node/services';
|
|
import { Selection } from '../../src/vscodeTypes';
|
|
import { NonExtensionConfiguration, ssuite, stest } from '../base/stest';
|
|
import { KnownDiagnosticProviders } from '../simulation/diagnosticProviders';
|
|
import { simulateInlineChat, simulateInlineChatIntent } from '../simulation/inlineChatSimulator';
|
|
import { assertContainsAllSnippets, assertNoDiagnosticsAsync, assertNoElidedCodeComments, assertNoSyntacticDiagnosticsAsync, findTextBetweenMarkersFromTop } from '../simulation/outcomeValidators';
|
|
import { simulatePanelCodeMapper } from '../simulation/panelCodeMapperSimulator';
|
|
import { assertInlineEdit, assertInlineEditShape, assertNoOccurrence, assertOccursOnce, assertSomeStrings, extractInlineReplaceEdits, fromFixture, toFile } from '../simulation/stestUtil';
|
|
import { EditTestStrategy, IScenario } from '../simulation/types';
|
|
|
|
function executeEditTest(
|
|
strategy: EditTestStrategy,
|
|
testingServiceCollection: TestingServiceCollection,
|
|
scenario: IScenario
|
|
): Promise<void> {
|
|
if (strategy === EditTestStrategy.Inline) {
|
|
return simulateInlineChat(testingServiceCollection, scenario);
|
|
} else if (strategy === EditTestStrategy.InlineChatIntent) {
|
|
return simulateInlineChatIntent(testingServiceCollection, scenario);
|
|
} else {
|
|
return simulatePanelCodeMapper(testingServiceCollection, scenario, strategy);
|
|
}
|
|
}
|
|
|
|
function forInlineAndInlineChatIntent(callback: (strategy: EditTestStrategy, location: 'inline' | 'panel', variant: string | undefined, configurations?: NonExtensionConfiguration[]) => void): void {
|
|
callback(EditTestStrategy.Inline, 'inline', '', undefined);
|
|
callback(EditTestStrategy.InlineChatIntent, 'inline', '-InlineChatIntent', [['inlineChat.enableV2', true], ['chat.agent.autoFix', false]]);
|
|
}
|
|
|
|
forInlineAndInlineChatIntent((strategy, location, variant, nonExtensionConfigurations) => {
|
|
|
|
ssuite({ title: `edit${variant}`, location }, () => {
|
|
stest({ description: 'Context Outline: TypeScript between methods', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('vscode/codeEditorWidget.ts')],
|
|
queries: [
|
|
{
|
|
file: 'codeEditorWidget.ts',
|
|
selection: [211, 0, 213, 0],
|
|
query: 'convert private property to lowercase',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 211,
|
|
originalLength: 2,
|
|
modifiedLength: 2,
|
|
});
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['_onkeyup']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'Context Outline: TypeScript in method', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('vscode/codeEditorWidget.ts')],
|
|
queries: [
|
|
{
|
|
file: 'codeEditorWidget.ts',
|
|
selection: [1085, 2, 1089, 3],
|
|
query: 'log to console in case the action is missing',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = assertInlineEditShape(outcome, [{
|
|
line: 1089,
|
|
originalLength: 0,
|
|
modifiedLength: 2,
|
|
}, {
|
|
line: 1090,
|
|
originalLength: 0,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 1090,
|
|
originalLength: 9,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 1091,
|
|
originalLength: 0,
|
|
modifiedLength: 2,
|
|
}, {
|
|
line: 1091,
|
|
originalLength: 8,
|
|
modifiedLength: 1,
|
|
}]);
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['console']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #404: Add a cat to a comment', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('ghpr/commands.ts')],
|
|
queries: [
|
|
{
|
|
file: 'commands.ts',
|
|
selection: [45, 0, 45, 79],
|
|
query: 'Add a cat to this comment',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
if (outcome.type === 'conversational') {
|
|
// ok
|
|
assert.ok(true);
|
|
return;
|
|
}
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = assertInlineEditShape(outcome, [{
|
|
line: 45,
|
|
originalLength: 1,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 46,
|
|
originalLength: 0,
|
|
modifiedLength: undefined,
|
|
}]);
|
|
assertSomeStrings(edit.changedModifiedLines.join('\n'), ['🐱', '( o.o )']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
|
|
stest({ description: 'issue #405: "make simpler" query is surprising', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
// SKIPPED because of the error below
|
|
// <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":[]}
|
|
if (1) {
|
|
throw new Error('SKIPPED');
|
|
}
|
|
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('vscode/extHost.api.impl.ts')],
|
|
queries: [
|
|
{
|
|
file: 'extHost.api.impl.ts',
|
|
selection: [696, 0, 711, 0],
|
|
query: 'make simpler',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
if (outcome.type === 'conversational') {
|
|
// acceptable
|
|
assert.ok(true);
|
|
return;
|
|
}
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #246: Add comment sends request to sidebar', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('vscode/vscode.proposed.notebookDocumentWillSave.d.ts')],
|
|
queries: [
|
|
{
|
|
file: 'vscode.proposed.notebookDocumentWillSave.d.ts',
|
|
selection: [52, 5, 52, 5],
|
|
visibleRanges: [[0, 65]],
|
|
query: 'add comment',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #4151: Rewrite the selection to use async/await', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit-asyncawait-4151/index.ts')],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [47, 0, 57, 3],
|
|
query: 'Rewrite the selection to use async/await',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 47,
|
|
originalLength: 10,
|
|
modifiedLength: 10,
|
|
});
|
|
assert.deepStrictEqual(
|
|
edit.changedModifiedLines.join('\n'),
|
|
`app.get('/episodes/:id/summary', async (req: Request, res: Response) => {\n` +
|
|
' try {\n' +
|
|
' const response = await fetch(`${process.env.PODCAST_URL}episodes/${req.params.id}`);\n' +
|
|
' const json: Episode = await response.json();\n' +
|
|
' const summary = json.description;\n' +
|
|
' res.send({ summary });\n' +
|
|
' } catch (error) {\n' +
|
|
' console.log(error);\n' +
|
|
' res.status(500).send({ error });\n' +
|
|
' }'
|
|
);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #4149: If ChatGPT makes the request, send only the first 20 episodes', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-slice-4149/index.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [44, 1],
|
|
visibleRanges: [[24, 64]],
|
|
query: 'If ChatGPT user agent makes the request, send only the first 20 episodes',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = extractInlineReplaceEdits(outcome);
|
|
assert.ok(edit, 'unexpected identical files');
|
|
const newText = edit.allModifiedLines.join('\n');
|
|
assert.ok(
|
|
newText.includes('\'user-agent\'')
|
|
|| newText.includes('\'User-Agent\'')
|
|
);
|
|
assert.ok(!newText.includes('limit: \'20\''));
|
|
assert.ok(newText.includes('slice(0, 20)'));
|
|
assert.ok(newText.includes('\'ChatGPT\''));
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #3759: add type', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
// SKIPPED because of the error below
|
|
// <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":[]}
|
|
if (1) {
|
|
throw new Error('SKIPPED');
|
|
}
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-add-explicit-type-issue-3759/pullRequestModel.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'pullRequestModel.ts',
|
|
selection: [1071, 0],
|
|
visibleRanges: [[1051, 1091]],
|
|
query: 'Add types to `reviewRequiredCheck`',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 1071,
|
|
originalLength: 1,
|
|
modifiedLength: 1,
|
|
});
|
|
let text = findTextBetweenMarkersFromTop(edit.changedModifiedLines.join('\n'), 'const reviewRequiredCheck', '= await this._getReviewRequiredCheck();');
|
|
assert(text);
|
|
text = text.trim();
|
|
assert(text.length > 3);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #1198: Multi-lingual queries throw off the inline response formatting', language: 'python', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit-issue-1198/main.py')],
|
|
queries: [
|
|
{
|
|
file: 'main.py',
|
|
selection: [1, 0, 7, 0],
|
|
query: 'Translate to German',
|
|
fileIndentInfo: { insertSpaces: true, tabSize: 4 },
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
if (outcome.type === 'conversational') {
|
|
// This is acceptable because translating is not strictly a development action
|
|
assert.ok(true);
|
|
return;
|
|
}
|
|
assertInlineEdit(outcome);
|
|
const expectedLines = [
|
|
`{"id": "1", "text": "Roter Karabiner, groß, Edelstahl", "url": None},`,
|
|
`{"id": "2", "text": "Blauer kleiner Karabiner", "url": None},`,
|
|
[
|
|
`{"id": "3", "text": "Ganzjahres-Wanderhose", "url": None},`,
|
|
`{"id": "3", "text": "Ganzjahreshose zum Wandern", "url": None},`,
|
|
],
|
|
[
|
|
`{"id": "4", "text": "Schwarze Lederschuhe, Größe 10", "url": None},`,
|
|
`{"id": "4", "text": "Schwarze Lederstiefel, Größe 10", "url": None},`,
|
|
`{"id": "4", "text": "Schwarze Lederstiefel, Größe 44", "url": None},`,
|
|
],
|
|
[
|
|
`{"id": "5", "text": "Gelbe wasserdichte Jacke, mittelgroß", "url": None},`,
|
|
`{"id": "5", "text": "Gelbe wasserdichte Jacke, mittel", "url": None},`,
|
|
`{"id": "5", "text": "Gelbe wasserdichte Jacke, Größe M", "url": None},`,
|
|
`{"id": "5", "text": "Gelbe wasserdichte Jacke, Medium", "url": None},`,
|
|
],
|
|
[
|
|
`{"id": "6", "text": "Grünes Campingzelt, 4 Personen", "url": None}`,
|
|
`{"id": "6", "text": "Grünes Campingzelt, 4-Personen", "url": None}`,
|
|
`{"id": "6", "text": "Grünes Campingzelt, für 4 Personen", "url": None}`,
|
|
]
|
|
];
|
|
const actualLines = outcome.fileContents.split('\n').map(s => s.trim()).slice(1, 7);
|
|
for (let i = 0; i < expectedLines.length; i++) {
|
|
const expected = expectedLines[i];
|
|
const actual = actualLines[i];
|
|
if (Array.isArray(expected)) {
|
|
assert.ok(expected.includes(actual), `Line ${i + 2} does not match any expected variant. Actual: "${actual}"`);
|
|
} else {
|
|
assert.strictEqual(actual, expected);
|
|
}
|
|
}
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'refactor forloop, but only selected one', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
const selection: [number, number, number, number] = [109, 8, 125, 9];
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit-refactor-loop/index.ts')],
|
|
queries: [{
|
|
file: 'index.ts',
|
|
selection: selection,
|
|
query: 'change for-of loop to use an index',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = assertInlineEditShape(outcome, [{
|
|
line: 109,
|
|
originalLength: 16,
|
|
modifiedLength: 16,
|
|
}, {
|
|
line: 109,
|
|
originalLength: 14,
|
|
modifiedLength: 14,
|
|
}, {
|
|
line: 109,
|
|
originalLength: 1,
|
|
modifiedLength: 2,
|
|
}]);
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['for (let i = 0; i < groups.length; i++)']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'convert ternary to if/else in short function', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-convert-ternary-to-if-else/index.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [4, 28],
|
|
visibleRanges: [[0, 14]],
|
|
query: 'convert to if/else',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEdit(outcome);
|
|
// Only the ternary expression should be replaced
|
|
const edit = assertInlineEditShape(outcome, [{
|
|
line: 4,
|
|
originalLength: 1,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 4,
|
|
originalLength: 3,
|
|
modifiedLength: undefined,
|
|
}]);
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['if', 'else']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'edit: add toString1', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-add-toString/index.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [53, 1],
|
|
visibleRanges: [[33, 73]],
|
|
query: 'add toString',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEdit(outcome);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'edit: add toString2', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-add-toString2/index.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [54, 1],
|
|
visibleRanges: [[34, 74]],
|
|
query: 'add toString()',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEdit(outcome);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'edit: add enum variant', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-add-enum-variant/index.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [8, 9],
|
|
visibleRanges: [[0, 32]],
|
|
query: 'add enum variant NearBottom',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEdit(outcome);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
function verifyTsImportStatementsAreTogether(fileContents: string): boolean {
|
|
const lines = fileContents.split('\n');
|
|
let i = 0;
|
|
while (i < lines.length && !lines[i].trim().startsWith('import ')) {
|
|
i++;
|
|
}
|
|
while (i < lines.length && lines[i].trim().startsWith('import ')) {
|
|
i++;
|
|
}
|
|
while (i < lines.length && !lines[i].trim().startsWith('import ')) {
|
|
i++;
|
|
}
|
|
if (lines.length !== i) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
stest({ description: 'edit: import assert', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-import-assert/index.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [47, 14],
|
|
query: 'use the assert library to check that element is defined',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assert(verifyTsImportStatementsAreTogether(outcome.fileContents));
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'edit: import assert 2', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit-import-assert2/index.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'index.ts',
|
|
selection: [5, 0],
|
|
query: 'use assert to check that file is defined',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
|
|
function countOccurences(str: string, substr: string): number {
|
|
return str.split(substr).length - 1;
|
|
}
|
|
|
|
assert.deepStrictEqual(
|
|
countOccurences(outcome.fileContents, 'ises'),
|
|
countOccurences(outcome.fileContents, 'promises')
|
|
);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #2431: Inline Chat follow-up tweak ends up in noop text-only answer', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('vscode/editorGroupWatermark.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'editorGroupWatermark.ts',
|
|
selection: [24, 0],
|
|
query: 'Add a title to each entry, expanding what the feature does',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
},
|
|
{
|
|
query: 'use localize and ALL CAPS for the title',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'Inline chat does not leak system prompt', language: 'json', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('gen-json/test.json'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'test.json',
|
|
selection: [0, 0],
|
|
query: 'edit this file to contain json, use tabs',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
['assistant', 'Microsoft', 'AI'].forEach((text) => {
|
|
assert.strictEqual(outcome.fileContents.includes(text), false);
|
|
});
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
},
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'Inline chat touching code outside of my selection #2988', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
|
|
const selection = new Selection(107, 1, 132, 7);
|
|
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-2988/pseudoStartStopConversationCallback.test.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'pseudoStartStopConversationCallback.test.ts',
|
|
selection: [selection.start.line, selection.start.character, selection.end.line, selection.end.character],
|
|
query: 'rewrite these asserts as one assert on an array',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
|
|
assertInlineEditShape(outcome, [{
|
|
line: 123,
|
|
originalLength: 9,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 125,
|
|
originalLength: 7,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 125,
|
|
originalLength: 9,
|
|
modifiedLength: undefined,
|
|
}]);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'Inline chat touching code outside of my selection #2988 with good selection', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
|
|
const selection = new Selection(125, 0, 132, 0);
|
|
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-2988/pseudoStartStopConversationCallback.test.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'pseudoStartStopConversationCallback.test.ts',
|
|
selection: [selection.start.line, selection.start.character, selection.end.line, selection.end.character],
|
|
query: 'rewrite these asserts as one assert on an array',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
|
|
const edit = assertInlineEditShape(outcome, [{
|
|
line: 125,
|
|
originalLength: 7,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 125,
|
|
originalLength: 9,
|
|
modifiedLength: undefined,
|
|
}]);
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['assert.deepStrictEqual', '[', ']']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #2946: Inline chat markers don\'t work', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('editing/math.js'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'math.js',
|
|
selection: [17, 0, 32, 1],
|
|
query: 'use recursion',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
const edit = assertInlineEditShape(outcome, [{
|
|
line: 21,
|
|
originalLength: 11,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 22,
|
|
originalLength: 10,
|
|
modifiedLength: 1,
|
|
}]);
|
|
assertContainsAllSnippets(edit.changedModifiedLines[0], ['return', 'doSomething', 'n - 1', 'n - 2']);
|
|
assertInlineEdit(outcome);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #3257: Inline chat ends up duplicating code', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('editing/mainThreadChatAgents2.ts'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'mainThreadChatAgents2.ts',
|
|
selection: [100, 3],
|
|
visibleRanges: [[80, 120]],
|
|
query: 'add a function for welcome message',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 100,
|
|
originalLength: 1,
|
|
modifiedLength: undefined,
|
|
});
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), [': async']);
|
|
assertInlineEdit(outcome);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue release#275: Inline Diff refinement causes massive duplication of code', language: 'csharp', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-release-275/BasketService.cs')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'BasketService.cs',
|
|
selection: [0, 0, 83, 1],
|
|
query: 'replace ardalis guard classes with vanilla null checking and remove dependency on ardalis throughout the class',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
|
|
assertOccursOnce(outcome.fileContents, 'public class BasketService');
|
|
const fileContentsWithoutComments = outcome.fileContents.replace(/\/\/.*/g, '');
|
|
assertNoOccurrence(fileContentsWithoutComments, 'using Ardalis.GuardClauses;');
|
|
assertNoOccurrence(fileContentsWithoutComments, 'using Ardalis.Result;');
|
|
assert.ok(outcome.fileContents.split(/\r\n|\r|\n/g).length < 95, 'file stays under 95 lines');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #5755: Inline edits go outside the selection', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-5755/vscode.proposed.chatParticipantAdditions.d.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'vscode.proposed.chatParticipantAdditions.d.ts',
|
|
selection: [158, 0, 166, 0],
|
|
query: 'make the comment more readable',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertInlineEditShape(outcome, [{
|
|
line: 159,
|
|
originalLength: 2,
|
|
modifiedLength: 2,
|
|
}, {
|
|
line: 159,
|
|
originalLength: 4,
|
|
modifiedLength: 4,
|
|
}, {
|
|
line: 159,
|
|
originalLength: 5,
|
|
modifiedLength: 4,
|
|
}, {
|
|
line: 159,
|
|
originalLength: 4,
|
|
modifiedLength: 5,
|
|
}, {
|
|
line: 162,
|
|
originalLength: 1,
|
|
modifiedLength: 1,
|
|
}]);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #4302: Code doesn\'t come with backticks', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/4302.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: '4302.ts',
|
|
selection: [12, 0, 23, 0],
|
|
query: 'put it all in one line',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 12,
|
|
originalLength: 11,
|
|
modifiedLength: undefined,
|
|
});
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['clojure', 'coffeescript', 'fsharp', 'latex', 'markdown', 'pug', 'python', 'sql', 'yaml']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #5710: Code doesn\'t come with backticks', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/5710.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: '5710.ts',
|
|
selection: [7, 66, 10, 5],
|
|
query: 'Implement the stubbed-out class members for BinaryExpression with a useful implementation.',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 9,
|
|
originalLength: 1,
|
|
modifiedLength: 1,
|
|
});
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['this.left', 'this.operator', 'this.right']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #3575: Inline Chat in function expands to delete whole file', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/3575.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: '3575.ts',
|
|
selection: [51, 9, 51, 9],
|
|
visibleRanges: [[14, 54]],
|
|
query: 'make faster',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEditShape(outcome, [{
|
|
line: 47,
|
|
originalLength: 4,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 47,
|
|
originalLength: 5,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 45,
|
|
originalLength: 9,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 39,
|
|
originalLength: 13,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 39,
|
|
originalLength: 15,
|
|
modifiedLength: undefined,
|
|
}, {
|
|
line: 46,
|
|
originalLength: 6,
|
|
modifiedLength: undefined,
|
|
}]);
|
|
// assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['break']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'edit for cpp', language: 'cpp', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('cpp/basic/main.cpp')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'main.cpp',
|
|
selection: [4, 0, 17, 0],
|
|
query: 'add a parameter to getName that controls whether or not to ask for a last name',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertContainsAllSnippets(outcome.fileContents, ['bool', 'lastName', 'if']);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'cpp');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'edit for macro', language: 'cpp', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('cpp/headers/abi_macros.hpp'),
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'abi_macros.hpp',
|
|
selection: [0, 0, 100, 0],
|
|
query: 'Update the version to 4.2.4',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertContainsAllSnippets(outcome.fileContents, ['#define NLOHMANN_JSON_VERSION_MAJOR 4', '#define NLOHMANN_JSON_VERSION_MINOR 2', '#define NLOHMANN_JSON_VERSION_PATCH 4']);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'cpp');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'merge markdown sections', language: 'markdown', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/markdown/README.md')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'README.md',
|
|
selection: [11, 0, 32, 0],
|
|
query: 'merge these two sections in a single one',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertContainsAllSnippets(outcome.fileContents, ['npm install monaco-editor\n```']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #5899: make this code more efficient inside markdown', language: 'markdown', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/markdown/explanation.md')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'explanation.md',
|
|
selection: [4, 0, 17, 0],
|
|
visibleRanges: [[0, 23]],
|
|
query: 'make this code more efficient',
|
|
expectedIntent: EditCodeIntent.ID,
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertOccursOnce(outcome.fileContents, 'Here is an example');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
],
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6276', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/6276.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: '6276.ts',
|
|
selection: [162, 0, 163, 39],
|
|
query: 'declare as fields',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #7487', language: 'typescriptreact', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-7487/EditForm.tsx')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'EditForm.tsx',
|
|
selection: [138, 0, 147, 17],
|
|
query: 'smaller lighter text with more padding',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEditShape(outcome, [{
|
|
line: 142,
|
|
originalLength: 1,
|
|
modifiedLength: 1,
|
|
}]);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6329', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [toFile({
|
|
filePath: fromFixture('edit/issue-6329/math.js')
|
|
})],
|
|
queries: [
|
|
{
|
|
file: 'math.js',
|
|
selection: [36, 0, 36, 0],
|
|
query: 'use assert lib from nodejs to check that N is positive',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
await assertNoDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertInlineEdit(outcome);
|
|
assertOccursOnce(outcome.fileContents, 'isPrime');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #7202', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-7202/languageModelToolsContribution.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'languageModelToolsContribution.ts',
|
|
selection: [112, 127, 112, 127],
|
|
visibleRanges: [[92, 132]],
|
|
query: 'make this message match the format of the log message below',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
|
|
const edit = assertInlineEditShape(outcome, {
|
|
line: 112,
|
|
originalLength: 1,
|
|
modifiedLength: 1,
|
|
});
|
|
assertContainsAllSnippets(edit.changedModifiedLines.join('\n'), ['Extension', 'CANNOT register']);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6469', language: 'css', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-6469/inlineChat.css')],
|
|
queries: [
|
|
{
|
|
file: 'inlineChat.css',
|
|
selection: [80, 0, 81, 17],
|
|
query: 'combine this',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertInlineEditShape(outcome, [{
|
|
line: 80,
|
|
originalLength: 2,
|
|
modifiedLength: 1,
|
|
}]);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6956', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('generate/issue-6956/.eslintrc.js')],
|
|
queries: [
|
|
{
|
|
file: '.eslintrc.js',
|
|
selection: [23, 6, 23, 6],
|
|
query: 'turn prefer-const off for destructured variables',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'generate',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'Issue #7282', language: 'javascript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-7282/math.js')],
|
|
queries: [
|
|
{
|
|
file: 'math.js',
|
|
selection: [1, 0, 8, 0],
|
|
query: 'avoid recursion',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6973', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [
|
|
fromFixture('edit/issue-6973/utils.ts')
|
|
],
|
|
queries: [
|
|
{
|
|
file: 'utils.ts',
|
|
selection: [7, 0, 17, 0],
|
|
query: 'implement logging',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #7660', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('unknown/issue-7660/positionOffsetTransformer.spec.ts')],
|
|
queries: [
|
|
{
|
|
file: 'positionOffsetTransformer.spec.ts',
|
|
selection: [0, 0, 77, 0],
|
|
query: 'convert to suite, test and assert',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'unknown',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
|
|
const firstLine = outcome.fileContents.split('\n')[0];
|
|
assert.ok(!firstLine.includes('import'), 'First line should not contain an import statement');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6614', language: 'html', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-6614/workbench-dev.html')],
|
|
queries: [
|
|
{
|
|
file: 'workbench-dev.html',
|
|
selection: [75, 4, 75, 4],
|
|
visibleRanges: [[37, 77]],
|
|
query: 'add a style sheel from out/vs/workbench/workbench.web.main.css',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assertInlineEditShape(outcome, [{
|
|
line: 76,
|
|
originalLength: 0,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 75,
|
|
originalLength: 0,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 71,
|
|
originalLength: 0,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 72,
|
|
originalLength: 0,
|
|
modifiedLength: 1,
|
|
}, {
|
|
line: 66,
|
|
originalLength: 0,
|
|
modifiedLength: 1,
|
|
}]);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'issue #6059', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-6059/serializers.ts')],
|
|
queries: [
|
|
{
|
|
file: 'serializers.ts',
|
|
selection: [202, 0, 211, 5],
|
|
query: 'sort properties',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, 'tsc');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
|
|
stest({ description: 'Issue #7996 - use entire context window', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-7996/codeEditorWidget.ts')],
|
|
queries: [
|
|
{
|
|
file: 'codeEditorWidget.ts',
|
|
selection: [1666, 0, 1757, 0],
|
|
query: 'convert this to if/else',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace) => {
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
|
|
stest({ description: 'Issue #8129 (no errors)', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-8129/optimize.ts')],
|
|
queries: [
|
|
{
|
|
file: 'optimize.ts',
|
|
selection: [365, 6, 376, 79],
|
|
query: 'adjust the sourcemaps if we have a filecontentmapper',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
await assertNoDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
stest({ description: 'Issue #8129 (no syntax errors)', language: 'typescript', nonExtensionConfigurations }, (testingServiceCollection) => {
|
|
return executeEditTest(strategy, testingServiceCollection, {
|
|
files: [fromFixture('edit/issue-8129/optimize.ts')],
|
|
queries: [
|
|
{
|
|
file: 'optimize.ts',
|
|
selection: [365, 6, 376, 79],
|
|
query: 'adjust the sourcemaps if we have a filecontentmapper',
|
|
diagnostics: 'tsc',
|
|
expectedIntent: 'edit',
|
|
validate: async (outcome, workspace, accessor) => {
|
|
assertInlineEdit(outcome);
|
|
assert.ok(outcome.fileContents.length > outcome.originalFileContents.length / 2, 'File was truncated');
|
|
await assertNoSyntacticDiagnosticsAsync(accessor, outcome, workspace, KnownDiagnosticProviders.tscIgnoreImportErrors);
|
|
assertNoElidedCodeComments(outcome.fileContents);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
});
|
|
});
|
|
});
|