Skip to content

Commit

Permalink
Use nopt for options, and mkdirp for making dirs
Browse files Browse the repository at this point in the history
This brings a needed bit of sanity to the options parsing.  Also, adds
the following options:

1. --stderr   print standard error of tests to standard error
2. --diag     show diagnostics for all tests
3. --tap      print the raw tap instead of the pretty stuff
4. --timeout  The timeout value in seconds

Fix #15
Fix #31
Fix #3
  • Loading branch information
isaacs committed Jan 8, 2012
1 parent 5e69dda commit bdc03c6
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 94 deletions.
53 changes: 50 additions & 3 deletions bin/tap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,58 @@
var argv = process.argv.slice(2)
, path = require("path")
, Runner = require("../lib/tap-runner")
, r = new Runner(argv, null)

, nopt = require("nopt")

, knownOpts =
{ cover: [path, false]
, "cover-dir": path
, stderr: Boolean
, stdout: Boolean
, diag: Boolean
, version: Boolean
, tap: Boolean
, timeout: Number
}

, shorthands =
// debugging 1: show stderr
{ d: ["--stderr"]
// debugging 2: show stderr and tap
, dd: ["--stderr", "--tap"]
// debugging 3: show stderr, tap, AND always show diagnostics.
, ddd: ["--stderr", "--tap", "--diag"]
, e: ["--stderr"]
, t: ["--timeout"]
, o: ["--tap"]
, c: ["--cover"]
, v: ["--version"]
}

, defaults =
{ cover: "./lib"
, "cover-dir": "./coverage"
, stderr: process.env.TAP_STDERR
, tap: process.env.TAP
, diag: process.env.TAP_DIAG
, timeout: +process.env.TAP_TIMEOUT || 30
, version: false }

, options = nopt(knownOpts, shorthands)

Object.keys(defaults).forEach(function (k) {
if (!options.hasOwnProperty(k)) options[k] = defaults[k]
})

// other tests that might rely on these
if (options.diag) process.env.TAP_DIAG = true
if (options.tap) process.env.TAP = true
if (options.timeout) process.env.TAP_TIMEOUT = options.timeout

var r = new Runner(options)
, TapProducer = require("../lib/tap-producer")

