rspec-mocks 3.0.4 → 3.12.6

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.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +1 -1
  5. data/Changelog.md +512 -2
  6. data/{License.txt → LICENSE.md} +5 -4
  7. data/README.md +113 -30
  8. data/lib/rspec/mocks/any_instance/chain.rb +5 -3
  9. data/lib/rspec/mocks/any_instance/error_generator.rb +31 -0
  10. data/lib/rspec/mocks/any_instance/expect_chain_chain.rb +1 -5
  11. data/lib/rspec/mocks/any_instance/expectation_chain.rb +9 -8
  12. data/lib/rspec/mocks/any_instance/message_chains.rb +7 -8
  13. data/lib/rspec/mocks/any_instance/proxy.rb +14 -5
  14. data/lib/rspec/mocks/any_instance/recorder.rb +61 -31
  15. data/lib/rspec/mocks/any_instance/stub_chain.rb +15 -11
  16. data/lib/rspec/mocks/any_instance/stub_chain_chain.rb +1 -5
  17. data/lib/rspec/mocks/any_instance.rb +1 -0
  18. data/lib/rspec/mocks/argument_list_matcher.rb +55 -10
  19. data/lib/rspec/mocks/argument_matchers.rb +88 -30
  20. data/lib/rspec/mocks/configuration.rb +61 -13
  21. data/lib/rspec/mocks/error_generator.rb +250 -107
  22. data/lib/rspec/mocks/example_methods.rb +151 -28
  23. data/lib/rspec/mocks/instance_method_stasher.rb +17 -6
  24. data/lib/rspec/mocks/matchers/have_received.rb +50 -20
  25. data/lib/rspec/mocks/matchers/receive.rb +39 -11
  26. data/lib/rspec/mocks/matchers/receive_message_chain.rb +22 -7
  27. data/lib/rspec/mocks/matchers/receive_messages.rb +12 -7
  28. data/lib/rspec/mocks/message_chain.rb +3 -7
  29. data/lib/rspec/mocks/message_expectation.rb +466 -307
  30. data/lib/rspec/mocks/method_double.rb +88 -29
  31. data/lib/rspec/mocks/method_reference.rb +85 -25
  32. data/lib/rspec/mocks/minitest_integration.rb +68 -0
  33. data/lib/rspec/mocks/mutate_const.rb +50 -109
  34. data/lib/rspec/mocks/object_reference.rb +89 -32
  35. data/lib/rspec/mocks/order_group.rb +4 -5
  36. data/lib/rspec/mocks/proxy.rb +156 -60
  37. data/lib/rspec/mocks/space.rb +52 -35
  38. data/lib/rspec/mocks/standalone.rb +1 -1
  39. data/lib/rspec/mocks/syntax.rb +26 -30
  40. data/lib/rspec/mocks/targets.rb +55 -28
  41. data/lib/rspec/mocks/test_double.rb +43 -7
  42. data/lib/rspec/mocks/verifying_double.rb +27 -33
  43. data/lib/rspec/mocks/{verifying_message_expecation.rb → verifying_message_expectation.rb} +11 -16
  44. data/lib/rspec/mocks/verifying_proxy.rb +77 -26
  45. data/lib/rspec/mocks/version.rb +1 -1
  46. data/lib/rspec/mocks.rb +8 -1
  47. data.tar.gz.sig +0 -0
  48. metadata +80 -43
  49. metadata.gz.sig +0 -0
@@ -10,7 +10,7 @@ module RSpec
10
10
  end
11
11
 
12
12
  # @private
13
- def self.warn_unless_should_configured(method_name ,replacement = "the new `:expect` syntax or explicitly enable `:should`")
13
+ def self.warn_unless_should_configured(method_name , replacement="the new `:expect` syntax or explicitly enable `:should`")
14
14
  if @warn_about_should
15
15
  RSpec.deprecate(
16
16
  "Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax",
@@ -23,7 +23,7 @@ module RSpec
23
23
 
24
24
  # @api private
25
25
  # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
26
- def self.enable_should(syntax_host = default_should_syntax_host)
26
+ def self.enable_should(syntax_host=default_should_syntax_host)
27
27
  @warn_about_should = false if syntax_host == default_should_syntax_host
28
28
  return if should_enabled?(syntax_host)
29
29
 
@@ -41,14 +41,14 @@ module RSpec
41
41
  def stub(message_or_hash, opts={}, &block)
42
42
  ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__)
