test-console
Advanced tools
Comparing version 1.0.0 to 1.1.0
{ | ||
"name": "test-console", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "A simple and pragmatic library for testing Node.js console output.", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -40,9 +40,14 @@ # test-console | ||
All functions accept an optional options object as the first argument, where isTTY is the only available option. isTTY, if defined, will override the `stdout` field of the same name. | ||
The same API is also available on `stderr`. | ||
### `inspect = stdout.inspect()` | ||
### `inspect = stdout.inspect(options)` | ||
Redirects writes to `stdout` into an array instead of writing them to the console. | ||
* `options`: object [optional] | ||
* `isTTY`: If not undefined, this value will be used to temporarily overwrite `stdout.isTTY` | ||
* `inspect`: Returned as an object with two properties: | ||
@@ -72,6 +77,10 @@ * `inspect.output`: An array containing one string for each call to `stdout.write()`. This array updates every time another call to `stdout.write()` is made. | ||
### `output = stdout.inspectSync(fn)` | ||
### `output = stdout.inspectSync(options, fn)` | ||
Or: `output = stdout.inspectSync(fn)` | ||
Just like `inspect()`, but automatically restores the console when done. | ||
* `options`: object [optional] | ||
* `isTTY`: If not undefined, this value will be used to temporarily overwrite `stdout.isTTY` | ||
* `fn(output)`: The function to run while inspecting stdout. After the function returns, stdout.write is automatically restored. Note that `output` is passed into this function in addition to being returned from `inspectSync()`. | ||
@@ -102,6 +111,9 @@ | ||
### `restore = stdout.ignore()` | ||
### `restore = stdout.ignore(options)` | ||
Prevent writes to `stdout` from appearing on the console. | ||
* `options`: object [optional] | ||
* `isTTY`: If not undefined, this value will be used to temporarily overwrite `stdout.isTTY` | ||
* `restore()`: Call this function to restore stdout.write to its normal behavior. | ||
@@ -133,7 +145,7 @@ | ||
restoreStdout = stdout.ignore(); | ||
}; | ||
}); | ||
afterEach(function() { | ||
restoreStdout(); | ||
}; | ||
}); | ||
@@ -144,6 +156,10 @@ // tests go here | ||
### `ignoreSync(fn)` | ||
### `ignoreSync(options, fn)` | ||
Or: `ignoreSync(fn)` | ||
Just like `ignore()`, but automatically restores the console when done. | ||
* `options`: object [optional] | ||
* `isTTY`: If not undefined, this value will be used to temporarily overwrite `stdout.isTTY` | ||
* `fn()`: The function to run while ignoring stdout. After the function returns, stdout.write is automatically restored. | ||
@@ -154,3 +170,3 @@ | ||
```javascript | ||
stdout.ignore(function() { | ||
stdout.ignoreSync(function() { | ||
functionUnderTest(); | ||
@@ -163,2 +179,4 @@ }); | ||
__1.1.0:__ Add ability to override stdout.isTTY (and stderr.isTTY). | ||
__1.0.0:__ API fails with nice error messages when called with wrong number of arguments. | ||
@@ -175,4 +193,14 @@ | ||
Option for mocking isTTY added by Jason Boileau. | ||
### Release Process | ||
1. Update version history in readme | ||
2. Ensure clean build: `./jake.sh` | ||
3. Update npm version: `npm version [major|minor|patch]` | ||
4. Release to npm: `npm publish` | ||
5. Release to github: `git push && git push --tags` | ||
## License | ||
@@ -179,0 +207,0 @@ |
@@ -22,5 +22,9 @@ // Copyright (c) 2014-2015 Titanium I.T. LLC. All rights reserved. For license, see "README" or "LICENSE" file. | ||
it("fails nicely when user forgets to pass in a function", function() { | ||
var errMsg = "inspectSync() requires a function parameter. Did you mean to call inspect()?"; | ||
assert.throws(function() { | ||
stdout.inspectSync(); | ||
}, "inspectSync() requires a function parameter. Did you mean to call inspect()?"); | ||
}, errMsg); | ||
assert.throws(function() { | ||
stdout.inspectSync({}); | ||
}, errMsg); | ||
}); | ||
@@ -58,10 +62,44 @@ | ||
it("mocks isTTY value", function() { | ||
var originalIsTTY = process.stdout.isTTY; | ||
stdout.inspectSync({ isTTY: !originalIsTTY }, function() { | ||
assert.equal(process.stdout.isTTY, !originalIsTTY, 'isTTY should be changed'); | ||
}); | ||
assert.equal(process.stdout.isTTY, originalIsTTY, 'isTTY should be restored'); | ||
}); | ||
it("uses existing isTTY value by default", function() { | ||
// Testing for various argument lists | ||
var originalIsTTY = process.stdout.isTTY; | ||
stdout.inspectSync(function() { | ||
assert.equal(process.stdout.isTTY, originalIsTTY, 'isTTY should not be changed'); | ||
}); | ||
stdout.inspectSync({}, function() { | ||
assert.equal(process.stdout.isTTY, originalIsTTY, 'isTTY should not be changed'); | ||
}); | ||
// testing for both original values of isTTY for failure modes that don't occur for both isTTY=false and isTTY=true | ||
stdout.inspectSync({ isTTY: true }, function() { | ||
stdout.inspectSync(function() { | ||
assert.equal(process.stdout.isTTY, true, 'isTTY should still be true if original value was true'); | ||
}); | ||
}); | ||
stdout.inspectSync({ isTTY: false }, function() { | ||
stdout.inspectSync(function() { | ||
assert.equal(process.stdout.isTTY, false, 'isTTY should still be false if original value was false'); | ||
}); | ||
}); | ||
}); | ||
it("restores old behavior when done", function() { | ||
// More inception! | ||
stdout.inspectSync(function(output) { | ||
stdout.inspectSync(function() { | ||
var originalIsTTY = process.stdout.isTTY; | ||
stdout.inspectSync({ isTTY: !originalIsTTY }, function() { | ||
// this space intentionally left blank | ||
}); | ||
console.log("foo"); | ||
assert.deepEqual(output, [ "foo\n" ], "console should be restored"); | ||
assert.deepEqual(output, ["foo\n"], "console should be restored"); | ||
assert.equal(process.stdout.isTTY, originalIsTTY, 'isTTY should be restored'); | ||
}); | ||
@@ -73,9 +111,10 @@ }); | ||
stdout.inspectSync(function(output) { | ||
var originalIsTTY = process.stdout.isTTY; | ||
var exceptionPropagated = false; | ||
try { | ||
stdout.inspectSync(function() { | ||
stdout.inspectSync({ isTTY: !process.stdout.isTTY }, function() { | ||
throw new Error("intentional exception"); | ||
}); | ||
} | ||
catch (err) { | ||
catch(err) { | ||
exceptionPropagated = true; | ||
@@ -85,3 +124,4 @@ } | ||
console.log("foo"); | ||
assert.deepEqual(output, [ "foo\n" ], "console should be restored"); | ||
assert.deepEqual(output, ["foo\n"], "console should be restored"); | ||
assert.equal(process.stdout.isTTY, originalIsTTY, 'isTTY should be restored'); | ||
}); | ||
@@ -94,3 +134,3 @@ }); | ||
}); | ||
assert.deepEqual(output, [ "foo\n" ], "returned output"); | ||
assert.deepEqual(output, ["foo\n"], "returned output"); | ||
}); | ||
@@ -103,5 +143,9 @@ }); | ||
it("fails nicely when user confuses it for inspectSync and passes in a function", function() { | ||
var errMsg = "inspect() doesn't take a function parameter. Did you mean to call inspectSync()?"; | ||
assert.throws(function() { | ||
stdout.inspect(function() {}); | ||
}, "inspect() doesn't take a function parameter. Did you mean to call inspectSync()?"); | ||
}, errMsg); | ||
assert.throws(function() { | ||
stdout.inspect({}, function() {}); | ||
}, errMsg); | ||
}); | ||
@@ -112,3 +156,3 @@ | ||
console.log("foo"); | ||
assert.deepEqual(inspect.output, [ "foo\n" ], "output"); | ||
assert.deepEqual(inspect.output, ["foo\n"], "output"); | ||
inspect.restore(); | ||
@@ -127,3 +171,3 @@ }); | ||
console.log("bar"); | ||
assert.deepEqual(output, [ "bar\n" ], "console should be restored"); | ||
assert.deepEqual(output, ["bar\n"], "console should be restored"); | ||
}); | ||
@@ -151,3 +195,3 @@ }); | ||
console.log("bar"); | ||
assert.deepEqual(output, [ "bar\n" ], "console should be restored"); | ||
assert.deepEqual(output, ["bar\n"], "console should be restored"); | ||
}); | ||
@@ -183,3 +227,3 @@ }); | ||
console.log("bar"); | ||
assert.deepEqual(output, [ "bar\n" ], "console should be restored"); | ||
assert.deepEqual(output, ["bar\n"], "console should be restored"); | ||
}); | ||
@@ -203,3 +247,3 @@ }); | ||
process.stderr.write("foo"); | ||
assert.deepEqual(inspect.output, [ "foo" ], "output"); | ||
assert.deepEqual(inspect.output, ["foo"], "output"); | ||
inspect.restore(); | ||
@@ -206,0 +250,0 @@ }); |
@@ -11,5 +11,10 @@ // Copyright (c) 2014-2015 Titanium I.T. LLC. All rights reserved. For license, see "README" or "LICENSE" file. | ||
TestStream.prototype.inspect = function() { | ||
expectNoArguments(arguments, "inspect", "inspectSync"); | ||
TestStream.prototype.inspect = function(options) { | ||
expectNoFunction(arguments, "inspect", "inspectSync"); | ||
var isTTY; | ||
if (options && options.isTTY !== undefined) { | ||
isTTY = options.isTTY; | ||
} | ||
// This code inspired by http://userinexperience.com/?p=714 | ||
@@ -24,2 +29,7 @@ var output = []; | ||
var originalIsTTY = stream.isTTY; | ||
if (isTTY !== undefined) { | ||
stream.isTTY = isTTY; | ||
} | ||
return { | ||
@@ -29,2 +39,3 @@ output: output, | ||
stream.write = originalWrite; | ||
stream.isTTY = originalIsTTY; | ||
} | ||
@@ -34,7 +45,13 @@ }; | ||
TestStream.prototype.inspectSync = function(fn) { | ||
expectOneFunction(arguments, "inspectSync", "inspect"); | ||
TestStream.prototype.inspectSync = function(options, fn) { | ||
expectFunction(arguments, "inspectSync", "inspect"); | ||
var inspect = this.inspect(); | ||
if (arguments.length === 1) { | ||
fn = options; | ||
options = {}; | ||
} | ||
var inspect = this.inspect(options); | ||
try { | ||
fn(inspect.output); | ||
@@ -48,12 +65,17 @@ } | ||
TestStream.prototype.ignore = function() { | ||
expectNoArguments(arguments, "ignore", "ignoreSync"); | ||
TestStream.prototype.ignore = function(options) { | ||
expectNoFunction(arguments, "ignore", "ignoreSync"); | ||
return this.inspect().restore; | ||
return this.inspect(options).restore; | ||
}; | ||
TestStream.prototype.ignoreSync = function(fn) { | ||
expectOneFunction(arguments, "ignoreSync", "ignore"); | ||
TestStream.prototype.ignoreSync = function(options, fn) { | ||
expectFunction(arguments, "ignoreSync", "ignore"); | ||
this.inspectSync(function() { | ||
if (arguments.length === 1) { | ||
fn = options; | ||
options = {}; | ||
} | ||
this.inspectSync(options, function() { | ||
fn(); | ||
@@ -63,4 +85,4 @@ }); | ||
function expectNoArguments(args, calledFunction, functionToCallInstead) { | ||
if (args.length !== 0) { | ||
function expectNoFunction(args, calledFunction, functionToCallInstead) { | ||
if (args.length && typeof args[0] === 'function' || args.length > 1) { | ||
throw new Error(calledFunction + "() doesn't take a function parameter. Did you mean to call " + | ||
@@ -71,4 +93,4 @@ functionToCallInstead + "()?"); | ||
function expectOneFunction(args, calledFunction, functionToCallInstead) { | ||
if (args.length !== 1) { | ||
function expectFunction(args, calledFunction, functionToCallInstead) { | ||
if (args.length === 0 || args.length > 2 || typeof args[args.length - 1] !== 'function') { | ||
throw new Error(calledFunction + "() requires a function parameter. Did you mean to call " + | ||
@@ -75,0 +97,0 @@ functionToCallInstead + "()?"); |
18770
330
222
6