Class: RR::Double

Inherits:
Object
  • Object
show all
Defined in:
lib/rr/double.rb

Overview

RR::Double is the use case for a method call. It has the ArgumentEqualityExpectation, TimesCalledExpectation, and the implementation.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(space, double_insertion, definition) ⇒ Double

Returns a new instance of Double.



21
22
23
24
25
26
27
# File 'lib/rr/double.rb', line 21

def initialize(space, double_insertion, definition)
  @space = space
  @double_insertion = double_insertion
  @definition = definition
  @times_called = 0
  @times_called_expectation = Expectations::TimesCalledExpectation.new(self)
end

Instance Attribute Details

#definitionObject (readonly)

Returns the value of attribute definition.



19
20
21
# File 'lib/rr/double.rb', line 19

def definition
  @definition
end

#double_insertionObject (readonly)

Returns the value of attribute double_insertion.



19
20
21
# File 'lib/rr/double.rb', line 19

def double_insertion
  @double_insertion
end

#times_calledObject (readonly)

Returns the value of attribute times_called.



19
20
21
# File 'lib/rr/double.rb', line 19

def times_called
  @times_called
end

Class Method Details

.formatted_name(method_name, args) ⇒ Object



7
8
9
10
# File 'lib/rr/double.rb', line 7

def formatted_name(method_name, args)
  formatted_errors = args.collect {|arg| arg.inspect}.join(', ')
  "#{method_name}(#{formatted_errors})"
end

.list_message_part(scenarios) ⇒ Object



12
13
14
15
16
# File 'lib/rr/double.rb', line 12

def list_message_part(scenarios)
  scenarios.collect do |scenario|
    "- #{formatted_name(scenario.method_name, scenario.expected_arguments)}"
  end.join("\n")
end

Instance Method Details

#after_call(&block) ⇒ Object

Double#after_call creates a callback that occurs after call is called. The passed in block receives the return value of the Double being called. An Expection will be raised if no block is passed in.

mock(subject).method_name {return_value}.after_call {|return_value|}
subject.method_name # return_value

This feature is built into proxies.

mock.proxy(User).find('1') {|user| mock(user).valid? {false}}


172
173
174
# File 'lib/rr/double.rb', line 172

def after_call(&block)
  definition.after_call &block
end

#any_number_of_times(&returns) ⇒ Object

Double#any_number_of_times sets an that the Double will be called any number of times. This effectively removes the times called expectation from the Doublen

Passing in a block sets the return value.

mock(subject).method_name.any_number_of_times


118
119
120
# File 'lib/rr/double.rb', line 118

def any_number_of_times(&returns)
  definition.any_number_of_times(&returns)
end

#argument_expectationObject



325
326
327
# File 'lib/rr/double.rb', line 325

def argument_expectation
  definition.argument_expectation
end

#at_least(number, &returns) ⇒ Object

Double#at_least sets the expectation that the Double will be called at least n times. It works by creating a TimesCalledExpectation.

Passing in a block sets the return value.

mock(subject).method_name.at_least(4) {:return_value}


96
97
98
# File 'lib/rr/double.rb', line 96

def at_least(number, &returns)
  definition.at_least(number, &returns)
end

#at_most(number, &returns) ⇒ Object

Double#at_most allows sets the expectation that the Double will be called at most n times. It works by creating a TimesCalledExpectation.

Passing in a block sets the return value.

mock(subject).method_name.at_most(4) {:return_value}


107
108
109
# File 'lib/rr/double.rb', line 107

def at_most(number, &returns)
  definition.at_most(number, &returns)
end

#attempt?Boolean

Double#attempt? returns true when the TimesCalledExpectation is satisfied.

Returns:

  • (Boolean)


277
278
279
280
# File 'lib/rr/double.rb', line 277

def attempt?
  return true unless definition.times_matcher
  times_called_expectation.attempt?
end

#call(double_insertion, *args, &block) ⇒ Object

Double#call calls the Double’s implementation. The return value of the implementation is returned.

A TimesCalledError is raised when the times called exceeds the expected TimesCalledExpectation.



219
220
221
222
223
224
225
226
# File 'lib/rr/double.rb', line 219

def call(double_insertion, *args, &block)
  self.times_called_expectation.attempt! if definition.times_matcher
  @space.verify_ordered_scenario(self) if ordered?
  yields!(block)
  return_value = call_implementation(double_insertion, *args, &block)
  return return_value unless definition.after_call_value
  definition.after_call_value.call(return_value)
end

#exact_match?(*arguments) ⇒ Boolean

Double#exact_match? returns true when the passed in arguments exactly match the ArgumentEqualityExpectation arguments.

Returns:

  • (Boolean)


265
266
267
# File 'lib/rr/double.rb', line 265

def exact_match?(*arguments)
  definition.exact_match?(*arguments)
end

#expected_argumentsObject

The Arguments that this Double expects



302
303
304
305
# File 'lib/rr/double.rb', line 302

def expected_arguments
  return [] unless argument_expectation
  argument_expectation.expected_arguments
end

#formatted_nameObject



333
334
335
# File 'lib/rr/double.rb', line 333

def formatted_name
  self.class.formatted_name(method_name, expected_arguments)
end

#implementationObject



317
318
319
# File 'lib/rr/double.rb', line 317

def implementation
  definition.implementation
end

#implemented_by(implementation) ⇒ Object

Double#implemented_by sets the implementation of the Double. This method takes a Proc or a Method. Passing in a Method allows the Double to accept blocks.

obj = Object.new
def obj.foobar
  yield(1)
end
mock(obj).method_name.implemented_by(obj.method(:foobar))


