Skip to content

Commit

Permalink
parent 9eacadc
Browse files Browse the repository at this point in the history
author Jakub Lála <68380659+jakublala@users.noreply.github.com> 1626864006 +0200
committer Jakub Lála <jakublala@gmail.com> 1626892362 +0200

parent 9eacadc
author Jakub Lála <68380659+jakublala@users.noreply.github.com> 1626864006 +0200
committer Jakub Lála <jakublala@gmail.com> 1626892347 +0200

parent 9eacadc
author Jakub Lála <68380659+jakublala@users.noreply.github.com> 1626864006 +0200
committer Jakub Lála <jakublala@gmail.com> 1626892324 +0200

Use Karma to run unit tests (lab-cosmo#173)

Previously tests would run on node, and we would mimic a browser environment with JSDom, but the limitations of this approach were too big.

Karma allows to run the tests in real browsers, which is where chemiscope runs in practice

Temp Commit

Changed .gitIgnore

temp commit

temp commit

Added Karma

Viewer test added

Remove coverage files

Moved files / Changed chrome launcher

setup-chrome driver attempt

Revert previosu commit

Update .github/workflows/tests.yml

Co-authored-by: Guillaume Fraux <luthaf@luthaf.fr>

Enacted on suggestions

Day 1 commit

temp commit

Added a few unit tests for Map Options

One more
  • Loading branch information
jakublala committed Jul 21, 2021
1 parent 9eacadc commit f490624
Show file tree
Hide file tree
Showing 10 changed files with 2,489 additions and 3,810 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ jobs:
node-version: ${{ matrix.node-version }}
- uses: bahmutov/npm-install@v1
- run: npm run build
- run: npm test
- run: sudo apt-get install xvfb
# use xvfb to run the tests with a pseudo-display attached
# so that the browsers started by karma think there is a screen
- run: xvfb-run --auto-servernum npm test

# Python unit tests
python-test:
Expand Down
5,831 changes: 2,121 additions & 3,710 deletions package-lock.json

Large diffs are not rendered by default.

57 changes: 32 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"url": "git+https://github.com/cosmo-epfl/chemiscope.git"
},
"scripts": {
"test": "npm run test:mocha && npm run test:lint",
"test:mocha": "mochapack --webpack-config=tests/webpack.config.ts --recursive --glob '*.test.ts' tests",
"test": "npm run test:karma && npm run test:lint",
"test:karma": "karma start",
"test:lint": "eslint src && prettier --check src",
"build": "rimraf dist && webpack --mode production && npm run merge-dts",
"download-examples": "ts-node ./utils/download-examples.ts",
Expand All @@ -31,36 +31,40 @@
"pretty": "prettier --write src"
},
"devDependencies": {
"@types/chai": "^4.2.12",
"@types/glob": "^7.1.3",
"@types/jquery": "^3.5.5",
"@types/markdown-it": "^12",
"@types/mocha": "^8.0.3",
"@types/node": "^15",
"@types/pako": "^1.0.1",
"@types/plotly.js": "^1.50.15",
"@types/tmp": "^0.2.0",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"@typescript-eslint/parser": "^4.5.0",
"@types/chai": "^4.2.21",
"@types/glob": "^7.1.4",
"@types/jquery": "^3.5.6",
"@types/markdown-it": "^12.0.3",
"@types/mocha": "^8.2.3",
"@types/node": "^16.3.0",
"@types/pako": "^1.0.2",
"@types/plotly.js": "^1.54.11",
"@types/tmp": "^0.2.1",
"@typescript-eslint/eslint-plugin": "^4.28.2",
"@typescript-eslint/parser": "^4.28.2",
"3dmol": "^1.6.4",
"assert": "^2.0.0",
"bootstrap": "^4.6.0",
"bubleify": "^2.0.0",
"buffer": "^6.0.2",
"canvas": "^2.6.1",
"chai": "^4.2.0",
"css-loader": "^5.0.0",
"css-loader": "^5.2.6",
"dts-bundle-generator": "^5.1.0",
"eslint": "^7.5.0",
"eslint": "^7.30.0",
"eslint-config-prettier": "^8.3",
"eslint-plugin-prettier": "^3.1.4",
"html-loader": "^2.1",
"ify-loader": "^1.1.0",
"jquery": "^3.6.0",
"jsdom": "^16.4.0",
"markdown-it": "^12.0.2",
"mocha": "^8.1.2",
"mochapack": "^2.1.2",
"karma": "^6.3.4",
"karma-chrome-launcher": "^3.1.0",
"karma-detect-browsers": "^2.3.3",
"karma-firefox-launcher": "^2.1.1",
"karma-mocha": "^2.0.1",
"karma-safarinative-launcher": "^1.1.0",
"karma-webpack": "https://github.com/ryanclark/karma-webpack/archive/ef7edb6b6756fb563871eaff88ca876892694896.tar.gz",
"markdown-it": "^12.1.0",
"mocha": "^9.0.0",
"node-loader": "^2.0",
"plotly.js": "1.58.4",
"popper.js": "^1.16.1",
Expand All @@ -69,13 +73,16 @@
"rimraf": "^3.0.2",
"style-loader": "^2.0.0",
"tmp": "^0.2.1",
"ts-loader": "^9.1",
"ts-node": "^9.0.0",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"typedoc": "^0.19",
"typedoc-plugin-external-module-name": "^4",
"typescript": "^4.0.3",
"webpack": "^5.37.0",
"webpack-cli": "^4.7.0",
"typescript": "^4.3.5",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "4.0.0-beta.3"
},
"dependencies": {
"@types/karma": "^6.3.1"
}
}
30 changes: 0 additions & 30 deletions tests/jsdom.ts

