rspec-mocks-diag 3.8.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.yardopts +6 -0
  4. data/Changelog.md +1108 -0
  5. data/LICENSE.md +25 -0
  6. data/README.md +460 -0
  7. data/lib/rspec/mocks.rb +130 -0
  8. data/lib/rspec/mocks/any_instance.rb +11 -0
  9. data/lib/rspec/mocks/any_instance/chain.rb +110 -0
  10. data/lib/rspec/mocks/any_instance/error_generator.rb +31 -0
  11. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +31 -0
  12. data/lib/rspec/mocks/any_instance/expectation_chain.rb +50 -0
  13. data/lib/rspec/mocks/any_instance/message_chains.rb +83 -0
  14. data/lib/rspec/mocks/any_instance/proxy.rb +116 -0
  15. data/lib/rspec/mocks/any_instance/recorder.rb +289 -0
  16. data/lib/rspec/mocks/any_instance/stub_chain.rb +51 -0
  17. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +23 -0
  18. data/lib/rspec/mocks/argument_list_matcher.rb +100 -0
  19. data/lib/rspec/mocks/argument_matchers.rb +320 -0
  20. data/lib/rspec/mocks/configuration.rb +212 -0
  21. data/lib/rspec/mocks/error_generator.rb +378 -0
  22. data/lib/rspec/mocks/example_methods.rb +434 -0
  23. data/lib/rspec/mocks/instance_method_stasher.rb +146 -0
  24. data/lib/rspec/mocks/marshal_extension.rb +41 -0
  25. data/lib/rspec/mocks/matchers/expectation_customization.rb +20 -0
  26. data/lib/rspec/mocks/matchers/have_received.rb +134 -0
  27. data/lib/rspec/mocks/matchers/receive.rb +132 -0
  28. data/lib/rspec/mocks/matchers/receive_message_chain.rb +82 -0
  29. data/lib/rspec/mocks/matchers/receive_messages.rb +77 -0
  30. data/lib/rspec/mocks/message_chain.rb +87 -0
  31. data/lib/rspec/mocks/message_expectation.rb +748 -0
  32. data/lib/rspec/mocks/method_double.rb +287 -0
  33. data/lib/rspec/mocks/method_reference.rb +202 -0
  34. data/lib/rspec/mocks/minitest_integration.rb +68 -0
  35. data/lib/rspec/mocks/mutate_const.rb +339 -0
  36. data/lib/rspec/mocks/object_reference.rb +149 -0
  37. data/lib/rspec/mocks/order_group.rb +81 -0
  38. data/lib/rspec/mocks/proxy.rb +485 -0
  39. data/lib/rspec/mocks/space.rb +238 -0
  40. data/lib/rspec/mocks/standalone.rb +3 -0
  41. data/lib/rspec/mocks/syntax.rb +325 -0
  42. data/lib/rspec/mocks/targets.rb +124 -0
  43. data/lib/rspec/mocks/test_double.rb +171 -0
  44. data/lib/rspec/mocks/verifying_double.rb +129 -0
  45. data/lib/rspec/mocks/verifying_message_expectation.rb +54 -0
  46. data/lib/rspec/mocks/verifying_proxy.rb +220 -0
  47. data/lib/rspec/mocks/version.rb +9 -0
  48. metadata +186 -0
