rspec-mocks 2.13.1 → 2.14.0.rc1

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 (99) hide show
  1. data/Changelog.md +45 -4
  2. data/README.md +1 -1
  3. data/features/argument_matchers/README.md +2 -2
  4. data/features/argument_matchers/explicit.feature +2 -3
  5. data/features/argument_matchers/general_matchers.feature +2 -2
  6. data/features/argument_matchers/type_matchers.feature +3 -4
  7. data/features/message_expectations/README.md +2 -2
  8. data/features/message_expectations/any_instance.feature +2 -2
  9. data/features/message_expectations/block_local_expectations.feature.pending +3 -3
  10. data/features/message_expectations/expect_message_using_expect.feature +103 -0
  11. data/features/message_expectations/expect_message_using_should_receive.feature +118 -0
  12. data/features/message_expectations/receive_counts.feature +1 -1
  13. data/features/method_stubs/README.md +1 -1
  14. data/features/method_stubs/any_instance.feature +11 -11
  15. data/features/method_stubs/as_null_object.feature +1 -1
  16. data/features/method_stubs/stub_implementation.feature +2 -2
  17. data/features/outside_rspec/configuration.feature +0 -20
  18. data/features/spies/spy_partial_mock_method.feature +34 -0
  19. data/features/spies/spy_pure_mock_method.feature +76 -0
  20. data/features/spies/spy_unstubbed_method.feature +18 -0
  21. data/features/step_definitions/additional_cli_steps.rb +7 -0
  22. data/features/test_frameworks/test_unit.feature +43 -0
  23. data/lib/rspec/mocks.rb +9 -34
  24. data/lib/rspec/mocks/any_instance/chain.rb +8 -2
  25. data/lib/rspec/mocks/any_instance/expectation_chain.rb +19 -16
  26. data/lib/rspec/mocks/any_instance/recorder.rb +6 -3
  27. data/lib/rspec/mocks/any_instance/stub_chain.rb +11 -11
  28. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +8 -10
  29. data/lib/rspec/mocks/argument_list_matcher.rb +7 -3
  30. data/lib/rspec/mocks/configuration.rb +28 -1
  31. data/lib/rspec/mocks/deprecation.rb +18 -0
  32. data/lib/rspec/mocks/error_generator.rb +60 -8
  33. data/lib/rspec/mocks/errors.rb +1 -1
  34. data/lib/rspec/mocks/example_methods.rb +39 -3
  35. data/lib/rspec/mocks/extensions/marshal.rb +4 -10
  36. data/lib/rspec/mocks/framework.rb +16 -4
  37. data/lib/rspec/mocks/instance_method_stasher.rb +3 -0
  38. data/lib/rspec/mocks/matchers/have_received.rb +93 -0
  39. data/lib/rspec/mocks/matchers/receive.rb +92 -0
  40. data/lib/rspec/mocks/message_expectation.rb +66 -129
  41. data/lib/rspec/mocks/method_double.rb +50 -43
  42. data/lib/rspec/mocks/mutate_const.rb +8 -20
  43. data/lib/rspec/mocks/proxy.rb +41 -25
  44. data/lib/rspec/mocks/proxy_for_nil.rb +36 -0
  45. data/lib/rspec/mocks/space.rb +64 -11
  46. data/lib/rspec/mocks/stub_chain.rb +51 -0
  47. data/lib/rspec/mocks/syntax.rb +329 -0
  48. data/lib/rspec/mocks/targets.rb +69 -0
  49. data/lib/rspec/mocks/test_double.rb +25 -4
  50. data/lib/rspec/mocks/version.rb +1 -1
  51. data/lib/spec/mocks.rb +1 -3
  52. data/spec/rspec/mocks/and_call_original_spec.rb +8 -0
  53. data/spec/rspec/mocks/and_yield_spec.rb +6 -6
  54. data/spec/rspec/mocks/any_instance_spec.rb +43 -31
  55. data/spec/rspec/mocks/any_number_of_times_spec.rb +6 -0
  56. data/spec/rspec/mocks/argument_expectation_spec.rb +12 -14
  57. data/spec/rspec/mocks/at_least_spec.rb +46 -37
  58. data/spec/rspec/mocks/at_most_spec.rb +12 -12
  59. data/spec/rspec/mocks/block_return_value_spec.rb +18 -1
  60. data/spec/rspec/mocks/bug_report_10260_spec.rb +1 -1
  61. data/spec/rspec/mocks/bug_report_10263_spec.rb +1 -1
  62. data/spec/rspec/mocks/bug_report_11545_spec.rb +4 -4
  63. data/spec/rspec/mocks/bug_report_600_spec.rb +1 -1
  64. data/spec/rspec/mocks/bug_report_7611_spec.rb +1 -1
  65. data/spec/rspec/mocks/configuration_spec.rb +124 -0
  66. data/spec/rspec/mocks/double_spec.rb +13 -1
  67. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +17 -1
  68. data/spec/rspec/mocks/hash_excluding_matcher_spec.rb +13 -13
  69. data/spec/rspec/mocks/matchers/have_received_spec.rb +266 -0
  70. data/spec/rspec/mocks/matchers/receive_spec.rb +318 -0
  71. data/spec/rspec/mocks/methods_spec.rb +27 -0
  72. data/spec/rspec/mocks/mock_ordering_spec.rb +4 -4
  73. data/spec/rspec/mocks/mock_space_spec.rb +94 -39
  74. data/spec/rspec/mocks/mock_spec.rb +65 -50
  75. data/spec/rspec/mocks/multiple_return_value_spec.rb +10 -10
  76. data/spec/rspec/mocks/mutate_const_spec.rb +21 -1
  77. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +10 -4
  78. data/spec/rspec/mocks/null_object_mock_spec.rb +11 -2
  79. data/spec/rspec/mocks/once_counts_spec.rb +5 -5
  80. data/spec/rspec/mocks/options_hash_spec.rb +4 -4
  81. data/spec/rspec/mocks/partial_mock_spec.rb +20 -11
  82. data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +7 -7
  83. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +2 -2
  84. data/spec/rspec/mocks/precise_counts_spec.rb +6 -6
  85. data/spec/rspec/mocks/serialization_spec.rb +1 -22
  86. data/spec/rspec/mocks/stash_spec.rb +4 -12
  87. data/spec/rspec/mocks/stub_implementation_spec.rb +3 -3
  88. data/spec/rspec/mocks/stub_spec.rb +44 -20
  89. data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +6 -6
  90. data/spec/rspec/mocks/twice_counts_spec.rb +6 -6
  91. data/spec/rspec/mocks_spec.rb +1 -3
  92. data/spec/spec_helper.rb +25 -1
  93. metadata +86 -81
  94. data/features/message_expectations/expect_message.feature +0 -94
  95. data/lib/rspec/mocks/any_instance.rb +0 -81
  96. data/lib/rspec/mocks/extensions/psych.rb +0 -23
  97. data/lib/rspec/mocks/methods.rb +0 -155
  98. data/lib/rspec/mocks/serialization.rb +0 -34
  99. data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +0 -197