if (process.env.TAP || process.env.TAP_DIAG) {
if (options.tap || options.diag) {
r.pipe(process.stdout)
} else {
r.on("file", function (file, results, details) {
Expand Down Expand Up @@ -36,7 +84,6 @@ if (process.env.TAP || process.env.TAP_DIAG) {
console.error( "\nCoverage: %s\n"
, path.resolve(r.coverageOutDir, "index.html") )
}
// process.stdout.flush()
})
}

Expand Down
127 changes: 65 additions & 62 deletions lib/tap-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ var fs = require("fs")
, inherits = require("inherits")
, util = require("util")
, CovHtml = require("./tap-cov-html.js")

// XXX Clean up the coverage options
, doCoverage = process.env.TAP_COV
|| process.env.npm_package_config_coverage
|| process.env.npm_config_coverage

var Runner = module.exports = function (dir, diag, cb) {
module.exports = Runner

inherits(Runner, TapProducer)

function Runner (options, cb) {
this.options = options

var diag = this.options.diag
var dir = this.options.argv.remain
Runner.super.call(this, diag)

this.doCoverage = doCoverage
Expand All @@ -22,7 +32,7 @@ var Runner = module.exports = function (dir, diag, cb) {
// The source of these files
this.coverageFilesSource = {}
// Where to write coverage information
this.coverageOutDir = "./coverage"
this.coverageOutDir = this.options["coverage-dir"]
// Temporary test files bunkerified we'll remove later
this.f2delete = []
// Raw coverage stats, as read from JSON files
Expand All @@ -31,75 +41,60 @@ var Runner = module.exports = function (dir, diag, cb) {
this.covStats = {}

if (dir) {
var filesToCover = "./lib"
, coverageOutDir = "./coverage"
var filesToCover = this.options.cover

if (doCoverage) {
dir = dir.filter(function(arg) {
if (arg.match(/^--cover=/)) {
filesToCover = arg.split("--cover=")[1]
return false
} else if (arg.match(/^--cover-dir=/)) {
coverageOutDir = arg.split("--cover-dir=")[1]
return false
}
return true
})
coverageOutDir = path.resolve(coverageOutDir)
path.exists(coverageOutDir, function(exists) {
if (!exists) {
fs.mkdir(coverageOutDir, 0755, function(er) {
if (er) {
throw er
}
})
}
})
this.coverageOutDir = coverageOutDir
var mkdirp = require("mkdirp")
this.coverageOutDir = path.resolve(this.coverageOutDir)
this.getFilesToCover(filesToCover)
var self = this
return mkdirp(this.coverageOutDir, 0755, function (er) {
if (er) return self.emit("error", er)
self.run(dir, cb)
})
}

this.run(dir, cb)
}
}

inherits(Runner, TapProducer)


Runner.prototype.run = function() {
var self = this
, args = Array.prototype.slice.call(arguments)
, cb = args.pop() || function (er) {
if (er) {
self.emit("error", er)
}
, cb = args.pop() || finish

if (doCoverage) {
// Cleanup temporary test files with coverage:
self.f2delete.forEach(function(f) {
fs.unlinkSync(f)
})
self.getFilesToCoverSource(function(err, data) {
if (err) {
self.emit("error", err)
}
self.getPerFileCovInfo(function(err, data) {
if (err) {
self.emit("error", err)
}
self.mergeCovStats(function(err, data) {
if (err) {
self.emit("error", err)
}
CovHtml(self.covStats, self.coverageOutDir, function() {
self.end()
})
})
})
})
} else {
self.end()
}
function finish (er) {
if (er) {
self.emit("error", er)
}

if (!doCoverage) return self.end()

// Cleanup temporary test files with coverage:
self.f2delete.forEach(function(f) {
fs.unlinkSync(f)
})
self.getFilesToCoverSource(function(err, data) {
if (err) {
self.emit("error", err)
}
self.getPerFileCovInfo(function(err, data) {
if (err) {
self.emit("error", err)
}
self.mergeCovStats(function(err, data) {
if (err) {
self.emit("error", err)
}
CovHtml(self.covStats, self.coverageOutDir, function() {
self.end()
})
})
})
})
}

if (Array.isArray(args[0])) {
args = args[0]
}
Expand Down Expand Up @@ -184,16 +179,19 @@ Runner.prototype.runFiles = function (files, dir, cb) {
cp._timedOut = true
cp.kill()
}
}, ((process.env.TAP_TIMEOUT || 30) * 1000))
}, self.options.timeout * 1000)

tc.on("data", function(c) {
self.emit("result", c)
self.write(c)
})

cp.stdout.pipe(tc)
cp.stdout.on("data", function(c) { out += c })
cp.stderr.on("data", function(c) { err += c })
cp.stdout.on("data", function (c) { out += c })
cp.stderr.on("data", function (c) {
if (self.options.stderr) process.stderr.write(c)
err += c
})

cp.on("exit", function (code) {
cp._ended = true
Expand All @@ -208,11 +206,16 @@ Runner.prototype.runFiles = function (files, dir, cb) {

if (err) {
res.stderr = err
if (tc.results.ok && tc.results.tests === 0) {
// perhaps a compilation error or something else failed...
if (tc.results.ok &&
tc.results.tests === 0 &&
!self.options.stderr) {
// perhaps a compilation error or something else failed.
// no need if stderr is set, since it will have been
// output already anyway.
console.error(err)
}
}

// tc.results.ok = tc.results.ok && ok
tc.results.add(res)
res.command = [cmd].concat(args).map(JSON.stringify).join(" ")
Expand Down
62 changes: 33 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
{ "name" : "tap"
, "version" : "0.1.4"
, "author" : "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)"
, "description" : "A Test-Anything-Protocol library"
, "bin" : "bin/tap.js"
, "main" : "lib/main.js"
, "dependencies" :
{ "inherits" : "*"
, "yamlish" : "*"
, "slide": "*"
, "runforcover": "~0.0.2"
}
, "bundledDependencies" :
[ "inherits"
, "tap-consumer"
, "yamlish"
]
, "keywords" :
[ "assert"
, "test"
, "tap"
]
, "contributors" :
[
{
"name": "tap",
"version": "0.1.4",
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
"description": "A Test-Anything-Protocol library",
"bin": "bin/tap.js",
"main": "lib/main.js",
"dependencies": {
"inherits": "*",
"yamlish": "*",
"slide": "*",
"runforcover": "~0.0.2",
"nopt": "~1.0.10",
"mkdirp": "~0.2.2"
},
"bundledDependencies": [
"inherits",
"tap-consumer",
"yamlish"
],
"keywords": [
"assert",
"test",
"tap"
],
"contributors": [
"Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
"baudehlo <helpme+github@gmail.com>"
]
, "license": {
],
"license": {
"type": "MIT",
"url": "https://github.com/isaacs/node-tap/raw/master/LICENSE"
},
"repository": "git://github.com/isaacs/node-tap.git",
"scripts": {
"test": "bin/tap.js test"
}
, "repository" : "git://github.com/isaacs/node-tap.git"
, "scripts" : { "test" : "bin/tap.js test" } }

}

0 comments on commit bdc03c6

Please sign in to comment.