This file was deleted.

93 changes: 93 additions & 0 deletions tests/karma.conf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { Config, ConfigOptions } from 'karma';
import webpack from 'webpack';

import { WEBPACK_CONFIG } from './webpack.config';

/**
* Small webpack plugin to remove typescript declaration files (.d.ts) from the
* list of assets.
*
* karma-webpack is using this list to know which file to load for tests, which
* contains both the path to test files compiled to javascript, and the path to
* typescript declaration files. Webpack output path is set to a temporary
* directory, and the javascript files are inside this directory. The typescript
* declaration files are not in this temporary directory (they are emitted in
* `chemiscope/dist/` by tsc), and for a still unknown reason that can cause
* karma not to found these file in some very specific cases (macOS and/or ZSH
* seems to be required to hit this issue).
*
* Since we do not care about the `.d.ts` files in karma, this plugin works
* around the issue by removing said files from the assets list. This can break
* if webpack plugin API changes, or if karma-webpack stops using the assets.
*/
class RemoveDeclarationsFromAssets implements webpack.WebpackPluginInstance {
apply(compiler: webpack.Compiler) {
compiler.hooks.done.tap('RemoveDeclarationsFromAssets', (stats) => {
const toRemove = [];
for (const path in stats.compilation.assets) {
if (path.endsWith('.d.ts')) {
toRemove.push(path);
}
}

for (const key of toRemove) {
delete stats.compilation.assets[key];
}
});
}
}

WEBPACK_CONFIG.plugins?.push(new RemoveDeclarationsFromAssets());

