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

Add flag to require modules before running tests #224

Merged
merged 10 commits into from
Dec 23, 2015
28 changes: 25 additions & 3 deletions bin/tape
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
#!/usr/bin/env node

var path = require('path');
var resolveModule = require('resolve').sync;
var resolvePath = require('path').resolve;
var parseOpts = require('minimist');
var glob = require('glob');

process.argv.slice(2).forEach(function (arg) {
var opts = parseOpts(process.argv.slice(2), {
alias: { r: 'require' },
string: 'require',
default: { r: [] }
});

var cwd = process.cwd();

if (typeof opts.require === 'string') {
Copy link
Collaborator

Choose a reason for hiding this comment

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

you could replace this if block with var requires = [].concat(opts.require), fwiw (that would also avoid mutating opts)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did something similar previously, but @Raynos suggested the change to the typeof block instead. I don't really care much either way to be honest.

Copy link
Collaborator

Choose a reason for hiding this comment

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

i guess either way is fine

opts.require = [opts.require];
}

opts.require.forEach(function(module) {
if (module) {
/* This check ensures we ignore `-r ""`, trailing `-r`, or
* other silly things the user might (inadvertently) be doing. */
require(resolveModule(module, { basedir: cwd }));
}
});

opts._.forEach(function (arg) {
glob(arg, function (err, files) {
files.forEach(function (file) {
require(path.resolve(process.cwd(), file));
require(resolvePath(cwd, file));
});
});
});
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"glob": "~5.0.3",
"has": "~1.0.1",
"inherits": "~2.0.1",
"minimist": "~1.2.0",
"object-inspect": "~1.0.0",
"resolve": "~1.1.6",
"resumer": "~0.0.0",
"string.prototype.trim": "^1.1.1",
"through": "~2.3.4"
Expand Down
20 changes: 20 additions & 0 deletions readme.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@ $ tape 'tests/**/*.js'
$ tape "tests/**/*.js"
```

## Preloading modules

Additionally, it is possible to make `tape` load one or more modules before running any tests, by using the `-r` or `--require` flag. Here's an example that loads [babel-register](http://babeljs.io/docs/usage/require/) before running any tests, to allow for JIT compilation:

```sh
$ tape -r babel-register tests/**/*.js
```

Depending on the module you're loading, you may be able to paramaterize it using environment variables or auxiliary files. Babel, for instance, will load options from [`.babelrc`](http://babeljs.io/docs/usage/babelrc/) at runtime.

The `-r` flag behaves exactly like node's `require`, and uses the same module resolution algorithm. This means that if you need to load local modules, you have to prepend their path with `./` or `../` accordingly.

For example:

```sh
$ tape -r ./my/local/module tests/**/*.js
```

Please note that modules that all modules loaded using the `-r` flag will run *before* any tests, regardless of when they are specified. For example, `tape -r a b -r c` will actually load `a` and `c` *before` loading `b`, since they are flagged as required modules.

# things that go well with tape

tape maintains a fairly minimal core. Additional features are usually added by using another module alongside tape.
Expand Down
83 changes: 83 additions & 0 deletions test/require.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
var tap = require('tap');
var spawn = require('child_process').spawn;
var trim = require('string.prototype.trim');

tap.test('requiring a single module', function (t) {
t.plan(2);

var tc = tap.createConsumer();

var rows = [];
tc.on('data', function (r) { rows.push(r) });
tc.on('end', function () {
var rs = rows.map(function (r) {
if (r && typeof r === 'object') {
return { id : r.id, ok : r.ok, name : trim(r.name) };
}
else return r;
});
t.same(rs, [
'TAP version 13',
'module-a',
{ id: 1, ok: true, name: 'loaded module a' },
'test-a',
{ id: 2, ok: true, name: 'module-a loaded in same context'},
{ id: 3, ok: true, name: 'test ran after module-a was loaded'},
'tests 3',
'pass 3',
'ok'
]);
});

var ps = tape('-r ./require/a require/test-a.js');
ps.stdout.pipe(tc);
ps.on('exit', function (code) {
t.equal(code, 0);
});
});

tap.test('requiring multiple modules', function (t) {
t.plan(2);

var tc = tap.createConsumer();

var rows = [];
tc.on('data', function (r) { rows.push(r) });
tc.on('end', function () {
var rs = rows.map(function (r) {
if (r && typeof r === 'object') {
return { id : r.id, ok : r.ok, name : trim(r.name) };
}
else return r;
});
t.same(rs, [
'TAP version 13',
'module-a',
{ id: 1, ok: true, name: 'loaded module a' },
'module-b',
{ id: 2, ok: true, name: 'loaded module b' },
'test-a',
{ id: 3, ok: true, name: 'module-a loaded in same context'},
{ id: 4, ok: true, name: 'test ran after module-a was loaded'},
'test-b',
{ id: 5, ok: true, name: 'module-b loaded in same context'},
{ id: 6, ok: true, name: 'test ran after module-b was loaded'},
'tests 6',
'pass 6',
'ok'
]);
});

var ps = tape('-r ./require/a -r ./require/b require/test-a.js require/test-b.js');
ps.stdout.pipe(tc);
ps.on('exit', function (code) {
t.equal(code, 0);
});
});

function tape(args) {
var proc = require('child_process')
var bin = __dirname + '/../bin/tape'

return proc.spawn(bin, args.split(' '), { cwd: __dirname })
}
8 changes: 8 additions & 0 deletions test/require/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var tape = require('../..');

tape.test('module-a', function(t) {
t.pass('loaded module a')
t.end()
})

global.module_a = true
8 changes: 8 additions & 0 deletions test/require/b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var tape = require('../..');

tape.test('module-b', function(t) {
t.pass('loaded module b')
t.end()
})

global.module_b = true
7 changes: 7 additions & 0 deletions test/require/test-a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var tape = require('../..');

tape.test('test-a', function(t) {
t.ok(global.module_a, 'module-a loaded in same context')
t.pass('test ran after module-a was loaded')
t.end()
})
7 changes: 7 additions & 0 deletions test/require/test-b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var tape = require('../..');

tape.test('test-b', function(t) {
t.ok(global.module_b, 'module-b loaded in same context')
t.pass('test ran after module-b was loaded')
t.end()
})