Skip to content

Commit a8b8176

Browse files
committed
JavaScript tests
1 parent 2d937b0 commit a8b8176

10 files changed

Lines changed: 2577 additions & 65 deletions

File tree

.github/workflows/build.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ jobs:
8585
- name: JavaScript prettyfier
8686
run: yarn run prettier:check
8787

88+
- name: JavaScript tests
89+
run: yarn run test
90+
8891
- name: Install Galata
8992
run: yarn install
9093
working-directory: ui-tests
@@ -110,10 +113,6 @@ jobs:
110113
name: ui-test-output
111114
path: ui-tests/test-output
112115

113-
# - name: JavaScript tests
114-
# run: yarn run test
115-
# working-directory: js
116-
117116
- name: Build Python package
118117
run: |
119118
python setup.py sdist bdist_wheel

karma.conf.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Karma configuration
2+
// Generated on Wed Jun 20 2018 16:46:14 GMT+0200 (CEST)
3+
const webpackConfig = require('./webpack.config.js');
4+
5+
module.exports = function (config) {
6+
config.set({
7+
basePath: '',
8+
frameworks: ['mocha', 'chai', 'sinon'],
9+
files: [
10+
// we use 1 bundle for testing
11+
{ pattern: 'lib/test/index.js' },
12+
],
13+
exclude: ['**/embed.js'],
14+
preprocessors: {
15+
// the bundle goes through webpack, and will emit (inline) source maps, which karma needs to read again
16+
'lib/test/index.js': ['webpack', 'sourcemap'],
17+
},
18+
webpack: {
19+
module: {
20+
rules: webpackConfig[0].module.rules,
21+
},
22+
// source mapping without inline does not seem to work
23+
devtool: 'inline-source-map',
24+
mode: 'development',
25+
resolve: {
26+
extensions: ['.js'],
27+
},
28+
},
29+
reporters: ['progress', 'mocha'],
30+
port: 9876,
31+
colors: true,
32+
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
33+
logLevel: config.LOG_INFO,
34+
autoWatch: true,
35+
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
36+
browsers: ['ChromeHeadless'],
37+
customLauncher: {
38+
ChromeHeadless: {
39+
base: 'ChromeHeadless',
40+
flags: ['--headless', '--remote-debugging-port=9222'],
41+
},
42+
},
43+
// if true, Karma captures browsers, runs the tests and exits
44+
singleRun: true,
45+
// how many browser should be started simultaneous
46+
concurrency: Infinity,
47+
});
48+
};