196
197
198
# File 'lib/rr/double.rb', line 196

def implemented_by(implementation)
  definition.implemented_by implementation
end

#implemented_by_original_methodObject

Double#implemented_by_original_method sets the implementation of the Double to be the original method. This is primarily used with proxy.

obj = Object.new
def obj.foobar
  yield(1)
end
mock(obj).method_name.implemented_by_original_method
obj.foobar {|arg| puts arg} # puts 1


210
211
212
# File 'lib/rr/double.rb', line 210

def implemented_by_original_method
  definition.implemented_by_original_method
end

#method_nameObject

The method name that this Double is attatched to



297
298
299
# File 'lib/rr/double.rb', line 297

def method_name
  double_insertion.method_name
end

#neverObject

Double#never sets the expectation that the Double will never be called.

This method does not accept a block because it will never be called.

mock(subject).method_name.never


65
66
67
# File 'lib/rr/double.rb', line 65

def never
  definition.never
end

#once(&returns) ⇒ Object

Double#once sets the expectation that the Double will be called 1 time.

Passing in a block sets the return value.

mock(subject).method_name.once {:return_value}


75
76
77
# File 'lib/rr/double.rb', line 75

def once(&returns)
  definition.once(&returns)
end

#ordered(&returns) ⇒ Object

Double#ordered sets the Double to have an ordered expectation.

Passing in a block sets the return value.

mock(subject).method_name.ordered {return_value}


138
139
140
# File 'lib/rr/double.rb', line 138

def ordered(&returns)
  definition.ordered(&returns)
end

#ordered?Boolean

Double#ordered? returns true when the Double is ordered.

mock(subject).method_name.ordered?

Returns:

  • (Boolean)


145
146
147
# File 'lib/rr/double.rb', line 145

def ordered?
  definition.ordered?
end

#returns(value = nil, &implementation) ⇒ Object

Double#returns accepts an argument value or a block. It will raise an ArgumentError if both are passed in.

Passing in a block causes Double to return the return value of the passed in block.

Passing in an argument causes Double to return the argument.



183
184
185
# File 'lib/rr/double.rb', line 183

def returns(value=nil, &implementation)
  definition.returns(value, &implementation)
end

#terminal?Boolean

Returns:

  • (Boolean)


291
292
293
294
# File 'lib/rr/double.rb', line 291

def terminal?
  return false unless definition.times_matcher
  times_called_expectation.terminal?
end

#times(number, &returns) ⇒ Object

Double#times creates an TimesCalledExpectation of the passed in number.

Passing in a block sets the return value.

mock(subject).method_name.times(4) {:return_value}


128
129
130
# File 'lib/rr/double.rb', line 128

def times(number, &returns)
  definition.times(number, &returns)
end

#times_called_expectationObject



312
313
314
315
# File 'lib/rr/double.rb', line 312

def times_called_expectation
  @times_called_expectation.matcher = definition.times_matcher
  @times_called_expectation
end

#times_matcherObject

The TimesCalledMatcher for the TimesCalledExpectation



308
309
310
# File 'lib/rr/double.rb', line 308

def times_matcher
  times_called_expectation.matcher
end

#twice(&returns) ⇒ Object

Double#twice sets the expectation that the Double will be called 2 times.

Passing in a block sets the return value.

mock(subject).method_name.twice {:return_value}


85
86
87
# File 'lib/rr/double.rb', line 85

def twice(&returns)
  definition.twice(&returns)
end

#verifyObject

Double#verify verifies the the TimesCalledExpectation is satisfied for this scenario. A TimesCalledError is raised if the TimesCalledExpectation is not met.



285
286
287
288
289
# File 'lib/rr/double.rb', line 285

def verify
  return true unless definition.times_matcher
  times_called_expectation.verify!
  true
end

#wildcard_match?(*arguments) ⇒ Boolean

Double#wildcard_match? returns true when the passed in arguments wildcard match the ArgumentEqualityExpectation arguments.

Returns:

  • (Boolean)


271
272
273
# File 'lib/rr/double.rb', line 271

def wildcard_match?(*arguments)
  definition.wildcard_match?(*arguments)
end

#with(*args, &returns) ⇒ Object

Double#with sets the expectation that the Double will receive the passed in arguments.

Passing in a block sets the return value.

mock(subject).method_name.with(1, 2) {:return_value}


35
36
37
# File 'lib/rr/double.rb', line 35

def with(*args, &returns)
  definition.with(*args, &returns)
end

#with_any_args(&returns) ⇒ Object

Double#with_any_args sets the expectation that the Double can receive any arguments.

Passing in a block sets the return value.

mock(subject).method_name.with_any_args {:return_value}


45
46
47
# File 'lib/rr/double.rb', line 45

def with_any_args(&returns)
  definition.with_any_args(&returns)
end

#with_no_args(&returns) ⇒ Object

Double#with_no_args sets the expectation that the Double will receive no arguments.

Passing in a block sets the return value.

mock(subject).method_name.with_no_args {:return_value}


55
56
57
# File 'lib/rr/double.rb', line 55

def with_no_args(&returns)
  definition.with_no_args(&returns)
end

#yields(*args, &returns) ⇒ Object

Double#yields sets the Double to invoke a passed in block when the Double is called. An Expection will be raised if no block is passed in when the Double is called.

Passing in a block sets the return value.

mock(subject).method_name.yields(yield_arg1, yield_arg2) {return_value}
subject.method_name {|yield_arg1, yield_arg2|}


158
159
160
# File 'lib/rr/double.rb', line 158

def yields(*args, &returns)
  definition.yields(*args, &returns)
end