rspec-mocks 2.99.4 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -19,7 +19,7 @@ module RSpec
|
|
19
19
|
chain.shift
|
20
20
|
matching_stub.invoke(nil).stub_chain(*chain, &block)
|
21
21
|
else
|
22
|
-
next_in_chain =
|
22
|
+
next_in_chain = Mock.new
|
23
23
|
object.stub(chain.shift) { next_in_chain }
|
24
24
|
StubChain.stub_chain_on(next_in_chain, *chain, &block)
|
25
25
|
end
|
@@ -35,7 +35,7 @@ module RSpec
|
|
35
35
|
hash = chain.pop
|
36
36
|
hash.each do |k,v|
|
37
37
|
chain << k
|
38
|
-
blk =
|
38
|
+
blk = lambda { v }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
return chain.join('.').split('.'), blk
|
data/lib/rspec/mocks/syntax.rb
CHANGED
@@ -5,75 +5,81 @@ module RSpec
|
|
5
5
|
# provided by rspec-mocks.
|
6
6
|
module Syntax
|
7
7
|
# @api private
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
def self.warn_about_should!
|
9
|
+
@warn_about_should = true
|
10
|
+
end
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
def self.warn_unless_should_configured(method_name)
|
14
|
+
if @warn_about_should
|
15
|
+
RSpec.deprecate(
|
16
|
+
"Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
|
17
|
+
:replacement => "the new `:expect` syntax or explicitly enable `:should`"
|
18
|
+
)
|
19
|
+
|
20
|
+
@warn_about_should = false
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
24
|
# @api private
|
24
25
|
# Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
|
25
26
|
def self.enable_should(syntax_host = default_should_syntax_host)
|
27
|
+
@warn_about_should = false
|
26
28
|
return if should_enabled?(syntax_host)
|
27
29
|
|
28
|
-
syntax_host.
|
30
|
+
syntax_host.class_exec do
|
29
31
|
def should_receive(message, opts={}, &block)
|
32
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
30
33
|
opts[:expected_from] ||= CallerFilter.first_non_rspec_line
|
31
|
-
::RSpec::Mocks.expect_message(self, message
|
34
|
+
::RSpec::Mocks.expect_message(self, message, opts, &block)
|
32
35
|
end
|
33
36
|
|
34
37
|
def should_not_receive(message, &block)
|
35
|
-
|
36
|
-
|
38
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
39
|
+
opts = {:expected_from => CallerFilter.first_non_rspec_line}
|
40
|
+
::RSpec::Mocks.expect_message(self, message, opts, &block).never
|
37
41
|
end
|
38
42
|
|
39
43
|
def stub(message_or_hash, opts={}, &block)
|
40
|
-
::RSpec::Mocks::Syntax.
|
44
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
45
|
+
if ::Hash === message_or_hash
|
46
|
+
message_or_hash.each {|message, value| stub(message).and_return value }
|
47
|
+
else
|
48
|
+
opts[:expected_from] = CallerFilter.first_non_rspec_line
|
49
|
+
::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block)
|
50
|
+
end
|
41
51
|
end
|
42
52
|
|
43
53
|
def unstub(message)
|
54
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
44
55
|
::RSpec::Mocks.space.proxy_for(self).remove_stub(message)
|
45
56
|
end
|
46
57
|
|
47
|
-
def stub!(message_or_hash, opts={}, &block)
|
48
|
-
::RSpec.deprecate "stub!", :replacement => "stub"
|
49
|
-
::RSpec::Mocks::Syntax.stub_object(self, message_or_hash, opts, &block)
|
50
|
-
end
|
51
|
-
|
52
|
-
def unstub!(message)
|
53
|
-
::RSpec.deprecate "unstub!", :replacement => "unstub"
|
54
|
-
unstub(message)
|
55
|
-
end
|
56
|
-
|
57
58
|
def stub_chain(*chain, &blk)
|
59
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
58
60
|
::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk)
|
59
61
|
end
|
60
62
|
|
61
63
|
def as_null_object
|
64
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
62
65
|
@_null_object = true
|
63
66
|
::RSpec::Mocks.proxy_for(self).as_null_object
|
64
67
|
end
|
65
68
|
|
66
69
|
def null_object?
|
70
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
67
71
|
defined?(@_null_object)
|
68
72
|
end
|
69
73
|
|
70
74
|
def received_message?(message, *args, &block)
|
75
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
71
76
|
::RSpec::Mocks.proxy_for(self).received_message?(message, *args, &block)
|
72
77
|
end
|
73
78
|
|
74
79
|
unless Class.respond_to? :any_instance
|
75
|
-
Class.
|
80
|
+
Class.class_exec do
|
76
81
|
def any_instance
|
82
|
+
::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
|
77
83
|
::RSpec::Mocks.any_instance_recorder_for(self)
|
78
84
|
end
|
79
85
|
end
|
@@ -86,20 +92,18 @@ module RSpec
|
|
86
92
|
def self.disable_should(syntax_host = default_should_syntax_host)
|
87
93
|
return unless should_enabled?(syntax_host)
|
88
94
|
|
89
|
-
syntax_host.
|
95
|
+
syntax_host.class_exec do
|
90
96
|
undef should_receive
|
91
97
|
undef should_not_receive
|
92
98
|
undef stub
|
93
99
|
undef unstub
|
94
|
-
undef stub!
|
95
|
-
undef unstub!
|
96
100
|
undef stub_chain
|
97
101
|
undef as_null_object
|
98
102
|
undef null_object?
|
99
103
|
undef received_message?
|
100
104
|
end
|
101
105
|
|
102
|
-
Class.
|
106
|
+
Class.class_exec do
|
103
107
|
undef any_instance
|
104
108
|
end
|
105
109
|
end
|
@@ -109,11 +113,17 @@ module RSpec
|
|
109
113
|
def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
|
110
114
|
return if expect_enabled?(syntax_host)
|
111
115
|
|
112
|
-
syntax_host.
|
116
|
+
syntax_host.class_exec do
|
113
117
|
def receive(method_name, &block)
|
114
118
|
Matchers::Receive.new(method_name, block)
|
115
119
|
end
|
116
120
|
|
121
|
+
def receive_messages(message_return_value_hash)
|
122
|
+
matcher = Matchers::ReceiveMessages.new(message_return_value_hash)
|
123
|
+
matcher.warn_about_block if block_given?
|
124
|
+
matcher
|
125
|
+
end
|
126
|
+
|
117
127
|
def allow(target)
|
118
128
|
AllowanceTarget.new(target)
|
119
129
|
end
|
@@ -127,7 +137,7 @@ module RSpec
|
|
127
137
|
end
|
128
138
|
end
|
129
139
|
|
130
|
-
RSpec::Mocks::ExampleMethods::ExpectHost.
|
140
|
+
RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do
|
131
141
|
def expect(target)
|
132
142
|
ExpectationTarget.new(target)
|
133
143
|
end
|
@@ -139,14 +149,15 @@ module RSpec
|
|
139
149
|
def self.disable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
|
140
150
|
return unless expect_enabled?(syntax_host)
|
141
151
|
|
142
|
-
syntax_host.
|
152
|
+
syntax_host.class_exec do
|
143
153
|
undef receive
|
154
|
+
undef receive_messages
|
144
155
|
undef allow
|
145
156
|
undef expect_any_instance_of
|
146
157
|
undef allow_any_instance_of
|
147
158
|
end
|
148
159
|
|
149
|
-
RSpec::Mocks::ExampleMethods::ExpectHost.
|
160
|
+
RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do
|
150
161
|
undef expect
|
151
162
|
end
|
152
163
|
end
|
@@ -343,6 +354,20 @@ module RSpec
|
|
343
354
|
# expect(obj).to receive(:hello).with("world").exactly(3).times
|
344
355
|
#
|
345
356
|
# @note This is only available when you have enabled the `expect` syntax.
|
357
|
+
#
|
358
|
+
# @method receive_messages
|
359
|
+
# Shorthand syntax used to setup message(s), and their return value(s),
|
360
|
+
# that you expect or allow an object to receive. The method takes a hash
|
361
|
+
# of messages and their respective return values. Unlike with `receive`,
|
362
|
+
# you cannot apply further customizations using a block or the fluent
|
363
|
+
# interface.
|
364
|
+
#
|
365
|
+
# @example
|
366
|
+
#
|
367
|
+
# allow(obj).to receive_messages(:speak => "Hello World")
|
368
|
+
# allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow")
|
369
|
+
#
|
370
|
+
# @note This is only available when you have enabled the `expect` syntax.
|
346
371
|
end
|
347
372
|
end
|
348
373
|
end
|
data/lib/rspec/mocks/targets.rb
CHANGED
@@ -8,30 +8,51 @@ module RSpec
|
|
8
8
|
@target = target
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.delegate_to(matcher_method
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
unless Matchers::Receive === matcher
|
16
|
-
raise UnsupportedMatcherError, "only the `receive` matcher is supported " +
|
17
|
-
"with `\#{expression}(...).\#{#{method_name.inspect}}`, but you have provided: \#{matcher}"
|
11
|
+
def self.delegate_to(matcher_method)
|
12
|
+
define_method(:to) do |matcher, &block|
|
13
|
+
unless Matchers::Receive === matcher || Matchers::ReceiveMessages === matcher
|
14
|
+
raise_unsupported_matcher(:to, matcher)
|
18
15
|
end
|
16
|
+
define_matcher(matcher, matcher_method, &block)
|
17
|
+
end
|
18
|
+
end
|
19
19
|
|
20
|
-
|
20
|
+
def self.delegate_not_to(matcher_method, options = {})
|
21
|
+
method_name = options.fetch(:from)
|
22
|
+
define_method(method_name) do |matcher, &block|
|
23
|
+
case matcher
|
24
|
+
when Matchers::Receive then define_matcher(matcher, matcher_method, &block)
|
25
|
+
when Matchers::ReceiveMessages then raise_negation_unsupported(method_name, matcher)
|
26
|
+
else
|
27
|
+
raise_unsupported_matcher(method_name, matcher)
|
28
|
+
end
|
21
29
|
end
|
22
|
-
RUBY
|
23
30
|
end
|
24
31
|
|
25
|
-
def self.disallow_negation(
|
26
|
-
define_method
|
27
|
-
|
28
|
-
"`#{expression}(...).#{method} receive` is not supported since it " +
|
29
|
-
"doesn't really make sense. What would it even mean?"
|
32
|
+
def self.disallow_negation(method_name)
|
33
|
+
define_method(method_name) do |matcher, *args|
|
34
|
+
raise_negation_unsupported(method_name, matcher)
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
33
38
|
private
|
34
39
|
|
40
|
+
def define_matcher(matcher, name, &block)
|
41
|
+
matcher.__send__(name, @target, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def raise_unsupported_matcher(method_name, matcher)
|
45
|
+
raise UnsupportedMatcherError,
|
46
|
+
"only the `receive` or `receive_messages` matchers are supported " +
|
47
|
+
"with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def raise_negation_unsupported(method_name, matcher)
|
51
|
+
raise NegationUnsupportedError,
|
52
|
+
"`#{expression}(...).#{method_name} #{matcher.name}` is not supported since it " +
|
53
|
+
"doesn't really make sense. What would it even mean?"
|
54
|
+
end
|
55
|
+
|
35
56
|
def expression
|
36
57
|
self.class::EXPRESSION
|
37
58
|
end
|
@@ -47,12 +68,12 @@ module RSpec
|
|
47
68
|
class ExpectationTarget < TargetBase
|
48
69
|
EXPRESSION = :expect
|
49
70
|
delegate_to :setup_expectation
|
50
|
-
|
51
|
-
|
71
|
+
delegate_not_to :setup_negative_expectation, :from => :not_to
|
72
|
+
delegate_not_to :setup_negative_expectation, :from => :to_not
|
52
73
|
end
|
53
74
|
|
54
75
|
class AnyInstanceAllowanceTarget < TargetBase
|
55
|
-
EXPRESSION = :
|
76
|
+
EXPRESSION = :allow_any_instance_of
|
56
77
|
delegate_to :setup_any_instance_allowance
|
57
78
|
disallow_negation :not_to
|
58
79
|
disallow_negation :to_not
|
@@ -61,8 +82,8 @@ module RSpec
|
|
61
82
|
class AnyInstanceExpectationTarget < TargetBase
|
62
83
|
EXPRESSION = :expect_any_instance_of
|
63
84
|
delegate_to :setup_any_instance_expectation
|
64
|
-
|
65
|
-
|
85
|
+
delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to
|
86
|
+
delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not
|
66
87
|
end
|
67
88
|
end
|
68
89
|
end
|
@@ -12,16 +12,15 @@ module RSpec
|
|
12
12
|
# module = Module.new
|
13
13
|
# RSpec::Mocks::TestDouble.extend_onto(module, "MyMixin", :foo => "bar")
|
14
14
|
# module.foo #=> "bar"
|
15
|
-
def self.extend_onto(object, name=nil,
|
16
|
-
RSpec.deprecate("`RSpec::Mocks::TestDouble.extend_onto(...)`")
|
15
|
+
def self.extend_onto(object, name=nil, stubs={})
|
17
16
|
object.extend self
|
18
|
-
object.send(:__initialize_as_test_double, name,
|
17
|
+
object.send(:__initialize_as_test_double, name, stubs)
|
19
18
|
end
|
20
19
|
|
21
20
|
# Creates a new test double with a `name` (that will be used in error
|
22
21
|
# messages only)
|
23
|
-
def initialize(name=nil,
|
24
|
-
__initialize_as_test_double(name,
|
22
|
+
def initialize(name=nil, stubs={})
|
23
|
+
__initialize_as_test_double(name, stubs)
|
25
24
|
end
|
26
25
|
|
27
26
|
# Tells the object to respond to all messages. If specific stub values
|
@@ -29,14 +28,11 @@ module RSpec
|
|
29
28
|
# returned.
|
30
29
|
def as_null_object
|
31
30
|
__mock_proxy.as_null_object
|
32
|
-
@__null_object = true
|
33
|
-
self
|
34
31
|
end
|
35
32
|
|
36
33
|
# Returns true if this object has received `as_null_object`
|
37
34
|
def null_object?
|
38
|
-
|
39
|
-
@__null_object
|
35
|
+
__mock_proxy.null_object?
|
40
36
|
end
|
41
37
|
|
42
38
|
# This allows for comparing the mock to other objects that proxy such as
|
@@ -64,37 +60,21 @@ module RSpec
|
|
64
60
|
__mock_proxy.null_object? ? true : super
|
65
61
|
end
|
66
62
|
|
67
|
-
def freeze
|
68
|
-
RSpec.deprecate 'Freezing a test double'
|
69
|
-
super
|
70
|
-
end
|
71
|
-
|
72
63
|
# @private
|
73
|
-
def __build_mock_proxy
|
74
|
-
|
75
|
-
__warn_of_expired_use_if_expired
|
76
|
-
proxy.as_null_object if @__null_object
|
77
|
-
proxy
|
78
|
-
end
|
79
|
-
|
80
|
-
def __warn_if_used_further!
|
81
|
-
@__unfrozen_attributes[:expired] = true
|
64
|
+
def __build_mock_proxy(order_group)
|
65
|
+
Proxy.new(self, order_group, @name)
|
82
66
|
end
|
83
67
|
|
84
68
|
private
|
85
69
|
|
86
|
-
def __initialize_as_test_double(name=nil,
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
if name.is_a?(Hash) && stubs_and_options.empty?
|
91
|
-
stubs_and_options = name
|
70
|
+
def __initialize_as_test_double(name=nil, stubs={})
|
71
|
+
if Hash === name && stubs.empty?
|
72
|
+
stubs = name
|
92
73
|
@name = nil
|
93
74
|
else
|
94
75
|
@name = name
|
95
76
|
end
|
96
|
-
|
97
|
-
assign_stubs(stubs_and_options)
|
77
|
+
assign_stubs(stubs)
|
98
78
|
end
|
99
79
|
|
100
80
|
def method_missing(message, *args, &block)
|
@@ -115,33 +95,9 @@ module RSpec
|
|
115
95
|
end
|
116
96
|
end
|
117
97
|
|
118
|
-
def extract_options(stubs_and_options)
|
119
|
-
if stubs_and_options[:null_object]
|
120
|
-
@null_object = stubs_and_options.delete(:null_object)
|
121
|
-
RSpec.deprecate("double('name', :null_object => true)", :replacement => "double('name').as_null_object")
|
122
|
-
end
|
123
|
-
options = {}
|
124
|
-
extract_option(stubs_and_options, options, :__declared_as, 'Mock')
|
125
|
-
options
|
126
|
-
end
|
127
|
-
|
128
|
-
def extract_option(source, target, key, default=nil)
|
129
|
-
if source[key]
|
130
|
-
target[key] = source.delete(key)
|
131
|
-
elsif default
|
132
|
-
target[key] = default
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
98
|
def assign_stubs(stubs)
|
137
99
|
stubs.each_pair do |message, response|
|
138
|
-
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def __warn_of_expired_use_if_expired
|
143
|
-
if @__unfrozen_attributes && @__unfrozen_attributes[:expired]
|
144
|
-
RSpec.deprecate "Continuing to use a test double after it has been reset (e.g. in a subsequent example)"
|
100
|
+
__mock_proxy.add_simple_stub(message, response)
|
145
101
|
end
|
146
102
|
end
|
147
103
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rspec/mocks/mock'
|
2
|
+
require 'rspec/mocks/verifying_proxy'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Mocks
|
6
|
+
|
7
|
+
module VerifyingDouble
|
8
|
+
def method_missing(message, *args, &block)
|
9
|
+
# Null object conditional is an optimization. If not a null object,
|
10
|
+
# validity of method expectations will have been checked at definition
|
11
|
+
# time.
|
12
|
+
__mock_proxy.ensure_implemented(message) if null_object?
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# A mock providing a custom proxy that can verify the validity of any
|
18
|
+
# method stubs or expectations against the public instance methods of the
|
19
|
+
# given class.
|
20
|
+
class InstanceVerifyingDouble
|
21
|
+
include TestDouble
|
22
|
+
include VerifyingDouble
|
23
|
+
|
24
|
+
def initialize(doubled_module, *args)
|
25
|
+
@doubled_module = doubled_module
|
26
|
+
|
27
|
+
__initialize_as_test_double(doubled_module, *args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def __build_mock_proxy(order_group)
|
31
|
+
VerifyingProxy.new(self, order_group,
|
32
|
+
@doubled_module,
|
33
|
+
InstanceMethodReference
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# An awkward module necessary because we cannot otherwise have
|
39
|
+
# ClassVerifyingDouble inherit from Module and still share these methods.
|
40
|
+
module ObjectVerifyingDoubleMethods
|
41
|
+
include TestDouble
|
42
|
+
include VerifyingDouble
|
43
|
+
|
44
|
+
def initialize(doubled_module, *args)
|
45
|
+
@doubled_module = doubled_module
|
46
|
+
|
47
|
+
__initialize_as_test_double(doubled_module, *args)
|
48
|
+
end
|
49
|
+
|
50
|
+
def __build_mock_proxy(order_group)
|
51
|
+
VerifyingProxy.new(self, order_group,
|
52
|
+
@doubled_module,
|
53
|
+
ObjectMethodReference
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def as_stubbed_const(options = {})
|
58
|
+
ConstantMutator.stub(@doubled_module.const_to_replace, self, options)
|
59
|
+
self
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Similar to an InstanceVerifyingDouble, except that it verifies against
|
64
|
+
# public methods of the given object.
|
65
|
+
class ObjectVerifyingDouble
|
66
|
+
include ObjectVerifyingDoubleMethods
|
67
|
+
end
|
68
|
+
|
69
|
+
# Effectively the same as an ObjectVerifyingDouble (since a class is a type
|
70
|
+
# of object), except with Module in the inheritance chain so that
|
71
|
+
# transferring nested constants to work.
|
72
|
+
class ClassVerifyingDouble < Module
|
73
|
+
include ObjectVerifyingDoubleMethods
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|