notebook tests for notebook content change events.

This commit is contained in:
rebornix
2020-05-19 14:46:14 -07:00
parent 345f02dad4
commit cc151dd103
6 changed files with 226 additions and 130 deletions

View File

@@ -8,25 +8,161 @@ import * as assert from 'assert';
import * as vscode from 'vscode';
import { join } from 'path';
function waitFor(ms: number): Promise<void> {
let resolveFunc: () => void;
export function once<T>(event: vscode.Event<T>): vscode.Event<T> {
return (listener: any, thisArgs = null, disposables?: any) => {
// we need this, in case the event fires during the listener call
let didFire = false;
let result: vscode.Disposable;
result = event(e => {
if (didFire) {
return;
} else if (result) {
result.dispose();
} else {
didFire = true;
}
const promise = new Promise<void>(resolve => {
resolveFunc = resolve;
});
setTimeout(() => {
resolveFunc!();
}, ms);
return listener.call(thisArgs, e);
}, null, disposables);
return promise;
if (didFire) {
result.dispose();
}
return result;
};
}
async function getEventOncePromise<T>(event: vscode.Event<T>): Promise<T> {
return new Promise<T>((resolve, _reject) => {
once(event)((result: T) => resolve(result));
});
}
suite('API tests', () => {
test('document open/close event', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
const firstDocumentOpen = getEventOncePromise(vscode.notebook.onDidOpenNotebookDocument);
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await firstDocumentOpen;
const firstDocumentClose = getEventOncePromise(vscode.notebook.onDidCloseNotebookDocument);
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
await firstDocumentClose;
});
test('shared document in notebook editors', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
let counter = 0;
const disposables: vscode.Disposable[] = [];
disposables.push(vscode.notebook.onDidOpenNotebookDocument(() => {
counter++;
}));
disposables.push(vscode.notebook.onDidCloseNotebookDocument(() => {
counter--;
}));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
assert.equal(counter, 1);
await vscode.commands.executeCommand('workbench.action.splitEditor');
assert.equal(counter, 1);
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
assert.equal(counter, 0);
disposables.forEach(d => d.dispose());
});
test('editor open/close event', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
const firstEditorOpen = getEventOncePromise(vscode.notebook.onDidChangeVisibleNotebookEditors);
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await firstEditorOpen;
const firstEditorClose = getEventOncePromise(vscode.notebook.onDidChangeVisibleNotebookEditors);
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
await firstEditorClose;
});
test('editor open/close event', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
let count = 0;
const disposables: vscode.Disposable[] = [];
disposables.push(vscode.notebook.onDidChangeVisibleNotebookEditors(() => {
count = vscode.notebook.visibleNotebookEditors.length;
}));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
assert.equal(count, 1);
await vscode.commands.executeCommand('workbench.action.splitEditor');
assert.equal(count, 2);
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
assert.equal(count, 0);
});
test('editor editing event', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
const cellsChangeEvent = getEventOncePromise<vscode.NotebookCellsChangeEvent>(vscode.notebook.onDidChangeNotebookCells);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
const cellChangeEventRet = await cellsChangeEvent;
assert.equal(cellChangeEventRet.document, vscode.notebook.activeNotebookEditor?.document);
assert.equal(cellChangeEventRet.changes.length, 1);
assert.deepEqual(cellChangeEventRet.changes[0], {
start: 1,
deletedCount: 0,
items: [
vscode.notebook.activeNotebookEditor!.document.cells[1]
]
});
const moveCellEvent = getEventOncePromise<vscode.NotebookCellMoveEvent>(vscode.notebook.onDidMoveNotebookCell);
await vscode.commands.executeCommand('notebook.cell.moveUp');
const moveCellEventRet = await moveCellEvent;
assert.deepEqual(moveCellEventRet, {
document: vscode.notebook.activeNotebookEditor!.document,
index: 1,
newIndex: 0
});
const cellOutputChange = getEventOncePromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs);
await vscode.commands.executeCommand('notebook.cell.execute');
const cellOutputsAddedRet = await cellOutputChange;
assert.deepEqual(cellOutputsAddedRet, {
document: vscode.notebook.activeNotebookEditor!.document,
cells: [vscode.notebook.activeNotebookEditor!.document.cells[0]]
});
assert.equal(cellOutputsAddedRet.cells[0].outputs.length, 1);
const cellOutputClear = getEventOncePromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs);
await vscode.commands.executeCommand('notebook.cell.clearOutputs');
const cellOutputsCleardRet = await cellOutputClear;
assert.deepEqual(cellOutputsCleardRet, {
document: vscode.notebook.activeNotebookEditor!.document,
cells: [vscode.notebook.activeNotebookEditor!.document.cells[0]]
});
assert.equal(cellOutputsAddedRet.cells[0].outputs.length, 0);
// const cellChangeLanguage = getEventOncePromise<vscode.NotebookCellLanguageChangeEvent>(vscode.notebook.onDidChangeCellLanguage);
// await vscode.commands.executeCommand('notebook.cell.changeToMarkdown');
// const cellChangeLanguageRet = await cellChangeLanguage;
// assert.deepEqual(cellChangeLanguageRet, {
// document: vscode.notebook.activeNotebookEditor!.document,
// cells: vscode.notebook.activeNotebookEditor!.document.cells[0],
// language: 'markdown'
// });
await vscode.commands.executeCommand('workbench.action.files.save');
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
});
});
suite('notebook workflow', () => {
test('notebook open', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, 'test');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.language, 'typescript');
@@ -48,8 +184,6 @@ suite('notebook workflow', () => {
test('notebook cell actions', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, 'test');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.language, 'typescript');
@@ -119,8 +253,6 @@ suite('notebook workflow', () => {
test('move cells will not recreate cells in ExtHost', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove');
await vscode.commands.executeCommand('notebook.focusTop');
@@ -139,8 +271,6 @@ suite('notebook workflow', () => {
// const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
// await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
// await waitFor(500);
// assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
// const editor = vscode.notebook.activeNotebookEditor!;
@@ -164,9 +294,6 @@ suite('notebook workflow', () => {
test('cell runnable metadata is respected', async () => {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
const editor = vscode.notebook.activeNotebookEditor!;
@@ -188,9 +315,6 @@ suite('notebook workflow', () => {
test('document runnable metadata is respected', async () => {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
const editor = vscode.notebook.activeNotebookEditor!;
@@ -213,8 +337,6 @@ suite('notebook dirty state', () => {
test('notebook open', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, 'test');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.language, 'typescript');
@@ -235,8 +357,6 @@ suite('notebook dirty state', () => {
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true);
assert.equal(vscode.notebook.activeNotebookEditor?.selection !== undefined, true);
assert.deepEqual(vscode.notebook.activeNotebookEditor?.document.cells[1], vscode.notebook.activeNotebookEditor?.selection);
@@ -251,8 +371,6 @@ suite('notebook undo redo', () => {
test('notebook open', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, 'test');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.language, 'typescript');
@@ -296,8 +414,6 @@ suite('notebook working copy', () => {
test('notebook revert on close', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, '');
@@ -307,8 +423,6 @@ suite('notebook working copy', () => {
// close active editor from command will revert the file
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true);
assert.equal(vscode.notebook.activeNotebookEditor?.selection !== undefined, true);
assert.deepEqual(vscode.notebook.activeNotebookEditor?.document.cells[0], vscode.notebook.activeNotebookEditor?.selection);
@@ -321,8 +435,6 @@ suite('notebook working copy', () => {
test('notebook revert', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, '');
@@ -342,8 +454,6 @@ suite('notebook working copy', () => {
test('multiple tabs: dirty + clean', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, '');
@@ -352,7 +462,6 @@ suite('notebook working copy', () => {
const secondResource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './second.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
// make sure that the previous dirty editor is still restored in the extension host and no data loss
@@ -369,8 +478,6 @@ suite('notebook working copy', () => {
test('multiple tabs: two dirty tabs and switching', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, '');
@@ -379,7 +486,6 @@ suite('notebook working copy', () => {
const secondResource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './second.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, '');
@@ -407,8 +513,6 @@ suite('notebook working copy', () => {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
const firstNotebookEditor = vscode.notebook.activeNotebookEditor;
assert.equal(firstNotebookEditor !== undefined, true, 'notebook first');
assert.equal(firstNotebookEditor!.selection?.source, 'test');
@@ -433,8 +537,6 @@ suite('metadata', () => {
test('custom metadata should be supported', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.document.metadata.custom!['testMetadata'] as boolean, false);
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.metadata.custom!['testCellMetadata'] as number, 123);
@@ -446,8 +548,6 @@ suite('metadata', () => {
test('custom metadata should be supported', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.document.metadata.custom!['testMetadata'] as boolean, false);
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.metadata.custom!['testCellMetadata'] as number, 123);
@@ -464,8 +564,6 @@ suite('regression', () => {
test('microsoft/vscode-github-issue-notebooks#26. Insert template cell in the new empty document', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './empty.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.source, '');
assert.equal(vscode.notebook.activeNotebookEditor!.selection?.language, 'typescript');
@@ -476,8 +574,6 @@ suite('regression', () => {
test('#97830, #97764. Support switch to other editor types', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './empty.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
await vscode.commands.executeCommand('default:type', { text: 'var abc = 0;' });
@@ -496,15 +592,11 @@ suite('regression', () => {
test('#96105 - dirty editors', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './empty.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'default');
await waitFor(500);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
await vscode.commands.executeCommand('default:type', { text: 'var abc = 0;' });
// now it's dirty, open the resource with notebook editor should open a new one
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.notEqual(vscode.notebook.activeNotebookEditor, undefined, 'notebook first');
assert.notEqual(vscode.window.activeTextEditor, undefined);
@@ -518,10 +610,9 @@ suite('webview resource uri', () => {
test('asWebviewUri', async function () {
const resource = vscode.Uri.parse(join(vscode.workspace.rootPath || '', './first.vsctestnb'));
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await waitFor(500);
assert.equal(vscode.notebook.activeNotebookEditor !== undefined, true, 'notebook first');
const uri = vscode.notebook.activeNotebookEditor!.asWebviewUri(vscode.Uri.parse('./hello.png'));
assert.equal(uri.scheme, 'vscode-webview-resource');
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
});
});