Class: XSpec::Evaluator::Doubles::Double

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

Overview

Since the double object inherits from ‘BasicObject`, virtually every method call will be routed through `method_missing`. From there, the message can be recorded and an appropriate return value selected from the stubs.

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Double

Returns a new instance of Double.



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

def initialize(klass)
  @klass    = klass
  @expected = []
  @received = []
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
# File 'lib/xspec/evaluators.rb', line 188

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

  ret = if stub
    stub[1].call
  end

  @received << actual_args

  ret
end

Instance Method Details

#_stub(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).



207
208
209
210
211
# File 'lib/xspec/evaluators.rb', line 207

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

  @expected << [args, ret]
end

#_verify(args) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/xspec/evaluators.rb', line 213

def _verify(args)
  @klass.validate_call! args

  i = @received.index(args)

  if i
    @received.delete_at(i)
  else
    name, rest = *args
    ::Kernel.raise EvaluateFailed,
      "Did not receive: %s(%s)\nDid receive:%s\n" % [
        name,
        [*rest].map(&:inspect).join(", "),
        @received.map {|name, *args|
          "  %s(%s)" % [name, args.map(&:inspect).join(", ")]
        }.join("\n")
      ]
  end
end