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
@@ -12,11 +12,16 @@ module RSpec
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def create_message_expectation_on(instance)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
proxy = ::RSpec::Mocks.proxy_for(instance)
|
16
|
+
expected_from = IGNORED_BACKTRACE_LINE
|
17
|
+
stub = proxy.add_stub(expected_from, *@expectation_args, &@expectation_block)
|
18
|
+
@recorder.stubs[stub.message] << stub
|
19
|
+
|
20
|
+
if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks?
|
21
|
+
stub.and_yield_receiver_to_implementation
|
19
22
|
end
|
23
|
+
|
24
|
+
stub
|
20
25
|
end
|
21
26
|
|
22
27
|
def invocation_order
|
@@ -23,6 +23,8 @@ module RSpec
|
|
23
23
|
# arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b'))
|
24
24
|
# arg_list_matcher.args_match?(123, :a => 'b')
|
25
25
|
#
|
26
|
+
# This class is immutable.
|
27
|
+
#
|
26
28
|
# @see ArgumentMatchers
|
27
29
|
class ArgumentListMatcher
|
28
30
|
# @private
|
@@ -69,7 +71,7 @@ module RSpec
|
|
69
71
|
|
70
72
|
def matcher_for(arg)
|
71
73
|
return ArgumentMatchers::MatcherMatcher.new(arg) if is_matcher?(arg)
|
72
|
-
return ArgumentMatchers::RegexpMatcher.new(arg) if arg
|
74
|
+
return ArgumentMatchers::RegexpMatcher.new(arg) if Regexp === arg
|
73
75
|
return ArgumentMatchers::EqualityProxy.new(arg)
|
74
76
|
end
|
75
77
|
|
@@ -92,6 +94,11 @@ module RSpec
|
|
92
94
|
def match_any_args?
|
93
95
|
@match_any_args
|
94
96
|
end
|
97
|
+
|
98
|
+
# Value that will match all argument lists.
|
99
|
+
#
|
100
|
+
# @private
|
101
|
+
MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher.new)
|
95
102
|
end
|
96
103
|
end
|
97
104
|
end
|
@@ -83,6 +83,20 @@ module RSpec
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
class ArrayIncludingMatcher
|
87
|
+
def initialize(expected)
|
88
|
+
@expected = expected
|
89
|
+
end
|
90
|
+
|
91
|
+
def ==(actual)
|
92
|
+
Set.new(actual).superset?(Set.new(@expected))
|
93
|
+
end
|
94
|
+
|
95
|
+
def description
|
96
|
+
"array_including(#{@expected.join(",")})"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
86
100
|
class DuckTypeMatcher
|
87
101
|
def initialize(*methods_to_respond_to)
|
88
102
|
@methods_to_respond_to = methods_to_respond_to
|
@@ -109,18 +123,6 @@ module RSpec
|
|
109
123
|
end
|
110
124
|
|
111
125
|
def ==(expected)
|
112
|
-
if defined?(DateTime) && DateTime === expected
|
113
|
-
RSpec.warn_deprecation <<-WARN.gsub(/^\s*\|/,'')
|
114
|
-
|In RSpec 3.0.0 matchers use `#===` (the match operator) to perform
|
115
|
-
|comparision between expected and actual arguments. Due to strange
|
116
|
-
|behaviour with `DateTime#===` (which ignores the time of the object
|
117
|
-
|when performing a comparison) this may result in undesired
|
118
|
-
|behaviour. We recommend you switch to a `Date` or `Time` object
|
119
|
-
|instead.
|
120
|
-
|
|
121
|
-
|Called from: #{RSpec::CallerFilter.first_non_rspec_line}
|
122
|
-
WARN
|
123
|
-
end
|
124
126
|
@given == expected
|
125
127
|
end
|
126
128
|
end
|
@@ -204,6 +206,18 @@ module RSpec
|
|
204
206
|
HashIncludingMatcher.new(anythingize_lonely_keys(*args))
|
205
207
|
end
|
206
208
|
|
209
|
+
# Matches an array that includes the specified items at least once.
|
210
|
+
# Ignores duplicates and additional values
|
211
|
+
#
|
212
|
+
# @example
|
213
|
+
#
|
214
|
+
# object.should_receive(:message).with(array_including(1,2,3))
|
215
|
+
# object.should_receive(:message).with(array_including([1,2,3]))
|
216
|
+
def array_including(*args)
|
217
|
+
actually_an_array = Array === args.first && args.count == 1 ? args.first : args
|
218
|
+
ArrayIncludingMatcher.new(actually_an_array)
|
219
|
+
end
|
220
|
+
|
207
221
|
# Matches a hash that doesn't include the specified key(s) or key/value.
|
208
222
|
#
|
209
223
|
# @example
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Mocks
|
3
|
+
|
4
|
+
# Figures out the valid arity range for a method. Surprisingly non-trivial.
|
5
|
+
class ArityCalculator
|
6
|
+
|
7
|
+
def initialize(method)
|
8
|
+
@method = method
|
9
|
+
end
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
def within_range?(actual)
|
13
|
+
min_arity <= actual && actual <= max_arity
|
14
|
+
end
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
def range_description
|
18
|
+
return min_arity.to_s if min_arity == max_arity
|
19
|
+
return "#{min_arity} or more" if max_arity == INFINITY
|
20
|
+
"#{min_arity} to #{max_arity}"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def method
|
26
|
+
@method
|
27
|
+
end
|
28
|
+
|
29
|
+
# @api private
|
30
|
+
def self.supports_optional_and_splat_args?
|
31
|
+
Method.method_defined?(:parameters)
|
32
|
+
end
|
33
|
+
|
34
|
+
def min_arity
|
35
|
+
return method.arity if method.arity >= 0
|
36
|
+
# `~` inverts the one's complement and gives us the number of
|
37
|
+
# required arguments.
|
38
|
+
~method.arity
|
39
|
+
end
|
40
|
+
|
41
|
+
if supports_optional_and_splat_args?
|
42
|
+
def max_arity
|
43
|
+
params = method.parameters
|
44
|
+
if params.any? {|(type, _)| type == :rest }
|
45
|
+
# Method takes a splat argument
|
46
|
+
return INFINITY
|
47
|
+
else
|
48
|
+
params.count {|(type, _)| type != :block }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
else
|
52
|
+
def max_arity
|
53
|
+
# On 1.8, Method#parameters does not exist. There is no way to
|
54
|
+
# distinguish between default and splat args, so there is no way to
|
55
|
+
# have it work correctly for both default and splat args, as far as I
|
56
|
+
# can tell. The best we can do is consider it INFINITY (to be
|
57
|
+
# tolerant of splat args).
|
58
|
+
method.arity < 0 ? INFINITY : method.arity
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
INFINITY = 1/0.0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -4,9 +4,10 @@ module RSpec
|
|
4
4
|
class Configuration
|
5
5
|
|
6
6
|
def initialize
|
7
|
-
@yield_receiver_to_any_instance_implementation_blocks =
|
8
|
-
@
|
9
|
-
@
|
7
|
+
@yield_receiver_to_any_instance_implementation_blocks = true
|
8
|
+
@verify_doubled_constant_names = false
|
9
|
+
@transfer_nested_constants = false
|
10
|
+
@verify_partial_doubles = false
|
10
11
|
end
|
11
12
|
|
12
13
|
def yield_receiver_to_any_instance_implementation_blocks?
|
@@ -14,14 +15,9 @@ module RSpec
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def yield_receiver_to_any_instance_implementation_blocks=(arg)
|
17
|
-
@should_warn_about_any_instance_blocks = false
|
18
18
|
@yield_receiver_to_any_instance_implementation_blocks = arg
|
19
19
|
end
|
20
20
|
|
21
|
-
def should_warn_about_any_instance_blocks?
|
22
|
-
@should_warn_about_any_instance_blocks
|
23
|
-
end
|
24
|
-
|
25
21
|
# Adds `stub` and `should_receive` to the given
|
26
22
|
# modules or classes. This is usually only necessary
|
27
23
|
# if you application uses some proxy classes that
|
@@ -64,12 +60,45 @@ module RSpec
|
|
64
60
|
syntaxes
|
65
61
|
end
|
66
62
|
|
67
|
-
def
|
68
|
-
|
63
|
+
def verify_doubled_constant_names?
|
64
|
+
!!@verify_doubled_constant_names
|
65
|
+
end
|
66
|
+
|
67
|
+
# When this is set to true, an error will be raised when
|
68
|
+
# `instance_double` or `class_double` is given the name of an undefined
|
69
|
+
# constant. You probably only want to set this when running your entire
|
70
|
+
# test suite, with all production code loaded. Setting this for an
|
71
|
+
# isolated unit test will prevent you from being able to isolate it!
|
72
|
+
def verify_doubled_constant_names=(val)
|
73
|
+
@verify_doubled_constant_names = val
|
69
74
|
end
|
70
75
|
|
71
|
-
def
|
72
|
-
|
76
|
+
def transfer_nested_constants?
|
77
|
+
!!@transfer_nested_constants
|
78
|
+
end
|
79
|
+
|
80
|
+
# Sets the default for the `transfer_nested_constants` option when
|
81
|
+
# stubbing constants.
|
82
|
+
def transfer_nested_constants=(val)
|
83
|
+
@transfer_nested_constants = val
|
84
|
+
end
|
85
|
+
|
86
|
+
# When set to true, partial mocks will be verified the same as object
|
87
|
+
# doubles. Any stubs will have their arity checked against the original
|
88
|
+
# method, and methods that do not exist cannot be stubbed.
|
89
|
+
def verify_partial_doubles=(val)
|
90
|
+
@verify_partial_doubles = !!val
|
91
|
+
end
|
92
|
+
|
93
|
+
def verify_partial_doubles?
|
94
|
+
@verify_partial_doubles
|
95
|
+
end
|
96
|
+
|
97
|
+
# @api private
|
98
|
+
# Resets the configured syntax to the default.
|
99
|
+
def reset_syntaxes_to_default
|
100
|
+
self.syntax = [:should, :expect]
|
101
|
+
RSpec::Mocks::Syntax.warn_about_should!
|
73
102
|
end
|
74
103
|
end
|
75
104
|
|
@@ -77,7 +106,6 @@ module RSpec
|
|
77
106
|
@configuration ||= Configuration.new
|
78
107
|
end
|
79
108
|
|
80
|
-
configuration.
|
109
|
+
configuration.reset_syntaxes_to_default
|
81
110
|
end
|
82
111
|
end
|
83
|
-
|
@@ -4,8 +4,7 @@ module RSpec
|
|
4
4
|
class ErrorGenerator
|
5
5
|
attr_writer :opts
|
6
6
|
|
7
|
-
def initialize(target, name
|
8
|
-
@declared_as = options[:__declared_as] || 'Mock'
|
7
|
+
def initialize(target, name)
|
9
8
|
@target = target
|
10
9
|
@name = name
|
11
10
|
end
|
@@ -48,6 +47,22 @@ module RSpec
|
|
48
47
|
__raise "(#{intro}).#{message}#{format_args(*args)}\n #{expected_part}\n #{received_part}"
|
49
48
|
end
|
50
49
|
|
50
|
+
# @private
|
51
|
+
def raise_unimplemented_error(doubled_module, method_name)
|
52
|
+
__raise "%s does not implement:\n %s" % [
|
53
|
+
doubled_module.description,
|
54
|
+
method_name
|
55
|
+
]
|
56
|
+
end
|
57
|
+
|
58
|
+
# @private
|
59
|
+
def raise_arity_error(calculator, actual)
|
60
|
+
__raise "Wrong number of arguments. Expected %s, got %s." % [
|
61
|
+
calculator.range_description,
|
62
|
+
actual
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
51
66
|
# @private
|
52
67
|
def received_part_of_expectation_error(actual_received_count, *args)
|
53
68
|
"received: #{count_message(actual_received_count)}" +
|
@@ -62,11 +77,14 @@ module RSpec
|
|
62
77
|
|
63
78
|
# @private
|
64
79
|
def method_call_args_description(args)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
80
|
+
case args.first
|
81
|
+
when ArgumentMatchers::AnyArgsMatcher
|
82
|
+
return " with any arguments"
|
83
|
+
when ArgumentMatchers::NoArgsMatcher
|
84
|
+
return " with no arguments"
|
85
|
+
end
|
86
|
+
|
87
|
+
if args.length > 0
|
70
88
|
" with arguments: #{args.inspect.gsub(/\A\[(.+)\]\z/, '(\1)')}"
|
71
89
|
else
|
72
90
|
""
|
@@ -127,9 +145,9 @@ module RSpec
|
|
127
145
|
|
128
146
|
def intro
|
129
147
|
if @name
|
130
|
-
"
|
148
|
+
"Double #{@name.inspect}"
|
131
149
|
elsif TestDouble === @target
|
132
|
-
|
150
|
+
"Double"
|
133
151
|
elsif Class === @target
|
134
152
|
"<#{@target.inspect} (class)>"
|
135
153
|
elsif @target
|
@@ -153,7 +171,13 @@ module RSpec
|
|
153
171
|
end
|
154
172
|
|
155
173
|
def arg_list(*args)
|
156
|
-
args.collect {|arg| arg
|
174
|
+
args.collect {|arg| arg_has_valid_description(arg) ? arg.description : arg.inspect }.join(", ")
|
175
|
+
end
|
176
|
+
|
177
|
+
def arg_has_valid_description(arg)
|
178
|
+
return false unless arg.respond_to?(:description)
|
179
|
+
|
180
|
+
!arg.description.nil? && !arg.description.empty?
|
157
181
|
end
|
158
182
|
|
159
183
|
def format_received_args(*args)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rspec/mocks/object_reference'
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module Mocks
|
3
5
|
module ExampleMethods
|
@@ -9,12 +11,12 @@ module RSpec
|
|
9
11
|
# @overload double(name, stubs)
|
10
12
|
# @param name [String/Symbol] (optional) used in
|
11
13
|
# clarify intent
|
12
|
-
# @param stubs (Hash) (optional) hash of
|
14
|
+
# @param stubs (Hash) (optional) hash of message/return-value pairs
|
13
15
|
# @return (Mock)
|
14
16
|
#
|
15
17
|
# Constructs an instance of [RSpec::Mocks::Mock](RSpec::Mocks::Mock) configured
|
16
18
|
# with an optional name, used for reporting in failure messages, and an optional
|
17
|
-
# hash of
|
19
|
+
# hash of message/return-value pairs.
|
18
20
|
#
|
19
21
|
# @example
|
20
22
|
#
|
@@ -25,22 +27,53 @@ module RSpec
|
|
25
27
|
# card.suit #=> "Spades"
|
26
28
|
# card.rank #=> "A"
|
27
29
|
#
|
28
|
-
# @see #mock
|
29
|
-
# @see #stub
|
30
30
|
def double(*args)
|
31
|
-
declare_double(
|
31
|
+
declare_double(Mock, *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @overload instance_double(doubled_class)
|
35
|
+
# @overload instance_double(doubled_class, stubs)
|
36
|
+
# @param doubled_class [String, Class]
|
37
|
+
# @param stubs [Hash] (optional) hash of message/return-value pairs
|
38
|
+
# @return InstanceVerifyingDouble
|
39
|
+
#
|
40
|
+
# Constructs a test double against a specific class. If the given class
|
41
|
+
# name has been loaded, only instance methods defined on the class are
|
42
|
+
# allowed to be stubbed. In all other ways it behaves like a
|
43
|
+
# [double](double).
|
44
|
+
def instance_double(doubled_class, *args)
|
45
|
+
ref = ObjectReference.for(doubled_class)
|
46
|
+
declare_verifying_double(InstanceVerifyingDouble, ref, *args)
|
32
47
|
end
|
33
48
|
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
49
|
+
# @overload class_double(doubled_class)
|
50
|
+
# @overload class_double(doubled_class, stubs)
|
51
|
+
# @param doubled_class [String, Module]
|
52
|
+
# @param stubs [Hash] (optional) hash of message/return-value pairs
|
53
|
+
# @return ClassVerifyingDouble
|
54
|
+
#
|
55
|
+
# Constructs a test double against a specific class. If the given class
|
56
|
+
# name has been loaded, only class methods defined on the class are
|
57
|
+
# allowed to be stubbed. In all other ways it behaves like a
|
58
|
+
# [double](double).
|
59
|
+
def class_double(doubled_class, *args)
|
60
|
+
ref = ObjectReference.for(doubled_class)
|
61
|
+
declare_verifying_double(ClassVerifyingDouble, ref, *args)
|
38
62
|
end
|
39
63
|
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
64
|
+
# @overload object_double(object_or_name)
|
65
|
+
# @overload object_double(object_or_name, stubs)
|
66
|
+
# @param object_or_name [String, Object]
|
67
|
+
# @param stubs [Hash] (optional) hash of message/return-value pairs
|
68
|
+
# @return ObjectVerifyingDouble
|
69
|
+
#
|
70
|
+
# Constructs a test double against a specific object. Only the methods
|
71
|
+
# the object responds to are allowed to be stubbed. If a String argument
|
72
|
+
# is provided, it is assumed to reference a constant object which is used
|
73
|
+
# for verification. In all other ways it behaves like a [double](double).
|
74
|
+
def object_double(object_or_name, *args)
|
75
|
+
ref = ObjectReference.for(object_or_name, :allow_direct_object_refs)
|
76
|
+
declare_verifying_double(ObjectVerifyingDouble, ref, *args)
|
44
77
|
end
|
45
78
|
|
46
79
|
# Disables warning messages about expectations being set on nil.
|
@@ -127,12 +160,12 @@ module RSpec
|
|
127
160
|
#
|
128
161
|
# # You can also use most message expectations:
|
129
162
|
# expect(invitation).to have_received(:accept).with(mailer).once
|
130
|
-
def have_received(method_name)
|
131
|
-
Matchers::HaveReceived.new(method_name)
|
163
|
+
def have_received(method_name, &block)
|
164
|
+
Matchers::HaveReceived.new(method_name, &block)
|
132
165
|
end
|
133
166
|
|
134
167
|
def self.included(klass)
|
135
|
-
klass.
|
168
|
+
klass.class_exec do
|
136
169
|
# This gets mixed in so that if `RSpec::Matchers` is included in
|
137
170
|
# `klass` later, it's definition of `expect` will take precedence.
|
138
171
|
include ExpectHost unless method_defined?(:expect)
|
@@ -141,10 +174,22 @@ module RSpec
|
|
141
174
|
|
142
175
|
private
|
143
176
|
|
144
|
-
def
|
177
|
+
def declare_verifying_double(type, ref, *args)
|
178
|
+
if RSpec::Mocks.configuration.verify_doubled_constant_names? &&
|
179
|
+
!ref.defined?
|
180
|
+
|
181
|
+
raise NameError,
|
182
|
+
"#{ref.name} is not a defined constant. " +
|
183
|
+
"Perhaps you misspelt it? " +
|
184
|
+
"Disable check with verify_doubled_constant_names configuration option."
|
185
|
+
end
|
186
|
+
|
187
|
+
declare_double(type, ref, *args)
|
188
|
+
end
|
189
|
+
|
190
|
+
def declare_double(type, *args)
|
145
191
|
args << {} unless Hash === args.last
|
146
|
-
args
|
147
|
-
RSpec::Mocks::Double.new(*args)
|
192
|
+
type.new(*args)
|
148
193
|
end
|
149
194
|
|
150
195
|
# This module exists to host the `expect` method for cases where
|