From e0732080eebd0163f14a715b41e2cea6727c9c71 Mon Sep 17 00:00:00 2001 From: Zachary Sailer Date: Fri, 17 Sep 2021 11:18:59 -0700 Subject: [PATCH] File Radar Extension (#158) * add file radar extension * add extension to plugin list * explicitly calculate coverage from all files * jest config point at ts * working tests * remove unnecessary testing logic * add yarn.lock back in and remove unused imports in test/utils * bump test coverage threshold --- jest.config.js | 3 +- src/fileradar.ts | 37 ++++++++++++++++++++++++ src/index.ts | 4 ++- test/fileradar.spec.ts | 65 ++++++++++++++++++++++++++++++++++++++++++ test/utils.ts | 1 - 5 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/fileradar.ts create mode 100644 test/fileradar.spec.ts diff --git a/jest.config.js b/jest.config.js index a4492d1ae5..249a9c3c24 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,8 +11,9 @@ config.coverageThreshold = { global: { functions: 90, lines: 85, - statements: -15 + statements: -20 } }; +config.collectCoverageFrom = ['src/**/*.{ts,tsx}']; module.exports = config; diff --git a/src/fileradar.ts b/src/fileradar.ts new file mode 100644 index 0000000000..30a5da106e --- /dev/null +++ b/src/fileradar.ts @@ -0,0 +1,37 @@ +import { IMainMenu } from '@jupyterlab/mainmenu'; + +import { + JupyterFrontEnd, + JupyterFrontEndPlugin +} from '@jupyterlab/application'; + +/** + * Build an external links menu item. + */ +export const FileRadarPlugin: JupyterFrontEndPlugin = { + id: 'data_studio:file_radar_plugin', + autoStart: true, + requires: [IMainMenu], + activate: (app: JupyterFrontEnd, mainMenu: IMainMenu) => { + console.log('JupyterLab extension "File Radar" is activated!'); + + const radarUrl = + 'rdar://new/problem/component=ACI%20Data%20Studio&version=Support'; + const commandID = 'help:file-radar'; + + app.commands.addCommand(commandID, { + label: 'File a Radar', + isEnabled: () => true, + isVisible: () => true, + execute: () => { + window.open(radarUrl); + } + }); + + mainMenu.helpMenu.addGroup([ + { + command: commandID + } + ]); + } +}; diff --git a/src/index.ts b/src/index.ts index 96045656a7..7aa63df593 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,10 +2,12 @@ import { JupyterFrontEndPlugin } from '@jupyterlab/application'; import { ExternalLinksPlugin } from './externallinks'; import { kernelStatusPlugin } from './status'; +import { FileRadarPlugin } from './fileradar'; const plugins: JupyterFrontEndPlugin[] = [ kernelStatusPlugin, - ExternalLinksPlugin + ExternalLinksPlugin, + FileRadarPlugin ]; export default plugins; diff --git a/test/fileradar.spec.ts b/test/fileradar.spec.ts new file mode 100644 index 0000000000..696d01e79b --- /dev/null +++ b/test/fileradar.spec.ts @@ -0,0 +1,65 @@ +// import { CommandRegistry } from '@lumino/commands'; + +import { JupyterLab } from '@jupyterlab/application'; + +import { MainMenu } from '@jupyterlab/mainmenu'; +import { CommandRegistry } from '@lumino/commands'; +import { JupyterServer } from '@jupyterlab/testutils'; + +import { FileRadarPlugin } from '../src/fileradar'; + +jest.useFakeTimers(); // Keep at the Top of the file +const server = new JupyterServer(); + +beforeAll(async () => { + jest.setTimeout(20000); + await server.start(); +}); + +afterAll(async () => { + await server.shutdown(); +}); + +describe('status', () => { + let app: JupyterLab; + let registry: CommandRegistry; + let mainMenu: MainMenu; + + beforeEach(async () => { + // Wait for the server to start before creating the application + // so we pick up the page config (base url, etc.) + app = new JupyterLab(); + registry = app.commands; + mainMenu = new MainMenu(registry); + }); + + it('should handle file radar link', () => { + FileRadarPlugin.activate(app, mainMenu); + const registry = app.commands; + const helpMenu = mainMenu.helpMenu; + const commandID = 'help:file-radar'; + + // Assert that the command is registered when the + // extension is activated. + expect(registry.hasCommand(commandID)).toEqual(true); + // Assert that the helpmenu includes the new item. + expect(helpMenu.items).toEqual( + expect.arrayContaining([expect.objectContaining({ command: commandID })]) + ); + + // Set up a spy to see if the window opens + // a radar. + const closeSpy = jest.fn(); + window.open = jest.fn().mockReturnValue({ close: closeSpy }); + window.close = jest.fn(); + + // Execute the command and assert that a radar is opened. + registry.execute(commandID); + expect(window.open).toHaveBeenCalled(); + expect(window.open).toHaveBeenCalledWith( + 'rdar://new/problem/component=ACI%20Data%20Studio&version=Support' + ); + + jest.runAllTimers(); + }); +}); diff --git a/test/utils.ts b/test/utils.ts index b519d7db92..6b5be89f36 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -9,7 +9,6 @@ import { } from '@jupyterlab/notebook'; import { NBTestUtils } from '@jupyterlab/testutils'; - /** * Create a notebook widget factory. */