rspec-mocks 2.99.4 → 3.0.0.beta1

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 (133) hide show
  1. checksums.yaml +14 -6
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +1 -0
  4. data/Changelog.md +89 -105
  5. data/License.txt +1 -0
  6. data/README.md +77 -57
  7. data/features/argument_matchers/explicit.feature +5 -5
  8. data/features/argument_matchers/general_matchers.feature +10 -10
  9. data/features/argument_matchers/type_matchers.feature +3 -3
  10. data/features/message_expectations/allow_any_instance_of.feature +1 -1
  11. data/features/message_expectations/any_instance.feature +27 -5
  12. data/features/message_expectations/call_original.feature +2 -2
  13. data/features/message_expectations/expect_message_using_expect.feature +2 -2
  14. data/features/message_expectations/expect_message_using_should_receive.feature +2 -2
  15. data/features/message_expectations/receive_counts.feature +7 -7
  16. data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +3 -3
  17. data/features/method_stubs/README.md +3 -0
  18. data/features/method_stubs/any_instance.feature +11 -11
  19. data/features/method_stubs/as_null_object.feature +4 -4
  20. data/features/method_stubs/simple_return_value_with_stub.feature +7 -7
  21. data/features/method_stubs/stub_chain.feature +3 -3
  22. data/features/method_stubs/stub_implementation.feature +2 -2
  23. data/features/method_stubs/to_ary.feature +2 -2
  24. data/features/mutating_constants/hiding_defined_constant.feature +2 -2
  25. data/features/mutating_constants/stub_defined_constant.feature +5 -5
  26. data/features/mutating_constants/stub_undefined_constant.feature +6 -6
  27. data/features/outside_rspec/configuration.feature +0 -2
  28. data/features/outside_rspec/standalone.feature +1 -1
  29. data/features/spies/spy_partial_mock_method.feature +2 -2
  30. data/features/spies/spy_pure_mock_method.feature +5 -5
  31. data/features/spies/spy_unstubbed_method.feature +1 -1
  32. data/features/support/env.rb +10 -1
  33. data/features/test_frameworks/test_unit.feature +1 -1
  34. data/features/verifying_doubles/class_doubles.feature +88 -0
  35. data/features/verifying_doubles/dynamic_classes.feature +72 -0
  36. data/features/verifying_doubles/introduction.feature +85 -0
  37. data/features/verifying_doubles/object_doubles.feature +65 -0
  38. data/features/verifying_doubles/partial_doubles.feature +34 -0
  39. data/lib/rspec/mocks.rb +8 -34
  40. data/lib/rspec/mocks/any_instance/chain.rb +4 -34
  41. data/lib/rspec/mocks/any_instance/expectation_chain.rb +14 -4
  42. data/lib/rspec/mocks/any_instance/message_chains.rb +27 -12
  43. data/lib/rspec/mocks/any_instance/recorder.rb +23 -31
  44. data/lib/rspec/mocks/any_instance/stub_chain.rb +9 -4
  45. data/lib/rspec/mocks/argument_list_matcher.rb +8 -1
  46. data/lib/rspec/mocks/argument_matchers.rb +26 -12
  47. data/lib/rspec/mocks/arity_calculator.rb +66 -0
  48. data/lib/rspec/mocks/configuration.rb +42 -14
  49. data/lib/rspec/mocks/error_generator.rb +34 -10
  50. data/lib/rspec/mocks/example_methods.rb +64 -19
  51. data/lib/rspec/mocks/extensions/marshal.rb +0 -15
  52. data/lib/rspec/mocks/framework.rb +4 -4
  53. data/lib/rspec/mocks/instance_method_stasher.rb +80 -62
  54. data/lib/rspec/mocks/matchers/have_received.rb +18 -14
  55. data/lib/rspec/mocks/matchers/receive.rb +29 -7
  56. data/lib/rspec/mocks/matchers/receive_messages.rb +72 -0
  57. data/lib/rspec/mocks/message_expectation.rb +95 -148
  58. data/lib/rspec/mocks/method_double.rb +77 -139
  59. data/lib/rspec/mocks/method_reference.rb +95 -0
  60. data/lib/rspec/mocks/mock.rb +1 -1
  61. data/lib/rspec/mocks/mutate_const.rb +12 -9
  62. data/lib/rspec/mocks/object_reference.rb +90 -0
  63. data/lib/rspec/mocks/order_group.rb +49 -7
  64. data/lib/rspec/mocks/proxy.rb +72 -33
  65. data/lib/rspec/mocks/proxy_for_nil.rb +2 -2
  66. data/lib/rspec/mocks/space.rb +13 -18
  67. data/lib/rspec/mocks/stub_chain.rb +2 -2
  68. data/lib/rspec/mocks/syntax.rb +61 -36
  69. data/lib/rspec/mocks/targets.rb +40 -19
  70. data/lib/rspec/mocks/test_double.rb +12 -56
  71. data/lib/rspec/mocks/verifying_double.rb +77 -0
  72. data/lib/rspec/mocks/verifying_message_expecation.rb +60 -0
  73. data/lib/rspec/mocks/verifying_proxy.rb +151 -0
  74. data/lib/rspec/mocks/version.rb +1 -1
  75. data/spec/rspec/mocks/and_call_original_spec.rb +34 -30
  76. data/spec/rspec/mocks/and_yield_spec.rb +2 -2
  77. data/spec/rspec/mocks/any_instance/message_chains_spec.rb +1 -1
  78. data/spec/rspec/mocks/any_instance_spec.rb +53 -260
  79. data/spec/rspec/mocks/argument_expectation_spec.rb +4 -4
  80. data/spec/rspec/mocks/arity_calculator_spec.rb +95 -0
  81. data/spec/rspec/mocks/array_including_matcher_spec.rb +41 -0
  82. data/spec/rspec/mocks/at_least_spec.rb +4 -32
  83. data/spec/rspec/mocks/block_return_value_spec.rb +4 -135
  84. data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +10 -11
  85. data/spec/rspec/mocks/configuration_spec.rb +79 -0
  86. data/spec/rspec/mocks/double_spec.rb +10 -78
  87. data/spec/rspec/mocks/extensions/marshal_spec.rb +0 -8
  88. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +49 -4
  89. data/spec/rspec/mocks/instance_method_stasher_spec.rb +20 -3
  90. data/spec/rspec/mocks/matchers/have_received_spec.rb +74 -0
  91. data/spec/rspec/mocks/matchers/receive_messages_spec.rb +140 -0
  92. data/spec/rspec/mocks/matchers/receive_spec.rb +82 -42
  93. data/spec/rspec/mocks/methods_spec.rb +1 -1
  94. data/spec/rspec/mocks/{bug_report_830_spec.rb → mock_expectation_error_spec.rb} +4 -3
  95. data/spec/rspec/mocks/mock_ordering_spec.rb +11 -0
  96. data/spec/rspec/mocks/mock_space_spec.rb +10 -1
  97. data/spec/rspec/mocks/mock_spec.rb +26 -82
  98. data/spec/rspec/mocks/multiple_return_value_spec.rb +1 -1
  99. data/spec/rspec/mocks/mutate_const_spec.rb +18 -5
  100. data/spec/rspec/mocks/null_object_mock_spec.rb +6 -4
  101. data/spec/rspec/mocks/options_hash_spec.rb +3 -3
  102. data/spec/rspec/mocks/order_group_spec.rb +27 -0
  103. data/spec/rspec/mocks/partial_mock_spec.rb +101 -1
  104. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +3 -20
  105. data/spec/rspec/mocks/record_messages_spec.rb +4 -4
  106. data/spec/rspec/mocks/serialization_spec.rb +4 -6
  107. data/spec/rspec/mocks/space_spec.rb +3 -3
  108. data/spec/rspec/mocks/stub_chain_spec.rb +0 -12
  109. data/spec/rspec/mocks/stub_spec.rb +23 -44
  110. data/spec/rspec/mocks/test_double_spec.rb +3 -22
  111. data/spec/rspec/mocks/verifying_double_spec.rb +327 -0
  112. data/spec/rspec/mocks/verifying_message_expecation_spec.rb +68 -0
  113. data/spec/rspec/mocks_spec.rb +16 -39
  114. data/spec/spec_helper.rb +29 -18
  115. metadata +131 -86
  116. metadata.gz.sig +1 -0
  117. data/features/message_expectations/expect_any_instance_of.feature +0 -27
  118. data/lib/rspec/mocks/caller_filter.rb +0 -60
  119. data/lib/rspec/mocks/deprecation.rb +0 -26
  120. data/lib/rspec/mocks/extensions/instance_exec.rb +0 -34
  121. data/lib/rspec/mocks/extensions/proc.rb +0 -63
  122. data/lib/spec/mocks.rb +0 -4
  123. data/spec/rspec/mocks/and_return_spec.rb +0 -17
  124. data/spec/rspec/mocks/any_number_of_times_spec.rb +0 -36
  125. data/spec/rspec/mocks/before_all_spec.rb +0 -74
  126. data/spec/rspec/mocks/bug_report_10260_spec.rb +0 -8
  127. data/spec/rspec/mocks/bug_report_10263_spec.rb +0 -27
  128. data/spec/rspec/mocks/bug_report_11545_spec.rb +0 -32
  129. data/spec/rspec/mocks/bug_report_496_spec.rb +0 -17
  130. data/spec/rspec/mocks/bug_report_600_spec.rb +0 -22
  131. data/spec/rspec/mocks/bug_report_7611_spec.rb +0 -16
  132. data/spec/rspec/mocks/bug_report_8165_spec.rb +0 -31
  133. data/spec/rspec/mocks/bug_report_957_spec.rb +0 -22
