Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a test runner and template Enzyme test. #216

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules/
build
tmp
.DS_Store
*.tgz
my-app*
1 change: 1 addition & 0 deletions bin/react-scripts.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ switch (script) {
case 'build':
case 'start':
case 'eject':
case 'test':
spawn(
'node',
[require.resolve('../scripts/' + script)].concat(args),
Expand Down
12 changes: 9 additions & 3 deletions config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,40 @@ if (isInCreateReactAppSource) {
// create-react-app development: we're in ./config/
module.exports = {
appBuild: resolve('../build'),
appTmp: resolve('../tmp'),
appHtml: resolve('../template/index.html'),
appFavicon: resolve('../template/favicon.ico'),
appPackageJson: resolve('../package.json'),
appSrc: resolve('../template/src'),
appNodeModules: resolve('../node_modules'),
ownNodeModules: resolve('../node_modules')
ownNodeModules: resolve('../node_modules'),
testEntry: resolve('tests.webpack.debug.js')
};
} else if (isInNodeModules) {
// before eject: we're in ./node_modules/react-scripts/config/
module.exports = {
appBuild: resolve('../../../build'),
appTmp: resolve('../../../tmp'),
appHtml: resolve('../../../index.html'),
appFavicon: resolve('../../../favicon.ico'),
appPackageJson: resolve('../../../package.json'),
appSrc: resolve('../../../src'),
appNodeModules: resolve('../..'),
// this is empty with npm3 but node resolution searches higher anyway:
ownNodeModules: resolve('../node_modules')
ownNodeModules: resolve('../node_modules'),
testEntry: resolve('tests.webpack.preeject.js')
};
} else {
// after eject: we're in ./config/
module.exports = {
appBuild: resolve('../build'),
appTmp: resolve('../tmp'),
appHtml: resolve('../index.html'),
appFavicon: resolve('../favicon.ico'),
appPackageJson: resolve('../package.json'),
appSrc: resolve('../src'),
appNodeModules: resolve('../node_modules'),
ownNodeModules: resolve('../node_modules')
ownNodeModules: resolve('../node_modules'),
testEntry: resolve('tests.webpack.js')
};
}
13 changes: 13 additions & 0 deletions config/tests.webpack.debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

const context = require.context('../template/src', true, /\.js$/);
context.keys()
.filter(path => path.match(/__tests__|\/test\/|\.(spec|test)\.js$/))
.forEach(context);
13 changes: 13 additions & 0 deletions config/tests.webpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

const context = require.context('../src', true, /\.js$/);
context.keys()
.filter(path => path.match(/__tests__|\/test\/|\.(spec|test)\.js$/))
.forEach(context);
13 changes: 13 additions & 0 deletions config/tests.webpack.preeject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

const context = require.context('../../../src', true, /\.js$/);
context.keys()
.filter(path => path.match(/__tests__|\/test\/|\.(spec|test)\.js$/))
.forEach(context);
74 changes: 74 additions & 0 deletions config/webpack.config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

var webpack = require('webpack');
var paths = require('./paths');

module.exports = {
devtool: 'eval',
target: 'node',
entry: paths.testEntry,
output: {
path: paths.appTmp,
pathinfo: true,
filename: 'testBundle.js',
},
resolve: {
extensions: ['', '.js'],
},
resolveLoader: {
root: paths.ownNodeModules,
moduleTemplates: ['*-loader']
},
module: {
loaders: [
{
test: /\.js$/,
include: paths.appSrc,
loader: 'babel',
query: require('./babel.dev')
},
{
test: /\.css$/,
include: [paths.appSrc, paths.appNodeModules],
loader: 'null'
},
{
test: /\.json$/,
// include: [paths.appSrc, paths.appNodeModules],
loader: 'json'
},
{
test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)$/,
include: [paths.appSrc, paths.appNodeModules],
loader: 'file',
},
{
test: /\.(mp4|webm)$/,
include: [paths.appSrc, paths.appNodeModules],
loader: 'url?limit=10000'
}
]
},
plugins: [
new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"test"' }),
// cheerio uses an implicit require('./package') that webpack doesn't understand
// https://github.com/cheeriojs/cheerio/issues/836
new webpack.NormalModuleReplacementPlugin(/^\.\/package$/, function(result) {
if(/cheerio/.test(result.context)) {
result.request = "./package.json"
}
})
],
externals: {
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
}
};
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
"babel-preset-es2015": "6.9.0",
"babel-preset-es2016": "6.11.3",
"babel-preset-react": "6.11.1",
"chai": "^3.5.0",
"chalk": "1.1.3",
"cross-spawn": "4.0.0",
"css-loader": "0.23.1",
"enzyme": "^2.4.1",
"eslint": "3.1.1",
"eslint-loader": "1.4.1",
"eslint-plugin-import": "1.10.3",
Expand All @@ -51,8 +53,11 @@
"fs-extra": "^0.30.0",
"html-webpack-plugin": "2.22.0",
"json-loader": "0.5.4",
"mocha": "^2.5.3",
"null-loader": "^0.1.1",
"opn": "4.0.2",
"postcss-loader": "0.9.1",
"react-addons-test-utils": "^15.2.1",
"rimraf": "2.5.3",
"style-loader": "0.13.1",
"url-loader": "0.5.7",
Expand Down
6 changes: 4 additions & 2 deletions scripts/eject.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ var path = require('path');
var rl = require('readline');
var rimrafSync = require('rimraf').sync;
var spawnSync = require('cross-spawn').sync;
var paths = require('../config/paths');

var prompt = function(question, cb) {
var rlInterface = rl.createInterface({
Expand Down Expand Up @@ -47,11 +46,14 @@ prompt('Are you sure you want to eject? This action is permanent. [y/N]', functi
path.join('config', 'flow', 'file.js.flow'),
path.join('config', 'eslint.js'),
path.join('config', 'paths.js'),
path.join('config', 'tests.webpack.js'),
path.join('config', 'webpack.config.dev.js'),
path.join('config', 'webpack.config.prod.js'),
path.join('config', 'webpack.config.test.js'),
path.join('scripts', 'build.js'),
path.join('scripts', 'start.js'),
path.join('scripts', 'openChrome.applescript')
path.join('scripts', 'openChrome.applescript'),
path.join('scripts', 'test.js'),
];

// Ensure that the app folder is clean and we won't override any files
Expand Down
8 changes: 7 additions & 1 deletion scripts/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@ module.exports = function(appPath, appName, verbose, originalDirectory) {
appPackage.dependencies[key] = ownPackage.devDependencies[key];
});

// copy over chai and enzyme so the example test works
appPackage.devDependencies = appPackage.devDependencies || {};
['chai', 'enzyme', 'react-addons-test-utils'].forEach(function (key) {
appPackage.devDependencies[key] = ownPackage.dependencies[key];
});

// Setup the script rules
appPackage.scripts = {};
['start', 'build', 'eject'].forEach(function(command) {
['start', 'build', 'eject', 'test'].forEach(function(command) {
appPackage.scripts[command] = 'react-scripts ' + command;
});

Expand Down
37 changes: 37 additions & 0 deletions scripts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

process.env.NODE_ENV = 'test';

var path = require('path');
var rimrafSync = require('rimraf').sync;
var webpack = require('webpack');
var Mocha = require('mocha');
var mocha = new Mocha();
var paths = require('../config/paths');
var config = require('../config/webpack.config.test');

var tmpPath = paths.appTmp;
rimrafSync(tmpPath);

webpack(config).run(function(err, stats) {
if (err) {
console.error('Failed to create a test build. Reason:');
console.error(err.message || err);
process.exit(1);
}

mocha.addFile(path.join(tmpPath, 'testBundle.js'))

mocha.run(function(failures){
process.on('exit', function () {
process.exit(failures);
});
});
});
3 changes: 3 additions & 0 deletions template/gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ node_modules
# production
build

# test
tmp

# misc
npm-debug.log
21 changes: 21 additions & 0 deletions template/src/__tests__/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

/* global describe, it */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import App from '../App';

describe('<App />', () => {
it('contains a "Welcome to React" header', () => {
const wrapper = shallow(<App />);
expect(wrapper.contains(<h2>Welcome to React</h2>)).to.equal(true);
});
});