package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"clean:labextension": "rimraf bqplot-gl/labextension",
4141
"clean:nbextension": "rimraf bqplot-gl/nbextension/static/index.js",
4242
"prepack": "yarn run build:lib",
43+
"test": "karma start --single-run",
4344
"watch": "npm-run-all -p watch:*",
4445
"watch:lib": "tsc -w",
4546
"watch:nbextension": "webpack --watch --mode=development",
@@ -59,28 +60,47 @@
5960
"three": "^0.91.0"
6061
},
6162
"devDependencies": {
63+
"@jupyter-widgets/controls": "^1.5.0 || ^2 || ^3",
6264
"@babel/core": "^7.5.0",
6365
"@babel/preset-env": "^7.5.0",
6466
"@babel/preset-typescript": "^7.15.0",
6567
"@jupyterlab/builder": "^3.0.0",
6668
"@phosphor/application": "^1.6.0",
6769
"@phosphor/widgets": "^1.6.0",
70+
"@types/chai": "^4.1.7",
6871
"@types/d3": "^5.7.2",
72+
"@types/expect.js": "^0.3.29",
73+
"@types/mocha": "^7.0.2",
74+
"@types/sinon": "^9.0.0",
6975
"@types/webpack-env": "^1.13.6",
7076
"@typescript-eslint/eslint-plugin": "^4.29.3",
7177
"@typescript-eslint/parser": "^4.29.3",
78+
"chai": "^4.1.2",
7279
"acorn": "^7.2.0",
7380
"css-loader": "^3.2.0",
7481
"eslint": "^7.4.0",
7582
"eslint-config-prettier": "^8.3.0",
7683
"eslint-plugin-prettier": "^3.4.1",
84+
"karma": "^5.0.2",
85+
"karma-chai": "^0.1.0",
86+
"karma-chrome-launcher": "^3.1.0",
87+
"karma-mocha": "^2.0.0",
88+
"karma-mocha-reporter": "^2.2.5",
89+
"karma-sinon": "^1.0.5",
90+
"karma-sourcemap-loader": "^0.3.7",
91+
"karma-typescript": "^5.0.2",
92+
"karma-typescript-es6-transform": "^5.0.2",
93+
"karma-webpack": "^5.0.0",
94+
"mocha": "^7.1.1",
7795
"fs-extra": "^7.0.0",
7896
"identity-obj-proxy": "^3.0.0",
7997
"mkdirp": "^0.5.1",
8098
"npm-run-all": "^4.1.3",
8199
"prettier": "^2.0.5",
82100
"raw-loader": "~4.0.1",
83101
"rimraf": "^2.6.2",
102+
"sinon": "^9.0.2",
103+
"sinon-chai": "^3.3.0",
84104
"source-map-loader": "^1.1.3",
85105
"style-loader": "^1.0.0",
86106
"ts-loader": "^8.0.0",

src/LinesGLModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { LinesModel } from 'bqplot';
2020
export class LinesGLModel extends LinesModel {
2121
defaults() {
2222
return {
23-
...LinesModel.prototype.defaults(),
23+
...super.defaults(),
2424
_model_name: LinesGLModel.model_name,
2525
_model_module: LinesGLModel.model_module,
2626
_model_module_version: LinesGLModel.model_module_version,

src/ScatterGLModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { MODULE_NAME, MODULE_VERSION } from './version';
2020
export class ScatterGLModel extends ScatterModel {
2121
defaults() {
2222
return {
23-
...ScatterModel.prototype.defaults(),
23+
...super.defaults(),
2424
_model_name: ScatterGLModel.model_name,
2525
_model_module: ScatterGLModel.model_module,
2626
_model_module_version: ScatterGLModel.model_module_version,

src/test/dummy-manager.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
import * as services from '@jupyterlab/services';
5+
import * as Backbone from 'backbone';
6+
import * as widgets from '@jupyter-widgets/controls';
7+
import * as base from '@jupyter-widgets/base';
8+
import * as bqscales from 'bqscales';
9+
import * as bqplot from 'bqplot';
10+
11+
let numComms = 0;
12+
13+
export class MockComm {
14+
constructor() {
15+
this.comm_id = `mock-comm-id-${numComms}`;
16+
numComms += 1;
17+
}
18+
on_open(fn) {
19+
this._on_open = fn;
20+
}
21+
on_close(fn) {
22+
this._on_close = fn;
23+
}
24+
on_msg(fn) {
25+
this._on_msg = fn;
26+
}
27+
_process_msg(msg) {
28+
if (this._on_msg) {
29+
return this._on_msg(msg);
30+
} else {
31+
return Promise.resolve();
32+
}
33+
}
34+
open() {
35+
if (this._on_open) {
36+
this._on_open();
37+
}
38+
return '';
39+
}
40+
close() {
41+
if (this._on_close) {
42+
this._on_close();
43+
}
44+
return '';
45+
}
46+
send() {
47+
return '';
48+
}
49+
comm_id: string;
50+
target_name: string;
51+
_on_msg: Function = null;
52+
_on_open: Function = null;
53+
_on_close: Function = null;
54+
}
55+
56+
export class DummyManager extends base.ManagerBase<HTMLElement> {
57+
constructor(library: any) {
58+
super();
59+
this.el = window.document.createElement('div');
60+
window.document.body.appendChild(this.el);
61+
this.library = library;
62+
}
63+
64+
// @ts-ignore
65+
display_view(
66+
msg: services.KernelMessage.IMessage,
67+
view: Backbone.View<Backbone.Model>,
68+
options: any
69+
) {
70+
return Promise.resolve(view).then((view) => {
71+
this.el.appendChild(view.el);
72+
view.on('remove', () => console.log('view removed', view));
73+
(<any>window).last_view = view;
74+
view.trigger('displayed');
75+
return view.el;
76+
});
77+
}
78+
79+
protected loadClass(
80+
className: string,
81+
moduleName: string,
82+
moduleVersion: string
83+
): Promise<any> {
84+
if (moduleName === '@jupyter-widgets/base') {
85+
if (base[className]) {
86+
return Promise.resolve(base[className]);
87+
} else {
88+
return Promise.reject(`Cannot find class ${className}`);
89+
}
90+
} else if (moduleName === '@jupyter-widgets/controls') {
91+
if (widgets[className]) {
92+
return Promise.resolve(widgets[className]);
93+
} else {
94+
return Promise.reject(`Cannot find class ${className}`);
95+
}
96+
} else if (moduleName === 'bqscales') {
97+
if (bqscales[className]) {
98+
return Promise.resolve(bqscales[className]);
99+
} else {
100+
return Promise.reject(`Cannot find class ${className}`);
101+
}
102+
} else if (moduleName === 'bqplot') {
103+
if (bqplot[className]) {
104+
return Promise.resolve(bqplot[className]);
105+
} else {
106+
return Promise.reject(`Cannot find class ${className}`);
107+
}
108+
} else if (moduleName in this.library) {
109+
return Promise.resolve(this.library[moduleName][className]);
110+
} else {
111+
return Promise.reject(`Cannot find module ${moduleName}`);
112+
}
113+
}
114+
115+
_get_comm_info() {
116+
return Promise.resolve({});
117+
}
118+
119+
_create_comm() {
120+
return Promise.resolve(new MockComm());
121+
}
122+
123+
el: HTMLElement;
124+
library: any;
125+
}

src/test/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import './scatter-gl';
2+
3+
require('@jupyter-widgets/controls/css/widgets.css');
4+
require('bqplot/css/bqplot.css');

0 commit comments

Comments
 (0)