Skip to content

Commit 2f2f095

Browse files
author
Frédéric Collonval
committed
Switch to jest
1 parent ea6d772 commit 2f2f095

File tree

14 files changed

+212
-280
lines changed

14 files changed

+212
-280
lines changed

.github/workflows/build.yml

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,30 @@ jobs:
5050
python -m pip install -U pip setuptools cookiecutter
5151
5252
- name: Test the extension
53-
# env:
54-
# CHROME_BIN: chromium-browser
5553
run: |
5654
cookiecutter . --config-file tests/testconfig.yaml --no-input
5755
pushd jupyter-widget-testwidgets
5856
python -m pip install --upgrade -v -e ".[test, examples, docs]"
5957
yarn run lint:check
6058
6159
pytest
62-
npm run test:ci
60+
yarn run test
61+
popd
6362
64-
# - name: Check docs can be build + links
65-
# run: |
66-
# pushd jupyter-widget-testwidgets/docs
67-
# make html
68-
# make linkcheck
69-
# popd
63+
- name: Check docs can be build + links
64+
run: |
65+
python -m pip install jupyter_sphinx sphinx sphinx_rtd_theme nbsphinx nbsphinx-link pytest-check-links
66+
pushd jupyter-widget-testwidgets/docs
67+
make html
68+
popd
69+
70+
python -m pytest --check-links
7071
7172
- name: Make a non-local install so the data_files get populated
7273
run: |
7374
pip uninstall -y jupyter_widget_testwidgets
74-
cd jupyter-widget-testwidgets
75+
pushd jupyter-widget-testwidgets
76+
7577
pip install .
7678
7779
# Validate nbextension (enable does not use exit code):
@@ -84,3 +86,5 @@ jobs:
8486
jupyter labextension list 2>&1 | grep -ie "jupyter-widget-testwidgets.*OK"
8587
# Make sure our lab extension can be develop installed.
8688
jupyter labextension develop . --overwrite
89+
90+
popd

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.pythonPath": "/home/fcollonval/miniconda3/envs/widgets/bin/python"
3+
}

{{cookiecutter.github_project_name}}/.github/workflows/build.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@ jobs:
5050
run: |
5151
python -m pip install --upgrade -v -e ".[test, examples, docs]"
5252
yarn run lint:check
53+
5354
pytest
54-
yarn run test:ci
55+
yarn run test
56+
5557
- name: Check docs can be build + links
5658
run: |
59+
python -m pip install jupyter_sphinx sphinx sphinx_rtd_theme nbsphinx nbsphinx-link pytest-check-links
5760
pushd docs
5861
make html
59-
make linkcheck
6062
popd
61-
python -m pytest_check_links --links-ext=.md -o testpaths=. -o addopts=
63+
python -m pytest --check-links
6264
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
sourceMap: 'inline',
3+
presets: [
4+
[
5+
'@babel/preset-env',
6+
{
7+
targets: {
8+
node: 'current',
9+
},
10+
},
11+
],
12+
],
13+
};

{{cookiecutter.github_project_name}}/docs/environment.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ name: {{cookiecutter.python_package_name}}_docs
33
channels:
44
- conda-forge
55
dependencies:
6-
- python=3.5
7-
- nodejs
8-
- numpy
9-
- sphinx
10-
- nbsphinx
11-
- jupyter_sphinx
6+
- python=3.*
7+
- nodejs
8+
- jupyter_sphinx
9+
- sphinx
10+
- sphinx_rtd_theme
11+
- nbsphinx
12+
- nbsphinx-link
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
automock: false,
3+
moduleNameMapper: {
4+
'\\.(css|less|sass|scss)$': 'identity-obj-proxy',
5+
},
6+
preset: 'ts-jest/presets/js-with-babel',
7+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
8+
testPathIgnorePatterns: ['/lib/', '/node_modules/'],
9+
testRegex: '/__tests__/.*.spec.ts[x]?$',
10+
transformIgnorePatterns: ['/node_modules/(?!(@jupyter(lab|-widgets)/.*)/)'],
11+
globals: {
12+
'ts-jest': {
13+
tsconfig: '<rootDir>/tsconfig.json',
14+
},
15+
},
16+
};

