Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use nopt for options, and mkdirp for making dirs

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...
commit bdc03c60c756fcddff7ea7b1661c7d108cf6b036 1 parent 5e69dda
@isaacs authored
Showing with 148 additions and 94 deletions.
  1. +50 −3 bin/tap.js
  2. +65 −62 lib/tap-runner.js
  3. +33 −29 package.json
View
53 bin/tap.js
@@ -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) {
@@ -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()
})
}
View
127 lib/tap-runner.js
@@ -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
@@ -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
@@ -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]
}
@@ -184,7 +179,7 @@ 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)
@@ -192,8 +187,11 @@ Runner.prototype.runFiles = function (files, dir, cb) {
})
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
@@ -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(" ")
View
62 package.json
@@ -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" } }
-
+}
Please sign in to comment.
Something went wrong with that request. Please try again.