Skip to content
代码片段 群组 项目
未验证 提交 b2356dca 编辑于 作者: Paul Slaughter's avatar Paul Slaughter
浏览文件

Setup fake web worker for jest

- This does a fake implementation of some
  trivial web worker API. This way we can
  have integration specs without overly stubbing
  these out.
上级 41303181
No related branches found
No related tags found
无相关合并请求
...@@ -86,6 +86,8 @@ module.exports = (path, options = {}) => { ...@@ -86,6 +86,8 @@ module.exports = (path, options = {}) => {
collectCoverageFrom, collectCoverageFrom,
coverageDirectory: coverageDirectory(), coverageDirectory: coverageDirectory(),
coverageReporters: ['json', 'lcov', 'text-summary', 'clover'], coverageReporters: ['json', 'lcov', 'text-summary', 'clover'],
// We need ignore _worker code coverage since we are manually transforming it
coveragePathIgnorePatterns: ['<rootDir>/node_modules/', '_worker\\.js$'],
cacheDirectory: '<rootDir>/tmp/cache/jest', cacheDirectory: '<rootDir>/tmp/cache/jest',
modulePathIgnorePatterns: ['<rootDir>/.yarn-cache/'], modulePathIgnorePatterns: ['<rootDir>/.yarn-cache/'],
reporters, reporters,
...@@ -93,6 +95,7 @@ module.exports = (path, options = {}) => { ...@@ -93,6 +95,7 @@ module.exports = (path, options = {}) => {
restoreMocks: true, restoreMocks: true,
transform: { transform: {
'^.+\\.(gql|graphql)$': 'jest-transform-graphql', '^.+\\.(gql|graphql)$': 'jest-transform-graphql',
'^.+_worker\\.js$': './spec/frontend/__helpers__/web_worker_transformer.js',
'^.+\\.js$': 'babel-jest', '^.+\\.js$': 'babel-jest',
'^.+\\.vue$': 'vue-jest', '^.+\\.vue$': 'vue-jest',
'^.+\\.(md|zip|png)$': 'jest-raw-loader', '^.+\\.(md|zip|png)$': 'jest-raw-loader',
......
import path from 'path';
const isRelative = (pathArg) => pathArg.startsWith('.');
const transformRequirePath = (base, pathArg) => {
if (!isRelative(pathArg)) {
return pathArg;
}
return path.resolve(base, pathArg);
};
const createRelativeRequire = (filename) => {
const rel = path.relative(__dirname, path.dirname(filename));
const base = path.resolve(__dirname, rel);
// reason: Dynamic require should be fine here since the code is dynamically evaluated anyways.
// eslint-disable-next-line import/no-dynamic-require, global-require
return (pathArg) => require(transformRequirePath(base, pathArg));
};
/**
* Simulates a WebWorker module similar to the kind created by Webpack's [`worker-loader`][1]
*
* [1]: https://webpack.js.org/loaders/worker-loader/
*/
export class FakeWebWorker {
/**
* Constructs a new FakeWebWorker instance
*
* @param {String} filename is the full path of the code, which is used to resolve relative imports.
* @param {String} code is the raw code of the web worker, which is dynamically evaluated on construction.
*/
constructor(filename, code) {
let isAlive = true;
const clientTarget = new EventTarget();
const workerTarget = new EventTarget();
this.addEventListener = (...args) => clientTarget.addEventListener(...args);
this.removeEventListener = (...args) => clientTarget.removeEventListener(...args);
this.postMessage = (message) => {
if (!isAlive) {
return;
}
workerTarget.dispatchEvent(new MessageEvent('message', { data: message }));
};
this.terminate = () => {
isAlive = false;
};
const workerScope = {
addEventListener: (...args) => workerTarget.addEventListener(...args),
removeEventListener: (...args) => workerTarget.removeEventListener(...args),
postMessage: (message) => {
if (!isAlive) {
return;
}
clientTarget.dispatchEvent(new MessageEvent('message', { data: message }));
},
};
// reason: `no-new-func` is like `eval` except it only executed on global scope and it's easy
// to pass in local references. `eval` is very unsafe in production, but in our test environment
// we shold be fine.
// eslint-disable-next-line no-new-func
Function('self', 'require', code)(workerScope, createRelativeRequire(filename));
}
}
/* eslint-disable class-methods-use-this */
export default class WebWorkerMock {
addEventListener() {}
removeEventListener() {}
terminate() {}
postMessage() {}
}
/* eslint-disable import/no-commonjs */
const babelJestTransformer = require('babel-jest');
// This Jest will transform the code of a WebWorker module into a FakeWebWorker subclass.
// This is meant to mirror Webpack's [`worker-loader`][1].
// [1]: https://webpack.js.org/loaders/worker-loader/
module.exports = {
process: (contentArg, filename, ...args) => {
const { code: content } = babelJestTransformer.process(contentArg, filename, ...args);
return `const { FakeWebWorker } = require("helpers/web_worker_fake");
module.exports = class JestTransformedWorker extends FakeWebWorker {
constructor() {
super(${JSON.stringify(filename)}, ${JSON.stringify(content)});
}
};`;
},
};
...@@ -258,6 +258,8 @@ describe('DiffsStoreActions', () => { ...@@ -258,6 +258,8 @@ describe('DiffsStoreActions', () => {
{ type: types.SET_LOADING, payload: false }, { type: types.SET_LOADING, payload: false },
{ type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs }, { type: types.SET_MERGE_REQUEST_DIFFS, payload: diffMetadata.merge_request_diffs },
{ type: types.SET_DIFF_METADATA, payload: noFilesData }, { type: types.SET_DIFF_METADATA, payload: noFilesData },
// Workers are synchronous in Jest environment (see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58805)
{ type: types.SET_TREE_DATA, payload: utils.generateTreeList(diffMetadata.diff_files) },
], ],
[], [],
() => { () => {
......
export { default } from 'helpers/web_worker_mock';
export { default } from 'helpers/web_worker_mock';
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册