From d7c2fd37312cb81109dff7904646692cfb373cb6 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 26 Dec 2019 13:55:33 -0800 Subject: [PATCH 1/6] [lint] fix object key spacing --- .eslintrc | 1 + lib/test.js | 148 ++++++++++++++++----------------- test/circular-things.js | 2 +- test/deep-equal-failure.js | 6 +- test/fail.js | 2 +- test/has spaces.js | 2 +- test/max_listeners.js | 2 +- test/not-deep-equal-failure.js | 6 +- test/not-equal-failure.js | 2 +- test/onFailure.js | 2 +- test/only-twice.js | 2 +- test/too_many.js | 2 +- 12 files changed, 89 insertions(+), 88 deletions(-) diff --git a/.eslintrc b/.eslintrc index cc09afbc..674234d4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,7 @@ "root": true, "rules": { "indent": ["error", 4], + "key-spacing": "error", "semi": ["error", "always"], "space-before-function-paren": ["error", { "anonymous": "always", diff --git a/lib/test.js b/lib/test.js index de302c33..7f8c3d81 100644 --- a/lib/test.js +++ b/lib/test.js @@ -169,8 +169,8 @@ Test.prototype._end = function (err) { if (!this._planError && this._plan !== undefined && pendingAsserts) { this._planError = true; this.fail('plan != count', { - expected : this._plan, - actual : this.assertCount + expected: this._plan, + actual: this.assertCount }); } this.ended = true; @@ -181,9 +181,9 @@ Test.prototype._exit = function () { !this._planError && this.assertCount !== this._plan) { this._planError = true; this.fail('plan != count', { - expected : this._plan, - actual : this.assertCount, - exiting : true + expected: this._plan, + actual: this.assertCount, + exiting: true }); } else if (!this.ended) { this.fail('test exited without ending', { @@ -310,44 +310,44 @@ Test.prototype._assert = function assert(ok, opts) { if (!self._planError && pendingAsserts < 0) { self._planError = true; self.fail('plan != count', { - expected : self._plan, - actual : self._plan - pendingAsserts + expected: self._plan, + actual: self._plan - pendingAsserts }); } }; Test.prototype.fail = function (msg, extra) { this._assert(false, { - message : msg, - operator : 'fail', - extra : extra + message: msg, + operator: 'fail', + extra: extra }); }; Test.prototype.pass = function (msg, extra) { this._assert(true, { - message : msg, - operator : 'pass', - extra : extra + message: msg, + operator: 'pass', + extra: extra }); }; Test.prototype.skip = function (msg, extra) { this._assert(true, { - message : msg, - operator : 'skip', - skip : true, - extra : extra + message: msg, + operator: 'skip', + skip: true, + extra: extra }); }; function assert(value, msg, extra) { this._assert(value, { - message : defined(msg, 'should be truthy'), - operator : 'ok', - expected : true, - actual : value, - extra : extra + message: defined(msg, 'should be truthy'), + operator: 'ok', + expected: true, + actual: value, + extra: extra }); } Test.prototype.ok @@ -357,11 +357,11 @@ Test.prototype.ok function notOK(value, msg, extra) { this._assert(!value, { - message : defined(msg, 'should be falsy'), - operator : 'notOk', - expected : false, - actual : value, - extra : extra + message: defined(msg, 'should be falsy'), + operator: 'notOk', + expected: false, + actual: value, + extra: extra }); } Test.prototype.notOk @@ -371,10 +371,10 @@ Test.prototype.notOk function error(err, msg, extra) { this._assert(!err, { - message : defined(msg, String(err)), - operator : 'error', - actual : err, - extra : extra + message: defined(msg, String(err)), + operator: 'error', + actual: err, + extra: extra }); } Test.prototype.error @@ -385,11 +385,11 @@ Test.prototype.error function equal(a, b, msg, extra) { this._assert(a === b, { - message : defined(msg, 'should be equal'), - operator : 'equal', - actual : a, - expected : b, - extra : extra + message: defined(msg, 'should be equal'), + operator: 'equal', + actual: a, + expected: b, + extra: extra }); } Test.prototype.equal @@ -402,11 +402,11 @@ Test.prototype.equal function notEqual(a, b, msg, extra) { this._assert(a !== b, { - message : defined(msg, 'should not be equal'), - operator : 'notEqual', - actual : a, - expected : b, - extra : extra + message: defined(msg, 'should not be equal'), + operator: 'notEqual', + actual: a, + expected: b, + extra: extra }); } Test.prototype.notEqual @@ -422,11 +422,11 @@ Test.prototype.notEqual function tapeDeepEqual(a, b, msg, extra) { this._assert(deepEqual(a, b, { strict: true }), { - message : defined(msg, 'should be equivalent'), - operator : 'deepEqual', - actual : a, - expected : b, - extra : extra + message: defined(msg, 'should be equivalent'), + operator: 'deepEqual', + actual: a, + expected: b, + extra: extra }); } Test.prototype.deepEqual @@ -437,11 +437,11 @@ Test.prototype.deepEqual function deepLooseEqual(a, b, msg, extra) { this._assert(deepEqual(a, b), { - message : defined(msg, 'should be equivalent'), - operator : 'deepLooseEqual', - actual : a, - expected : b, - extra : extra + message: defined(msg, 'should be equivalent'), + operator: 'deepLooseEqual', + actual: a, + expected: b, + extra: extra }); } Test.prototype.deepLooseEqual @@ -451,11 +451,11 @@ Test.prototype.deepLooseEqual function notDeepEqual(a, b, msg, extra) { this._assert(!deepEqual(a, b, { strict: true }), { - message : defined(msg, 'should not be equivalent'), - operator : 'notDeepEqual', - actual : a, - expected : b, - extra : extra + message: defined(msg, 'should not be equivalent'), + operator: 'notDeepEqual', + actual: a, + expected: b, + extra: extra }); } Test.prototype.notDeepEqual @@ -471,11 +471,11 @@ Test.prototype.notDeepEqual function notDeepLooseEqual(a, b, msg, extra) { this._assert(!deepEqual(a, b), { - message : defined(msg, 'should be equivalent'), - operator : 'notDeepLooseEqual', - actual : a, - expected : b, - extra : extra + message: defined(msg, 'should be equivalent'), + operator: 'notDeepLooseEqual', + actual: a, + expected: b, + extra: extra }); } Test.prototype.notDeepLooseEqual @@ -494,7 +494,7 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) { try { fn(); } catch (err) { - caught = { error : err }; + caught = { error: err }; if ((err != null) && (!isEnumerable(err, 'message') || !has(err, 'message'))) { var message = err.message; delete err.message; @@ -514,12 +514,12 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) { } this._assert(typeof fn === 'function' && passed, { - message : defined(msg, 'should throw'), - operator : 'throws', - actual : caught && caught.error, - expected : expected, + message: defined(msg, 'should throw'), + operator: 'throws', + actual: caught && caught.error, + expected: expected, error: !passed && caught && caught.error, - extra : extra + extra: extra }); }; @@ -533,15 +533,15 @@ Test.prototype.doesNotThrow = function (fn, expected, msg, extra) { fn(); } catch (err) { - caught = { error : err }; + caught = { error: err }; } this._assert(!caught, { - message : defined(msg, 'should not throw'), - operator : 'throws', - actual : caught && caught.error, - expected : expected, - error : caught && caught.error, - extra : extra + message: defined(msg, 'should not throw'), + operator: 'throws', + actual: caught && caught.error, + expected: expected, + error: caught && caught.error, + extra: extra }); }; diff --git a/test/circular-things.js b/test/circular-things.js index 88a8465b..98e57a38 100644 --- a/test/circular-things.js +++ b/test/circular-things.js @@ -5,7 +5,7 @@ var concat = require('concat-stream'); var stripFullStack = require('./common').stripFullStack; tap.test('circular test', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); assert.plan(1); test.createStream().pipe(concat(function (body) { diff --git a/test/deep-equal-failure.js b/test/deep-equal-failure.js index c6fa3f64..6bf91d8d 100644 --- a/test/deep-equal-failure.js +++ b/test/deep-equal-failure.js @@ -8,7 +8,7 @@ var getDiag = common.getDiag; var stripFullStack = common.stripFullStack; tap.test('deep equal failure', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); @@ -69,7 +69,7 @@ tap.test('deep equal failure', function (assert) { }); tap.test('deep equal failure, depth 6, with option', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); @@ -130,7 +130,7 @@ tap.test('deep equal failure, depth 6, with option', function (assert) { }); tap.test('deep equal failure, depth 6, without option', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); diff --git a/test/fail.js b/test/fail.js index b1123c2c..96769341 100644 --- a/test/fail.js +++ b/test/fail.js @@ -8,7 +8,7 @@ var stripFullStack = require('./common').stripFullStack; tap.test('array test', function (tt) { tt.plan(1); - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var tc = function (rows) { tt.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', diff --git a/test/has spaces.js b/test/has spaces.js index 19a2b9e3..f8630de3 100644 --- a/test/has spaces.js +++ b/test/has spaces.js @@ -7,7 +7,7 @@ var stripFullStack = require('./common').stripFullStack; tap.test('array test', function (tt) { tt.plan(1); - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var tc = function (rows) { tt.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', diff --git a/test/max_listeners.js b/test/max_listeners.js index e807cdbf..23ebea8c 100644 --- a/test/max_listeners.js +++ b/test/max_listeners.js @@ -3,7 +3,7 @@ var path = require('path'); var ps = spawn(process.execPath, [path.join(__dirname, 'max_listeners', 'source.js')]); -ps.stdout.pipe(process.stdout, { end : false }); +ps.stdout.pipe(process.stdout, { end: false }); ps.stderr.on('data', function (buf) { console.log('not ok ' + buf); diff --git a/test/not-deep-equal-failure.js b/test/not-deep-equal-failure.js index 305029ca..166f7e02 100644 --- a/test/not-deep-equal-failure.js +++ b/test/not-deep-equal-failure.js @@ -8,7 +8,7 @@ var getDiag = common.getDiag; var stripFullStack = common.stripFullStack; tap.test('deep equal failure', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); @@ -69,7 +69,7 @@ tap.test('deep equal failure', function (assert) { }); tap.test('not deep equal failure, depth 6, with option', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); @@ -130,7 +130,7 @@ tap.test('not deep equal failure, depth 6, with option', function (assert) { }); tap.test('not deep equal failure, depth 6, without option', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); diff --git a/test/not-equal-failure.js b/test/not-equal-failure.js index d007b37d..83fc0a4e 100644 --- a/test/not-equal-failure.js +++ b/test/not-equal-failure.js @@ -8,7 +8,7 @@ var getDiag = common.getDiag; var stripFullStack = common.stripFullStack; tap.test('not equal failure', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var stream = test.createStream(); var parser = tapParser(); assert.plan(3); diff --git a/test/onFailure.js b/test/onFailure.js index 518c3732..ec5d9345 100644 --- a/test/onFailure.js +++ b/test/onFailure.js @@ -4,7 +4,7 @@ var tape = require("../").createHarness(); //Because this test passing depends on a failure, //we must direct the failing output of the inner test var noop = function () {}; -var mockSink = {on:noop, removeListener:noop, emit:noop, end:noop}; +var mockSink = {on: noop, removeListener: noop, emit: noop, end: noop}; tape.createStream().pipe(mockSink); tap.test("on failure", { timeout: 1000 }, function (tt) { diff --git a/test/only-twice.js b/test/only-twice.js index 50eea1ec..47c97f5f 100644 --- a/test/only-twice.js +++ b/test/only-twice.js @@ -2,7 +2,7 @@ var tape = require('../'); var tap = require('tap'); tap.test('only twice error', function (assert) { - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); test.only("first only", function (t) { t.end(); diff --git a/test/too_many.js b/test/too_many.js index c62cb4c3..a3a780a2 100644 --- a/test/too_many.js +++ b/test/too_many.js @@ -8,7 +8,7 @@ var stripFullStack = require('./common').stripFullStack; tap.test('array test', function (tt) { tt.plan(1); - var test = tape.createHarness({ exit : false }); + var test = tape.createHarness({ exit: false }); var tc = function (rows) { tt.same(stripFullStack(rows.toString('utf8')), [ 'TAP version 13', From 21ac4036eb99af0eb41d88f038af0d4d9623112c Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 26 Dec 2019 14:10:06 -0800 Subject: [PATCH 2/6] [Tests] handle stack trace variation in node <= 0.8 --- test/anonymous-fn.js | 6 ------ test/common.js | 6 +++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/test/anonymous-fn.js b/test/anonymous-fn.js index 5b3b948a..3e5da152 100644 --- a/test/anonymous-fn.js +++ b/test/anonymous-fn.js @@ -12,12 +12,6 @@ tap.test('inside anonymous functions', function (tt) { var tc = function (rows) { var body = stripFullStack(rows.toString('utf8')); - // Handle stack trace variation in Node v0.8 - body = body.replace( - /at(:?) Test\.module\.exports/g, - 'at$1 Test.' - ); - tt.same(body, [ 'TAP version 13', '# wrapped test failure', diff --git a/test/common.js b/test/common.js index dac41bf1..ae1681e8 100644 --- a/test/common.js +++ b/test/common.js @@ -57,5 +57,9 @@ module.exports.stripFullStack = function (output) { return !hasPrior; }); - return deduped.join('\n'); + return deduped.join('\n').replace( + // Handle stack trace variation in Node v0.8 + /at(:?) Test\.(?:module\.exports|tap\.test\.err\.code)/g, + 'at$1 Test.' + ); }; From 0330d8254d361b5b47d1ca427447a2ba84f6c2b6 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 7 Jan 2020 16:45:08 -0800 Subject: [PATCH 3/6] [New] add `t.match()` and `t.doesNotMatch()`, new in `node` `v13.6` - https://github.com/nodejs/node/pull/30929 --- .editorconfig | 2 +- lib/test.js | 37 +++++++++++ readme.markdown | 8 +++ test/match.js | 173 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 test/match.js diff --git a/.editorconfig b/.editorconfig index a356c3a7..1474ee61 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,7 +7,7 @@ end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -max_line_length = 140 +max_line_length = 180 block_comment_start = /* block_comment = * block_comment_end = */ diff --git a/lib/test.js b/lib/test.js index 7f8c3d81..652a4cdc 100644 --- a/lib/test.js +++ b/lib/test.js @@ -8,8 +8,10 @@ var isRegExp = require('is-regex'); var trim = require('string.prototype.trim'); var bind = require('function-bind'); var forEach = require('for-each'); +var inspect = require('object-inspect'); var isEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable); var toLowerCase = bind.call(Function.call, String.prototype.toLowerCase); +var $test = bind.call(Function.call, RegExp.prototype.test); module.exports = Test; @@ -545,6 +547,41 @@ Test.prototype.doesNotThrow = function (fn, expected, msg, extra) { }); }; +Test.prototype.match = function match(string, regexp, msg, extra) { + if (!isRegExp(regexp)) { + throw new TypeError('The "regexp" argument must be an instance of RegExp. Received type ' + typeof regexp + ' (' + inspect(regexp) + ')'); + } + if (typeof string !== 'string') { + throw new TypeError('The "string" argument must be of type string. Received type ' + typeof string + ' (' + inspect(string) + ')'); + } + + var matches = $test(regexp, string); + this._assert(matches, { + message: defined(msg, 'The input did not match the regular expression ' + inspect(regexp) + '. Input: ' + inspect(string)), + operator: 'match', + actual: string, + expected: regexp, + extra: extra + }); +}; + +Test.prototype.doesNotMatch = function doesNotMatch(string, regexp, msg, extra) { + if (!isRegExp(regexp)) { + throw new TypeError('The "regexp" argument must be an instance of RegExp. Received type ' + typeof regexp + ' (' + inspect(regexp) + ')'); + } + if (typeof string !== 'string') { + throw new TypeError('The "string" argument must be of type string. Received type ' + typeof string + ' (' + inspect(string) + ')'); + } + var matches = $test(regexp, string); + this._assert(!matches, { + message: defined(msg, 'The input was expected to not match the regular expression ' + inspect(regexp) + '. Input: ' + inspect(string)), + operator: 'doesNotMatch', + actual: string, + expected: regexp, + extra: extra + }); +}; + Test.skip = function (name_, _opts, _cb) { var args = getTestArgs.apply(null, arguments); args.opts.skip = true; diff --git a/readme.markdown b/readme.markdown index b49f6123..6854811f 100644 --- a/readme.markdown +++ b/readme.markdown @@ -285,6 +285,14 @@ You may pass the same options that [`test()`](#testname-opts-cb) accepts. Print a message without breaking the tap output. (Useful when using e.g. `tap-colorize` where output is buffered & `console.log` will print in incorrect order vis-a-vis tap output.) +## t.match(string, regexp, message) + +Assert that `string` matches the RegExp `regexp`. Will throw (not just fail) when the first two arguments are the wrong type. + +## t.doesNotMatch(string, regexp, message) + +Assert that `string` does not match the RegExp `regexp`. Will throw (not just fail) when the first two arguments are the wrong type. + ## var htest = test.createHarness() Create a new test harness instance, which is a function like `test()`, but with diff --git a/test/match.js b/test/match.js new file mode 100644 index 00000000..22d576d0 --- /dev/null +++ b/test/match.js @@ -0,0 +1,173 @@ +'use strict'; + +var tape = require('../'); +var tap = require('tap'); +var concat = require('concat-stream'); + +var stripFullStack = require('./common').stripFullStack; + +tap.test('match', function (tt) { + tt.plan(1); + + var test = tape.createHarness({ exit: false }); + var tc = function (rows) { + tt.same(stripFullStack(rows.toString('utf8')), [ + 'TAP version 13', + '# match', + 'ok 1 regex arg must be a regex', + 'ok 2 string arg must be a string', + 'not ok 3 The input did not match the regular expression /abc/. Input: \'string\'', + ' ---', + ' operator: match', + ' expected: /abc/', + ' actual: \'string\'', + ' at: Test. ($TEST/match.js:$LINE:$COL)', + ' stack: |-', + ' Error: The input did not match the regular expression /abc/. Input: \'string\'', + ' [... stack stripped ...]', + ' at Test. ($TEST/match.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + 'not ok 4 "string" does not match /abc/', + ' ---', + ' operator: match', + ' expected: /abc/', + ' actual: \'string\'', + ' at: Test. ($TEST/match.js:$LINE:$COL)', + ' stack: |-', + ' Error: "string" does not match /abc/', + ' [... stack stripped ...]', + ' at Test. ($TEST/match.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + 'ok 5 The input did not match the regular expression /pass$/. Input: \'I will pass\'', + 'ok 6 "I will pass" matches /pass$/', + '', + '1..6', + '# tests 6', + '# pass 4', + '# fail 2', + '' + ].join('\n')); + }; + + test.createStream().pipe(concat(tc)); + + test('match', function (t) { + t.plan(6); + + t.throws( + function () { t.match(/abc/, 'string'); }, + TypeError, + 'regex arg must be a regex' + ); + + t.throws( + function () { t.match({ abc: 123 }, /abc/); }, + TypeError, + 'string arg must be a string' + ); + + t.match('string', /abc/); + t.match('string', /abc/, '"string" does not match /abc/'); + + t.match('I will pass', /pass$/); + t.match('I will pass', /pass$/, '"I will pass" matches /pass$/'); + + t.end(); + }); +}); + +tap.test('doesNotMatch', function (tt) { + tt.plan(1); + + var test = tape.createHarness({ exit: false }); + var tc = function (rows) { + tt.same(stripFullStack(rows.toString('utf8')), [ + 'TAP version 13', + '# doesNotMatch', + 'ok 1 regex arg must be a regex', + 'ok 2 string arg must be a string', + 'not ok 3 The input was expected to not match the regular expression /string/. Input: \'string\'', + ' ---', + ' operator: doesNotMatch', + ' expected: /string/', + ' actual: \'string\'', + ' at: Test. ($TEST/match.js:$LINE:$COL)', + ' stack: |-', + ' Error: The input was expected to not match the regular expression /string/. Input: \'string\'', + ' [... stack stripped ...]', + ' at Test. ($TEST/match.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + 'not ok 4 "string" should not match /string/', + ' ---', + ' operator: doesNotMatch', + ' expected: /string/', + ' actual: \'string\'', + ' at: Test. ($TEST/match.js:$LINE:$COL)', + ' stack: |-', + ' Error: "string" should not match /string/', + ' [... stack stripped ...]', + ' at Test. ($TEST/match.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + 'not ok 5 The input was expected to not match the regular expression /pass$/. Input: \'I will pass\'', + ' ---', + ' operator: doesNotMatch', + ' expected: /pass$/', + ' actual: \'I will pass\'', + ' at: Test. ($TEST/match.js:$LINE:$COL)', + ' stack: |-', + ' Error: The input was expected to not match the regular expression /pass$/. Input: \'I will pass\'', + ' [... stack stripped ...]', + ' at Test. ($TEST/match.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + 'not ok 6 "I will pass" should not match /pass$/', + ' ---', + ' operator: doesNotMatch', + ' expected: /pass$/', + ' actual: \'I will pass\'', + ' at: Test. ($TEST/match.js:$LINE:$COL)', + ' stack: |-', + ' Error: "I will pass" should not match /pass$/', + ' [... stack stripped ...]', + ' at Test. ($TEST/match.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + '', + '1..6', + '# tests 6', + '# pass 2', + '# fail 4', + '' + ].join('\n')); + }; + + test.createStream().pipe(concat(tc)); + + test('doesNotMatch', function (t) { + t.plan(6); + + t.throws( + function () { t.doesNotMatch(/abc/, 'string'); }, + TypeError, + 'regex arg must be a regex' + ); + + t.throws( + function () { t.doesNotMatch({ abc: 123 }, /abc/); }, + TypeError, + 'string arg must be a string' + ); + + t.doesNotMatch('string', /string/); + t.doesNotMatch('string', /string/, '"string" should not match /string/'); + + t.doesNotMatch('I will pass', /pass$/); + t.doesNotMatch('I will pass', /pass$/, '"I will pass" should not match /pass$/'); + + t.end(); + }); +}); From 0f15085b090ef52176564cbc2a6b7994d38173f5 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 7 Jan 2020 17:40:12 -0800 Subject: [PATCH 4/6] [Deps] update `resolve` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c7e52d0d..2fabfaee 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "is-regex": "~1.0.5", "minimist": "~1.2.0", "object-inspect": "~1.7.0", - "resolve": "~1.14.1", + "resolve": "~1.14.2", "resumer": "~0.0.0", "string.prototype.trim": "~1.2.1", "through": "~2.3.8" From e0e2542240875e5dad2ba12b1edc4be3251ae571 Mon Sep 17 00:00:00 2001 From: Ram Damera Date: Tue, 7 Jan 2020 13:40:59 +0530 Subject: [PATCH 5/6] [New] `tape` binary: Add -i flag to ignore files from gitignore (#492) --- bin/tape | 22 ++++- package.json | 1 + test/ignore/.ignore | 1 + test/ignore/fake_node_modules/stub1.js | 8 ++ test/ignore/fake_node_modules/stub2.js | 8 ++ test/ignore/test.js | 8 ++ test/ignore/test/stub1.js | 8 ++ test/ignore/test/stub2.js | 8 ++ test/ignore/test/sub/sub.stub1.js | 8 ++ test/ignore/test/sub/sub.stub2.js | 8 ++ test/ignore/test2.js | 8 ++ test/ignore_from_gitignore.js | 122 +++++++++++++++++++++++++ 12 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 test/ignore/.ignore create mode 100644 test/ignore/fake_node_modules/stub1.js create mode 100644 test/ignore/fake_node_modules/stub2.js create mode 100644 test/ignore/test.js create mode 100644 test/ignore/test/stub1.js create mode 100644 test/ignore/test/stub2.js create mode 100644 test/ignore/test/sub/sub.stub1.js create mode 100644 test/ignore/test/sub/sub.stub2.js create mode 100644 test/ignore/test2.js create mode 100644 test/ignore_from_gitignore.js diff --git a/bin/tape b/bin/tape index 74f4aba5..3ea1cec5 100755 --- a/bin/tape +++ b/bin/tape @@ -2,14 +2,16 @@ var resolveModule = require('resolve').sync; var resolvePath = require('path').resolve; +var readFileSync = require('fs').readFileSync; var parseOpts = require('minimist'); var glob = require('glob'); +var ignore = require('dotignore'); var opts = parseOpts(process.argv.slice(2), { - alias: { r: 'require' }, - string: 'require', - default: { r: [] } - }); + alias: { r: 'require', i: 'ignore' }, + string: ['require', 'ignore'], + default: { r: [], i: null } +}); var cwd = process.cwd(); @@ -26,6 +28,16 @@ opts.require.forEach(function (module) { } }); +if (typeof opts.ignore === 'string') { + try { + var ignoreStr = readFileSync(resolvePath(cwd, opts.ignore || '.gitignore'), 'utf-8'); + } catch (e) { + console.error(e.message); + process.exit(2); + } + var matcher = ignore.createMatcher(ignoreStr); +} + opts._.forEach(function (arg) { // If glob does not match, `files` will be an empty array. // Note: `glob.sync` may throw an error and crash the node process. @@ -35,7 +47,7 @@ opts._.forEach(function (arg) { throw new TypeError('unknown error: glob.sync did not return an array or throw. Please report this.'); } - files.forEach(function (file) { + files.filter(function (file) { return !matcher || !matcher.shouldIgnore(file); }).forEach(function (file) { require(resolvePath(cwd, file)); }); }); diff --git a/package.json b/package.json index 2fabfaee..664e7674 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "deep-equal": "~1.1.1", "defined": "~1.0.0", + "dotignore": "~0.1.2", "for-each": "~0.3.3", "function-bind": "~1.1.1", "glob": "~7.1.6", diff --git a/test/ignore/.ignore b/test/ignore/.ignore new file mode 100644 index 00000000..ec1cc296 --- /dev/null +++ b/test/ignore/.ignore @@ -0,0 +1 @@ +fake_node_modules diff --git a/test/ignore/fake_node_modules/stub1.js b/test/ignore/fake_node_modules/stub1.js new file mode 100644 index 00000000..6ef0b71c --- /dev/null +++ b/test/ignore/fake_node_modules/stub1.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../../'); + +tape.test(function (t) { + t.plan(1); + t.fail('Should not print'); +}); diff --git a/test/ignore/fake_node_modules/stub2.js b/test/ignore/fake_node_modules/stub2.js new file mode 100644 index 00000000..27bebd87 --- /dev/null +++ b/test/ignore/fake_node_modules/stub2.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../../'); + +tape.test(function (t) { + t.fail('Should not print'); + t.end(); +}); diff --git a/test/ignore/test.js b/test/ignore/test.js new file mode 100644 index 00000000..f2d6f572 --- /dev/null +++ b/test/ignore/test.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../'); + +tape.test(function (t) { + t.plan(1); + t.ok('Okay'); +}); diff --git a/test/ignore/test/stub1.js b/test/ignore/test/stub1.js new file mode 100644 index 00000000..e91244ee --- /dev/null +++ b/test/ignore/test/stub1.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../../'); + +tape.test(function (t) { + t.plan(1); + t.pass('test/stub1'); +}); diff --git a/test/ignore/test/stub2.js b/test/ignore/test/stub2.js new file mode 100644 index 00000000..f4661b88 --- /dev/null +++ b/test/ignore/test/stub2.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../../'); + +tape.test(function (t) { + t.pass('test/stub2'); + t.end(); +}); diff --git a/test/ignore/test/sub/sub.stub1.js b/test/ignore/test/sub/sub.stub1.js new file mode 100644 index 00000000..0f39cfee --- /dev/null +++ b/test/ignore/test/sub/sub.stub1.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../../../'); + +tape.test(function (t) { + t.plan(1); + t.pass('test/sub/stub1'); +}); diff --git a/test/ignore/test/sub/sub.stub2.js b/test/ignore/test/sub/sub.stub2.js new file mode 100644 index 00000000..bec910d7 --- /dev/null +++ b/test/ignore/test/sub/sub.stub2.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../../../'); + +tape.test(function (t) { + t.pass('test/sub/stub2'); + t.end(); +}); diff --git a/test/ignore/test2.js b/test/ignore/test2.js new file mode 100644 index 00000000..a2ceecc0 --- /dev/null +++ b/test/ignore/test2.js @@ -0,0 +1,8 @@ +'use strict'; + +var tape = require('../../'); + +tape.test(function (t) { + t.pass('Should print'); + t.end(); +}); diff --git a/test/ignore_from_gitignore.js b/test/ignore_from_gitignore.js new file mode 100644 index 00000000..16b076a4 --- /dev/null +++ b/test/ignore_from_gitignore.js @@ -0,0 +1,122 @@ +'use strict'; + +var tap = require('tap'); +var path = require('path'); +var spawn = require('child_process').spawn; +var concat = require('concat-stream'); + +var stripFullStack = require('./common').stripFullStack; + +var tapeBin = path.join(process.cwd(), 'bin/tape'); + +tap.test('Should pass with ignoring', { skip: process.platform === 'win32' }, function (tt) { + tt.plan(2); + + var tc = function (rows) { + tt.same(stripFullStack(rows.toString('utf8')), [ + 'TAP version 13', + '# (anonymous)', + 'ok 1 should be truthy', + '# (anonymous)', + 'ok 2 test/stub1', + '# (anonymous)', + 'ok 3 test/stub2', + '# (anonymous)', + 'ok 4 test/sub/stub1', + '# (anonymous)', + 'ok 5 test/sub/stub2', + '# (anonymous)', + 'ok 6 Should print', + '', + '1..6', + '# tests 6', + '# pass 6', + '', + '# ok', + '', + '' + ].join('\n')); + }; + + var ps = spawn(tapeBin, ['**/*.js', '-i', '.ignore'], {cwd: path.join(__dirname, 'ignore')}); + ps.stdout.pipe(concat(tc)); + ps.on('exit', function (code) { + tt.equal(code, 0); // code 0 + }); +}); + +tap.test('Should pass', { skip: process.platform === 'win32' }, function (tt) { + tt.plan(2); + + var tc = function (rows) { + tt.same(stripFullStack(rows.toString('utf8')), [ + 'TAP version 13', + '# (anonymous)', + 'not ok 1 Should not print', + ' ---', + ' operator: fail', + ' at: Test. ($TEST/ignore/fake_node_modules/stub1.js:$LINE:$COL)', + ' stack: |-', + ' Error: Should not print', + ' [... stack stripped ...]', + ' at Test. ($TEST/ignore/fake_node_modules/stub1.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + '# (anonymous)', + 'not ok 2 Should not print', + ' ---', + ' operator: fail', + ' at: Test. ($TEST/ignore/fake_node_modules/stub2.js:$LINE:$COL)', + ' stack: |-', + ' Error: Should not print', + ' [... stack stripped ...]', + ' at Test. ($TEST/ignore/fake_node_modules/stub2.js:$LINE:$COL)', + ' [... stack stripped ...]', + ' ...', + '# (anonymous)', + 'ok 3 should be truthy', + '# (anonymous)', + 'ok 4 test/stub1', + '# (anonymous)', + 'ok 5 test/stub2', + '# (anonymous)', + 'ok 6 test/sub/stub1', + '# (anonymous)', + 'ok 7 test/sub/stub2', + '# (anonymous)', + 'ok 8 Should print', + '', + '1..8', + '# tests 8', + '# pass 6', + '# fail 2', + '', + '' + ].join('\n')); + }; + + var ps = spawn(tapeBin, ['**/*.js'], {cwd: path.join(__dirname, 'ignore')}); + ps.stdout.pipe(concat(tc)); + ps.on('exit', function (code) { + tt.equal(code, 1); + }); +}); + +tap.test('Should fail when ignore file does not exist', { skip: process.platform === 'win32' }, function (tt) { + tt.plan(3); + + var testStdout = function (rows) { + tt.same(rows.toString('utf8'), ''); + }; + + var testStderr = function (rows) { + tt.ok(/^ENOENT[:,] no such file or directory,? (?:open )?'\$TEST\/ignore\/.gitignore'\n$/m.test(stripFullStack(rows.toString('utf8')))); + }; + + var ps = spawn(tapeBin, ['**/*.js', '-i'], {cwd: path.join(__dirname, 'ignore')}); + ps.stdout.pipe(concat(testStdout)); + ps.stderr.pipe(concat(testStderr)); + ps.on('exit', function (code) { + tt.equal(code, 2); + }); +}); From 1fba54a4a15ec5a8c894e1a4df7e6ef584f6531e Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 7 Jan 2020 23:30:32 -0800 Subject: [PATCH 6/6] v4.13.0 - [New] `tape` binary: Add -i flag to ignore files from gitignore (#492) - [New] add `t.match()` and `t.doesNotMatch()`, new in `node` `v13.6` - [Deps] update `resolve` - [Tests] handle stack trace variation in node <= 0.8 - [lint] fix object key spacing --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 664e7674..5a738bec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tape", - "version": "4.12.1", + "version": "4.13.0", "description": "tap-producing test harness for node and browsers", "main": "index.js", "bin": "./bin/tape",