Skip to content

Add tests for notebook cell manipulations #12204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 207 additions & 2 deletions src/test/datascience/notebook/edit.ds.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@
import { assert } from 'chai';
import * as path from 'path';
import * as sinon from 'sinon';
import { Uri } from 'vscode';
import { commands, Uri } from 'vscode';
import { IDisposable } from '../../../client/common/types';
import { NotebookModelChange } from '../../../client/datascience/interactive-common/interactiveWindowTypes';
import { INotebookEditorProvider, INotebookModel } from '../../../client/datascience/types';
import { splitMultilineString } from '../../../datascience-ui/common';
import { createCodeCell, createMarkdownCell } from '../../../datascience-ui/common/cellFactory';
import { createEventHandler, IExtensionTestApi, TestEventHandler } from '../../common';
import { createEventHandler, IExtensionTestApi, TestEventHandler, waitForCondition } from '../../common';
import { EXTENSION_ROOT_DIR_FOR_TESTS } from '../../constants';
import { initialize } from '../../initialize';
import {
canRunTests,
closeNotebooksAndCleanUpAfterTests,
createTemporaryNotebook,
deleteAllCellsAndWait,
deleteCell,
insertMarkdownCell,
insertMarkdownCellAndWait,
insertPythonCell,
insertPythonCellAndWait,
swallowSavingOfNotebooks
} from './helper';

