Commit b0b244cc authored by Jérémy Lal's avatar Jérémy Lal

New upstream version 7.1.2

parent 18f66a55
......@@ -2,5 +2,6 @@ sudo: false
language: node_js
node_js:
- '0.10'
- '0.12'
- '4'
- '5'
- '6'
# contributors sorted by whether or not they're me
Isaac Z. Schlueter <i@izs.me>
baudehlo <helpme+github@gmail.com>
James Halliday <mail@substack.net>
Jason Smith (air) <jhs@iriscouch.com>
Pedro P. Candel <kusorbox@gmail.com>
Stein Martin Hustad <stein@hustad.com>
Trent Mick <trentm@gmail.com>
Corey Richardson <kb1pkl@aim.com>
Raynos <raynos2@gmail.com>
Siddharth Mahendraker <siddharth_mahen@me.com>
Ryan Graham <r.m.graham@gmail.com>
## 4.0
Raise an error if `t.end()` is explicitly called more than once. This
is a breaking change, because it can cause previously-passing tests to
fail, if they did `t.end()` in multiple places.
Support promises returned by mochalike functions.
## 3.1
Support sending coverage output to both codecov.io and coveralls.io.
## 3.0
Upgrade to nyc 5. This means that `config.nyc.exclude` arrays in
`package.json` now take globs instead of regular expressions.
## 2.3
Use the name of the function supplied to `t.test(fn)` as the test name
if a string name is not provided.
Better support for sparse arrays.
## 2.2
Add support for Codecov.io as well as Coveralls.io.
Catch failures that come after an otherwise successful test set.
Fix timing of `t.on('end')` so that event fires *before* the next
child test is started, instead of immediately after it.
`t.throws()` can now be supplied a regexp for the expected Error
message.
## 2.1
Exit in failure on root test bailout.
Support promises returned by `t.test(fn)` function.
## 2.0
Update matching behavior using [tmatch](http://npm.im/tmatch). This
is a breaking change to `t.match`, `t.similar`, `t.has`, etc., but
brings them more in line with what people epirically seem to expect
these functions to do.
Deal with pending handles left open when a child process gets a
`SIGTERM` on timeout.
Remove domains in favor of more reliable and less invasive state and
error-catching bookkeeping.
## 1.4
Add `t.contains()` alias for `t.match()`.
Use `deeper` for deep object similarity testing.
Treat unfinished tests as failures.
Add support for pragmas in TAP output.
## 1.3
Bind all Test methods to object.
Add `t.tearDown()`, `t.autoend()`, so that the root export is Just
Another Test Object, which just happens to be piping to stdout.
Support getting an error object in bailout()
## 1.2
Better support for exit status codes.
## 1.1
Add coverage using nyc.
If a `COVERALLS_REPO_TOKEN` is provided, then run tests with coverage,
and pipe to coveralls.
## 1.0
Complete rewrite from 0.x.
Child tests implemented as nested TAP output, similar to Perl's `Test::More`.
## 0.x
The 0.x versions used a "flattened" approach to child tests, which
requires some bookkeeping.
It worked, mostly, but its primary success was inspiring
[tape](http://npm.im/tape) and tap v1 and beyond.
Please see [the tap website](http://www.node-tap.org/changelog/) for
the curated changelog.
- Check the `TODO.md` file to see stuff that is likely to be accepted.
- Check the [issues](https://github.com/tapjs/node-tap/issues) to see
stuff that is likely to be accepted.
- Every patch should have a new test that fails without the patch and
passes with the patch.
- All tests should pass on Node 0.8 and above. If some tests have to
be skipped for very old Node versions that's fine, but the
functionality should still work as intended.
- Run `node scripts/generate-test-test.js test/test/*.js` to
re-generate the output tests whenever output is changed. However,
when you do this, make sure to check the change to ensure that it's
what you intended, and that it didn't cause any other inadvertent
changes.
- Run `npm run regen-fixtures` to re-generate the output tests
whenever output is changed. However, when you do this, make sure to
check the change to ensure that it's what you intended, and that it
didn't cause any other inadvertent changes.
- Prefer adding cases to an existing test rather than writing a new
one from scratch. For example, add a new test in `test/test/*.js`
rather than create a new test that validates test output.
- Docs should be changed on the `gh-pages` branch
This diff is collapsed.
- fix the markdown reporter
- make it faster (seems like mostly this is just node spawn() overhead)
- read a config file at ~/.taprc for setting default colors,
reporters, etc
- make colors (and diff colors) configurable
- tests for reporter output
- split lib/stack.js out into a separate module
- Add more of the mocha globals when you call tap.mochaGlobals()
environment:
matrix:
- nodejs_version: '5'
- nodejs_version: '4'
- nodejs_version: '0.12'
install:
- ps: Install-Product node $env:nodejs_version
- set CI=true
- npm -g install npm@latest
- set PATH=%APPDATA%\npm;%PATH%
- npm install
matrix:
fast_finish: true
build: off
version: '{build}'
shallow_clone: true
clone_depth: 1
test_script:
- npm test -- -Rclassic --no-coverage --timeout=3600
if (process.platform === 'win32') {
// On windows, there is no good way to check that a file is executable
module.exports = function isExe () {
return true
}
} else {
module.exports = function isExe (stat) {
var mod = stat.mode
var uid = stat.uid
var gid = stat.gid
var u = parseInt('100', 8)
var g = parseInt('010', 8)
var o = parseInt('001', 8)
var ug = u | g
var ret = (mod & o) ||
(mod & g) && process.getgid && gid === process.getgid() ||
(mod & u) && process.getuid && uid === process.getuid() ||
(mod & ug) && process.getuid && process.getuid() === 0
return ret
}
}
This diff is collapsed.
......@@ -9,6 +9,12 @@ To parse TAP data from stdin, specify "-" as a filename.
Short options are parsed gnu-style, so for example '-bCRspec' would be
equivalent to '--bail --no-color --reporter=spec'
If the --check-coverage or --coverage-report options are provided, but
no test files are specified, then a coverage report or coverage check
will be run on the data from the last test run.
Coverage is never enabled for stdin.
Options:
-c --color Use colors (Default for TTY)
......@@ -48,10 +54,7 @@ Options:
If a COVERALLS_REPO_TOKEN environment
variable is set, then coverage is
captured by default and sent to the
coveralls.io service. If a CODECOV_TOKEN
environment variable is set, then coverage is
captured by default and sent to the
codecov.io service.
coveralls.io service.
--no-coverage --no-cov Do not capture coverage information.
Note that if nyc is already loaded, then
......@@ -62,14 +65,19 @@ Options:
Default is 'text' when running on the
command line, or 'text-lcov' when piping
to coveralls or codecov.
to coveralls.
If 'lcov' is used, then the report will
If 'html' is used, then the report will
be opened in a web browser after running.
This can be run on its own at any time
after a test run that included coverage.
--no-coverage-report Do not output a coverage report.
--no-browser Do not open a web browser after
generating an html coverage report.
-t<n> --timeout=<n> Time out test files after <n> seconds.
Defaults to 30, or the value of the
TAP_TIMEOUT environment variable.
......@@ -78,6 +86,12 @@ Options:
-v --version show the version of this program
--node-arg=<arg> Pass an argument to Node binary in all
child processes. Run 'node --help' to
see a list of all relevant arguments.
This can be specified multiple times to
pass multiple args to Node.
-gc --expose-gc Expose the gc() function to Node tests
--debug Run JavaScript tests with node --debug
......@@ -88,6 +102,84 @@ Options:
--strict Run JS tests in 'use strict' mode
--test-arg=<arg> Pass an argument to test files spawned
by the tap command line executable.
This can be specified multiple times to
pass multiple args to test scripts.
--nyc-arg=<arg> Pass an argument to nyc when running
child processes with coverage enabled.
This can be specified multiple times to
pass multiple args to nyc.
--check-coverage Check whether coverage is within
thresholds provided. Setting this
explicitly will default --coverage to
true.
This can be run on its own any time
after a test run that included coverage.
--branches what % of branches must be covered?
Setting this will default both
--check-coverage and --coverage to true.
[default: 0]
--functions what % of functions must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 0]
--lines what % of lines must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 90]
--statements what % of statements must be covered?
Setting this explicitly will default both
--check-coverage and --coverage to true.
[default: 0]
--100 Full coverage, 100%.
Sets branches, statements, functions,
and lines to 100.
--nyc-help Print nyc usage banner. Useful for
viewing options for --nyc-arg.
--nyc-version Print version of nyc used by tap.
--dump-config Dump the config options in JSON format.
-- Stop parsing flags, and treat any additional
command line arguments as filenames.
Environment Variables:
TAP_RCFILE A yaml formatted file which can set any
of the above options. Defaults to
$HOME/.taprc
TAP_TIMEOUT Default value for --timeout option.
TAP_COLORS Set to '1' to force color output, or '0'
to prevent color output.
TAP_BAIL Bail out on the first test failure.
Used internally when '--bailout' is set.
TAP Set to '1' to force standard TAP output,
and suppress any reporters. Used when
running child tests so that their output
is parseable by the test harness.
_TAP_COVERAGE_ Reserved for internal use.
Config Files:
You can create a yaml file with any of the options above. By default,
the file at ~/.taprc will be loaded, but the TAP_RCFILE environment
variable can modify this.
Run 'tap --dump-config' for a listing of what can be set in that file.
Each of the keys corresponds to one of the options above.
/* standard ignore next */
describe('parent', function () {
before('name', function () {
console.error('before')
});
after(function () {
console.error('after')
});
beforeEach(function () {
console.error('beforeEach')
});
afterEach('after each name', function () {
console.error('afterEach')
});
it('first', function () {
console.error('first it')
})
it('second', function () {
console.error('second it')
})
describe('child 1', function () {
console.error('in child 1')
before(function () {
console.error('before 2')
});
after(function () {
console.error('after 2')
});
beforeEach(function () {
console.error('beforeEach 2')
});
afterEach(function () {
console.error('afterEach 2')
});
it('first x', function () {
console.error('first it')
})
it('second', function (done) {
console.error('second it')
setTimeout(done)
})
describe('gc 1', function () {
it('first y', function () {
console.error('first it')
})
it('second', function (done) {
console.error('second it')
setTimeout(done)
})
it('third', function (done) {
console.error('third it')
done()
})
})
it('third after gc 1', function () {
console.error('second it')
})
})
describe('child 2', function () {
console.error('in child 2')
it('first z', function () {
console.error('first it')
})
it('second', function (done) {
console.error('second it')
setTimeout(done)
})
it('third', function (done) {
console.error('third it')
done()
})
})
it('third', function () {
console.error('second it')
})
})
......@@ -169,7 +169,11 @@ function decorate (t) {
for (var i = 0; i < arguments.length - 1; i++) {
var arg = arguments[i]
if (typeof arg === 'function') {
fn = arg
if (arg === Error || arg.prototype instanceof Error) {
wanted = arg
} else if (!fn) {
fn = arg
}
} else if (typeof arg === 'string' && arg) {
m = arg
} else if (typeof arg === 'object') {
......@@ -181,9 +185,10 @@ function decorate (t) {
}
}
for (i in e__) {
// Copy local properties of the 'extra' object, like 'skip' etc
Object.keys(e__).forEach(function (i) {
e[i] = e__[i]
}
})
if (!m) {
m = fn && fn.name || 'expected to throw'
......@@ -198,6 +203,8 @@ function decorate (t) {
w.name = wanted.name
}
// intentionally copying non-local properties, since this
// is an Error object, and those are funky.
for (i in wanted) {
w[i] = wanted[i]
}
......@@ -208,10 +215,6 @@ function decorate (t) {
if (e !== wanted) {
e.wanted = wanted
}
} else if (typeof wanted === 'string') {
wanted = {
message: wanted
}
}
}
......
......@@ -7,9 +7,9 @@ var stack = require('./stack.js')
exports.it = it
exports.describe = describe
exports.global = function () {
for (var g in exports) {
Object.keys(exports).forEach(function (g) {
global[g] = exports[g]
}
})
}
var t = require('./root.js')
......
......@@ -10,45 +10,84 @@ if (tap._timer && tap._timer.unref) {
tap._name = 'TAP'
// No sense continuing after bailout!
tap.on('bailout', function () {
// allow 1 tick for any other bailout handlers to run first.
tap.bailout = function (reason) {
Test.prototype.bailout.apply(tap, arguments)
process.exit(1)
})
}
// need to autoend if a teardown is added.
// otherwise we may never see process.on('exit')!
tap.tearDown = function (fn) {
var ret = Test.prototype.tearDown.apply(tap, arguments)
tap.autoend()
return ret
}
var didPipe = false
process.on('exit', function (code) {
tap.endAll()
if (didPipe) {
tap.endAll()
}
if (!tap._ok && code === 0) {
process.exit(1)
}
})
// need to autoend if a teardown is added.
// otherwise we may never see process.on('exit')!
tap.tearDown = function (fn) {
var ret = Test.prototype.tearDown.apply(tap, arguments)
tap.autoend()
return ret
tap.pipe = function () {
didPipe = true
tap.push = Test.prototype.push
tap.pipe = Test.prototype.pipe
process.on('uncaughtException', onUncaught)
return Test.prototype.pipe.apply(tap, arguments)
}
function pipe () {
if (didPipe) {
return
}
tap.pipe(process.stdout)
}
tap.pipe(process.stdout)
tap.push = function push () {
pipe()
return tap.push.apply(tap, arguments)
}
tap.mocha = require('./mocha.js')
tap.mochaGlobals = tap.mocha.global
tap.Test = Test
tap.synonyms = require('./synonyms.js')
process.on('uncaughtException', function onUncaught (er) {
function onUncaught (er) {
var child = tap
while (child._currentChild && child._currentChild instanceof Test) {
child = child._currentChild
}
child.threw(er)
child._tryResumeEnd()
}
// remove any and all zombie processes on quit
function dezombie () {
if (tap._currentChild && tap._currentChild.kill) {
tap._currentChild.kill('SIGKILL')
}
}
tap.on('end', function () {
process.removeListener('uncaughtException', onUncaught)
})
// SIGTERM means being forcibly killed, almost always by timeout
var onExit = require('signal-exit')
onExit(function (code, signal) {
if (signal !== 'SIGTERM') {
dezombie()
if (signal !== 'SIGTERM' || !didPipe) {
return
}
......@@ -58,16 +97,25 @@ onExit(function (code, signal) {
h !== process.stderr
})
var requests = process._getActiveRequests()
var msg = 'received SIGTERM with pending event queue activity'
tap.fail(msg, {
requests: requests.map(function (r) {
// Ignore this because it's really hard to test cover in a way
// that isn't inconsistent and unpredictable.
/* istanbul ignore next */
var extra = {
at: null,
signal: signal
}
if (requests.length) {
extra.requests = requests.map(function (r) {
var ret = { type: r.constructor.name }
if (r.context) {
ret.context = r.context
}
return ret
}),
handles: handles.map(function (h) {
})
}
if (handles.length) {
extra.handles = handles.map(function (h) {
var ret = { type: h.constructor.name }
if (h.msecs) {
ret.msecs = h.msecs
......@@ -82,9 +130,23 @@ onExit(function (code, signal) {
ret.connectionKey = h._connectionKey
}
return ret
}),
at: null
})
})
}
tap.end()
if (!tap._ended) {
tap._onTimeout(extra)
} else {
console.error('possible timeout: SIGTERM received after tap end')
if (extra.handles || extra.requests) {
delete extra.signal
if (!extra.at) {
delete extra.at
}
var yaml = require('js-yaml')
console.error(' ---\n ' +
yaml.safeDump(extra).split('\n').join('\n ').trim() +
'\n ...\n')
}
process.exit(1)
}
})
exports.capture = capture
exports.captureString = captureString
exports.at = at
exports.parseLine = parseLine
exports.clean = clean
var cwd = process.cwd()
// var methods =[
// 'getThis',
// 'getFunction',
// 'getTypeName',
// 'getFunctionName',
// 'getMethodName',
// 'getFileName',
// 'getLineNumber',
// 'getColumnNumber',
// 'getEvalOrigin',
// 'isToplevel',
// 'isEval',
// 'isNative',
// 'isConstructor'
// ]
function clean (stack) {