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

CLI: Implement --require option #1271

Merged
merged 1 commit into from Mar 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions bin/qunit
Expand Up @@ -17,6 +17,11 @@ const description = `Runs tests using the QUnit framework.

For more info on working with QUnit, check out http://qunitjs.com.`;

function collect( val, collection ) {
collection.push( val );
return collection;
}

program._name = "qunit";
program
.version( pkg.version )
Expand All @@ -26,6 +31,8 @@ program
.option( "-r, --reporter [name]", "specify the reporter to use; " +
"if no match is found or no name is provided, a list of available " +
"reporters will be displayed" )
.option( "--require <module>", "specify a module to require prior to running " +
"any tests.", collect, [] )
.option( "--seed [value]", "specify a seed to order your tests; " +
"if option is specified without a value, one will be generated" )
.option( "-w, --watch", "Watch files for changes and re-run the test suite" )
Expand All @@ -39,6 +46,7 @@ const args = program.args;
const options = {
filter: program.filter,
reporter: findReporter( program.reporter ),
requires: program.require,
seed: program.seed
};

Expand Down
6 changes: 6 additions & 0 deletions bin/require-from-cwd.js
@@ -0,0 +1,6 @@
const resolve = require( "resolve" );
Copy link
Member

@Krinkle Krinkle Mar 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR, but we seem to have grown a fair number of files in bin/ that are not intended as standalone CLI entry points. We should consider moving these to src/ instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 agreed, though I would like to ensure we keep some clear separation between CLI code and library code (just means we likely need src/cli or something)


module.exports = function requireFromCWD( mod ) {
const resolvedPath = resolve.sync( mod, { basedir: process.cwd() } );
return require( resolvedPath );
};
52 changes: 28 additions & 24 deletions bin/run.js
Expand Up @@ -3,6 +3,7 @@
const path = require( "path" );
const walkSync = require( "walk-sync" );

const requireFromCWD = require( "./require-from-cwd" );
const requireQUnit = require( "./require-qunit" );
const utils = require( "./utils" );

Expand All @@ -14,34 +15,10 @@ const RESTART_DEBOUNCE_LENGTH = 200;
let QUnit;

function run( args, options ) {
let running = true;

// Default to non-zero exit code to avoid false positives
process.exitCode = 1;

process.on( "exit", function() {
if ( running ) {
console.error( "Error: Process exited before tests finished running" );

const currentTest = QUnit.config.current;
if ( currentTest && currentTest.semaphore ) {
const name = currentTest.testName;
console.error( "Last test to run (" + name + ") has an async hold. " +
"Ensure all assert.async() callbacks are invoked and Promises resolve. " +
"You should also set a standard timeout via QUnit.config.testTimeout." );
}
}
} );

// Listen for unhandled rejections, and call QUnit.onUnhandledRejection
process.on( "unhandledRejection", function( reason ) {
QUnit.onUnhandledRejection( reason );
} );

process.on( "uncaughtException", function( error ) {
QUnit.onError( error );
} );

const files = utils.getFilesFromArgs( args );

QUnit = requireQUnit();
Expand All @@ -65,6 +42,8 @@ function run( args, options ) {
// still done automatically.
global.QUnit = QUnit;

options.requires.forEach( requireFromCWD );

options.reporter.init( QUnit );

for ( let i = 0; i < files.length; i++ ) {
Expand All @@ -85,6 +64,31 @@ function run( args, options ) {
}
}

let running = true;

// Listen for unhandled rejections, and call QUnit.onUnhandledRejection
process.on( "unhandledRejection", function( reason ) {
QUnit.onUnhandledRejection( reason );
} );

process.on( "uncaughtException", function( error ) {
QUnit.onError( error );
} );

process.on( "exit", function() {
if ( running ) {
console.error( "Error: Process exited before tests finished running" );

const currentTest = QUnit.config.current;
if ( currentTest && currentTest.semaphore ) {
const name = currentTest.testName;
console.error( "Last test to run (" + name + ") has an async hold. " +
"Ensure all assert.async() callbacks are invoked and Promises resolve. " +
"You should also set a standard timeout via QUnit.config.testTimeout." );
}
}
} );

QUnit.start();

QUnit.on( "runEnd", function setExitCode( data ) {
Expand Down
13 changes: 12 additions & 1 deletion test/cli/fixtures/expected/tap-outputs.js
Expand Up @@ -158,5 +158,16 @@ not ok 1 global failure
# skip 0
# todo 0
# fail 1
`
`,

"qunit single.js --require require-dep --require './node_modules/require-dep/module.js'":
`required require-dep/index.js
required require-dep/module.js
TAP version 13
ok 1 Single > has a test
1..1
# pass 1
# skip 0
# todo 0
# fail 0`
};
1 change: 1 addition & 0 deletions test/cli/fixtures/node_modules/require-dep/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/cli/fixtures/node_modules/require-dep/module.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions test/cli/fixtures/node_modules/require-dep/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions test/cli/main.js
Expand Up @@ -146,6 +146,28 @@ QUnit.module( "CLI Main", function() {
} ) );
} );

QUnit.module( "require", function() {
QUnit.test( "can properly require dependencies and modules", co.wrap( function* ( assert ) {
const command = "qunit single.js --require require-dep --require './node_modules/require-dep/module.js'";
const execution = yield execute( command );

assert.equal( execution.code, 0 );
assert.equal( execution.stderr, "" );
assert.equal( execution.stdout, expectedOutput[ command ] );
} ) );

QUnit.test( "displays helpful error when failing to require a file", co.wrap( function* ( assert ) {
const command = "qunit single.js --require 'does-not-exist-at-all'";
try {
yield execute( command );
} catch ( e ) {
assert.equal( e.code, 1 );
assert.ok( e.stderr.includes( "Error: Cannot find module 'does-not-exist-at-all'" ) );
assert.equal( e.stdout, "" );
}
} ) );
} );

QUnit.module( "seed", function() {
QUnit.test( "can properly seed tests", co.wrap( function* ( assert ) {
const command = "qunit --seed 's33d' test single.js 'glob/**/*-test.js'";
Expand Down