[Pkg-javascript-commits] [node-tap] 64/186: add test for addAssert, support \ chars in snapshots

Bastien Roucariès rouca at moszumanska.debian.org
Fri Dec 1 16:40:44 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 5a042d063d55e87fa86c8e81652d78d628be5a92
Author: isaacs <i at izs.me>
Date:   Tue Nov 7 14:28:00 2017 +0000

    add test for addAssert, support \ chars in snapshots
---
 lib/snapshot.js                   |  9 +++-
 lib/test.js                       | 87 +++++++++++++++++----------------------
 package.json                      |  1 +
 tap-snapshots/unit-test.js-TAP.js | 42 +++++++++++++++++++
 unit/test.js                      | 32 +++++++++++++-
 5 files changed, 119 insertions(+), 52 deletions(-)

diff --git a/lib/snapshot.js b/lib/snapshot.js
index 7ce8818..1a14ce2 100644
--- a/lib/snapshot.js
+++ b/lib/snapshot.js
@@ -47,12 +47,17 @@ class Snapshot {
     if (!this.snapshot)
       rimraf.sync(this.file)
     else {
+      const escape = s => s
+        .replace(/\\/g, '\\\\')
+        .replace(/\`/g, '\\\`')
+        .replace(/\$\{/g, '\\${')
+
       const data = `'use strict'\n` + (
         Object.keys(this.snapshot).map(s =>
           `exports[\`${
-            s.replace(/\`/g, '\\\`')
+            escape(s)
           }\`] = \`\n${
-            this.snapshot[s].replace(/\`/g, '\\\`')
+            escape(this.snapshot[s])
           }\n\`\n`).join('\n'))
       mkdirp.sync(path.dirname(this.file))
       writeFile.sync(this.file, data, 'utf8')
diff --git a/lib/test.js b/lib/test.js
index 2799ace..b6512e6 100644
--- a/lib/test.js
+++ b/lib/test.js
@@ -46,6 +46,7 @@ const IMPLICIT = Symbol('implicit t.end()')
 // Sigil to put in the queue to signal the end of all things
 const EOF = Symbol('EOF')
 
+const _currentAssert = Symbol('_currentAssert')
 const _end = Symbol('_end')
 const _snapshot = Symbol('_snapshot')
 const Snapshot = require('./snapshot.js')
@@ -88,7 +89,7 @@ class Test extends Base {
       this.cb = this.domain.bind(options.cb)
 
     this.occupied = false
-    this.currentAssert = null
+    this[_currentAssert] = null
     this.count = 0
     this.n = 0
     this.ended = false
@@ -451,9 +452,7 @@ class Test extends Base {
       throw new TypeError('attempt to re-define `' + name + '` assert')
 
     function ASSERT () {
-      if (!this.currentAssert) {
-        this.currentAssert = ASSERT
-      }
+      this.currentAssert = ASSERT
       const args = new Array(length + 2)
       for (let i = 0; i < length; i++) {
         args[i] = arguments[i]
@@ -473,6 +472,10 @@ class Test extends Base {
 
   printResult (ok, message, extra, front) {
     const n = this.count + 1
+    this.currentAssert = Test.prototype.printResult
+    const fn = this[_currentAssert]
+    this[_currentAssert] = null
+
     if (this.planEnd !== -1 && n > this.planEnd) {
       if (!this.passing())
         return
@@ -482,8 +485,7 @@ class Test extends Base {
           : 'test count exceeds plan'
 
       const er = new Error(failMessage)
-      Error.captureStackTrace(er,
-        this.currentAssert || Test.prototype.printResult)
+      Error.captureStackTrace(er, fn)
       er.test = this.name
       er.plan = this.planEnd
       this.threw(er)
@@ -508,8 +510,6 @@ class Test extends Base {
     if (hasOwn(extra, 'stack') && !hasOwn(extra, 'at'))
       extra.at = stack.parseLine(extra.stack.split('\n')[0])
 
-    const fn = this.currentAssert || Test.prototype.printResult
-    this.currentAssert = null
     if (!ok && !extra.skip && !hasOwn(extra, 'at')) {
       assert.equal(typeof fn, 'function')
       extra.at = stack.at(fn)
@@ -611,7 +611,7 @@ class Test extends Base {
       if (this.explicitEnded) {
         this.multiEndThrew = true
         const er = new Error('test end() method called more than once')
-        Error.captureStackTrace(er, this.currentAssert ||
+        Error.captureStackTrace(er, this[_currentAssert] ||
           Test.prototype[_end])
         er.test = this.name
         this.threw(er)
@@ -753,9 +753,17 @@ class Test extends Base {
     this.parser.end()
   }
 
+  get currentAssert () {
+    return this[_currentAssert]
+  }
+
+  set currentAssert (fn) {
+    if (!this[_currentAssert])
+      this[_currentAssert] = fn
+  }
+
   pass (message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.pass
+    this.currentAssert = Test.prototype.pass
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -768,8 +776,7 @@ class Test extends Base {
   }
 
   fail (message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.fail
+    this.currentAssert = Test.prototype.fail
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -782,8 +789,7 @@ class Test extends Base {
   }
 
   ok (obj, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.ok
+    this.currentAssert = Test.prototype.ok
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -795,8 +801,7 @@ class Test extends Base {
   }
 
   notOk (obj, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.notOk
+    this.currentAssert = Test.prototype.notOk
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -808,8 +813,7 @@ class Test extends Base {
   }
 
   error (er, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.error
+    this.currentAssert = Test.prototype.error
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -832,8 +836,7 @@ class Test extends Base {
   }
 
   equal (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.equal
+    this.currentAssert = Test.prototype.equal
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -862,8 +865,7 @@ class Test extends Base {
   }
 
   not (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.not
+    this.currentAssert = Test.prototype.not
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -884,8 +886,7 @@ class Test extends Base {
   }
 
   same (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.same
+    this.currentAssert = Test.prototype.same
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -900,8 +901,7 @@ class Test extends Base {
   }
 
   notSame (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.notSame
+    this.currentAssert = Test.prototype.notSame
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -916,8 +916,7 @@ class Test extends Base {
   }
 
   strictSame (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.strictSame
+    this.currentAssert = Test.prototype.strictSame
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -932,8 +931,7 @@ class Test extends Base {
   }
 
   strictNotSame (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.strictNotSame
+    this.currentAssert = Test.prototype.strictNotSame
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -957,8 +955,7 @@ class Test extends Base {
   }
 
   matchSnapshot (found, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.matchSnapshot
+    this.currentAssert = Test.prototype.matchSnapshot
 
     if (message && typeof message === 'object')
       extra = message, message = 'must match snapshot'
@@ -982,8 +979,7 @@ class Test extends Base {
   }
 
   match (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.match
+    this.currentAssert = Test.prototype.match
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -998,8 +994,7 @@ class Test extends Base {
   }
 
   notMatch (found, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.notMatch
+    this.currentAssert = Test.prototype.notMatch
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -1014,8 +1009,7 @@ class Test extends Base {
   }
 
   type (obj, klass, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.type
+    this.currentAssert = Test.prototype.type
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -1066,8 +1060,7 @@ class Test extends Base {
   }
 
   throws (_fn, _wanted, _message, _extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.throws
+    this.currentAssert = Test.prototype.throws
 
     let fn, wanted, message, extra
     for (let i = 0; i < arguments.length; i++) {
@@ -1136,8 +1129,7 @@ class Test extends Base {
   }
 
   doesNotThrow (fn, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.doesNotThrow
+    this.currentAssert = Test.prototype.doesNotThrow
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -1173,8 +1165,7 @@ class Test extends Base {
   // 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
+    this.currentAssert = Test.prototype.rejects
 
     let fn, wanted, extra, promise, message
     for (let i = 0; i < arguments.length; i++) {
@@ -1262,8 +1253,7 @@ class Test extends Base {
   }
 
   resolves (promise, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.rejects
+    this.currentAssert = Test.prototype.rejects
 
     if (message && typeof message === 'object')
       extra = message, message = ''
@@ -1300,8 +1290,7 @@ class Test extends Base {
   }
 
   resolveMatch (promise, wanted, message, extra) {
-    if (!this.currentAssert)
-      this.currentAssert = Test.prototype.rejects
+    this.currentAssert = Test.prototype.rejects
 
     if (message && typeof message === 'object')
       extra = message, message = ''
diff --git a/package.json b/package.json
index e9539ac..ae67330 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
   "repository": "https://github.com/tapjs/node-tap.git",
   "scripts": {
     "regen-fixtures": "node scripts/generate-test-test.js test/test/*.js",
+    "snap": "TAP_SNAPSHOT=1 node bin/run.js unit/*.js",
     "unit": "node bin/run.js unit/*.js --100 --nyc-arg=--include=lib/*.js",
     "test": "node bin/run.js test/*.* --coverage -t3600 -sfails",
     "smoke": "node bin/run.js --node-arg=test/test.js test/test/*.js -j2",
diff --git a/tap-snapshots/unit-test.js-TAP.js b/tap-snapshots/unit-test.js-TAP.js
index 23b6385..fcdd0bc 100644
--- a/tap-snapshots/unit-test.js-TAP.js
+++ b/tap-snapshots/unit-test.js-TAP.js
@@ -1937,3 +1937,45 @@ TAP version 13
 # this is fine
 
 `
+
+exports[` TAP addAssert > using the custom isUrl assertion 1`] = `
+TAP version 13
+not ok 1 - expect a valid http/https url
+  ---
+  found:
+    protocol: null
+    slashes: null
+    auth: null
+    host: null
+    port: null
+    hostname: null
+    hash: null
+    search: null
+    query: null
+    pathname: hello%20is%20not%20a%20url
+    path: hello%20is%20not%20a%20url
+    href: hello%20is%20not%20a%20url
+  pattern:
+    protocol: '/^https?:$/'
+    slashes: true
+    host: 'function String() { [native code] }'
+    path: /^\\/.*$/
+  at:
+    line: #
+    column: #
+    file: unit/test.js
+    type: Test
+    function: t.test.t
+  stack: |
+    {STACK}
+  source: |
+    tt.isUrl('hello is not a url')
+  ...
+
+ok 2 - x is a url!
+ok 3 - expect a valid http/https url # SKIP
+1..3
+# failed 1 of 3 tests
+# skip: 1
+
+`
diff --git a/unit/test.js b/unit/test.js
index a8af382..81a278a 100644
--- a/unit/test.js
+++ b/unit/test.js
@@ -11,6 +11,8 @@ const clean = out => out
   .replace(/ # time=[0-9\.]+m?s( \{.*)?\n/g, ' # {time}$1\n')
   .replace(/\n(( {2})+)stack: \|-?\n((\1  .*).*\n)+/gm,
     '\n$1stack: |\n$1  {STACK}\n')
+  .replace(/\n(( {2})+)stack: \>-?\n((\1  .*).*\n(\1\n)?)+/gm,
+    '\n$1stack: |\n$1  {STACK}\n')
   .replace(/\n([a-zA-Z]*Error): (.*)\n((    at .*\n)*)+/gm,
     '\n$1: $2\n    {STACK}\n')
   .replace(/:[0-9]+:[0-9]+(\)?\n)/g, '#:#$1')
@@ -583,9 +585,37 @@ t.test('assertions and weird stuff', t => {
   }
 })
 
+t.test('addAssert', t => {
+  t.throws(() => t.addAssert(null), new TypeError('name is required'))
+  t.throws(() => t.addAssert('x'), new TypeError('number of args required'))
+  t.throws(() => t.addAssert('x', -1),
+           new TypeError('number of args required'))
+  t.throws(() => t.addAssert('x', 1),
+           new TypeError('function required for addAssert'))
+  t.throws(() => t.addAssert('ok', 1, () => {}),
+           new TypeError('attempt to re-define `ok` assert'))
+
+  const url = require('url')
+  const tt = new Test({ buffered: true })
+  tt.addAssert('isUrl', 1, function isUrl (u, message, extra) {
+    return this.match(url.parse(u), {
+      protocol: /^https?:$/,
+      slashes: true,
+      host: String,
+      path: /^\/.*$/
+    }, message || 'expect a valid http/https url', extra)
+  })
+  tt.isUrl('hello is not a url')
+  tt.isUrl('http://x', 'x is a url!')
+  tt.isUrl('https://skip:420/', { skip: 420 })
+  tt.end()
+
+  t.matchSnapshot(clean(tt.output), 'using the custom isUrl assertion')
+  return t.end()
+})
+
 t.test('autoEnd')
 t.test('endAll')
-t.test('addAssert')
 t.test('snapshots')
 t.test('spawn')
 t.test('stdin')

-- 
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