Skip to content

Commit

Permalink
cleanup Stdin for boosting test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Jan 25, 2017
1 parent f6023b1 commit 7510a6d
Show file tree
Hide file tree
Showing 26 changed files with 375 additions and 58 deletions.
1 change: 1 addition & 0 deletions lib/base.js
Expand Up @@ -185,6 +185,7 @@ Base.prototype.debug = (/\btap\b/i.test(process.env.NODE_DEBUG || ''))

function nodebug () {}

/* istanbul ignore next */
function debug () {
var prefix = 'TAP ' + process.pid + ' ' + this.name + ': '
var msg = util.format.apply(util, arguments).trim()
Expand Down
1 change: 1 addition & 0 deletions lib/clean-yaml-object.js
Expand Up @@ -47,6 +47,7 @@ function yamlFilter (propertyName, isRoot, source, target) {

return !(propertyName === 'todo' ||
/^_?tapChild/.test(propertyName) ||
/^tapStream/.test(propertyName) ||
/^tapMochaTest/.test(propertyName) ||
propertyName === 'cb' ||
propertyName === 'name' ||
Expand Down
12 changes: 9 additions & 3 deletions lib/parse-test-args.js
Expand Up @@ -42,13 +42,19 @@ module.exports = function (name_, extra_, cb_, defaultName) {
if (!cb)
extra.todo = true

if (!name && extra.name)
name = extra.name

if (!name && cb && cb.name)
name = cb.name

name = name || defaultName
extra.name = name
extra.cb = cb || function () {
throw new Error('callback called for TODO test')
}
extra.cb = cb || todoCb
return extra
}

/* istanbul ignore next */
function todoCb () {
throw new Error('callback called for TODO test')
}
3 changes: 3 additions & 0 deletions lib/point.js
Expand Up @@ -9,6 +9,9 @@ function TestPoint (ok, message, extra) {
if (typeof ok !== 'boolean')
throw new TypeError('ok must be boolean')

if (!(this instanceof TestPoint))
return new TestPoint(ok, message, extra)

this.ok = ok ? 'ok ' : 'not ok '
this.message = tpMessage(message, extra)
}
Expand Down
9 changes: 4 additions & 5 deletions lib/spawn.js
Expand Up @@ -20,18 +20,17 @@ function Spawn (options) {
Base.call(this, options)

this.command = options.command
if (!this.command) {

if (!this.command)
throw new TypeError('no command provided')
}

this.args = options.args
// stdout must be a pipe
if (options.stdio) {
if (typeof options.stdio === 'string') {
if (typeof options.stdio === 'string')
this.stdio = [ options.stdio, 'pipe', options.stdio ]
} else {
else
this.stdio = options.stdio.slice(0)
}
} else
this.stdio = [ 0, 'pipe', 2 ]

Expand Down
8 changes: 5 additions & 3 deletions lib/stdin.js
Expand Up @@ -16,13 +16,15 @@ function Stdin (options) {
Base.call(this, options)

// This has to be here for node 0.10's wonky streams
process.stdin.pause()
this.stream = ownOr(options, 'tapStream', process.stdin)
this.stream.pause()
}

Stdin.prototype.main = function (cb) {
this.domain.add(process.stdin)
this.domain.add(this.stream)
this.setTimeout(this.options.timeout)
process.stdin.pipe(this.parser)
this.stream.pipe(this.parser)
this.stream.resume()
this.once('end', cb)
}

Expand Down
4 changes: 4 additions & 0 deletions lib/tap.js
@@ -1,4 +1,6 @@
var Test = require('./test.js')
var Stdin = require('./stdin.js')
var Spawn = require('./spawn.js')
var util = require('util')
var objToYaml = require('./obj-to-yaml.js')
var yaml = require('js-yaml')
Expand Down Expand Up @@ -59,6 +61,8 @@ process.on('exit', function (code) {
})

tap.Test = Test
tap.Spawn = Spawn
tap.Stdin = Stdin
tap.synonyms = require('./synonyms.js')

// SIGTERM means being forcibly killed, almost always by timeout
Expand Down
1 change: 0 additions & 1 deletion test/runner-read-stdin.js
Expand Up @@ -143,4 +143,3 @@ t.test('read from stdin', { skip: process.platform === 'win32' && 'skip stdin te

t.end()
})

32 changes: 19 additions & 13 deletions test/test-args.js
Expand Up @@ -4,12 +4,18 @@ var parseTestArgs = require('../lib/parse-test-args.js')

function namedFunction () {}
var fn = function () {}
function clone (o) {
return Object.keys(o).reduce(function (c, k) {
c[k] = o[k]
return c
}, {})
}
var obj = { thisIsMyObject: true }
var cobj = clone.bind(null, obj)
var objTodo = { thisIsMyObject: true, todo: true }
var cobjTodo = clone.bind(null, objTodo)

function runTest (args, expect) {
delete obj.todo

var result = parseTestArgs.apply(null, args)
t.match(result, expect)
}
Expand All @@ -22,30 +28,30 @@ function c (obj, props) {
}, props)
}

runTest(['name', obj, fn], c(obj, {name: 'name', cb: fn}))
runTest(['name', cobj(), fn], c(cobj(), {name: 'name', cb: fn}))
runTest(['name', fn], { name: 'name', cb: fn })
runTest([obj, fn], c(obj, { name: /\(unnamed test\)|fn/, cb: fn }))
runTest([obj, namedFunction], c(obj, { name: 'namedFunction', cb: namedFunction }))
runTest(['name', obj], c(objTodo, { name: 'name' }))
runTest([cobj(), fn], c(cobj(), { name: /\(unnamed test\)|fn/, cb: fn }))
runTest([cobj(), namedFunction], c(cobj(), { name: 'namedFunction', cb: namedFunction }))
runTest(['name', cobj()], c(cobjTodo(), { name: 'name' }))
runTest(['name'], { name: 'name', todo: true })
runTest([obj], c(objTodo, { name: /\(unnamed test\)|fn/ }))
runTest([cobj()], c(cobjTodo(), { name: /\(unnamed test\)|fn/ }))
runTest([fn], {name: /\(unnamed test\)|fn/, cb: fn})
runTest([namedFunction], { name: 'namedFunction', cb: namedFunction })
runTest([], { name: /\(unnamed test\)|fn/, todo: true })

var dn = 'defaultName'
var _ = undefined
runTest(['name', obj, fn, dn], c(obj, {name: 'name', cb: fn}))
runTest(['name', cobj(), fn, dn], c(cobj(), {name: 'name', cb: fn}))
runTest(['name', fn, _, dn], { name: 'name', cb: fn })
runTest([obj, fn, _, dn], c(obj, { name: /defaultName|fn/, cb: fn }))
runTest([obj, namedFunction, _, dn], c(obj, { name: 'namedFunction', cb: namedFunction }))
runTest(['name', obj, _, dn], c(objTodo, { name: 'name' }))
runTest([cobj(), fn, _, dn], c(cobj(), { name: /defaultName|fn/, cb: fn }))
runTest([cobj(), namedFunction, _, dn], c(cobj(), { name: 'namedFunction', cb: namedFunction }))
runTest(['name', cobj(), _, dn], c(cobjTodo(), { name: 'name' }))
runTest(['name', _, _, dn], { name: 'name', todo: true })
runTest([obj, _, _, dn], c(objTodo, { name: /defaultName|fn/ }))
runTest([cobj(), _, _, dn], c(cobjTodo(), { name: /defaultName|fn/ }))
runTest([fn, _, _, dn], {name: /defaultName|fn/, cb: fn})
runTest([namedFunction, _, _, dn], { name: 'namedFunction', cb: namedFunction })
runTest([_, _, _, dn], { name: /defaultName|fn/, todo: true })

t.throws(function () {
runTest(['name', obj, 99], {})
runTest(['name', cobj(), 99], {})
})
52 changes: 32 additions & 20 deletions test/test-test.js
@@ -1,8 +1,7 @@
var tap = require('../')
var test = tap.test
var Test = tap.Test
var t = require('../')
var Test = t.Test

test('testing the test object', function (t) {
t.test('testing the test object', function (t) {
t.isa(t, Test, 'test object should be instanceof Test')

// now test all the methods.
Expand Down Expand Up @@ -80,7 +79,7 @@ test('testing the test object', function (t) {
t.end()
})

test('plan stuff', function (t) {
t.test('plan stuff', function (t) {
t.throws(function () {
var tt = new Test({ buffered: false })
tt.plan(1)
Expand All @@ -98,20 +97,7 @@ test('plan stuff', function (t) {
t.end()
})

test('subtest with name and function', function (t) {
var tt = new Test({ buffered: false })
var out = ''
tt.on('data', function (c) {
out += c
})
tt.test('name', function (t){t.end()})
tt.end()

t.equal(out, 'TAP version 13\n# Subtest: name\n 1..0\nok 1 - name\n\n1..1\n');
t.end()
})

test('invalid test arguments', function (t) {
t.test('invalid test arguments', function (t) {
t.throws(function () {
var tt = new Test({ buffered: false })
tt.test('name', { skip: false }, 'not a function')
Expand All @@ -120,7 +106,7 @@ test('invalid test arguments', function (t) {
t.end()
})

test('throws type', function (t) {
t.test('throws type', function (t) {
t.throws(function() {
throw new TypeError('some type error');
}, TypeError, 'should throw a TypeError');
Expand All @@ -144,3 +130,29 @@ test('throws type', function (t) {

t.end()
})

t.test('test-point', function (t) {
var TestPoint = require('../lib/point.js')
t.throws(function () {
new TestPoint(100, 'century!', { flerg: 'blooze' })
}, new TypeError('ok must be boolean'))

var tp = TestPoint(true, 'msg', { a: 1 })
t.isa(tp, TestPoint)
t.match(tp, {
ok: 'ok ',
message: '- msg\n'
})

t.match(TestPoint(true, 'msg', { a: 1, diagnostic: true }), {
ok: 'ok ',
message: ' - msg\n ---\n a: 1\n ...\n\n'
})

t.match(TestPoint(true, 'msg', { a: 1, tapChildBuffer: 'subtest output' }), {
ok: 'ok ',
message: ' - msg {\nsubtest output\n}\n\n'
})

t.end()
})
5 changes: 4 additions & 1 deletion test/test.js
Expand Up @@ -8,7 +8,10 @@ var path = require('path')
var yaml = require('js-yaml')

process.env.TAP_BUFFER = 1
t.jobs = 2
// don't turn on parallelization for `npm test`, because it also
// has coverage and this makes the spawn timeouts stuff break.
if (process.env.npm_lifecycle_event !== 'test')
t.jobs = 2

function regEsc (str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')
Expand Down
1 change: 1 addition & 0 deletions test/test/mocha-bdd--bail--buffer.tap
Expand Up @@ -10,6 +10,7 @@ beforeEach should return the index where the element first appears in the array
during should return the index where the element first appears in the array
afterEach should return the index where the element first appears in the array
after
after named
ok 1 - Array {
ok 1 - #indexOf() {
ok 1 - when not present {
Expand Down
1 change: 1 addition & 0 deletions test/test/mocha-bdd--bail.tap
Expand Up @@ -35,6 +35,7 @@ afterEach should return the index where the element first appears in the array
ok 1 - #indexOf()

after
after named
1..1
ok 1 - Array

Expand Down
1 change: 1 addition & 0 deletions test/test/mocha-bdd--buffer.tap
Expand Up @@ -10,6 +10,7 @@ beforeEach should return the index where the element first appears in the array
during should return the index where the element first appears in the array
afterEach should return the index where the element first appears in the array
after
after named
ok 1 - Array {
ok 1 - #indexOf() {
ok 1 - when not present {
Expand Down
4 changes: 4 additions & 0 deletions test/test/mocha-bdd.js
Expand Up @@ -11,6 +11,10 @@ describe('Array', function () {
console.log('after')
})

after('named', function () {
console.log('after named')
})

beforeEach(function () {
console.log('beforeEach', this.name)
return new Promise(function (res) {
Expand Down
1 change: 1 addition & 0 deletions test/test/mocha-bdd.tap
Expand Up @@ -35,6 +35,7 @@ afterEach should return the index where the element first appears in the array
ok 1 - #indexOf()

after
after named
1..1
ok 1 - Array

Expand Down
47 changes: 47 additions & 0 deletions test/test/stdin--bail--buffer.tap
@@ -0,0 +1,47 @@
TAP version 13
# before
ok 1 - fake stdin {
1..3
ok 1 - child {
1..1
ok
}
ok 2 - empty {

}
ok 3
}

# between
#### TAP version 13
#### 1..3
#### ok 1 - child {
#### 1..1
#### ok
#### }
#### ok 2 - empty {
####
#### }
#### ok 3
# after
not ok 2 - /dev/stdin
---
{"at":{"column":17,"file":"test/test/stdin.js","function":"Object.<anonymous>","line":60},"failures":[{"id":4,"name":"test unfinished","plan":{"end":3,"start":1},"tapError":"id greater than plan end"},{"id":4,"name":"test unfinished","plan":{"end":3,"start":1},"tapError":"id greater than plan end"}],"source":"p.emit('error', new Error('expect to throw this'))\n","test":"/dev/stdin"}
...
{
1..3
ok 1 - child {
1..1
ok
}
ok 2 - empty {

}
ok 3

not ok 4 - test unfinished

Bail out! # test unfinished
}
Bail out! # test unfinished

0 comments on commit 7510a6d

Please sign in to comment.