rspec-mocks 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. data/README.md +0 -19
  2. data/features/Scope.md +17 -0
  3. data/features/argument_matchers/README.md +27 -0
  4. data/features/argument_matchers/explicit.feature +60 -0
  5. data/features/argument_matchers/general_matchers.feature +85 -0
  6. data/features/argument_matchers/type_matchers.feature +25 -0
  7. data/features/message_expectations/any_instance.feature +2 -0
  8. data/features/message_expectations/receive_counts.feature +209 -0
  9. data/features/method_stubs/README.md +6 -10
  10. data/features/method_stubs/any_instance.feature +111 -1
  11. data/features/method_stubs/simple_return_value.feature +34 -25
  12. data/features/method_stubs/stub_implementation.feature +1 -1
  13. data/features/method_stubs/to_ary.feature +12 -10
  14. data/features/support/env.rb +1 -1
  15. data/lib/rspec/mocks/any_instance/chain.rb +49 -0
  16. data/lib/rspec/mocks/any_instance/expectation_chain.rb +33 -0
  17. data/lib/rspec/mocks/any_instance/message_chains.rb +48 -0
  18. data/lib/rspec/mocks/any_instance/recorder.rb +168 -0
  19. data/lib/rspec/mocks/any_instance/stub_chain.rb +35 -0
  20. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +34 -0
  21. data/lib/rspec/mocks/any_instance.rb +8 -235
  22. data/lib/rspec/mocks/argument_expectation.rb +1 -1
  23. data/lib/rspec/mocks/argument_matchers.rb +19 -25
  24. data/lib/rspec/mocks/extensions/marshal.rb +1 -1
  25. data/lib/rspec/mocks/extensions/psych.rb +1 -1
  26. data/lib/rspec/mocks/message_expectation.rb +7 -4
  27. data/lib/rspec/mocks/methods.rb +6 -8
  28. data/lib/rspec/mocks/mock.rb +2 -2
  29. data/lib/rspec/mocks/proxy.rb +4 -4
  30. data/lib/rspec/mocks/version.rb +4 -4
  31. data/lib/rspec/mocks.rb +13 -14
  32. data/spec/rspec/mocks/any_instance/message_chains_spec.rb +40 -0
  33. data/spec/rspec/mocks/any_instance_spec.rb +219 -24
  34. data/spec/rspec/mocks/any_number_of_times_spec.rb +2 -2
  35. data/spec/rspec/mocks/argument_expectation_spec.rb +15 -3
  36. data/spec/rspec/mocks/at_least_spec.rb +1 -1
  37. data/spec/rspec/mocks/at_most_spec.rb +1 -1
  38. data/spec/rspec/mocks/bug_report_10263_spec.rb +1 -1
  39. data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
  40. data/spec/rspec/mocks/bug_report_8165_spec.rb +2 -2
  41. data/spec/rspec/mocks/bug_report_957_spec.rb +2 -2
  42. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +1 -1
  43. data/spec/rspec/mocks/hash_including_matcher_spec.rb +11 -11
  44. data/spec/rspec/mocks/hash_not_including_matcher_spec.rb +6 -6
  45. data/spec/rspec/mocks/mock_spec.rb +49 -43
  46. data/spec/rspec/mocks/multiple_return_value_spec.rb +26 -26
  47. data/spec/rspec/mocks/partial_mock_spec.rb +3 -2
  48. data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +1 -0
  49. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +3 -3
  50. data/spec/rspec/mocks/precise_counts_spec.rb +1 -1
  51. data/spec/rspec/mocks/serialization_spec.rb +7 -2
  52. data/spec/rspec/mocks/stub_implementation_spec.rb +6 -6
  53. data/spec/rspec/mocks/stub_spec.rb +6 -6
  54. data/spec/rspec/mocks/to_ary_spec.rb +9 -0
  55. metadata +45 -42
  56. data/.autotest +0 -7
  57. data/.document +0 -5
  58. data/.gitignore +0 -10
  59. data/.travis.yml +0 -7
  60. data/Gemfile +0 -40
  61. data/Guardfile +0 -8
  62. data/License.txt +0 -22
  63. data/Rakefile +0 -75
  64. data/autotest/discover.rb +0 -1
  65. data/cucumber.yml +0 -2
  66. data/features/.nav +0 -17
  67. data/features/Changelog.md +0 -80
  68. data/rspec-mocks.gemspec +0 -25
  69. data/specs.watchr +0 -57
