macgyver
Version:
[](http://travis-ci.org/dominictarr/macgyver) [](http://ci.testling.com/dominictarr/macgyver) declarative assertion framework for invocation ordering.
170 lines (109 loc) • 4.2 kB
Markdown
//secure.travis-ci.org/dominictarr/macgyver.png)](http://travis-ci.org/dominictarr/macgyver)
[](http://ci.testling.com/dominictarr/macgyver)
declarative assertion framework for invocation ordering.
when evented code really gets _mission critical_ there is one man you send in...
useful for testing streams, and other complex evented modules.
``` js
var macgyver = require('macgyver')
//create a context
var mac = macgyver()
//wrap a function...
function hello () {
console.log('hello')
}
function goodbye () {
console.log('goodbye')
}
var hi = mac(hello)
//declare it's behaviours
hi.isCalled(1, 7) //must be called between 1 and 7 times.
var bye = mac(goodbye).once() //must be called strictly once.
hi.before(bye) //hi must be called strictly before bye is called
hi(); hi(); bye()
/*
//this will produce an error!
hi(); hi(); bye(); hi()
*/
mac.validate()
```
here is a real life example: [dominictarr/event-stream/test/spec.js](https://github.com/dominictarr/event-stream/blob/3f4f5cb57fb61144751ab5fe643b8974ab9007aa/test/spec.js#L14-56)
create a `maggyver` context.
``` js
var macgyver = require('macgyver')
var mac = macgyver()
```
wrap a function
``` js
function doSomething() {}
var _doSomething = mac(doSomething)
```
now, we can make declairations about how the wrapped function must be called.
assert that the function is called at least `min` times, and at most `max` times.
if `min`, or `max` is null, then that bound is not checked. i.e. `mac(fun).isCalled(null, 10)`
will assert that `fun` is called not more than 10 times.
alias for `isCalled (1, 1)`
alias for `isCalled (n, n)`
alias for `isCalled (null, 1)`
alias for `isCalled (0, 0)`
alias for `isCalled (null, 1)`
alias for `isCalled (null, max)`
alias for `isCalled (min, null)`
increments the number of times a function may be called.
(inc may be negative)
assert that a function is called before another function.
the `other` must also be a wrapped function.
`mac(first).before(second = mac(second))`
`before` does not check wether the second function is eventually called or not. use `isCalled` or an alias.
just like `before` but checks that the function is called before the other function returns, so that it is possible for the first function to be called by the other.
assert that a function returns a value.
if value is a function, it will be called with the return value.
``` js
//assert that fun returns a string.
mac(fun).returns(function (val) {
assert.equal(typeof val, 'string')
})
```
the function should throw if the return value was not valid.
assert that a function is passed the correct arguments.
if `args` is a function, that function is called as in returns.
assert that a function throws. test may be a value or a function. `test` is optional.
if supplyed `test` is called on every call.
``` js
mac(fun).throws(function (err, threw) {
if(threw) {
assert.equal(err.code,'ERRCODE') //check correct error
} else {
//what to do if there was no error?
}
})
```
this is useful for checking conditions about when the error should be thrown. example [stream\
check all rules passed. must be called once you are sure all calls are finished.
for example `process.on('exit', mac.validate)` is a good time. `validate` in necessary
to check that lower bounds of `isCalled` and aliases where met.
call validate on `process.on('exit', mac.validate)`.
if process.on is not available (as on the browser) wait until `browserTimeout` instead.
[testling ci](http://ci.testling.com) kills tests after 30 seconds, so by default
`browserTimeout = 10e3` (10 seconds)
MIT / Apachce2
[![build status](https: