adopt tests to new notebook change event

This commit is contained in:
Johannes 2022-03-29 11:58:54 +02:00
parent bf0b4ac976
commit b1faab40de
No known key found for this signature in database
GPG key ID: 6DEF802A22264FCA
6 changed files with 85 additions and 73 deletions

View file

@ -10,7 +10,8 @@
},
"enabledApiProposals": [
"notebookEditor",
"notebookEditorEdit"
"notebookEditorEdit",
"notebookDocumentEvents"
],
"activationEvents": [
"*"
@ -31,9 +32,9 @@
"commands": [
{
"command": "ipynb.newUntitledIpynb",
"title": "New Jupyter Notebook",
"title": "New Jupyter Notebook",
"shortTitle": "Jupyter Notebook",
"category": "Create"
"category": "Create"
},
{
"command": "ipynb.openIpynbInNotebookEditor",
@ -60,9 +61,9 @@
}
],
"commandPalette": [
{
"command": "ipynb.newUntitledIpynb"
},
{
"command": "ipynb.newUntitledIpynb"
},
{
"command": "ipynb.openIpynbInNotebookEditor",
"when": "false"

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext, NotebookCellsChangeEvent, NotebookDocument, notebooks, workspace, WorkspaceEdit } from 'vscode';
import { ExtensionContext, NotebookDocument, NotebookDocumentChangeEvent, workspace, WorkspaceEdit } from 'vscode';
import { v4 as uuid } from 'uuid';
import { getCellMetadata } from './serializers';
import { CellMetadata } from './common';
@ -15,21 +15,21 @@ import * as nbformat from '@jupyterlab/nbformat';
* Details of the spec can be found here https://jupyter.org/enhancement-proposals/62-cell-id/cell-id.html#
*/
export function ensureAllNewCellsHaveCellIds(context: ExtensionContext) {
notebooks.onDidChangeNotebookCells(onDidChangeNotebookCells, undefined, context.subscriptions);
workspace.onDidChangeNotebookDocument(onDidChangeNotebookCells, undefined, context.subscriptions);
}
function onDidChangeNotebookCells(e: NotebookCellsChangeEvent) {
const nbMetadata = getNotebookMetadata(e.document);
function onDidChangeNotebookCells(e: NotebookDocumentChangeEvent) {
const nbMetadata = getNotebookMetadata(e.notebook);
if (!isCellIdRequired(nbMetadata)) {
return;
}
e.changes.forEach(change => {
change.items.forEach(cell => {
e.contentChanges.forEach(change => {
change.addedCells.forEach(cell => {
const cellMetadata = getCellMetadata(cell);
if (cellMetadata?.id) {
return;
}
const id = generateCellId(e.document);
const id = generateCellId(e.notebook);
const edit = new WorkspaceEdit();
// Don't edit the metadata directly, always get a clone (prevents accidental singletons and directly editing the objects).
const updatedMetadata: CellMetadata = { ...JSON.parse(JSON.stringify(cellMetadata || {})) };

View file

@ -11,5 +11,6 @@
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.notebookEditor.d.ts",
"../../src/vscode-dts/vscode.proposed.notebookEditorEdit.d.ts",
"../../src/vscode-dts/vscode.proposed.notebookDocumentEvents.d.ts",
]
}

View file

@ -23,6 +23,7 @@
"notebookControllerKind",
"notebookDebugOptions",
"notebookDeprecated",
"notebookDocumentEvents",
"notebookEditor",
"notebookEditorDecorationType",
"notebookEditorEdit",

View file

@ -261,7 +261,7 @@ suite.skip('Notebook Document', function () {
value: 'new_code'
}]);
const event = utils.asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
const event = utils.asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
@ -274,13 +274,13 @@ suite.skip('Notebook Document', function () {
assert.strictEqual(document.cellAt(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.cellAt(0));
assert.strictEqual(data.changes[0].items[1], document.cellAt(1));
assert.strictEqual(data.notebook === document, true);
assert.strictEqual(data.contentChanges.length, 1);
assert.strictEqual(data.contentChanges[0].range.isEmpty, true);
assert.strictEqual(data.contentChanges[0].removedCells.length, 0);
assert.strictEqual(data.contentChanges[0].addedCells.length, 2);
assert.strictEqual(data.contentChanges[0].addedCells[0], document.cellAt(0));
assert.strictEqual(data.contentChanges[0].addedCells[1], document.cellAt(1));
});
test('workspace edit API (replaceMetadata)', async function () {
@ -299,7 +299,7 @@ suite.skip('Notebook Document', function () {
const document = await vscode.workspace.openNotebookDocument(uri);
const edit = new vscode.WorkspaceEdit();
const event = utils.asPromise<vscode.NotebookCellMetadataChangeEvent>(vscode.notebooks.onDidChangeCellMetadata);
const event = utils.asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
edit.replaceNotebookCellMetadata(document.uri, 0, { inputCollapsed: true });
const success = await vscode.workspace.applyEdit(edit);
@ -310,8 +310,10 @@ suite.skip('Notebook Document', function () {
assert.strictEqual(document.cellAt(0).metadata.inputCollapsed, true);
// check event data
assert.strictEqual(data.document === document, true);
assert.strictEqual(data.cell.index, 0);
assert.strictEqual(data.notebook === document, true);
assert.strictEqual(data.contentChanges.length, 0);
assert.strictEqual(data.cellChanges.length, 1);
assert.strictEqual(data.cellChanges[0].cell.index, 0);
});
test('document save API', async function () {

View file

@ -194,41 +194,52 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const notebook = await openRandomNotebookDocument();
const editor = await vscode.window.showNotebookDocument(notebook);
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
const cellsChangeEvent = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
const cellChangeEventRet = await cellsChangeEvent;
assert.strictEqual(cellChangeEventRet.document, editor.document);
assert.strictEqual(cellChangeEventRet.changes.length, 1);
assert.deepStrictEqual(cellChangeEventRet.changes[0], {
start: 1,
deletedCount: 0,
deletedItems: [],
items: [
editor.document.cellAt(1)
]
assert.strictEqual(cellChangeEventRet.notebook, editor.document);
assert.strictEqual(cellChangeEventRet.contentChanges.length, 1);
assert.deepStrictEqual(cellChangeEventRet.contentChanges[0], <vscode.NotebookDocumentContentChange>{
range: new vscode.NotebookRange(1, 1),
removedCells: [],
addedCells: [editor.document.cellAt(1)]
});
const moveCellEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
const moveCellEvent = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
await vscode.commands.executeCommand('notebook.cell.moveUp');
await moveCellEvent;
const cellOutputChange = asPromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs);
const cellOutputChange = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
await vscode.commands.executeCommand('notebook.cell.execute');
const cellOutputsAddedRet = await cellOutputChange;
assert.deepStrictEqual(cellOutputsAddedRet, {
document: editor.document,
cells: [editor.document.cellAt(0)]
});
assert.strictEqual(cellOutputsAddedRet.cells[0].outputs.length, 1);
const cellOutputClear = asPromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs);
assert.strictEqual(cellOutputsAddedRet.notebook.uri.toString(), editor.document.uri.toString());
assert.strictEqual(cellOutputsAddedRet.metadata, undefined);
assert.strictEqual(cellOutputsAddedRet.contentChanges.length, 0);
assert.strictEqual(cellOutputsAddedRet.cellChanges.length, 1);
assert.deepStrictEqual(cellOutputsAddedRet.cellChanges[0].cell, editor.document.cellAt(0));
assert.deepStrictEqual(cellOutputsAddedRet.cellChanges[0].executionSummary, { executionOrder: undefined, success: undefined, timing: undefined }); // TODO@jrieken should this be undefined instead all empty?
assert.strictEqual(cellOutputsAddedRet.cellChanges[0].document, undefined);
assert.strictEqual(cellOutputsAddedRet.cellChanges[0].metadata, undefined);
assert.strictEqual(cellOutputsAddedRet.cellChanges[0].outputs, undefined);
assert.strictEqual(cellOutputsAddedRet.cellChanges[0].cell.outputs.length, 1);
const cellOutputClear = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
await vscode.commands.executeCommand('notebook.cell.clearOutputs');
const cellOutputsCleardRet = await cellOutputClear;
assert.deepStrictEqual(cellOutputsCleardRet, {
document: editor.document,
cells: [editor.document.cellAt(0)]
assert.deepStrictEqual(cellOutputsCleardRet, <vscode.NotebookDocumentChangeEvent>{
notebook: editor.document,
metadata: undefined,
contentChanges: [],
cellChanges: [{
cell: editor.document.cellAt(0),
document: undefined,
executionSummary: undefined,
metadata: undefined,
outputs: editor.document.cellAt(0).outputs
}],
});
assert.strictEqual(cellOutputsAddedRet.cells[0].outputs.length, 0);
assert.strictEqual(cellOutputsCleardRet.cellChanges[0].cell.outputs.length, 0);
// const cellChangeLanguage = getEventOncePromise<vscode.NotebookCellLanguageChangeEvent>(vscode.notebooks.onDidChangeCellLanguage);
// await vscode.commands.executeCommand('notebook.cell.changeToMarkdown');
@ -244,16 +255,14 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const notebook = await openRandomNotebookDocument();
const editor = await vscode.window.showNotebookDocument(notebook);
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
const cellMetadataChangeEvent = asPromise<vscode.NotebookCellMetadataChangeEvent>(vscode.notebooks.onDidChangeCellMetadata);
const notebookChangeEvent = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
const version = editor.document.version;
await editor.edit(editBuilder => {
editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]);
editBuilder.replaceCellMetadata(0, { inputCollapsed: false });
});
await cellsChangeEvent;
await cellMetadataChangeEvent;
await notebookChangeEvent;
assert.strictEqual(version + 1, editor.document.version);
});
@ -261,16 +270,14 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const notebook = await openRandomNotebookDocument();
const editor = await vscode.window.showNotebookDocument(notebook);
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
const cellMetadataChangeEvent = asPromise<vscode.NotebookCellMetadataChangeEvent>(vscode.notebooks.onDidChangeCellMetadata);
const notebookChangeEvent = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
const version = editor.document.version;
await editor.edit(editBuilder => {
editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]);
editBuilder.replaceCellMetadata(0, { inputCollapsed: false });
});
await cellsChangeEvent;
await cellMetadataChangeEvent;
await notebookChangeEvent;
assert.strictEqual(editor.document.cellCount, 3);
assert.strictEqual(editor.document.cellAt(0)?.metadata.inputCollapsed, false);
assert.strictEqual(version + 1, editor.document.version);
@ -285,7 +292,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
test.skip('#98841, initialzation should not emit cell change events.', async function () {
let count = 0;
testDisposables.push(vscode.notebooks.onDidChangeNotebookCells(() => {
testDisposables.push(vscode.workspace.onDidChangeNotebookDocument(() => {
count++;
}));
@ -387,9 +394,9 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const activeCell = getFocusedCell(editor);
assert.strictEqual(activeCell?.index, 0);
const moveChange = asPromise(vscode.notebooks.onDidChangeNotebookCells);
const notebookChangeEvent = asPromise(vscode.workspace.onDidChangeNotebookDocument);
await vscode.commands.executeCommand('notebook.cell.moveDown');
assert.ok(await moveChange);
assert.ok(await notebookChangeEvent);
const newActiveCell = getFocusedCell(editor);
assert.strictEqual(newActiveCell?.index, 1);
@ -440,13 +447,13 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const editor = vscode.window.activeNotebookEditor!;
const cell = editor.document.cellAt(0);
await withEvent(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
await withEvent(vscode.workspace.onDidChangeNotebookDocument, async (event) => {
await vscode.commands.executeCommand('notebook.execute');
await event;
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
});
await withEvent(vscode.notebooks.onDidChangeCellOutputs, async event => {
await withEvent(vscode.workspace.onDidChangeNotebookDocument, async event => {
await vscode.commands.executeCommand('notebook.cell.clearOutputs');
await event;
assert.strictEqual(cell.outputs.length, 0, 'should clear');
@ -455,7 +462,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const secondResource = await createRandomNotebookFile();
await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest');
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
await withEvent<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument, async (event) => {
await vscode.commands.executeCommand('notebook.cell.execute', { start: 0, end: 1 }, resource);
await event;
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
@ -473,13 +480,13 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
let secondCellExecuted = false;
let resolve: () => void;
const p = new Promise<void>(r => resolve = r);
const listener = vscode.notebooks.onDidChangeCellOutputs(e => {
e.cells.forEach(cell => {
if (cell.index === 0) {
const listener = vscode.workspace.onDidChangeNotebookDocument(e => {
e.cellChanges.forEach(change => {
if (change.cell.index === 0) {
firstCellExecuted = true;
}
if (cell.index === 1) {
if (change.cell.index === 1) {
secondCellExecuted = true;
}
});
@ -501,13 +508,13 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const editor = vscode.window.activeNotebookEditor!;
const cell = editor.document.cellAt(0);
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
await withEvent<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument, async (event) => {
await vscode.commands.executeCommand('notebook.execute');
await event;
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
});
const clearChangeEvent = asPromise<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs);
const clearChangeEvent = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
await vscode.commands.executeCommand('notebook.cell.clearOutputs');
await clearChangeEvent;
assert.strictEqual(cell.outputs.length, 0, 'should clear');
@ -515,7 +522,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const secondResource = await createRandomNotebookFile();
await vscode.commands.executeCommand('vscode.openWith', secondResource, 'notebookCoreTest');
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
await withEvent<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument, async (event) => {
await vscode.commands.executeCommand('notebook.execute', resource);
await event;
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
@ -547,7 +554,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
};
testDisposables.push(alternativeKernel.controller);
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
await withEvent<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument, async (event) => {
await assertKernel(defaultKernel, notebook);
await vscode.commands.executeCommand('notebook.cell.execute');
await event;
@ -557,7 +564,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), cell.document.getText());
});
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
await withEvent<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument, async (event) => {
await assertKernel(alternativeKernel, notebook);
await vscode.commands.executeCommand('notebook.cell.execute');
await event;
@ -798,16 +805,16 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
const notebook = await vscode.workspace.openNotebookDocument(resource);
const editor = await vscode.window.showNotebookDocument(notebook);
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
const cellsChangeEvent = asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
await editor.edit(editBuilder => {
editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]);
});
const cellChangeEventRet = await cellsChangeEvent;
assert.strictEqual(cellChangeEventRet.document === notebook, true);
assert.strictEqual(cellChangeEventRet.document.isDirty, true);
assert.strictEqual(cellChangeEventRet.notebook === notebook, true);
assert.strictEqual(cellChangeEventRet.notebook.isDirty, true);
const saveEvent = asPromise(vscode.notebooks.onDidSaveNotebookDocument);
const saveEvent = asPromise(vscode.workspace.onDidSaveNotebookDocument);
await notebook.save();