Skip to content
This repository has been archived by the owner on Mar 16, 2020. It is now read-only.

Commit

Permalink
Add a 'matches' method for testing an object against a duck
Browse files Browse the repository at this point in the history
  • Loading branch information
rowanmanning committed Jul 19, 2012
1 parent 978fdae commit 51c6463
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
31 changes: 31 additions & 0 deletions README.md
Expand Up @@ -93,6 +93,37 @@ jemima.hasMethods(obj, ['foo', 'baz']); // false
```


### jemima.matches ###

This function tests whether an object has the specified
properties and that the type of object stored in each property
is as expected. You call it with an object (what we're testing)
and a 'duck' (an object which specifies the expected properties
and types); it will return a boolean value indicating whether
all of the properties match:

```js
var duck = {
foo: 'string',
bar: 'function'
};

jemima.matches({
foo: 'bar',
bar: function () {}
}, duck); // true

jemima.matches({
foo: 'bar'
}, duck); // false

jemima.matches({
foo: 'bar',
bar: 'baz'
}, duck); // false
```


## Development ##

In order to develop Jemima, you'll need to install the following
Expand Down
13 changes: 10 additions & 3 deletions src/jemima.coffee
Expand Up @@ -32,6 +32,13 @@ module.exports = jemima =
results = (jemima.hasMethod(object, method) for method in methods)
(false in results) is false

# Check whether an object's properties match those of another object
matches: (object, duck) ->
varg.isValidObjectArgument object
varg.isValidObjectArgument duck, 'duck'
results = (typeof object[property] is type for own property, type of duck)
(false in results) is false


# Argument verification
varg =
Expand Down Expand Up @@ -65,9 +72,9 @@ varg =
if typeof value isnt 'string'
throw new er.ArgumentTypeError "Invalid #{arg} argument, array of strings expected"

isValidObjectArgument: (object) ->
varg.notMissing object, 'object'
varg.isObject object, 'object'
isValidObjectArgument: (object, arg = 'object') ->
varg.notMissing object, arg
varg.isObject object, arg

isValidPropertyArgument: (property, arg = 'property') ->
varg.notMissing property, arg
Expand Down
43 changes: 43 additions & 0 deletions test/unit/jemima.coffee
Expand Up @@ -24,6 +24,9 @@ suite 'jemima module', ->
test 'should have a `hasMethods` function', ->
assert.isFunction jemima.hasMethods

test 'should have a `matches` function', ->
assert.isFunction jemima.matches

suite '`hasProperty` function', ->

test 'should not throw when called with correct arguments', ->
Expand Down Expand Up @@ -266,3 +269,43 @@ suite 'jemima module', ->
assert.isTrue jemima.hasMethod.firstCall.calledWith(object, 'foo')
assert.isTrue jemima.hasMethod.secondCall.calledWith(object, 'bar')
assert.isTrue jemima.hasMethod.thirdCall.calledWith(object, 'baz')

suite '`matches` function', ->

test 'should not throw when called with correct arguments', ->
assert.doesNotThrow -> jemima.matches {}, {}

test 'should throw when called with a non-object first argument', ->
assert.throws ->
jemima.matches 123, {}
, er.ArgumentTypeError

test 'should throw when called with a non-object second argument', ->
assert.throws ->
jemima.matches {}, 123
, er.ArgumentTypeError

test 'should throw when called with a missing first argument', ->
assert.throws ->
jemima.matches undefined, {}
, er.ArgumentMissingError

test 'should throw when called with a missing second argument', ->
assert.throws ->
jemima.matches {}
, er.ArgumentMissingError

test 'should return `true` when the object has properties matching the types specified in the duck', ->
assert.isTrue jemima.matches {foo: 'bar', bar: (->)}, {foo: 'string', bar: 'function'}

test 'should return `true` when the object\'s prototype has properties matching the types specified in the duck', ->
class Foo
foo: 'bar'
bar: ->
assert.isTrue jemima.matches new Foo, {foo: 'string', bar: 'function'}

test 'should return `false` when one or more properties specified in the duck are not present in the object', ->
assert.isFalse jemima.matches {foo: 'bar'}, {foo: 'string', bar: 'function'}

test 'should return `false` when one or more properties in the object don\'t match the type specified in the duck', ->
assert.isFalse jemima.matches {foo: 'bar', bar: 'baz'}, {foo: 'string', bar: 'function'}

0 comments on commit 51c6463

Please sign in to comment.