moodswing.coffee | |
---|---|
Moodswing uses CoffeeScript to provide assertions which can look like english sentences.
This is possible because of the
CoffeeScript object
literal syntax. For
example the line This means that the object The You can install moodswing through NPM
To use moodswing just require it in your tests
The code is available on github under MIT license. | |
Prerequisites | |
We use | {inspect} = require 'util' |
We use the standard | assert = require 'assert' |
Inernals | |
Primitive safe | keys = (something) ->
Object.keys(Object something) |
Takes the first object from an object or array named. | first = (it) ->
return it[0] if Array.isArray(it) or typeof it is 'string'
it[keys(it)[0]] |
Capitalizes a string. | capitalize = (str) ->
"#{str[0].toUpperCase()}#{str[1...]}" |
Exports | |
The expectation object is responsible for the assertions behavior. All of the assertions pointed by the directives are living in its constructor. | class Expectation
constructor: (@target, options = {}) ->
@negate = options.negate or false |
Assert @target to be equal to | beEqual: (other) ->
assert.equal @target, other unless @negate
assert.notEqual @target, other if @negate
this |
Assert | beAnInstanceOf: (kind) ->
unless @target instanceof kind
assert.fail("Expected #{@target} to be an instance of #{kind}")
this |
Assert | haveProperty: (name) ->
assert.notEqual undefined, @target[name] unless @negate
assert.equal undefined, @target[name] if @negate
this |
Assert | haveLength: (len) ->
@haveProperty 'length'
assert.equal @target.length, len unless @negate
assert.notEqual @target.length, len if @negate
this |
Assert | raise: (error) ->
try
@target()
catch e
if not e instanceof error and not @negate
assert.fail("Expected error of #{error} kind; got: #{e}")
if @negate
assert.fail("Unexpected error of #{error} kind.")
this |
Creates some common aliases... | (alias = (dict) ->
for name, aliases of dict
Expectation::[as] = Expectation::[name] for as in aliases
)
beEqual: ['beEqualOf', 'beEqualTo' , 'be']
beAnInstanceOf: ['beInstanceOf', 'beA']
haveProperty: ['havePropertyOf', 'have']
haveLength: ['haveLengthOf']
raise: ['throw', 'throws'] |
Parses a A | Expectation::to = (directive) -> |
Supports | return this unless directive?
possibilities = {} |
Find all the methods pointed by the directive. | method = new String
while keys(directive).length isnt 0
break unless typeof directive is 'object'
for part, directive of directive
method += if method.length is 0 then part else capitalize part
possibilities[method] = directive if @[method]?
if keys(possibilities).length is 0
throw TypeError "No suitible directive found: #{inspect directive}" |
Call the longest one of them. | longest = (keys(possibilities).sort (lhs, rhs) ->
lhs.length - rhs.length
).pop()
@[longest](possibilities[longest])
|
Provide public access for monkey patching. | exports.Expectation = Expectation |
Create an expectation for the | exports.expect = (target) ->
new exports.Expectation target |
Create an negated expectation for the | exports.dontExpect = (target) ->
new exports.Expectation target, negate: true |
Have fun. | |