From 7ae60f5ff63b6bfd9c7811eb8977ed60bfeaa5ac Mon Sep 17 00:00:00 2001 From: Marcus Stade Date: Mon, 21 Dec 2015 21:53:03 +0100 Subject: [PATCH] This implements `-r` and `--require` as command line options @Raynos accurately pointed out that the source map support was a bit too specific, and felt outside of the purview of tape. As a more general solution, this implements the `-r` and `--require` CLI flags, which will allow a user to load node modules before any tests are run. For example, if someon wants to enable source map support in node, they might do: tape -r source-map-support/register test/*.js --- bin/tape | 26 +++++++++++-- package.json | 2 + test/require.js | 83 ++++++++++++++++++++++++++++++++++++++++++ test/require/a.js | 8 ++++ test/require/b.js | 8 ++++ test/require/test-a.js | 7 ++++ test/require/test-b.js | 7 ++++ 7 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 test/require.js create mode 100644 test/require/a.js create mode 100644 test/require/b.js create mode 100644 test/require/test-a.js create mode 100644 test/require/test-b.js diff --git a/bin/tape b/bin/tape index 500f1b14..df3f0c1f 100755 --- a/bin/tape +++ b/bin/tape @@ -1,12 +1,32 @@ #!/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 only one require is specified, the value of `opts.require` + * will be a string. This is why we concatenate. + */ +;[].concat(opts.require).forEach(function(module) { + /* The `module &&` ensures we ignore `-r ""`, trailing `-r` or other + * silly things the user might (inadvertedly) be doing. + */ + module && 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)); }); }); }); diff --git a/package.json b/package.json index 0be3595b..66a65290 100644 --- a/package.json +++ b/package.json @@ -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" diff --git a/test/require.js b/test/require.js new file mode 100644 index 00000000..0385ea45 --- /dev/null +++ b/test/require.js @@ -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 }) +} \ No newline at end of file diff --git a/test/require/a.js b/test/require/a.js new file mode 100644 index 00000000..0947b7b9 --- /dev/null +++ b/test/require/a.js @@ -0,0 +1,8 @@ +var tape = require('../..'); + +tape.test('module-a', function(t) { + t.pass('loaded module a') + t.end() +}) + +global.module_a = true \ No newline at end of file diff --git a/test/require/b.js b/test/require/b.js new file mode 100644 index 00000000..18942e0c --- /dev/null +++ b/test/require/b.js @@ -0,0 +1,8 @@ +var tape = require('../..'); + +tape.test('module-b', function(t) { + t.pass('loaded module b') + t.end() +}) + +global.module_b = true \ No newline at end of file diff --git a/test/require/test-a.js b/test/require/test-a.js new file mode 100644 index 00000000..822ef540 --- /dev/null +++ b/test/require/test-a.js @@ -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() +}) \ No newline at end of file diff --git a/test/require/test-b.js b/test/require/test-b.js new file mode 100644 index 00000000..8efcba1c --- /dev/null +++ b/test/require/test-b.js @@ -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() +}) \ No newline at end of file