@@ -0,0 +1,23 @@
1
+ module RSpec
2
+ module Mocks
3
+ module AnyInstance
4
+ # @private
5
+ class StubChainChain < StubChain
6
+ def initialize(*args)
7
+ super
8
+ @expectation_fulfilled = false
9
+ end
10
+
11
+ private
12
+
13
+ def create_message_expectation_on(instance)
14
+ ::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block)
15
+ end
16
+
17
+ def invocation_order
18
+ EmptyInvocationOrder
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,100 @@
1
+ # We intentionally do not use the `RSpec::Support.require...` methods
2
+ # here so that this file can be loaded individually, as documented
3
+ # below.
4
+ require 'rspec/mocks/argument_matchers'
5
+ require 'rspec/support/fuzzy_matcher'
6
+
7
+ module RSpec
8
+ module Mocks
9
+ # Wrapper for matching arguments against a list of expected values. Used by
10
+ # the `with` method on a `MessageExpectation`:
11
+ #
12
+ # expect(object).to receive(:message).with(:a, 'b', 3)
13
+ # object.message(:a, 'b', 3)
14
+ #
15
+ # Values passed to `with` can be literal values or argument matchers that
16
+ # match against the real objects .e.g.
17
+ #
18
+ # expect(object).to receive(:message).with(hash_including(:a => 'b'))
19
+ #
20
+ # Can also be used directly to match the contents of any `Array`. This
21
+ # enables 3rd party mocking libs to take advantage of rspec's argument
22
+ # matching without using the rest of rspec-mocks.
23
+ #
24
+ # require 'rspec/mocks/argument_list_matcher'
25
+ # include RSpec::Mocks::ArgumentMatchers
26
+ #
27
+ # arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b'))
28
+ # arg_list_matcher.args_match?(123, :a => 'b')
29
+ #
30
+ # This class is immutable.
31
+ #
32
+ # @see ArgumentMatchers
33
+ class ArgumentListMatcher
34
+ # @private
35
+ attr_reader :expected_args
36
+
37
+ # @api public
38
+ # @param [Array] expected_args a list of expected literals and/or argument matchers
39
+ #
40
+ # Initializes an `ArgumentListMatcher` with a collection of literal
41
+ # values and/or argument matchers.
42
+ #
43
+ # @see ArgumentMatchers
44
+ # @see #args_match?
45
+ def initialize(*expected_args)
46
+ @expected_args = expected_args
47
+ ensure_expected_args_valid!
48
+ end
49
+
50
+ # @api public
51
+ # @param [Array] args
52
+ #
53
+ # Matches each element in the `expected_args` against the element in the same
54
+ # position of the arguments passed to `new`.
55
+ #
56
+ # @see #initialize
57
+ def args_match?(*args)
58
+ Support::FuzzyMatcher.values_match?(resolve_expected_args_based_on(args), args)
59
+ end
60
+
61
+ # @private
62
+ # Resolves abstract arg placeholders like `no_args` and `any_args` into
63
+ # a more concrete arg list based on the provided `actual_args`.
64
+ def resolve_expected_args_based_on(actual_args)
65
+ return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args
66
+
67
+ any_args_index = expected_args.index { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a }
68
+ return expected_args unless any_args_index
69
+
70
+ replace_any_args_with_splat_of_anything(any_args_index, actual_args.count)
71
+ end
72
+
73
+ private
74
+
75
+ def replace_any_args_with_splat_of_anything(before_count, actual_args_count)
76
+ any_args_count = actual_args_count - expected_args.count + 1
77
+ after_count = expected_args.count - before_count - 1
78
+
79
+ any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE }
80
+ expected_args.first(before_count) + any_args + expected_args.last(after_count)
81
+ end
82
+
83
+ def ensure_expected_args_valid!
84
+ if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1
85
+ raise ArgumentError, "`any_args` can only be passed to " \
86
+ "`with` once but you have passed it multiple times."
87
+ elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a }
88
+ raise ArgumentError, "`no_args` can only be passed as a " \
89
+ "singleton argument to `with` (i.e. `with(no_args)`), " \
90
+ "but you have passed additional arguments."
91
+ end
92
+ end
93
+
94
+ # Value that will match all argument lists.
95
+ #
96
+ # @private
97
+ MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,320 @@
1
+ # This cannot take advantage of our relative requires, since this file is a
2
+ # dependency of `rspec/mocks/argument_list_matcher.rb`. See comment there for
3
+ # details.
4
+ require 'rspec/support/matcher_definition'
5
+
6
+ module RSpec
7
+ module Mocks
8
+ # ArgumentMatchers are placeholders that you can include in message
9
+ # expectations to match arguments against a broader check than simple
10
+ # equality.
11
+ #
12
+ # With the exception of `any_args` and `no_args`, they all match against
13
+ # the arg in same position in the argument list.
14
+ #
15
+ # @see ArgumentListMatcher
16
+ module ArgumentMatchers
17
+ # Acts like an arg splat, matching any number of args at any point in an arg list.
18
+ #
19
+ # @example
20
+ # expect(object).to receive(:message).with(1, 2, any_args)
21
+ #
22
+ # # matches any of these:
23
+ # object.message(1, 2)
24
+ # object.message(1, 2, 3)
25
+ # object.message(1, 2, 3, 4)
26
+ def any_args
27
+ AnyArgsMatcher::INSTANCE
28
+ end
29
+
30
+ # Matches any argument at all.
31
+ #
32
+ # @example
33
+ # expect(object).to receive(:message).with(anything)
34
+ def anything
35
+ AnyArgMatcher::INSTANCE
36
+ end
37
+
38
+ # Matches no arguments.
39
+ #
40
+ # @example
41
+ # expect(object).to receive(:message).with(no_args)
42
+ def no_args
43
+ NoArgsMatcher::INSTANCE
44
+ end
45
+
46
+ # Matches if the actual argument responds to the specified messages.
47
+ #
48
+ # @example
49
+ # expect(object).to receive(:message).with(duck_type(:hello))
50
+ # expect(object).to receive(:message).with(duck_type(:hello, :goodbye))
51
+ def duck_type(*args)
52
+ DuckTypeMatcher.new(*args)
53
+ end
54
+
55
+ # Matches a boolean value.
56
+ #
57
+ # @example
58
+ # expect(object).to receive(:message).with(boolean())
59
+ def boolean
60
+ BooleanMatcher::INSTANCE
61
+ end
62
+
63
+ # Matches a hash that includes the specified key(s) or key/value pairs.
64
+ # Ignores any additional keys.
65
+ #
66
+ # @example
67
+ # expect(object).to receive(:message).with(hash_including(:key => val))
68
+ # expect(object).to receive(:message).with(hash_including(:key))
69
+ # expect(object).to receive(:message).with(hash_including(:key, :key2 => val2))
70
+ def hash_including(*args)
71
+ HashIncludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args))
72
+ end
73
+
74
+ # Matches an array that includes the specified items at least once.
75
+ # Ignores duplicates and additional values
76
+ #
77
+ # @example
78
+ # expect(object).to receive(:message).with(array_including(1,2,3))
79
+ # expect(object).to receive(:message).with(array_including([1,2,3]))
80
+ def array_including(*args)
81
+ actually_an_array = Array === args.first && args.count == 1 ? args.first : args
82
+ ArrayIncludingMatcher.new(actually_an_array)
83
+ end
84
+
85
+ # Matches a hash that doesn't include the specified key(s) or key/value.
86
+ #
87
+ # @example
88
+ # expect(object).to receive(:message).with(hash_excluding(:key => val))
89
+ # expect(object).to receive(:message).with(hash_excluding(:key))
90
+ # expect(object).to receive(:message).with(hash_excluding(:key, :key2 => :val2))
91
+ def hash_excluding(*args)
92
+ HashExcludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args))
93
+ end
94
+
95
+ alias_method :hash_not_including, :hash_excluding
96
+
97
+ # Matches if `arg.instance_of?(klass)`
98
+ #
99
+ # @example
100
+ # expect(object).to receive(:message).with(instance_of(Thing))
101
+ def instance_of(klass)
102
+ InstanceOf.new(klass)
103
+ end
104
+
105
+ alias_method :an_instance_of, :instance_of
106
+
107
+ # Matches if `arg.kind_of?(klass)`
108
+ #
109
+ # @example
110
+ # expect(object).to receive(:message).with(kind_of(Thing))
111
+ def kind_of(klass)
112
+ KindOf.new(klass)
113
+ end
114
+
115
+ alias_method :a_kind_of, :kind_of
116
+
117
+ # @private
118
+ def self.anythingize_lonely_keys(*args)
119
+ hash = Hash === args.last ? args.delete_at(-1) : {}
120
+ args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE }
121
+ hash
122
+ end
123
+
124
+ # Intended to be subclassed by stateless, immutable argument matchers.
125
+ # Provides a `<klass name>::INSTANCE` constant for accessing a global
126
+ # singleton instance of the matcher. There is no need to construct
127
+ # multiple instance since there is no state. It also facilities the
128
+ # special case logic we need for some of these matchers, by making it
129
+ # easy to do comparisons like: `[klass::INSTANCE] == args` rather than
130
+ # `args.count == 1 && klass === args.first`.
131
+ #
132
+ # @private
133
+ class SingletonMatcher
134
+ private_class_method :new
135
+
136
+ def self.inherited(subklass)
137
+ subklass.const_set(:INSTANCE, subklass.send(:new))
138
+ end
139
+ end
140
+
141
+ # @private
142
+ class AnyArgsMatcher < SingletonMatcher
143
+ def description
144
+ "*(any args)"
145
+ end
146
+ end
147
+
148
+ # @private
149
+ class AnyArgMatcher < SingletonMatcher
150
+ def ===(_other)
151
+ true
152
+ end
153
+
154
+ def description
155
+ "anything"
156
+ end
157
+ end
158
+
159
+ # @private
160
+ class NoArgsMatcher < SingletonMatcher
161
+ def description
162
+ "no args"
163
+ end
164
+ end
165
+
166
+ # @private
167
+ class BooleanMatcher < SingletonMatcher
168
+ def ===(value)
169
+ true == value || false == value
170
+ end
171
+
172
+ def description
173
+ "boolean"
174
+ end
175
+ end
176
+
177
+ # @private
178
+ class BaseHashMatcher
179
+ def initialize(expected)
180
+ @expected = expected
181
+ end
182
+
183
+ def ===(predicate, actual)
184
+ @expected.__send__(predicate) do |k, v|
185
+ actual.key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k])
186
+ end
187
+ rescue NoMethodError
188
+ false
189
+ end
190
+
191
+ def description(name)
192
+ "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})"
193
+ end
194
+
195
+ private
196
+
197
+ def formatted_expected_hash
198
+ Hash[
199
+ @expected.map do |k, v|
200
+ k = RSpec::Support.rspec_description_for_object(k)
201
+ v = RSpec::Support.rspec_description_for_object(v)
202
+
203
+ [k, v]
204
+ end
205
+ ]
206
+ end
207
+ end
208
+
209
+ # @private
210
+ class HashIncludingMatcher < BaseHashMatcher
211
+ def ===(actual)
212
+ super(:all?, actual)
213
+ end
214
+
215
+ def description
216
+ super("hash_including")
217
+ end
218
+ end
219
+
220
+ # @private
221
+ class HashExcludingMatcher < BaseHashMatcher
222
+ def ===(actual)
223
+ super(:none?, actual)
224
+ end
225
+
226
+ def description
227
+ super("hash_not_including")
228
+ end
229
+ end
230
+
231
+ # @private
232
+ class ArrayIncludingMatcher
233
+ def initialize(expected)
234
+ @expected = expected
235
+ end
236
+
237
+ def ===(actual)
238
+ actual = actual.uniq
239
+ @expected.uniq.all? do |expected_element|
240
+ actual.any? do |actual_element|
241
+ RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element)
242
+ end
243
+ end
244
+ end
245
+
246
+ def description
247
+ "array_including(#{formatted_expected_values})"
248
+ end
249
+
250
+ private
251
+
252
+ def formatted_expected_values
253
+ @expected.map do |x|
254
+ RSpec::Support.rspec_description_for_object(x)
255
+ end.join(", ")
256
+ end
257
+ end
258
+
259
+ # @private
260
+ class DuckTypeMatcher
261
+ def initialize(*methods_to_respond_to)
262
+ @methods_to_respond_to = methods_to_respond_to
263
+ end
264
+
265
+ def ===(value)
266
+ @methods_to_respond_to.all? { |message| value.respond_to?(message) }
267
+ end
268
+
269
+ def description
270
+ "duck_type(#{@methods_to_respond_to.map(&:inspect).join(', ')})"
271
+ end
272
+ end
273
+
274
+ # @private
275
+ class InstanceOf
276
+ def initialize(klass)
277
+ @klass = klass
278
+ end
279
+
280
+ def ===(actual)
281
+ actual.instance_of?(@klass)
282
+ end
283
+
284
+ def description
285
+ "an_instance_of(#{@klass.name})"
286
+ end
287
+ end
288
+
289
+ # @private
290
+ class KindOf
291
+ def initialize(klass)
292
+ @klass = klass
293
+ end
294
+
295
+ def ===(actual)
296
+ actual.kind_of?(@klass)
297
+ end
298
+
299
+ def description
300
+ "kind of #{@klass.name}"
301
+ end
302
+ end
303
+
304
+ matcher_namespace = name + '::'
305
+ ::RSpec::Support.register_matcher_definition do |object|
306
+ # This is the best we have for now. We should tag all of our matchers
307
+ # with a module or something so we can test for it directly.
308
+ #
309
+ # (Note Module#parent in ActiveSupport is defined in a similar way.)
310
+ begin
311
+ object.class.name.include?(matcher_namespace)
312
+ rescue NoMethodError
313
+ # Some objects, like BasicObject, don't implemented standard
314
+ # reflection methods.
315
+ false
316
+ end
317
+ end
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,212 @@
1
+ module RSpec
2
+ module Mocks
3
+ # Provides configuration options for rspec-mocks.
4
+ class Configuration
5
+ def initialize
6
+ @allow_message_expectations_on_nil = nil
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
11
+ @temporarily_suppress_partial_double_verification = false
12
+ @color = false
13
+ end
14
+
15
+ # Sets whether RSpec will warn, ignore, or fail a test when
16
+ # expectations are set on nil.
17
+ # By default, when this flag is not set, warning messages are issued when
18
+ # expectations are set on nil. This is to prevent false-positives and to
19
+ # catch potential bugs early on.
20
+ # When set to `true`, warning messages are suppressed.
21
+ # When set to `false`, it will raise an error.
22
+ #
23
+ # @example
24
+ # RSpec.configure do |config|
25
+ # config.mock_with :rspec do |mocks|
26
+ # mocks.allow_message_expectations_on_nil = false
27
+ # end
28
+ # end
29
+ attr_accessor :allow_message_expectations_on_nil
30
+
31
+ def yield_receiver_to_any_instance_implementation_blocks?
32
+ @yield_receiver_to_any_instance_implementation_blocks
33
+ end
34
+
35
+ # Sets whether or not RSpec will yield the receiving instance of a
36
+ # message to blocks that are used for any_instance stub implementations.
37
+ # When set, the first yielded argument will be the receiving instance.
38
+ # Defaults to `true`.
39
+ #
40
+ # @example
41
+ # RSpec.configure do |rspec|
42
+ # rspec.mock_with :rspec do |mocks|
43
+ # mocks.yield_receiver_to_any_instance_implementation_blocks = false
44
+ # end
45
+ # end
46
+ attr_writer :yield_receiver_to_any_instance_implementation_blocks
47
+
48
+ # Adds `stub` and `should_receive` to the given
49
+ # modules or classes. This is usually only necessary
50
+ # if you application uses some proxy classes that
51
+ # "strip themselves down" to a bare minimum set of
52
+ # methods and remove `stub` and `should_receive` in
53
+ # the process.
54
+ #
55
+ # @example
56
+ # RSpec.configure do |rspec|
57
+ # rspec.mock_with :rspec do |mocks|
58
+ # mocks.add_stub_and_should_receive_to Delegator
59
+ # end
60
+ # end
61
+ #
62
+ def add_stub_and_should_receive_to(*modules)
63
+ modules.each do |mod|
64
+ Syntax.enable_should(mod)
65
+ end
66
+ end
67
+
68
+ # Provides the ability to set either `expect`,
69
+ # `should` or both syntaxes. RSpec uses `expect`
70
+ # syntax by default. This is needed if you want to
71
+ # explicitly enable `should` syntax and/or explicitly
72
+ # disable `expect` syntax.
73
+ #
74
+ # @example
75
+ # RSpec.configure do |rspec|
76
+ # rspec.mock_with :rspec do |mocks|
77
+ # mocks.syntax = [:expect, :should]
78
+ # end
79
+ # end
80
+ #
81
+ def syntax=(*values)
82
+ syntaxes = values.flatten
83
+ if syntaxes.include?(:expect)
84
+ Syntax.enable_expect
85
+ else
86
+ Syntax.disable_expect
87
+ end
88
+
89
+ if syntaxes.include?(:should)
90
+ Syntax.enable_should
91
+ else
92
+ Syntax.disable_should
93
+ end
94
+ end
95
+
96
+ # Returns an array with a list of syntaxes
97
+ # that are enabled.
98
+ #
99
+ # @example
100
+ # unless RSpec::Mocks.configuration.syntax.include?(:expect)
101
+ # raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax"
102
+ # end
103
+ #
104
+ def syntax
105
+ syntaxes = []
106
+ syntaxes << :should if Syntax.should_enabled?
107
+ syntaxes << :expect if Syntax.expect_enabled?
108
+ syntaxes
109
+ end
110
+
111
+ def verify_doubled_constant_names?
112
+ !!@verify_doubled_constant_names
113
+ end
114
+
115
+ # When this is set to true, an error will be raised when
116
+ # `instance_double` or `class_double` is given the name of an undefined
117
+ # constant. You probably only want to set this when running your entire
118
+ # test suite, with all production code loaded. Setting this for an
119
+ # isolated unit test will prevent you from being able to isolate it!
120
+ attr_writer :verify_doubled_constant_names
121
+
122
+ # Provides a way to perform customisations when verifying doubles.
123
+ #
124
+ # @example
125
+ # RSpec::Mocks.configuration.before_verifying_doubles do |ref|
126
+ # ref.some_method!
127
+ # end
128
+ def before_verifying_doubles(&block)
129
+ verifying_double_callbacks << block
130
+ end
131
+ alias :when_declaring_verifying_double :before_verifying_doubles
132
+
133
+ # @api private
134
+ # Returns an array of blocks to call when verifying doubles
135
+ def verifying_double_callbacks
136
+ @verifying_double_callbacks ||= []
137
+ end
138
+
139
+ def transfer_nested_constants?
140
+ !!@transfer_nested_constants
141
+ end
142
+
143
+ # Sets the default for the `transfer_nested_constants` option when
144
+ # stubbing constants.
145
+ attr_writer :transfer_nested_constants
146
+
147
+ # When set to true, partial mocks will be verified the same as object
148
+ # doubles. Any stubs will have their arguments checked against the original
149
+ # method, and methods that do not exist cannot be stubbed.
150
+ def verify_partial_doubles=(val)
151
+ @verify_partial_doubles = !!val
152
+ end
153
+
154
+ def verify_partial_doubles?
155
+ @verify_partial_doubles
156
+ end
157
+
158
+ # @private
159
+ # Used to track wether we are temporarily suppressing verifying partial
160
+ # doubles with `without_partial_double_verification { ... }`
161
+ attr_accessor :temporarily_suppress_partial_double_verification
162
+
163
+ if ::RSpec.respond_to?(:configuration)
164
+ def color?
165
+ ::RSpec.configuration.color_enabled?
166
+ end
167
+ else
168
+ # Indicates whether or not diffs should be colored.
169
+ # Delegates to rspec-core's color option if rspec-core
170
+ # is loaded; otherwise you can set it here.
171
+ attr_writer :color
172
+
173
+ # Indicates whether or not diffs should be colored.
174
+ # Delegates to rspec-core's color option if rspec-core
175
+ # is loaded; otherwise you can set it here.
176
+ def color?
177
+ @color
178
+ end
179
+ end
180
+
181
+ # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed
182
+ # objects. By default this will not work since RSpec mocks works by
183
+ # adding singleton methods that cannot be serialized. This patch removes
184
+ # these singleton methods before serialization. Setting to falsey removes
185
+ # the patch.
186
+ #
187
+ # This method is idempotent.
188
+ def patch_marshal_to_support_partial_doubles=(val)
189
+ if val
190
+ RSpec::Mocks::MarshalExtension.patch!
191
+ else
192
+ RSpec::Mocks::MarshalExtension.unpatch!
193
+ end
194
+ end
195
+
196
+ # @api private
197
+ # Resets the configured syntax to the default.
198
+ def reset_syntaxes_to_default
199
+ self.syntax = [:should, :expect]
200
+ RSpec::Mocks::Syntax.warn_about_should!
201
+ end
202
+ end
203
+
204
+ # Mocks specific configuration, as distinct from `RSpec.configuration`
205
+ # which is core RSpec configuration.
206
+ def self.configuration
207
+ @configuration ||= Configuration.new
208
+ end
209
+
210
+ configuration.reset_syntaxes_to_default
211
+ end
212
+ end