@@ -4,9 +4,21 @@ describe "double" do
4
4
  it "is an alias for stub and mock" do
5
5
  expect(double()).to be_a(RSpec::Mocks::Mock)
6
6
  end
7
-
7
+
8
8
  it "uses 'Double' in failure messages" do
9
9
  double = double('name')
10
10
  expect {double.foo}.to raise_error(/Double "name" received/)
11
11
  end
12
+
13
+ describe "deprecated aliases" do
14
+ it "warns if #stub is used" do
15
+ expect(RSpec).to receive(:deprecate).with("stub", :replacement => "double")
16
+ stub("TestDouble")
17
+ end
18
+
19
+ it "warns if #mock is used" do
20
+ expect(RSpec).to receive(:deprecate).with("mock", :replacement => "double")
21
+ mock("TestDouble")
22
+ end
23
+ end
12
24
  end
@@ -9,7 +9,7 @@ module RSpec
9
9
  end
10
10
 
11
11
  after(:each) do
12
- @double.rspec_reset
12
+ reset @double
13
13
  end
14
14
 
15
15
  it "rejects non boolean" do
@@ -89,6 +89,22 @@ module RSpec
89
89
  @double.msg :no_msg_for_you
90
90
  end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected: :received.*\s*.*got: :no_msg_for_you/)
