add npm script that can run specific js specs

example usage: `npm run jspec spec/javascripts/jsx/files`

refs CNVS-33223

test plan:
- current webpack test build should work exactly the same
- `npm run jspec` should build + run all specs
- `npm run jspec path/to/stuff` should build + run only specified
 specs
- should work with both directories and individual files
- `jspec-watch` should watch + build a path, but not run specs

Change-Id: I788dd38a6c69a4c36a1300fcecf43678bc7f5327
Reviewed-on: https://gerrit.instructure.com/94625
Tested-by: Jenkins
Reviewed-by: Steven Burnett <sburnett@instructure.com>
Product-Review: Felix Milea-Ciobanu <fmileaciobanu@instructure.com>
QA-Review: Felix Milea-Ciobanu <fmileaciobanu@instructure.com>
This commit is contained in:
Felix Milea-Ciobanu 2016-11-07 14:13:53 -07:00
parent 631b339259
commit 03e93802fb
6 changed files with 89 additions and 32 deletions

View File

@ -15,39 +15,37 @@ Before we can get started in earnest, we need to make a few changes to a couple
of files. Inside your `.env` file, add the phantomjs-tests override in your
`COMPOSE_FILE` definition: `docker-compose/js-phantomjs-tests.override.yml`
The next file to be aware of is `webpack_spec_index.js`. This file is how the test bundle
gets created. We can modify it to limit what tests get run. For instance, if you don't
want to run any of the CoffeeScript tests, just comment out that portion of the file.
If you want to scope tests to a certain folder, adjust the path to that folder so that
### JSpec
```
var jsxTestsContext = require.context(__dirname + "/jsx", true, /Spec$/);
The `jspec` npm script allows you to build and run specific JavaScript specs as follows:
requireAll(jsxTestsContext);
```
1) `npm run jspec path/to/specs`
This will build the specified specs using webpack and run them locally using Chrome.
becomes
You can specify a directory or a single spec file to build and run. If no path
is provided, all javascript specs are built and ran.
```
var jsxTestsContext = require.context(__dirname + "/jsx/theFolderIWanted", true, /Spec$/);
2) `npm run jspec-watch path/to/specs`
This will get webpack building the specified specs in watch mode, making it so your
changes are instantly (or close to instantly) reflected in the test bundle.
requireAll(jsxTestsContext);
```
You can specify a directory or a single spec file to watch and build. If no path
is provided, all javascript specs are watched and built.
If you want to scope it to a single file adjust the RegEx as needed so it might look
something like this:
Using `jspec` in this way assumes you will run the specs yourself using PhantomJS
(see below) or by using `npm run test` to run them locally in Chrome.
```
var jsxTestsContext = require.context(__dirname + "/jsx", true, /MyCoolComponentSpec$/);
### PhantomJS
requireAll(jsxTestsContext);
```
To run javascript specs using PhantomJS you can do so as follow:
Now that we have all the files we needed prepared we are going to do two things:
1) `docker-compose run --rm web npm run webpack-test-watch`
1) `npm run jspec-watch path/to/specs`
This will get webpack building the test bundle in watch mode, making it so your
changes are instantly (or close to instantly) reflected in the test bundle.
You can specify a directory or a single spec file to watch and build. If no path
is provided, all javascript specs are watched and built.
2) `docker-compose run --rm phantomjs-tests`
This will start the PhantomJS container in watch mode running the test bundle
anytime the test bundle gets updated.

View File

@ -120,6 +120,8 @@
"webpack-test": "NODE_ENV=test webpack --progress --color --config webpack.test.config.js",
"webpack-test-ember": "NODE_ENV=test WEBPACK_TEST_BUNDLE=ember webpack --progress --color --config webpack.test.config.js",
"webpack-test-watch": "NODE_ENV=test webpack --progress --color --watch --config webpack.test.config.js",
"webpack-production": "NODE_ENV=production webpack --progress --color --config webpack.production.config.js"
"webpack-production": "NODE_ENV=production webpack --progress --color --config webpack.production.config.js",
"jspec": "./spec/jspec.sh",
"jspec-watch": "./spec/jspec.sh --watch"
}
}