43
43
  if ::Hash === message_or_hash
44
- message_or_hash.each {|message, value| stub(message).and_return value }
44
+ message_or_hash.each { |message, value| stub(message).and_return value }
45
45
  else
46
46
  ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block)
47
47
  end
48
48
  end
49
49
 
50
50
  def unstub(message)
51
- ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to_receive(...).and_call_original` or explicitly enable `:should`")
51
+ ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to receive(...).and_call_original` or explicitly enable `:should`")
52
52
  ::RSpec::Mocks.space.proxy_for(self).remove_stub(message)
53
53
  end
54
54
 
@@ -86,7 +86,7 @@ module RSpec
86
86
 
87
87
  # @api private
88
88
  # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc).
89
- def self.disable_should(syntax_host = default_should_syntax_host)
89
+ def self.disable_should(syntax_host=default_should_syntax_host)
90
90
  return unless should_enabled?(syntax_host)
91
91
 
92
92
  syntax_host.class_exec do
@@ -107,7 +107,7 @@ module RSpec
107
107
 
108
108
  # @api private
109
109
  # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
110
- def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
110
+ def self.enable_expect(syntax_host=::RSpec::Mocks::ExampleMethods)
111
111
  return if expect_enabled?(syntax_host)
112
112
 
113
113
  syntax_host.class_exec do
@@ -147,7 +147,7 @@ module RSpec
147
147
 
148
148
  # @api private
149
149
  # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
150
- def self.disable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
150
+ def self.disable_expect(syntax_host=::RSpec::Mocks::ExampleMethods)
151
151
  return unless expect_enabled?(syntax_host)
152
152
 
153
153
  syntax_host.class_exec do
@@ -166,13 +166,13 @@ module RSpec
166
166
 
167
167
  # @api private
168
168
  # Indicates whether or not the should syntax is enabled.
169
- def self.should_enabled?(syntax_host = default_should_syntax_host)
169
+ def self.should_enabled?(syntax_host=default_should_syntax_host)
170
170
  syntax_host.method_defined?(:should_receive)
171
171
  end
172
172
 
173
173
  # @api private
174
174
  # Indicates whether or not the expect syntax is enabled.
175
- def self.expect_enabled?(syntax_host = ::RSpec::Mocks::ExampleMethods)
175
+ def self.expect_enabled?(syntax_host=::RSpec::Mocks::ExampleMethods)
176
176
  syntax_host.method_defined?(:allow)
177
177
  end
178
178
 
@@ -214,11 +214,10 @@ if defined?(BasicObject)
214
214
  # the end of the example.
215
215
  #
216
216
  # @example
217
- #
218
- # logger = double('logger')
219
- # thing_that_logs = ThingThatLogs.new(logger)
220
- # logger.should_receive(:log)
221
- # thing_that_logs.do_something_that_logs_a_message
217
+ # logger = double('logger')
218
+ # thing_that_logs = ThingThatLogs.new(logger)
219
+ # logger.should_receive(:log)
220
+ # thing_that_logs.do_something_that_logs_a_message
222
221
  #
223
222
  # @note This is only available when you have enabled the `should` syntax.
224
223
  # @see RSpec::Mocks::ExampleMethods#expect
@@ -232,10 +231,9 @@ if defined?(BasicObject)
232
231
  # Tells the object to respond to the message with the specified value.
233
232
  #
234
233
  # @example
235
- #
236
- # counter.stub(:count).and_return(37)
237
- # counter.stub(:count => 37)
238
- # counter.stub(:count) { 37 }
234
+ # counter.stub(:count).and_return(37)
235
+ # counter.stub(:count => 37)
236
+ # counter.stub(:count) { 37 }
239
237
  #
240
238
  # @note This is only available when you have enabled the `should` syntax.
241
239
  # @see RSpec::Mocks::ExampleMethods#allow
@@ -269,10 +267,9 @@ if defined?(BasicObject)
269
267
  # implementation calls `foo.baz.bar`, the stub will not work.
270
268
  #
271
269
  # @example
