Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1bd8290
Showing
5 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
|
||
|
||
var exec = require('child_process').exec, | ||
util = require('util'), | ||
events = require('events'); | ||
|
||
|
||
// | ||
// Main assertion thingy. First rough work. | ||
// | ||
// Thx to @visionmedia, based off supertest's Test object: | ||
// https://github.com/visionmedia/supertest/blob/master/lib/test.js | ||
// | ||
|
||
|
||
module.exports = Test; | ||
|
||
// Initialize a new `Test` with the given `options` Hash object. | ||
|
||
function Test(o) { | ||
this.options = o || {}; | ||
this._body = ''; | ||
this._status = 0; | ||
this._command = ''; | ||
} | ||
|
||
// inherits from EventEmitter | ||
|
||
util.inherits(Test, events.EventEmitter); | ||
|
||
// | ||
// Expectations: | ||
// | ||
// .expect(0) | ||
// .expect(0, fn) | ||
// .expect(0, body) | ||
// .expect('Some body') | ||
// .expect('Some body', fn) | ||
// | ||
|
||
Test.prototype.expect = function(a, b){ | ||
var self = this; | ||
|
||
// callback | ||
if (typeof b === 'function') this.end(b); | ||
|
||
// status | ||
if (typeof a === 'number') { | ||
this._status = a; | ||
// body | ||
if (b && typeof b !== 'function') this._body = b; | ||
return this; | ||
} | ||
|
||
// body | ||
this._body = a; | ||
|
||
return this; | ||
}; | ||
|
||
// | ||
|
||
Test.prototype.end = function(fn) { | ||
this.assert(res, fn); | ||
return this; | ||
}; | ||
|
||
// | ||
// Setup CLI location and default arguments. | ||
// | ||
|
||
Test.prototype.use = function (command) { | ||
this._command = command; | ||
return this; | ||
}; | ||
|
||
// | ||
// Defer invoking `.end()` until | ||
// the command is done running. | ||
// | ||
|
||
Test.prototype.end = function(fn) { | ||
var self = this; | ||
|
||
this.run(function(err, stdout, stderr) { | ||
var code = err ? err.code : 0; | ||
|
||
self.emit('done'); | ||
|
||
self.assert({ | ||
status: code, | ||
text: (stdout || stderr), | ||
err: err | ||
}, fn); | ||
}); | ||
|
||
return this; | ||
}; | ||
|
||
// | ||
// Add topic to current (or root) vow | ||
// | ||
|
||
Test.prototype.run = function (fn) { | ||
var cmd = this._command; | ||
|
||
if(!cmd) return this.emit(new Error('Cannot run withou a command. Use .use!')); | ||
|
||
this.emit('run'); | ||
|
||
// Execute defined command with arguments and passed options | ||
exec(cmd, fn); | ||
|
||
return this; | ||
}; | ||
|
||
|
||
// Perform assertions and invoke `fn(err)`. | ||
|
||
Test.prototype.assert = function(res, fn) { | ||
var status = this._status, | ||
body = this._body, | ||
isregexp = body instanceof RegExp, | ||
expected, | ||
actual, | ||
re; | ||
|
||
// status | ||
if (status && res.status !== status) { | ||
return fn(new Error('expected ' + status + ', got ' + res.status), res); | ||
} | ||
|
||
// body | ||
if (body != null) { | ||
// string | ||
actual = util.inspect(res.text); | ||
expected = util.inspect(body); | ||
|
||
if (body !== res.text) { | ||
// regexp | ||
if (isregexp) { | ||
if (!body.test(res.text)) { | ||
return fn(new Error('expected body ' + res.text + ' to match ' + body)); | ||
} | ||
} else { | ||
return fn(new Error('expected ' + expected + ' response body, got ' + actual)); | ||
} | ||
} | ||
} | ||
|
||
fn(null, res); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
var Test = require('./lib/test'); | ||
|
||
module.exports = cli; | ||
cli.Test = Test; | ||
|
||
function cli(o) { | ||
o = o || {}; | ||
return new Test(o); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "clt", | ||
"version": "0.0.1", | ||
"description": "Easy way to run assertions against CLI tools.", | ||
"main": "main.js", | ||
"directories": { | ||
"test": "test" | ||
:q | ||
}, | ||
"scripts": { | ||
"test": "node node_modules/mocha/bin/mocha --reporter spec" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
clt | ||
=== | ||
|
||
**Inspired / Based off both | ||
[cli-easy](https://github.com/flatiron/cli-easy) and | ||
[supertest](https://github.com/visionmedia/supertest)** | ||
|
||
> A fluent (i.e. chainable) syntax for generating vows tests for CLI applications. | ||
> HTTP assertions made easy via super-agent. | ||
Description | ||
----------- | ||
|
||
- Struggling with testing cli tools. | ||
- cli-easy is super great, but designed for generating vows | ||
- supertest is super great, but designed to make HTTP assertions via | ||
super-agent. | ||
|
||
clt is nothing more than a simple, chainable API to ease the process of | ||
testing CLI applications & tools. | ||
|
||
Right now, it doesn't do anything fancy and just allow you to easily | ||
test the exit code and stdout output, and make assertions on top of | ||
that. | ||
|
||
Example | ||
------- | ||
|
||
It should work with any test framework, here is an example using any | ||
test framework at all. | ||
|
||
```js | ||
var cli = require('clt'); | ||
|
||
cli() | ||
.use('uname') | ||
.expect(0, 'Linux\n') | ||
.end(function(err, stdout, stderr) { | ||
if(err) throw err; | ||
}); | ||
``` | ||
|
||
Here's an example with mocha, note how you can pass done straight to any | ||
of the `.expect()` calls (or `.end()`): | ||
|
||
```js | ||
describe('test uname', function() { | ||
it('respond with Linux', function(done) { | ||
cli() | ||
.use('uname') | ||
.expect('should return Linux', 'Linux\n') | ||
.expect(0, done) | ||
}); | ||
}); | ||
``` | ||
|
||
fancier example. | ||
|
||
```js | ||
describe('Testing on a wtf thing', function() { | ||
it('should fail as expected', function(done) { | ||
cli() | ||
.use('wtfBinary') | ||
.expect(127, /command not found/) | ||
.end(done); | ||
}); | ||
}); | ||
``` | ||
|
||
API | ||
--- | ||
|
||
> tbd | ||
- expect(code, fn) | ||
- expect(code, body, [fn]) | ||
- expect(body, [fn]) | ||
- end(fn) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
var cli = require('..'); | ||
|
||
describe('Testing on uname', function() { | ||
it('should return Linux ', function(done) { | ||
cli() | ||
.use('uname') | ||
.expect(0, 'Linux\n') | ||
.end(done); | ||
}); | ||
}); | ||
|
||
describe('Testing on a wtf thing', function() { | ||
it('should fail as expected', function(done) { | ||
cli() | ||
.use('wtfBinary') | ||
.expect(127, /command not found/) | ||
.end(done); | ||
}); | ||
}); | ||
|