Class: XSpec::AssertionContext::Doubles::Double

Inherits:
BasicObject
Defined in:
lib/xspec/assertion_contexts.rb

Overview

Since the double object inherits from ‘BasicObject`, virtually every method call will be routed through `method_missing`. From there, the call can be checked against the expectations that were setup at the beginning of a spec.

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Double

Returns a new instance of Double.



183
184
185
186
# File 'lib/xspec/assertion_contexts.rb', line 183

def initialize(klass)
  @klass    = klass
  @expected = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*actual_args) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/xspec/assertion_contexts.rb', line 188

def method_missing(*actual_args)
  i = @expected.find_index {|expected_args, ret|
    expected_args == actual_args
  }

  if i
    @expected.delete_at(i)[1].call
  else
    name, rest = *actual_args
    ::Kernel.raise DoubleFailure, "Unexpectedly received: %s(%s)" % [
      name,
      [*rest].map(&:inspect).join(", ")
    ]
  end
end

Instance Method Details

#_expect(args, &ret) ⇒ Object

The two methods needed on this object to set it up and verify it are prefixed by ‘_` to try to ensure they don’t clash with any method expectations. While not fail-safe, users should only be using expectations for a public API, and ‘_` is traditionally only used for private methods (if at all).



209
210
211
212
213
# File 'lib/xspec/assertion_contexts.rb', line 209

def _expect(args, &ret)
  @klass.validate_call! args

  @expected << [args, ret]
end

#_verifyObject



215
216
217
218
219
220
221
222
223
224
# File 'lib/xspec/assertion_contexts.rb', line 215

def _verify
  return if @expected.empty?

  ::Kernel.raise DoubleFailure, "%s double did not receive:\n%s" % [
    @klass.to_s,
    @expected.map {|(name, *args), _|
      "  %s(%s)" % [name, args.map(&:inspect).join(", ")]
    }.join("\n")
  ]
end