272
- #
273
- # double.stub_chain("foo.bar") { :baz }
274
- # double.stub_chain(:foo, :bar => :baz)
275
- # double.stub_chain(:foo, :bar) { :baz }
270
+ # double.stub_chain("foo.bar") { :baz }
271
+ # double.stub_chain(:foo, :bar => :baz)
272
+ # double.stub_chain(:foo, :bar) { :baz }
276
273
  #
277
274
  # # Given any of ^^ these three forms ^^:
278
275
  # double.foo.bar # => :baz
@@ -311,15 +308,14 @@ class Class
311
308
  # class.
312
309
  #
313
310
  # @example
311
+ # Car.any_instance.should_receive(:go)
312
+ # race = Race.new
313
+ # race.cars << Car.new
314
+ # race.go # assuming this delegates to all of its cars
315
+ # # this example would pass
314
316
  #
315
- # Car.any_instance.should_receive(:go)
316
- # race = Race.new
317
- # race.cars << Car.new
318
- # race.go # assuming this delegates to all of its cars
319
- # # this example would pass
320
- #
321
- # Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
322
- # Account.new.balance # => Money.new(:USD, 25))
317
+ # Account.any_instance.stub(:balance) { Money.new(:USD, 25) }
318
+ # Account.new.balance # => Money.new(:USD, 25))
323
319
  #
324
320
  # @return [Recorder]
325
321
  #
@@ -1,12 +1,8 @@
1
1
  module RSpec
2
2
  module Mocks
3
3
  # @private
4
- class TargetBase
5
- def initialize(target)
6
- @target = target
7
- end
8
-
9
- def self.delegate_to(matcher_method)
4
+ module TargetDelegationClassMethods
5
+ def delegate_to(matcher_method)
10
6
  define_method(:to) do |matcher, &block|
11
7
  unless matcher_allowed?(matcher)
12
8
  raise_unsupported_matcher(:to, matcher)
@@ -15,11 +11,11 @@ module RSpec
15
11
  end
16
12
  end
17
13
 
18
- def self.delegate_not_to(matcher_method, options = {})
14
+ def delegate_not_to(matcher_method, options={})
19
15
  method_name = options.fetch(:from)
20
16
  define_method(method_name) do |matcher, &block|
21
17
  case matcher
22
- when Matchers::Receive
18
+ when Matchers::Receive, Matchers::HaveReceived
23
19
  define_matcher(matcher, matcher_method, &block)
24
20
  when Matchers::ReceiveMessages, Matchers::ReceiveMessageChain
25
21
  raise_negation_unsupported(method_name, matcher)
@@ -29,58 +25,86 @@ module RSpec
29
25
  end
30
26
  end
31
27
 
32
- def self.disallow_negation(method_name)
33
- define_method(method_name) do |matcher, *args|
28
+ def disallow_negation(method_name)
29
+ define_method(method_name) do |matcher, *_args|
34
30
  raise_negation_unsupported(method_name, matcher)
35
31
  end
36
32
  end
33
+ end
34
+
35
+ # @private
36
+ module TargetDelegationInstanceMethods
37
+ attr_reader :target
37
38
 
38
39
  private
39
40
 
40
41
  def matcher_allowed?(matcher)
41
- matcher.class.name.start_with?("RSpec::Mocks::Matchers".freeze)
42
+ Matchers::Matcher === matcher
42
43
  end
43
44
 
44
45
  def define_matcher(matcher, name, &block)
45
- matcher.__send__(name, @target, &block)
46
+ matcher.__send__(name, target, &block)
46
47
  end
47
48
 
48
49
  def raise_unsupported_matcher(method_name, matcher)
49
50
  raise UnsupportedMatcherError,
50
- "only the `receive` or `receive_messages` matchers are supported " +
51
- "with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}"
51
+ "only the `receive`, `have_received` and `receive_messages` matchers are supported " \
52
+ "with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}"
52
53
  end
53
54
 
54
55
  def raise_negation_unsupported(method_name, matcher)
55
56
  raise NegationUnsupportedError,
56
- "`#{expression}(...).#{method_name} #{matcher.name}` is not supported since it " +
57
- "doesn't really make sense. What would it even mean?"
57
+ "`#{expression}(...).#{method_name} #{matcher.matcher_name}` is not supported since it " \
58
+ "doesn't really make sense. What would it even mean?"
59
+ end
60
+ end
61
+
62
+ # @private
63
+ class TargetBase
64
+ def initialize(target)
65
+ @target = target
58
66
  end