91
91
  end
92
+
93
+ it "fails with sensible message when args respond to #description" do
94
+ arg = Class.new do
95
+ def description
96
+ end
97
+
98
+ def inspect
99
+ "my_thing"
100
+ end
101
+ end.new
102
+
103
+ expect do
104
+ @double.should_receive(:msg).with(3)
105
+ @double.msg arg
106
+ end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (3)\n got: (my_thing)")
107
+ end
92
108
  end
93
109
  end
94
110
  end
@@ -4,20 +4,20 @@ module RSpec
4
4
  module Mocks
5
5
  module ArgumentMatchers
6
6
  describe HashExcludingMatcher do
7
-
7
+
8
8
  it "describes itself properly" do
9
9
  expect(HashExcludingMatcher.new(:a => 5).description).to eq "hash_not_including(:a=>5)"
10
- end
10
+ end
11
11
 
12
12
  describe "passing" do
13
13
  it "matches a hash without the specified key" do
14
14
  expect(hash_not_including(:c)).to eq({:a => 1, :b => 2})
15
15
  end
16
-
16
+
17
17
  it "matches a hash with the specified key, but different value" do
18
18
  expect(hash_not_including(:b => 3)).to eq({:a => 1, :b => 2})
19
19
  end
20
-
20
+
21
21
  it "matches a hash without the specified key, given as anything()" do
22
22
  expect(hash_not_including(:c => anything)).to eq({:a => 1, :b => 2})
23
23
  end
@@ -25,38 +25,38 @@ module RSpec
25
25
  it "matches an empty hash" do
26
26
  expect(hash_not_including(:a)).to eq({})
27
27
  end
28
-
28
+
29
29
  it "matches a hash without any of the specified keys" do
30
30
  expect(hash_not_including(:a, :b, :c)).to eq(:d => 7)
31
31
  end
32
-
32
+
33
33
  end
34
-
34
+
35
35
  describe "failing" do
36
36
  it "does not match a non-hash" do
37
37
  expect(hash_not_including(:a => 1)).not_to eq 1
38
38
  end
39
-
39
+
40
40
  it "does not match a hash with a specified key" do
41
41
  expect(hash_not_including(:b)).not_to eq(:b => 2)
42
42
  end
43
-
43
+
44
44
  it "does not match a hash with the specified key/value pair" do
45
45
  expect(hash_not_including(:b => 2)).not_to eq(:a => 1, :b => 2)
46
46
  end
47
-
47
+
48
48
  it "does not match a hash with the specified key" do
49
49
  expect(hash_not_including(:a, :b => 3)).not_to eq(:a => 1, :b => 2)
50
50
  end
51
-
51
+
52
52
  it "does not match a hash with one of the specified keys" do
53
53
  expect(hash_not_including(:a, :b)).not_to eq(:b => 2)
54
54
  end
55
-
55
+
56
56
  it "does not match a hash with some of the specified keys" do
57
57
  expect(hash_not_including(:a, :b, :c)).not_to eq(:a => 1, :b => 2)
58
58
  end
59
-
59
+
60
60
  it "does not match a hash with one key/value pair included" do
61
61
  expect(hash_not_including(:a, :b, :c, :d => 7)).not_to eq(:d => 7)
62
62
  end
