Class: RR::Scenario

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

Overview

RR::Scenario 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) ⇒ Scenario

Returns a new instance of Scenario.



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

def initialize(space, double)
  @space = space
  @implementation = nil
  @argument_expectation = nil
  @times_called_expectation = nil
  @times_called = 0
  @after_call = nil
  @double = double
  @yields = nil
end

Instance Attribute Details

#argument_expectationObject (readonly)

Returns the value of attribute argument_expectation.



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

def argument_expectation
  @argument_expectation
end

#doubleObject (readonly)

Returns the value of attribute double.



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

def double
  @double
end

#times_calledObject (readonly)

Returns the value of attribute times_called.



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

def times_called
  @times_called
end

#times_called_expectationObject (readonly)

Returns the value of attribute times_called_expectation.



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

def times_called_expectation
  @times_called_expectation
end

Class Method Details

.formatted_name(method_name, args) ⇒ Object



7
8
9
10
# File 'lib/rr/scenario.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/scenario.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

Scenario#after_call creates a callback that occurs after call is called. The passed in block receives the return value of the Scenario 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 probes.

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

Raises:

  • (ArgumentError)


201
202
203
204
205
# File 'lib/rr/scenario.rb', line 201

def after_call(&block)
  raise ArgumentError, "after_call expects a block" unless block
  @after_call = block
  self
end

#any_number_of_times(&returns) ⇒ Object

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

Passing in a block sets the return value.

mock(subject).method_name.any_number_of_times


138
139
140
141
142
# File 'lib/rr/scenario.rb', line 138

def any_number_of_times(&returns)
  @times_called_expectation = Expectations::TimesCalledExpectation.new(TimesCalledMatchers::AnyTimesMatcher.new)
  returns(&returns) if returns
  self
end

#at_least(number, &returns) ⇒ Object

Scenario#at_least sets the expectation that the Scenario 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}


110
111
112
113
114
115
# File 'lib/rr/scenario.rb', line 110

def at_least(number, &returns)
  matcher = RR::TimesCalledMatchers::AtLeastMatcher.new(number)
  @times_called_expectation = Expectations::TimesCalledExpectation.new(matcher)
  returns(&returns) if returns
  self
end

#at_most(number, &returns) ⇒ Object

Scenario#at_most allows sets the expectation that the Scenario 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}


124
125
126
127
128
129
# File 'lib/rr/scenario.rb', line 124

def at_most(number, &returns)
  matcher = RR::TimesCalledMatchers::AtMostMatcher.new(number)
  @times_called_expectation = Expectations::TimesCalledExpectation.new(matcher)
  returns(&returns) if returns
  self
end

#attempt?Boolean

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

Returns:

  • (Boolean)


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

def attempt?
  return true unless @times_called_expectation
  @times_called_expectation.attempt?
end

#call(*args, &block) ⇒ Object

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

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



244
245
246
247
248
# File 'lib/rr/scenario.rb', line 244

def call(*args, &block)
  return_value = call_implementation(*args, &block)
  @after_call.call(return_value) if @after_call
  return_value
end

#exact_match?(*arguments) ⇒ Boolean

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

Returns:

  • (Boolean)


272
273
274
275
# File 'lib/rr/scenario.rb', line 272

def exact_match?(*arguments)
  return false unless @argument_expectation 
  @argument_expectation.exact_match?(*arguments)
end

#expected_argumentsObject

The Arguments that this Scenario expects



311
312
313
314
# File 'lib/rr/scenario.rb', line 311

def expected_arguments
  return [] unless argument_expectation
  argument_expectation.expected_arguments
end

#implemented_by(implementation) ⇒ Object

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

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


234
235
236
237
# File 'lib/rr/scenario.rb', line 234

def implemented_by(implementation)
  @implementation = implementation
  self
end

#method_nameObject

The method name that this Scenario is attatched to



306
307
308
# File 'lib/rr/scenario.rb', line 306

def method_name
  double.method_name
end

#neverObject

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

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

mock(subject).method_name.never


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

