Browse files

Implemented verifyZeroInteractions

  • Loading branch information...
1 parent b9e1548 commit a94d464f5d3970e99b5f3e3507645006c6b8723c @dhasenan committed May 20, 2011
Showing with 70 additions and 11 deletions.
  1. +51 −11 lib/maryjane.coffee
  2. +19 −0 test/maryjanetests.coffee
View
62 lib/maryjane.coffee
@@ -42,6 +42,18 @@ class Range
match: (point) -> point <= @max and point >= @min
+# There's a rather interesting situation here worth mentioning.
+# The user might have set up some calls before this:
+# when(mock).blah().thenDo blah
+# verifyZeroInteractions(mock)
+#
+# This is perfectly sensible. They might have some outrageously
+# horrible or stupid test, maybe with a random element, and
+# the interactions should be all-or-nothing.
+#
+# It's a pretty stupid use case, but we support it!
+exports.verifyZeroInteractions = (mock) ->
+ onMock mock, (m) -> m._mockInternals.verifyZeroInteractions()
# Repeat functions
exports.times = (min, max) -> new Range(min, max)
@@ -67,6 +79,18 @@ getName = (type) ->
f = f.split('(', 2)[0]
f.replace ' ', ''
+formatMethodCall = (typeName, method, args) ->
+ argString = '('
+ first = true
+ for arg in args
+ if first
+ first = false
+ else
+ argString += ', '
+ argString += arg
+ argString += ')'
+ return typeName + '.' + method + argString
+
class MockInternals
constructor: (@type, @mock) ->
if @type == null or @type == undefined
@@ -127,17 +151,8 @@ class MockInternals
failCheck: (field, args, match) ->
count = if match? then match.count() else 0
- argString = '('
- first = true
- for arg in args
- if first
- first = false
- else
- argString += ', '
- argString += arg
- argString += ')'
-
- throw new Error 'Expected ' + @typeName + '.' + field + argString + ' to be called ' + @range.toString() + ', but it was called ' + count + ' times'
+ method = formatMethodCall @typeName, field, args
+ throw new Error 'Expected ' + method + ' to be called ' + @range.toString() + ', but it was called ' + count + ' times'
newExpectation: ->
@recording = true
@@ -147,6 +162,28 @@ class MockInternals
@checking = true
@range = times
@mock
+
+ verifyZeroInteractions: ->
+ if @unexpectedMethodCalls.length == 0 && @expectedMethodCalls.length == 0
+ return
+ first = true
+ result = 'Expected no interactions with ' + @typeName + ', but '
+ found = false
+ for a in @unexpectedMethodCalls
+ found = true
+ if !first
+ result += '\n\t'
+ result += a.callDescription()
+ first = false
+ for a in @expectedMethodCalls
+ if a.count() > 0
+ found = true
+ if !first
+ result += '\n\t'
+ result += a.callDescription()
+ first = false
+ if found
+ throw new Error result
class Mock
constructor: (type) ->
@@ -230,3 +267,6 @@ class MockOptions
count: ->
@_count
+
+ callDescription: ->
+ return formatMethodCall(@_mock._mockInternals.typeName, @_name, @_args) + ' was called ' + @_count + ' times'
View
19 test/maryjanetests.coffee
@@ -258,3 +258,22 @@ exports['number of times called, range, too low'] = ->
cb = -> mj.verify(mock, mj.range(1, 3)).frob(1, 7)
assert.throws cb, (ex) ->
ex.message == 'Expected UnderTest.frob(1, 7) to be called between 1 and 3 times, but it was called 4 times'
+
+exports['verifyZeroInteractions'] = ->
+ mock = mj.mock(new UnderTest())
+ mj.verifyZeroInteractions(mock)
+
+exports['verifyZeroInteractions with setup'] = ->
+ mock = mj.mock(new UnderTest())
+ mj.when(mock).frob(1, 7).thenReturn 4
+ mj.verifyZeroInteractions(mock)
+
+exports['verifyZeroInteractions failure'] = ->
+ mock = mj.mock(new UnderTest())
+ mock.frob(1, 7)
+ mock.frob(1, 7)
+ mock.frob(1, 7)
+ mock.frob(1, 7)
+ cb = -> mj.verifyZeroInteractions(mock)
+ assert.throws cb, (ex) ->
+ ex.message == 'Expected no interactions with UnderTest, but UnderTest.frob(1, 7) was called 4 times'

0 comments on commit a94d464

Please sign in to comment.