View File

@ -1,16 +1,24 @@
const path = require('path')
require('./support/sinon/sinon-1.17.2');
require('./support/sinon/sinon-qunit-amd-1.0.0');
var fixturesDiv = document.createElement('div');
const fixturesDiv = document.createElement('div');
fixturesDiv.id = 'fixtures';
document.body.appendChild(fixturesDiv);
if(!window.ENV) window.ENV = {};
require("react_files/mockFilesENV")
if (!window.ENV) window.ENV = {};
require('react_files/mockFilesENV')
function requireAll(requireContext) {
return requireContext.keys().map(requireContext);
}
requireAll(require.context(__dirname + "/../coffeescripts", true, /Spec$/));
requireAll(require.context(__dirname + "/jsx", true, /Spec$/));
if (__SPEC_FILE) {
require(__SPEC_FILE)
} else if (__SPEC_DIR) {
requireAll(require.context(__SPEC_DIR, true, /Spec$/))
} else {
requireAll(require.context(path.join(__dirname, '../coffeescripts'), true, /Spec$/))
requireAll(require.context(path.join(__dirname, 'jsx'), true, /Spec$/))
}

11
spec/jspec.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
export JSPEC_WD=$(pwd)
if [ "$1" == "--watch" ]; then
export JSPEC_PATH=$2
npm run webpack-test-watch --silent || true
else
export JSPEC_PATH=$1
npm run webpack-test --silent && npm run test --silent || true
fi

38
spec/jspec_env.js Normal file
View File

@ -0,0 +1,38 @@
const fs = require('fs')
const path = require('path')
const config = {
__SPEC_FILE: null,
__SPEC_DIR: null,
}
const printErr = (...args) => {
// wrap err output in red
console.error('\033[31m\n', ...args, '\033[37m')
}
// make sure JSPEC env was set properly
if (process.env.JSPEC_WD && process.env.JSPEC_PATH) {
const specPath = path.join(process.env.JSPEC_WD, process.env.JSPEC_PATH)
try {
const pathInfo = fs.statSync(specPath)
if (pathInfo.isFile()) {
config.__SPEC_FILE = specPath
} else if (pathInfo.isDirectory()) {
config.__SPEC_DIR = specPath
}
} catch (e) {
// most likely ENOENT (file not found)
// print error and exit so we don't continue with the webpack build
printErr('Error reading spec path:', e.code, specPath)
process.exit(1)
}
}
// JSON.stringify config values since webpack plugin does a hard search-replace
module.exports = Object.keys(config).reduce((outputConfig, key) => {
outputConfig[key] = JSON.stringify(config[key])
return outputConfig
}, {})

View File

@ -5,14 +5,15 @@ var CompiledReferencePlugin = require("./frontend_build/CompiledReferencePlugin"
var baseWebpackConfig = require("./frontend_build/baseWebpackConfig");
var testWebpackConfig = baseWebpackConfig;
var jspecEnv = require('./spec/jspec_env');
// the ember specs don't play nice with the rest,
// so we run them in totally seperate bundles
if(process.env.WEBPACK_TEST_BUNDLE == 'ember'){
if (process.env.WEBPACK_TEST_BUNDLE == 'ember') {
testWebpackConfig.entry = {
'WebpackedEmberSpecs': "./spec/javascripts/webpack_ember_spec_index.js"
}
}else {
} else {
testWebpackConfig.entry = {
'WebpackedSpecs': "./spec/javascripts/webpack_spec_index.js"
}
@ -23,10 +24,9 @@ testWebpackConfig.output.path = __dirname + '/spec/javascripts/webpack';
testWebpackConfig.output.pathinfo = true;
testWebpackConfig.output.filename = "[name].bundle.test.js";
testWebpackConfig.plugins = [
// expose a 'qunit' global variable to any file that uses it
new webpack.ProvidePlugin({qunit: 'qunitjs'}),
new webpack.DefinePlugin(jspecEnv),
new I18nPlugin(),
new ClientAppsPlugin(),
new CompiledReferencePlugin(),