mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-22 09:38:38 +01:00
notebook tests for notebook content change events.
This commit is contained in:
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user