Expand Down Expand Up @@ -86,6 +89,7 @@ suite('DataScience - VSCode Notebook (Edit)', function () {

// Verify model has been updated
assert.equal(model.cells.length, 2);
assertMarkdownCell(0, 'HELLO');
});
test('Adding a markdown cell then deleting it should trigger updates in our NotebookModel', async () => {
await insertMarkdownCell('HELLO');
Expand Down Expand Up @@ -117,6 +121,7 @@ suite('DataScience - VSCode Notebook (Edit)', function () {

// Verify model has been updated
assert.equal(model.cells.length, 2);
assertCodeCell(0, 'HELLO');
});
test('Adding a code cell in specific position should trigger updates in our NotebookModel', async () => {
await insertPythonCell('HELLO', 1);
Expand All @@ -133,6 +138,206 @@ suite('DataScience - VSCode Notebook (Edit)', function () {
// Verify model has been updated
assert.equal(model.cells.length, 2);
});
function assertCodeCell(index: number, text: string) {
const cell = model.cells[index];
assert.equal(cell.data.cell_type, 'code');
assert.deepEqual(cell.data.source, text === '' ? [''] : splitMultilineString(text));
return true;
}
function assertMarkdownCell(index: number, text?: string) {
const cell = model.cells[index];
assert.equal(cell.data.cell_type, 'markdown');
assert.deepEqual(
cell.data.source,
text === undefined ? [] : text === '' ? [''] : splitMultilineString(text)
);
return true;
}
test('Change cell to markdown', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('HELLO');
handler.reset();

await commands.executeCommand('notebook.cell.changeToMarkdown');

await waitForCondition(async () => assertMarkdownCell(0, 'HELLO'), 1_000, 'Not Changed');
assert.isOk(handler.count);
});
test('Change cell to code', async function () {
this.timeout(10_000);
await deleteAllCellsAndWait();
await insertMarkdownCellAndWait('HELLO');
handler.reset();

await commands.executeCommand('notebook.cell.changeToCode');

await waitForCondition(async () => assertCodeCell(0, 'HELLO'), 1_000, 'Not Changed');
assert.isOk(handler.count);
});
test('Toggle cells (code->mardown->code->markdown)', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('HELLO');
handler.reset();

await commands.executeCommand('notebook.cell.changeToMarkdown');
await waitForCondition(async () => assertMarkdownCell(0, 'HELLO'), 1_000, 'Not Changed');
assert.isOk(handler.count);

handler.reset();
await commands.executeCommand('notebook.cell.changeToCode');
await waitForCondition(async () => assertCodeCell(0, 'HELLO'), 1_000, 'Not Changed');
assert.isOk(handler.count);

handler.reset();
await commands.executeCommand('notebook.cell.changeToMarkdown');
await waitForCondition(async () => assertMarkdownCell(0, 'HELLO'), 1_000, 'Not Changed');
assert.isOk(handler.count);
});
test('Cut cell', async () => {
await commands.executeCommand('notebook.cell.cut');

await handler.assertFiredExactly(1); // cut first cell
assert.lengthOf(model.cells, 0);
});
test('Copy & paste (code cell)', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('HELLO');
handler.reset();

await commands.executeCommand('notebook.cell.copy');
await commands.executeCommand('notebook.cell.paste');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertCodeCell(0, 'HELLO');
assertCodeCell(1, 'HELLO');
});
test('Copy & paste (markdown cell)', async () => {
await deleteAllCellsAndWait();
await insertMarkdownCellAndWait('HELLO');
handler.reset();

await commands.executeCommand('notebook.cell.copy');
await commands.executeCommand('notebook.cell.paste');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertMarkdownCell(0, 'HELLO');
assertMarkdownCell(1, 'HELLO');
});
test('Copy & paste above', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('PYTHON');
await commands.executeCommand('notebook.cell.copy');
handler.reset();
const oldCell = model.cells[0];

await commands.executeCommand('notebook.cell.pasteAbove');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertCodeCell(0, 'PYTHON');
assertCodeCell(1, 'PYTHON');
// Verify the previous cell that was in the first index is now in the second place.
assert.equal(model.cells[1], oldCell);
// Verify the new cell is a whole new reference.
assert.notEqual(model.cells[0], oldCell);
});
test('Copy & paste below', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('PYTHON');
await commands.executeCommand('notebook.cell.copy');
handler.reset();
const oldCell = model.cells[0];

await commands.executeCommand('notebook.cell.paste');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertCodeCell(0, 'PYTHON');
assertCodeCell(1, 'PYTHON');
// Verify the previous cell that was in the first index is still in the first place.
assert.equal(model.cells[0], oldCell);
// Verify the new cell is a whole new reference.
assert.notEqual(model.cells[1], oldCell);
});
test('Insert code cell above', async () => {
await deleteAllCellsAndWait();
await insertMarkdownCellAndWait('MARKDOWN');
handler.reset();

await commands.executeCommand('notebook.cell.insertCodeCellAbove');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertCodeCell(0, '');
assertMarkdownCell(1, 'MARKDOWN');
});
test('Insert code cell below', async () => {
await deleteAllCellsAndWait();
await insertMarkdownCellAndWait('MARKDOWN');
handler.reset();

await commands.executeCommand('notebook.cell.insertCodeCellBelow');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertMarkdownCell(0, 'MARKDOWN');
assertCodeCell(1, '');
});
test('Insert markdown cell above', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('PYTHON');
handler.reset();

await commands.executeCommand('notebook.cell.insertMarkdownCellAbove');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertMarkdownCell(0);
assertCodeCell(1, 'PYTHON');
});
test('Insert markdown cell below', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('PYTHON');
handler.reset();

await commands.executeCommand('notebook.cell.insertMarkdownCellBelow');

await handler.assertFiredExactly(1); // paste cell.
assert.lengthOf(model.cells, 2);
assertCodeCell(0, 'PYTHON');
assertMarkdownCell(1);
});
test('Move cell down', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('PYTHON');
await insertMarkdownCellAndWait('MARKDOWN', 1);
assertCodeCell(0, 'PYTHON');
assertMarkdownCell(1, 'MARKDOWN');

handler.reset();
await commands.executeCommand('notebook.cell.moveDown');

await handler.assertFiredExactly(1); // paste cell.
assertMarkdownCell(0, 'MARKDOWN');
assertCodeCell(1, 'PYTHON');
});
test('Join cells', async () => {
await deleteAllCellsAndWait();
await insertPythonCellAndWait('PYTHON1');
await insertPythonCellAndWait('PYTHON2', 1);
assert.lengthOf(model.cells, 2);
assertCodeCell(0, 'PYTHON1');
assertCodeCell(1, 'PYTHON2');

handler.reset();
await commands.executeCommand('notebook.cell.joinBelow');

await handler.assertFiredExactly(1); // Delete last cell.
// Bug in VS Code.
assertCodeCell(0, 'PYTHON1PYTHON2');
Copy link
Author

@DonJayamanne DonJayamanne Jun 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a known upstream but

});
});
});
});
3 changes: 3 additions & 0 deletions src/test/datascience/notebook/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ export async function insertPythonCell(source: string, index: number = 0) {
export async function insertPythonCellAndWait(source: string, index: number = 0) {
await (await insertPythonCell(source, index)).waitForCellToGetAdded();
}
export async function insertMarkdownCellAndWait(source: string, index: number = 0) {
await (await insertMarkdownCell(source, index)).waitForCellToGetAdded();
}
export async function deleteCell(index: number = 0) {
const { vscodeNotebook } = await getServices();
const activeEditor = vscodeNotebook.activeNotebookEditor;
Expand Down