@@ -104,7 +104,7 @@ module RSpec
104
104
 
105
105
  describe "a message expectation with multiple return values with a specified count larger than the number of values" do
106
106
  before(:each) do
107
- @double = RSpec::Mocks::Double.new("double")
107
+ @double = RSpec::Mocks::Mock.new("double")
108
108
  @double.should_receive(:do_something).exactly(3).times.and_return(11, 22)
109
109
  end
110
110
 
@@ -32,11 +32,6 @@ module RSpec
32
32
  ::RSpec::Mocks.space.reset_all
33
33
  end
34
34
 
35
- specify "the use of ConstantStubber is deprecated" do
36
- expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
37
- expect(RSpec::Mocks::ConstantStubber).to eq RSpec::Mocks::ConstantMutator
38
- end
39
-
40
35
  shared_context "constant example methods" do |const_name|
41
36
  define_method :const do
42
37
  recursive_const_get(const_name)
@@ -316,6 +311,24 @@ module RSpec
316
311
 
317
312
  expect(TestClass).to be(original_tc)
318
313
  end
314
+
315
+ describe 'with global transfer_nested_constant option set' do
316
+ include_context "with isolated configuration"
317
+
318
+ before do
319
+ RSpec::Mocks.configuration.transfer_nested_constants = true
320
+ end
321
+
322
+ it 'allows nested constants to be transferred to a stub module' do
323
+ tc_nested = TestClass::Nested
324
+ stub = Module.new
325
+ stub_const("TestClass", stub)
326
+ expect(stub::M).to eq(:m)
327
+ expect(stub::N).to eq(:n)
328
+ expect(stub::Nested).to be(tc_nested)
329
+ end
330
+ end
331
+
319
332
  end
