Skip to content
This repository has been archived by the owner on May 17, 2019. It is now read-only.

Add jest as a test runner #67

Merged
merged 2 commits into from
Dec 12, 2017
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -33,3 +33,6 @@ yarn add fusion-cli
- `--cover`: Run tests with coverage
- `--watch`: Use existing built assets
- `--skip-build`: Automatically re-profile your application on changes
- `fusion test-app [--watch] [--match]`: Run tests
- `--watch`: Automatically run tests when code changes.
- `--match="somestring"`: Only runs tests against files which match this string.
14 changes: 14 additions & 0 deletions build/jest-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-env node */

module.exports = {
cache: true,
rootDir: process.cwd(),
setupFiles: [
'<rootDir>/node_modules/fusion-cli/build/jest-framework-shims.js',
'<rootDir>/node_modules/fusion-cli/build/jest-framework-setup.js',
],
transform: {
'^.+\\.js$': '<rootDir>/node_modules/fusion-cli/build/jest-transformer.js',
},
transformIgnorePatterns: ['/node_modules/(?!(fusion-cli.*build))'],
};
10 changes: 10 additions & 0 deletions build/jest-framework-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-env node */
import {configure} from 'enzyme';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if people don't use enzyme in their tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's necessary, but I think we should probably enable by default? We can add a config to turn this off though.

import Adapter from 'enzyme-adapter-react-16';

// Setup Enzyme for all Jest tests
configure({adapter: new Adapter()});

const testEnv = process.env.ENV || 'browser';
global.__NODE__ = testEnv === 'node';
global.__BROWSER__ = testEnv === 'browser';
4 changes: 4 additions & 0 deletions build/jest-framework-shims.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* eslint-env node */
global.requestAnimationFrame = callback => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required for running react tests in node - they ask you to bring your own polyfills.

setTimeout(callback, 0);
};
23 changes: 23 additions & 0 deletions build/jest-transformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* eslint-env node */

const transformer = require('babel-jest').createTransformer({
presets: [
'babel-preset-flow',
'babel-preset-es2015',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the es2015 preset required given that we require Node 8+?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try getting rid of it. 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out this is required for modules to work. Might be able to do this with a smaller plugin, but since it's only for tests, I don't think it's too bad.

'babel-preset-react',
].map(require.resolve),
});

const originalProcessFn = transformer.process;

transformer.process = function(src, filename, config, transformOptions) {
return originalProcessFn.call(
transformer,
src,
filename,
config,
transformOptions
);
};

module.exports = transformer;
54 changes: 54 additions & 0 deletions build/test-app-runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* eslint-env node */
const path = require('path');
const {spawn} = require('child_process');

module.exports.TestAppRuntime = function({dir = '.', watch = false, match}) {
const state = {proc: null};

this.run = () => {
this.stop();

let command = require.resolve('jest-cli/bin/jest.js');
let args = [
// '--no-cache',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this should be deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, though it's really useful for debugging.

'--config',
'./node_modules/fusion-cli/build/jest-config.js',
];

if (watch) {
args.push('--watch');
}

if (match && match.length > 0) {
args.push(match);
}

return new Promise((resolve, reject) => {
state.proc = spawn(command, args, {
cwd: path.resolve(process.cwd(), dir),
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
env: Object.assign({}, process.env),
});

state.proc.on('error', reject);
state.proc.on('exit', (code, signal) => {
if (code) {
return reject(new Error(`Test exited with code ${code}`));
}

if (signal) {
return reject(new Error(`Test process exited with signal ${signal}`));
}

return resolve();
});
});
};

this.stop = () => {
if (state.proc) {
state.proc.kill();
state.proc = null;
}
};
};
33 changes: 33 additions & 0 deletions commands/test-app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-env node */
const {TestAppRuntime} = require('../build/test-app-runtime');

exports.desc = 'Run browser tests, using Jest';
exports.builder = {
dir: {
type: 'string',
default: '.',
describe: 'Root path for the application relative to CLI CWD',
},
watch: {
type: 'boolean',
default: false,
describe: 'Automatically re-run tests on file changes',
},
match: {
type: 'string',
default: null,
describe: 'Runs test files that match a given string',
},
};

exports.run = async function({dir = '.', watch, match}) {
const testRuntime = new TestAppRuntime({dir, watch, match});

await testRuntime.run();

return {
stop() {
testRuntime.stop();
},
};
};
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -12,25 +12,30 @@
},
"dependencies": {
"@nadiia/file-loader": "^1.0.0-beta.5",
"babel-core": "^6.22.1",
"babel-core": "^6.26.0",
"babel-jest": "^21.2.0",
"babel-loader": "^7.1.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-istanbul": "^4.0.0",
"babel-plugin-istanbul": "^4.1.5",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-async-generator-functions": "^6.22.0",
"babel-plugin-transform-class-properties": "^6.23.0",
"babel-plugin-transform-cup-globals": "^1.0.0-rc.2",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-react-jsx": "^6.23.0",
"babel-preset-env": "^1.1.8",
"babel-preset-es2015": "^6.24.1",
"babel-preset-flow": "^6.23.0",
"babel-preset-jest": "^21.2.0",
"babel-preset-react": "^6.23.0",
"browser-unhandled-rejection": "^1.0.1",
"case-sensitive-paths-webpack-plugin": "^1.1.4",
"chalk": "^1.1.3",
"compose-middleware": "3.0.0",
"compression-webpack-plugin": "^0.4.0",
"core-js": "^2.5.1",
"enzyme": "^3.2.0",
"enzyme-adapter-react-16": "^1.1.0",
"es6-object-assign": "^1.1.0",
"express": "^4.15.2",
"fast-async": "^6.3.0",
@@ -39,6 +44,8 @@
"iltorb": "^1.3.1",
"imagemin": "^5.3.1",
"imagemin-svgo": "^5.2.2",
"jest": "^21.2.1",
"jest-cli": "^21.2.1",
"just-snake-case": "^1.0.0",
"koa": "^2.3.0",
"koa-mount": "^3.0.0",
972 changes: 925 additions & 47 deletions yarn.lock

Large diffs are not rendered by default.