59
67
 
68
+ extend TargetDelegationClassMethods
69
+ include TargetDelegationInstanceMethods
70
+ end
71
+
72
+ # @private
73
+ module ExpectationTargetMethods
74
+ extend TargetDelegationClassMethods
75
+ include TargetDelegationInstanceMethods
76
+
77
+ delegate_to :setup_expectation
78
+ delegate_not_to :setup_negative_expectation, :from => :not_to
79
+ delegate_not_to :setup_negative_expectation, :from => :to_not
80
+
60
81
  def expression
61
- self.class::EXPRESSION
82
+ :expect
62
83
  end
63
84
  end
64
85
 
86
+ # @private
87
+ class ExpectationTarget < TargetBase
88
+ include ExpectationTargetMethods
89
+ end
90
+
65
91
  # @private
66
92
  class AllowanceTarget < TargetBase
67
- EXPRESSION = :allow
93
+ def expression
94
+ :allow
95
+ end
96
+
68
97
  delegate_to :setup_allowance
69
98
  disallow_negation :not_to
70
99
  disallow_negation :to_not
71
100
  end
72
101
 
73
- # @private
74
- class ExpectationTarget < TargetBase
75
- EXPRESSION = :expect
76
- delegate_to :setup_expectation
77
- delegate_not_to :setup_negative_expectation, :from => :not_to
78
- delegate_not_to :setup_negative_expectation, :from => :to_not
79
- end
80
-
81
102
  # @private
82
103
  class AnyInstanceAllowanceTarget < TargetBase
83
- EXPRESSION = :allow_any_instance_of
104
+ def expression
105
+ :allow_any_instance_of
106
+ end
107
+
84
108
  delegate_to :setup_any_instance_allowance
85
109
  disallow_negation :not_to
86
110
  disallow_negation :to_not
@@ -88,7 +112,10 @@ module RSpec
88
112
 
89
113
  # @private
90
114
  class AnyInstanceExpectationTarget < TargetBase
91
- EXPRESSION = :expect_any_instance_of
115
+ def expression
116
+ :expect_any_instance_of
117
+ end
118
+
92
119
  delegate_to :setup_any_instance_expectation
93
120
  delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to
94
121
  delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not
@@ -39,12 +39,12 @@ module RSpec
39
39
 
40
40
  # @private
41
41
  def inspect
42
- "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
42
+ TestDoubleFormatter.format(self)
43
43
  end
44
44
 
45
45
  # @private
46
46
  def to_s
47
- inspect.gsub('<','[').gsub('>',']')
47
+ inspect.tr('<', '[').tr('>', ']')
48
48
  end
49
49
 
50
50
  # @private
@@ -54,7 +54,7 @@ module RSpec
54
54
 
55
55
  # @private
56
56
  def __build_mock_proxy_unless_expired(order_group)
57
- __raise_expired_error or __build_mock_proxy(order_group)
57
+ __raise_expired_error || __build_mock_proxy(order_group)
58
58
  end
59
59
 
60
60
  # @private
@@ -66,6 +66,7 @@ module RSpec
66
66
  # doubles.
67
67
  def freeze
68
68
  RSpec.warn_with("WARNING: you attempted to freeze a test double. This is explicitly a no-op as freezing doubles can lead to undesired behaviour when resetting tests.")
69
+ self
69
70
  end
70
71
 
71
72
  private
@@ -91,14 +92,14 @@ module RSpec
91
92
  # https://github.com/jruby/jruby/issues/1398
92
93
  visibility = proxy.visibility_for(message)
93
94
  if visibility == :private || visibility == :protected