320
333
 
321
334
  context 'for a loaded nested constant' do
@@ -89,11 +89,13 @@ module RSpec
89
89
  expect(("%i" % @double)).to eq("0")
90
90
  end
91
91
 
92
- it "preserves its nullness to subsequent examples to " +
93
- "maintain compatibility with <= 2.13" do
92
+ it "does not allow null-ness to persist between examples" do
94
93
  RSpec::Mocks.teardown
95
- RSpec::Mocks.setup
96
- allow(RSpec).to receive(:deprecate)
94
+
95
+ expect(@double).not_to be_null_object
96
+ expect { @double.some.long.message.chain }.to raise_error(RSpec::Mocks::MockExpectationError)
97
+
98
+ @double.as_null_object
97
99
  expect(@double).to be_null_object
98
100
  expect { @double.some.long.message.chain }.not_to raise_error
99
101
  end
@@ -5,7 +5,7 @@ module RSpec
5
5
  describe "calling :should_receive with an options hash" do
6
6
  it "reports the file and line submitted with :expected_from" do
7
7
  begin
8
- mock = RSpec::Mocks::Double.new("a mock")
8
+ mock = RSpec::Mocks::Mock.new("a mock")
9
9
  mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37")
10
10
  verify mock
11
11
  rescue Exception => e
