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.
- checksums.yaml +14 -6
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +1 -0
- data/Changelog.md +89 -105
- data/License.txt +1 -0
- data/README.md +77 -57
- data/features/argument_matchers/explicit.feature +5 -5
- data/features/argument_matchers/general_matchers.feature +10 -10
- data/features/argument_matchers/type_matchers.feature +3 -3
- data/features/message_expectations/allow_any_instance_of.feature +1 -1
- data/features/message_expectations/any_instance.feature +27 -5
- data/features/message_expectations/call_original.feature +2 -2
- data/features/message_expectations/expect_message_using_expect.feature +2 -2
- data/features/message_expectations/expect_message_using_should_receive.feature +2 -2
- data/features/message_expectations/receive_counts.feature +7 -7
- data/features/message_expectations/warn_when_expectation_is_set_on_nil.feature +3 -3
- data/features/method_stubs/README.md +3 -0
- data/features/method_stubs/any_instance.feature +11 -11
- data/features/method_stubs/as_null_object.feature +4 -4
- data/features/method_stubs/simple_return_value_with_stub.feature +7 -7
- data/features/method_stubs/stub_chain.feature +3 -3
- data/features/method_stubs/stub_implementation.feature +2 -2
- data/features/method_stubs/to_ary.feature +2 -2
- data/features/mutating_constants/hiding_defined_constant.feature +2 -2
- data/features/mutating_constants/stub_defined_constant.feature +5 -5
- data/features/mutating_constants/stub_undefined_constant.feature +6 -6
- data/features/outside_rspec/configuration.feature +0 -2
- data/features/outside_rspec/standalone.feature +1 -1
- data/features/spies/spy_partial_mock_method.feature +2 -2
- data/features/spies/spy_pure_mock_method.feature +5 -5
- data/features/spies/spy_unstubbed_method.feature +1 -1
- data/features/support/env.rb +10 -1
- data/features/test_frameworks/test_unit.feature +1 -1
- data/features/verifying_doubles/class_doubles.feature +88 -0
- data/features/verifying_doubles/dynamic_classes.feature +72 -0
- data/features/verifying_doubles/introduction.feature +85 -0
- data/features/verifying_doubles/object_doubles.feature +65 -0
- data/features/verifying_doubles/partial_doubles.feature +34 -0
- data/lib/rspec/mocks.rb +8 -34
- data/lib/rspec/mocks/any_instance/chain.rb +4 -34
- data/lib/rspec/mocks/any_instance/expectation_chain.rb +14 -4
- data/lib/rspec/mocks/any_instance/message_chains.rb +27 -12
- data/lib/rspec/mocks/any_instance/recorder.rb +23 -31
- data/lib/rspec/mocks/any_instance/stub_chain.rb +9 -4
- data/lib/rspec/mocks/argument_list_matcher.rb +8 -1
- data/lib/rspec/mocks/argument_matchers.rb +26 -12
- data/lib/rspec/mocks/arity_calculator.rb +66 -0
- data/lib/rspec/mocks/configuration.rb +42 -14
- data/lib/rspec/mocks/error_generator.rb +34 -10
- data/lib/rspec/mocks/example_methods.rb +64 -19
- data/lib/rspec/mocks/extensions/marshal.rb +0 -15
- data/lib/rspec/mocks/framework.rb +4 -4
- data/lib/rspec/mocks/instance_method_stasher.rb +80 -62
- data/lib/rspec/mocks/matchers/have_received.rb +18 -14
- data/lib/rspec/mocks/matchers/receive.rb +29 -7
- data/lib/rspec/mocks/matchers/receive_messages.rb +72 -0
- data/lib/rspec/mocks/message_expectation.rb +95 -148
- data/lib/rspec/mocks/method_double.rb +77 -139
- data/lib/rspec/mocks/method_reference.rb +95 -0
- data/lib/rspec/mocks/mock.rb +1 -1
- data/lib/rspec/mocks/mutate_const.rb +12 -9
- data/lib/rspec/mocks/object_reference.rb +90 -0
- data/lib/rspec/mocks/order_group.rb +49 -7
- data/lib/rspec/mocks/proxy.rb +72 -33
- data/lib/rspec/mocks/proxy_for_nil.rb +2 -2
- data/lib/rspec/mocks/space.rb +13 -18
- data/lib/rspec/mocks/stub_chain.rb +2 -2
- data/lib/rspec/mocks/syntax.rb +61 -36
- data/lib/rspec/mocks/targets.rb +40 -19
- data/lib/rspec/mocks/test_double.rb +12 -56
- data/lib/rspec/mocks/verifying_double.rb +77 -0
- data/lib/rspec/mocks/verifying_message_expecation.rb +60 -0
- data/lib/rspec/mocks/verifying_proxy.rb +151 -0
- data/lib/rspec/mocks/version.rb +1 -1
- data/spec/rspec/mocks/and_call_original_spec.rb +34 -30
- data/spec/rspec/mocks/and_yield_spec.rb +2 -2
- data/spec/rspec/mocks/any_instance/message_chains_spec.rb +1 -1
- data/spec/rspec/mocks/any_instance_spec.rb +53 -260
- data/spec/rspec/mocks/argument_expectation_spec.rb +4 -4
- data/spec/rspec/mocks/arity_calculator_spec.rb +95 -0
- data/spec/rspec/mocks/array_including_matcher_spec.rb +41 -0
- data/spec/rspec/mocks/at_least_spec.rb +4 -32
- data/spec/rspec/mocks/block_return_value_spec.rb +4 -135
- data/spec/rspec/mocks/combining_implementation_instructions_spec.rb +10 -11
- data/spec/rspec/mocks/configuration_spec.rb +79 -0
- data/spec/rspec/mocks/double_spec.rb +10 -78
- data/spec/rspec/mocks/extensions/marshal_spec.rb +0 -8
- data/spec/rspec/mocks/failing_argument_matchers_spec.rb +49 -4
- data/spec/rspec/mocks/instance_method_stasher_spec.rb +20 -3
- data/spec/rspec/mocks/matchers/have_received_spec.rb +74 -0
- data/spec/rspec/mocks/matchers/receive_messages_spec.rb +140 -0
- data/spec/rspec/mocks/matchers/receive_spec.rb +82 -42
- data/spec/rspec/mocks/methods_spec.rb +1 -1
- data/spec/rspec/mocks/{bug_report_830_spec.rb → mock_expectation_error_spec.rb} +4 -3
- data/spec/rspec/mocks/mock_ordering_spec.rb +11 -0
- data/spec/rspec/mocks/mock_space_spec.rb +10 -1
- data/spec/rspec/mocks/mock_spec.rb +26 -82
- data/spec/rspec/mocks/multiple_return_value_spec.rb +1 -1
- data/spec/rspec/mocks/mutate_const_spec.rb +18 -5
- data/spec/rspec/mocks/null_object_mock_spec.rb +6 -4
- data/spec/rspec/mocks/options_hash_spec.rb +3 -3
- data/spec/rspec/mocks/order_group_spec.rb +27 -0
- data/spec/rspec/mocks/partial_mock_spec.rb +101 -1
- data/spec/rspec/mocks/passing_argument_matchers_spec.rb +3 -20
- data/spec/rspec/mocks/record_messages_spec.rb +4 -4
- data/spec/rspec/mocks/serialization_spec.rb +4 -6
- data/spec/rspec/mocks/space_spec.rb +3 -3
- data/spec/rspec/mocks/stub_chain_spec.rb +0 -12
- data/spec/rspec/mocks/stub_spec.rb +23 -44
- data/spec/rspec/mocks/test_double_spec.rb +3 -22
- data/spec/rspec/mocks/verifying_double_spec.rb +327 -0
- data/spec/rspec/mocks/verifying_message_expecation_spec.rb +68 -0
- data/spec/rspec/mocks_spec.rb +16 -39
- data/spec/spec_helper.rb +29 -18
- metadata +131 -86
- metadata.gz.sig +1 -0
- data/features/message_expectations/expect_any_instance_of.feature +0 -27
- data/lib/rspec/mocks/caller_filter.rb +0 -60
- data/lib/rspec/mocks/deprecation.rb +0 -26
- data/lib/rspec/mocks/extensions/instance_exec.rb +0 -34
- data/lib/rspec/mocks/extensions/proc.rb +0 -63
- data/lib/spec/mocks.rb +0 -4
- data/spec/rspec/mocks/and_return_spec.rb +0 -17
- data/spec/rspec/mocks/any_number_of_times_spec.rb +0 -36
- data/spec/rspec/mocks/before_all_spec.rb +0 -74
- data/spec/rspec/mocks/bug_report_10260_spec.rb +0 -8
- data/spec/rspec/mocks/bug_report_10263_spec.rb +0 -27
- data/spec/rspec/mocks/bug_report_11545_spec.rb +0 -32
- data/spec/rspec/mocks/bug_report_496_spec.rb +0 -17
- data/spec/rspec/mocks/bug_report_600_spec.rb +0 -22
- data/spec/rspec/mocks/bug_report_7611_spec.rb +0 -16
- data/spec/rspec/mocks/bug_report_8165_spec.rb +0 -31
- data/spec/rspec/mocks/bug_report_957_spec.rb +0 -22
@@ -85,6 +85,11 @@ module RSpec
|
|
85
85
|
expect(configured_syntax).to eq([:should])
|
86
86
|
end
|
87
87
|
|
88
|
+
it "does not warn about the should syntax" do
|
89
|
+
RSpec.should_not_receive(:deprecate)
|
90
|
+
Object.new.should_not_receive(:bees)
|
91
|
+
end
|
92
|
+
|
88
93
|
it 'is a no-op when configured a second time' do
|
89
94
|
Syntax.default_should_syntax_host.should_not_receive(:method_added)
|
90
95
|
::RSpec::Mocks::ExampleMethods.should_not_receive(:method_undefined)
|
@@ -110,6 +115,68 @@ module RSpec
|
|
110
115
|
it 'reports that both syntaxes are enabled' do
|
111
116
|
expect(configured_syntax).to eq([:should, :expect])
|
112
117
|
end
|
118
|
+
|
119
|
+
it "does not warn about the should syntax" do
|
120
|
+
RSpec.should_not_receive(:deprecate)
|
121
|
+
Object.new.should_not_receive(:bees)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "by default" do
|
126
|
+
before do
|
127
|
+
configure_default_syntax
|
128
|
+
end
|
129
|
+
|
130
|
+
let(:expected_arguments) {
|
131
|
+
[
|
132
|
+
/Using.*without explicitly enabling/,
|
133
|
+
{:replacement=>"the new `:expect` syntax or explicitly enable `:should`"}
|
134
|
+
]
|
135
|
+
}
|
136
|
+
|
137
|
+
it "it warns about should once, regardless of how many times it is called" do
|
138
|
+
expect(RSpec).to receive(:deprecate).with(*expected_arguments)
|
139
|
+
o = Object.new
|
140
|
+
o2 = Object.new
|
141
|
+
o.should_receive(:bees)
|
142
|
+
o2.should_receive(:bees)
|
143
|
+
|
144
|
+
o.bees
|
145
|
+
o2.bees
|
146
|
+
end
|
147
|
+
|
148
|
+
it "warns about should not once, regardless of how many times it is called" do
|
149
|
+
expect(RSpec).to receive(:deprecate).with(*expected_arguments)
|
150
|
+
o = Object.new
|
151
|
+
o2 = Object.new
|
152
|
+
o.should_not_receive(:bees)
|
153
|
+
o2.should_not_receive(:bees)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "warns about stubbing once, regardless of how many times it is called" do
|
157
|
+
expect(RSpec).to receive(:deprecate).with(*expected_arguments)
|
158
|
+
o = Object.new
|
159
|
+
o2 = Object.new
|
160
|
+
|
161
|
+
o.stub(:faces)
|
162
|
+
o2.stub(:faces)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "doesn't warn about stubbing after a reset and setting should" do
|
166
|
+
expect(RSpec).not_to receive(:deprecate)
|
167
|
+
RSpec::Mocks.configuration.reset_syntaxes_to_default
|
168
|
+
RSpec::Mocks.configuration.syntax = :should
|
169
|
+
o = Object.new
|
170
|
+
o2 = Object.new
|
171
|
+
o.stub(:faces)
|
172
|
+
o2.stub(:faces)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "includes the call site in the deprecation warning" do
|
176
|
+
obj = Object.new
|
177
|
+
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
178
|
+
obj.stub(:faces)
|
179
|
+
end
|
113
180
|
end
|
114
181
|
end
|
115
182
|
|
@@ -122,6 +189,10 @@ module RSpec
|
|
122
189
|
def configured_syntax
|
123
190
|
RSpec::Mocks.configuration.syntax
|
124
191
|
end
|
192
|
+
|
193
|
+
def configure_default_syntax
|
194
|
+
RSpec::Mocks.configuration.reset_syntaxes_to_default
|
195
|
+
end
|
125
196
|
end
|
126
197
|
end
|
127
198
|
|
@@ -142,6 +213,14 @@ module RSpec
|
|
142
213
|
end
|
143
214
|
end
|
144
215
|
end
|
216
|
+
|
217
|
+
def configure_default_syntax
|
218
|
+
RSpec.configure do |rspec|
|
219
|
+
rspec.mock_with :rspec do |c|
|
220
|
+
c.reset_syntaxes_to_default
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
145
224
|
end
|
146
225
|
end
|
147
226
|
end
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe "double" do
|
4
4
|
it "is an alias for stub and mock" do
|
5
|
-
expect(double()).to be_a(RSpec::Mocks::
|
5
|
+
expect(double()).to be_a(RSpec::Mocks::Mock)
|
6
6
|
end
|
7
7
|
|
8
8
|
it "uses 'Double' in failure messages" do
|
@@ -10,16 +10,16 @@ describe "double" do
|
|
10
10
|
expect {double.foo}.to raise_error(/Double "name" received/)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
13
|
+
it "hides internals in its inspect representation" do
|
14
|
+
m = double('cup')
|
15
|
+
expect(m.inspect).to match(/#<RSpec::Mocks::Mock:0x[a-f0-9.]+ @name="cup">/)
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
it 'restores standard object methods on reset' do
|
19
|
+
dbl = double(:tainted? => true)
|
20
|
+
expect(dbl.tainted?).to eq(true)
|
21
|
+
reset dbl
|
22
|
+
expect(dbl.tainted?).to eq(false)
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'does not get string vs symbol messages confused' do
|
@@ -28,72 +28,4 @@ describe "double" do
|
|
28
28
|
expect(dbl.foo).to eq(2)
|
29
29
|
expect { reset dbl }.not_to raise_error
|
30
30
|
end
|
31
|
-
|
32
|
-
context "after it has been torn down" do
|
33
|
-
let(:dbl) { double }
|
34
|
-
|
35
|
-
before do
|
36
|
-
expect(dbl).to receive(:foo).at_least(:once)
|
37
|
-
allow(dbl).to receive(:bar)
|
38
|
-
dbl.foo
|
39
|
-
|
40
|
-
RSpec::Mocks.verify
|
41
|
-
RSpec::Mocks.teardown
|
42
|
-
RSpec::Mocks.setup
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'warns when stubbing new methods (with receive)' do
|
46
|
-
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
47
|
-
allow(dbl).to receive(:bazz).and_return(3)
|
48
|
-
expect(dbl.bazz).to eq(3)
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'warns when mocking new methods' do
|
52
|
-
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
53
|
-
expect(dbl).to receive(:bazz)
|
54
|
-
dbl.bazz
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'warns when turned into a null object' do
|
58
|
-
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
59
|
-
dbl.as_null_object
|
60
|
-
dbl.foo.bar.bazz.goo
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'warns when checked for nullness' do
|
64
|
-
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
65
|
-
dbl.null_object?
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
context 'when frozen' do
|
70
|
-
it 'warns of deprecation' do
|
71
|
-
expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
|
72
|
-
double.freeze
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'is really frozen' do
|
76
|
-
expect(double.freeze).to be_frozen
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'when it has turned into a null object and been frozen' do
|
81
|
-
before do
|
82
|
-
double.as_null_object.freeze
|
83
|
-
end
|
84
|
-
|
85
|
-
context 'on tearing down' do
|
86
|
-
it 'does not raise error' do
|
87
|
-
expect { RSpec::Mocks.verify }.not_to raise_error
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'when being deserialized from YAML' do
|
93
|
-
let(:yaml) { YAML.dump(double) }
|
94
|
-
|
95
|
-
it 'does not raise error' do
|
96
|
-
expect { YAML.load(yaml) }.not_to raise_error
|
97
|
-
end
|
98
|
-
end
|
99
31
|
end
|
@@ -31,21 +31,13 @@ describe Marshal, 'extensions' do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
context 'when rspec-mocks has been fully initialized' do
|
34
|
-
include_context 'with isolated configuration'
|
35
|
-
|
36
34
|
it 'duplicates objects with stubbed or mocked implementations before serialization' do
|
37
|
-
RSpec::Mocks.configuration.patch_marshal_to_support_partial_doubles = true
|
38
35
|
obj = double(:foo => "bar")
|
39
36
|
|
40
37
|
serialized = Marshal.dump(obj)
|
41
38
|
expect(Marshal.load(serialized)).to be_an(obj.class)
|
42
39
|
end
|
43
40
|
|
44
|
-
it 'provides a deprecation warning' do
|
45
|
-
expect_warn_deprecation_with_call_site('marshal_spec.rb', __LINE__ + 1)
|
46
|
-
Marshal.dump double(:foo => "bar")
|
47
|
-
end
|
48
|
-
|
49
41
|
it 'does not duplicate other objects before serialization' do
|
50
42
|
obj = UndupableObject.new
|
51
43
|
|
@@ -83,12 +83,24 @@ module RSpec
|
|
83
83
|
end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (hash_including(:a=>1))\n got: ({})")
|
84
84
|
end
|
85
85
|
|
86
|
-
it "fails
|
87
|
-
|
86
|
+
it "fails array_including when args aren't array" do
|
87
|
+
expect do
|
88
|
+
@double.should_receive(:msg).with(array_including(1,2,3))
|
89
|
+
@double.msg(1,2,3)
|
90
|
+
end.to raise_error(/array_including\(1,2,3\)/)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "fails array_including when arg doesn't contain all elements" do
|
94
|
+
expect do
|
95
|
+
@double.should_receive(:msg).with(array_including(1,2,3))
|
96
|
+
@double.msg(1,2)
|
97
|
+
end.to raise_error(/array_including\(1,2,3\)/)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "fails with zero arguments" do
|
88
101
|
expect do
|
89
102
|
@double.should_receive(:msg).with {|arg| expect(arg).to eq :received }
|
90
|
-
|
91
|
-
end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /expected: :received.*\s*.*got: :no_msg_for_you/)
|
103
|
+
end.to raise_error(ArgumentError, /must have at least one argument/)
|
92
104
|
end
|
93
105
|
|
94
106
|
it "fails with sensible message when args respond to #description" do
|
@@ -106,6 +118,39 @@ module RSpec
|
|
106
118
|
@double.msg arg
|
107
119
|
end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (3)\n got: (my_thing)")
|
108
120
|
end
|
121
|
+
|
122
|
+
it "fails with sensible message when arg#description is nil" do
|
123
|
+
arg = Class.new do
|
124
|
+
def description
|
125
|
+
end
|
126
|
+
|
127
|
+
def inspect
|
128
|
+
"my_thing"
|
129
|
+
end
|
130
|
+
end.new
|
131
|
+
|
132
|
+
expect do
|
133
|
+
@double.should_receive(:msg).with(arg)
|
134
|
+
@double.msg 3
|
135
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (my_thing)\n got: (3)")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "fails with sensible message when arg#description is blank" do
|
139
|
+
arg = Class.new do
|
140
|
+
def description
|
141
|
+
""
|
142
|
+
end
|
143
|
+
|
144
|
+
def inspect
|
145
|
+
"my_thing"
|
146
|
+
end
|
147
|
+
end.new
|
148
|
+
|
149
|
+
expect do
|
150
|
+
@double.should_receive(:msg).with(arg)
|
151
|
+
@double.msg 3
|
152
|
+
end.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"double\" received :msg with unexpected arguments\n expected: (my_thing)\n got: (3)")
|
153
|
+
end
|
109
154
|
end
|
110
155
|
end
|
111
156
|
end
|
@@ -13,11 +13,15 @@ module RSpec
|
|
13
13
|
class << obj; self; end
|
14
14
|
end
|
15
15
|
|
16
|
+
def stasher_for(obj, method_name)
|
17
|
+
InstanceMethodStasher.new(obj, method_name)
|
18
|
+
end
|
19
|
+
|
16
20
|
it "stashes the current implementation of an instance method so it can be temporarily replaced" do
|
17
21
|
obj = Object.new
|
18
22
|
def obj.hello; :hello_defined_on_singleton_class; end;
|
19
23
|
|
20
|
-
stashed_method =
|
24
|
+
stashed_method = stasher_for(obj, :hello)
|
21
25
|
stashed_method.stash
|
22
26
|
|
23
27
|
def obj.hello; :overridden_hello; end
|
@@ -32,7 +36,7 @@ module RSpec
|
|
32
36
|
def obj.hello; :hello_defined_on_singleton_class; end;
|
33
37
|
singleton_class_for(obj).__send__(:private, :hello)
|
34
38
|
|
35
|
-
stashed_method =
|
39
|
+
stashed_method = stasher_for(obj, :hello)
|
36
40
|
stashed_method.stash
|
37
41
|
|
38
42
|
def obj.hello; :overridden_hello; end
|
@@ -43,7 +47,7 @@ module RSpec
|
|
43
47
|
it "only stashes methods directly defined on the given class, not its ancestors" do
|
44
48
|
obj = ExampleClass.new
|
45
49
|
|
46
|
-
stashed_method =
|
50
|
+
stashed_method = stasher_for(obj, :hello)
|
47
51
|
stashed_method.stash
|
48
52
|
|
49
53
|
def obj.hello; :overridden_hello; end;
|
@@ -52,6 +56,19 @@ module RSpec
|
|
52
56
|
stashed_method.restore
|
53
57
|
expect(obj.hello).to eql :overridden_hello
|
54
58
|
end
|
59
|
+
|
60
|
+
it "does not unnecessarily create obfuscated aliased methods", :if => (RUBY_VERSION.to_f > 1.8) do
|
61
|
+
obj = Object.new
|
62
|
+
def obj.hello; :hello_defined_on_singleton_class; end;
|
63
|
+
|
64
|
+
stashed_method = stasher_for(obj, :hello)
|
65
|
+
|
66
|
+
expect {
|
67
|
+
stashed_method.stash
|
68
|
+
}.not_to change { obj.methods.count }
|
69
|
+
|
70
|
+
expect(obj.methods.grep(/rspec/)).to eq([])
|
71
|
+
end
|
55
72
|
end
|
56
73
|
end
|
57
74
|
end
|
@@ -48,6 +48,58 @@ module RSpec
|
|
48
48
|
}.to raise_error(/method has been mocked instead of stubbed/)
|
49
49
|
end
|
50
50
|
|
51
|
+
it "takes a curly-bracket block and yields the arguments given to the stubbed method call" do
|
52
|
+
dbl = double(:foo => nil)
|
53
|
+
yielded = []
|
54
|
+
dbl.foo(:a, :b, :c)
|
55
|
+
expect(dbl).to have_received(:foo) { |*args|
|
56
|
+
yielded << args
|
57
|
+
}
|
58
|
+
expect(yielded).to include([:a,:b,:c])
|
59
|
+
end
|
60
|
+
|
61
|
+
it "takes a do-end block and yields the arguments given to the stubbed method call" do
|
62
|
+
dbl = double(:foo => nil)
|
63
|
+
yielded = []
|
64
|
+
dbl.foo(:a, :b, :c)
|
65
|
+
expect(dbl).to have_received(:foo) do |*args|
|
66
|
+
yielded << args
|
67
|
+
end
|
68
|
+
expect(yielded).to include([:a,:b,:c])
|
69
|
+
end
|
70
|
+
|
71
|
+
it "passes if expectations against the yielded arguments pass" do
|
72
|
+
dbl = double(:foo => nil)
|
73
|
+
dbl.foo(42)
|
74
|
+
expect {
|
75
|
+
expect(dbl).to have_received(:foo) { |arg|
|
76
|
+
expect(arg).to eq(42)
|
77
|
+
}
|
78
|
+
}.to_not raise_error
|
79
|
+
end
|
80
|
+
|
81
|
+
it "fails if expectations against the yielded arguments fail" do
|
82
|
+
dbl = double(:foo => nil)
|
83
|
+
dbl.foo(43)
|
84
|
+
expect {
|
85
|
+
expect(dbl).to have_received(:foo) { |arg|
|
86
|
+
expect(arg).to eq(42)
|
87
|
+
}
|
88
|
+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'gives precedence to a `{ ... }` block when both forms are provided ' +
|
92
|
+
'since that form actually binds to `receive`' do
|
93
|
+
dbl = double(:foo => nil)
|
94
|
+
called = []
|
95
|
+
dbl.foo
|
96
|
+
expect(dbl).to have_received(:foo) { called << :curly } do
|
97
|
+
called << :do_end
|
98
|
+
end
|
99
|
+
expect(called).to include(:curly)
|
100
|
+
expect(called).not_to include(:do_end)
|
101
|
+
end
|
102
|
+
|
51
103
|
it 'resets expectations on class methods when mocks are reset' do
|
52
104
|
dbl = Object
|
53
105
|
dbl.stub(:expected_method)
|
@@ -195,6 +247,28 @@ module RSpec
|
|
195
247
|
end
|
196
248
|
end
|
197
249
|
end
|
250
|
+
|
251
|
+
context 'ordered' do
|
252
|
+
let(:dbl) { double :one => 1, :two => 2 }
|
253
|
+
|
254
|
+
it 'passes when the messages were received in order' do
|
255
|
+
dbl.one
|
256
|
+
dbl.two
|
257
|
+
|
258
|
+
expect(dbl).to have_received(:one).ordered
|
259
|
+
expect(dbl).to have_received(:two).ordered
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'fails when the messages are received out of order' do
|
263
|
+
dbl.two
|
264
|
+
dbl.one
|
265
|
+
|
266
|
+
expect {
|
267
|
+
expect(dbl).to have_received(:one).ordered
|
268
|
+
expect(dbl).to have_received(:two).ordered
|
269
|
+
}.to raise_error(/received :two out of order/m)
|
270
|
+
end
|
271
|
+
end
|
198
272
|
end
|
199
273
|
|
200
274
|
describe "expect(...).not_to have_received" do
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Mocks
|
5
|
+
shared_examples_for "complains when given blocks" do
|
6
|
+
it "complains if a { } block is given" do
|
7
|
+
expect {
|
8
|
+
target.to receive_messages(:a => 1) { "implementation" }
|
9
|
+
}.to raise_error "Implementation blocks aren't supported with `receive_messages`"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "complains if a do; end; block is given" do
|
13
|
+
expect {
|
14
|
+
target.to receive_messages(:a => 1) do
|
15
|
+
"implementation"
|
16
|
+
end
|
17
|
+
}.to raise_error "Implementation blocks aren't supported with `receive_messages`"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
shared_examples_for "handles partially mocked objects correctly" do
|
22
|
+
let(:obj) { Struct.new(:a).new('original') }
|
23
|
+
|
24
|
+
it "resets partially mocked objects correctly" do
|
25
|
+
target.to receive_messages(:a => 1, :b => 2)
|
26
|
+
|
27
|
+
expect {
|
28
|
+
reset obj
|
29
|
+
}.to change { obj.a }.from(1).to("original")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "allow(...).to receive_messages(:a => 1, :b => 2)" do
|
34
|
+
let(:obj) { double "Object" }
|
35
|
+
let(:target) { allow(obj) }
|
36
|
+
|
37
|
+
it "allows the object to respond to multiple messages" do
|
38
|
+
allow(obj).to receive_messages(:a => 1, :b => 2)
|
39
|
+
expect(obj.a).to eq 1
|
40
|
+
expect(obj.b).to eq 2
|
41
|
+
end
|
42
|
+
|
43
|
+
it_behaves_like "complains when given blocks"
|
44
|
+
it_behaves_like "handles partially mocked objects correctly"
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "allow_any_instance_of(...).to receive_messages(:a => 1, :b => 2)" do
|
48
|
+
let(:obj) { Object.new }
|
49
|
+
let(:target) { allow_any_instance_of(Object) }
|
50
|
+
|
51
|
+
it "allows the object to respond to multiple messages" do
|
52
|
+
allow_any_instance_of(Object).to receive_messages(:a => 1, :b => 2)
|
53
|
+
expect(obj.a).to eq 1
|
54
|
+
expect(obj.b).to eq 2
|
55
|
+
end
|
56
|
+
|
57
|
+
it_behaves_like "complains when given blocks"
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "expect(...).to receive_messages(:a => 1, :b => 2)" do
|
61
|
+
let(:obj) { double "Object" }
|
62
|
+
let(:target) { expect(obj) }
|
63
|
+
|
64
|
+
let(:expectation_error) do
|
65
|
+
failure = nil
|
66
|
+
begin
|
67
|
+
RSpec::Mocks.space.verify_all
|
68
|
+
rescue RSpec::Mocks::MockExpectationError => error
|
69
|
+
failure = error
|
70
|
+
end
|
71
|
+
failure
|
72
|
+
end
|
73
|
+
|
74
|
+
it "sets up multiple expectations" do
|
75
|
+
expect(obj).to receive_messages(:a => 1, :b => 2)
|
76
|
+
obj.a
|
77
|
+
expect { RSpec::Mocks.space.verify_all }.to raise_error RSpec::Mocks::MockExpectationError
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'fails with a sensible message' do
|
81
|
+
expect(obj).to receive_messages(:a => 1, :b => 2)
|
82
|
+
obj.b
|
83
|
+
expect(expectation_error.to_s).to eq %Q{(Double "Object").a(no args)\n expected: 1 time with any arguments\n received: 0 times}
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'fails with the correct location' do
|
87
|
+
expect(obj).to receive_messages(:a => 1, :b => 2); line = __LINE__
|
88
|
+
expect(expectation_error.backtrace[0]).to match(/#{__FILE__}:#{line}/)
|
89
|
+
end
|
90
|
+
|
91
|
+
it_behaves_like "complains when given blocks"
|
92
|
+
it_behaves_like "handles partially mocked objects correctly"
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "expect_any_instance_of(...).to receive_messages(:a => 1, :b => 2)" do
|
96
|
+
let(:obj) { Object.new }
|
97
|
+
let(:target) { expect_any_instance_of(Object) }
|
98
|
+
|
99
|
+
it "sets up multiple expectations" do
|
100
|
+
expect_any_instance_of(Object).to receive_messages(:a => 1, :b => 2)
|
101
|
+
obj.a
|
102
|
+
expect { RSpec::Mocks.space.verify_all }.to raise_error RSpec::Mocks::MockExpectationError
|
103
|
+
end
|
104
|
+
|
105
|
+
it_behaves_like "complains when given blocks"
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "negative expectation failure" do
|
109
|
+
let(:obj) { Object.new }
|
110
|
+
|
111
|
+
example "allow(...).to_not receive_messages(:a => 1, :b => 2)" do
|
112
|
+
expect { allow(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
|
113
|
+
raise_error "`allow(...).to_not receive_messages` is not supported "+
|
114
|
+
"since it doesn't really make sense. What would it even mean?"
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
example "allow_any_instance_of(...).to_not receive_messages(:a => 1, :b => 2)" do
|
119
|
+
expect { allow_any_instance_of(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
|
120
|
+
raise_error "`allow_any_instance_of(...).to_not receive_messages` is not supported "+
|
121
|
+
"since it doesn't really make sense. What would it even mean?"
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
example "expect(...).to_not receive_messages(:a => 1, :b => 2)" do
|
126
|
+
expect { expect(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
|
127
|
+
raise_error "`expect(...).to_not receive_messages` is not supported "+
|
128
|
+
"since it doesn't really make sense. What would it even mean?"
|
129
|
+
)
|
130
|
+
end
|
131
|
+
|
132
|
+
example "expect_any_instance_of(...).to_not receive_messages(:a => 1, :b => 2)" do
|
133
|
+
expect { expect_any_instance_of(obj).to_not receive_messages(:a => 1, :b => 2) }.to(
|
134
|
+
raise_error "`expect_any_instance_of(...).to_not receive_messages` is not supported "+
|
135
|
+
"since it doesn't really make sense. What would it even mean?"
|
136
|
+
)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|