@@ -0,0 +1,266 @@
1
+ require 'spec_helper'
2
+
3
+ module RSpec
4
+ module Mocks
5
+ describe Matchers::HaveReceived do
6
+ describe "expect(...).to have_received" do
7
+ it 'passes when the double has received the given message' do
8
+ dbl = double_with_met_expectation(:expected_method)
9
+ expect(dbl).to have_received(:expected_method)
10
+ end
11
+
12
+ it 'passes when a null object has received the given message' do
13
+ dbl = null_object_with_met_expectation(:expected_method)
14
+ expect(dbl).to have_received(:expected_method)
15
+ end
16
+
17
+ it 'fails when the double has not received the given message' do
18
+ dbl = double_with_unmet_expectation(:expected_method)
19
+
20
+ expect {
21
+ expect(dbl).to have_received(:expected_method)
22
+ }.to raise_error(/expected: 1 time/)
23
+ end
24
+
25
+ it 'fails when a null object has not received the given message' do
26
+ dbl = double.as_null_object
27
+
28
+ expect {
29
+ expect(dbl).to have_received(:expected_method)
30
+ }.to raise_error(/expected: 1 time/)
31
+ end
32
+
33
+ it 'fails when the method has not been previously stubbed' do
34
+ dbl = double
35
+
36
+ expect {
37
+ expect(dbl).to have_received(:expected_method)
38
+ }.to raise_error(/method has not been stubbed/)
39
+ end
40
+
41
+ it 'fails when the method has been mocked' do
42
+ dbl = double
43
+ dbl.should_receive(:expected_method)
44
+ dbl.expected_method
45
+
46
+ expect {
47
+ expect(dbl).to have_received(:expected_method)
48
+ }.to raise_error(/method has been mocked instead of stubbed/)
49
+ end
50
+
51
+ it 'resets expectations on class methods when mocks are reset' do
52
+ dbl = Object
53
+ dbl.stub(:expected_method)
54
+ dbl.expected_method
55
+ reset dbl
56
+ dbl.stub(:expected_method)
57
+
58
+ expect {
59
+ expect(dbl).to have_received(:expected_method)
60
+ }.to raise_error(/0 times/)
61
+ end
62
+
63
+ context "with" do
64
+ it 'passes when the given args match the args used with the message' do
65
+ dbl = double_with_met_expectation(:expected_method, :expected, :args)
66
+ expect(dbl).to have_received(:expected_method).with(:expected, :args)
67
+ end
68
+
69
+ it 'fails when the given args do not match the args used with the message' do
70
+ dbl = double_with_met_expectation(:expected_method, :expected, :args)
71
+
72
+ expect {
73
+ expect(dbl).to have_received(:expected_method).with(:unexpected, :args)
74
+ }.to raise_error(/with unexpected arguments/)
75
+ end
76
+ end
77
+
78
+ it 'generates a useful description' do
79
+ matcher = have_received(:expected_method).with(:expected_args).once
80
+ expect(matcher.description).to eq 'have received expected_method(:expected_args) 1 time'
81
+ end
82
+
83
+ context "counts" do
84
+ let(:dbl) { double(:expected_method => nil) }
85
+
86
+ before do
87
+ dbl.expected_method
88
+ dbl.expected_method
89
+ dbl.expected_method
90
+ end
91
+
92
+ context "exactly" do
93
+ it 'passes when the message was received the given number of times' do
94
+ expect(dbl).to have_received(:expected_method).exactly(3).times
95
+ end
96
+
97
+ it 'fails when the message was received more times' do
98
+ expect {
99
+ expect(dbl).to have_received(:expected_method).exactly(2).times
100
+ }.to raise_error(/expected: 2 times.*received: 3 times/m)
101
+ end
102
+
103
+ it 'fails when the message was received fewer times' do
104
+ expect {
105
+ expect(dbl).to have_received(:expected_method).exactly(4).times
106
+ }.to raise_error(/expected: 4 times.*received: 3 times/m)
107
+ end
108
+ end
109
+
110
+ context 'at_least' do
111
+ it 'passes when the message was received the given number of times' do
112
+ expect(dbl).to have_received(:expected_method).at_least(3).times
113
+ end
114
+
115
+ it 'passes when the message was received more times' do
116
+ expect(dbl).to have_received(:expected_method).at_least(2).times
117
+ end
118
+
119
+ it 'fails when the message was received fewer times' do
120
+ expect {
121
+ expect(dbl).to have_received(:expected_method).at_least(4).times
122
+ }.to raise_error(/expected: at least 4 times.*received: 3 times/m)
123
+ end
124
+ end
125
+
126
+ context 'at_most' do
127
+ it 'passes when the message was received the given number of times' do
128
+ expect(dbl).to have_received(:expected_method).at_most(3).times
129
+ end
130
+
131
+ it 'passes when the message was received fewer times' do
132
+ expect(dbl).to have_received(:expected_method).at_most(4).times
133
+ end
134
+
135
+ it 'fails when the message was received more times' do
136
+ expect {
137
+ expect(dbl).to have_received(:expected_method).at_most(2).times
138
+ }.to raise_error(/expected: at most 2 times.*received: 3 times/m)
139
+ end
140
+ end
141
+
142
+ context 'once' do
143
+ it 'passes when the message was received once' do
144
+ dbl = double(:expected_method => nil)
145
+ dbl.expected_method
146
+ expect(dbl).to have_received(:expected_method).once
147
+ end
148
+
149
+ it 'fails when the message was never received' do
150
+ dbl = double(:expected_method => nil)
151
+
152
+ expect {
153
+ expect(dbl).to have_received(:expected_method).once
154
+ }.to raise_error(/expected: 1 time.*received: 0 times/m)
155
+ end
156
+
157
+ it 'fails when the message was received twice' do
158
+ dbl = double(:expected_method => nil)
159
+ dbl.expected_method
160
+ dbl.expected_method
161
+
162
+ expect {
163
+ expect(dbl).to have_received(:expected_method).once
164
+ }.to raise_error(/expected: 1 time.*received: 2 times/m)
165
+ end
166
+ end
167
+
168
+ context 'twice' do
169
+ it 'passes when the message was received twice' do
170
+ dbl = double(:expected_method => nil)
171
+ dbl.expected_method
172
+ dbl.expected_method
173
+
174
+ expect(dbl).to have_received(:expected_method).twice
175
+ end
176
+
177
+ it 'fails when the message was received once' do
178
+ dbl = double(:expected_method => nil)
179
+ dbl.expected_method
180
+
181
+ expect {
182
+ expect(dbl).to have_received(:expected_method).twice
183
+ }.to raise_error(/expected: 2 times.*received: 1 time/m)
184
+ end
185
+
186
+ it 'fails when the message was received thrice' do
187
+ dbl = double(:expected_method => nil)
188
+ dbl.expected_method
189
+ dbl.expected_method
190
+ dbl.expected_method
191
+
192
+ expect {
193
+ expect(dbl).to have_received(:expected_method).twice
194
+ }.to raise_error(/expected: 2 times.*received: 3 times/m)
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ describe "expect(...).not_to have_received" do
201
+ it 'passes when the double has not received the given message' do
202
+ dbl = double_with_unmet_expectation(:expected_method)
203
+ expect(dbl).not_to have_received(:expected_method)
204
+ end
205
+
206
+ it 'fails when the double has received the given message' do
207
+ dbl = double_with_met_expectation(:expected_method)
208
+
209
+ expect {
210
+ expect(dbl).not_to have_received(:expected_method)
211
+ }.to raise_error(/expected: 0 times.*received: 1 time/m)
212
+ end
213
+
214
+ it 'fails when the method has not been previously stubbed' do
215
+ dbl = double
216
+
217
+ expect {
218
+ expect(dbl).not_to have_received(:expected_method)
219
+ }.to raise_error(/method has not been stubbed/)
220
+ end
221
+
222
+ context "with" do
223
+ it 'passes when the given args do not match the args used with the message' do
224
+ dbl = double_with_met_expectation(:expected_method, :expected, :args)
225
+ expect(dbl).not_to have_received(:expected_method).with(:unexpected, :args)
226
+ end
227
+
228
+ it 'fails when the given args match the args used with the message' do
229
+ dbl = double_with_met_expectation(:expected_method, :expected, :args)
230
+
231
+ expect {
232
+ expect(dbl).not_to have_received(:expected_method).with(:expected, :args)
233
+ }.to raise_error(/expected: 0 times.*received: 1 time/m) # TODO: better message
234
+ end
235
+ end
236
+
237
+ %w(exactly at_least at_most times once twice).each do |constraint|
238
+ it "does not allow #{constraint} to be used because it creates confusion" do
239
+ dbl = double_with_unmet_expectation(:expected_method)
240
+ expect {
241
+ expect(dbl).not_to have_received(:expected_method).send(constraint)
242
+ }.to raise_error(/can't use #{constraint} when negative/)
243
+ end
244
+ end
245
+ end
246
+
247
+ def double_with_met_expectation(method_name, *args)
248
+ double = double_with_unmet_expectation(method_name)
249
+ meet_expectation(double, method_name, *args)
250
+ end
251
+
252
+ def null_object_with_met_expectation(method_name, *args)
253
+ meet_expectation(double.as_null_object, method_name, *args)
254
+ end
255
+
256
+ def meet_expectation(double, method_name, *args)
257
+ double.send(method_name, *args)
258
+ double
259
+ end
260
+
261
+ def double_with_unmet_expectation(method_name)
262
+ double('double', method_name => true)
263
+ end
264
+ end
265
+ end
266
+ end
@@ -0,0 +1,318 @@
1
+ require 'spec_helper'
2
+
3
+ module RSpec
4
+ module Mocks
5
+ describe Matchers::Receive do
6
+ include_context "with syntax", :expect
7
+
8
+ def verify_all
9
+ ::RSpec::Mocks.space.verify_all
10
+ end
11
+
12
+ shared_examples_for "a receive matcher" do |*options|
13
+ it 'allows the caller to configure how the subject responds' do
14
+ wrapped.to receive(:foo).and_return(5)
15
+ expect(receiver.foo).to eq(5)
16
+ end
17
+
18
+ it 'allows the caller to constrain the received arguments' do
19
+ wrapped.to receive(:foo).with(:a)
20
+ receiver.foo(:a)
21
+
22
+ expect {
23
+ receiver.foo(:b)
24
+ }.to raise_error(/received :foo with unexpected arguments/)
25
+ end
26
+
27
+ it 'allows a `do...end` block implementation to be provided' do
28
+ wrapped.to receive(:foo) do
29
+ 4
30
+ end
31
+
32
+ expect(receiver.foo).to eq(4)
33
+ end
34
+
35
+ it 'allows a `{ ... }` block implementation to be provided' do
36
+ wrapped.to receive(:foo) { 5 }
37
+ expect(receiver.foo).to eq(5)
38
+ end
39
+
40
+ it 'gives precedence to a `{ ... }` block when both forms are provided ' +
41
+ 'since that form actually binds to `receive`' do
42
+ wrapped.to receive(:foo) { :curly } do
43
+ :do_end
44
+ end
45
+
46
+ expect(receiver.foo).to eq(:curly)
47
+ end
48
+
49
+ it 'does not support other matchers', :unless => options.include?(:allow_other_matchers) do
50
+ expect {
51
+ wrapped.to eq(3)
52
+ }.to raise_error(UnsupportedMatcherError)
53
+ end
54
+ end
55
+
56
+ shared_examples_for "an expect syntax allowance" do |*options|
57
+ include_examples "a receive matcher", *options
58
+
59
+ it 'does not expect the message to be received' do
60
+ wrapped.to receive(:foo)
61
+ expect { verify_all }.not_to raise_error
62
+ end
63
+ end
64
+
65
+ shared_examples_for "an expect syntax negative allowance" do
66
+ it 'is disabled since this expression is confusing' do
67
+ expect {
68
+ wrapped.not_to receive(:foo)
69
+ }.to raise_error(/not_to receive` is not supported/)
70
+
71
+ expect {
72
+ wrapped.to_not receive(:foo)
73
+ }.to raise_error(/to_not receive` is not supported/)
74
+ end
75
+ end
76
+
77
+ shared_examples_for "an expect syntax expectation" do |*options|
78
+ include_examples "a receive matcher", *options
79
+
80
+ it 'sets up a message expectation that passes if the message is received' do
81
+ wrapped.to receive(:foo)
82
+ receiver.foo
83
+ verify_all
84
+ end
85
+
86
+ it 'sets up a message expectation that fails if the message is not received' do
87
+ wrapped.to receive(:foo)
88
+
89
+ expect {
90
+ verify_all
91
+ }.to raise_error(RSpec::Mocks::MockExpectationError)
92
+ end
93
+
94
+ it "reports the line number of expectation of unreceived message", :pending => options.include?(:does_not_report_line_num) do
95
+ expected_error_line = __LINE__; wrapped.to receive(:foo)
96
+
97
+ expect {
98
+ verify_all
99
+ }.to raise_error { |e|
100
+ expect(e.backtrace.first).to match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
101
+ }
102
+ end
103
+ end
104
+
105
+ shared_examples_for "an expect syntax negative expectation" do
106
+ it 'sets up a negaive message expectation that passes if the message is not received' do
107
+ wrapped.not_to receive(:foo)
108
+ verify_all
109
+ end
110
+
111
+ it 'sets up a negative message expectation that fails if the message is received' do
112
+ wrapped.not_to receive(:foo)
113
+
114
+ expect {
115
+ receiver.foo
116
+ }.to raise_error(/expected: 0 times.*received: 1 time/m)
117
+ end
118
+
119
+ it 'supports `to_not` as an alias for `not_to`' do
120
+ wrapped.to_not receive(:foo)
121
+
122
+ expect {
123
+ receiver.foo
124
+ }.to raise_error(/expected: 0 times.*received: 1 time/m)
125
+ end
126
+
127
+ it 'allows the caller to constrain the received arguments' do
128
+ wrapped.not_to receive(:foo).with(:a)
129
+ def receiver.method_missing(*a); end # a poor man's stub...
130
+
131
+ expect {
132
+ receiver.foo(:b)
133
+ }.not_to raise_error
134
+
135
+ expect {
136
+ receiver.foo(:a)
137
+ }.to raise_error(/expected: 0 times.*received: 1 time/m)
138
+ end
139
+ end
140
+
141
+ describe "allow(...).to receive" do
142
+ include_examples "an expect syntax allowance" do
143
+ let(:receiver) { double }
144
+ let(:wrapped) { allow(receiver) }
145
+ end
146
+ end
147
+
148
+ describe "allow(...).not_to receive" do
149
+ include_examples "an expect syntax negative allowance" do
150
+ let(:wrapped) { allow(double) }
151
+ end
152
+ end
153
+
154
+ describe "allow_any_instance_of(...).to receive" do
155
+ include_examples "an expect syntax allowance" do
156
+ let(:klass) { Class.new }
157
+ let(:wrapped) { allow_any_instance_of(klass) }
158
+ let(:receiver) { klass.new }
159
+ end
160
+ end
161
+
162
+ describe "allow_any_instance_of(...).not_to receive" do
163
+ include_examples "an expect syntax negative allowance" do
164
+ let(:wrapped) { allow_any_instance_of(Class.new) }
165
+ end
166
+ end
167
+
168
+ describe "expect(...).to receive" do
169
+ include_examples "an expect syntax expectation", :allow_other_matchers do
170
+ let(:receiver) { double }
171
+ let(:wrapped) { expect(receiver) }
172
+ end
173
+ end
174
+
175
+ describe "expect_any_instance_of(...).to receive" do
176
+ include_examples "an expect syntax expectation", :does_not_report_line_num do
177
+ let(:klass) { Class.new }
178
+ let(:wrapped) { expect_any_instance_of(klass) }
179
+ let(:receiver) { klass.new }
180
+ end
181
+ end
182
+
183
+ describe "expect(...).not_to receive" do
184
+ include_examples "an expect syntax negative expectation" do
185
+ let(:receiver) { double }
186
+ let(:wrapped) { expect(receiver) }
187
+ end
188
+ end
189
+
190
+ describe "expect_any_instance_of(...).not_to receive" do
191
+ include_examples "an expect syntax negative expectation" do
192
+ let(:klass) { Class.new }
193
+ let(:wrapped) { expect_any_instance_of(klass) }
194
+ let(:receiver) { klass.new }
195
+ end
196
+ end
197
+
198
+ shared_examples "using rspec-mocks in another test framework" do
199
+ it 'can use the `expect` syntax' do
200
+ dbl = double
201
+
202
+ framework.new.instance_eval do
203
+ expect(dbl).to receive(:foo).and_return(3)
204
+ end
205
+
206
+ expect(dbl.foo).to eq(3)
207
+ end
208
+
209
+ it 'expects the method to be called when `expect` is used' do
210
+ dbl = double
211
+
212
+ framework.new.instance_eval do
213
+ expect(dbl).to receive(:foo)
214
+ end
215
+
216
+ expect { verify dbl }.to raise_error(RSpec::Mocks::MockExpectationError)
217
+ end
218
+
219
+ it 'supports `expect(...).not_to receive`' do
220
+ dbl = double
221
+
222
+ framework.new.instance_eval do
223
+ expect(dbl).not_to receive(:foo)
224
+ end
225
+
226
+ expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError)
227
+ end
228
+
229
+ it 'supports `expect(...).to_not receive`' do
230
+ dbl = double
231
+
232
+ framework.new.instance_eval do
233
+ expect(dbl).to_not receive(:foo)
234
+ end
235
+
236
+ expect { dbl.foo }.to raise_error(RSpec::Mocks::MockExpectationError)
237
+ end
238
+ end
239
+
240
+ context "when used in a test framework without rspec-expectations" do
241
+ let(:framework) do
242
+ Class.new do
243
+ include RSpec::Mocks::ExampleMethods
244
+
245
+ def eq(value)
246
+ double("MyMatcher")
247
+ end
248
+ end
249
+ end
250
+
251
+ include_examples "using rspec-mocks in another test framework"
252
+
253
+ it 'cannot use `expect` with another matcher' do
254
+ expect {
255
+ framework.new.instance_eval do
256
+ expect(3).to eq(3)
257
+ end
258
+ }.to raise_error(/only the `receive` matcher is supported/)
259
+ end
260
+
261
+ it 'can toggle the available syntax' do
262
+ expect(framework.new).to respond_to(:expect)
263
+ RSpec::Mocks.configuration.syntax = :should
264
+ expect(framework.new).not_to respond_to(:expect)
265
+ RSpec::Mocks.configuration.syntax = :expect
266
+ expect(framework.new).to respond_to(:expect)
267
+ end
268
+
269
+ after { RSpec::Mocks.configuration.syntax = :expect }
270
+ end
271
+
272
+ context "when rspec-expectations is included in the test framework first" do
273
+ before do
274
+ # the examples here assume `expect` is define in RSpec::Matchers...
275
+ expect(RSpec::Matchers.method_defined?(:expect)).to be_true
276
+ end
277
+
278
+ let(:framework) do
279
+ Class.new do
280
+ include RSpec::Matchers
281
+ include RSpec::Mocks::ExampleMethods
282
+ end
283
+ end
284
+
285
+ include_examples "using rspec-mocks in another test framework"
286
+
287
+ it 'can use `expect` with any matcher' do
288
+ framework.new.instance_eval do
289
+ expect(3).to eq(3)
290
+ end
291
+ end
292
+ end
293
+
294
+ context "when rspec-expectations is included in the test framework last" do
295
+ before do
296
+ # the examples here assume `expect` is define in RSpec::Matchers...
297
+ expect(RSpec::Matchers.method_defined?(:expect)).to be_true
298
+ end
299
+
300
+ let(:framework) do
301
+ Class.new do
302
+ include RSpec::Mocks::ExampleMethods
303
+ include RSpec::Matchers
304
+ end
305
+ end
306
+
307
+ include_examples "using rspec-mocks in another test framework"
308
+
309
+ it 'can use `expect` with any matcher' do
310
+ framework.new.instance_eval do
311
+ expect(3).to eq(3)
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
318
+