Skip to content
This repository has been archived by the owner on Jul 9, 2018. It is now read-only.

Commit

Permalink
Scripts: Provide the default configuration for the test command (#83)
Browse files Browse the repository at this point in the history
* Scripts: Provide the default configuration for the `test` command
It is used in the case when the project does not have a config for Jest or Babel

* Scripts: Add tests for utils to ensure they work properly

* Add back end-of-file new line
  • Loading branch information
gziolo authored and ntwb committed Feb 21, 2018
1 parent 445072e commit 6b94f93
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 61 deletions.
7 changes: 7 additions & 0 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"lerna": "2.9.0",
"commands": {
"publish": {
"ignore": [
"**/test/*.js"
]
}
},
"packages": [
"packages/*"
],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"create-symlinks": "node ./scripts/create-symlinks.js",
"lerna-bootstrap": "lerna bootstrap --hoist",
"postinstall": "npm-run-all lerna-bootstrap create-symlinks build",
"test": "wp-scripts test",
"test": "wp-scripts test-unit",
"test:coverage": "npm run test -- --coverage",
"test:coverage-ci": "npm run test -- --coverage && codecov",
"test:watch": "npm run test -- --watch",
Expand Down
12 changes: 7 additions & 5 deletions packages/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ This is a CLI and exposes a binary called `wp-scripts` so you can call it direct
```json
{
"scripts": {
"test": "wp-scripts",
"test:help": "wp-scripts --help",
"test:watch": "wp-scripts --watch"
"test": "wp-scripts test-unit",
"test:help": "wp-scripts test-unit --help",
"test:watch": "wp-scripts test-unit --watch"
}
}
```
Expand All @@ -30,9 +30,11 @@ This is how you execute those scripts using the presented setup:

## Available Scripts

### `wp-scripts test`
### `wp-scripts test-unit`

Launches the test runner. It uses [Jest](https://facebook.github.io/jest/) behind the scenes and you are able to utilize all of its [CLI options](https://facebook.github.io/jest/docs/en/cli.html). You can also run `./node_modules/.bin/wp-scripts --help` or `npm run test:help` (if you use `package.json` setup shared above) to view all of the available options.
_Alias_: `wp-scripts test-unit-jest`

Launches the test runner. It uses [Jest](https://facebook.github.io/jest/) behind the scenes and you are able to utilize all of its [CLI options](https://facebook.github.io/jest/docs/en/cli.html). You can also run `./node_modules/.bin/wp-scripts test-unit --help` or `npm run test:help` (if you use `package.json` setup shared above) to view all of the available options.

## Inspiration

Expand Down
40 changes: 6 additions & 34 deletions packages/scripts/bin/wp-scripts.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,10 @@
#!/usr/bin/env node

const spawn = require( 'cross-spawn' );
/**
* Internal dependencies
*/
const { getCliArgs, spawnScript } = require( '../utils' );

const allowedScripts = [ 'test' ];
const [ scriptName, ...nodeArgs ] = process.argv.slice( 2 );
const [ scriptName, ...nodesArgs ] = getCliArgs();

if ( allowedScripts.indexOf( scriptName ) === -1 ) {
console.log( 'Unknown script "' + scriptName + '".' );
console.log( 'Perhaps you need to update @wordpress/scripts?' );
process.exit( 1 );
}

const result = spawn.sync(
'node',
[
require.resolve( `../scripts/${ scriptName }-script` ),
...nodeArgs
],
{ stdio: 'inherit' }
);
if ( result.signal ) {
if ( result.signal === 'SIGKILL' ) {
console.log(
'The build failed because the process exited too early. ' +
'This probably means the system ran out of memory or someone called ' +
'`kill -9` on the process.'
);
} else if ( result.signal === 'SIGTERM' ) {
console.log(
'The build failed because the process exited too early. ' +
'Someone might have called `kill` or `killall`, or the system could ' +
'be shutting down.'
);
}
process.exit( 1 );
}
process.exit( result.status );
spawnScript( scriptName, nodesArgs );
8 changes: 8 additions & 0 deletions packages/scripts/config/babel-transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* External dependencies
*/
const babelJest = require( 'babel-jest' );

module.exports = babelJest.createTransformer( {
presets: [ '@wordpress/default' ],
} );
27 changes: 27 additions & 0 deletions packages/scripts/config/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* External dependencies
*/
const path = require( 'path' );

/**
* Internal dependencies
*/
const {
hasProjectFile,
hasPackageProp,
} = require( '../utils' );

const jestConfig = {
preset: '@wordpress/jest-preset-default'
};

const hasBabelConfig = hasProjectFile( '.babelrc' ) ||
hasPackageProp( 'babel' );

if ( ! hasBabelConfig ) {
jestConfig.transform = {
'^.+\\.js$': path.join( __dirname, 'babel-transform' ),
};
}

module.exports = jestConfig;
9 changes: 7 additions & 2 deletions packages/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@
},
"files": [
"bin",
"scripts"
"config",
"scripts",
"utils"
],
"bin": {
"wp-scripts": "./bin/wp-scripts.js"
},
"dependencies": {
"@wordpress/babel-preset-default": "^1.0.2",
"@wordpress/jest-preset-default": "^1.0.0",
"cross-spawn": "^5.1.0",
"jest": "^22.0.4"
"jest": "^22.0.4",
"read-pkg-up": "^3.0.0"
},
"publishConfig": {
"access": "public"
Expand Down
19 changes: 0 additions & 19 deletions packages/scripts/scripts/test-script.js

This file was deleted.

39 changes: 39 additions & 0 deletions packages/scripts/scripts/test-unit-jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on( 'unhandledRejection', err => {
throw err;
} );

/**
* External dependencies
*/
const jest = require( 'jest' );

/**
* Internal dependencies
*/
const {
getCliArgs,
hasCliArg,
hasProjectFile,
hasPackageProp,
} = require( '../utils' );

const args = getCliArgs();

const hasJestConfig = hasCliArg( '-c' ) ||
hasCliArg( '--config' ) ||
hasProjectFile( 'jest.config.js' ) ||
hasProjectFile( 'jest.config.json' ) ||
hasPackageProp( 'jest' );

const config = ! hasJestConfig
? [ '--config', JSON.stringify( require( '../config/jest.config' ) ) ]
: [];

jest.run( [ ...config, ...args ] );
1 change: 1 addition & 0 deletions packages/scripts/scripts/test-unit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require( './test-unit-jest' );
82 changes: 82 additions & 0 deletions packages/scripts/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* External dependencies
*/
const spawn = require( 'cross-spawn' );
const { existsSync } = require( 'fs' );
const path = require( 'path' );

/**
* Internal dependencies
*/
const { getPackagePath, hasPackageProp } = require( './package' );
const { exit, getCliArgs } = require( './process' );

const first = list => list[ 0 ];

const hasCliArg = ( arg ) => getCliArgs()
.some( ( value ) => first( value.split( '=' ) ) === arg );

const fromProjectRoot = ( fileName ) =>
path.join( path.dirname( getPackagePath() ), fileName );

const hasProjectFile = ( fileName ) =>
existsSync( fromProjectRoot( fileName ) );

const fromScriptsRoot = ( scriptName ) =>
path.join( path.dirname( __dirname ), 'scripts', `${ scriptName }.js` );

const hasScriptFile = ( scriptName ) =>
existsSync( fromScriptsRoot( scriptName ) );

const handleSignal = ( signal ) => {
if ( signal === 'SIGKILL' ) {
console.log(
'The script failed because the process exited too early. ' +
'This probably means the system ran out of memory or someone called ' +
'`kill -9` on the process.'
);
} else if ( signal === 'SIGTERM' ) {
console.log(
'The script failed because the process exited too early. ' +
'Someone might have called `kill` or `killall`, or the system could ' +
'be shutting down.'
);
}
exit( 1 );
};

const spawnScript = ( scriptName, args = [] ) => {
if ( ! scriptName ) {
console.log( 'Script name is missing.' );
exit( 1 );
}

if ( ! hasScriptFile( scriptName ) ) {
console.log( 'Unknown script "' + scriptName + '".' );
console.log( 'Perhaps you need to update @wordpress/scripts?' );
exit( 1 );
}

const { signal, status } = spawn.sync(
'node',
[
fromScriptsRoot( scriptName ),
...args
],
{ stdio: 'inherit' },
);

if ( signal ) {
handleSignal( signal );
}

exit( status );
};

module.exports = {
getCliArgs,
hasCliArg,
hasProjectFile,
hasPackageProp,
spawnScript,
};
23 changes: 23 additions & 0 deletions packages/scripts/utils/package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* External dependencies
*/
const { realpathSync } = require( 'fs' );
const readPkgUp = require( 'read-pkg-up' );

/**
* Internal dependencies
*/
const { getCurrentWorkingDirectory } = require( './process' );

const { pkg, path: pkgPath } = readPkgUp.sync( {
cwd: realpathSync( getCurrentWorkingDirectory() ),
} );

const getPackagePath = () => pkgPath;

const hasPackageProp = ( prop ) => pkg && pkg.hasOwnProperty( prop );

module.exports = {
getPackagePath,
hasPackageProp,
};
7 changes: 7 additions & 0 deletions packages/scripts/utils/process.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const getCliArgs = () => process.argv.slice( 2 );

module.exports = {
exit: process.exit,
getCliArgs,
getCurrentWorkingDirectory: process.cwd,
};
Loading

0 comments on commit 6b94f93

Please sign in to comment.