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
@@ -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
|