module.exports = (config: Config) => {
config.set({
browserNoActivityTimeout: 8000,
client: {
mocha: {
timeout: 8000,
},
},

files: [
// FIXME: we should not have to manually load jquery, but we
// currently don't include it in the main bundle
'node_modules/jquery/dist/jquery.min.js',
'tests/**/*.test.ts',
],
frameworks: ['webpack', 'mocha', 'detectBrowsers'],

preprocessors: {
'tests/**/*.test.ts': 'webpack',
},
reporters: ['progress'],
singleRun: true,

webpack: WEBPACK_CONFIG,
webpackMiddleware: {
stats: 'errors-only',
},

detectBrowsers: {
postDetection: function (availableBrowsers: string[]) {
// Remove IE
const IEindex = availableBrowsers.indexOf('IE');
if (IEindex !== -1) {
availableBrowsers.splice(IEindex);
}

// Rename Safari to use SafariNative karma launcher
const SafariIndex = availableBrowsers.indexOf('Safari');
if (SafariIndex !== -1) {
availableBrowsers[SafariIndex] = 'SafariNative';
}

return availableBrowsers;
},
// we can not enable headless mode since firefox does not support
// WebGL in this case (https://bugzilla.mozilla.org/show_bug.cgi?id=1375585)
preferHeadless: false,
usePhantomJS: false,
},
} as ConfigOptions);
};
127 changes: 127 additions & 0 deletions tests/map/map.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { PropertiesMap } from '../../src/map';
import { EnvironmentIndexer } from '../../src/indexer';
import { Target } from '../../src/dataset';
import { getByID } from '../../src/utils';
import { AxisOptions } from '../../src/map/options';

import { assert } from 'chai';

let KARMA_INSERTED_HTML: string;

const DUMMY_PROPERTIES = {
first: {
target: 'structure' as Target,
values: [1.1, 1.2],
},
second: {
target: 'structure' as Target,
values: [2.1, 2.2],
},
third: {
target: 'structure' as Target,
values: [3.1, 3.2],
},
};

const DUMMY_MAP_SETTINGS = {
x: {
max: 0,
min: 10,
property: 'first',
scale: 'linear',
},
y: {
max: 0,
min: 10,
property: 'first',
scale: 'linear',
},
z: {
max: 0,
min: 10,
property: 'first',
scale: 'linear',
},
color: {
max: 0,
min: 10,
property: 'second',
scale: 'linear',
},
symbol: '',
palette: 'hsv (periodic)',
size: {
factor: 50,
property: '',
},
};

const DUMMY_STRUCTURES = [
{
size: 2,
names: ['X', 'Y'],
x: [0, 1],
y: [0, 1],
z: [0, 1],
},
];

describe('Map', () => {
before(() => {
// store karma's default HTML
KARMA_INSERTED_HTML = document.body.innerHTML;
});

it('can remove itself from DOM', () => {
const root = document.createElement('div');
const indexer = new EnvironmentIndexer('structure', DUMMY_STRUCTURES);
const map = new PropertiesMap(
{ element: root, settings: DUMMY_MAP_SETTINGS },
indexer,
DUMMY_PROPERTIES
);

assert(root.innerHTML !== '');
assert(document.body.innerHTML !== '');

map.remove();
assert(root.innerHTML === '');

// remove SVG element created by Plotly
document.getElementById('js-plotly-tester')?.remove();
assert(document.body.innerHTML === KARMA_INSERTED_HTML);
});

// it('color range resets when clicked', () => {
// const root = document.createElement('div');
// const indexer = new EnvironmentIndexer('structure', DUMMY_STRUCTURES);
// const map = new PropertiesMap(
// { element: root, settings: DUMMY_MAP_SETTINGS },
// indexer,
// DUMMY_PROPERTIES
// );
// const minSelectElement = getByID<HTMLSelectElement>(`chsp-color-min`);
// const maxSelectElement = getByID<HTMLSelectElement>(`chsp-color-max`);
// const originalMin = minSelectElement.value;
// const originalMax = maxSelectElement.value;

// const colorSelectElement = getByID<HTMLSelectElement>(`chsp-color`);
// colorSelectElement.value = 'third';
// colorSelectElement.dispatchEvent(new window.Event('change'));

// console.log(originalMin);

// minSelectElement.value = '-0.01';
// maxSelectElement.value = '0.01';

// map['_colorReset'].onclick();
// assert(minSelectElement.value === originalMin);
// assert(maxSelectElement.value === originalMax);
// });
});

/** Removes the map and an additional HTML element creted by Plotly */
function removeMap(map: PropertiesMap): void {
map.remove();
document.getElementById('js-plotly-tester')?.remove();
}
Loading

0 comments on commit f490624

Please sign in to comment.