@@ -1,245 +1,18 @@
1
+ require 'rspec/mocks/any_instance/chain'
2
+ require 'rspec/mocks/any_instance/stub_chain'
3
+ require 'rspec/mocks/any_instance/stub_chain_chain'
4
+ require 'rspec/mocks/any_instance/expectation_chain'
5
+ require 'rspec/mocks/any_instance/message_chains'
6
+ require 'rspec/mocks/any_instance/recorder'
7
+
1
8
  module RSpec
2
9
  module Mocks
3
10
  module AnyInstance
4
- class Chain
5
- [
6
- :with, :and_return, :and_raise, :and_yield,
7
- :once, :twice, :any_number_of_times,
8
- :exactly, :times, :never,
9
- :at_least, :at_most
10
- ].each do |method_name|
11
- class_eval(<<-EOM, __FILE__, __LINE__)
12
- def #{method_name}(*args, &block)
13
- record(:#{method_name}, *args, &block)
14
- end
15
- EOM
16
- end
17
-
18
- def playback!(instance)
19
- messages.inject(instance) do |instance, message|
20
- instance.send(*message.first, &message.last)
21
- end
22
- end
23
-
24
- def constrained_to_any_of?(*constraints)
25
- constraints.any? do |constraint|
26
- messages.any? do |message|
27
- message.first.first == constraint
28
- end
29
- end
30
- end
31
-
32
- private
33
- def messages
34
- @messages ||= []
35
- end
36
-
37
- def last_message
38
- messages.last.first.first unless messages.empty?
39
- end
40
-
41
- def record(rspec_method_name, *args, &block)
42
- verify_invocation_order(rspec_method_name, *args, &block)
43
- messages << [args.unshift(rspec_method_name), block]
44
- self
45
- end
46
- end
47
-
48
- class StubChain < Chain
49
- def initialize(*args, &block)
50
- record(:stub, *args, &block)
51
- end
52
-
53
- def invocation_order
54
- @invocation_order ||= {
55
- :stub => [nil],
56
- :with => [:stub],
57
- :and_return => [:with, :stub],
58
- :and_raise => [:with, :stub],
59
- :and_yield => [:with, :stub]
60
- }
61
- end
62
-
63
- def expectation_filfilled?
64
- true
65
- end
66
-
67
- private
68
- def verify_invocation_order(rspec_method_name, *args, &block)
69
- unless invocation_order[rspec_method_name].include?(last_message)
70
- raise(NoMethodError, "Undefined method #{rspec_method_name}")
71
- end
72
- end
73
- end
74
-
75
- class ExpectationChain < Chain
76
- def initialize(*args, &block)
77
- record(:should_receive, *args, &block)
78
- @expectation_fulfilled = false
79
- end
80
-
81
- def invocation_order
82
- @invocation_order ||= {
83
- :should_receive => [nil],
84
- :with => [:should_receive],
85
- :and_return => [:with, :should_receive],
86
- :and_raise => [:with, :should_receive]
87
- }
88
- end
89
-
90
- def expectation_fulfilled!
91
- @expectation_fulfilled = true
92
- end
93
-
94
- def expectation_filfilled?
95
- @expectation_fulfilled || constrained_to_any_of?(:never, :any_number_of_times)
96
- end
97
-
98
- private
99
- def verify_invocation_order(rspec_method_name, *args, &block)
100
- end
101
- end
102
-
103
- class Recorder
104
- def initialize(klass)
105
- @message_chains = {}
106
- @observed_methods = []
107
- @played_methods = {}
108
- @klass = klass
109
- @expectation_set = false
110
- end
111
-
112
- def stub(method_name, *args, &block)
113
- observe!(method_name)
114
- @message_chains[method_name] = StubChain.new(method_name, *args, &block)
115
- end
116
-
117
- def should_receive(method_name, *args, &block)
118
- observe!(method_name)
119
- @expectation_set = true
120
- @message_chains[method_name] = ExpectationChain.new(method_name, *args, &block)
121
- end
122
-
123
- def stop_all_observation!
124
- @observed_methods.each do |method_name|
125
- restore_method!(method_name)
126
- end
127
- end
128
-
129
- def playback!(instance, method_name)
130
- RSpec::Mocks::space.add(instance)
131
- @message_chains[method_name].playback!(instance)
132
- @played_methods[method_name] = instance
133
- received_expected_message!(method_name) if has_expectation?(method_name)
134
- end
135
-
136
- def instance_that_received(method_name)
137
- @played_methods[method_name]
138
- end
139
-
140
- def verify
141
- if @expectation_set && !each_expectation_filfilled?
142
- raise RSpec::Mocks::MockExpectationError, "Exactly one instance should have received the following message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}"
143
- end
144
- end
145
-
146
- private
147
- def each_expectation_filfilled?
148
- @message_chains.all? do |method_name, chain|
149
- chain.expectation_filfilled?
150
- end
151
- end
152
-
153
- def has_expectation?(method_name)
154
- @message_chains[method_name].is_a?(ExpectationChain)
155
- end
156
-
157
- def unfulfilled_expectations
158
- @message_chains.map do |method_name, chain|
159
- method_name.to_s if chain.is_a?(ExpectationChain) unless chain.expectation_filfilled?
160
- end.compact
161
- end
162
-
163
- def received_expected_message!(method_name)
164
- @message_chains[method_name].expectation_fulfilled!
165
- restore_method!(method_name)
166
- mark_invoked!(method_name)
167
- end
168
-
169
- def restore_method!(method_name)
170
- if @klass.method_defined?(build_alias_method_name(method_name))
171
- restore_original_method!(method_name)
172
- else
173
- remove_dummy_method!(method_name)
174
- end
175
- end
176
-
177
- def build_alias_method_name(method_name)
178
- "__#{method_name}_without_any_instance__"
179
- end
180
-
181
- def restore_original_method!(method_name)
182
- alias_method_name = build_alias_method_name(method_name)
183
- @klass.class_eval do
184
- alias_method method_name, alias_method_name
185
- remove_method alias_method_name
186
- end
187
- end
188
-
189
- def remove_dummy_method!(method_name)
190
- @klass.class_eval do
191
- remove_method method_name
192
- end
193
- end
194
-
195
- def backup_method!(method_name)
196
- alias_method_name = build_alias_method_name(method_name)
197
- @klass.class_eval do
198
- if method_defined?(method_name)
199
- alias_method alias_method_name, method_name
200
- end
201
- end
202
- end
203
-
204
- def stop_observing!(method_name)
205
- restore_method!(method_name)
206
- @observed_methods.delete(method_name)
207
- end
208
-
209
- def already_observing?(method_name)
210
- @observed_methods.include?(method_name)
211
- end
212
-
213
- def observe!(method_name)
214
- stop_observing!(method_name) if already_observing?(method_name)
215
- @observed_methods << method_name
216
- backup_method!(method_name)
217
- @klass.class_eval(<<-EOM, __FILE__, __LINE__)
218
- def #{method_name}(*args, &blk)
219
- self.class.__recorder.playback!(self, :#{method_name})
220
- self.send(:#{method_name}, *args, &blk)
221
- end
222
- EOM
223
- end
224
-
225
- def mark_invoked!(method_name)
226
- backup_method!(method_name)
227
- @klass.class_eval(<<-EOM, __FILE__, __LINE__)
228
- def #{method_name}(*args, &blk)
229
- method_name = :#{method_name}
230
- current_instance = self
231
- invoked_instance = self.class.__recorder.instance_that_received(method_name)
232
- raise RSpec::Mocks::MockExpectationError, "The message '#{method_name}' was received by \#{self.inspect} but has already been received by \#{invoked_instance}"
233
- end
234
- EOM
235
- end
236
- end
237
-
238
11
  def any_instance
239
12
  RSpec::Mocks::space.add(self)
240
13
  __recorder
241
14
  end
242
-
15
+
243
16
  def rspec_verify
244
17
  __recorder.verify
245
18
  super
@@ -26,7 +26,7 @@ module RSpec
26
26
  end
27
27
 
28
28
  def is_matcher?(obj)
29
- !null_object?(obj) & obj.respond_to?(:matches?) & obj.respond_to?(:description)
29
+ !null_object?(obj) & obj.respond_to?(:matches?) & [:failure_message_for_should, :failure_message].any? { |m| obj.respond_to?(m) }
30
30
  end
31
31
 
32
32
  def args_match?(*args)
@@ -138,48 +138,41 @@ module RSpec
138
138
  end
139
139
  end
140
140
 
141
- # :call-seq:
142
- # object.should_receive(:message).with(any_args())
143
- #
144
141
  # Passes if object receives :message with any args at all. This is
145
142
  # really a more explicit variation of object.should_receive(:message)
143
+ #
144
+ # == Examples
145
+ # object.should_receive(:message).with(any_args())
146
146
  def any_args
147
147
  AnyArgsMatcher.new
148
148
  end
149
149
 
150
- # :call-seq:
151
- # object.should_receive(:message).with(anything())
152
- #
153
150
  # Passes as long as there is an argument.
151
+ #
152
+ # == Examples
153
+ # object.should_receive(:message).with(anything())
154
154
  def anything
155
155
  AnyArgMatcher.new(nil)
156
156
  end
157
157
 
158
- # :call-seq:
159
- # object.should_receive(:message).with(no_args)
160
- #
161
158
  # Passes if no arguments are passed along with the message
159
+ #
160
+ # == Examples
161
+ # object.should_receive(:message).with(no_args)
162
162
  def no_args
163
163
  NoArgsMatcher.new
164
164
  end
165
165
 
166
- # :call-seq:
167
- # object.should_receive(:message).with(duck_type(:hello))
168
- # object.should_receive(:message).with(duck_type(:hello, :goodbye))
169
- #
170
166
  # Passes if the argument responds to the specified messages.
171
167
  #
172
168
  # == Examples
173
- #
174
- # array = []
175
- # display = double('display')
176
- # display.should_receive(:present_names).with(duck_type(:length, :each))
177
- # => passes
169
+ # object.should_receive(:message).with(duck_type(:hello))
170
+ # object.should_receive(:message).with(duck_type(:hello, :goodbye))
178
171
  def duck_type(*args)
179
172
  DuckTypeMatcher.new(*args)
180
173
  end
181
174
 
182
- # :call-seq:
175
+ # == Examples
183
176
  # object.should_receive(:message).with(boolean())
184
177
  #
185
178
  # Passes if the argument is boolean.
@@ -187,22 +180,23 @@ module RSpec
187
180
  BooleanMatcher.new(nil)
188
181
  end
189
182
 
190
- # :call-seq:
183
+ # Passes if the argument is a hash that includes the specified key(s) or key/value
184
+ # pairs. If the hash includes other keys, it will still pass.
185
+ #
186
+ # == Examples
191
187
  # object.should_receive(:message).with(hash_including(:key => val))
192
188
  # object.should_receive(:message).with(hash_including(:key))
193
189
  # object.should_receive(:message).with(hash_including(:key, :key2 => val2))
194
- # Passes if the argument is a hash that includes the specified key(s) or key/value
195
- # pairs. If the hash includes other keys, it will still pass.
196
190
  def hash_including(*args)
197
191
  HashIncludingMatcher.new(anythingize_lonely_keys(*args))
198
192
  end
199
193
 
200
- # :call-seq:
194
+ # Passes if the argument is a hash that doesn't include the specified key(s) or key/value
195
+ #
196
+ # == Examples
201
197
  # object.should_receive(:message).with(hash_not_including(:key => val))
202
198
  # object.should_receive(:message).with(hash_not_including(:key))
203
199
  # object.should_receive(:message).with(hash_not_including(:key, :key2 => :val2))
204
- #
205
- # Passes if the argument is a hash that doesn't include the specified key(s) or key/value
206
200
  def hash_not_including(*args)
207
201
  HashNotIncludingMatcher.new(anythingize_lonely_keys(*args))
208
202
  end
@@ -7,7 +7,7 @@ module Marshal
7
7
  mp = object.instance_variable_get(:@mock_proxy)
8
8
  return dump_without_mocks(*args.unshift(object)) unless mp.is_a?(::RSpec::Mocks::Proxy)
9
9
 
10
- object.send(:remove_instance_variable, :@mock_proxy)
10
+ object.__send__(:remove_instance_variable, :@mock_proxy)
11
11
 
12
12
  begin
13
13
  dump_without_mocks(*args.unshift(object.dup))
@@ -7,7 +7,7 @@ if defined?(Psych) && Psych.respond_to?(:dump)
7
7
  mp = object.instance_variable_get(:@mock_proxy)
8
8
  return dump_without_mocks(object, *args) unless mp.is_a?(::RSpec::Mocks::Proxy)
9
9
 
10
- object.send(:remove_instance_variable, :@mock_proxy)
10
+ object.__send__(:remove_instance_variable, :@mock_proxy)
11
11
 
12
12
  begin
13
13
  dump_without_mocks(object, *args)
@@ -63,10 +63,8 @@ module RSpec
63
63
  @return_block = block_given? ? return_block : lambda { value }
64
64
  end
65
65
 
66
- # :call-seq:
67
- # and_raise()
68
- # and_raise(Exception) #any exception class
69
- # and_raise(exception) #any exception object
66
+ # Tells the mock or stub to raise an exception when the message
67
+ # is received.
70
68
  #
71
69
  # == Warning
72
70
  #
@@ -74,6 +72,11 @@ module RSpec
74
72
  # raise an instance of it, creating it with +new+. If the exception
75
73
  # class initializer requires any parameters, you must pass in an
76
74
  # instance and not the class.
75
+ #
76
+ # == Examples
77
+ # and_raise()
78
+ # and_raise(Exception) #any exception class
79
+ # and_raise(exception) #any exception object
77
80
  def and_raise(exception=Exception)
78
81
  @exception_to_raise = exception
79
82
  end
@@ -11,7 +11,7 @@ module RSpec
11
11
 
12
12
  def stub(sym_or_hash, opts={}, &block)
13
13
  if Hash === sym_or_hash
14
- sym_or_hash.each {|method, value| stub!(method).and_return value }
14
+ sym_or_hash.each {|method, value| stub(method).and_return value }
15
15
  else
16
16
  __mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts, &block)
17
17
  end
@@ -24,15 +24,13 @@ module RSpec
24
24
  alias_method :stub!, :stub
25
25
  alias_method :unstub!, :unstub
26
26
 
27
- # :call-seq:
28
- # double.stub_chain("foo.bar") { :baz }
29
- # double.stub_chain(:foo, :bar) { :baz }
30
- #
31
27
  # Stubs a chain of methods. Especially useful with fluent and/or
32
28
  # composable interfaces.
33
29
  #
34
30
  # == Examples
35
31
  #
32
+ # double.stub_chain("foo.bar") { :baz }
33
+ # double.stub_chain(:foo, :bar) { :baz }
36
34
  # Article.stub_chain("recent.published") { [Article.new] }
37
35
  def stub_chain(*chain, &blk)
38
36
  chain, blk = format_chain(*chain, &blk)
@@ -50,15 +48,15 @@ module RSpec
50
48
  end
51
49
  end
52
50
 
53
- def received_message?(sym, *args, &block) #:nodoc:
51
+ def received_message?(sym, *args, &block)
54
52
  __mock_proxy.received_message?(sym.to_sym, *args, &block)
55
53
  end
56
54
 
57
- def rspec_verify #:nodoc:
55
+ def rspec_verify
58
56
  __mock_proxy.verify
59
57
  end
60
58
 
61
- def rspec_reset #:nodoc:
59
+ def rspec_reset
62
60
  __mock_proxy.reset
63
61
  end
64
62
 
@@ -35,7 +35,7 @@ module RSpec
35
35
  alias_method :to_str, :to_s
36
36
 
37
37
  def respond_to?(sym, incl_private=false)
38
- __mock_proxy.null_object? ? true : super
38
+ __mock_proxy.null_object? && sym != :to_ary ? true : super
39
39
  end
40
40
 
41
41
  private
@@ -70,7 +70,7 @@ module RSpec
70
70
 
71
71
  def assign_stubs(stubs)
72
72
  stubs.each_pair do |message, response|
73
- stub!(message).and_return(response)
73
+ stub(message).and_return(response)
74
74
  end
75
75
  end
76
76
  end
@@ -45,11 +45,11 @@ module RSpec
45
45
  @object
46
46
  end
47
47
 
48
- def already_proxied_respond_to # :nodoc:
48
+ def already_proxied_respond_to
49
49
  @already_proxied_respond_to = true
50
50
  end
51
51
 
52
- def already_proxied_respond_to? # :nodoc:
52
+ def already_proxied_respond_to?
53
53
  @already_proxied_respond_to
54
54
  end
55
55
 
@@ -69,7 +69,7 @@ module RSpec
69
69
  method_double[method_name].remove_stub
70
70
  end
71
71
 
72
- def verify #:nodoc:
72
+ def verify
73
73
  method_doubles.each {|d| d.verify}
74
74
  ensure
75
75
  reset
@@ -110,7 +110,7 @@ module RSpec
110
110
  stub.advise(*args)
111
111
  raise_unexpected_message_args_error(stub, *args)
112
112
  elsif @object.is_a?(Class)
113
- @object.superclass.send(method_name, *args, &block)
113
+ @object.superclass.__send__(method_name, *args, &block)
114
114
  else
115
115
  @object.__send__(:method_missing, method_name, *args, &block)
116
116
  end
@@ -1,7 +1,7 @@
1
- module RSpec # :nodoc:
2
- module Mocks # :nodoc:
3
- module Version # :nodoc:
4
- STRING = '2.6.0'
1
+ module RSpec
2
+ module Mocks
3
+ module Version
4
+ STRING = '2.7.0'
5
5
  end
6
6
  end
7
7
  end
data/lib/rspec/mocks.rb CHANGED
@@ -17,7 +17,7 @@ module RSpec
17
17
  #
18
18
  # book = double("book")
19
19
  # double.stub(:title) { "The RSpec Book" }
20
- # double.title => "The RSpec Book"
20
+ # double.title # => "The RSpec Book"
21
21
  #
22
22
  # When we declare a stub, we say we are "stubbing" a method.
23
23
  #
@@ -37,9 +37,9 @@ module RSpec
37
37
  # == Mock Objects and Test Stubs
38
38
  #
39
39
  # The names Mock Object and Test Stub suggest specialized Test Doubles. i.e.
40
- # Test Stub evokes Test Double that only supports method stubs, and a Mock
41
- # Object evokes a Test Double that only supports message expectations, or
42
- # sometimes supports message expectations in addition to method stubs.
40
+ # a Test Stub is a Test Double that only supports method stubs, and a Mock
41
+ # Object is a Test Double that supports message expectations and method
42
+ # stubs.
43
43
  #
44
44
  # There is a lot of overlapping nomenclature here, and there are many
45
45
  # variations of these patterns (fakes, spies, etc). Keep in mind that most of
@@ -60,7 +60,7 @@ module RSpec
60
60
  #
61
61
  # In this case we're instrumenting Person to return the person object we've
62
62
  # defined whenever it receives the +find+ message. We can do this with any
63
- # object in a system because RSpec adds the +stub+ and +should_receive+
63
+ # object in a system because rspec-mocks adds the +stub+ and +should_receive+
64
64
  # methods to every object. When we use either, RSpec replaces the method
65
65
  # we're stubbing or mocking with it's own test-double-like method. At the
66
66
  # end of the example, RSpec verifies any message expectations, and then
@@ -73,15 +73,14 @@ module RSpec
73
73
  #
74
74
  # == Argument Matchers
75
75
  #
76
- # Arguments that are passed to #with are compared with actual arguments received
77
- # using == by default. In cases in which you want to specify things about the arguments
78
- # rather than the arguments themselves, you can use any of RSpec's Expression Matchers.
79
- # They don't all make syntactic sense (they were primarily designed for use with
80
- # RSpec::Expectations), but you are free to create your own custom RSpec::Matchers.
76
+ # Arguments that are passed to +with+ are compared with actual arguments
77
+ # received using ==. In cases in which you want to specify things about the
78
+ # arguments rather than the arguments themselves, you can use any of the
79
+ # matchers that ship with rspec-expectations. They don't all make syntactic
80
+ # sense (they were primarily designed for use with RSpec::Expectations), but
81
+ # you are free to create your own custom RSpec::Matchers.
81
82
  #
82
- # RSpec::Mocks does provide one additional Matcher method named #ducktype.
83
- #
84
- # In addition, RSpec::Mocks adds some keyword Symbols that you can use to
83
+ # rspec-mocks also adds some keyword Symbols that you can use to
85
84
  # specify certain kinds of arguments:
86
85
  #
87
86
  # double.should_receive(:msg).with(no_args())
@@ -152,7 +151,7 @@ module RSpec
152
151
  #
153
152
  # double.should_receive(:msg) do |arg|
154
153
  # arg.should be_an_istance_of(Array)
155
- # arg.length.should == 7
154
+ # arg.length.should eq 7
156
155
  # end
157
156
  #
158
157
  # == Combining Expectation Details
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe RSpec::Mocks::AnyInstance::MessageChains do
4
+ let(:chains) { RSpec::Mocks::AnyInstance::MessageChains.new }
5
+ let(:stub_chain) { RSpec::Mocks::AnyInstance::StubChain.new }
6
+ let(:expectation_chain) { RSpec::Mocks::AnyInstance::ExpectationChain.new }
7
+
8
+ it "knows if a method does not have an expectation set on it" do
9
+ chains.add(:method_name, stub_chain)
10
+ chains.has_expectation?(:method_name).should be_false
11
+ end
12
+
13
+ it "knows if a method has an expectation set on it" do
14
+ chains.add(:method_name, stub_chain)
15
+ chains.add(:method_name, expectation_chain)
16
+ chains.has_expectation?(:method_name).should be_true
17
+ end
18
+
19
+ it "can remove all stub chains" do
20
+ chains.add(:method_name, stub_chain)
21
+ chains.add(:method_name, expectation_chain)
22
+ chains.add(:method_name, another_stub_chain = RSpec::Mocks::AnyInstance::StubChain.new)
23
+
24
+ chains.remove_stub_chains_for!(:method_name)
25
+ chains[:method_name].should eq([expectation_chain])
26
+ end
27
+
28
+ context "creating stub chains" do
29
+ it "understands how to add a stub chain for a method" do
30
+ chains.add(:method_name, stub_chain)
31
+ chains[:method_name].should eq([stub_chain])
32
+ end
33
+
34
+ it "allows multiple stub chains for a method" do
35
+ chains.add(:method_name, stub_chain)
36
+ chains.add(:method_name, another_stub_chain = RSpec::Mocks::AnyInstance::StubChain.new)
37
+ chains[:method_name].should eq([stub_chain, another_stub_chain])
38
+ end
39
+ end
40
+ end