def never
  @times_called_expectation = Expectations::TimesCalledExpectation.new(0)
  self
end

#once(&returns) ⇒ Object

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

Passing in a block sets the return value.

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


85
86
87
88
89
# File 'lib/rr/scenario.rb', line 85

def once(&returns)
  @times_called_expectation = Expectations::TimesCalledExpectation.new(1)
  returns(&returns) if returns
  self
end

#ordered(&returns) ⇒ Object

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

Passing in a block sets the return value.

mock(subject).method_name.ordered {return_value}


162
163
164
165
166
167
# File 'lib/rr/scenario.rb', line 162

def ordered(&returns)
  @ordered = true
  @space.ordered_scenarios << self unless @space.ordered_scenarios.include?(self)
  returns(&returns) if returns
  self
end

#ordered?Boolean

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

mock(subject).method_name.ordered?

Returns:

  • (Boolean)


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

def ordered?
  @ordered
end

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

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

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

Passing in an argument causes Scenario to return the argument.



214
215
216
217
218
219
220
221
222
223
# File 'lib/rr/scenario.rb', line 214

def returns(value=nil, &implementation)
  if value && implementation
    raise ArgumentError, "returns cannot accept both an argument and a block"
  end
  if value.nil?
    implemented_by implementation
  else
    implemented_by proc {value}
  end
end

#terminal?Boolean

Returns:

  • (Boolean)


300
301
302
303
# File 'lib/rr/scenario.rb', line 300

def terminal?
  return false unless @times_called_expectation
  @times_called_expectation.terminal?
end

#times(number, &returns) ⇒ Object

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


150
151
152
153
154
# File 'lib/rr/scenario.rb', line 150

def times(number, &returns)
  @times_called_expectation = Expectations::TimesCalledExpectation.new(number)
  returns(&returns) if returns
  self
end

#times_matcherObject

The TimesCalledMatcher for the TimesCalledExpectation



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

def times_matcher
  times_called_expectation.matcher
end

#twice(&returns) ⇒ Object

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

Passing in a block sets the return value.

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


97
98
99
100
101
# File 'lib/rr/scenario.rb', line 97

def twice(&returns)
  @times_called_expectation = Expectations::TimesCalledExpectation.new(2)
  returns(&returns) if returns
  self
end

#verifyObject

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



294
295
296
297
298
# File 'lib/rr/scenario.rb', line 294

def verify
  return true unless @times_called_expectation
  @times_called_expectation.verify!
  true
end

#wildcard_match?(*arguments) ⇒ Boolean

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

Returns:

  • (Boolean)


279
280
281
282
# File 'lib/rr/scenario.rb', line 279

def wildcard_match?(*arguments)
  return false unless @argument_expectation
  @argument_expectation.wildcard_match?(*arguments)
end

#with(*args, &returns) ⇒ Object

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

Passing in a block sets the return value.

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


38
39
40
41
42
# File 'lib/rr/scenario.rb', line 38

def with(*args, &returns)
  @argument_expectation = Expectations::ArgumentEqualityExpectation.new(*args)
  returns(&returns) if returns
  self
end

#with_any_args(&returns) ⇒ Object

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

Passing in a block sets the return value.

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


50
51
52
53
54
# File 'lib/rr/scenario.rb', line 50

def with_any_args(&returns)
  @argument_expectation = Expectations::AnyArgumentExpectation.new
  returns(&returns) if returns
  self
end

#with_no_args(&returns) ⇒ Object

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

Passing in a block sets the return value.

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


62
63
64
65
66
# File 'lib/rr/scenario.rb', line 62

def with_no_args(&returns)
  @argument_expectation = Expectations::ArgumentEqualityExpectation.new()
  returns(&returns) if returns
  self
end

#yields(*args, &returns) ⇒ Object

Scenario#yields sets the Scenario to invoke a passed in block when the Scenario is called. An Expection will be raised if no block is passed in when the Scenario 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|}


185
186
187
188
189
# File 'lib/rr/scenario.rb', line 185

def yields(*args, &returns)
  @yields = args
  returns(&returns) if returns
  self
end