未验证 提交 eb7024f1 编写于 作者: D Daniel Imms 提交者: GitHub

Merge pull request #83788 from microsoft/tyriar/integration_test

Several fixes to terminal/tasks integration tests
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode';
import { window, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget, Disposable } from 'vscode';
import { doesNotThrow, equal, ok, deepEqual } from 'assert';
suite('window namespace tests', () => {
......@@ -12,75 +12,91 @@ suite('window namespace tests', () => {
await workspace.getConfiguration('terminal.integrated').update('windowsEnableConpty', false, ConfigurationTarget.Global);
});
suite('Terminal', () => {
let disposables: Disposable[] = [];
teardown(() => {
disposables.forEach(d => d.dispose());
disposables.length = 0;
});
test('sendText immediately after createTerminal should not throw', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(terminal, term);
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
terminal.dispose();
reg1.dispose();
const reg2 = window.onDidCloseTerminal(() => {
reg2.dispose();
done();
});
});
disposables.push(window.onDidCloseTerminal(() => done()));
}));
const terminal = window.createTerminal();
doesNotThrow(terminal.sendText.bind(terminal, 'echo "foo"'));
});
test('onDidCloseTerminal event fires when terminal is disposed', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(terminal, term);
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
terminal.dispose();
reg1.dispose();
const reg2 = window.onDidCloseTerminal(() => {
reg2.dispose();
done();
});
});
disposables.push(window.onDidCloseTerminal(() => done()));
}));
const terminal = window.createTerminal();
});
test('processId immediately after createTerminal should fetch the pid', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(terminal, term);
reg1.dispose();
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
terminal.processId.then(id => {
ok(id > 0);
try {
ok(id > 0);
} catch (e) {
done(e);
}
terminal.dispose();
const reg2 = window.onDidCloseTerminal(() => {
reg2.dispose();
done();
});
disposables.push(window.onDidCloseTerminal(() => done()));
});
});
}));
const terminal = window.createTerminal();
});
test('name in constructor should set terminal.name', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(terminal, term);
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
terminal.dispose();
reg1.dispose();
const reg2 = window.onDidCloseTerminal(() => {
reg2.dispose();
done();
});
});
disposables.push(window.onDidCloseTerminal(() => done()));
}));
const terminal = window.createTerminal('a');
equal(terminal.name, 'a');
try {
equal(terminal.name, 'a');
} catch (e) {
done(e);
}
});
test('onDidOpenTerminal should fire when a terminal is created', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(term.name, 'b');
reg1.dispose();
const reg2 = window.onDidCloseTerminal(() => {
reg2.dispose();
done();
});
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(term.name, 'b');
} catch (e) {
done(e);
}
disposables.push(window.onDidCloseTerminal(() => done()));
terminal.dispose();
});
}));
const terminal = window.createTerminal('b');
});
// test('onDidChangeActiveTerminal should fire when new terminals are created', (done) => {
// const reg1 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => {
// equal(active, terminal);
......@@ -154,16 +170,20 @@ suite('window namespace tests', () => {
suite('hideFromUser', () => {
test('should be available to terminals API', done => {
const terminal = window.createTerminal({ name: 'bg', hideFromUser: true });
window.onDidOpenTerminal(t => {
equal(t, terminal);
equal(t.name, 'bg');
ok(window.terminals.indexOf(terminal) !== -1);
const reg3 = window.onDidCloseTerminal(() => {
reg3.dispose();
disposables.push(window.onDidOpenTerminal(t => {
try {
equal(t, terminal);
equal(t.name, 'bg');
ok(window.terminals.indexOf(terminal) !== -1);
} catch (e) {
done(e);
}
disposables.push(window.onDidCloseTerminal(() => {
// reg3.dispose();
done();
});
}));
terminal.dispose();
});
}));
});
});
......@@ -172,32 +192,34 @@ suite('window namespace tests', () => {
const openEvents: string[] = [];
const dataEvents: { name: string, data: string }[] = [];
const closeEvents: string[] = [];
const reg1 = window.onDidOpenTerminal(e => openEvents.push(e.name));
disposables.push(window.onDidOpenTerminal(e => openEvents.push(e.name)));
let resolveOnceDataWritten: (() => void) | undefined;
let resolveOnceClosed: (() => void) | undefined;
const reg2 = window.onDidWriteTerminalData(e => {
disposables.push(window.onDidWriteTerminalData(e => {
dataEvents.push({ name: e.terminal.name, data: e.data });
resolveOnceDataWritten!();
});
}));
const reg3 = window.onDidCloseTerminal(e => {
disposables.push(window.onDidCloseTerminal(e => {
closeEvents.push(e.name);
if (closeEvents.length === 1) {
deepEqual(openEvents, ['test1']);
deepEqual(dataEvents, [{ name: 'test1', data: 'write1' }]);
deepEqual(closeEvents, ['test1']);
resolveOnceClosed!();
} else if (closeEvents.length === 2) {
deepEqual(openEvents, ['test1', 'test2']);
deepEqual(dataEvents, [{ name: 'test1', data: 'write1' }, { name: 'test2', data: 'write2' }]);
deepEqual(closeEvents, ['test1', 'test2']);
try {
if (closeEvents.length === 1) {
deepEqual(openEvents, ['test1']);
deepEqual(dataEvents, [{ name: 'test1', data: 'write1' }]);
deepEqual(closeEvents, ['test1']);
} else if (closeEvents.length === 2) {
deepEqual(openEvents, ['test1', 'test2']);
deepEqual(dataEvents, [{ name: 'test1', data: 'write1' }, { name: 'test2', data: 'write2' }]);
deepEqual(closeEvents, ['test1', 'test2']);
}
resolveOnceClosed!();
} catch (e) {
done(e);
}
});
}));
const term1Write = new EventEmitter<string>();
const term1Close = new EventEmitter<void>();
......@@ -233,9 +255,6 @@ suite('window namespace tests', () => {
// Wait until the terminal is closed
await new Promise<void>(resolve => { resolveOnceClosed = resolve; });
reg1.dispose();
reg2.dispose();
reg3.dispose();
done();
},
close: () => { }
......@@ -250,15 +269,15 @@ suite('window namespace tests', () => {
suite('Extension pty terminals', () => {
test('should fire onDidOpenTerminal and onDidCloseTerminal', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(term.name, 'c');
reg1.dispose();
const reg2 = window.onDidCloseTerminal(() => {
reg2.dispose();
done();
});
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(term.name, 'c');
} catch (e) {
done(e);
}
disposables.push(window.onDidCloseTerminal(() => done()));
term.dispose();
});
}));
const pty: Pseudoterminal = {
onDidWrite: new EventEmitter<string>().event,
open: () => { },
......@@ -315,22 +334,29 @@ suite('window namespace tests', () => {
// });
test('should respect dimension overrides', (done) => {
const reg1 = window.onDidOpenTerminal(term => {
equal(terminal, term);
reg1.dispose();
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
term.show();
const reg2 = window.onDidChangeTerminalDimensions(e => {
equal(e.dimensions.columns, 10);
equal(e.dimensions.rows, 5);
equal(e.terminal, terminal);
reg2.dispose();
const reg3 = window.onDidCloseTerminal(() => {
reg3.dispose();
done();
});
disposables.push(window.onDidChangeTerminalDimensions(e => {
if (e.dimensions.columns === 0 || e.dimensions.rows === 0) {
// HACK: Ignore the event if dimension(s) are zero (#83778)
return;
}
try {
equal(e.dimensions.columns, 10);
equal(e.dimensions.rows, 5);
equal(e.terminal, terminal);
} catch (e) {
done(e);
}
disposables.push(window.onDidCloseTerminal(() => done()));
terminal.dispose();
});
});
}));
}));
const writeEmitter = new EventEmitter<string>();
const overrideDimensionsEmitter = new EventEmitter<TerminalDimensions>();
const pty: Pseudoterminal = {
......
......@@ -4,14 +4,20 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as vscode from 'vscode';
import { window, tasks, Disposable, TaskDefinition, Task, EventEmitter, CustomExecution, Pseudoterminal, TaskScope, commands, Task2 } from 'vscode';
suite('workspace-namespace', () => {
suite('Tasks', () => {
let disposables: Disposable[] = [];
teardown(() => {
disposables.forEach(d => d.dispose());
disposables.length = 0;
});
test('CustomExecution task should start and shutdown successfully', (done) => {
interface CustomTestingTaskDefinition extends vscode.TaskDefinition {
interface CustomTestingTaskDefinition extends TaskDefinition {
/**
* One of the task properties. This can be used to customize the task in the tasks.json
*/
......@@ -19,45 +25,58 @@ suite('workspace-namespace', () => {
}
const taskType: string = 'customTesting';
const taskName = 'First custom task';
const reg1 = vscode.window.onDidOpenTerminal(term => {
reg1.dispose();
const reg2 = vscode.window.onDidWriteTerminalData(e => {
reg2.dispose();
assert.equal(e.data, 'testing\r\n');
let isPseudoterminalClosed = false;
disposables.push(window.onDidOpenTerminal(term => {
disposables.push(window.onDidWriteTerminalData(e => {
try {
assert.equal(e.data, 'testing\r\n');
} catch (e) {
done(e);
}
disposables.push(window.onDidCloseTerminal(() => {
try {
// Pseudoterminal.close should have fired by now, additionally we want
// to make sure all events are flushed before continuing with more tests
assert.ok(isPseudoterminalClosed);
} catch (e) {
done(e);
return;
}
done();
}));
term.dispose();
});
});
const taskProvider = vscode.tasks.registerTaskProvider(taskType, {
}));
}));
disposables.push(tasks.registerTaskProvider(taskType, {
provideTasks: () => {
const result: vscode.Task[] = [];
const result: Task[] = [];
const kind: CustomTestingTaskDefinition = {
type: taskType,
customProp1: 'testing task one'
};
const writeEmitter = new vscode.EventEmitter<string>();
const execution = new vscode.CustomExecution((): Thenable<vscode.Pseudoterminal> => {
const pty: vscode.Pseudoterminal = {
const writeEmitter = new EventEmitter<string>();
const execution = new CustomExecution((): Thenable<Pseudoterminal> => {
const pty: Pseudoterminal = {
onDidWrite: writeEmitter.event,
open: () => {
writeEmitter.fire('testing\r\n');
},
close: () => {
taskProvider.dispose();
done();
}
open: () => writeEmitter.fire('testing\r\n'),
close: () => isPseudoterminalClosed = true
};
return Promise.resolve(pty);
});
const task = new vscode.Task2(kind, vscode.TaskScope.Workspace, taskName, taskType, execution);
const task = new Task2(kind, TaskScope.Workspace, taskName, taskType, execution);
result.push(task);
return result;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
resolveTask(_task: Task): Task | undefined {
try {
assert.fail('resolveTask should not trigger during the test');
} catch (e) {
done(e);
}
return undefined;
}
});
vscode.commands.executeCommand('workbench.action.tasks.runTask', `${taskType}: ${taskName}`);
}));
commands.executeCommand('workbench.action.tasks.runTask', `${taskType}: ${taskName}`);
});
});
});
......@@ -369,7 +369,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
if (this._terminalProcesses[id]) {
// Extension pty terminal only - when virtual process resize fires it means that the
// terminal's maximum dimensions changed
this._terminalProcesses[id].resize(cols, rows);
this._terminalProcesses[id]?.resize(cols, rows);
}
}
......@@ -481,12 +481,12 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
}
public $acceptProcessInput(id: number, data: string): void {
this._terminalProcesses[id].input(data);
this._terminalProcesses[id]?.input(data);
}
public $acceptProcessResize(id: number, cols: number, rows: number): void {
try {
this._terminalProcesses[id].resize(cols, rows);
this._terminalProcesses[id]?.resize(cols, rows);
} catch (error) {
// We tried to write to a closed pipe / channel.
if (error.code !== 'EPIPE' && error.code !== 'ERR_IPC_CHANNEL_CLOSED') {
......@@ -496,15 +496,15 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
}
public $acceptProcessShutdown(id: number, immediate: boolean): void {
this._terminalProcesses[id].shutdown(immediate);
this._terminalProcesses[id]?.shutdown(immediate);
}
public $acceptProcessRequestInitialCwd(id: number): void {
this._terminalProcesses[id].getInitialCwd().then(initialCwd => this._proxy.$sendProcessInitialCwd(id, initialCwd));
this._terminalProcesses[id]?.getInitialCwd().then(initialCwd => this._proxy.$sendProcessInitialCwd(id, initialCwd));
}
public $acceptProcessRequestCwd(id: number): void {
this._terminalProcesses[id].getCwd().then(cwd => this._proxy.$sendProcessCwd(id, cwd));
this._terminalProcesses[id]?.getCwd().then(cwd => this._proxy.$sendProcessCwd(id, cwd));
}
public $acceptProcessRequestLatency(id: number): number {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册