Skip to content

Commit

Permalink
Warn users if verifying an exact stubbing
Browse files Browse the repository at this point in the history
Fixes #76
  • Loading branch information
searls committed Apr 3, 2016
1 parent 93df704 commit ed32418
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/verify.coffee
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
_ = require('lodash')
store = require('./store')
callsStore = require('./store/calls')
stubbingsStore = require('./store/stubbings')
stringifyArgs = require('./stringify/arguments')
log = require('./log')
argsMatch = require('./args-match')

module.exports = (__userDoesPretendInvocationHere__, config = {}) ->
if last = callsStore.pop()
if callsStore.wasInvoked(last.testDouble, last.args, config)
# Do nothing! We're verified! :-D
warnIfStubbed(last.testDouble, last.args)
else
log.fail(unsatisfiedErrorMessage(last.testDouble, last.args, config))
else
Expand All @@ -18,6 +21,15 @@ module.exports = (__userDoesPretendInvocationHere__, config = {}) ->
verify(myTestDouble('foo'))
"""

warnIfStubbed = (testDouble, actualArgs) ->
_.find stubbingsStore.for(testDouble), (stubbing) ->
if argsMatch(stubbing.args, actualArgs, allowMatchers: false)
log.warn 'td.verify', """
test double#{stringifyName(testDouble)} was both stubbed and verified with arguments (#{stringifyArgs(actualArgs)}), which is redundant and probably unnecessary.
""", "https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with"
true


unsatisfiedErrorMessage = (testDouble, args, config) ->
"""
Unsatisfied verification on test double#{stringifyName(testDouble)}.
Expand All @@ -26,6 +38,11 @@ unsatisfiedErrorMessage = (testDouble, args, config) ->
- called with `(#{stringifyArgs(args)})`#{timesMessage(config)}.
""" + invocationSummary(testDouble)

stringifyName = (testDouble) ->
if name = store.for(testDouble).name
" `#{name}`"
else
""
invocationSummary = (testDouble) ->
calls = callsStore.for(testDouble)
if calls.length == 0
Expand All @@ -35,12 +52,6 @@ invocationSummary = (testDouble) ->
desc + "\n - called with `(#{stringifyArgs(call.args)})`."
, "\n\n But was actually called:"

stringifyName = (testDouble) ->
if name = store.for(testDouble).name
" `#{name}`"
else
""

timesMessage = (config) ->
return "" unless config.times?
" #{config.times} time#{if config.times == 1 then '' else 's'}"
22 changes: 22 additions & 0 deletions test/src/verify-test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,25 @@ describe '.verify', ->
- called with `()`.
- called with `()`.
"""

describe 'warning when verifying a stubbed invocation', ->
Given -> @ogWarn = console.warn
Given -> @warnings = []
Given -> console.warn = (msg) => @warnings.push(msg)
afterEach = console.warn = @ogWarn
Given -> @td = td.function('.foo')

context 'an exact match in calls', ->
Given -> td.when(@td(1)).thenReturn(5)
Given -> @td(1)
When -> td.verify(@td(1))
Then -> @warnings[0] == """
Warning: testdouble.js - td.verify - test double `.foo` was both stubbed and verified with arguments (1), which is redundant and probably unnecessary. (see: https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with )
"""

context 'matchers are used', ->
Given -> td.when(@td(td.matchers.isA(Number))).thenReturn(5)
Given -> @td(1)
When -> td.verify(@td(1))
Then -> @warnings.length == 0

0 comments on commit ed32418

Please sign in to comment.