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

Commit

Permalink
Scripts: Provide the default configuration for the test command
Browse files Browse the repository at this point in the history
It is used in the case when the project does not have a config for Jest or Babel
  • Loading branch information
gziolo committed Feb 13, 2018
1 parent b07155e commit 640a3ba
Show file tree
Hide file tree
Showing 12 changed files with 242 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.8.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 @@ -28,7 +28,7 @@
"prebuild": "check-node-version --package",
"build": "node ./scripts/build.js",
"postinstall": "lerna bootstrap --hoist && ./scripts/create-symlinks.sh && npm run 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
10 changes: 5 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,9 @@ 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.
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.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 ] );
81 changes: 81 additions & 0 deletions packages/scripts/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* External dependencies
*/
const spawn = require( 'cross-spawn' );
const { existsSync, realpathSync } = require( 'fs' );
const path = require( 'path' );
const readPkgUp = require( 'read-pkg-up' );

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

const first = list => list[ 0 ];

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

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

const appDirectory = path.dirname( pkgPath );

const fromProjectRoot = ( fileName ) => path.join( appDirectory, 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 hasPackageProp = ( prop ) => pkg && pkg.hasOwnProperty( prop );

const handleSignal = ( signal ) => {
if ( 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 ( 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.'
);
}
exit( 1 );
};

const spawnScript = ( scriptName, args ) => {
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,
};
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,
};
54 changes: 54 additions & 0 deletions packages/scripts/utils/test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
jest.mock( '../process', () => {
const process = require.requireActual( '../process' );

return Object.keys( process ).reduce(
( accumulator, methodName ) => ( {
...accumulator,
[ methodName ]: jest.spyOn( process, methodName ),
} ),
{},
);
} );

/**
* Internal dependencies
*/
import {
getCliArgs,
hasCliArg,
} from '../';
import { getCliArgs as getCliArgsMock } from '../process';

describe( 'utils', () => {
describe( 'getCliArgs', () => {
test( 'should have function defined', () => {
expect( getCliArgs() ).toBeDefined();
} );
} );

describe( 'hasCliArg', () => {
beforeAll( () => {
getCliArgsMock.mockReturnValue( [ '-a', '--b', '--config=test' ] );
} );

afterAll( () => {
getCliArgsMock.mockReset();
} );

test( 'should return false when no args passed', () => {
getCliArgsMock.mockReturnValueOnce( [] );

expect( hasCliArg( '--no-args' ) ).toBe( false );
} );

test( 'should return false when checking for unrecognized arg', () => {
expect( hasCliArg( '--non-existent' ) ).toBe( false );
} );

test( 'should return true when CLI arg found', () => {
expect( hasCliArg( '-a' ) ).toBe( true );
expect( hasCliArg( '--b' ) ).toBe( true );
expect( hasCliArg( '--config' ) ).toBe( true );
} );
} );
} );

0 comments on commit 640a3ba

Please sign in to comment.