diff --git a/extensions/typescript-language-features/src/test/completions.test.ts b/extensions/typescript-language-features/src/test/completions.test.ts index 644871101d0..6cb29a8b66d 100644 --- a/extensions/typescript-language-features/src/test/completions.test.ts +++ b/extensions/typescript-language-features/src/test/completions.test.ts @@ -3,37 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; import { disposeAll } from '../utils/dispose'; -import { createTestEditor, joinLines, wait } from './testUtils'; import { acceptFirstSuggestion, typeCommitCharacter } from './suggestTestHelpers'; +import { assertEditorContents, Config, createTestEditor, joinLines, updateConfig, VsCodeConfiguration, wait } from './testUtils'; const testDocumentUri = vscode.Uri.parse('untitled:test.ts'); -type VsCodeConfiguration = { [key: string]: any }; - -async function updateConfig(newConfig: VsCodeConfiguration): Promise { - const oldConfig: VsCodeConfiguration = {}; - const config = vscode.workspace.getConfiguration(undefined, testDocumentUri); - for (const configKey of Object.keys(newConfig)) { - oldConfig[configKey] = config.get(configKey); - await new Promise((resolve, reject) => - config.update(configKey, newConfig[configKey], vscode.ConfigurationTarget.Global) - .then(() => resolve(), reject)); - } - return oldConfig; -} - -namespace Config { - export const autoClosingBrackets = 'editor.autoClosingBrackets'; - export const completeFunctionCalls = 'typescript.suggest.completeFunctionCalls'; - export const insertMode = 'editor.suggest.insertMode'; - export const snippetSuggestions = 'editor.snippetSuggestions'; - export const suggestSelection = 'editor.suggestSelection'; -} - const insertModes = Object.freeze(['insert', 'replace']); suite('TypeScript Completions', () => { @@ -52,28 +29,27 @@ suite('TypeScript Completions', () => { await wait(100); // Save off config and apply defaults - oldConfig = await updateConfig(configDefaults); + oldConfig = await updateConfig(testDocumentUri, configDefaults); }); teardown(async () => { disposeAll(_disposables); // Restore config - await updateConfig(oldConfig); + await updateConfig(testDocumentUri, oldConfig); return vscode.commands.executeCommand('workbench.action.closeAllEditors'); }); test('Basic var completion', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `const abcdef = 123;`, `ab$0;` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `const abcdef = 123;`, `abcdef;` @@ -85,14 +61,14 @@ suite('TypeScript Completions', () => { test('Should treat period as commit character for var completions', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `const abcdef = 123;`, `ab$0;` ); - const document = await typeCommitCharacter(testDocumentUri, '.', _disposables); - assert.strictEqual( - document.getText(), + await typeCommitCharacter(testDocumentUri, '.', _disposables); + + assertEditorContents(editor, joinLines( `const abcdef = 123;`, `abcdef.;` @@ -103,14 +79,14 @@ suite('TypeScript Completions', () => { test('Should treat paren as commit character for function completions', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `function abcdef() {};`, `ab$0;` ); - const document = await typeCommitCharacter(testDocumentUri, '(', _disposables); - assert.strictEqual( - document.getText(), + await typeCommitCharacter(testDocumentUri, '(', _disposables); + + assertEditorContents(editor, joinLines( `function abcdef() {};`, `abcdef();` @@ -120,14 +96,13 @@ suite('TypeScript Completions', () => { test('Should insert backets when completing dot properties with spaces in name', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, 'const x = { "hello world": 1 };', 'x.$0' ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( 'const x = { "hello world": 1 };', 'x["hello world"]' @@ -140,14 +115,14 @@ suite('TypeScript Completions', () => { { char: '.', insert: '.' }, { char: '(', insert: '()' }, ]) { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, 'const x = { "hello world2": 1 };', 'x.$0' ); - const document = await typeCommitCharacter(testDocumentUri, char, _disposables); - assert.strictEqual( - document.getText(), + await typeCommitCharacter(testDocumentUri, char, _disposables); + + assertEditorContents(editor, joinLines( 'const x = { "hello world2": 1 };', `x["hello world2"]${insert}` @@ -161,14 +136,13 @@ suite('TypeScript Completions', () => { test('Should not prioritize bracket accessor completions. #63100', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { // 'a' should be first entry in completion list - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, 'const x = { "z-z": 1, a: 1 };', 'x.$0' ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( 'const x = { "z-z": 1, a: 1 };', 'x.a' @@ -178,7 +152,7 @@ suite('TypeScript Completions', () => { }); test('Accepting a string completion should replace the entire string. #53962', async () => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, 'interface TFunction {', ` (_: 'abc.abc2', __ ?: {}): string;`, ` (_: 'abc.abc', __?: {}): string;`, @@ -187,9 +161,8 @@ suite('TypeScript Completions', () => { `f('abc.abc$0')` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( 'interface TFunction {', ` (_: 'abc.abc2', __ ?: {}): string;`, @@ -201,17 +174,16 @@ suite('TypeScript Completions', () => { }); test('completeFunctionCalls should complete function parameters when at end of word', async () => { - await updateConfig({ [Config.completeFunctionCalls]: true }); + await updateConfig(testDocumentUri, { [Config.completeFunctionCalls]: true }); // Complete with-in word - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `function abcdef(x, y, z) { }`, `abcdef$0` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `function abcdef(x, y, z) { }`, `abcdef(x, y, z)` @@ -219,16 +191,15 @@ suite('TypeScript Completions', () => { }); test.skip('completeFunctionCalls should complete function parameters when within word', async () => { - await updateConfig({ [Config.completeFunctionCalls]: true }); + await updateConfig(testDocumentUri, { [Config.completeFunctionCalls]: true }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `function abcdef(x, y, z) { }`, `abcd$0ef` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `function abcdef(x, y, z) { }`, `abcdef(x, y, z)` @@ -236,16 +207,15 @@ suite('TypeScript Completions', () => { }); test('completeFunctionCalls should not complete function parameters at end of word if we are already in something that looks like a function call, #18131', async () => { - await updateConfig({ [Config.completeFunctionCalls]: true }); + await updateConfig(testDocumentUri, { [Config.completeFunctionCalls]: true }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `function abcdef(x, y, z) { }`, `abcdef$0(1, 2, 3)` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `function abcdef(x, y, z) { }`, `abcdef(1, 2, 3)` @@ -253,16 +223,15 @@ suite('TypeScript Completions', () => { }); test.skip('completeFunctionCalls should not complete function parameters within word if we are already in something that looks like a function call, #18131', async () => { - await updateConfig({ [Config.completeFunctionCalls]: true }); + await updateConfig(testDocumentUri, { [Config.completeFunctionCalls]: true }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `function abcdef(x, y, z) { }`, `abcd$0ef(1, 2, 3)` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `function abcdef(x, y, z) { }`, `abcdef(1, 2, 3)` @@ -271,7 +240,7 @@ suite('TypeScript Completions', () => { test('should not de-prioritize `this.member` suggestion, #74164', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` private detail = '';`, ` foo() {`, @@ -280,9 +249,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` private detail = '';`, @@ -297,7 +265,7 @@ suite('TypeScript Completions', () => { test('Member completions for string property name should insert `this.` and use brackets', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` ['xyz 123'] = 1`, ` foo() {`, @@ -306,9 +274,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` ['xyz 123'] = 1`, @@ -323,7 +290,7 @@ suite('TypeScript Completions', () => { test('Member completions for string property name already using `this.` should add brackets', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` ['xyz 123'] = 1`, ` foo() {`, @@ -332,9 +299,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` ['xyz 123'] = 1`, @@ -348,16 +314,15 @@ suite('TypeScript Completions', () => { }); test('Accepting a completion in word using `insert` mode should insert', async () => { - await updateConfig({ [Config.insertMode]: 'insert' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'insert' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `const abc = 123;`, `ab$0c` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `const abc = 123;`, `abcc` @@ -365,16 +330,15 @@ suite('TypeScript Completions', () => { }); test('Accepting a completion in word using `replace` mode should replace', async () => { - await updateConfig({ [Config.insertMode]: 'replace' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'replace' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `const abc = 123;`, `ab$0c` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `const abc = 123;`, `abc` @@ -382,9 +346,9 @@ suite('TypeScript Completions', () => { }); test('Accepting a member completion in word using `insert` mode add `this.` and insert', async () => { - await updateConfig({ [Config.insertMode]: 'insert' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'insert' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class Foo {`, ` abc = 1;`, ` foo() {`, @@ -393,9 +357,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class Foo {`, ` abc = 1;`, @@ -407,9 +370,9 @@ suite('TypeScript Completions', () => { }); test('Accepting a member completion in word using `replace` mode should add `this.` and replace', async () => { - await updateConfig({ [Config.insertMode]: 'replace' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'replace' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class Foo {`, ` abc = 1;`, ` foo() {`, @@ -418,9 +381,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class Foo {`, ` abc = 1;`, @@ -432,16 +394,15 @@ suite('TypeScript Completions', () => { }); test('Accepting string completion inside string using `insert` mode should insert', async () => { - await updateConfig({ [Config.insertMode]: 'insert' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'insert' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `const abc = { 'xy z': 123 }`, `abc["x$0y w"]` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `const abc = { 'xy z': 123 }`, `abc["xy zy w"]` @@ -450,16 +411,15 @@ suite('TypeScript Completions', () => { // Waiting on https://github.com/microsoft/TypeScript/issues/35602 test.skip('Accepting string completion inside string using insert mode should insert', async () => { - await updateConfig({ [Config.insertMode]: 'replace' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'replace' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `const abc = { 'xy z': 123 }`, `abc["x$0y w"]` ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `const abc = { 'xy z': 123 }`, `abc["xy w"]` @@ -468,7 +428,7 @@ suite('TypeScript Completions', () => { test('Private field completions on `this.#` should work', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` #xyz = 1;`, ` foo() {`, @@ -477,9 +437,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` #xyz = 1;`, @@ -494,7 +453,7 @@ suite('TypeScript Completions', () => { test('Private field completions on `#` should insert `this.`', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` #xyz = 1;`, ` foo() {`, @@ -503,9 +462,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` #xyz = 1;`, @@ -520,7 +478,7 @@ suite('TypeScript Completions', () => { test('Private field completions should not require strict prefix match (#89556)', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` #xyz = 1;`, ` foo() {`, @@ -529,9 +487,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` #xyz = 1;`, @@ -546,7 +503,7 @@ suite('TypeScript Completions', () => { test('Private field completions without `this.` should not require strict prefix match (#89556)', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` #xyz = 1;`, ` foo() {`, @@ -555,9 +512,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` #xyz = 1;`, @@ -571,9 +527,9 @@ suite('TypeScript Completions', () => { }); test('Accepting a completion for async property in `insert` mode should insert and add await', async () => { - await updateConfig({ [Config.insertMode]: 'insert' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'insert' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` xyz = Promise.resolve({ 'abc': 1 });`, ` async foo() {`, @@ -582,9 +538,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` xyz = Promise.resolve({ 'abc': 1 });`, @@ -596,9 +551,9 @@ suite('TypeScript Completions', () => { }); test('Accepting a completion for async property in `replace` mode should replace and add await', async () => { - await updateConfig({ [Config.insertMode]: 'replace' }); + await updateConfig(testDocumentUri, { [Config.insertMode]: 'replace' }); - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` xyz = Promise.resolve({ 'abc': 1 });`, ` async foo() {`, @@ -607,9 +562,8 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + assertEditorContents(editor, joinLines( `class A {`, ` xyz = Promise.resolve({ 'abc': 1 });`, @@ -622,7 +576,7 @@ suite('TypeScript Completions', () => { test.skip('Accepting a completion for async string property should add await plus brackets', async () => { await enumerateConfig(Config.insertMode, insertModes, async config => { - await createTestEditor(testDocumentUri, + const editor = await createTestEditor(testDocumentUri, `class A {`, ` xyz = Promise.resolve({ 'ab c': 1 });`, ` async foo() {`, @@ -631,9 +585,9 @@ suite('TypeScript Completions', () => { `}`, ); - const document = await acceptFirstSuggestion(testDocumentUri, _disposables); - assert.strictEqual( - document.getText(), + await acceptFirstSuggestion(testDocumentUri, _disposables); + + assertEditorContents(editor, joinLines( `class A {`, ` xyz = Promise.resolve({ 'abc': 1 });`, @@ -650,7 +604,7 @@ suite('TypeScript Completions', () => { async function enumerateConfig(configKey: string, values: readonly string[], f: (message: string) => Promise): Promise { for (const value of values) { const newConfig = { [configKey]: value }; - await updateConfig(newConfig); + await updateConfig(testDocumentUri, newConfig); await f(JSON.stringify(newConfig)); } } diff --git a/extensions/typescript-language-features/src/test/jsDocCompletions.test.ts b/extensions/typescript-language-features/src/test/jsDocCompletions.test.ts index e0f67065b0a..f9c6c39da88 100644 --- a/extensions/typescript-language-features/src/test/jsDocCompletions.test.ts +++ b/extensions/typescript-language-features/src/test/jsDocCompletions.test.ts @@ -7,20 +7,34 @@ import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; import { disposeAll } from '../utils/dispose'; -import { createTestEditor, joinLines, wait } from './testUtils'; import { acceptFirstSuggestion } from './suggestTestHelpers'; +import { Config, createTestEditor, joinLines, updateConfig, VsCodeConfiguration, wait } from './testUtils'; const testDocumentUri = vscode.Uri.parse('untitled:test.ts'); suite('JSDoc Completions', () => { const _disposables: vscode.Disposable[] = []; + const configDefaults: VsCodeConfiguration = Object.freeze({ + [Config.snippetSuggestions]: 'inline', + }); + + let oldConfig: { [key: string]: any } = {}; + setup(async () => { await wait(100); + + // Save off config and apply defaults + oldConfig = await updateConfig(testDocumentUri, configDefaults); }); teardown(async () => { disposeAll(_disposables); + + // Restore config + await updateConfig(testDocumentUri, oldConfig); + + return vscode.commands.executeCommand('workbench.action.closeAllEditors'); }); test('Should complete jsdoc inside single line comment', async () => { diff --git a/extensions/typescript-language-features/src/test/testUtils.ts b/extensions/typescript-language-features/src/test/testUtils.ts index 753814a99bd..e0b4ac867e2 100644 --- a/extensions/typescript-language-features/src/test/testUtils.ts +++ b/extensions/typescript-language-features/src/test/testUtils.ts @@ -3,10 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; +import * as assert from 'assert'; import * as fs from 'fs'; import * as os from 'os'; import { join } from 'path'; +import * as vscode from 'vscode'; function rndName() { return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10); @@ -80,4 +81,50 @@ export async function createTestEditor(uri: vscode.Uri, ...lines: string[]) { } await activeEditor.insertSnippet(new vscode.SnippetString(joinLines(...lines)), new vscode.Range(0, 0, 1000, 0)); + return activeEditor; } + +export function assertEditorContents(editor: vscode.TextEditor, expectedDocContent: string, message?: string): void { + const cursorIndex = expectedDocContent.indexOf(CURSOR); + + assert.strictEqual( + editor.document.getText(), + expectedDocContent.replace(CURSOR, ''), + message); + + if (cursorIndex >= 0) { + const expectedCursorPos = editor.document.positionAt(cursorIndex); + assert.strictEqual( + editor.selection.active.line, + expectedCursorPos.line + ); + assert.strictEqual( + editor.selection.active.character, + expectedCursorPos.character + ); + + } +} + +export type VsCodeConfiguration = { [key: string]: any }; + +export async function updateConfig(documentUri: vscode.Uri, newConfig: VsCodeConfiguration): Promise { + const oldConfig: VsCodeConfiguration = {}; + const config = vscode.workspace.getConfiguration(undefined, documentUri); + for (const configKey of Object.keys(newConfig)) { + oldConfig[configKey] = config.get(configKey); + await new Promise((resolve, reject) => + config.update(configKey, newConfig[configKey], vscode.ConfigurationTarget.Global) + .then(() => resolve(), reject)); + } + return oldConfig; +} + + +export const Config = Object.freeze({ + autoClosingBrackets: 'editor.autoClosingBrackets', + completeFunctionCalls: 'typescript.suggest.completeFunctionCalls', + insertMode: 'editor.suggest.insertMode', + snippetSuggestions: 'editor.snippetSuggestions', + suggestSelection: 'editor.suggestSelection', +} as const);