[Pkg-javascript-commits] [node-tap] 15/19: Bundle modules from tapjs as patches
Jérémy Lal
kapouer at moszumanska.debian.org
Sat Nov 12 01:03:57 UTC 2016
This is an automated email from the git hooks/post-receive script.
kapouer pushed a commit to branch master
in repository node-tap.
commit d8526e291e61297843d6d5f017c6fb6fba9c44b7
Author: Jérémy Lal <kapouer at melix.org>
Date: Sat Nov 12 01:36:41 2016 +0100
Bundle modules from tapjs as patches
---
debian/control | 17 +-
debian/copyright | 59 +-
debian/install | 3 +-
debian/links | 3 +-
debian/nodemodules/foreground-child.js | 80 -
debian/patches/module-buffer-to-string.patch | 21 +
debian/patches/module-clean-yaml-object.patch | 93 +
debian/patches/module-foreground-child.patch | 88 +
debian/patches/module-stack-utils.patch | 287 ++
debian/patches/module-tap-mocha-reporter.patch | 3598 ++++++++++++++++++++++++
debian/patches/sbuild_disable_tests.patch | 12 +-
debian/patches/series | 7 +-
debian/patches/use_available_modules.patch | 173 +-
debian/rules | 15 +-
14 files changed, 4306 insertions(+), 150 deletions(-)
diff --git a/debian/control b/debian/control
index c35eac3..99be413 100644
--- a/debian/control
+++ b/debian/control
@@ -9,11 +9,13 @@ Build-Depends:
, help2man
, node-glob
, node-nopt
- , node-yamlish
+ , node-js-yaml
, node-mkdirp
, node-slide
, node-inherits
, node-diff
+ , node-signal-exit
+ , node-deep-equal
, nodejs
Standards-Version: 3.9.8
Homepage: https://github.com/isaacs/node-tap
@@ -26,14 +28,23 @@ Depends:
${misc:Depends}
, nodejs
, node-glob
+ , node-escape-string-regexp
+ , node-debug
, node-nopt
- , node-yamlish
+ , node-js-yaml
, node-mkdirp
, node-slide
, node-inherits
+ , node-signal-exit
+ , node-supports-color
+ , node-strip-ansi
+ , node-deep-equal
, node-diff
+ , node-tmatch
+ , node-tap-parser
Suggests:
- node-runforcover
+ node-coveralls
+ , node-nyc
Description: Test-Anything-Protocol module for Node.js
Utilities for writing test harnesses complying with TAP output format.
.
diff --git a/debian/copyright b/debian/copyright
index ea0e25b..fd26939 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -7,11 +7,45 @@ Files: *
Copyright: 2014 Isaac Z. Schlueter and Contributors
License: ISC
-Files: debian/node_modules/foreground-child.js
+Files: node_modules/module-foreground-child.js
Copyright: 2015 Isaac Z. Schlueter and Contributors
License: ISC
Source: https://github.com/tapjs/foreground-child/releases/tag/v1.5.3
-Comment: Bundled because too related to node-tap
+Comment: Bundled because tied to this package, limited interest outside of it
+
+Files: node_modules/tap-mocha-reporter/*
+Copyright: 2014 Isaac Z. Schlueter and Contributors
+License: ISC
+Source: https://github.com/tapjs/tap-mocha-reporter/releases/tag/v3.0.0
+Comment: Bundled because tied to this package, limited interest outside of it
+
+Files: node_modules/mocha-tap-reporter/reporters/*
+Copyright: 2011-2015 TJ Holowaychuk <tj at vision-media.ca>
+License: Expat
+
+Files: node_modules/stack-utils.js
+Copyright: Isaac Z. Schlueter <i at izs.me>
+ James Talmage <james at talmage.io> (github.com/jamestalmage)
+ and Contributors
+License: Expat
+Source: https://github.com/tapjs/stack-utils/releases/tag/v0.4.0
+Comment: Bundled because tied to this package, limited interest outside of it
+
+Files: node_modules/clean-yaml-object.js
+Copyright: Isaac Z. Schlueter <i at izs.me>
+ James Talmage <james at talmage.io> (github.com/jamestalmage)
+ and Contributors
+License: Expat
+Source: https://github.com/tapjs/clean-yaml-object/releases/tag/v0.1.0
+Comment: Bundled because tied to this package, limited interest outside of it
+
+Files: node_modules/buffer-to-string.js
+Copyright: Isaac Z. Schlueter <i at izs.me>
+ James Talmage <james at talmage.io> (github.com/jamestalmage)
+ and Contributors
+License: Expat
+Source: https://github.com/tapjs/buffer-to-string/releases/tag/v0.1.0
+Comment: Bundled because tied to this package, limited interest outside of it
Files: debian/*
Copyright: 2014 Jérémy Lal <kapouer at melix.org>
@@ -30,3 +64,24 @@ License: ISC
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+License: Expat
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
diff --git a/debian/install b/debian/install
index 7763890..ae3303b 100644
--- a/debian/install
+++ b/debian/install
@@ -1,3 +1,4 @@
package.json usr/lib/nodejs/tap/
-bin usr/lib/nodejs/tap/
+bin/run.js usr/lib/nodejs/tap/bin/run.js
lib usr/lib/nodejs/tap/
+node_modules usr/lib/nodejs/tap/
diff --git a/debian/links b/debian/links
index ea0f573..dc74c82 100644
--- a/debian/links
+++ b/debian/links
@@ -1,2 +1 @@
-usr/lib/nodejs/tap/bin/tap.js usr/bin/tap
-debian/nodemodules usr/lib/nodejs/tap/node_modules
+usr/lib/nodejs/tap/bin/run.js usr/bin/tap
diff --git a/debian/nodemodules/foreground-child.js b/debian/nodemodules/foreground-child.js
deleted file mode 100644
index aa48c6f..0000000
--- a/debian/nodemodules/foreground-child.js
+++ /dev/null
@@ -1,80 +0,0 @@
-var signalExit = require('signal-exit')
-var spawn = require('child_process').spawn
-if (process.platform === 'win32') {
- spawn = require('cross-spawn')
-}
-
-module.exports = function (program, args, cb) {
- var arrayIndex = arguments.length
-
- if (typeof args === 'function') {
- cb = args
- args = undefined
- } else {
- cb = Array.prototype.slice.call(arguments).filter(function (arg, i) {
- if (typeof arg === 'function') {
- arrayIndex = i
- return true
- }
- })[0]
- }
-
- cb = cb || function (done) {
- return done()
- }
-
- if (Array.isArray(program)) {
- args = program.slice(1)
- program = program[0]
- } else if (!Array.isArray(args)) {
- args = [].slice.call(arguments, 1, arrayIndex)
- }
-
- var spawnOpts = { stdio: [0, 1, 2] }
-
- if (process.send) {
- spawnOpts.stdio.push('ipc')
- }
-
- var child = spawn(program, args, spawnOpts)
-
- var childExited = false
- signalExit(function (code, signal) {
- child.kill(signal || 'SIGHUP')
- })
-
- child.on('close', function (code, signal) {
- // Allow the callback to inspect the child’s exit code and/or modify it.
- process.exitCode = signal ? 128 + signal : code
-
- cb(function () {
- childExited = true
- if (signal) {
- // If there is nothing else keeping the event loop alive,
- // then there's a race between a graceful exit and getting
- // the signal to this process. Put this timeout here to
- // make sure we're still alive to get the signal, and thus
- // exit with the intended signal code.
- setTimeout(function () {}, 200)
- process.kill(process.pid, signal)
- } else {
- // Equivalent to process.exit() on Node.js >= 0.11.8
- process.exit(process.exitCode)
- }
- })
- })
-
- if (process.send) {
- process.removeAllListeners('message')
-
- child.on('message', function (message, sendHandle) {
- process.send(message, sendHandle)
- })
-
- process.on('message', function (message, sendHandle) {
- child.send(message, sendHandle)
- })
- }
-
- return child
-}
diff --git a/debian/patches/module-buffer-to-string.patch b/debian/patches/module-buffer-to-string.patch
new file mode 100644
index 0000000..a101c1e
--- /dev/null
+++ b/debian/patches/module-buffer-to-string.patch
@@ -0,0 +1,21 @@
+--- /dev/null
++++ b/node_modules/buffer-to-string.js
+@@ -0,0 +1,18 @@
++'use strict';
++module.exports = function (buffer, limit) {
++ limit = limit || 20;
++ return buffer.toString('hex').split('')
++ .reduce(function (arr, char) {
++ if (arr.length && arr[arr.length - 1].length === 1) {
++ arr[arr.length - 1] += char;
++ if (arr.length && arr.length % limit === 0) {
++ arr[arr.length - 1] += '\n';
++ } else {
++ arr[arr.length - 1] += ' ';
++ }
++ } else {
++ arr.push(char);
++ }
++ return arr;
++ }, []).join('').trim();
++};
diff --git a/debian/patches/module-clean-yaml-object.patch b/debian/patches/module-clean-yaml-object.patch
new file mode 100644
index 0000000..20b54f9
--- /dev/null
+++ b/debian/patches/module-clean-yaml-object.patch
@@ -0,0 +1,93 @@
+--- /dev/null
++++ b/node_modules/clean-yaml-object.js
+@@ -0,0 +1,90 @@
++'use strict';
++var bufferToString = require('buffer-to-string');
++
++module.exports = function (object, filterFn) {
++ return cleanYamlObj(object, filterFn || defaultFilter, true, []);
++};
++
++function cleanYamlObj(object, filter, isRoot, seen) {
++ if (object === undefined) {
++ return null;
++ }
++
++ if (typeof object === 'function') {
++ return object.toString();
++ }
++
++ if (Buffer.isBuffer(object)) {
++ return 'Buffer\n' + bufferToString(object);
++ }
++
++ if (object && typeof object === 'object') {
++ if (object instanceof RegExp) {
++ return object.toString();
++ }
++
++ seen = seen.concat([object]);
++
++ var isArray = Array.isArray(object);
++
++ // Fill in any holes. This means we lose expandos,
++ // but we were gonna lose those anyway.
++ if (isArray) {
++ object = fillHoles(object);
++ }
++
++ var isError = object && typeof object === 'object' && object instanceof Error;
++
++ var set = isArray ? [] : {};
++
++ // name is typically not an ownProperty on an Error
++ if (isError && object.name && !{}.hasOwnProperty.call(object, 'name') && filter('name', isRoot, object, set)) {
++ setProp('name', object, set, seen, filter);
++ }
++
++ var keys = Object.getOwnPropertyNames(object);
++ return keys.reduce(function (set, k) {
++ // magic property!
++ if (isArray && k === 'length') {
++ return set;
++ }
++
++ // Don't dump massive EventEmitter and Domain
++ // objects onto the output, that's never friendly.
++ if (isError && /^domain/.test(k)) {
++ return set;
++ }
++
++ if (!filter(k, isRoot, object, set)) {
++ return set;
++ }
++
++ setProp(k, object, set, seen, filter);
++
++ return set;
++ }, set);
++ }
++
++ return object;
++}
++
++function setProp(propName, source, target, seen, filter) {
++ if (seen.indexOf(source[propName]) === -1) {
++ target[propName] = cleanYamlObj(source[propName], filter, false, seen);
++ } else {
++ target[propName] = '[Circular]';
++ }
++}
++
++function defaultFilter() {
++ return true;
++}
++
++function fillHoles(arr) {
++ var result = [];
++ for (var i = 0; i < arr.length; i++) {
++ result[i] = arr[i];
++ }
++ return result;
++}
++
diff --git a/debian/patches/module-foreground-child.patch b/debian/patches/module-foreground-child.patch
new file mode 100644
index 0000000..63ec5bd
--- /dev/null
+++ b/debian/patches/module-foreground-child.patch
@@ -0,0 +1,88 @@
+Description: module foreground-child
+ see copyright for more information
+Last-Update: 2016-11-11
+Forwarded: not-needed
+Author: Jérémy Lal <kapouer at melix.org>
+--- /dev/null
++++ b/node_modules/foreground-child.js
+@@ -0,0 +1,80 @@
++var signalExit = require('signal-exit')
++var spawn = require('child_process').spawn
++if (process.platform === 'win32') {
++ spawn = require('cross-spawn')
++}
++
++module.exports = function (program, args, cb) {
++ var arrayIndex = arguments.length
++
++ if (typeof args === 'function') {
++ cb = args
++ args = undefined
++ } else {
++ cb = Array.prototype.slice.call(arguments).filter(function (arg, i) {
++ if (typeof arg === 'function') {
++ arrayIndex = i
++ return true
++ }
++ })[0]
++ }
++
++ cb = cb || function (done) {
++ return done()
++ }
++
++ if (Array.isArray(program)) {
++ args = program.slice(1)
++ program = program[0]
++ } else if (!Array.isArray(args)) {
++ args = [].slice.call(arguments, 1, arrayIndex)
++ }
++
++ var spawnOpts = { stdio: [0, 1, 2] }
++
++ if (process.send) {
++ spawnOpts.stdio.push('ipc')
++ }
++
++ var child = spawn(program, args, spawnOpts)
++
++ var childExited = false
++ signalExit(function (code, signal) {
++ child.kill(signal || 'SIGHUP')
++ })
++
++ child.on('close', function (code, signal) {
++ // Allow the callback to inspect the child’s exit code and/or modify it.
++ process.exitCode = signal ? 128 + signal : code
++
++ cb(function () {
++ childExited = true
++ if (signal) {
++ // If there is nothing else keeping the event loop alive,
++ // then there's a race between a graceful exit and getting
++ // the signal to this process. Put this timeout here to
++ // make sure we're still alive to get the signal, and thus
++ // exit with the intended signal code.
++ setTimeout(function () {}, 200)
++ process.kill(process.pid, signal)
++ } else {
++ // Equivalent to process.exit() on Node.js >= 0.11.8
++ process.exit(process.exitCode)
++ }
++ })
++ })
++
++ if (process.send) {
++ process.removeAllListeners('message')
++
++ child.on('message', function (message, sendHandle) {
++ process.send(message, sendHandle)
++ })
++
++ process.on('message', function (message, sendHandle) {
++ child.send(message, sendHandle)
++ })
++ }
++
++ return child
++}
diff --git a/debian/patches/module-stack-utils.patch b/debian/patches/module-stack-utils.patch
new file mode 100644
index 0000000..87d1c89
--- /dev/null
+++ b/debian/patches/module-stack-utils.patch
@@ -0,0 +1,287 @@
+--- /dev/null
++++ b/node_modules/stack-utils.js
+@@ -0,0 +1,284 @@
++module.exports = StackUtils;
++
++function StackUtils(opts) {
++ if (!(this instanceof StackUtils)) {
++ throw new Error('StackUtils constructor must be called with new');
++ }
++ opts = opts || {};
++ this._cwd = (opts.cwd || process.cwd()).replace(/\\/g, '/');
++ this._internals = opts.internals || [];
++}
++
++module.exports.nodeInternals = nodeInternals;
++
++function nodeInternals() {
++ return [
++ /\(native\)$/,
++ /\(domain.js:\d+:\d+\)$/,
++ /\(events.js:\d+:\d+\)$/,
++ /\(node.js:\d+:\d+\)$/,
++ /\(timers.js:\d+:\d+\)$/,
++ /\(module.js:\d+:\d+\)$/,
++ /\(internal\/[\w_-]+\.js:\d+:\d+\)$/,
++ /\s*at node\.js:\d+:\d+?$/,
++ /\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/
++ ];
++}
++
++StackUtils.prototype.clean = function (stack) {
++ if (!Array.isArray(stack)) {
++ stack = stack.split('\n');
++ }
++
++ if (!(/^\s*at /.test(stack[0])) &&
++ (/^\s*at /.test(stack[1]))) {
++ stack = stack.slice(1);
++ }
++
++ var outdent = false;
++ var lastNonAtLine = null;
++ var result = [];
++
++ stack.forEach(function (st) {
++ st = st.replace(/\\/g, '/');
++ var isInternal = this._internals.some(function (internal) {
++ return internal.test(st);
++ });
++
++ if (isInternal) {
++ return null;
++ }
++
++ var isAtLine = /^\s*at /.test(st);
++
++ if (outdent) {
++ st = st.replace(/\s+$/, '').replace(/^(\s+)at /, '$1');
++ } else {
++ st = st.trim();
++ if (isAtLine) {
++ st = st.substring(3);
++ }
++ }
++
++ st = st.replace(this._cwd + '/', '');
++
++ if (st) {
++ if (isAtLine) {
++ if (lastNonAtLine) {
++ result.push(lastNonAtLine);
++ lastNonAtLine = null;
++ }
++ result.push(st);
++ } else {
++ outdent = true;
++ lastNonAtLine = st;
++ }
++ }
++ }, this);
++
++ stack = result.join('\n').trim();
++
++ if (stack) {
++ return stack + '\n';
++ }
++ return '';
++};
++
++StackUtils.prototype.captureString = function (limit, fn) {
++ if (typeof limit === 'function') {
++ fn = limit;
++ limit = Infinity;
++ }
++ if (!fn) {
++ fn = this.captureString;
++ }
++
++ var limitBefore = Error.stackTraceLimit;
++ if (limit) {
++ Error.stackTraceLimit = limit;
++ }
++
++ var obj = {};
++
++ Error.captureStackTrace(obj, fn);
++ var stack = obj.stack;
++ Error.stackTraceLimit = limitBefore;
++
++ return this.clean(stack);
++};
++
++StackUtils.prototype.capture = function (limit, fn) {
++ if (typeof limit === 'function') {
++ fn = limit;
++ limit = Infinity;
++ }
++ if (!fn) {
++ fn = this.capture;
++ }
++ var prepBefore = Error.prepareStackTrace;
++ var limitBefore = Error.stackTraceLimit;
++
++ Error.prepareStackTrace = function (obj, site) {
++ return site;
++ };
++
++ if (limit) {
++ Error.stackTraceLimit = limit;
++ }
++
++ var obj = {};
++ Error.captureStackTrace(obj, fn);
++ var stack = obj.stack;
++ Error.prepareStackTrace = prepBefore;
++ Error.stackTraceLimit = limitBefore;
++
++ return stack;
++};
++
++StackUtils.prototype.at = function at(fn) {
++ if (!fn) {
++ fn = at;
++ }
++
++ var site = this.capture(1, fn)[0];
++
++ if (!site) {
++ return {};
++ }
++
++ var res = {
++ line: site.getLineNumber(),
++ column: site.getColumnNumber()
++ };
++
++ this._setFile(res, site.getFileName());
++
++ if (site.isConstructor()) {
++ res.constructor = true;
++ }
++
++ if (site.isEval()) {
++ res.evalOrigin = site.getEvalOrigin();
++ }
++
++ if (site.isNative()) {
++ res.native = true;
++ }
++
++ var typename = null;
++ try {
++ typename = site.getTypeName();
++ } catch (er) {}
++
++ if (typename &&
++ typename !== 'Object' &&
++ typename !== '[object Object]') {
++ res.type = typename;
++ }
++
++ var fname = site.getFunctionName();
++ if (fname) {
++ res.function = fname;
++ }
++
++ var meth = site.getMethodName();
++ if (meth && fname !== meth) {
++ res.method = meth;
++ }
++
++ return res;
++};
++
++StackUtils.prototype._setFile = function (result, filename) {
++ if (filename) {
++ filename = filename.replace(/\\/g, '/');
++ if ((filename.indexOf(this._cwd + '/') === 0)) {
++ filename = filename.substr(this._cwd.length + 1);
++ }
++ result.file = filename;
++ }
++};
++
++var re = new RegExp(
++ '^' +
++ // Sometimes we strip out the ' at' because it's noisy
++ '(?:\\s*at )?' +
++ // $1 = ctor if 'new'
++ '(?:(new) )?' +
++ // Object.method [as foo] (, maybe
++ // $2 = function name
++ // $3 = method name
++ '(?:([^\\(\\[]*)(?: \\[as ([^\\]]+)\\])? \\()?' +
++ // (eval at <anonymous> (file.js:1:1),
++ // $4 = eval origin
++ // $5:$6:$7 are eval file/line/col, but not normally reported
++ '(?:eval at ([^ ]+) \\(([^\\)]+):(\\d+):(\\d+)\\), )?' +
++ // file:line:col
++ // $8:$9:$10
++ // $11 = 'native' if native
++ '(?:([^\\)]+):(\\d+):(\\d+)|(native))' +
++ // maybe close the paren, then end
++ '\\)?$'
++);
++
++StackUtils.prototype.parseLine = function parseLine(line) {
++ var match = line && line.match(re);
++ if (!match) {
++ return null;
++ }
++
++ var ctor = match[1] === 'new';
++ var fname = match[2];
++ var meth = match[3];
++ var evalOrigin = match[4];
++ var evalFile = match[5];
++ var evalLine = Number(match[6]);
++ var evalCol = Number(match[7]);
++ var file = match[8];
++ var lnum = match[9];
++ var col = match[10];
++ var native = match[11] === 'native';
++
++ var res = {};
++
++ if (lnum) {
++ res.line = Number(lnum);
++ }
++
++ if (col) {
++ res.column = Number(col);
++ }
++
++ this._setFile(res, file);
++
++ if (ctor) {
++ res.constructor = true;
++ }
++
++ if (evalOrigin) {
++ res.evalOrigin = evalOrigin;
++ res.evalLine = evalLine;
++ res.evalColumn = evalCol;
++ res.evalFile = evalFile && evalFile.replace(/\\/g, '/');
++ }
++
++ if (native) {
++ res.native = true;
++ }
++
++ if (fname) {
++ res.function = fname;
++ }
++
++ if (meth && fname !== meth) {
++ res.method = meth;
++ }
++
++ return res;
++};
++
++var bound = new StackUtils();
++
++Object.keys(StackUtils.prototype).forEach(function (key) {
++ StackUtils[key] = bound[key].bind(bound);
++});
diff --git a/debian/patches/module-tap-mocha-reporter.patch b/debian/patches/module-tap-mocha-reporter.patch
new file mode 100644
index 0000000..38206fe
--- /dev/null
+++ b/debian/patches/module-tap-mocha-reporter.patch
@@ -0,0 +1,3598 @@
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/formatter.js
+@@ -0,0 +1,87 @@
++// A formatter is a Duplex stream that TAP data is written into,
++// and then something else (presumably not-TAP) is read from.
++//
++// See tap-classic.js for an example of a formatter in use.
++
++var Duplex = require('stream').Duplex
++if (!Duplex) {
++ try {
++ Duplex = require('readable-stream').Duplex
++ } catch (er) {
++ throw new Error('Please install "readable-stream" to use this module ' +
++ 'with Node.js v0.8 and before')
++ }
++}
++
++var util = require('util')
++var Parser = require('tap-parser')
++util.inherits(Formatter, Duplex)
++module.exports = Formatter
++
++function Formatter(options, parser, parent) {
++ if (!(this instanceof Formatter))
++ return new Formatter(options, parser, parent)
++
++ if (!parser)
++ parser = new Parser()
++
++ Duplex.call(this, options)
++ this.child = null
++ this.parent = parent || null
++ this.level = parser.level
++ this.parser = parser
++
++ attachEvents(this, parser, options)
++
++ if (options.init)
++ options.init.call(this)
++}
++
++function attachEvents (self, parser, options) {
++ var events = [
++ 'version', 'plan', 'assert', 'comment',
++ 'complete', 'extra', 'bailout'
++ ]
++
++ parser.on('child', function (childparser) {
++ self.child = new Formatter(options, childparser, self)
++ if (options.child)
++ options.child.call(self, self.child)
++ })
++
++ events.forEach(function (ev) {
++ if (typeof options[ev] === 'function')
++ parser.on(ev, options[ev].bind(self))
++ })
++
++ // proxy all stream events directly
++ var streamEvents = [
++ 'pipe', 'prefinish', 'finish', 'unpipe', 'close'
++ ]
++
++ streamEvents.forEach(function (ev) {
++ parser.on(ev, function () {
++ var args = [ev]
++ args.push.apply(args, arguments)
++ self.emit.apply(self, args)
++ })
++ })
++}
++
++Formatter.prototype.write = function (c, e, cb) {
++ return this.parser.write(c, e, cb)
++}
++
++Formatter.prototype.end = function (c, e, cb) {
++ return this.parser.end(c, e, cb)
++}
++
++Formatter.prototype._read = function () {}
++
++// child formatters always push data to the root obj
++Formatter.prototype.push = function (c) {
++ if (this.parent)
++ return this.parent.push(c)
++
++ Duplex.prototype.push.call(this, c)
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/ms.js
+@@ -0,0 +1,109 @@
++/**
++ * Helpers.
++ */
++
++var s = 1000;
++var m = s * 60;
++var h = m * 60;
++var d = h * 24;
++var y = d * 365.25;
++
++/**
++ * Parse or format the given `val`.
++ *
++ * Options:
++ *
++ * - `long` verbose formatting [false]
++ *
++ * @param {String|Number} val
++ * @param {Object} options
++ * @return {String|Number}
++ * @api public
++ */
++
++module.exports = function(val, options){
++ options = options || {};
++ if ('string' == typeof val) return parse(val);
++ return options['long'] ? longFormat(val) : shortFormat(val);
++};
++
++/**
++ * Parse the given `str` and return milliseconds.
++ *
++ * @param {String} str
++ * @return {Number}
++ * @api private
++ */
++
++function parse(str) {
++ var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
++ if (!match) return;
++ var n = parseFloat(match[1]);
++ var type = (match[2] || 'ms').toLowerCase();
++ switch (type) {
++ case 'years':
++ case 'year':
++ case 'y':
++ return n * y;
++ case 'days':
++ case 'day':
++ case 'd':
++ return n * d;
++ case 'hours':
++ case 'hour':
++ case 'h':
++ return n * h;
++ case 'minutes':
++ case 'minute':
++ case 'm':
++ return n * m;
++ case 'seconds':
++ case 'second':
++ case 's':
++ return n * s;
++ case 'ms':
++ return n;
++ }
++}
++
++/**
++ * Short format for `ms`.
++ *
++ * @param {Number} ms
++ * @return {String}
++ * @api private
++ */
++
++function shortFormat(ms) {
++ if (ms >= d) return Math.round(ms / d) + 'd';
++ if (ms >= h) return Math.round(ms / h) + 'h';
++ if (ms >= m) return Math.round(ms / m) + 'm';
++ if (ms >= s) return Math.round(ms / s) + 's';
++ return ms + 'ms';
++}
++
++/**
++ * Long format for `ms`.
++ *
++ * @param {Number} ms
++ * @return {String}
++ * @api private
++ */
++
++function longFormat(ms) {
++ return plural(ms, d, 'day')
++ || plural(ms, h, 'hour')
++ || plural(ms, m, 'minute')
++ || plural(ms, s, 'second')
++ || ms + ' ms';
++}
++
++/**
++ * Pluralization helper.
++ */
++
++function plural(ms, n, name) {
++ if (ms < n) return;
++ if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
++ return Math.ceil(ms / n) + ' ' + name + 's';
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/base.js
+@@ -0,0 +1,463 @@
++/**
++ * Module dependencies.
++ */
++
++var tty = require('tty')
++ , diff = require('diff')
++ , ms = require('../ms')
++ , utils = require('../utils')
++ , supportsColor = require('color-support')()
++
++/**
++ * Save timer references to avoid Sinon interfering (see GH-237).
++ */
++
++var Date = global.Date
++ , setTimeout = global.setTimeout
++ , setInterval = global.setInterval
++ , clearTimeout = global.clearTimeout
++ , clearInterval = global.clearInterval;
++
++/**
++ * Check if both stdio streams are associated with a tty.
++ */
++
++var isatty = tty.isatty(1);
++
++/**
++ * Expose `Base`.
++ */
++
++exports = module.exports = Base;
++
++/**
++ * Enable coloring by default, except in the browser interface.
++ */
++
++exports.useColors = process.env
++ ? (supportsColor || (process.env.TAP_COLORS !== undefined))
++ : false;
++
++if (exports.useColors && +process.env.TAP_COLORS === 0)
++ exports.useColors = false
++
++/**
++ * Inline diffs instead of +/-
++ */
++
++exports.inlineDiffs = false;
++
++/**
++ * Default color map.
++ */
++
++exports.colors = {
++ 'pass': 90
++ , 'fail': 31
++ , 'bright pass': 92
++ , 'bright fail': 91
++ , 'bright yellow': 93
++ , 'pending': 35
++ , 'skip': 36
++ , 'suite': 0
++ , 'error title': 0
++ , 'error message': 31
++ , 'error stack': 90
++ , 'checkmark': 32
++ , 'fast': 90
++ , 'medium': 33
++ , 'slow': 31
++ , 'green': 32
++ , 'light': 90
++ , 'diff gutter': 90
++ , 'diff added': 42
++ , 'diff removed': 41
++};
++
++/**
++ * Default symbol map.
++ */
++
++exports.symbols = {
++ ok: '✓',
++ err: '✖',
++ dot: '․'
++};
++
++// With node.js on Windows: use symbols available in terminal default fonts
++if ('win32' == process.platform) {
++ exports.symbols.ok = '\u221A';
++ exports.symbols.err = '\u00D7';
++ exports.symbols.dot = '.';
++}
++
++/**
++ * Color `str` with the given `type`,
++ * allowing colors to be disabled,
++ * as well as user-defined color
++ * schemes.
++ *
++ * @param {String} type
++ * @param {String} str
++ * @return {String}
++ * @api private
++ */
++
++var color = exports.color = function(type, str) {
++ if (!exports.useColors) return String(str);
++ return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
++};
++
++/**
++ * Expose term window size, with some
++ * defaults for when stderr is not a tty.
++ */
++
++exports.window = {
++ width: isatty
++ ? process.stdout.getWindowSize
++ ? process.stdout.getWindowSize(1)[0]
++ : tty.getWindowSize()[1]
++ : 75
++};
++
++/**
++ * Expose some basic cursor interactions
++ * that are common among reporters.
++ */
++
++exports.cursor = {
++ hide: function(){
++ isatty && process.stdout.write('\u001b[?25l');
++ },
++
++ show: function(){
++ isatty && process.stdout.write('\u001b[?25h');
++ },
++
++ deleteLine: function(){
++ isatty && process.stdout.write('\u001b[2K');
++ },
++
++ beginningOfLine: function(){
++ isatty && process.stdout.write('\u001b[0G');
++ },
++
++ CR: function(){
++ if (isatty) {
++ exports.cursor.deleteLine();
++ exports.cursor.beginningOfLine();
++ } else {
++ process.stdout.write('\r');
++ }
++ }
++};
++
++/**
++ * Outut the given `failures` as a list.
++ *
++ * @param {Array} failures
++ * @api public
++ */
++
++exports.list = function(failures){
++ console.log();
++ failures.forEach(function(test, i){
++ // format
++ var fmt = color('error title', ' %s) %s:\n')
++ + color('error message', ' %s')
++ + color('error stack', '\n%s\n');
++
++ // msg
++ var err = test.err
++ , message = err.message || ''
++ , stack = err.stack || message
++
++ var index = stack.indexOf(message) + message.length
++ , msg = stack.slice(0, index)
++ , actual = err.actual
++ , expected = err.expected
++ , escape = true;
++
++
++ // uncaught
++ if (err.uncaught) {
++ msg = 'Uncaught ' + msg;
++ }
++ // explicitly show diff
++ if (err.showDiff && sameType(actual, expected)) {
++
++ if ('string' !== typeof actual) {
++ escape = false;
++ err.actual = actual = utils.stringify(actual);
++ err.expected = expected = utils.stringify(expected);
++ }
++
++ fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
++ var match = message.match(/^([^:]+): expected/);
++ msg = '\n ' + color('error message', match ? match[1] : msg);
++
++ if (exports.inlineDiffs) {
++ msg += inlineDiff(err, escape);
++ } else {
++ msg += unifiedDiff(err, escape);
++ }
++ }
++
++ // indent stack trace without msg
++ stack = utils.stackTraceFilter()(stack.slice(index ? index + 1 : index)
++ .replace(/^/gm, ' '));
++
++ console.log(fmt, (i + 1), test.fullTitle(), msg, stack);
++ });
++};
++
++/**
++ * Initialize a new `Base` reporter.
++ *
++ * All other reporters generally
++ * inherit from this reporter, providing
++ * stats such as test duration, number
++ * of tests passed / failed etc.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Base(runner) {
++ var self = this
++ , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
++ , failures = this.failures = [];
++
++ if (!runner) return;
++ this.runner = runner;
++
++ runner.stats = stats;
++
++ runner.on('start', function(){
++ stats.start = new Date;
++ });
++
++ runner.on('suite', function(suite){
++ stats.suites = stats.suites || 0;
++ suite.root || stats.suites++;
++ });
++
++ runner.on('test end', function(test){
++ stats.tests = stats.tests || 0;
++ stats.tests++;
++ });
++
++ runner.on('pass', function(test){
++ stats.passes = stats.passes || 0;
++
++ var medium = test.slow() / 2;
++ test.speed = test.duration > test.slow()
++ ? 'slow'
++ : test.duration > medium
++ ? 'medium'
++ : 'fast';
++
++ stats.passes++;
++ });
++
++ runner.on('fail', function(test, err){
++ stats.failures = stats.failures || 0;
++ stats.failures++;
++ test.err = err;
++ failures.push(test);
++ });
++
++ runner.on('end', function(){
++ stats.end = new Date;
++ if (!stats.duration)
++ stats.duration = stats.end - stats.start;
++ });
++
++ runner.on('pending', function(){
++ stats.pending++;
++ });
++}
++
++/**
++ * Output common epilogue used by many of
++ * the bundled reporters.
++ *
++ * @api public
++ */
++
++Base.prototype.epilogue = function(){
++ var stats = this.stats;
++ var tests;
++ var fmt;
++
++ console.log();
++
++ // passes
++ fmt = color('bright pass', ' ')
++ + color('green', ' %d passing')
++ + color('light', ' (%s)');
++
++ console.log(fmt,
++ stats.passes || 0,
++ ms(stats.duration));
++
++ // pending
++ if (stats.pending) {
++ fmt = color('pending', ' ')
++ + color('pending', ' %d pending');
++
++ console.log(fmt, stats.pending);
++ }
++
++ // failures
++ if (stats.failures) {
++ fmt = color('fail', ' %d failing');
++
++ console.log(fmt, stats.failures);
++
++ Base.list(this.failures);
++ }
++};
++
++/**
++ * Pad the given `str` to `len`.
++ *
++ * @param {String} str
++ * @param {String} len
++ * @return {String}
++ * @api private
++ */
++
++function pad(str, len) {
++ str = String(str);
++ return Array(len - str.length + 1).join(' ') + str;
++}
++
++
++/**
++ * Returns an inline diff between 2 strings with coloured ANSI output
++ *
++ * @param {Error} Error with actual/expected
++ * @return {String} Diff
++ * @api private
++ */
++
++function inlineDiff(err, escape) {
++ var msg = errorDiff(err, 'WordsWithSpace', escape);
++
++ // linenos
++ var lines = msg.split('\n');
++ if (lines.length > 4) {
++ var width = String(lines.length).length;
++ msg = lines.map(function(str, i){
++ return pad(++i, width) + ' |' + ' ' + str;
++ }).join('\n');
++ }
++
++ // legend
++ msg = '\n'
++ + color('diff removed', 'actual')
++ + ' '
++ + color('diff added', 'expected')
++ + '\n\n'
++ + msg
++ + '\n';
++
++ // indent
++ msg = msg.replace(/^/gm, ' ');
++ return msg;
++}
++
++/**
++ * Returns a unified diff between 2 strings
++ *
++ * @param {Error} Error with actual/expected
++ * @return {String} Diff
++ * @api private
++ */
++
++function unifiedDiff(err, escape) {
++ var indent = ' ';
++ function cleanUp(line) {
++ if (escape) {
++ line = escapeInvisibles(line);
++ }
++ if (line[0] === '+') return indent + colorLines('diff added', line);
++ if (line[0] === '-') return indent + colorLines('diff removed', line);
++ if (line.match(/\@\@/)) return null;
++ if (line.match(/\\ No newline/)) return null;
++ else return indent + line;
++ }
++ function notBlank(line) {
++ return line != null;
++ }
++ var msg = diff.createPatch('string', err.actual, err.expected);
++ var lines = msg.split('\n').splice(4);
++ return '\n '
++ + colorLines('diff added', '+ expected') + ' '
++ + colorLines('diff removed', '- actual')
++ + '\n\n'
++ + lines.map(cleanUp).filter(notBlank).join('\n');
++}
++
++/**
++ * Return a character diff for `err`.
++ *
++ * @param {Error} err
++ * @return {String}
++ * @api private
++ */
++
++function errorDiff(err, type, escape) {
++ var actual = escape ? escapeInvisibles(err.actual) : err.actual;
++ var expected = escape ? escapeInvisibles(err.expected) : err.expected;
++ return diff['diff' + type](actual, expected).map(function(str){
++ if (str.added) return colorLines('diff added', str.value);
++ if (str.removed) return colorLines('diff removed', str.value);
++ return str.value;
++ }).join('');
++}
++
++/**
++ * Returns a string with all invisible characters in plain text
++ *
++ * @param {String} line
++ * @return {String}
++ * @api private
++ */
++function escapeInvisibles(line) {
++ return line.replace(/\t/g, '<tab>')
++ .replace(/\r/g, '<CR>')
++ .replace(/\n/g, '<LF>\n');
++}
++
++/**
++ * Color lines for `str`, using the color `name`.
++ *
++ * @param {String} name
++ * @param {String} str
++ * @return {String}
++ * @api private
++ */
++
++function colorLines(name, str) {
++ return str.split('\n').map(function(str){
++ return color(name, str);
++ }).join('\n');
++}
++
++/**
++ * Check that a / b have the same type.
++ *
++ * @param {Object} a
++ * @param {Object} b
++ * @return {Boolean}
++ * @api private
++ */
++
++function sameType(a, b) {
++ a = Object.prototype.toString.call(a);
++ b = Object.prototype.toString.call(b);
++ return a == b;
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/classic.js
+@@ -0,0 +1,402 @@
++exports = module.exports = Classic
++
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color
++ , yaml = require('js-yaml')
++ , util = require('util')
++ , fancy = Base.useColors && !process.env.TRAVIS
++ , ms = require('../ms.js')
++ , diff = require('diff')
++ , utils = require('../utils.js')
++ , uclen = require('unicode-length').get
++ , colorSupport = require('color-support')()
++
++function hasOwnProperty (obj, key) {
++ return Object.prototype.hasOwnProperty.call(obj, key)
++}
++
++function doDiff (found, wanted, palette) {
++ // TODO: Make this a configurable thing or something?
++ //
++ // Choosing a palette for diffs in a test-runner context
++ // is really tricky. The temptation is to make it look
++ // exactly like `git diff`, but the default red and green
++ // are very confusing with the colors used to indicate
++ // pass/fail.
++ //
++ // So, I decided to experiment with setting a background to
++ // distinguish the diff section from the rest of the test
++ // output. The obvious choice, then, was to mimick GitHub's
++ // diff styling.
++ //
++ // The problem there is that, while those of us with an
++ // abundance of cones tend to find that palette most pleasing,
++ // it's virtually impossible for people with various sorts of
++ // red/green colorblindness to distinguish those colors.
++ //
++ // The resulting option, with a somewhat pink-ish red and a
++ // somewhat yellow-ish green, seems to be a pretty good
++ // compromise between esthetics and accessibility. In a poll
++ // on twitter, it was the only one that no color-sighted people
++ // strongly objected to, and no color-blind people had
++ // significant trouble interpreting. The twitter poll agrees
++ // with the results of Sim Daltonism, which showed that this
++ // palette was easily distinguishable across all forms of color
++ // deficiency.
++
++ // TODO: add a TrueColor one that looks nicer
++ palette = colorSupport.has256 ? 6 : 1
++
++ var plain = ''
++ var reset = '\u001b[m'
++
++ switch (palette) {
++ case 1:
++ // most git-like. r/g, no background, no bold
++ var bg = ''
++ var removed = '\u001b[31m'
++ var added = '\u001b[32m'
++ break
++
++ case 2:
++ // dark option, maybe confusing with pass/fail colors?
++ var bg = '\u001b[48;5;234m'
++ var removed = '\u001b[31;1m'
++ var added = '\u001b[32;1m'
++ break
++
++ case 3:
++ // pastel option, most githubby
++ var removed = '\u001b[48;5;224m\u001b[38;5;52m'
++ var added = '\u001b[48;5;194m\u001b[38;5;22m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ case 4:
++ // orange/cyan pastel option, most r/g-colorblind friendly
++ var removed = '\u001b[48;5;223m\u001b[38;5;52m'
++ var added = '\u001b[48;5;158m\u001b[38;5;22m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ case 5:
++ // pastel option, green is bluish, red is just red
++ var removed = '\u001b[48;5;224m\u001b[38;5;52m'
++ var added = '\u001b[48;5;158m\u001b[38;5;22m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ case 6:
++ // pastel option, red is purplish, green is yellowish
++ var removed = '\u001b[48;5;218m\u001b[38;5;52m'
++ var added = '\u001b[48;5;193m\u001b[38;5;22m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ case 7:
++ // pastel option, red is purplish, green is just green
++ var removed = '\u001b[48;5;218m\u001b[38;5;52m'
++ var added = '\u001b[48;5;194m\u001b[38;5;22m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ case 8:
++ // pastel, red and blue
++ var removed = '\u001b[48;5;224m\u001b[38;5;52m'
++ var added = '\u001b[48;5;189m\u001b[38;5;17m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ case 9:
++ // pastel option, red is purplish, green is yellowish
++ var removed = '\u001b[48;5;224m\u001b[38;5;52m'
++ var added = '\u001b[48;5;193m\u001b[38;5;22m'
++ var plain = '\u001b[38;5;233m'
++ var bg = '\u001b[48;5;255m'
++ break
++
++ }
++
++
++ var maxLen = process.stdout.columns || 0
++ if (maxLen >= 5)
++ maxLen -= 5
++
++ if (!Base.useColors) {
++ bg = removed = added = reset = plain = ''
++ maxLen = 0
++ }
++
++ // If they are not strings, or only differ in trailing whitespace,
++ // then stringify them so that we can see the difference.
++ if (typeof found !== 'string' ||
++ typeof wanted !== 'string' ||
++ found.trim() === wanted.trim()) {
++ found = utils.stringify(found)
++ wanted = utils.stringify(wanted)
++ }
++
++ var patch = diff.createPatch('', wanted, found)
++ //console.error(patch)
++ var width = 0
++ patch = patch.split('\n').map(function (line, index) {
++ if (uclen(line) > width)
++ width = Math.min(maxLen, uclen(line))
++ if (line.match(/^\=+$/) ||
++ line === '\\ No newline at end of file')
++ return null
++ else
++ return line
++ }).filter(function (line, i) {
++ return line && i > 4
++ }).map(function (line) {
++ if (uclen(line) < width)
++ line += new Array(width - uclen(line) + 1).join(' ')
++ return line
++ }).map(function (line) {
++ if (line.charAt(0) === '+')
++ return bg + added + line + reset
++ else if (line.charAt(0) === '-')
++ return bg + removed + line + reset
++ else
++ return bg + plain + line + reset
++ }).join('\n')
++
++ var pref =
++ bg + added + '+++ found' +
++ (Base.useColors
++ ? new Array(width - '+++ found'.length + 1).join(' ')
++ : '') +
++ reset + '\n' +
++ bg + removed + '--- wanted' +
++ (Base.useColors
++ ? new Array(width - '--- wanted'.length + 1).join(' ')
++ : '') +
++ reset + '\n'
++
++ return pref + patch
++}
++
++util.inherits(Classic, Base)
++
++function Classic (runner) {
++ Base.call(this, runner);
++
++ var self = this
++
++ var grandTotal = 0
++ var grandPass = 0
++
++ var bailed = false
++ var hadFails = false
++ var currentSuite = null
++ var tests = []
++ var skipped = 0
++ var skipMsg = []
++ var todo = []
++ var fails = []
++ var total = 0
++ var pass = 0
++ var tickDots = 0
++ var tickColor = 'checkmark'
++
++ runner.on('bailout', function (bailout, suite) {
++ if (currentSuite)
++ runner.emit('suite end', currentSuite)
++ if (bailed)
++ return
++ bailed = true
++ console.log(Base.color('fail', 'Bail out! ' + bailout))
++ })
++
++ runner.on('suite', function (suite) {
++ if (!suite.root)
++ return
++
++ if (fancy) {
++ process.stdout.write(suite.title + ' ')
++ tickDots = 0
++ tickColor = 'checkmark'
++ }
++
++ currentSuite = suite
++ tests = []
++ todo = []
++ fails = []
++ skipMsg = []
++ skipped = 0
++ pass = 0
++ total = 0
++ })
++
++ runner.on('suite end', function (suite) {
++ if (!suite.root)
++ return
++
++ if (fancy)
++ Base.cursor.beginningOfLine()
++
++ currentSuite = null
++ var len = 60
++ var title = suite.title || '(unnamed)'
++ var num = pass + '/' + total
++ var dots = len - uclen(title) - uclen(num) - 2
++ if (dots < 3)
++ dots = 3
++ dots = ' ' + new Array(dots).join('.') + ' '
++ if (fails.length)
++ num = Base.color('fail', num)
++ else if (pass === total)
++ num = Base.color('checkmark', num)
++ else
++ num = Base.color('pending', num)
++
++ var fmt = title + dots + num
++ if (suite.duration / total > 250)
++ fmt += Base.color('slow', ' ' + ms(Math.round(suite.duration)))
++
++ console.log(fmt)
++
++ if (fails.length) {
++ var failMsg = ''
++ fails.forEach(function (t) {
++ if (t.parent)
++ failMsg += t.parent + '\n'
++ failMsg += Base.color('fail', 'not ok ' + t.name) + '\n'
++ if (t.diag) {
++ var printDiff = false
++ if (hasOwnProperty(t.diag, 'found') &&
++ hasOwnProperty(t.diag, 'wanted')) {
++ printDiff = true
++ var found = t.diag.found
++ var wanted = t.diag.wanted
++ failMsg += indent(doDiff(found, wanted), 2) + '\n'
++ }
++
++ var o = {}
++ var print = false
++ for (var i in t.diag) {
++ // Don't re-print what we already showed in the diff
++ if (printDiff && ( i === 'found' || i === 'wanted'))
++ continue
++ o[i] = t.diag[i]
++ print = true
++ }
++ if (print)
++ failMsg += indent(yaml.safeDump(o), 2) + '\n'
++ }
++ })
++ console.log(indent(failMsg, 2))
++ }
++
++ if (todo.length) {
++ var todoMsg = ''
++ var bullet = Base.color('pending', '~ ')
++ todo.forEach(function (t) {
++ if (t.todo !== true)
++ t.name += ' - ' + Base.color('pending', t.todo)
++ todoMsg += bullet + t.name + '\n'
++ if (t.diag)
++ todoMsg += indent(yaml.safeDump(t.diag), 4) + '\n'
++ })
++ console.log(indent(todoMsg, 2))
++ }
++
++ if (skipped) {
++ var fmt = Base.color('skip', indent('Skipped: %d', 2))
++ console.log(fmt, skipped)
++ if (skipMsg.length)
++ console.log(indent(skipMsg.join('\n'), 4))
++ console.log('')
++ }
++ })
++
++ runner.on('test', function (test) {
++ total ++
++ grandTotal ++
++ var t = test.result
++ if (fancy && currentSuite) {
++ var max = 57 - uclen(currentSuite.title)
++ if (max < 3)
++ max = 3
++
++ if (tickDots > max) {
++ tickDots = 0
++ Base.cursor.deleteLine()
++ Base.cursor.beginningOfLine();
++ process.stdout.write(currentSuite.title + ' ')
++ }
++ tickDots ++
++
++ if (t.todo &&
++ (tickColor === 'checkmark' || tickColor === 'skip'))
++ tickColor = 'pending'
++ else if (t.skip && tickColor === 'checkmark')
++ tickColor = 'skip'
++ else if (!t.ok)
++ tickColor = 'fail'
++
++ process.stdout.write(Base.color(tickColor, '.'))
++ }
++
++ if (t.skip) {
++ skipped += 1
++ if (t.skip !== true)
++ skipMsg.push(t.name + ' ' + Base.color('skip', t.skip))
++ else
++ skipMsg.push(t.name)
++ }
++ else if (t.todo)
++ todo.push(t)
++ else if (!t.ok) {
++ t.parent = []
++ var p = test.parent
++ while (p && p !== currentSuite) {
++ var n = p.title || p.name || p.fullTitle()
++ if (n)
++ t.parent.unshift(n)
++ p = p.parent
++ }
++ t.parent.shift()
++ t.parent = t.parent.join(' > ')
++ fails.push(t)
++ hadFails = true
++ }
++ else {
++ pass ++
++ grandPass ++
++ }
++ })
++
++ runner.on('end', function () {
++ total = grandTotal
++ pass = grandPass
++ tests = []
++ todo = []
++ fails = []
++ skipMsg = []
++ skipped = 0
++ if (hadFails)
++ fails = [,,,]
++ runner.emit('suite end', { title: 'total', root: true })
++ self.failures = []
++ self.epilogue();
++
++ if (grandTotal === grandPass) {
++ console.log(Base.color('checkmark', '\n ok'))
++ }
++ })
++}
++
++function indent (str, n) {
++ var ind = new Array(n + 1).join(' ')
++ str = ind + str.split('\n').join('\n' + ind)
++ return str.replace(/(\n\s*)+$/, '\n')
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/dot.js
+@@ -0,0 +1,62 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , color = Base.color;
++
++/**
++ * Expose `Dot`.
++ */
++
++exports = module.exports = Dot;
++
++/**
++ * Initialize a new `Dot` matrix test reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Dot(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , width = Base.window.width * .75 | 0
++ , n = -1;
++
++ runner.on('start', function(){
++ process.stdout.write('\n');
++ });
++
++ runner.on('pending', function(test){
++ if (++n % width == 0) process.stdout.write('\n ');
++ process.stdout.write(color('pending', Base.symbols.dot));
++ });
++
++ runner.on('pass', function(test){
++ if (++n % width == 0) process.stdout.write('\n ');
++ if ('slow' == test.speed) {
++ process.stdout.write(color('bright yellow', Base.symbols.dot));
++ } else {
++ process.stdout.write(color(test.speed, Base.symbols.dot));
++ }
++ });
++
++ runner.on('fail', function(test, err){
++ if (++n % width == 0) process.stdout.write('\n ');
++ process.stdout.write(color('fail', Base.symbols.dot));
++ });
++
++ runner.on('end', function(){
++ console.log();
++ self.epilogue();
++ });
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++Dot.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/min.js
+@@ -0,0 +1,37 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base');
++
++/**
++ * Expose `Min`.
++ */
++
++exports = module.exports = Min;
++
++/**
++ * Initialize a new `Min` minimal test reporter (best used with --watch).
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Min(runner) {
++ Base.call(this, runner);
++
++ runner.on('start', function(){
++ // clear screen
++ process.stdout.write('\u001b[2J');
++ // set cursor position
++ process.stdout.write('\u001b[1;3H');
++ });
++
++ runner.on('end', this.epilogue.bind(this));
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++Min.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/progress.js
+@@ -0,0 +1,92 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color;
++
++/**
++ * Expose `Progress`.
++ */
++
++exports = module.exports = Progress;
++
++/**
++ * General progress bar color.
++ */
++
++Base.colors.progress = 90;
++
++/**
++ * Initialize a new `Progress` bar test reporter.
++ *
++ * @param {Runner} runner
++ * @param {Object} options
++ * @api public
++ */
++
++function Progress(runner, options) {
++ Base.call(this, runner);
++
++ var self = this
++ , options = options || {}
++ , stats = this.stats
++ , width = Base.window.width * .50 | 0
++ , total = runner.total
++ , complete = 0
++ , max = Math.max
++ , lastN = -1;
++
++ // default chars
++ options.open = options.open || '[';
++ options.complete = options.complete || '▬';
++ options.incomplete = options.incomplete || Base.symbols.dot;
++ options.close = options.close || ']';
++ options.verbose = false;
++
++ // tests started
++ runner.on('start', function(){
++ console.log();
++ cursor.hide();
++ });
++
++ // tests complete
++ runner.on('test end', function(){
++ complete++;
++ var incomplete = total - complete
++ , percent = complete / total
++ , n = width * percent | 0
++ , i = width - n;
++
++ if (lastN === n && !options.verbose) {
++ // Don't re-render the line if it hasn't changed
++ return;
++ }
++ lastN = n;
++
++ cursor.CR();
++ process.stdout.write('\u001b[J');
++ process.stdout.write(color('progress', ' ' + options.open));
++ process.stdout.write(Array(n).join(options.complete));
++ process.stdout.write(Array(i).join(options.incomplete));
++ process.stdout.write(color('progress', options.close));
++ if (options.verbose) {
++ process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
++ }
++ });
++
++ // tests are complete, output some stats
++ // and the failures if any
++ runner.on('end', function(){
++ cursor.show();
++ console.log();
++ self.epilogue();
++ });
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++Progress.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/silent.js
+@@ -0,0 +1 @@
++exports = module.exports = function () {}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/spec.js
+@@ -0,0 +1,82 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color;
++
++/**
++ * Expose `Spec`.
++ */
++
++exports = module.exports = Spec;
++
++/**
++ * Initialize a new `Spec` test reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Spec(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , indents = 0
++ , n = 0;
++
++ function indent() {
++ return Array(indents).join(' ')
++ }
++
++ runner.on('start', function(){
++ console.log();
++ });
++
++ runner.on('suite', function(suite){
++ ++indents;
++ console.log(color('suite', '%s%s'), indent(), suite.title);
++ });
++
++ runner.on('suite end', function(suite){
++ --indents;
++ if (1 == indents) console.log();
++ });
++
++ runner.on('pending', function(test){
++ var fmt = indent() + color('pending', ' - %s');
++ console.log(fmt, test.title);
++ });
++
++ runner.on('pass', function(test){
++ if ('fast' == test.speed) {
++ var fmt = indent()
++ + color('checkmark', ' ' + Base.symbols.ok)
++ + color('pass', ' %s');
++ cursor.CR();
++ console.log(fmt, test.title);
++ } else {
++ var fmt = indent()
++ + color('checkmark', ' ' + Base.symbols.ok)
++ + color('pass', ' %s')
++ + color(test.speed, ' (%dms)');
++ cursor.CR();
++ console.log(fmt, test.title, test.duration);
++ }
++ });
++
++ runner.on('fail', function(test, err){
++ cursor.CR();
++ console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
++ });
++
++ runner.on('end', self.epilogue.bind(self));
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++Spec.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/runner.js
+@@ -0,0 +1,347 @@
++// A facade from the tap-parser to the Mocha "Runner" object.
++// Note that pass/fail/suite events need to also mock the "Runnable"
++// objects (either "Suite" or "Test") since these have functions
++// which are called by the formatters.
++
++module.exports = Runner
++
++// relevant events:
++//
++// start()
++// Start of the top-level test set
++//
++// end()
++// End of the top-level test set.
++//
++// fail(test, err)
++// any "not ok" test that is not the trailing test for a suite
++// of >0 test points.
++//
++// pass(test)
++// any "ok" test point that is not the trailing test for a suite
++// of >0 tests
++//
++// pending(test)
++// Any "todo" test
++//
++// suite(suite)
++// A suite is a child test with >0 test points. This is a little bit
++// tricky, because TAP will provide a "child" event before we know
++// that it's a "suite". We see the "# Subtest: name" comment as the
++// first thing in the subtest. Then, when we get our first test point,
++// we know that it's a suite, and can emit the event with the mock suite.
++//
++// suite end(suite)
++// Emitted when we end the subtest
++//
++// test(test)
++// Any test point which is not the trailing test for a suite.
++//
++// test end(test)
++// Emitted immediately after the "test" event because test points are
++// not async in TAP.
++
++var util = require('util')
++var Test = require('./test.js')
++var Suite = require('./suite.js')
++var Writable = require('stream').Writable
++if (!Writable) {
++ try {
++ Writable = require('readable-stream').Writable
++ } catch (er) {
++ throw new Error('Please install "readable-stream" to use this module ' +
++ 'with Node.js v0.8 and before')
++ }
++}
++
++var Parser = require('tap-parser')
++
++// $1 = number, $2 = units
++var timere = /^#\s*time=((?:0|[1-9][0-9]*?)(?:\.[0-9]+)?)(ms|s)?$/
++
++util.inherits(Runner, Writable)
++
++function Runner (options) {
++ if (!(this instanceof Runner))
++ return new Runner(options)
++
++ var parser = this.parser = new Parser(options)
++ this.startTime = new Date()
++
++ attachEvents(this, parser, 0)
++ Writable.call(this, options)
++}
++
++Runner.prototype.write = function () {
++ if (!this.emittedStart) {
++ this.emittedStart = true
++ this.emit('start')
++ }
++
++ return this.parser.write.apply(this.parser, arguments)
++}
++
++Runner.prototype.end = function () {
++ return this.parser.end.apply(this.parser, arguments)
++}
++
++Parser.prototype.fullTitle = function () {
++ if (!this.parent)
++ return this.name || ''
++ else
++ return (this.parent.fullTitle() + ' ' + (this.name || '')).trim()
++}
++
++function attachEvents (runner, parser, level) {
++ parser.runner = runner
++
++ if (level === 0) {
++ parser.on('line', function (c) {
++ runner.emit('line', c)
++ })
++ parser.on('version', function (v) {
++ runner.emit('version', v)
++ })
++ parser.on('complete', function (res) {
++ runner.emit('end')
++ })
++ parser.on('comment', function (c) {
++ var tmatch = c.trim().match(timere)
++ if (tmatch) {
++ var t = +tmatch[1]
++ if (tmatch[2] === 's')
++ t *= 1000
++ parser.time = t
++ if (runner.stats)
++ runner.stats.duration = t
++ }
++ })
++ }
++
++ parser.emittedSuite = false
++ parser.didAssert = false
++ parser.name = parser.name || ''
++ parser.doingChild = null
++
++ parser.on('complete', function (res) {
++ if (!res.ok) {
++ var fail = { ok: false, diag: {} }
++ var count = res.count
++ if (res.plan) {
++ var plan = res.plan.end - res.plan.start + 1
++ if (count !== plan) {
++ fail.name = 'test count !== plan'
++ fail.diag = {
++ found: count,
++ wanted: plan
++ }
++ } else {
++ // probably handled on child parser
++ return
++ }
++ } else {
++ fail.name = 'missing plan'
++ }
++ fail.diag.results = res
++ emitTest(parser, fail)
++ }
++ })
++
++ parser.on('child', function (child) {
++ child.parent = parser
++ attachEvents(runner, child, level + 1)
++
++ // if we're in a suite, but we haven't emitted it yet, then we
++ // know that an assert will follow this child, even if there are
++ // no others. That means that we will definitely have a 'suite'
++ // event to emit.
++ emitSuite(this)
++
++ this.didAssert = true
++ this.doingChild = child
++ })
++
++ if (!parser.name) {
++ parser.on('comment', function (c) {
++ if (!this.name && c.match(/^# Subtest: /)) {
++ c = c.trim().replace(/^# Subtest: /, '')
++ this.name = c
++ }
++ })
++ }
++
++ // Just dump all non-parsing stuff to stderr
++ parser.on('extra', function (c) {
++ process.stderr.write(c)
++ })
++
++ parser.on('assert', function (result) {
++ emitSuite(this)
++
++ // no need to print the trailing assert for subtests
++ // we've already emitted a 'suite end' event for this.
++ // UNLESS, there were no other asserts, AND it's root level
++ if (this.doingChild) {
++ var suite = this.doingChild.suite
++ if (this.doingChild.name === result.name) {
++ if (suite) {
++ if (result.time)
++ suite.duration = result.time
++
++ // If it's ok so far, but the ending result is not-ok, then
++ // that means that it exited non-zero. Emit the test so
++ // that we can print it as a failure.
++ if (suite.ok && !result.ok)
++ emitTest(this, result)
++ }
++ }
++
++ var emitOn = this
++ var dc = this.doingChild
++ this.doingChild = null
++
++ if (!dc.didAssert && dc.level === 1) {
++ emitOn = dc
++ } else if (dc.didAssert) {
++ if (dc.suite)
++ runner.emit('suite end', dc.suite)
++ return
++ } else {
++ emitOn = this
++ }
++
++ emitSuite(emitOn)
++ emitTest(emitOn, result)
++ if (emitOn !== this && emitOn.suite) {
++ runner.emit('suite end', emitOn.suite)
++ delete emitOn.suite
++ }
++ if (dc.suite) {
++ runner.emit('suite end', dc.suite)
++ }
++ return
++ }
++
++ this.didAssert = true
++ this.doingChild = null
++
++ emitTest(this, result)
++ })
++
++ parser.on('complete', function (results) {
++ this.results = results
++ })
++
++ parser.on('bailout', function (reason) {
++ var suite = this.suite
++ runner.emit('bailout', reason, suite)
++ if (suite)
++ this.suite = suite.parent
++ })
++
++ // proxy all stream events directly
++ var streamEvents = [
++ 'pipe', 'prefinish', 'finish', 'unpipe', 'close'
++ ]
++
++ streamEvents.forEach(function (ev) {
++ parser.on(ev, function () {
++ var args = [ev]
++ args.push.apply(args, arguments)
++ runner.emit.apply(runner, args)
++ })
++ })
++}
++
++function emitSuite (parser) {
++ if (!parser.emittedSuite && parser.name) {
++ parser.emittedSuite = true
++ var suite = parser.suite = new Suite(parser)
++ if (parser.parent && parser.parent.suite)
++ parser.parent.suite.suites.push(suite)
++ if (parser.runner.stats)
++ parser.runner.stats.suites ++
++
++ parser.runner.emit('suite', suite)
++ }
++}
++
++function emitTest (parser, result) {
++ var runner = parser.runner
++ var test = new Test(result, parser)
++
++ if (parser.suite) {
++ parser.suite.tests.push(test)
++ if (!result.ok) {
++ for (var p = parser; p && p.suite; p = p.parent) {
++ p.suite.ok = false
++ }
++ }
++ parser.suite.ok = parser.suite.ok && result.ok
++ }
++
++ runner.emit('test', test)
++ if (result.skip || result.todo) {
++ runner.emit('pending', test)
++ } else if (result.ok) {
++ runner.emit('pass', test)
++ } else {
++ var error = getError(result)
++ runner.emit('fail', test, error)
++ }
++ runner.emit('test end', test)
++}
++
++function getError (result) {
++ var err
++
++ function reviveStack (stack) {
++ if (!stack)
++ return null
++
++ return stack.trim().split('\n').map(function (line) {
++ return ' at ' + line
++ }).join('\n')
++ }
++
++ if (result.diag && result.diag.error) {
++ err = {
++ name: result.diag.error.name || 'Error',
++ message: result.diag.error.message,
++ toString: function () {
++ return this.name + ': ' + this.message
++ },
++ stack: result.diag.error.stack
++ }
++ } else {
++ err = {
++ message: (result.name || '(unnamed error)').replace(/^Error: /, ''),
++ toString: function () {
++ return 'Error: ' + this.message
++ },
++ stack: result.diag && result.diag.stack
++ }
++ }
++
++ var diag = result.diag
++
++ if (err.stack)
++ err.stack = err.toString() + '\n' + reviveStack(err.stack)
++
++ if (diag) {
++ var hasFound = diag.hasOwnProperty('found')
++ var hasWanted = diag.hasOwnProperty('wanted')
++
++ if (hasFound)
++ err.actual = diag.found
++
++ if (hasWanted)
++ err.expected = diag.wanted
++
++ if (hasFound && hasWanted)
++ err.showDiff = true
++ }
++
++ return err
++}
++
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/suite.js
+@@ -0,0 +1,22 @@
++// minimal mock of mocha's Suite class for formatters
++
++module.exports = Suite
++
++function Suite (parent) {
++ if (!parent.parent || !parent.parent.emittedSuite)
++ this.root = true
++ else
++ this.root = false
++
++ this.title = parent.name || ''
++ this.suites = []
++ this.tests = []
++ this.ok = true
++}
++
++Suite.prototype.fullTitle = function () {
++ if (!this.parent)
++ return (this.title || '').trim()
++ else
++ return (this.parent.fullTitle() + ' ' + (this.title || '')).trim()
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/test.js
+@@ -0,0 +1,41 @@
++// minimal mock of the mocha Test class for formatters
++
++module.exports = Test
++
++function Test (result, parent) {
++ this.result = result
++ this._slow = 75
++ this.duration = result.time
++ this.title = result.name
++ this.state = result.ok ? 'pass' : 'failed'
++ this.pending = result.todo || result.skip || false
++ if (result.diag && result.diag.source) {
++ var source = result.diag.source
++ this.fn = {
++ toString: function () {
++ return 'function(){' + source + '\n}'
++ }
++ }
++ }
++
++ Object.defineProperty(this, 'parent', {
++ value: parent,
++ writable: true,
++ configurable: true,
++ enumerable: false
++ })
++}
++
++Test.prototype.fullTitle = function () {
++ return (this.parent.fullTitle() + ' ' + (this.title || '')).trim()
++}
++
++Test.prototype.slow = function (ms){
++ return 75
++}
++
++Test.prototype.fn = {
++ toString: function () {
++ return 'function () {\n}'
++ }
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/utils.js
+@@ -0,0 +1,699 @@
++/**
++ * Module dependencies.
++ */
++
++var fs = require('fs')
++ , path = require('path')
++ , basename = path.basename
++ , exists = fs.existsSync || path.existsSync
++ , glob = require('glob')
++ , join = path.join
++ , debug = require('debug')('mocha:watch');
++
++/**
++ * Ignored directories.
++ */
++
++var ignore = ['node_modules', '.git'];
++
++/**
++ * Escape special characters in the given string of html.
++ *
++ * @param {String} html
++ * @return {String}
++ * @api private
++ */
++
++exports.escape = function(html){
++ return String(html)
++ .replace('&', '&')
++ .replace('"', '"')
++ .replace('<', '<')
++ .replace('>', '>');
++};
++
++/**
++ * Array#forEach (<=IE8)
++ *
++ * @param {Array} array
++ * @param {Function} fn
++ * @param {Object} scope
++ * @api private
++ */
++
++exports.forEach = function(arr, fn, scope){
++ for (var i = 0, l = arr.length; i < l; i++)
++ fn.call(scope, arr[i], i);
++};
++
++/**
++ * Array#map (<=IE8)
++ *
++ * @param {Array} array
++ * @param {Function} fn
++ * @param {Object} scope
++ * @api private
++ */
++
++exports.map = function(arr, fn, scope){
++ var result = [];
++ for (var i = 0, l = arr.length; i < l; i++)
++ result.push(fn.call(scope, arr[i], i, arr));
++ return result;
++};
++
++/**
++ * Array#indexOf (<=IE8)
++ *
++ * @parma {Array} arr
++ * @param {Object} obj to find index of
++ * @param {Number} start
++ * @api private
++ */
++
++exports.indexOf = function(arr, obj, start){
++ for (var i = start || 0, l = arr.length; i < l; i++) {
++ if (arr[i] === obj)
++ return i;
++ }
++ return -1;
++};
++
++/**
++ * Array#reduce (<=IE8)
++ *
++ * @param {Array} array
++ * @param {Function} fn
++ * @param {Object} initial value
++ * @api private
++ */
++
++exports.reduce = function(arr, fn, val){
++ var rval = val;
++
++ for (var i = 0, l = arr.length; i < l; i++) {
++ rval = fn(rval, arr[i], i, arr);
++ }
++
++ return rval;
++};
++
++/**
++ * Array#filter (<=IE8)
++ *
++ * @param {Array} array
++ * @param {Function} fn
++ * @api private
++ */
++
++exports.filter = function(arr, fn){
++ var ret = [];
++
++ for (var i = 0, l = arr.length; i < l; i++) {
++ var val = arr[i];
++ if (fn(val, i, arr)) ret.push(val);
++ }
++
++ return ret;
++};
++
++/**
++ * Object.keys (<=IE8)
++ *
++ * @param {Object} obj
++ * @return {Array} keys
++ * @api private
++ */
++
++exports.keys = Object.keys || function(obj) {
++ var keys = []
++ , has = Object.prototype.hasOwnProperty; // for `window` on <=IE8
++
++ for (var key in obj) {
++ if (has.call(obj, key)) {
++ keys.push(key);
++ }
++ }
++
++ return keys;
++};
++
++/**
++ * Watch the given `files` for changes
++ * and invoke `fn(file)` on modification.
++ *
++ * @param {Array} files
++ * @param {Function} fn
++ * @api private
++ */
++
++exports.watch = function(files, fn){
++ var options = { interval: 100 };
++ files.forEach(function(file){
++ debug('file %s', file);
++ fs.watchFile(file, options, function(curr, prev){
++ if (prev.mtime < curr.mtime) fn(file);
++ });
++ });
++};
++
++/**
++ * Array.isArray (<=IE8)
++ *
++ * @param {Object} obj
++ * @return {Boolean}
++ * @api private
++ */
++var isArray = Array.isArray || function (obj) {
++ return '[object Array]' == {}.toString.call(obj);
++};
++
++/**
++ * @description
++ * Buffer.prototype.toJSON polyfill
++ * @type {Function}
++ */
++if(typeof Buffer !== 'undefined' && Buffer.prototype) {
++ Buffer.prototype.toJSON = Buffer.prototype.toJSON || function () {
++ return Array.prototype.slice.call(this, 0);
++ };
++}
++
++/**
++ * Ignored files.
++ */
++
++function ignored(path){
++ return !~ignore.indexOf(path);
++}
++
++/**
++ * Lookup files in the given `dir`.
++ *
++ * @return {Array}
++ * @api private
++ */
++
++exports.files = function(dir, ext, ret){
++ ret = ret || [];
++ ext = ext || ['js'];
++
++ var re = new RegExp('\\.(' + ext.join('|') + ')$');
++
++ fs.readdirSync(dir)
++ .filter(ignored)
++ .forEach(function(path){
++ path = join(dir, path);
++ if (fs.statSync(path).isDirectory()) {
++ exports.files(path, ext, ret);
++ } else if (path.match(re)) {
++ ret.push(path);
++ }
++ });
++
++ return ret;
++};
++
++/**
++ * Compute a slug from the given `str`.
++ *
++ * @param {String} str
++ * @return {String}
++ * @api private
++ */
++
++exports.slug = function(str){
++ return str
++ .toLowerCase()
++ .replace(/ +/g, '-')
++ .replace(/[^-\w]/g, '');
++};
++
++/**
++ * Strip the function definition from `str`,
++ * and re-indent for pre whitespace.
++ */
++
++exports.clean = function(str) {
++ str = str
++ .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
++ .replace(/^function *\(.*\) *{|\(.*\) *=> *{?/, '')
++ .replace(/\s+\}$/, '');
++
++ var spaces = str.match(/^\n?( *)/)[1].length
++ , tabs = str.match(/^\n?(\t*)/)[1].length
++ , re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');
++
++ str = str.replace(re, '');
++
++ return exports.trim(str);
++};
++
++/**
++ * Trim the given `str`.
++ *
++ * @param {String} str
++ * @return {String}
++ * @api private
++ */
++
++exports.trim = function(str){
++ return str.replace(/^\s+|\s+$/g, '');
++};
++
++/**
++ * Parse the given `qs`.
++ *
++ * @param {String} qs
++ * @return {Object}
++ * @api private
++ */
++
++exports.parseQuery = function(qs){
++ return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
++ var i = pair.indexOf('=')
++ , key = pair.slice(0, i)
++ , val = pair.slice(++i);
++
++ obj[key] = decodeURIComponent(val);
++ return obj;
++ }, {});
++};
++
++/**
++ * Highlight the given string of `js`.
++ *
++ * @param {String} js
++ * @return {String}
++ * @api private
++ */
++
++function highlight(js) {
++ return js
++ .replace(/</g, '<')
++ .replace(/>/g, '>')
++ .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
++ .replace(/('.*?')/gm, '<span class="string">$1</span>')
++ .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
++ .replace(/(\d+)/gm, '<span class="number">$1</span>')
++ .replace(/\bnew[ \t]+(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
++ .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
++}
++
++/**
++ * Highlight the contents of tag `name`.
++ *
++ * @param {String} name
++ * @api private
++ */
++
++exports.highlightTags = function(name) {
++ var code = document.getElementById('mocha').getElementsByTagName(name);
++ for (var i = 0, len = code.length; i < len; ++i) {
++ code[i].innerHTML = highlight(code[i].innerHTML);
++ }
++};
++
++/**
++ * If a value could have properties, and has none, this function is called, which returns
++ * a string representation of the empty value.
++ *
++ * Functions w/ no properties return `'[Function]'`
++ * Arrays w/ length === 0 return `'[]'`
++ * Objects w/ no properties return `'{}'`
++ * All else: return result of `value.toString()`
++ *
++ * @param {*} value Value to inspect
++ * @param {string} [type] The type of the value, if known.
++ * @returns {string}
++ */
++var emptyRepresentation = function emptyRepresentation(value, type) {
++ type = type || exports.type(value);
++
++ switch(type) {
++ case 'function':
++ return '[Function]';
++ case 'object':
++ return '{}';
++ case 'array':
++ return '[]';
++ default:
++ return value.toString();
++ }
++};
++
++/**
++ * Takes some variable and asks `{}.toString()` what it thinks it is.
++ * @param {*} value Anything
++ * @example
++ * type({}) // 'object'
++ * type([]) // 'array'
++ * type(1) // 'number'
++ * type(false) // 'boolean'
++ * type(Infinity) // 'number'
++ * type(null) // 'null'
++ * type(new Date()) // 'date'
++ * type(/foo/) // 'regexp'
++ * type('type') // 'string'
++ * type(global) // 'global'
++ * @api private
++ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
++ * @returns {string}
++ */
++exports.type = function type(value) {
++ if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
++ return 'buffer';
++ }
++ return Object.prototype.toString.call(value)
++ .replace(/^\[.+\s(.+?)\]$/, '$1')
++ .toLowerCase();
++};
++
++/**
++ * @summary Stringify `value`.
++ * @description Different behavior depending on type of value.
++ * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.
++ * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.
++ * - If `value` is an *empty* object, function, or array, return result of function
++ * {@link emptyRepresentation}.
++ * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of
++ * JSON.stringify().
++ *
++ * @see exports.type
++ * @param {*} value
++ * @return {string}
++ * @api private
++ */
++
++exports.stringify = function(value) {
++ var type = exports.type(value);
++
++ if (!~exports.indexOf(['object', 'array', 'function'], type)) {
++ if(type != 'buffer') {
++ return jsonStringify(value);
++ }
++ var json = value.toJSON();
++ // Based on the toJSON result
++ return jsonStringify(json.data && json.type ? json.data : json, 2)
++ .replace(/,(\n|$)/g, '$1');
++ }
++
++ for (var prop in value) {
++ if (Object.prototype.hasOwnProperty.call(value, prop)) {
++ return jsonStringify(exports.canonicalize(value), 2)
++ .replace(/,(\n|$)/g, '$1');
++ }
++ }
++
++ return emptyRepresentation(value, type);
++};
++
++/**
++ * @description
++ * like JSON.stringify but more sense.
++ * @param {Object} object
++ * @param {Number=} spaces
++ * @param {number=} depth
++ * @returns {*}
++ * @private
++ */
++function jsonStringify(object, spaces, depth) {
++ if(typeof spaces == 'undefined') return _stringify(object); // primitive types
++
++ depth = depth || 1;
++ var space = spaces * depth
++ , str = isArray(object) ? '[' : '{'
++ , end = isArray(object) ? ']' : '}'
++ , length = object.length || exports.keys(object).length
++ , repeat = function(s, n) { return new Array(n).join(s); }; // `.repeat()` polyfill
++
++ function _stringify(val) {
++ switch (exports.type(val)) {
++ case 'null':
++ case 'undefined':
++ val = '[' + val + ']';
++ break;
++ case 'array':
++ case 'object':
++ val = jsonStringify(val, spaces, depth + 1);
++ break;
++ case 'boolean':
++ case 'regexp':
++ case 'number':
++ val = val === 0 && (1/val) === -Infinity // `-0`
++ ? '-0'
++ : val.toString();
++ break;
++ case 'date':
++ val = '[Date: ' + val.toISOString() + ']';
++ break;
++ case 'buffer':
++ var json = val.toJSON();
++ // Based on the toJSON result
++ json = json.data && json.type ? json.data : json;
++ val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
++ break;
++ default:
++ val = (val == '[Function]' || val == '[Circular]')
++ ? val
++ : '"' + val + '"'; //string
++ }
++ return val;
++ }
++
++ for(var i in object) {
++ if(!Object.prototype.hasOwnProperty.call(object, i)) continue; // not my business
++ --length;
++ str += '\n ' + repeat(' ', space)
++ + (isArray(object) ? '' : '"' + i + '": ') // key
++ + _stringify(object[i]) // value
++ + (length ? ',' : ''); // comma
++ }
++
++ return str + (str.length != 1 // [], {}
++ ? '\n' + repeat(' ', --space) + end
++ : end);
++}
++
++/**
++ * Return if obj is a Buffer
++ * @param {Object} arg
++ * @return {Boolean}
++ * @api private
++ */
++exports.isBuffer = function (arg) {
++ return typeof Buffer !== 'undefined' && Buffer.isBuffer(arg);
++};
++
++/**
++ * @summary Return a new Thing that has the keys in sorted order. Recursive.
++ * @description If the Thing...
++ * - has already been seen, return string `'[Circular]'`
++ * - is `undefined`, return string `'[undefined]'`
++ * - is `null`, return value `null`
++ * - is some other primitive, return the value
++ * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
++ * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
++ * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
++ *
++ * @param {*} value Thing to inspect. May or may not have properties.
++ * @param {Array} [stack=[]] Stack of seen values
++ * @return {(Object|Array|Function|string|undefined)}
++ * @see {@link exports.stringify}
++ * @api private
++ */
++
++exports.canonicalize = function(value, stack) {
++ var canonicalizedObj,
++ type = exports.type(value),
++ prop,
++ withStack = function withStack(value, fn) {
++ stack.push(value);
++ fn();
++ stack.pop();
++ };
++
++ stack = stack || [];
++
++ if (exports.indexOf(stack, value) !== -1) {
++ return '[Circular]';
++ }
++
++ switch(type) {
++ case 'undefined':
++ case 'buffer':
++ case 'null':
++ canonicalizedObj = value;
++ break;
++ case 'array':
++ withStack(value, function () {
++ canonicalizedObj = exports.map(value, function (item) {
++ return exports.canonicalize(item, stack);
++ });
++ });
++ break;
++ case 'function':
++ for (prop in value) {
++ canonicalizedObj = {};
++ break;
++ }
++ if (!canonicalizedObj) {
++ canonicalizedObj = emptyRepresentation(value, type);
++ break;
++ }
++ /* falls through */
++ case 'object':
++ canonicalizedObj = canonicalizedObj || {};
++ withStack(value, function () {
++ exports.forEach(exports.keys(value).sort(), function (key) {
++ canonicalizedObj[key] = exports.canonicalize(value[key], stack);
++ });
++ });
++ break;
++ case 'date':
++ case 'number':
++ case 'regexp':
++ case 'boolean':
++ canonicalizedObj = value;
++ break;
++ default:
++ canonicalizedObj = value.toString();
++ }
++
++ return canonicalizedObj;
++};
++
++/**
++ * Lookup file names at the given `path`.
++ */
++exports.lookupFiles = function lookupFiles(path, extensions, recursive) {
++ var files = [];
++ var re = new RegExp('\\.(' + extensions.join('|') + ')$');
++
++ if (!exists(path)) {
++ if (exists(path + '.js')) {
++ path += '.js';
++ } else {
++ files = glob.sync(path);
++ if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
++ return files;
++ }
++ }
++
++ try {
++ var stat = fs.statSync(path);
++ if (stat.isFile()) return path;
++ }
++ catch (ignored) {
++ return;
++ }
++
++ fs.readdirSync(path).forEach(function(file) {
++ file = join(path, file);
++ try {
++ var stat = fs.statSync(file);
++ if (stat.isDirectory()) {
++ if (recursive) {
++ files = files.concat(lookupFiles(file, extensions, recursive));
++ }
++ return;
++ }
++ }
++ catch (ignored) {
++ return;
++ }
++ if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') return;
++ files.push(file);
++ });
++
++ return files;
++};
++
++/**
++ * Generate an undefined error with a message warning the user.
++ *
++ * @return {Error}
++ */
++
++exports.undefinedError = function() {
++ return new Error('Caught undefined error, did you throw without specifying what?');
++};
++
++/**
++ * Generate an undefined error if `err` is not defined.
++ *
++ * @param {Error} err
++ * @return {Error}
++ */
++
++exports.getError = function(err) {
++ return err || exports.undefinedError();
++};
++
++
++/**
++ * @summary
++ * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)
++ * @description
++ * When invoking this function you get a filter function that get the Error.stack as an input,
++ * and return a prettify output.
++ * (i.e: strip Mocha, node_modules, bower and componentJS from stack trace).
++ * @returns {Function}
++ */
++
++exports.stackTraceFilter = function() {
++ var slash = '/'
++ , is = typeof document === 'undefined'
++ ? { node: true }
++ : { browser: true }
++ , cwd = is.node
++ ? process.cwd() + slash
++ : location.href.replace(/\/[^\/]*$/, '/');
++
++ function isNodeModule (line) {
++ return (~line.indexOf('node_modules'));
++ }
++
++ function isMochaInternal (line) {
++ return (~line.indexOf('node_modules' + slash + 'tap-mocha-reporter')) ||
++ (~line.indexOf('components' + slash + 'mochajs')) ||
++ (~line.indexOf('components' + slash + 'mocha'));
++ }
++
++ // node_modules, bower, componentJS
++ function isBrowserModule(line) {
++ return (~line.indexOf('node_modules')) ||
++ (~line.indexOf('components'));
++ }
++
++ function isNodeInternal (line) {
++ return (~line.indexOf('(timers.js:')) ||
++ (~line.indexOf('(domain.js:')) ||
++ (~line.indexOf('(events.js:')) ||
++ (~line.indexOf('(node.js:')) ||
++ (~line.indexOf('(module.js:')) ||
++ (~line.indexOf('at node.js:')) ||
++ (~line.indexOf('GeneratorFunctionPrototype.next (native)')) ||
++ false
++ }
++
++ return function(stack) {
++ stack = stack.split('\n');
++
++ stack = stack.reduce(function (list, line) {
++ if (is.node && (isNodeModule(line) ||
++ isMochaInternal(line) ||
++ isNodeInternal(line)))
++ return list;
++
++ if (is.browser && (isBrowserModule(line)))
++ return list;
++
++ // Clean up cwd(absolute)
++ list.push(line.replace(cwd, ''));
++ return list;
++ }, []);
++
++ return stack.join('\n');
++ }
++};
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/index.js
+@@ -0,0 +1,106 @@
++#!/usr/bin/env node
++
++module.exports = Formatter
++
++var util = require('util')
++var reporters = require('./lib/reporters/index.js')
++Formatter.types = Object.keys(reporters).sort()
++var Writable = require('stream').Writable
++if (!Writable) {
++ try {
++ Writable = require('readable-stream').Writable
++ } catch (er) {
++ throw new Error('Please install "readable-stream" to use this module ' +
++ 'with Node.js v0.8 and before')
++ }
++}
++
++var Runner = require('./lib/runner.js')
++var Parser = require('tap-parser')
++
++util.inherits(Formatter, Writable)
++
++var exitCode
++function Formatter (type, options) {
++ if (!(this instanceof Formatter)) {
++ return new Formatter(type, options)
++ }
++ if (!reporters[type]) {
++ console.error('Unknown format type: %s\n\n%s', type, avail())
++ type = 'silent'
++ }
++
++ this.writable = true
++
++ // don't actually need a reporter to report the tap we're getting
++ // just parse it so that we exit with the correct code, but otherwise
++ // dump it straight through to stdout.
++ if (type === 'tap') {
++ var p = new Parser()
++ this.write = function (chunk) {
++ process.stdout.write(chunk)
++ return p.write(chunk)
++ }
++ this.end = p.end.bind(p)
++ p.on('complete', function () {
++ if (!p.ok)
++ exitCode = 1
++ })
++ return this
++ }
++
++ var runner = this.runner = new Runner(options)
++ this.reporter = new reporters[type](this.runner, {})
++ Writable.call(this, options)
++
++ runner.on('end', function () {
++ if (!runner.parser.ok)
++ exitCode = 1
++ })
++}
++
++process.on('exit', function (code) {
++ if (!code && exitCode)
++ process.exit(exitCode)
++})
++
++Formatter.prototype.write = function () {
++ return this.runner.write.apply(this.runner, arguments)
++}
++
++Formatter.prototype.end = function () {
++ return this.runner.end.apply(this.runner, arguments)
++}
++
++function avail () {
++ var types = Formatter.types.reduce(function (str, t) {
++ var ll = str.split('\n').pop().length + t.length
++ if (ll < 40)
++ return str + ' ' + t
++ else
++ return str + '\n' + t
++ }, '').trim()
++
++ return 'Available format types:\n\n' + types
++}
++
++
++function usage (err) {
++ console[err ? 'error' : 'log'](function () {/*
++Usage:
++ tap-mocha-reporter <type>
++
++Reads TAP data on stdin, and formats to stdout using the specified
++reporter. (Note that some reporters write to files instead of stdout.)
++
++%s
++*/}.toString().split('\n').slice(1, -1).join('\n'), avail())
++}
++
++if (require.main === module) {
++ var type = process.argv[2]
++ if (!type)
++ return usage()
++
++ process.stdin.pipe(new Formatter(type))
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/index.js
+@@ -0,0 +1,16 @@
++exports.dot = require('./dot.js')
++exports.doc = require('./doc.js')
++exports.tap = true
++exports.json = require('./json.js')
++exports.list = require('./list.js')
++exports.min = require('./min.js')
++exports.spec = require('./spec.js')
++exports.nyan = require('./nyan.js')
++exports.xunit = require('./xunit.js')
++exports.markdown = require('./markdown.js')
++exports.progress = require('./progress.js')
++exports.landing = require('./landing.js')
++exports.jsonstream = require('./json-stream.js')
++exports.dump = require('./dump.js')
++exports.classic = require('./classic.js')
++exports.silent = require('./silent.js')
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/doc.js
+@@ -0,0 +1,62 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , utils = require('../utils');
++
++/**
++ * Expose `Doc`.
++ */
++
++exports = module.exports = Doc;
++
++/**
++ * Initialize a new `Doc` reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Doc(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , total = runner.total
++ , indents = 2;
++
++ function indent() {
++ return Array(indents).join(' ');
++ }
++
++ runner.on('suite', function(suite){
++ if (suite.root) return;
++ ++indents;
++ console.log('%s<section class="suite">', indent());
++ ++indents;
++ console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
++ console.log('%s<dl>', indent());
++ });
++
++ runner.on('suite end', function(suite){
++ if (suite.root) return;
++ console.log('%s</dl>', indent());
++ --indents;
++ console.log('%s</section>', indent());
++ --indents;
++ });
++
++ runner.on('pass', function(test){
++ console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
++ var code = utils.escape(utils.clean(test.fn.toString()));
++ console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
++ });
++
++ runner.on('fail', function(test, err){
++ console.log('%s <dt class="error">%s</dt>', indent(), utils.escape(test.title));
++ var code = utils.escape(utils.clean(test.fn.toString()));
++ console.log('%s <dd class="error"><pre><code>%s</code></pre></dd>', indent(), code);
++ console.log('%s <dd class="error">%s</dd>', indent(), utils.escape(err));
++ });
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/dump.js
+@@ -0,0 +1,50 @@
++exports = module.exports = Dump
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color
++ , useColors = Base.useColors
++ , util = require('util')
++
++function Dump(runner) {
++ Base.call(this, runner);
++
++ var events = [
++ 'start',
++ 'version',
++ 'suite',
++ 'suite end',
++ 'test',
++ 'pending',
++ 'pass',
++ 'fail',
++ 'test end',
++ ];
++
++ var i = process.argv.indexOf('dump')
++ if (i !== -1) {
++ var args = process.argv.slice(i + 1)
++ if (args.length)
++ events = args
++ }
++
++ runner.on('line', function (c) {
++ if (c.trim())
++ process.stderr.write(Base.color('bright yellow', c))
++ })
++
++ events.forEach(function (ev) {
++ runner.on(ev, function (obj) {
++ console.log(ev)
++ if (arguments.length) {
++ console.log(util.inspect(obj, false, Infinity, useColors))
++ console.log()
++ }
++ })
++ })
++
++ runner.on('end', function () {
++ console.log('end')
++ console.log(runner.stats)
++ console.log()
++ })
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/json-stream.js
+@@ -0,0 +1,62 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , color = Base.color;
++
++/**
++ * Expose `List`.
++ */
++
++exports = module.exports = List;
++
++/**
++ * Initialize a new `List` test reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function List(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , total = runner.total;
++
++ runner.on('start', function(){
++ console.log(JSON.stringify(['start', { total: total }]));
++ });
++
++ runner.on('pass', function(test){
++ console.log(JSON.stringify(['pass', clean(test)]));
++ });
++
++ runner.on('fail', function(test, err){
++ test = clean(test);
++ test.err = err.message;
++ console.log(JSON.stringify(['fail', test]));
++ });
++
++ runner.on('end', function(){
++ process.stdout.write(JSON.stringify(['end', self.stats]));
++ });
++}
++
++/**
++ * Return a plain-object representation of `test`
++ * free of cyclic properties etc.
++ *
++ * @param {Object} test
++ * @return {Object}
++ * @api private
++ */
++
++function clean(test) {
++ return {
++ title: test.title
++ , fullTitle: test.fullTitle()
++ , duration: test.duration
++ }
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/json.js
+@@ -0,0 +1,92 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color;
++
++/**
++ * Expose `JSON`.
++ */
++
++exports = module.exports = JSONReporter;
++
++/**
++ * Initialize a new `JSON` reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function JSONReporter(runner) {
++ var self = this;
++ Base.call(this, runner);
++
++ var tests = []
++ , pending = []
++ , failures = []
++ , passes = [];
++
++ runner.on('test end', function(test){
++ tests.push(test);
++ });
++
++ runner.on('pass', function(test){
++ passes.push(test);
++ });
++
++ runner.on('fail', function(test){
++ failures.push(test);
++ });
++
++ runner.on('pending', function(test){
++ pending.push(test);
++ });
++
++ runner.on('end', function(){
++ var obj = {
++ stats: self.stats,
++ tests: tests.map(clean),
++ pending: pending.map(clean),
++ failures: failures.map(clean),
++ passes: passes.map(clean)
++ };
++
++ runner.testResults = obj;
++
++ process.stdout.write(JSON.stringify(obj, null, 2));
++ });
++}
++
++/**
++ * Return a plain-object representation of `test`
++ * free of cyclic properties etc.
++ *
++ * @param {Object} test
++ * @return {Object}
++ * @api private
++ */
++
++function clean(test) {
++ return {
++ title: test.title,
++ fullTitle: test.fullTitle(),
++ duration: test.duration,
++ err: errorJSON(test.err || {})
++ }
++}
++
++/**
++ * Transform `error` into a JSON object.
++ * @param {Error} err
++ * @return {Object}
++ */
++
++function errorJSON(err) {
++ var res = {};
++ Object.getOwnPropertyNames(err).forEach(function(key) {
++ res[key] = err[key];
++ }, err);
++ return res;
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/landing.js
+@@ -0,0 +1,96 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color;
++
++/**
++ * Expose `Landing`.
++ */
++
++exports = module.exports = Landing;
++
++/**
++ * Airplane color.
++ */
++
++Base.colors.plane = 0;
++
++/**
++ * Airplane crash color.
++ */
++
++Base.colors['plane crash'] = 31;
++
++/**
++ * Runway color.
++ */
++
++Base.colors.runway = 90;
++
++/**
++ * Initialize a new `Landing` reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Landing(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , width = Base.window.width * .75 | 0
++ , total = runner.total
++ , stream = process.stdout
++ , plane = color('plane', '✈')
++ , crashed = -1
++ , n = 0;
++
++ function runway() {
++ var buf = Array(width).join('-');
++ return ' ' + color('runway', buf);
++ }
++
++ runner.on('start', function(){
++ stream.write('\n\n\n ');
++ cursor.hide();
++ });
++
++ runner.on('test end', function(test){
++ // check if the plane crashed
++ var col = -1 == crashed
++ ? width * ++n / total | 0
++ : crashed;
++
++ // show the crash
++ if ('failed' == test.state) {
++ plane = color('plane crash', '✈');
++ crashed = col;
++ }
++
++ // render landing strip
++ stream.write('\u001b['+(width+1)+'D\u001b[2A');
++ stream.write(runway());
++ stream.write('\n ');
++ stream.write(color('runway', Array(col).join('⋅')));
++ stream.write(plane)
++ stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
++ stream.write(runway());
++ stream.write('\u001b[0m');
++ });
++
++ runner.on('end', function(){
++ cursor.show();
++ console.log();
++ self.epilogue();
++ });
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++Landing.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/list.js
+@@ -0,0 +1,63 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , cursor = Base.cursor
++ , color = Base.color;
++
++/**
++ * Expose `List`.
++ */
++
++exports = module.exports = List;
++
++/**
++ * Initialize a new `List` test reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function List(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , n = 0;
++
++ runner.on('start', function(){
++ console.log();
++ });
++
++ runner.on('test', function(test){
++ process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
++ });
++
++ runner.on('pending', function(test){
++ var fmt = color('checkmark', ' -')
++ + color('pending', ' %s');
++ console.log(fmt, test.fullTitle());
++ });
++
++ runner.on('pass', function(test){
++ var fmt = color('checkmark', ' '+Base.symbols.dot)
++ + color('pass', ' %s: ')
++ + color(test.speed, '%dms');
++ cursor.CR();
++ console.log(fmt, test.fullTitle(), test.duration);
++ });
++
++ runner.on('fail', function(test, err){
++ cursor.CR();
++ console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
++ });
++
++ runner.on('end', self.epilogue.bind(self));
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++List.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/markdown.js
+@@ -0,0 +1,126 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , utils = require('../utils');
++
++/**
++ * Constants
++ */
++
++var SUITE_PREFIX = '$';
++
++/**
++ * Expose `Markdown`.
++ */
++
++exports = module.exports = Markdown;
++
++/**
++ * Initialize a new `Markdown` reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function Markdown(runner) {
++ Base.call(this, runner);
++
++ var self = this
++ , stats = this.stats
++ , level = 0
++ , buf = '';
++
++ function title(str) {
++ return Array(level + 1).join('#') + ' ' + str;
++ }
++
++ function indent() {
++ return Array(level).join(' ');
++ }
++
++ function mapTOC(suite, obj) {
++ var ret = obj,
++ key = SUITE_PREFIX + suite.title;
++ obj = obj[key] = obj[key] || { suite: suite };
++ suite.suites.forEach(function(suite){
++ mapTOC(suite, obj);
++ });
++ return ret;
++ }
++
++ function stringifyTOC(obj, level) {
++ ++level;
++ var buf = '';
++ var link;
++ for (var key in obj) {
++ if ('suite' == key) continue;
++ if (key !== SUITE_PREFIX) {
++ link = ' - [' + key.substring(1) + ']';
++ link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
++ buf += Array(level).join(' ') + link;
++ }
++ buf += stringifyTOC(obj[key], level);
++ }
++ return buf;
++ }
++
++ function generateTOC() {
++ return suites.map(generateTOC_).join('')
++ }
++
++ function generateTOC_(suite) {
++ var obj = mapTOC(suite, {});
++ return stringifyTOC(obj, 0);
++ }
++
++ var suites = []
++ var currentSuite = null
++ runner.on('suite', function(suite){
++ currentSuite = suite
++ if (suite.root) {
++ suites.push(suite)
++ }
++ ++level;
++ var slug = utils.slug(suite.fullTitle());
++ buf += '<a name="' + slug + '"></a>' + '\n';
++ buf += title(suite.title) + '\n';
++ });
++
++ runner.on('suite end', function(suite){
++ if (suite.ok) {
++ buf += '\nok - ' + suite.title + '\n'
++ } else {
++ buf += '\nnot ok - ' + suite.title + '\n'
++ }
++ --level;
++ });
++
++ runner.on('test', function(test){
++ if (!test.ok || test.pending) {
++ var code = utils.clean(test.fn.toString());
++ buf += test.title + '.\n';
++ if (code) {
++ buf += '\n```js\n';
++ buf += code + '\n';
++ buf += '```\n';
++ }
++ var stack = test.err && test.err.stack
++ if (!stack) {
++ stack = test.result && test.result.diag && test.result.diag.stack
++ }
++ if (stack) {
++ buf += '\n```\n' + stack + '\n```\n';
++ }
++ buf += '\n\n';
++ }
++ });
++
++ runner.on('end', function(){
++ process.stdout.write('# TOC\n');
++ process.stdout.write(generateTOC());
++ process.stdout.write('\n\n');
++ process.stdout.write(buf);
++ });
++}
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/nyan.js
+@@ -0,0 +1,260 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base');
++
++/**
++ * Expose `Dot`.
++ */
++
++exports = module.exports = NyanCat;
++
++/**
++ * Initialize a new `Dot` matrix test reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function NyanCat(runner) {
++ Base.call(this, runner);
++ var self = this
++ , stats = this.stats
++ , width = Base.window.width * .75 | 0
++ , rainbowColors = this.rainbowColors = self.generateColors()
++ , colorIndex = this.colorIndex = 0
++ , numerOfLines = this.numberOfLines = 4
++ , trajectories = this.trajectories = [[], [], [], []]
++ , nyanCatWidth = this.nyanCatWidth = 11
++ , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
++ , scoreboardWidth = this.scoreboardWidth = 5
++ , tick = this.tick = 0
++ , n = 0;
++
++ runner.on('start', function(){
++ Base.cursor.hide();
++ self.draw();
++ });
++
++ runner.on('pending', function(test){
++ self.draw();
++ });
++
++ runner.on('pass', function(test){
++ self.draw();
++ });
++
++ runner.on('fail', function(test, err){
++ self.draw();
++ });
++
++ runner.on('end', function(){
++ Base.cursor.show();
++ for (var i = 0; i < self.numberOfLines; i++) write('\n');
++ self.epilogue();
++ });
++}
++
++/**
++ * Draw the nyan cat
++ *
++ * @api private
++ */
++
++NyanCat.prototype.draw = function(){
++ this.appendRainbow();
++ this.drawScoreboard();
++ this.drawRainbow();
++ this.drawNyanCat();
++ this.tick = !this.tick;
++};
++
++/**
++ * Draw the "scoreboard" showing the number
++ * of passes, failures and pending tests.
++ *
++ * @api private
++ */
++
++NyanCat.prototype.drawScoreboard = function(){
++ var stats = this.stats;
++
++ function draw(type, n) {
++ write(' ');
++ write(Base.color(type, n));
++ write('\n');
++ }
++
++ draw('green', stats.passes);
++ draw('fail', stats.failures);
++ draw('pending', stats.pending);
++ write('\n');
++
++ this.cursorUp(this.numberOfLines);
++};
++
++/**
++ * Append the rainbow.
++ *
++ * @api private
++ */
++
++NyanCat.prototype.appendRainbow = function(){
++ var segment = this.tick ? '_' : '-';
++ var rainbowified = this.rainbowify(segment);
++
++ for (var index = 0; index < this.numberOfLines; index++) {
++ var trajectory = this.trajectories[index];
++ if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
++ trajectory.push(rainbowified);
++ }
++};
++
++/**
++ * Draw the rainbow.
++ *
++ * @api private
++ */
++
++NyanCat.prototype.drawRainbow = function(){
++ var self = this;
++
++ this.trajectories.forEach(function(line, index) {
++ write('\u001b[' + self.scoreboardWidth + 'C');
++ write(line.join(''));
++ write('\n');
++ });
++
++ this.cursorUp(this.numberOfLines);
++};
++
++/**
++ * Draw the nyan cat
++ *
++ * @api private
++ */
++
++NyanCat.prototype.drawNyanCat = function() {
++ var self = this;
++ var startWidth = this.scoreboardWidth + this.trajectories[0].length;
++ var dist = '\u001b[' + startWidth + 'C';
++ var padding = '';
++
++ write(dist);
++ write('_,------,');
++ write('\n');
++
++ write(dist);
++ padding = self.tick ? ' ' : ' ';
++ write('_|' + padding + '/\\_/\\ ');
++ write('\n');
++
++ write(dist);
++ padding = self.tick ? '_' : '__';
++ var tail = self.tick ? '~' : '^';
++ var face;
++ write(tail + '|' + padding + this.face() + ' ');
++ write('\n');
++
++ write(dist);
++ padding = self.tick ? ' ' : ' ';
++ write(padding + '"" "" ');
++ write('\n');
++
++ this.cursorUp(this.numberOfLines);
++};
++
++/**
++ * Draw nyan cat face.
++ *
++ * @return {String}
++ * @api private
++ */
++
++NyanCat.prototype.face = function() {
++ var stats = this.stats;
++ if (stats.failures) {
++ return '( x .x)';
++ } else if (stats.pending) {
++ return '( o .o)';
++ } else if(stats.passes) {
++ return '( ^ .^)';
++ } else {
++ return '( - .-)';
++ }
++};
++
++/**
++ * Move cursor up `n`.
++ *
++ * @param {Number} n
++ * @api private
++ */
++
++NyanCat.prototype.cursorUp = function(n) {
++ write('\u001b[' + n + 'A');
++};
++
++/**
++ * Move cursor down `n`.
++ *
++ * @param {Number} n
++ * @api private
++ */
++
++NyanCat.prototype.cursorDown = function(n) {
++ write('\u001b[' + n + 'B');
++};
++
++/**
++ * Generate rainbow colors.
++ *
++ * @return {Array}
++ * @api private
++ */
++
++NyanCat.prototype.generateColors = function(){
++ var colors = [];
++
++ for (var i = 0; i < (6 * 7); i++) {
++ var pi3 = Math.floor(Math.PI / 3);
++ var n = (i * (1.0 / 6));
++ var r = Math.floor(3 * Math.sin(n) + 3);
++ var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
++ var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
++ colors.push(36 * r + 6 * g + b + 16);
++ }
++
++ return colors;
++};
++
++/**
++ * Apply rainbow to the given `str`.
++ *
++ * @param {String} str
++ * @return {String}
++ * @api private
++ */
++
++NyanCat.prototype.rainbowify = function(str){
++ if (!Base.useColors)
++ return str;
++ var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
++ this.colorIndex += 1;
++ return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
++};
++
++/**
++ * Stdout helper.
++ */
++
++function write(string) {
++ process.stdout.write(string);
++}
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++NyanCat.prototype.__proto__ = Base.prototype;
+--- /dev/null
++++ b/node_modules/tap-mocha-reporter/lib/reporters/xunit.js
+@@ -0,0 +1,149 @@
++/**
++ * Module dependencies.
++ */
++
++var Base = require('./base')
++ , utils = require('../utils')
++ , fs = require('fs')
++ , escape = utils.escape;
++
++/**
++ * Save timer references to avoid Sinon interfering (see GH-237).
++ */
++
++var Date = global.Date
++ , setTimeout = global.setTimeout
++ , setInterval = global.setInterval
++ , clearTimeout = global.clearTimeout
++ , clearInterval = global.clearInterval;
++
++/**
++ * Expose `XUnit`.
++ */
++
++exports = module.exports = XUnit;
++
++/**
++ * Initialize a new `XUnit` reporter.
++ *
++ * @param {Runner} runner
++ * @api public
++ */
++
++function XUnit(runner, options) {
++ Base.call(this, runner);
++ var stats = this.stats
++ , tests = []
++ , self = this;
++
++ if (options.reporterOptions && options.reporterOptions.output) {
++ if (! fs.createWriteStream) {
++ throw new Error('file output not supported in browser');
++ }
++ self.fileStream = fs.createWriteStream(options.reporterOptions.output);
++ }
++
++ runner.on('pending', function(test){
++ tests.push(test);
++ });
++
++ runner.on('pass', function(test){
++ tests.push(test);
++ });
++
++ runner.on('fail', function(test){
++ tests.push(test);
++ });
++
++ runner.on('end', function(){
++ self.write(tag('testsuite', {
++ name: 'TAP Tests'
++ , tests: stats.tests
++ , failures: stats.failures
++ , errors: stats.failures
++ , skipped: stats.tests - stats.failures - stats.passes
++ , timestamp: (new Date).toUTCString()
++ , time: (stats.duration / 1000) || 0
++ }, false));
++
++ tests.forEach(function(t) { self.test(t); });
++ self.write('</testsuite>');
++ });
++}
++
++/**
++ * Override done to close the stream (if it's a file).
++ */
++XUnit.prototype.done = function(failures, fn) {
++ if (this.fileStream) {
++ this.fileStream.end(function() {
++ fn(failures);
++ });
++ } else {
++ fn(failures);
++ }
++};
++
++/**
++ * Inherit from `Base.prototype`.
++ */
++
++XUnit.prototype.__proto__ = Base.prototype;
++
++/**
++ * Write out the given line
++ */
++XUnit.prototype.write = function(line) {
++ if (this.fileStream) {
++ this.fileStream.write(line + '\n');
++ } else {
++ console.log(line);
++ }
++};
++
++/**
++ * Output tag for the given `test.`
++ */
++
++XUnit.prototype.test = function(test, ostream) {
++ var attrs = {
++ classname: test.parent.fullTitle()
++ , name: test.title
++ , time: (test.duration / 1000) || 0
++ };
++
++ if ('failed' == test.state) {
++ var err = test.err;
++ this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + "\n" + err.stack))));
++ } else if (test.pending) {
++ this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
++ } else {
++ this.write(tag('testcase', attrs, true) );
++ }
++};
++
++/**
++ * HTML tag helper.
++ */
++
++function tag(name, attrs, close, content) {
++ var end = close ? '/>' : '>'
++ , pairs = []
++ , tag;
++
++ for (var key in attrs) {
++ pairs.push(key + '="' + escape(attrs[key]) + '"');
++ }
++
++ tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
++ if (content) tag += content + '</' + name + end;
++ return tag;
++}
++
++/**
++ * Return cdata escaped CDATA `str`.
++ */
++
++function cdata(str) {
++ return '<![CDATA[' + escape(str) + ']]>';
++}
diff --git a/debian/patches/sbuild_disable_tests.patch b/debian/patches/sbuild_disable_tests.patch
index b8d581f..fd59c8f 100644
--- a/debian/patches/sbuild_disable_tests.patch
+++ b/debian/patches/sbuild_disable_tests.patch
@@ -1,15 +1,7 @@
-Description: disable tests that are okay to fail on sbuild
- one is racey, the other one requires specific output fds
-Last-Update: 2014-10-20
+Description: disable tests requiring specific setup
+Last-Update: 2016-11-11
Author: Jérémy Lal <kapouer at melix.org>
Forwarded: not-needed
---- a/test/output-childtest-description.js
-+++ b/test/output-childtest-description.js
-@@ -1,3 +1,4 @@
-+return;
- var tap = require("../")
- , fs = require("fs")
- , path = require('path')
--- a/test/segv.js
+++ b/test/segv.js
@@ -1,3 +1,4 @@
diff --git a/debian/patches/series b/debian/patches/series
index 9347409..a0134ff 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1,7 @@
+module-foreground-child.patch
+module-tap-mocha-reporter.patch
+module-stack-utils.patch
+module-clean-yaml-object.patch
+module-buffer-to-string.patch
nodejs_rename.patch
use_available_modules.patch
-sbuild_disable_tests.patch
-mitigate_test_segv.patch
diff --git a/debian/patches/use_available_modules.patch b/debian/patches/use_available_modules.patch
index b4c6faf..464f03f 100644
--- a/debian/patches/use_available_modules.patch
+++ b/debian/patches/use_available_modules.patch
@@ -1,56 +1,147 @@
Description: use already packaged modules
- ... instead of adding new ones that do the same thing
+ instead of adding new ones that do the same thing
Forwarded: not-needed, would probably get upstream angry
Author: Jérémy Lal <kapouer at melix.org>
Last-Update: 2014-10-20
---- a/lib/tap-assert.js
-+++ b/lib/tap-assert.js
-@@ -1,9 +1,27 @@
- // an assert module that returns tappable data for each assertion.
--var difflet = require('difflet')
-- , deepEqual = require('deep-equal')
-- , bufferEqual = require('buffer-equal')
-+var createPatch = require('diff').createPatch
-+ , assertDeepEqual = require('assert').deepEqual
- , Buffer = require('buffer').Buffer
-
-+function deepEqual(a, b) {
-+ try {
-+ assertDeepEqual(a, b);
-+ } catch(e) {
-+ return false;
-+ }
-+ return true;
+--- a/lib/assert.js
++++ b/lib/assert.js
+@@ -1,6 +1,9 @@
+ var synonyms = require('./synonyms.js')
+-var deeper = require('deeper') // strict
+-var shallower = require('only-shallow') // in touch with its feelings
++var deepEqual = require('deep-equal')
++var deeper = function(a, b) {
++ return deepEqual(a, b, {strict: true});
+}
++var shallower = deepEqual;
+ var tmatch = require('tmatch') // ok with partial estimates
+
+ // Load Buffer the old way for browserify's sake
+--- a/bin/run.js
++++ b/bin/run.js
+@@ -3,12 +3,17 @@
+ var fs = require('fs')
+ var spawn = require('child_process').spawn
+ var fg = require('foreground-child')
+-var opener = require('opener')
+-var colorSupport = require('color-support')
+-var nycBin = require.resolve('nyc/bin/nyc.js')
++var colorSupport = require('supports-color')
++var nycBin;
++function getNycBin() {
++ if (!nycBin) {
++ nycBin = require.resolve('nyc/bin/nyc.js');
++ }
++ return nycBin;
++}
+ var glob = require('glob')
+ var isexe = require('isexe')
+-var osHomedir = require('os-homedir')
++var osHomedir = require('os').homedir
+ var yaml = require('js-yaml')
+
+ var coverageServiceTest = process.env.COVERAGE_SERVICE_TEST === 'true'
+@@ -32,13 +37,18 @@
+ // Currently only Coveralls is supported, but the infrastructure
+ // is left in place in case some noble soul fixes the codecov
+ // module in the future. See https://github.com/tapjs/node-tap/issues/270
+-var coverageServices = [
+- {
++var coverageServices = [];
+
-+function bufferEqual(a, b) {
-+ if (!Buffer.isBuffer(a)) return false;
-+ if (!Buffer.isBuffer(b)) return false;
-+ if (a.length != b.length) return false;
-+ for (var i=0, len=a.length; i < len; i++) {
-+ if (a[i] != b[i]) return false;
-+ }
-+ return true;
++try {
++ coverageServices.push({
+ env: 'COVERALLS_REPO_TOKEN',
+ bin: require.resolve('coveralls/bin/coveralls.js'),
+ name: 'Coveralls'
+- }
+-]
++ });
++} catch(ex) {
++ console.info("coveralls not enabled");
+}
+
- module.exports = assert
- var syns = {}
-@@ -405,6 +423,8 @@
- }})())
+ main()
+
+@@ -397,7 +407,7 @@
+ function respawnWithCoverage (options) {
+ // console.error('respawn with coverage')
+ // Re-spawn with coverage
+- var args = [nycBin].concat(
++ var args = [getNycBin()].concat(
+ '--silent',
+ options.nycArgs,
+ '--',
+@@ -479,7 +489,7 @@
+ }
+ }
+
+- var args = [nycBin, 'report', '--reporter', options.coverageReport]
++ var args = [getNycBin(), 'report', '--reporter', options.coverageReport]
+ // console.error('run coverage report', args)
+
+ var child
+@@ -493,7 +503,7 @@
+ child = fg(node, args)
+ if (options.coverageReport === 'lcov' && options.browser) {
+ child.on('exit', function () {
+- opener('coverage/lcov-report/index.html')
++ require('opener')('coverage/lcov-report/index.html')
+ })
+ }
+ }
+@@ -533,7 +543,7 @@
}
-+
-+
- function diffString (f, w) {
- if (w === f) return null
- var p = 0
-@@ -416,7 +436,7 @@
+ function runCoverageCheck (options, code, signal) {
+- var args = [nycBin, 'check-coverage'].concat(coverageCheckArgs(options))
++ var args = [getNycBin(), 'check-coverage'].concat(coverageCheckArgs(options))
+
+ var child = fg(node, args)
+ child.removeAllListeners('close')
+@@ -549,7 +559,7 @@
+ }
+
+ function nycHelp () {
+- fg(node, [nycBin, '--help'])
++ fg(node, [getNycBin(), '--help'])
}
- function diffObject (f, w) {
-- return difflet({ indent : 2, comment : true }).compare(w, f)
-+ return createPatch('', JSON.stringify(w, null, 2), JSON.stringify(f, null, 2));
+ function nycVersion () {
+--- a/node_modules/tap-mocha-reporter/lib/reporters/base.js
++++ b/node_modules/tap-mocha-reporter/lib/reporters/base.js
+@@ -6,7 +6,7 @@
+ , diff = require('diff')
+ , ms = require('../ms')
+ , utils = require('../utils')
+- , supportsColor = require('color-support')()
++ , supportsColor = require('supports-color')
+
+ /**
+ * Save timer references to avoid Sinon interfering (see GH-237).
+--- a/lib/test.js
++++ b/lib/test.js
+@@ -6,8 +6,6 @@
+ Readable = require('readable-stream').Readable
}
- function diff (f, w, p) {
+-var Promise = require('bluebird')
+-
+ function Deferred () {
+ this.resolve = null
+ this.reject = null
+--- a/node_modules/tap-mocha-reporter/lib/reporters/classic.js
++++ b/node_modules/tap-mocha-reporter/lib/reporters/classic.js
+@@ -9,8 +9,9 @@
+ , ms = require('../ms.js')
+ , diff = require('diff')
+ , utils = require('../utils.js')
+- , uclen = require('unicode-length').get
+- , colorSupport = require('color-support')()
++ , stripAnsi = require('strip-ansi')
++ , uclen = function(str) { return stripAnsi(str).length }
++ , colorSupport = require('supports-color')
+
+ function hasOwnProperty (obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key)
diff --git a/debian/rules b/debian/rules
index 78efe0e..1519373 100755
--- a/debian/rules
+++ b/debian/rules
@@ -7,15 +7,12 @@
%:
dh $@
-override_dh_install:
- dh_install
+override_dh_fixperms:
+ dh_fixperms
chmod a+x debian/node-tap/usr/lib/nodejs/tap/bin/*.js
-override_dh_auto_test:
- ./bin/tap.js test/*.js
-
-override_dh_auto_build: debian/tap.1
-
-debian/tap.1:
- help2man -N -n "Test-Anything-Protocol module for Node.js" bin/tap.js -o "$@"
+override_dh_auto_build:
+ help2man -N -n "Test-Anything-Protocol module for Node.js" --no-discard-stderr bin/run.js -o debian/tap.1
+override_dh_auto_clean:
+ rm -f debian/tap.1
--
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