diff --git a/jest.config.js b/jest.config.js index 2afa377fa6..afe36e4466 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,9 +6,10 @@ config.transform = { '\\.[j]sx?$': 'babel-jest' }; config.transformIgnorePatterns = []; +config.coveragePathIgnorePatterns = ['./node_modules/', './test']; config.coverageThreshold = { global: { - functions: 80, + functions: 90, lines: 90, statements: -10 } diff --git a/test/status.spec.ts b/test/status.spec.ts index a5eac73822..a55d9c8ae0 100644 --- a/test/status.spec.ts +++ b/test/status.spec.ts @@ -8,16 +8,7 @@ import { Widget } from '@lumino/widgets'; import { JupyterLab } from '@jupyterlab/application'; -import { sessionContextDialogs } from '@jupyterlab/apputils'; - -import { editorServices } from '@jupyterlab/codemirror'; - -import { - INotebookModel, - NotebookTracker, - NotebookWidgetFactory, - StaticNotebook -} from '@jupyterlab/notebook'; +import { INotebookModel, NotebookTracker } from '@jupyterlab/notebook'; import { Context } from '@jupyterlab/docregistry'; import { @@ -31,8 +22,12 @@ import { LoggerRegistry } from '@jupyterlab/logconsole'; import WS from 'jest-websocket-mock'; import plugin from '../src/index'; +import * as testUtils from './utils'; const server = new JupyterServer(); +const defaultRendermime = NBTestUtils.defaultRenderMime(); +const loggerRegistry = new LoggerRegistry({ defaultRendermime, maxLength: 10 }); +const notebookTracker = new NotebookTracker({ namespace: 'test' }); beforeAll(async () => { jest.setTimeout(20000); @@ -43,80 +38,33 @@ afterAll(async () => { await server.shutdown(); }); -const messages = [ - { - __timestamp__: '2021-08-26T11:36:40.946609Z', - __schema__: 'event.datastudio.jupyter.com/session-message', - __schema_version__: 1, - __metadata_version__: 1, - kernel_path: 'Untitled7.ipynb', - kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796', - message: - 'Starting a session for kernel: bb4cd953-ef2d-4bb7-b5ea-80749e937796.' - }, - { - __timestamp__: '2021-08-26T11:36:40.992769Z', - __schema__: 'event.datastudio.jupyter.com/kernel-message', - __schema_version__: 1, - __metadata_version__: 1, - process_id: 'e48b11fd-caf7-4c11-a35f-15f8337a585b', - message: 'Current Status (attempt 1): Ready (Kernel is running.)', - kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796' - }, - { - __timestamp__: '2021-08-26T11:36:40.993532Z', - __schema__: 'event.datastudio.jupyter.com/kernel-status', - __schema_version__: 1, - __metadata_version__: 1, - process_id: 'e48b11fd-caf7-4c11-a35f-15f8337a585b', - status: 'Ready', - details: 'Kernel is running.', - kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796' - }, - { - __timestamp__: '2021-08-26T11:36:40.998530Z', - __schema__: 'event.datastudio.jupyter.com/session-message', - __schema_version__: 1, - __metadata_version__: 1, - kernel_path: 'Untitled7.ipynb', - kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796', - message: 'Session created for kernel.' - } -]; - -const app = new JupyterLab(); -const defaultRendermime = NBTestUtils.defaultRenderMime(); -const loggerRegistry = new LoggerRegistry({ defaultRendermime, maxLength: 10 }); -const notebookTracker = new NotebookTracker({ namespace: 'test' }); - describe('status', () => { + let app: JupyterLab; + let context: Context; beforeEach(async () => { - context = await initNotebookContext({ startKernel: true }); + // Wait for the server to start before creating the application + // so we pick up the page config (base url, etc.) + app = new JupyterLab(); + context = await initNotebookContext({ + manager: app.serviceManager, + startKernel: true + }); }); - it('should handle websocket messages', async () => { - // TODO: Replace with a factory from NBTestUtils when available - const factory = new NotebookWidgetFactory({ - name: 'Notebook', - fileTypes: ['notebook'], - modelName: 'notebook', - defaultFor: ['notebook'], - preferKernel: true, - canStartKernel: true, - rendermime: defaultRendermime, - contentFactory: NBTestUtils.createNotebookPanelFactory(), - editorConfig: StaticNotebook.defaultEditorConfig, - notebookConfig: StaticNotebook.defaultNotebookConfig, - mimeTypeService: editorServices.mimeTypeService, - sessionDialogs: sessionContextDialogs + it('should handle telemetry messages', async () => { + const factory = testUtils.createNotebookWidgetFactory({ + rendermime: defaultRendermime }); app.docRegistry.addWidgetFactory(factory); const server = new WS('ws://localhost:5555', { jsonProtocol: true }); await plugin.activate(app, loggerRegistry, notebookTracker); + // Use the factory to create a panel and simulate the widget + // extensions being created for the panel. + // this is normally done by the WidgetManager. const notebookPanel = factory.createNew(context); const disposables: IDisposable[] = []; notebookTracker.add(notebookPanel); @@ -131,7 +79,8 @@ describe('status', () => { Widget.attach(notebookPanel, document.body); MessageLoop.sendMessage(notebookPanel, Widget.Msg.UpdateRequest); - messages.forEach(message => { + // Send the test messages + testUtils.telemetryMessages.forEach(message => { // Send unmodified message first to simulate getting messages // without having a sync if (message.__schema__.indexOf('session-message') === -1) { @@ -141,6 +90,8 @@ describe('status', () => { message.kernel_path = context.sessionContext.path; server.send(message); }); + + // Clean up all resources each(disposables, d => d.dispose()); server.close(); WS.clean(); diff --git a/test/utils.ts b/test/utils.ts new file mode 100644 index 0000000000..b519d7db92 --- /dev/null +++ b/test/utils.ts @@ -0,0 +1,76 @@ +import { sessionContextDialogs } from '@jupyterlab/apputils'; + +import { editorServices } from '@jupyterlab/codemirror'; + +import { + NotebookPanel, + NotebookWidgetFactory, + StaticNotebook +} from '@jupyterlab/notebook'; + +import { NBTestUtils } from '@jupyterlab/testutils'; + +/** + * Create a notebook widget factory. + */ +export function createNotebookWidgetFactory( + options: Partial> = {} +): NotebookWidgetFactory { + // TODO: Replace with a factory from NBTestUtils when available + return new NotebookWidgetFactory({ + name: 'Notebook', + fileTypes: ['notebook'], + modelName: 'notebook', + defaultFor: ['notebook'], + preferKernel: true, + canStartKernel: true, + rendermime: NBTestUtils.defaultRenderMime(), + contentFactory: NBTestUtils.createNotebookPanelFactory(), + editorConfig: StaticNotebook.defaultEditorConfig, + notebookConfig: StaticNotebook.defaultNotebookConfig, + mimeTypeService: editorServices.mimeTypeService, + sessionDialogs: sessionContextDialogs, + ...options + }); +} + +export const telemetryMessages = [ + { + __timestamp__: '2021-08-26T11:36:40.946609Z', + __schema__: 'event.datastudio.jupyter.com/session-message', + __schema_version__: 1, + __metadata_version__: 1, + kernel_path: 'Untitled7.ipynb', + kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796', + message: + 'Starting a session for kernel: bb4cd953-ef2d-4bb7-b5ea-80749e937796.' + }, + { + __timestamp__: '2021-08-26T11:36:40.992769Z', + __schema__: 'event.datastudio.jupyter.com/kernel-message', + __schema_version__: 1, + __metadata_version__: 1, + process_id: 'e48b11fd-caf7-4c11-a35f-15f8337a585b', + message: 'Current Status (attempt 1): Ready (Kernel is running.)', + kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796' + }, + { + __timestamp__: '2021-08-26T11:36:40.993532Z', + __schema__: 'event.datastudio.jupyter.com/kernel-status', + __schema_version__: 1, + __metadata_version__: 1, + process_id: 'e48b11fd-caf7-4c11-a35f-15f8337a585b', + status: 'Ready', + details: 'Kernel is running.', + kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796' + }, + { + __timestamp__: '2021-08-26T11:36:40.998530Z', + __schema__: 'event.datastudio.jupyter.com/session-message', + __schema_version__: 1, + __metadata_version__: 1, + kernel_path: 'Untitled7.ipynb', + kernel_id: 'bb4cd953-ef2d-4bb7-b5ea-80749e937796', + message: 'Session created for kernel.' + } +];