{{cookiecutter.github_project_name}}/package.json

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,21 @@
4242
"lint": "eslint . --ext .ts,.tsx --fix",
4343
"lint:check": "eslint . --ext .ts,.tsx",
4444
"prepack": "yarn run build:lib",
45-
"test": "yarn run test:firefox",
46-
"test:ci": "karma start --browsers=ChromeCI tests/karma.conf.js",
47-
"test:chrome": "karma start --browsers=Chrome tests/karma.conf.js",
48-
"test:debug": "karma start --browsers=Chrome --singleRun=false --debug=true tests/karma.conf.js",
49-
"test:firefox": "karma start --browsers=Firefox tests/karma.conf.js",
50-
"test:ie": "karma start --browsers=IE tests/karma.conf.js",
45+
"test": "jest",
5146
"watch": "npm-run-all -p watch:*",
5247
"watch:lib": "tsc -w",
5348
"watch:nbextension": "webpack --watch"
5449
},
5550
"dependencies": {
56-
"@jupyter-widgets/base": "^1.1.10 || ^2 || ^3 || ^4"
51+
"@jupyter-widgets/base": "^1.1.10 || ^2.0.0 || ^3.0.0 || ^4.0.0"
5752
},
5853
"devDependencies": {
54+
"@babel/core": "^7.5.0",
55+
"@babel/preset-env": "^7.5.0",
5956
"@jupyterlab/builder": "^3.0.0",
6057
"@phosphor/application": "^1.6.0",
6158
"@phosphor/widgets": "^1.6.0",
62-
"@types/expect.js": "^0.3.29",
63-
"@types/mocha": "^8.2.0",
64-
"@types/node": "^14.14.13",
59+
"@types/jest": "^26.0.0",
6560
"@types/webpack-env": "^1.13.6",
6661
"@typescript-eslint/eslint-plugin": "^3.6.0",
6762
"@typescript-eslint/parser": "^3.6.0",
@@ -70,23 +65,16 @@
7065
"eslint": "^7.4.0",
7166
"eslint-config-prettier": "^6.11.0",
7267
"eslint-plugin-prettier": "^3.1.4",
73-
"expect.js": "^0.3.1",
7468
"fs-extra": "^7.0.0",
75-
"karma": "^5.2.3",
76-
"karma-chrome-launcher": "^3.1.0",
77-
"karma-coverage": "^2.0.1",
78-
"karma-firefox-launcher": "^2.1.0",
79-
"karma-mocha": "^2.0.1",
80-
"karma-mocha-reporter": "^2.2.5",
81-
"karma-typescript": "^5.2.0",
82-
"karma-typescript-es6-transform": "^5.2.0",
69+
"identity-obj-proxy": "^3.0.0",
70+
"jest": "^26.0.0",
8371
"mkdirp": "^0.5.1",
84-
"mocha": "^8.2.1",
8572
"npm-run-all": "^4.1.3",
8673
"prettier": "^2.0.5",
8774
"rimraf": "^2.6.2",
8875
"source-map-loader": "^1.1.3",
8976
"style-loader": "^1.0.0",
77+
"ts-jest": "^26.0.0",
9078
"ts-loader": "^8.0.0",
9179
"typescript": "~4.1.3",
9280
"webpack": "^5.0.0",
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
// Add any needed widget imports here (or from controls)
5+
// import {} from '@jupyter-widgets/base';
6+
7+
import { createTestModel } from './utils';
8+
9+
import { ExampleModel } from '..';
10+
11+
describe('Example', () => {
12+
describe('ExampleModel', () => {
13+
it('should be createable', () => {
14+
const model = createTestModel(ExampleModel);
15+
expect(model).toBeInstanceOf(ExampleModel);
16+
expect(model.get('value')).toEqual('Hello World');
17+
});
18+
19+
it('should be createable with a value', () => {
20+
const state = { value: 'Foo Bar!' };
21+
const model = createTestModel(ExampleModel, state);
22+
expect(model).toBeInstanceOf(ExampleModel);
23+
expect(model.get('value')).toEqual('Foo Bar!');
24+
});
25+
});
26+
});
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
import * as widgets from '@jupyter-widgets/base';
5+
import * as services from '@jupyterlab/services';
6+
7+
let numComms = 0;
8+
9+
export class MockComm implements widgets.IClassicComm {
10+
constructor() {
11+
this.comm_id = `mock-comm-id-${numComms}`;
12+
numComms += 1;
13+
}
14+
on_close(fn: ((x?: any) => void) | null): void {
15+
this._on_close = fn;
16+
}
17+
on_msg(fn: (x?: any) => void): void {
18+
this._on_msg = fn;
19+
}
20+
_process_msg(msg: services.KernelMessage.ICommMsgMsg): void | Promise<void> {
21+
if (this._on_msg) {
22+
return this._on_msg(msg);
23+
} else {
24+
return Promise.resolve();
25+
}
26+
}
27+
close(): string {
28+
if (this._on_close) {
29+
this._on_close();
30+
}
31+
return 'dummy';
32+
}
33+
send(): string {
34+
return 'dummy';
35+
}
36+
37+
open(): string {
38+
return 'dummy';
39+
}
40+
41+
comm_id: string;
42+
target_name = 'dummy';
43+
_on_msg: ((x?: any) => void) | null = null;
44+
_on_close: ((x?: any) => void) | null = null;
45+
}
46+
47+
export class DummyManager extends widgets.ManagerBase<HTMLElement> {
48+
constructor() {
49+
super();
50+
this.el = window.document.createElement('div');
51+
}
52+
53+
display_view(
54+
msg: services.KernelMessage.IMessage,
55+
view: widgets.DOMWidgetView,
56+
options: any
57+
) {
58+
// TODO: make this a spy
59+
// TODO: return an html element
60+
return Promise.resolve(view).then((view) => {
61+
this.el.appendChild(view.el);
62+
view.on('remove', () => console.log('view removed', view));
63+
return view.el;
64+
});
65+
}
66+
67+
protected loadClass(
68+
className: string,
69+
moduleName: string,
70+
moduleVersion: string
71+
): Promise<any> {
72+
if (moduleName === '@jupyter-widgets/base') {
73+
if ((widgets as any)[className]) {
74+
return Promise.resolve((widgets as any)[className]);
75+
} else {
76+
return Promise.reject(`Cannot find class ${className}`);
77+
}
78+
} else if (moduleName === 'jupyter-datawidgets') {
79+
if (this.testClasses[className]) {
80+
return Promise.resolve(this.testClasses[className]);
81+
} else {
82+
return Promise.reject(`Cannot find class ${className}`);
83+
}
84+
} else {
85+
return Promise.reject(`Cannot find module ${moduleName}`);
86+
}
87+
}
88+
89+
_get_comm_info() {
90+
return Promise.resolve({});
91+
}
92+
93+
_create_comm() {
94+
return Promise.resolve(new MockComm());
95+
}
96+
97+
el: HTMLElement;
98+
99+
testClasses: { [key: string]: any } = {};
100+
}
101+
102+
export interface Constructor<T> {
103+
new (attributes?: any, options?: any): T;
104+
}
105+
106+
export function createTestModel<T extends widgets.WidgetModel>(
107+
constructor: Constructor<T>,
108+
attributes?: any
109+
): T {
110+
let id = widgets.uuid();
111+
let widget_manager = new DummyManager();
112+
let modelOptions = {
113+
widget_manager: widget_manager,
114+
model_id: id,
115+
};
116+
117+
return new constructor(attributes, modelOptions);
118+
}

{{cookiecutter.github_project_name}}/tests/karma.conf.js

Lines changed: 0 additions & 67 deletions
This file was deleted.

0 commit comments

Comments
 (0)