[Pkg-javascript-commits] [node-tap] 09/186: move assertions directly to Test class
Bastien Roucariès
rouca at moszumanska.debian.org
Fri Dec 1 16:40:38 UTC 2017
This is an automated email from the git hooks/post-receive script.
rouca pushed a commit to branch master
in repository node-tap.
commit da56f538c117fa64651998e6db55940c90f271b2
Author: isaacs <i at izs.me>
Date: Fri Jul 7 23:50:02 2017 -0700
move assertions directly to Test class
---
lib/test.js | 540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 505 insertions(+), 35 deletions(-)
diff --git a/lib/test.js b/lib/test.js
index 86c3eda..6326143 100644
--- a/lib/test.js
+++ b/lib/test.js
@@ -27,12 +27,14 @@ const parseTestArgs = require('./parse-test-args.js')
const loop = require('function-loop')
const extraFromError = require('./extra-from-error.js')
+const tsame = require('tsame') // same thing, strict or not
+const tmatch = require('tmatch') // ok with partial estimates
const stack = require('./stack.js')
+const synonyms = require('./synonyms.js')
const assert = require('assert')
const util = require('util')
const ownOr = require('own-or')
const ownOrEnv = require('own-or-env')
-const tapAsserts = require('./asserts.js')
const Promise = require('bluebird')
const bindObj = require('bind-obj-methods')
@@ -45,7 +47,6 @@ const EOF = Symbol('EOF')
const _end = Symbol('_end')
-
const hasOwn = (obj, key) =>
Object.prototype.hasOwnProperty.call(obj, key)
@@ -441,37 +442,6 @@ class Test extends Base {
this[name] = ASSERT
}
- fail (message, extra) {
- if (!this.currentAssert) {
- this.currentAssert = Test.prototype.fail
- }
-
- if (message && typeof message === 'object') {
- extra = message
- message = ''
- } else {
- if (!message) {
- message = ''
- }
- if (!extra) {
- extra = {}
- }
- }
-
- this.printResult(false, message, extra)
-
- // if it's todo or skip, it's still technically passing
- return !!(extra.todo || extra.skip)
- }
-
- pass (message, extra) {
- if (!this.currentAssert) {
- this.currentAssert = Test.prototype.pass
- }
- this.printResult(true, message || '(unnamed test)', extra)
- return true
- }
-
printResult (ok, message, extra, front) {
const n = this.count + 1
if (this.planEnd !== -1 && n > this.planEnd) {
@@ -749,6 +719,499 @@ class Test extends Base {
this.process()
this.parser.end()
}
+
+ pass (message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.pass
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ this.printResult(true, message || '(unnamed test)', extra)
+ return true
+ }
+
+ fail (message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.fail
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ this.printResult(false, message || '(unnamed test)', extra || {})
+ return !!(extra.todo || extra.skip)
+ }
+
+ ok (obj, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.ok
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+ message = message || 'expect truthy value'
+ return obj ? this.pass(message, extra) : this.fail(message, extra)
+ }
+
+ notOk (obj, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.notOk
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+ message = message || 'expect falsey value'
+ return this.ok(!obj, message, extra)
+ }
+
+ error (er, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.error
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ if (!er) {
+ return this.pass(message || 'should not error', extra)
+ }
+
+ if (!(er instanceof Error)) {
+ extra.found = er
+ return this.fail(message || 'non-Error error encountered', extra)
+ }
+
+ message = message || er.message
+ extra.found = er
+ return this.fail(message, extra)
+ }
+
+ equal (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.equal
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should be equal'
+ if (found === wanted) {
+ return this.pass(message, extra)
+ }
+
+ extra.found = found
+ extra.wanted = wanted
+ extra.compare = '==='
+
+ if (typeof found === 'object' &&
+ typeof wanted === 'object' &&
+ found &&
+ wanted &&
+ tsame(found, wanted)) {
+ extra.note = 'Objects never === one another'
+ }
+
+ return this.fail(message, extra)
+ }
+
+ not (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.not
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should not be equal'
+ if (found !== wanted) {
+ return this.pass(message, extra)
+ }
+
+ extra.found = found
+ extra.doNotWant = wanted
+ extra.compare = '!=='
+
+ return this.fail(message, extra)
+ }
+
+ same (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.same
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should be equivalent'
+ extra.found = found
+ extra.wanted = wanted
+ return this.ok(tsame(found, wanted), message, extra)
+ }
+
+ notSame (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.notSame
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should not be equivalent'
+ extra.found = found
+ extra.doNotWant = wanted
+ return this.notOk(tsame(found, wanted), message, extra)
+ }
+
+ strictSame (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.strictSame
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should be equivalent strictly'
+ extra.found = found
+ extra.wanted = wanted
+ return this.ok(tsame.strict(found, wanted), message, extra)
+ }
+
+ strictNotSame (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.strictNotSame
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should be equivalent strictly'
+ extra.found = found
+ extra.doNotWant = wanted
+ return this.notOk(tsame.strict(found, wanted), message, extra)
+ }
+
+ match (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.match
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should match pattern provided'
+ extra.found = found
+ extra.pattern = wanted
+ return this.ok(tmatch(found, wanted), message, extra)
+ }
+
+ notMatch (found, wanted, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.notMatch
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ message = message || 'should not match pattern provided'
+ extra.found = found
+ extra.pattern = wanted
+ return this.ok(!tmatch(found, wanted), message, extra)
+ }
+
+ type (obj, klass, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.type
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ const name = typeof klass === 'function' ?
+ klass.name || '(anonymous constructor)'
+ : klass
+
+ message = message || 'type is ' + name
+
+ // simplest case, it literally is the same thing
+ if (obj === klass) {
+ return this.pass(message, extra)
+ }
+
+ const tof = typeof obj
+ const type = (!obj && tof === 'object') ? 'null'
+ // treat as object, but not Object
+ // t.type(() => {}, Function)
+ : (tof === 'function' &&
+ typeof klass === 'function' &&
+ klass !== Object) ? 'object'
+ : tof
+
+ if (type === 'object' && klass !== 'object') {
+ if (typeof klass === 'function') {
+ extra.found = Object.getPrototypeOf(obj).constructor.name
+ extra.wanted = name
+ return this.ok(obj instanceof klass, message, extra)
+ }
+
+ // check prototype chain for name
+ // at this point, we already know klass is not a function
+ // if the klass specified is an obj in the proto chain, pass
+ // if the name specified is the name of a ctor in the chain, pass
+ for (let p = obj; p; p = Object.getPrototypeOf(p)) {
+ const ctor = p.constructor && p.constructor.name
+ if (p === klass || ctor === name) {
+ return this.pass(message, extra)
+ }
+ }
+ }
+
+ return this.equal(type, name, message, extra)
+ }
+
+ throws (_fn, _wanted, _message, _extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.throws
+
+ let fn, wanted, message, extra
+ for (let i = 0; i < arguments.length; i++) {
+ const arg = arguments[i]
+ if (typeof arg === 'function') {
+ if (arg === Error || arg.prototype instanceof Error) {
+ wanted = arg
+ } else if (!fn) {
+ fn = arg
+ }
+ } else if (typeof arg === 'string' && arg) {
+ message = arg
+ } else if (typeof arg === 'object') {
+ if (!wanted) {
+ wanted = arg
+ } else {
+ extra = arg
+ }
+ }
+ }
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ if (!message)
+ message = fn && fn.name || 'expected to throw'
+
+ if (wanted) {
+ if (wanted instanceof Error) {
+ const w = {
+ message: wanted.message
+ }
+ if (wanted.name) {
+ w.name = wanted.name
+ }
+
+ // intentionally copying non-local properties, since this
+ // is an Error object, and those are funky.
+ for (i in wanted) {
+ w[i] = wanted[i]
+ }
+ wanted = w
+
+ message += ': ' + (wanted.name || 'Error') + ' ' + wanted.message
+ extra = extra || {}
+ if (extra !== wanted) {
+ extra.wanted = wanted
+ }
+ }
+ }
+
+ if (typeof fn !== 'function') {
+ extra = extra || {}
+ extra.todo = true
+ return this.pass(message, extra)
+ }
+
+ try {
+ fn()
+ return this.fail(message, extra)
+ } catch (er) {
+ // 'name' is a getter.
+ if (er.name) {
+ er.name = er.name + ''
+ }
+
+ if (wanted) {
+ if (Object.prototype.toString.call(wanted) === '[object RegExp]') {
+ return this.match(er.message, wanted, message, extra)
+ }
+ return this.has(er, wanted, message, extra)
+ } else {
+ return this.pass(message, extra)
+ }
+ }
+ }
+
+ doesNotThrow (fn, message, extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.doesNotThrow
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ if (typeof fn === 'string') {
+ const x = fn
+ fn = message
+ message = x
+ }
+
+ if (!message) {
+ message = fn && fn.name || 'expected to not throw'
+ }
+
+ if (typeof fn !== 'function') {
+ extra.todo = true
+ return this.pass(message, extra)
+ }
+
+ try {
+ fn()
+ return this.pass(message, extra)
+ } catch (er) {
+ const e = extraFromError(er, extra)
+ e.message = er.message
+ return this.fail(message, e)
+ }
+ }
+
+ // like throws, but rejects a returned promise instead
+ // also, can pass in a promise instead of a function
+ rejects (_fn, _wanted, _message, _extra) {
+ if (!this.currentAssert)
+ this.currentAssert = Test.prototype.rejects
+
+ let fn, wanted, extra, promise, message
+ for (let i = 0; i < arguments.length; i++) {
+ const arg = arguments[i]
+ if (typeof arg === 'function') {
+ if (arg === Error || arg.prototype instanceof Error) {
+ wanted = arg
+ } else if (!fn) {
+ fn = arg
+ }
+ } else if (typeof arg === 'string' && arg) {
+ message = arg
+ } else if (arg && typeof arg.then === 'function' && !promise) {
+ promise = arg
+ } else if (typeof arg === 'object') {
+ if (!wanted) {
+ wanted = arg
+ } else {
+ extra = arg
+ }
+ }
+ }
+
+ if (message && typeof message === 'object')
+ extra = message, message = ''
+
+ if (!extra)
+ extra = {}
+
+ if (!message)
+ message = fn && fn.name || 'expect rejected Promise'
+
+ if (wanted) {
+ if (wanted instanceof Error) {
+ const w = {
+ message: wanted.message
+ }
+ if (wanted.name) {
+ w.name = wanted.name
+ }
+
+ // intentionally copying non-local properties, since this
+ // is an Error object, and those are funky.
+ for (i in wanted) {
+ w[i] = wanted[i]
+ }
+ wanted = w
+
+ message += ': ' + (wanted.name || 'Error') + ' ' + wanted.message
+ extra = extra || {}
+ if (extra !== wanted) {
+ extra.wanted = wanted
+ }
+ }
+ }
+
+ if (!promise && typeof fn !== 'function') {
+ extra = extra || {}
+ extra.todo = true
+ return this.pass(message, extra)
+ }
+
+ if (!promise)
+ promise = fn()
+
+ if (!promise || typeof promise.then !== 'function')
+ return this.fail(message, extra)
+
+ // have to do as a subtest, because promises are async
+ extra.at = stack.at(this.currentAssert)
+ this.test(message, { buffered: true }, function (t) {
+ return promise.then(function (value) {
+ extra.found = value
+ t.fail(message, extra)
+ }, function (er) {
+ // 'name' is a getter.
+ if (er.name) {
+ er.name = er.name + ''
+ }
+
+ if (wanted) {
+ if (Object.prototype.toString.call(wanted) === '[object RegExp]') {
+ return t.match(er.message, wanted, message, extra)
+ }
+ return t.has(er, wanted, message, extra)
+ } else {
+ return t.pass(message, extra)
+ }
+ })
+ })
+ }
}
const endAllQueue = queue => {
@@ -768,7 +1231,14 @@ const queueEmpty = t =>
Test.prototype.done = Test.prototype.end
Test.prototype.tearDown = Test.prototype.teardown
-// Add all the asserts
-tapAsserts.decorate(Test.prototype)
+Object.keys(synonyms)
+ .filter(c => Test.prototype[c])
+ .forEach(c => synonyms[c].forEach(s =>
+ Object.defineProperty(Test.prototype, s, {
+ value: Test.prototype[c],
+ enumerable: false,
+ configurable: true,
+ writable: true
+ })))
module.exports = Test
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-tap.git
More information about the Pkg-javascript-commits
mailing list