Archived
1
0

chore(vscode): update to 1.54.2

This commit is contained in:
Joe Previte
2021-03-11 10:27:10 -07:00
1459 changed files with 53404 additions and 51004 deletions

View File

@ -7,9 +7,12 @@ import 'mocha';
import * as assert from 'assert';
import { join } from 'path';
import { commands, workspace, window, Uri, Range, Position, ViewColumn } from 'vscode';
import { assertNoRpc } from '../utils';
suite('vscode API - commands', () => {
teardown(assertNoRpc);
test('getCommands', function (done) {
let p1 = commands.getCommands().then(commands => {

View File

@ -6,9 +6,12 @@
import 'mocha';
import * as assert from 'assert';
import * as vscode from 'vscode';
import { assertNoRpc } from '../utils';
suite('vscode API - configuration', () => {
teardown(assertNoRpc);
test('configurations, language defaults', function () {
const defaultLanguageSettings = vscode.workspace.getConfiguration().get('[abcLang]');

View File

@ -5,11 +5,13 @@
import * as assert from 'assert';
import { debug, workspace, Disposable, commands, window } from 'vscode';
import { disposeAll } from '../utils';
import { assertNoRpc, disposeAll } from '../utils';
import { basename } from 'path';
suite('vscode API - debug', function () {
teardown(assertNoRpc);
test('breakpoints', async function () {
assert.equal(debug.breakpoints.length, 0);
let onDidChangeBreakpointsCounter = 0;

View File

@ -5,11 +5,14 @@
import * as assert from 'assert';
import { workspace, window, Position, Range, commands, TextEditor, TextDocument, TextEditorCursorStyle, TextEditorLineNumbersStyle, SnippetString, Selection, Uri, env } from 'vscode';
import { createRandomFile, deleteFile, closeAllEditors } from '../utils';
import { createRandomFile, deleteFile, closeAllEditors, assertNoRpc } from '../utils';
suite('vscode API - editors', () => {
teardown(closeAllEditors);
teardown(async function () {
assertNoRpc();
await closeAllEditors();
});
function withRandomFileEditor(initialContents: string, run: (editor: TextEditor, doc: TextDocument) => Thenable<void>): Thenable<boolean> {
return createRandomFile(initialContents).then(file => {

View File

@ -5,9 +5,12 @@
import * as assert from 'assert';
import { env, extensions, ExtensionKind, UIKind, Uri } from 'vscode';
import { assertNoRpc } from '../utils';
suite('vscode API - env', () => {
teardown(assertNoRpc);
test('env is set', function () {
assert.equal(typeof env.language, 'string');
assert.equal(typeof env.appRoot, 'string');

View File

@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as assert from 'assert';
import * as vscode from 'vscode';
suite('vscode server cli', () => {
test('extension is installed and enabled when installed by server cli', function () {
const extension = process.env.TESTRESOLVER_INSTALL_BUILTIN_EXTENSION;
if (!process.env.BUILD_SOURCEVERSION // Skip it when running out of sources
|| !process.env.REMOTE_VSCODE // Skip it when not a remote integration test
|| !extension // Skip it when extension is not provided to server
) {
this.skip();
}
assert.ok(vscode.extensions.getExtension(extension!));
});
});

View File

@ -6,10 +6,12 @@
import * as assert from 'assert';
import { join } from 'path';
import * as vscode from 'vscode';
import { createRandomFile, testFs } from '../utils';
import { assertNoRpc, createRandomFile, testFs } from '../utils';
suite('vscode API - languages', () => {
teardown(assertNoRpc);
const isWindows = process.platform === 'win32';
function positionToString(p: vscode.Position) {

View File

@ -0,0 +1,391 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as vscode from 'vscode';
import * as utils from '../utils';
suite('Notebook Document', function () {
const contentProvider = new class implements vscode.NotebookContentProvider {
async openNotebook(uri: vscode.Uri, _openContext: vscode.NotebookDocumentOpenContext): Promise<vscode.NotebookData> {
return {
cells: [{ cellKind: vscode.NotebookCellKind.Code, source: uri.toString(), language: 'javascript', metadata: new vscode.NotebookCellMetadata(), outputs: [] }],
metadata: new vscode.NotebookDocumentMetadata()
};
}
async resolveNotebook(_document: vscode.NotebookDocument, _webview: vscode.NotebookCommunication) {
//
}
async saveNotebook(_document: vscode.NotebookDocument, _cancellation: vscode.CancellationToken) {
//
}
async saveNotebookAs(_targetResource: vscode.Uri, _document: vscode.NotebookDocument, _cancellation: vscode.CancellationToken) {
//
}
async backupNotebook(_document: vscode.NotebookDocument, _context: vscode.NotebookDocumentBackupContext, _cancellation: vscode.CancellationToken) {
return { id: '', delete() { } };
}
};
const disposables: vscode.Disposable[] = [];
suiteTeardown(async function () {
utils.assertNoRpc();
await utils.revertAllDirty();
await utils.closeAllEditors();
utils.disposeAll(disposables);
disposables.length = 0;
for (let doc of vscode.notebook.notebookDocuments) {
assert.strictEqual(doc.isDirty, false, doc.uri.toString());
}
});
suiteSetup(function () {
disposables.push(vscode.notebook.registerNotebookContentProvider('notebook.nbdtest', contentProvider));
});
test('cannot register sample provider multiple times', function () {
assert.throws(() => {
vscode.notebook.registerNotebookContentProvider('notebook.nbdtest', contentProvider);
});
});
test('cannot open unknown types', async function () {
try {
await vscode.notebook.openNotebookDocument(vscode.Uri.parse('some:///thing.notTypeKnown'));
assert.ok(false);
} catch {
assert.ok(true);
}
});
test('document basics', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const notebook = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(notebook.uri.toString(), uri.toString());
assert.strictEqual(notebook.isDirty, false);
assert.strictEqual(notebook.isUntitled, false);
assert.strictEqual(notebook.cells.length, 1);
assert.strictEqual(notebook.viewType, 'notebook.nbdtest');
});
test('notebook open/close, notebook ready when cell-document open event is fired', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
let didHappen = false;
const p = utils.asPromise(vscode.workspace.onDidOpenTextDocument).then(doc => {
if (doc.uri.scheme !== 'vscode-notebook-cell') {
return;
}
const notebook = vscode.notebook.notebookDocuments.find(notebook => {
const cell = notebook.cells.find(cell => cell.document === doc);
return Boolean(cell);
});
assert.ok(notebook, `notebook for cell ${doc.uri} NOT found`);
didHappen = true;
});
await vscode.notebook.openNotebookDocument(uri);
await p;
assert.strictEqual(didHappen, true);
});
test('notebook open/close, all cell-documents are ready', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const p = utils.asPromise(vscode.notebook.onDidOpenNotebookDocument).then(notebook => {
for (let cell of notebook.cells) {
const doc = vscode.workspace.textDocuments.find(doc => doc.uri.toString() === cell.uri.toString());
assert.ok(doc);
assert.strictEqual(doc.notebook === notebook, true);
assert.strictEqual(doc === cell.document, true);
assert.strictEqual(doc?.languageId, cell.language);
assert.strictEqual(doc?.isDirty, false);
assert.strictEqual(doc?.isClosed, false);
}
});
await vscode.notebook.openNotebookDocument(uri);
await p;
});
test('workspace edit API (replaceCells)', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const document = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(document.cells.length, 1);
// inserting two new cells
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, 0, 0, [{
cellKind: vscode.NotebookCellKind.Markdown,
language: 'markdown',
metadata: undefined,
outputs: [],
source: 'new_markdown'
}, {
cellKind: vscode.NotebookCellKind.Code,
language: 'fooLang',
metadata: undefined,
outputs: [],
source: 'new_code'
}]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
assert.strictEqual(document.cells.length, 3);
assert.strictEqual(document.cells[0].document.getText(), 'new_markdown');
assert.strictEqual(document.cells[1].document.getText(), 'new_code');
// deleting cell 1 and 3
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, 0, 1, []);
edit.replaceNotebookCells(document.uri, 2, 3, []);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
assert.strictEqual(document.cells.length, 1);
assert.strictEqual(document.cells[0].document.getText(), 'new_code');
// replacing all cells
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, 0, 1, [{
cellKind: vscode.NotebookCellKind.Markdown,
language: 'markdown',
metadata: undefined,
outputs: [],
source: 'new2_markdown'
}, {
cellKind: vscode.NotebookCellKind.Code,
language: 'fooLang',
metadata: undefined,
outputs: [],
source: 'new2_code'
}]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
assert.strictEqual(document.cells.length, 2);
assert.strictEqual(document.cells[0].document.getText(), 'new2_markdown');
assert.strictEqual(document.cells[1].document.getText(), 'new2_code');
// remove all cells
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, 0, document.cells.length, []);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
assert.strictEqual(document.cells.length, 0);
});
test('workspace edit API (replaceCells, event)', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const document = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(document.cells.length, 1);
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, 0, 0, [{
cellKind: vscode.NotebookCellKind.Markdown,
language: 'markdown',
metadata: undefined,
outputs: [],
source: 'new_markdown'
}, {
cellKind: vscode.NotebookCellKind.Code,
language: 'fooLang',
metadata: undefined,
outputs: [],
source: 'new_code'
}]);
const event = utils.asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebook.onDidChangeNotebookCells);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
const data = await event;
// check document
assert.strictEqual(document.cells.length, 3);
assert.strictEqual(document.cells[0].document.getText(), 'new_markdown');
assert.strictEqual(document.cells[1].document.getText(), 'new_code');
// check event data
assert.strictEqual(data.document === document, true);
assert.strictEqual(data.changes.length, 1);
assert.strictEqual(data.changes[0].deletedCount, 0);
assert.strictEqual(data.changes[0].deletedItems.length, 0);
assert.strictEqual(data.changes[0].items.length, 2);
assert.strictEqual(data.changes[0].items[0], document.cells[0]);
assert.strictEqual(data.changes[0].items[1], document.cells[1]);
});
test('workspace edit API (appendNotebookCellOutput, replaceCellOutput, event)', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const document = await vscode.notebook.openNotebookDocument(uri);
const outputChangeEvent = utils.asPromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs);
const edit = new vscode.WorkspaceEdit();
const firstCellOutput = new vscode.NotebookCellOutput([new vscode.NotebookCellOutputItem('foo', 'bar')]);
edit.appendNotebookCellOutput(document.uri, 0, [firstCellOutput]);
const success = await vscode.workspace.applyEdit(edit);
const data = await outputChangeEvent;
assert.strictEqual(success, true);
assert.strictEqual(document.cells.length, 1);
assert.strictEqual(document.cells[0].outputs.length, 1);
assert.deepStrictEqual(document.cells[0].outputs, [firstCellOutput]);
assert.strictEqual(data.document === document, true);
assert.strictEqual(data.cells.length, 1);
assert.strictEqual(data.cells[0].outputs.length, 1);
assert.deepStrictEqual(data.cells[0].outputs, [firstCellOutput]);
{
const outputChangeEvent = utils.asPromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs);
const edit = new vscode.WorkspaceEdit();
const secondCellOutput = new vscode.NotebookCellOutput([new vscode.NotebookCellOutputItem('foo', 'baz')]);
edit.appendNotebookCellOutput(document.uri, 0, [secondCellOutput]);
const success = await vscode.workspace.applyEdit(edit);
const data = await outputChangeEvent;
assert.strictEqual(success, true);
assert.strictEqual(document.cells.length, 1);
assert.strictEqual(document.cells[0].outputs.length, 2);
assert.deepStrictEqual(document.cells[0].outputs, [firstCellOutput, secondCellOutput]);
assert.strictEqual(data.document === document, true);
assert.strictEqual(data.cells.length, 1);
assert.strictEqual(data.cells[0].outputs.length, 2);
assert.deepStrictEqual(data.cells[0].outputs, [firstCellOutput, secondCellOutput]);
}
{
const outputChangeEvent = utils.asPromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs);
const edit = new vscode.WorkspaceEdit();
const thirdOutput = new vscode.NotebookCellOutput([new vscode.NotebookCellOutputItem('foo', 'baz1')]);
edit.replaceNotebookCellOutput(document.uri, 0, [thirdOutput]);
const success = await vscode.workspace.applyEdit(edit);
const data = await outputChangeEvent;
assert.strictEqual(success, true);
assert.strictEqual(document.cells.length, 1);
assert.strictEqual(document.cells[0].outputs.length, 1);
assert.deepStrictEqual(document.cells[0].outputs, [thirdOutput]);
assert.strictEqual(data.document === document, true);
assert.strictEqual(data.cells.length, 1);
assert.strictEqual(data.cells[0].outputs.length, 1);
assert.deepStrictEqual(data.cells[0].outputs, [thirdOutput]);
}
});
test('document save API', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const notebook = await vscode.notebook.openNotebookDocument(uri);
assert.strictEqual(notebook.uri.toString(), uri.toString());
assert.strictEqual(notebook.isDirty, false);
assert.strictEqual(notebook.isUntitled, false);
assert.strictEqual(notebook.cells.length, 1);
assert.strictEqual(notebook.viewType, 'notebook.nbdtest');
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(notebook.uri, 0, 0, [{
cellKind: vscode.NotebookCellKind.Markdown,
language: 'markdown',
metadata: undefined,
outputs: [],
source: 'new_markdown'
}, {
cellKind: vscode.NotebookCellKind.Code,
language: 'fooLang',
metadata: undefined,
outputs: [],
source: 'new_code'
}]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
assert.strictEqual(notebook.isDirty, true);
await notebook.save();
assert.strictEqual(notebook.isDirty, false);
});
test('setTextDocumentLanguage for notebook cells', async function () {
const uri = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const notebook = await vscode.notebook.openNotebookDocument(uri);
const first = notebook.cells[0];
assert.strictEqual(first.document.languageId, 'javascript');
const pclose = utils.asPromise(vscode.workspace.onDidCloseTextDocument);
const popen = utils.asPromise(vscode.workspace.onDidOpenTextDocument);
await vscode.languages.setTextDocumentLanguage(first.document, 'css');
assert.strictEqual(first.document.languageId, 'css');
const closed = await pclose;
const opened = await popen;
assert.strictEqual(closed.uri.toString(), first.uri.toString());
assert.strictEqual(opened.uri.toString(), first.uri.toString());
assert.strictEqual(opened === closed, true);
});
test('#117273, Add multiple outputs', async function () {
const resource = await utils.createRandomFile(undefined, undefined, '.nbdtest');
const document = await vscode.notebook.openNotebookDocument(resource);
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCellOutput(document.uri, 0, [
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem('application/x.notebook.stream', '1', { outputType: 'stream', streamName: 'stdout' })],
{ outputType: 'stream', streamName: 'stdout' }
)
]);
let success = await vscode.workspace.applyEdit(edit);
assert.ok(success);
assert.strictEqual(document.cells[0].outputs.length, 1);
assert.strictEqual(document.cells[0].outputs[0].outputs.length, 1);
assert.deepStrictEqual(document.cells[0].outputs[0].metadata, { outputType: 'stream', streamName: 'stdout' });
assert.deepStrictEqual(document.cells[0].outputs[0].outputs[0].metadata, { outputType: 'stream', streamName: 'stdout' });
const edit2 = new vscode.WorkspaceEdit();
edit2.appendNotebookCellOutput(document.uri, 0, [
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem('hello', '1', { outputType: 'stream', streamName: 'stderr' })],
{ outputType: 'stream', streamName: 'stderr' }
)
]);
success = await vscode.workspace.applyEdit(edit2);
assert.ok(success);
assert.strictEqual(document.cells[0].outputs.length, 2);
assert.strictEqual(document.cells[0].outputs[0].outputs.length, 1);
assert.strictEqual(document.cells[0].outputs[1].outputs.length, 1);
assert.deepStrictEqual(document.cells[0].outputs[0].metadata, { outputType: 'stream', streamName: 'stdout' });
assert.deepStrictEqual(document.cells[0].outputs[0].outputs[0].metadata, { outputType: 'stream', streamName: 'stdout' });
assert.deepStrictEqual(document.cells[0].outputs[1].metadata, { outputType: 'stream', streamName: 'stderr' });
assert.deepStrictEqual(document.cells[0].outputs[1].outputs[0].metadata, { outputType: 'stream', streamName: 'stderr' });
});
});

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
import * as assert from 'assert';
import { window, commands } from 'vscode';
import { closeAllEditors } from '../utils';
import { assertNoRpc, closeAllEditors } from '../utils';
interface QuickPickExpected {
events: string[];
@ -20,7 +20,10 @@ interface QuickPickExpected {
suite('vscode API - quick input', function () {
teardown(closeAllEditors);
teardown(async function () {
assertNoRpc();
await closeAllEditors();
});
test('createQuickPick, select second', function (_done) {
let done = (err?: any) => {

View File

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { assertNoRpcFromEntry, assertNoRpc, disposeAll } from '../utils';
import * as vscode from 'vscode';
suite('vscode', function () {
const dispo: vscode.Disposable[] = [];
teardown(() => {
assertNoRpc();
disposeAll(dispo);
});
test('no rpc', function () {
assertNoRpc();
});
test('no rpc, createTextEditorDecorationType(...)', function () {
const item = vscode.window.createTextEditorDecorationType({});
dispo.push(item);
assertNoRpcFromEntry([item, 'TextEditorDecorationType']);
});
test('no rpc, createOutputChannel(...)', function () {
const item = vscode.window.createOutputChannel('hello');
dispo.push(item);
assertNoRpcFromEntry([item, 'OutputChannel']);
});
test('no rpc, createDiagnosticCollection(...)', function () {
const item = vscode.languages.createDiagnosticCollection();
dispo.push(item);
assertNoRpcFromEntry([item, 'DiagnosticCollection']);
});
test('no rpc, createQuickPick(...)', function () {
const item = vscode.window.createQuickPick();
dispo.push(item);
assertNoRpcFromEntry([item, 'QuickPick']);
});
test('no rpc, createInputBox(...)', function () {
const item = vscode.window.createInputBox();
dispo.push(item);
assertNoRpcFromEntry([item, 'InputBox']);
});
test('no rpc, createStatusBarItem(...)', function () {
const item = vscode.window.createStatusBarItem();
dispo.push(item);
assertNoRpcFromEntry([item, 'StatusBarItem']);
});
test('no rpc, createSourceControl(...)', function () {
this.skip();
const item = vscode.scm.createSourceControl('foo', 'Hello');
dispo.push(item);
assertNoRpcFromEntry([item, 'SourceControl']);
});
test('no rpc, createCommentController(...)', function () {
this.skip();
const item = vscode.comments.createCommentController('foo', 'Hello');
dispo.push(item);
assertNoRpcFromEntry([item, 'CommentController']);
});
test('no rpc, createWebviewPanel(...)', function () {
const item = vscode.window.createWebviewPanel('webview', 'Hello', vscode.ViewColumn.Active);
dispo.push(item);
assertNoRpcFromEntry([item, 'WebviewPanel']);
});
test('no rpc, createTreeView(...)', function () {
const treeDataProvider = new class implements vscode.TreeDataProvider<string> {
getTreeItem(element: string): vscode.TreeItem | Thenable<vscode.TreeItem> {
return new vscode.TreeItem(element);
}
getChildren(_element?: string): vscode.ProviderResult<string[]> {
return ['foo', 'bar'];
}
};
const item = vscode.window.createTreeView('test.treeId', { treeDataProvider });
dispo.push(item);
assertNoRpcFromEntry([item, 'TreeView']);
});
test('no rpc, createNotebookEditorDecorationType(...)', function () {
const item = vscode.notebook.createNotebookEditorDecorationType({ top: {} });
dispo.push(item);
assertNoRpcFromEntry([item, 'NotebookEditorDecorationType']);
});
});

View File

@ -3,8 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget, Disposable, UIKind, env, EnvironmentVariableMutatorType, EnvironmentVariableMutator, extensions, ExtensionContext, TerminalOptions, ExtensionTerminalOptions } from 'vscode';
import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
import { window, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget, Disposable, UIKind, env, EnvironmentVariableMutatorType, EnvironmentVariableMutator, extensions, ExtensionContext, TerminalOptions, ExtensionTerminalOptions, Terminal } from 'vscode';
import { doesNotThrow, equal, deepEqual, throws, strictEqual } from 'assert';
import { assertNoRpc } from '../utils';
// Disable terminal tests:
// - Web https://github.com/microsoft/vscode/issues/92826
@ -30,61 +31,56 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
let disposables: Disposable[] = [];
teardown(() => {
assertNoRpc();
disposables.forEach(d => d.dispose());
disposables.length = 0;
});
test('sendText immediately after createTerminal should not throw', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
return;
}
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
}));
test('sendText immediately after createTerminal should not throw', async () => {
const terminal = window.createTerminal();
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
doesNotThrow(terminal.sendText.bind(terminal, 'echo "foo"'));
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
}));
terminal.dispose();
});
});
(process.platform === 'linux' ? test.skip : test)('echo works in the default shell', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
return;
}
let data = '';
const dataDisposable = window.onDidWriteTerminalData(e => {
try {
equal(terminal, e.terminal);
} catch (e) {
done(e);
return;
}
data += e.data;
if (data.indexOf(expected) !== 0) {
dataDisposable.dispose();
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => {
done();
}));
test('echo works in the default shell', async () => {
const terminal = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(terminal);
}
}));
// Use a single character to avoid winpty/conpty issues with injected sequences
const terminal = window.createTerminal({
env: { TEST: '`' }
});
disposables.push(dataDisposable);
}));
// Use a single character to avoid winpty/conpty issues with injected sequences
const expected = '`';
const terminal = window.createTerminal({
env: {
TEST: '`'
}
terminal.show();
});
terminal.show();
doesNotThrow(() => {
let data = '';
await new Promise<void>(r => {
disposables.push(window.onDidWriteTerminalData(e => {
if (e.terminal === terminal) {
data += e.data;
if (data.indexOf('`') !== 0) {
r();
}
}
}));
// Print an environment variable value so the echo statement doesn't get matched
if (process.platform === 'win32') {
terminal.sendText(`$env:TEST`);
@ -92,126 +88,143 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
terminal.sendText(`echo $TEST`);
}
});
});
test('onDidCloseTerminal event fires when terminal is disposed', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
return;
}
await new Promise<void>(r => {
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
}));
const terminal = window.createTerminal();
disposables.push(window.onDidCloseTerminal(t => {
strictEqual(terminal, t);
r();
}));
});
});
test('processId immediately after createTerminal should fetch the pid', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
return;
}
terminal.processId.then(id => {
try {
ok(id && id > 0);
} catch (e) {
done(e);
return;
test('onDidCloseTerminal event fires when terminal is disposed', async () => {
const terminal = window.createTerminal();
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
});
}));
}));
});
equal(result, terminal);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
}));
terminal.dispose();
});
});
test('processId immediately after createTerminal should fetch the pid', async () => {
const terminal = window.createTerminal();
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
let pid = await result.processId;
equal(true, pid && pid > 0);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
}));
terminal.dispose();
});
});
test('name in constructor should set terminal.name', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
return;
}
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
}));
test('name in constructor should set terminal.name', async () => {
const terminal = window.createTerminal('a');
try {
equal(terminal.name, 'a');
} catch (e) {
done(e);
return;
}
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
}));
terminal.dispose();
});
});
test('creationOptions should be set and readonly for TerminalOptions terminals', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
return;
}
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
}));
test('creationOptions should be set and readonly for TerminalOptions terminals', async () => {
const options = {
name: 'foo',
hideFromUser: true
};
const terminal = window.createTerminal(options);
try {
equal(terminal.name, 'foo');
const terminalOptions = terminal.creationOptions as TerminalOptions;
equal(terminalOptions.name, 'foo');
equal(terminalOptions.hideFromUser, true);
throws(() => terminalOptions.name = 'bad', 'creationOptions should be readonly at runtime');
} catch (e) {
done(e);
return;
}
});
test('onDidOpenTerminal should fire when a terminal is created', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(term.name, 'b');
} catch (e) {
done(e);
return;
}
disposables.push(window.onDidCloseTerminal(() => done()));
terminal.dispose();
}));
const terminal = window.createTerminal('b');
});
test('exitStatus.code should be set to undefined after a terminal is disposed', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(term, terminal);
} catch (e) {
done(e);
return;
}
disposables.push(window.onDidCloseTerminal(t => {
try {
deepEqual(t.exitStatus, { code: undefined });
} catch (e) {
done(e);
return;
const terminalOptions = terminal.creationOptions as TerminalOptions;
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
done();
}));
terminal.dispose();
}));
});
throws(() => terminalOptions.name = 'bad', 'creationOptions should be readonly at runtime');
});
test('onDidOpenTerminal should fire when a terminal is created', async () => {
const terminal = window.createTerminal('b');
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
}));
terminal.dispose();
});
});
test('exitStatus.code should be set to undefined after a terminal is disposed', async () => {
const terminal = window.createTerminal();
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
deepEqual(t.exitStatus, { code: undefined });
r();
}
}));
terminal.dispose();
});
});
// test('onDidChangeActiveTerminal should fire when new terminals are created', (done) => {
@ -285,23 +298,25 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
// });
suite('hideFromUser', () => {
test('should be available to terminals API', done => {
test('should be available to terminals API', async () => {
const terminal = window.createTerminal({ name: 'bg', hideFromUser: true });
disposables.push(window.onDidOpenTerminal(t => {
try {
equal(t, terminal);
equal(t.name, 'bg');
ok(window.terminals.indexOf(terminal) !== -1);
} catch (e) {
done(e);
return;
}
disposables.push(window.onDidCloseTerminal(() => {
// reg3.dispose();
done();
const result = await new Promise<Terminal>(r => {
disposables.push(window.onDidOpenTerminal(t => {
if (t === terminal) {
r(t);
}
}));
});
equal(result, terminal);
equal(true, window.terminals.indexOf(terminal) !== -1);
await new Promise<void>(r => {
disposables.push(window.onDidCloseTerminal(t => {
if (t === terminal) {
r();
}
}));
terminal.dispose();
}));
});
});
});
@ -626,10 +641,7 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
'~c2~c1'
];
disposables.push(window.onDidWriteTerminalData(e => {
try {
equal(terminal, e.terminal);
} catch (e) {
done(e);
if (terminal !== e.terminal) {
return;
}
// Multiple expected could show up in the same data event
@ -672,10 +684,7 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
'~c2~'
];
disposables.push(window.onDidWriteTerminalData(e => {
try {
equal(terminal, e.terminal);
} catch (e) {
done(e);
if (terminal !== e.terminal) {
return;
}
// Multiple expected could show up in the same data event
@ -717,10 +726,7 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
'~b1~'
];
disposables.push(window.onDidWriteTerminalData(e => {
try {
equal(terminal, e.terminal);
} catch (e) {
done(e);
if (terminal !== e.terminal) {
return;
}
// Multiple expected could show up in the same data event
@ -759,10 +765,7 @@ import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';
'~b2~'
];
disposables.push(window.onDidWriteTerminalData(e => {
try {
equal(terminal, e.terminal);
} catch (e) {
done(e);
if (terminal !== e.terminal) {
return;
}
// Multiple expected could show up in the same data event

View File

@ -6,9 +6,12 @@
import 'mocha';
import * as assert from 'assert';
import * as vscode from 'vscode';
import { assertNoRpc } from '../utils';
suite('vscode API - types', () => {
teardown(assertNoRpc);
test('static properties, es5 compat class', function () {
assert.ok(vscode.ThemeIcon.File instanceof vscode.ThemeIcon);
assert.ok(vscode.ThemeIcon.Folder instanceof vscode.ThemeIcon);

View File

@ -7,7 +7,7 @@ import * as assert from 'assert';
import 'mocha';
import * as os from 'os';
import * as vscode from 'vscode';
import { closeAllEditors, delay, disposeAll } from '../utils';
import { assertNoRpc, closeAllEditors, delay, disposeAll } from '../utils';
const webviewId = 'myWebview';
@ -26,8 +26,8 @@ suite.skip('vscode API - webview', () => {
}
teardown(async () => {
assertNoRpc();
await closeAllEditors();
disposeAll(disposables);
});

View File

@ -6,12 +6,15 @@
import * as assert from 'assert';
import { workspace, window, commands, ViewColumn, TextEditorViewColumnChangeEvent, Uri, Selection, Position, CancellationTokenSource, TextEditorSelectionChangeKind, QuickPickItem, TextEditor } from 'vscode';
import { join } from 'path';
import { closeAllEditors, pathEquals, createRandomFile } from '../utils';
import { closeAllEditors, pathEquals, createRandomFile, assertNoRpc } from '../utils';
suite('vscode API - window', () => {
teardown(closeAllEditors);
teardown(async function () {
assertNoRpc();
await closeAllEditors();
});
test('editor, active text editor', async () => {
const doc = await workspace.openTextDocument(join(workspace.rootPath || '', './far.js'));
@ -147,6 +150,13 @@ suite('vscode API - window', () => {
});
test('active editor not always correct... #49125', async function () {
if (!window.state.focused) {
// no focus!
this.skip();
return;
}
if (process.env['BUILD_SOURCEVERSION']) {
this.skip();
return;
@ -429,8 +439,8 @@ suite('vscode API - window', () => {
});
test('showQuickPick, select first two', async function () {
const label = 'showQuickPick, select first two';
let i = 0;
// const label = 'showQuickPick, select first two';
// let i = 0;
const resolves: ((value: string) => void)[] = [];
let done: () => void;
const unexpected = new Promise<void>((resolve, reject) => {
@ -442,26 +452,26 @@ suite('vscode API - window', () => {
canPickMany: true
});
const first = new Promise(resolve => resolves.push(resolve));
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
await new Promise(resolve => setTimeout(resolve, 100)); // Allow UI to update.
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
await commands.executeCommand('workbench.action.quickOpenSelectNext');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
assert.equal(await first, 'eins');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
await commands.executeCommand('workbench.action.quickPickManyToggle');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
const second = new Promise(resolve => resolves.push(resolve));
await commands.executeCommand('workbench.action.quickOpenSelectNext');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
assert.equal(await second, 'zwei');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
await commands.executeCommand('workbench.action.quickPickManyToggle');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem');
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
assert.deepStrictEqual(await picks, ['eins', 'zwei']);
console.log(`${label}: ${++i}`);
// console.log(`${label}: ${++i}`);
done!();
return unexpected;
});

View File

@ -5,20 +5,19 @@
import * as assert from 'assert';
import * as vscode from 'vscode';
import { createRandomFile, withLogDisabled } from '../utils';
import { assertNoRpc, createRandomFile, disposeAll, withLogDisabled } from '../utils';
suite('vscode API - workspace events', () => {
const disposables: vscode.Disposable[] = [];
teardown(() => {
for (const dispo of disposables) {
dispo.dispose();
}
assertNoRpc();
disposeAll(disposables);
disposables.length = 0;
});
test('onWillCreate/onDidCreate', async function () {
test('onWillCreate/onDidCreate', withLogDisabled(async function () {
const base = await createRandomFile();
const newUri = base.with({ path: base.path + '-foo' });
@ -42,9 +41,9 @@ suite('vscode API - workspace events', () => {
assert.ok(onDidCreate);
assert.equal(onDidCreate?.files.length, 1);
assert.equal(onDidCreate?.files[0].toString(), newUri.toString());
});
}));
test('onWillCreate/onDidCreate, make changes, edit another file', async function () {
test('onWillCreate/onDidCreate, make changes, edit another file', withLogDisabled(async function () {
const base = await createRandomFile();
const baseDoc = await vscode.workspace.openTextDocument(base);
@ -64,7 +63,7 @@ suite('vscode API - workspace events', () => {
assert.ok(success);
assert.equal(baseDoc.getText(), 'HALLO_NEW');
});
}));
test('onWillCreate/onDidCreate, make changes, edit new file fails', withLogDisabled(async function () {
@ -88,7 +87,7 @@ suite('vscode API - workspace events', () => {
assert.equal((await vscode.workspace.openTextDocument(newUri)).getText(), '');
}));
test('onWillDelete/onDidDelete', async function () {
test('onWillDelete/onDidDelete', withLogDisabled(async function () {
const base = await createRandomFile();
@ -111,9 +110,9 @@ suite('vscode API - workspace events', () => {
assert.ok(onDiddelete);
assert.equal(onDiddelete?.files.length, 1);
assert.equal(onDiddelete?.files[0].toString(), base.toString());
});
}));
test('onWillDelete/onDidDelete, make changes', async function () {
test('onWillDelete/onDidDelete, make changes', withLogDisabled(async function () {
const base = await createRandomFile();
const newUri = base.with({ path: base.path + '-NEW' });
@ -131,9 +130,9 @@ suite('vscode API - workspace events', () => {
const success = await vscode.workspace.applyEdit(edit);
assert.ok(success);
});
}));
test('onWillDelete/onDidDelete, make changes, del another file', async function () {
test('onWillDelete/onDidDelete, make changes, del another file', withLogDisabled(async function () {
const base = await createRandomFile();
const base2 = await createRandomFile();
@ -152,9 +151,9 @@ suite('vscode API - workspace events', () => {
assert.ok(success);
});
}));
test('onWillDelete/onDidDelete, make changes, double delete', async function () {
test('onWillDelete/onDidDelete, make changes, double delete', withLogDisabled(async function () {
const base = await createRandomFile();
let cnt = 0;
@ -171,9 +170,9 @@ suite('vscode API - workspace events', () => {
const success = await vscode.workspace.applyEdit(edit);
assert.ok(success);
});
}));
test('onWillRename/onDidRename', async function () {
test('onWillRename/onDidRename', withLogDisabled(async function () {
const oldUri = await createRandomFile();
const newUri = oldUri.with({ path: oldUri.path + '-NEW' });
@ -199,15 +198,15 @@ suite('vscode API - workspace events', () => {
assert.equal(onDidRename?.files.length, 1);
assert.equal(onDidRename?.files[0].oldUri.toString(), oldUri.toString());
assert.equal(onDidRename?.files[0].newUri.toString(), newUri.toString());
});
}));
test('onWillRename - make changes (saved file)', function () {
test('onWillRename - make changes (saved file)', withLogDisabled(function () {
return testOnWillRename(false);
});
}));
test('onWillRename - make changes (dirty file)', function () {
test('onWillRename - make changes (dirty file)', withLogDisabled(function () {
return testOnWillRename(true);
});
}));
async function testOnWillRename(withDirtyFile: boolean): Promise<void> {

View File

@ -6,6 +6,7 @@
import * as assert from 'assert';
import * as vscode from 'vscode';
import { posix } from 'path';
import { assertNoRpc } from '../utils';
suite('vscode API - workspace-fs', () => {
@ -15,6 +16,8 @@ suite('vscode API - workspace-fs', () => {
root = vscode.workspace.workspaceFolders![0]!.uri;
});
teardown(assertNoRpc);
test('fs.stat', async function () {
const stat = await vscode.workspace.fs.stat(root);
assert.equal(stat.type, vscode.FileType.Directory);

View File

@ -5,6 +5,7 @@
import * as assert from 'assert';
import { window, tasks, Disposable, TaskDefinition, Task, EventEmitter, CustomExecution, Pseudoterminal, TaskScope, commands, env, UIKind, ShellExecution, TaskExecution, Terminal, Event } from 'vscode';
import { assertNoRpc } from '../utils';
// Disable tasks tests:
// - Web https://github.com/microsoft/vscode/issues/90528
@ -14,6 +15,7 @@ import { window, tasks, Disposable, TaskDefinition, Task, EventEmitter, CustomEx
let disposables: Disposable[] = [];
teardown(() => {
assertNoRpc();
disposables.forEach(d => d.dispose());
disposables.length = 0;
});

View File

@ -5,14 +5,17 @@
import * as assert from 'assert';
import * as vscode from 'vscode';
import { createRandomFile, deleteFile, closeAllEditors, pathEquals, rndName, disposeAll, testFs, delay, withLogDisabled, revertAllDirty } from '../utils';
import { createRandomFile, deleteFile, closeAllEditors, pathEquals, rndName, disposeAll, testFs, delay, withLogDisabled, revertAllDirty, assertNoRpc } from '../utils';
import { join, posix, basename } from 'path';
import * as fs from 'fs';
import { TestFS } from '../memfs';
suite('vscode API - workspace', () => {
teardown(closeAllEditors);
teardown(async function () {
assertNoRpc();
await closeAllEditors();
});
test('MarkdownString', function () {
let md = new vscode.MarkdownString();

View File

@ -17,7 +17,7 @@ vscode.workspace.registerFileSystemProvider(testFs.scheme, testFs, { isCaseSensi
export async function createRandomFile(contents = '', dir: vscode.Uri | undefined = undefined, ext = ''): Promise<vscode.Uri> {
let fakeFile: vscode.Uri;
if (dir) {
assert.equal(dir.scheme, testFs.scheme);
assert.strictEqual(dir.scheme, testFs.scheme);
fakeFile = dir.with({ path: dir.path + '/' + rndName() + ext });
} else {
fakeFile = vscode.Uri.parse(`${testFs.scheme}:/${rndName() + ext}`);
@ -48,6 +48,10 @@ export function closeAllEditors(): Thenable<any> {
return vscode.commands.executeCommand('workbench.action.closeAllEditors');
}
export function saveAllEditors(): Thenable<any> {
return vscode.commands.executeCommand('workbench.action.files.saveAll');
}
export async function revertAllDirty(): Promise<void> {
return vscode.commands.executeCommand('_workbench.revertAllDirty');
}
@ -72,3 +76,64 @@ export function withLogDisabled(runnable: () => Promise<any>): () => Promise<voi
}
};
}
export function assertNoRpc() {
assertNoRpcFromEntry([vscode, 'vscode']);
}
export function assertNoRpcFromEntry(entry: [obj: any, name: string]) {
const symProxy = Symbol.for('rpcProxy');
const symProtocol = Symbol.for('rpcProtocol');
const proxyPaths: string[] = [];
const rpcPaths: string[] = [];
function walk(obj: any, path: string, seen: Set<any>) {
if (!obj) {
return;
}
if (typeof obj !== 'object' && typeof obj !== 'function') {
return;
}
if (seen.has(obj)) {
return;
}
seen.add(obj);
if (obj[symProtocol]) {
rpcPaths.push(`PROTOCOL via ${path}`);
}
if (obj[symProxy]) {
proxyPaths.push(`PROXY '${obj[symProxy]}' via ${path}`);
}
for (const key in obj) {
walk(obj[key], `${path}.${String(key)}`, seen);
}
}
try {
walk(entry[0], entry[1], new Set());
} catch (err) {
assert.fail(err);
}
assert.strictEqual(rpcPaths.length, 0, rpcPaths.join('\n'));
assert.strictEqual(proxyPaths.length, 0, proxyPaths.join('\n')); // happens...
}
export async function asPromise<T>(event: vscode.Event<T>, timeout = 5000): Promise<T> {
return new Promise<T>((resolve, reject) => {
const handle = setTimeout(() => {
sub.dispose();
reject(new Error('asPromise TIMEOUT reached'));
}, timeout);
const sub = event(e => {
clearTimeout(handle);
sub.dispose();
resolve(e);
});
});
}