Class: RR::Double

Inherits:
Object
  • Object
show all
Includes:
Space::Reader
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

Methods included from Space::Reader

#space

Constructor Details

#initialize(double_injection, definition) ⇒ Double

Returns a new instance of Double.



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

def initialize(double_injection, definition)
  @double_injection = double_injection
  @definition = definition
  @times_called = 0
  @times_called_expectation = Expectations::TimesCalledExpectation.new(self)
  definition.double = self
  double_injection.register_double 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_injectionObject (readonly)

Returns the value of attribute double_injection.



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

def double_injection
  @double_injection
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(doubles) ⇒ Object



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

def list_message_part(doubles)
  doubles.collect do |double|
    "- #{formatted_name(double.method_name, double.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}}


187
188
189
# File 'lib/rr/double.rb', line 187

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


120
121
122
# File 'lib/rr/double.rb', line 120

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

#argument_expectationObject



310
311
312
# File 'lib/rr/double.rb', line 310

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}


98
99
100
# File 'lib/rr/double.rb', line 98

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}


109
110
111
# File 'lib/rr/double.rb', line 109

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

#attempt?Boolean

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

Returns:

  • (Boolean)


262
263
264
265
# File 'lib/rr/double.rb', line 262

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

#call(double_injection, *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.



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

def call(double_injection, *args, &block)
  if verbose?
    puts Double.formatted_name(double_injection.method_name, args)
  end
  times_called_expectation.attempt if definition.times_matcher
  space.verify_ordered_double(self) if ordered?
  yields!(block)
  return_value = call_implementation(double_injection, *args, &block)
  definition.after_call_proc ? extract_subject_from_return_value(definition.after_call_proc.call(return_value)) : return_value
end

#exact_match?(*arguments) ⇒ Boolean

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

Returns:

  • (Boolean)


250
251
252
# File 'lib/rr/double.rb', line 250

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

#expected_argumentsObject

The Arguments that this Double expects



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

def expected_arguments
  return [] unless argument_expectation
  argument_expectation.expected_arguments
end

#formatted_nameObject



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

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

#implementationObject



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

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))


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

def implemented_by(implementation)
  definition.implemented_by implementation
end

#method_nameObject

The method name that this Double is attatched to



282
283
284
# File 'lib/rr/double.rb', line 282

def method_name
  double_injection.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


67
68
69
# File 'lib/rr/double.rb', line 67

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}


77
78
79
# File 'lib/rr/double.rb', line 77

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}


140
141
142
# File 'lib/rr/double.rb', line 140

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)


147
148
149
# File 'lib/rr/double.rb', line 147

def ordered?
  definition.ordered?
end

#returns(*args, &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.



198
199
200
# File 'lib/rr/double.rb', line 198

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

#terminal?Boolean

Returns:

  • (Boolean)


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

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}


130
131
132
# File 'lib/rr/double.rb', line 130

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

#times_called_expectationObject



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

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

#times_matcherObject

The TimesCalledMatcher for the TimesCalledExpectation



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

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}


87
88
89
# File 'lib/rr/double.rb', line 87

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

#verbose(&block) ⇒ Object

Double#verbose sets the Double to print out each method call it receives.

Passing in a block sets the return value



154
155
156
# File 'lib/rr/double.rb', line 154

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

#verbose?Boolean

Double#verbose? returns true when verbose has been called on it. It returns true when the double is set to print each method call it receives.

Returns:

  • (Boolean)


160
161
162
# File 'lib/rr/double.rb', line 160

def verbose?
  definition.verbose?
end

#verifyObject

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



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

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)


256
257
258
# File 'lib/rr/double.rb', line 256

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}


37
38
39
# File 'lib/rr/double.rb', line 37

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}


47
48
49
# File 'lib/rr/double.rb', line 47

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}


57
58
59
# File 'lib/rr/double.rb', line 57

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|}


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

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