123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import { CodeCell, MarkdownCell } from '@jupyterlab/cells';
- import { Context } from '@jupyterlab/docregistry';
- import { KernelMessage } from '@jupyterlab/services';
- import {
- acceptDialog,
- framePromise,
- signalToPromise,
- sleep
- } from '@jupyterlab/testutils';
- import { PromiseDelegate } from '@lumino/coreutils';
- import { Widget } from '@lumino/widgets';
- import { simulate } from 'simulate-event';
- import {
- INotebookModel,
- NotebookActions,
- NotebookPanel,
- ToolbarItems
- } from '..';
- import * as utils from './utils';
- const JUPYTER_CELL_MIME = 'application/vnd.jupyter.cells';
- describe('@jupyterlab/notebook', () => {
- describe('ToolbarItems', () => {
- describe('noKernel', () => {
- let context: Context<INotebookModel>;
- let panel: NotebookPanel;
- beforeEach(async () => {
- context = await utils.createMockContext();
- panel = utils.createNotebookPanel(context);
- context.model.fromJSON(utils.DEFAULT_CONTENT);
- });
- afterEach(() => {
- panel.dispose();
- context.dispose();
- });
- describe('#createSaveButton()', () => {
- it('should save when clicked', async () => {
- const button = ToolbarItems.createSaveButton(panel);
- Widget.attach(button, document.body);
- const promise = signalToPromise(context.fileChanged);
- await framePromise();
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- await promise;
- button.dispose();
- });
- it("should add an inline svg node with the 'save' icon", async () => {
- const button = ToolbarItems.createSaveButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(
- button.node.querySelector("[data-icon$='save']")
- ).toBeDefined();
- });
- });
- describe('#createInsertButton()', () => {
- it('should insert below when clicked', async () => {
- const button = ToolbarItems.createInsertButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- expect(panel.content.activeCellIndex).toBe(1);
- expect(panel.content.activeCell).toBeInstanceOf(CodeCell);
- button.dispose();
- });
- it("should add an inline svg node with the 'add' icon", async () => {
- const button = ToolbarItems.createInsertButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(button.node.querySelector("[data-icon$='add']")).toBeDefined();
- button.dispose();
- });
- });
- describe('#createCutButton()', () => {
- it('should cut when clicked', async () => {
- const button = ToolbarItems.createCutButton(panel);
- const count = panel.content.widgets.length;
- Widget.attach(button, document.body);
- await framePromise();
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- expect(panel.content.widgets.length).toBe(count - 1);
- expect(utils.clipboard.hasData(JUPYTER_CELL_MIME)).toBe(true);
- button.dispose();
- });
- it("should add an inline svg node with the 'cut' icon", async () => {
- const button = ToolbarItems.createCutButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(button.node.querySelector("[data-icon$='cut']")).toBeDefined();
- button.dispose();
- });
- });
- describe('#createCopyButton()', () => {
- it('should copy when clicked', async () => {
- const button = ToolbarItems.createCopyButton(panel);
- const count = panel.content.widgets.length;
- Widget.attach(button, document.body);
- await framePromise();
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- expect(panel.content.widgets.length).toBe(count);
- expect(utils.clipboard.hasData(JUPYTER_CELL_MIME)).toBe(true);
- button.dispose();
- });
- it("should add an inline svg node with the 'copy' icon", async () => {
- const button = ToolbarItems.createCopyButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(
- button.node.querySelector("[data-icon$='copy']")
- ).toBeDefined();
- button.dispose();
- });
- });
- describe('#createPasteButton()', () => {
- it('should paste when clicked', async () => {
- const button = ToolbarItems.createPasteButton(panel);
- const count = panel.content.widgets.length;
- Widget.attach(button, document.body);
- await framePromise();
- NotebookActions.copy(panel.content);
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- await sleep();
- expect(panel.content.widgets.length).toBe(count + 1);
- button.dispose();
- });
- it("should add an inline svg node with the 'paste' icon", async () => {
- const button = ToolbarItems.createPasteButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(
- button.node.querySelector("[data-icon$='paste']")
- ).toBeDefined();
- button.dispose();
- });
- });
- describe('#createCellTypeItem()', () => {
- it('should track the cell type of the current cell', async () => {
- const item = ToolbarItems.createCellTypeItem(panel);
- Widget.attach(item, document.body);
- await framePromise();
- const node = item.node.getElementsByTagName(
- 'select'
- )[0] as HTMLSelectElement;
- expect(node.value).toBe('code');
- panel.content.activeCellIndex++;
- await framePromise();
- expect(node.value).toBe('markdown');
- item.dispose();
- });
- it("should display `'-'` if multiple cell types are selected", async () => {
- const item = ToolbarItems.createCellTypeItem(panel);
- Widget.attach(item, document.body);
- await framePromise();
- const node = item.node.getElementsByTagName(
- 'select'
- )[0] as HTMLSelectElement;
- expect(node.value).toBe('code');
- panel.content.select(panel.content.widgets[1]);
- await framePromise();
- expect(node.value).toBe('-');
- item.dispose();
- });
- it('should display the active cell type if multiple cells of the same type are selected', async () => {
- const item = ToolbarItems.createCellTypeItem(panel);
- Widget.attach(item, document.body);
- await framePromise();
- const node = item.node.getElementsByTagName(
- 'select'
- )[0] as HTMLSelectElement;
- expect(node.value).toBe('code');
- const cell = panel.model!.contentFactory.createCodeCell({});
- panel.model!.cells.insert(1, cell);
- panel.content.select(panel.content.widgets[1]);
- await framePromise();
- expect(node.value).toBe('code');
- item.dispose();
- });
- });
- describe('#getDefaultItems()', () => {
- it('should return the default items of the panel toolbar', () => {
- const names = ToolbarItems.getDefaultItems(panel).map(item => {
- const name = item.name;
- item.widget.dispose();
- return name;
- });
- expect(names).toEqual([
- 'save',
- 'insert',
- 'cut',
- 'copy',
- 'paste',
- 'run',
- 'interrupt',
- 'restart',
- 'restart-and-run',
- 'cellType',
- 'spacer',
- 'kernelName'
- ]);
- });
- });
- });
- describe('kernelRequired', () => {
- let context: Context<INotebookModel>;
- let panel: NotebookPanel;
- beforeEach(async function () {
- context = await utils.createMockContext(true);
- panel = utils.createNotebookPanel(context);
- context.model.fromJSON(utils.DEFAULT_CONTENT);
- });
- afterEach(async () => {
- await context.sessionContext.shutdown();
- panel.dispose();
- context.dispose();
- });
- describe('#createRunButton()', () => {
- it('should run and advance when clicked', async () => {
- const button = ToolbarItems.createRunButton(panel);
- const widget = panel.content;
- // Clear and select the first two cells.
- const codeCell = widget.widgets[0] as CodeCell;
- codeCell.model.outputs.clear();
- widget.select(codeCell);
- const mdCell = widget.widgets[1] as MarkdownCell;
- mdCell.rendered = false;
- widget.select(mdCell);
- Widget.attach(button, document.body);
- await context.sessionContext.session!.kernel!.info;
- const delegate = new PromiseDelegate();
- panel.sessionContext.iopubMessage.connect((_, msg) => {
- if (KernelMessage.isExecuteInputMsg(msg)) {
- delegate.resolve(void 0);
- }
- });
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- await delegate.promise;
- button.dispose();
- });
- it("should add an inline svg node with the 'run' icon", async () => {
- const button = ToolbarItems.createRunButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(button.node.querySelector("[data-icon$='run']")).toBeDefined();
- });
- });
- describe('#createRestartRunAllButton()', () => {
- it('should restart and run all when clicked', async () => {
- const button = ToolbarItems.createRestartRunAllButton(panel);
- const widget = panel.content;
- // Clear the first two cells.
- const codeCell = widget.widgets[0] as CodeCell;
- codeCell.model.outputs.clear();
- const mdCell = widget.widgets[1] as MarkdownCell;
- mdCell.rendered = false;
- Widget.attach(button, document.body);
- await panel.sessionContext.ready;
- const delegate = new PromiseDelegate();
- panel.sessionContext.iopubMessage.connect((_, msg) => {
- if (KernelMessage.isExecuteInputMsg(msg)) {
- delegate.resolve(void 0);
- }
- });
- simulate(button.node.firstChild as HTMLElement, 'mousedown');
- await acceptDialog();
- await delegate.promise;
- button.dispose();
- });
- it("should add an inline svg node with the 'fast-forward' icon", async () => {
- const button = ToolbarItems.createRestartRunAllButton(panel);
- Widget.attach(button, document.body);
- await framePromise();
- expect(
- button.node.querySelector("[data-icon$='fast-forward']")
- ).toBeDefined();
- });
- });
- });
- });
- });
|