@@ -16,7 +16,7 @@ module RSpec
16
16
 
17
17
  it "uses the message supplied with :message" do
18
18
  expect {
19
- m = RSpec::Mocks::Double.new("a mock")
19
+ m = RSpec::Mocks::Mock.new("a mock")
20
20
  m.should_receive(:message, :message => "recebi nada")
21
21
  verify m
22
22
  }.to raise_error("recebi nada")
@@ -24,7 +24,7 @@ module RSpec
24
24
 
25
25
  it "uses the message supplied with :message after a similar stub" do
26
26
  expect {
27
- m = RSpec::Mocks::Double.new("a mock")
27
+ m = RSpec::Mocks::Mock.new("a mock")
28
28
  m.stub(:message)
29
29
  m.should_receive(:message, :message => "from mock")
30
30
  verify m
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ describe 'OrderGroup' do
3
+ let(:order_group) { ::RSpec::Mocks::OrderGroup.new }
4
+
5
+ describe '#consume' do
6
+ let(:ordered_1) { double :ordered? => true }
7
+ let(:ordered_2) { double :ordered? => true }
8
+ let(:unordered) { double :ordered? => false }
9
+
10
+ before do
11
+ order_group.register unordered
12
+ order_group.register ordered_1
13
+ order_group.register unordered
14
+ order_group.register ordered_2
15
+ order_group.register unordered
16
+ order_group.register unordered
17
+ end
18
+
19
+ it 'returns the first ordered? expectation' do
20
+ expect(order_group.consume).to eq ordered_1
21
+ end
22
+ it 'keeps returning ordered? expectation until all are returned' do
23
+ expectations = 3.times.map { order_group.consume }
24
+ expect(expectations).to eq [ordered_1, ordered_2, nil]
25
+ end
26
+ end
27
+ end
@@ -20,7 +20,7 @@ module RSpec
20
20
  end
21
21
 
22
22
  it "does not conflict with @options in the object" do
23
- object.instance_eval { @options = Object.new }
23
+ object.instance_exec { @options = Object.new }
24
24
  object.should_receive(:blah)
25
25
  object.blah
26
26
  end
@@ -166,6 +166,35 @@ module RSpec
166
166
  end
167
167
  end
168
168
 
169
+ describe "A partial class mock that has been subclassed" do
170
+
171
+ let(:klass) { Class.new }
172
+ let(:subklass) { Class.new(klass) }
173
+
174
+ it "cleans up stubs during #reset to prevent leakage onto subclasses between examples" do
175
+ allow(klass).to receive(:new).and_return(:new_foo)
176
+ expect(subklass.new).to eq :new_foo
177
+
178
+ reset(klass)
179
+
180
+ expect(subklass.new).to be_a(subklass)
181
+ end
182
+
183
+ describe "stubbing a base class class method" do
184
+ before do
185
+ klass.stub(:find).and_return "stubbed_value"
186
+ end
187
+
188
+ it "returns the value for the stub on the base class" do
189
+ expect(klass.find).to eq "stubbed_value"
190
+ end
191
+
192
+ it "returns the value for the descendent class" do
193
+ expect(subklass.find).to eq "stubbed_value"
194
+ end
195
+ end
196
+ end
197
+
169
198
  describe "Method visibility when using partial mocks" do
170
199
  let(:klass) do
171
200
  Class.new do
@@ -201,5 +230,76 @@ module RSpec
201
230
  end
202
231
 
203
232
  end
233
+
234
+ describe 'when verify_partial_doubles configuration option is set' do
235
+ include_context "with isolated configuration"
236
+
237
+ let(:klass) do
238
+ Class.new do
239
+ def implemented
240
+ "works"
241
+ end
242
+
243
+ def respond_to?(method_name, include_all=false)
244
+ method_name.to_s == "dynamic_method" || super
245
+ end
246
+
247
+ def method_missing(method_name, *args)
248
+ if respond_to?(method_name)
249
+ method_name
250
+ else
251
+ super
252
+ end
253
+ end
254
+ end
255
+ end
256
+
257
+ let(:object) { klass.new }
258
+
259
+ before do
260
+ RSpec::Mocks.configuration.verify_partial_doubles = true
261
+ end
262
+
263
+ it 'allows valid methods to be expected' do
264
+ expect(object).to receive(:implemented).and_call_original
265
+ expect(object.implemented).to eq("works")
266
+ end
267
+
268
+ it 'does not allow a non-existing method to be expected' do
269
+ prevents { expect(object).to receive(:unimplemented) }
270
+ end
271
+
272
+ it 'verifies arity range when matching arguments' do
273
+ prevents { expect(object).to receive(:implemented).with('bogus') }
274
+ end
275
+
276
+ it 'allows a method defined with method_missing to be expected' do
277
+ expect(object).to receive(:dynamic_method).with('a').and_call_original
278
+ expect(object.dynamic_method('a')).to eq(:dynamic_method)
279
+ end
280
+
281
+ it 'allows valid methods to be expected on any_instance' do
282
+ expect_any_instance_of(klass).to receive(:implemented)
283
+ object.implemented
284
+ end
285
+
286
+ it 'does not allow a non-existing method to be called on any_instance' do
287
+ prevents { expect_any_instance_of(klass).to receive(:unimplemented) }
288
+ end
289
+
290
+ it 'does not allow missing methods to be called on any_instance' do
291
+ # This is potentially surprising behaviour, but there is no way for us
292
+ # to know that this method is valid since we only have class and not an
293
+ # instance.
294
+ prevents { expect_any_instance_of(klass).to receive(:dynamic_method) }
295
+ end
296
+
297
+ it 'verifies arity range when receiving a message' do
298
+ allow(object).to receive(:implemented)
299
+ expect {
300
+ object.implemented('bogus')
301
+ }.to raise_error(ArgumentError, /wrong number of arguments \(1 for 0\)/)
302
+ end
303
+ end
204
304
  end
205
305
  end
@@ -82,27 +82,10 @@ module RSpec
82
82
  @double.should_receive(:random_call).with(hash_including(:a => 1))
83
83
  @double.random_call(:a => 1)
84
84
  end
85
- end
86
85
 
87
- context "handling block matchers" do
88
- before { allow_deprecation }
89
-
90
- it "matches arguments against RSpec expectations" do
91
- @double.should_receive(:random_call).with {|arg1, arg2, arr, *rest|
92
- expect(arg1).to eq 5
93
- expect(arg2.length).to be >= 3
94
- expect(arg2.length).to be <= 10
95
- expect(arr.map {|i| i * 2}).to eq [2,4,6]
96
- expect(rest).to eq [:fee, "fi", 4]
97
- }
98
- @double.random_call 5, "hello", [1,2,3], :fee, "fi", 4
99
- end
100
-
101
- it "does not eval the block as the return value" do
102
- eval_count = 0
103
- @double.should_receive(:msg).with {|a| eval_count += 1}
104
- @double.msg(:ignore)
105
- expect(eval_count).to eq(1)
86
+ it "matches array with array_including same array" do
87
+ @double.should_receive(:random_call).with(array_including(1,2))
88
+ @double.random_call([1,2])
106
89
  end
107
90
  end
108
91
 
@@ -7,19 +7,19 @@ module RSpec
7
7
  @mock = double("mock").as_null_object
8
8
  end
9
9
  it "answers false for received_message? when no messages received" do
10
- expect(@mock.received_message?(:message)).to be false
10
+ expect(@mock.received_message?(:message)).to be_falsey
11
11
  end
12
12
  it "answers true for received_message? when message received" do
13
13
  @mock.message
14
- expect(@mock.received_message?(:message)).to be true
14
+ expect(@mock.received_message?(:message)).to be_truthy
15
15
  end
16
16
  it "answers true for received_message? when message received with correct args" do
17
17
  @mock.message 1,2,3
18
- expect(@mock.received_message?(:message, 1,2,3)).to be true
18
+ expect(@mock.received_message?(:message, 1,2,3)).to be_truthy
19
19
  end
20
20
  it "answers false for received_message? when message received with incorrect args" do
21
21
  @mock.message 1,2,3
22
- expect(@mock.received_message?(:message, 1,2)).to be false
22
+ expect(@mock.received_message?(:message, 1,2)).to be_falsey
23
23
  end
24
24
  end
25
25
  end
@@ -3,13 +3,12 @@ require 'spec_helper'
3
3
  module RSpec
4
4
  module Mocks
5
5
  describe "Serialization of mocked objects" do
6
- include_context 'with isolated configuration'
7
6
 
8
7
  class SerializableObject < Struct.new(:foo, :bar); end
9
8
 
10
9
  def self.with_yaml_loaded(&block)
11
10
  context 'with YAML loaded' do
12
- module_eval(&block)
11
+ module_exec(&block)
13
12
  end
14
13
  end
15
14
 
@@ -18,16 +17,16 @@ module RSpec
18
17
  before do
19
18
  # We can't really unload yaml, but we can fake it here...
20
19
  hide_const("YAML")
21
- Struct.class_eval do
20
+ Struct.class_exec do
22
21
  alias __old_to_yaml to_yaml
23
22
  undef to_yaml
24
23
  end
25
24
  end
26
25
 
27
- module_eval(&block)
26
+ module_exec(&block)
28
27
 
29
28
  after do
30
- Struct.class_eval do
29
+ Struct.class_exec do
31
30
  alias to_yaml __old_to_yaml
32
31
  undef __old_to_yaml
33
32
  end
@@ -83,7 +82,6 @@ module RSpec
83
82
  end
84
83
 
85
84
  it 'marshals the same with and without stubbing' do
86
- RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = true
87
85
  expect { set_stub }.to_not change { Marshal.dump(serializable_object) }
88
86
  end
89
87
  end
@@ -5,11 +5,10 @@ module RSpec::Mocks
5
5
 
6
6
  describe "#proxies_of(klass)" do
7
7
  let(:space) { Space.new }
8
- before { space.outside_example = false }
9
8
 
10
9
  it 'returns proxies' do
11
10
  space.proxy_for("")
12
- expect(space.proxies_of(String).map(&:class)).to eq([Proxy])
11
+ expect(space.proxies_of(String).map(&:class)).to eq([PartialMockProxy])
13
12
  end
14
13
 
15
14
  it 'returns only the proxies whose object is an instance of the given class' do
@@ -21,7 +20,8 @@ module RSpec::Mocks
21
20
  parent = parent_class.new
22
21
  child = child_class.new
23
22
 
24
- _ = space.proxy_for(grandparent)
23
+ space.proxy_for(grandparent)
24
+
25
25
  parent_proxy = space.proxy_for(parent)
26
26
  child_proxy = space.proxy_for(child)
27
27
 
@@ -37,18 +37,6 @@ module RSpec
37
37
  end
38
38
 
39
39
  context "with two methods in chain" do
40
- it "accepts any number of arguments to the stubbed messages" do
41
- object.stub_chain(:msg1, :msg2).and_return(:return_value)
42
-
43
- expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
44
- end
45
-
46
- it "accepts any number of arguments to the stubbed messages with a return value from a hash" do
47
- object.stub_chain(:msg1, :msg2 => :return_value)
48
-
49
- expect(object.msg1("nonsense", :value).msg2("another", :nonsense, 3.0, "value")).to eq(:return_value)
50
- end
51
-
52
40
  context "using and_return" do
53
41
  it "returns expected value from chaining two method calls" do
54
42
  object.stub_chain(:msg1, :msg2).and_return(:return_value)
@@ -37,45 +37,6 @@ module RSpec
37
37
  end
38
38
  end
39
39
 
40
- describe "using stub!" do
41
- before do
42
- allow(RSpec).to receive(:deprecate)
43
- end
44
-
45
- it "warns of deprecation" do
46
- expect(RSpec).to receive(:deprecate).with("stub!", :replacement => "stub")
47
- @instance.stub!(:msg).and_return(:return_value)
48
- end
49
-
50
- it "returns the declared value when the message is received" do
51
- @instance.stub!(:msg).and_return(:return_value)
52
- expect(@instance.msg).to equal(:return_value)
53
- verify @instance
54
- end
55
-
56
- it "can be used to stub the example context itself (since `stub` returns a test dobule instead)" do
57
- stub!(:foo).and_return(5)
58
- expect(foo).to eq(5)
59
- end
60
- end
61
-
62
- describe 'using unstub' do
63
- it 'removes the message stub' do
64
- @instance.stub(:msg)
65
- @instance.unstub(:msg)
66
- expect { @instance.msg }.to raise_error NoMethodError
67
- end
68
- end
69
-
70
- describe 'using unstub!' do
71
- it 'removes the message stub but warns about deprecation' do
72
- @instance.stub(:msg)
73
- RSpec.should_receive(:deprecate).with("unstub!", :replacement => "unstub")
74
- @instance.unstub!(:msg)
75
- expect { @instance.msg }.to raise_error NoMethodError
76
- end
77
- end
78
-
79
40
  it "instructs an instance to respond_to the message" do
80
41
  @instance.stub(:msg)
81
42
  expect(@instance).to respond_to(:msg)
@@ -123,28 +84,47 @@ module RSpec
123
84
  end
124
85
 
125
86
  it "restores existing instance methods" do
126
- # See bug reports 8302 adn 7805
87
+ # See bug reports 8302 and 7805
127
88
  @instance.stub(:existing_instance_method) { :stub_value }
128
89
  reset @instance
129
90
  expect(@instance.existing_instance_method).to eq(:original_value)
130
91
  end
131
92
 
93
+ it "restores existing singleton methods with the appropriate context" do
94
+ klass = Class.new do
95
+ def self.say_hello
96
+ @hello if defined?(@hello)
97
+ end
98
+ end
99
+
100
+ subclass = Class.new(klass)
101
+
102
+ subclass.instance_variable_set(:@hello, "Hello")
103
+ expect(subclass.say_hello).to eq("Hello")
104
+
105
+ klass.stub(:say_hello) { "Howdy" }
106
+ expect(subclass.say_hello).to eq("Howdy")
107
+
108
+ reset klass
109
+ expect(subclass.say_hello).to eq("Hello")
110
+ end
111
+
132
112
  it "restores existing private instance methods" do
133
- # See bug reports 8302 adn 7805
113
+ # See bug reports 8302 and 7805
134
114
  @instance.stub(:existing_private_instance_method) { :stub_value }
135
115
  reset @instance
136
116
  expect(@instance.send(:existing_private_instance_method)).to eq(:original_value)
137
117
  end
138
118
 
139
119
  it "restores existing class methods" do
140
- # See bug reports 8302 adn 7805
120
+ # See bug reports 8302 and 7805
141
121
  @class.stub(:existing_class_method) { :stub_value }
142
122
  reset @class
143
123
  expect(@class.existing_class_method).to eq(:original_value)
144
124
  end
145
125
 
146
126
  it "restores existing private class methods" do
147
- # See bug reports 8302 adn 7805
127
+ # See bug reports 8302 and 7805
148
128
  @class.stub(:existing_private_class_method) { :stub_value }
149
129
  reset @class
150
130
  expect(@class.send(:existing_private_class_method)).to eq(:original_value)
@@ -285,7 +265,6 @@ module RSpec
285
265
  end
286
266
 
287
267
  it "calculates return value by executing block passed to #and_return" do
288
- allow_deprecation
289
268
  @stub.stub(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
290
269
  expect(@stub.something("a","b","c")).to eq "cba"
291
270
  verify @stub