94
- ErrorGenerator.new(self, @name).raise_non_public_error(
95
+ ErrorGenerator.new(self).raise_non_public_error(
95
96
  message, visibility
96
97
  )
97
98
  end
98
99
 
99
100
  # Required wrapping doubles in an Array on Ruby 1.9.2
100
101
  raise NoMethodError if [:to_a, :to_ary].include? message
101
- proxy.raise_unexpected_message_error(message, *args)
102
+ proxy.raise_unexpected_message_error(message, args)
102
103
  end
103
104
 
104
105
  def assign_stubs(stubs)
@@ -112,12 +113,12 @@ module RSpec
112
113
  end
113
114
 
114
115
  def __build_mock_proxy(order_group)
115
- TestDoubleProxy.new(self, order_group, @name)
116
+ TestDoubleProxy.new(self, order_group)
116
117
  end
117
118
 
118
119
  def __raise_expired_error
119
120
  return false unless @__expired
120
- ErrorGenerator.new(self, @name).raise_expired_test_double_error
121
+ ErrorGenerator.new(self).raise_expired_test_double_error
121
122
  end
122
123
 
123
124
  def initialize_copy(other)
@@ -131,5 +132,40 @@ module RSpec
131
132
  class Double
132
133
  include TestDouble
133
134
  end
135
+
136
+ # @private
137
+ module TestDoubleFormatter
138
+ def self.format(dbl, unwrap=false)
139
+ format = "#{type_desc(dbl)}#{verified_module_desc(dbl)} #{name_desc(dbl)}"
140
+ return format if unwrap
141
+ "#<#{format}>"
142
+ end
143
+
144
+ class << self
145
+ private
146
+
147
+ def type_desc(dbl)
148
+ case dbl
149
+ when InstanceVerifyingDouble then "InstanceDouble"
150
+ when ClassVerifyingDouble then "ClassDouble"
151
+ when ObjectVerifyingDouble then "ObjectDouble"
152
+ else "Double"
153
+ end
154
+ end
155
+
156
+ # @private
157
+ IVAR_GET = Object.instance_method(:instance_variable_get)
158
+
159
+ def verified_module_desc(dbl)
160
+ return nil unless VerifyingDouble === dbl
161
+ "(#{IVAR_GET.bind(dbl).call(:@doubled_module).description})"
162
+ end
163
+
164
+ def name_desc(dbl)
165
+ return "(anonymous)" unless (name = IVAR_GET.bind(dbl).call(:@name))
166
+ name.inspect
167
+ end
168
+ end
169
+ end
134
170
  end
135
171
  end
@@ -1,9 +1,7 @@
1
1
  RSpec::Support.require_rspec_mocks 'verifying_proxy'
2
- require 'stringio'
3
2
 
4
3
  module RSpec
5
4
  module Mocks
6
-
7
5
  # @private
8
6
  module VerifyingDouble
9
7
  def respond_to?(message, include_private=false)
@@ -11,11 +9,11 @@ module RSpec
11
9
 
12
10
  method_ref = __mock_proxy.method_reference[message]
13
11
 
14
- return case method_ref.visibility
15
- when :public then true
16
- when :private then include_private
17
- when :protected then include_private || RUBY_VERSION.to_f < 2.0
18
- else !method_ref.unimplemented?
12
+ case method_ref.visibility
13
+ when :public then true
14
+ when :private then include_private
15
+ when :protected then include_private || RUBY_VERSION.to_f < 2.0
16
+ else !method_ref.unimplemented?
19
17
  end
20
18
  end
21
19
 
@@ -29,27 +27,38 @@ module RSpec
29
27
  else
30
28
  __mock_proxy.ensure_publicly_implemented(message, self)
31
29
  end
30
+
31
+ __mock_proxy.validate_arguments!(message, args)
32
32
  end
33
33
 
34
34
  super
35
35
  end
36
36
 
37
37
  # Redefining `__send__` causes ruby to issue a warning.
38
- old, $stderr = $stderr, StringIO.new
38
+ old, $VERBOSE = $VERBOSE, nil
39
39
  def __send__(name, *args, &block)
40
40
  @__sending_message = name
41
41
  super
42
42
  ensure
43
43
  @__sending_message = nil
44
44
  end
45
- $stderr = old
45
+ ruby2_keywords :__send__ if respond_to?(:ruby2_keywords, true)
46
+ $VERBOSE = old
46
47
 
47
48
  def send(name, *args, &block)
48
49
  __send__(name, *args, &block)
49
50
  end
51
+ ruby2_keywords :send if respond_to?(:ruby2_keywords, true)
50
52
 
51
- def initialize(*args)
52
- super
53
+ def initialize(doubled_module, *args)
54
+ @doubled_module = doubled_module
55
+
56
+ possible_name = args.first
57
+ name = if String === possible_name || Symbol === possible_name
58
+ args.shift
59
+ end
60
+
61
+ super(name, *args)
53
62
  @__sending_message = nil
54
63
  end
55
64
  end
@@ -63,19 +72,10 @@ module RSpec
63
72
  include TestDouble
64
73
  include VerifyingDouble
65
74
 
66
- def initialize(doubled_module, *args)
67
- @doubled_module = doubled_module
68
-
69
- super(
70
- "#{doubled_module.description} (instance)",
71
- *args
72
- )
73
- end
74
-
75
75
  def __build_mock_proxy(order_group)
76
- VerifyingProxy.new(self, order_group, @name,
77
- @doubled_module,
78
- InstanceMethodReference
76
+ VerifyingProxy.new(self, order_group,
77
+ @doubled_module,
78
+ InstanceMethodReference
79
79
  )
80
80
  end
81
81
  end
@@ -88,22 +88,17 @@ module RSpec
88
88
  include TestDouble
89
89
  include VerifyingDouble
90
90
 
91
- def as_stubbed_const(options = {})
91
+ def as_stubbed_const(options={})
92
92
  ConstantMutator.stub(@doubled_module.const_to_replace, self, options)
93
93
  self
94
94
  end
95
95
 
96
96
  private
97
97
 
98
- def initialize(doubled_module, *args)
99
- @doubled_module = doubled_module
100
- super(doubled_module.description, *args)
101
- end
102
-
103
98
  def __build_mock_proxy(order_group)
104
- VerifyingProxy.new(self, order_group, @name,
105
- @doubled_module,
106
- ObjectMethodReference
99
+ VerifyingProxy.new(self, order_group,
100
+ @doubled_module,
101
+ ObjectMethodReference
107
102
  )
108
103
  end
109
104
  end
@@ -124,6 +119,5 @@ module RSpec
124
119
  class ClassVerifyingDouble < Module
125
120
  include ObjectVerifyingDoubleMethods
126
121
  end
127
-
128
122
  end
129
123
  end
@@ -2,13 +2,11 @@ RSpec::Support.require_rspec_support 'method_signature_verifier'
2
2
 
3
3
  module RSpec
4
4
  module Mocks
5
-
6
5
  # A message expectation that knows about the real implementation of the
7
6
  # message being expected, so that it can verify that any expectations
8
7
  # have the valid arguments.
9
8
  # @api private
10
9
  class VerifyingMessageExpectation < MessageExpectation
11
-
12
10
  # A level of indirection is used here rather than just passing in the
13
11
  # method itself, since method look up is expensive and we only want to
14
12
  # do it if actually needed.
@@ -25,30 +23,27 @@ module RSpec
25
23
 
26
24
  # @private
27
25
  def with(*args, &block)
28
- unless ArgumentMatchers::AnyArgsMatcher === args.first
29
- expected_args = if ArgumentMatchers::NoArgsMatcher === args.first
30
- []
31
- elsif args.length > 0
32
- args
33
- else
34
- # No arguments given, this will raise.
35
- super
26
+ super(*args, &block).tap do
27
+ validate_expected_arguments! do |signature|
28
+ example_call_site_args = [:an_arg] * signature.min_non_kw_args
29
+ example_call_site_args << :kw_args_hash if signature.required_kw_args.any?
30
+ @argument_list_matcher.resolve_expected_args_based_on(example_call_site_args)
36
31
  end
37
-
38
- validate_arguments!(expected_args)
39
32
  end
40
- super
41
33
  end
34
+ ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true)
42
35
 
43
36
  private
44
37
 
45
- def validate_arguments!(actual_args)
38
+ def validate_expected_arguments!
46
39
  return if method_reference.nil?
47
40
 
48
41
  method_reference.with_signature do |signature|
49
- verifier = Support::MethodSignatureVerifier.new(signature, actual_args)
42
+ args = yield signature
43
+ verifier = Support::LooseSignatureVerifier.new(signature, args)
44
+
50
45
  unless verifier.valid?
51
- # Fail fast is required, otherwise the message expecation will fail
46
+ # Fail fast is required, otherwise the message expectation will fail
52
47
  # as well ("expected method not called") and clobber this one.
53
48
  @failed_fast = true
54
49
  @error_generator.raise_invalid_arguments_error(verifier)