Last active
May 26, 2017 00:48
-
-
Save tomazzaman/1e2c71e1afb6a45c1001 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fs from 'fs'; | |
import path, { resolve } from 'path'; | |
import assert from 'assert'; | |
import Module from 'module'; | |
import jsdom from 'jsdom'; | |
import Mocha from 'mocha'; | |
import chokidar from 'chokidar'; | |
// Let's import and globalize testing tools so | |
// there's no need to require them in each test | |
import sinon from 'sinon'; | |
import chai, { expect } from 'chai'; | |
import chaiAsPromised from 'chai-as-promised'; | |
chai.use( chaiAsPromised ); | |
// Environment setup (used by Babel as well, see .babelrc) | |
process.env['NODE_ENV'] = 'test'; | |
/** | |
* Monkey-patching the Function prototype so we can have require.ensure working. | |
* Easier achieved than hacking the Module for targeting the "require" specifically. | |
*/ | |
Function.prototype.ensure = ( arr, func ) => func(); | |
/** | |
* Monkey-patching native require, because Webpack supports requiring files, other | |
* than JavaScript. But Node doesn't recognize them, so they should be ignored. | |
* IMPORTANT: don't use arrow functions because they change the scope of 'this'! | |
*/ | |
Module.prototype.require = function( path ) { | |
const types = /\.(s?css|sass|less|svg|html|png|jpe?g|gif)$/; | |
if ( path.search( types ) !== -1 ) return; | |
// Mimics Webpack's "alias" feature | |
if ( path === 'config' ) { | |
path = resolve( './src/js/secrets/test.js' ); | |
} | |
assert( typeof path === 'string', 'path must be a string' ); | |
assert( path, 'missing path' ); | |
return Module._load( path, this ); | |
}; | |
// setup the simplest document possible | |
let doc = jsdom.jsdom( '<!doctype html><html><body></body></html>' ); | |
let win = doc.defaultView; | |
// set globals for mocha that make access to document and window feel | |
// natural in the test environment | |
global.document = doc; | |
global.window = win; | |
global.self = global; | |
global.chai = chai; | |
global.expect = expect; | |
global.sinon = sinon; | |
/** | |
* Take all the properties of the window object and attach them to the mocha | |
* global object. This is to prevent 'undefined' errors which sometime occur. | |
* Gotten from: http://jaketrent.com/post/testing-react-with-jsdom/ | |
* @param {object} window: The fake window, build by jsdom | |
*/ | |
( ( window ) => { | |
for ( let key in window ) { | |
if ( ! window.hasOwnProperty( key ) ) continue; | |
if ( key in global ) continue; | |
global[ key ] = window[ key ]; | |
} | |
} )( win ); | |
/** | |
* A helper function to run Mocha tests. Since Mocha doesn't support changing | |
* tested files dynamically (except for adding), we need to clear require's | |
* cache on every run and instantiate a new runner. | |
*/ | |
let fileList = []; | |
function runSuite() { | |
Object.keys( require.cache ).forEach( key => delete require.cache[ key ] ); | |
const mocha = new Mocha( { reporter: 'dot' } ); | |
fileList.forEach( filepath => mocha.addFile( filepath ) ); | |
mocha.run(); | |
} | |
/** | |
* Chokidar watches all the files for any kind of change and calls the run function | |
* from above. Read more: https://github.com/paulmillr/chokidar | |
* @param {string} a glob of files to watch | |
* @param {object} settings | |
*/ | |
chokidar.watch( 'test/**/*.spec.js', { persistent: true } ) | |
.on( 'add', path => fileList.push( path ) ) | |
.on( 'change', path => runSuite() ) | |
.on( 'ready', () => runSuite() ); | |
chokidar.watch( 'src/**/*.js', { persistent: true } ) | |
.on( 'change', path => runSuite() ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment