flexmock 2.4.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55630790b40e21c94d842f9b5a173f0a3e2535aa40c4cc23c00aaaedaeaeb31a
4
- data.tar.gz: 2afc06542cbe3ef561fb51239ccdfd646e677ee5508038d7532fe427049713f8
3
+ metadata.gz: 97fdfec71cb9dd687df62403b26eb8d4d24e4b28ec7f35f5e2d5f3ac6ffed943
4
+ data.tar.gz: 8f250a12f731099db17e9fcea78b92e0b92ac523376a34e06b5295f3a17ec996
5
5
  SHA512:
6
- metadata.gz: e41731de6baa727d4580e5033180becda98c24a9b0522bf41a802f133023e20d6052c2d4a812ee435204cc8159bfdab32d3ddc66922ba8a69b8bf4427e89e13e
7
- data.tar.gz: fc31b71f78372d05cc3e44e7648d9a5c8c9f7499ac56a4713e63eb1a3db4ba4f9b2107ae989cf967d44e0206e0f8e134ec675821c3710248952835daa8e1b457
6
+ metadata.gz: 7672fd90360b33327119a7f135a7db9d05c7b7d41e0dd5299396296e0b68c8bb5175eaa2cf8d334b9b8cc62f52a87af4fe8af8216a4e9283341c909eed5ca196
7
+ data.tar.gz: a2112c506ef7152ba13aef9f67cb9ab5d58a0b566b5f50e7db00e545ff04e663da129f8291109dc25f028b2150ca4a936d96ced1444cbb85b4298534179046dc
@@ -8,7 +8,11 @@ jobs:
8
8
 
9
9
  strategy:
10
10
  matrix:
11
- ruby-version: ["2.7", "2.6", "2.5"]
11
+ ruby-version:
12
+ - "3.2"
13
+ - "3.1"
14
+ - "3.0"
15
+ - "2.7"
12
16
 
13
17
  steps:
14
18
  - uses: actions/checkout@v2
data/README.md CHANGED
@@ -22,6 +22,54 @@ Only significant changes (new APIs, deprecated APIs or backward-compatible
22
22
  changes) are documented here, a.k.a. minor or major version bumps. If you want a
23
23
  detailed changelog, go over the commit log in github (it's pretty low-traffic)
24
24
 
25
+ 3.0.0:
26
+ - Added keyword argument and explicit proc support. Keyword argument support
27
+ is Ruby 3.0+ only, getting the support to work on Ruby 2.7 deemed to be too
28
+ complicated. See the release notes for 2.4 below for information about how
29
+ migration can be done smoothly
30
+ - `with` now expects all expected keyword arguments to be explicitly given in a
31
+ natural way, for instance:
32
+
33
+ ```
34
+ mock.should_receive(:m).with("some", "args", with: 42)
35
+ ```
36
+
37
+ The values given to the arguments can be any matcher valid for the positional
38
+ arguments
39
+ - note that not giving any keyword arguments to `with` is interpreted as a
40
+ negative (no keyword arguments are expected), and will fail if some arguments
41
+ are given. Call `with_any_kw_args` after the `with` if you do not desire
42
+ validation of keyword arguments:
43
+
44
+ ```
45
+ mock.should_receive(:m).with("some", "args").with_any_kw_args
46
+ ```
47
+
48
+ - for more complex matches, pass a match object to the `with_kw_args` method.
49
+ For instance, to match only some keyword arguments, do
50
+
51
+ ```
52
+ mock.should_receive(:m).with("some", "args").with_kw_args(hsh(with: 42))
53
+ ```
54
+
55
+ - this release also makes matching procs explicit. Instead of passing Proc at
56
+ the end of `with` as in 2.x, call `with_block` or `with_no_block`. If neither
57
+ are called, flexmock won't validate either way (ignore whether or not a block
58
+ was given). The default is to not match blocks, that is working
59
+ - The default is to assume that blocks are optional (i.e. flexmock will match
60
+ either way). Nonetheless, the method `with_optional_block` is implemented
61
+ to help migration from flexmock 2.4.0 (but is a no-op).
62
+
63
+ 2.4.0:
64
+ - forward-compatible implementation of `with_kw_args`, `with_any_kw_args`,
65
+ `with_block` and `with_no_block`. The objective of this release is to ensure
66
+ that any test changes needed to handle Ruby 3 (along with flexmock 3) can run
67
+ on ruby 2.7 and flexmock 2.4
68
+ - the default behavior of flexmock 2 regarding proc matching, that is that one
69
+ needs to match them explicitly, is unchanged. Use `with_optional_block` instead
70
+ of passing `optional_proc` to `with`, to match optionally (IMPORTANT
71
+ the explicit `with` methods that match blocks are called `block`, not `proc`)
72
+
25
73
  2.3.0:
26
74
  - implemented validation of call arity for partial mocks. By setting
27
75
  FlexMock.partials_verify_signatures = true
@@ -546,12 +594,10 @@ determining whether a given expectation matches or not.
546
594
  series. The last value will be repeatably returned if the number of
547
595
  matching calls exceeds the number of values.
548
596
 
549
- * <b>and_return { |<em>args</em>, ...| <em>code</em> ... }</b>
597
+ * <b>and_return { |<em>*args</em>, <em>**kw</em>, <em>&block</em>| <em>code</em> ... }</b>
550
598
 
551
599
  Declares that the expected message will return the yielded value of
552
600
  the block. The block will receive all the arguments in the message.
553
- If the message was provided a block, it will be passed as the last
554
- parameter of the block's argument list.
555
601
 
556
602
  * <b>returns( ... )</b>
557
603
 
@@ -755,13 +801,15 @@ The following rules are used for argument matching:
755
801
 
756
802
  will match any even integer.
757
803
 
758
- * If you wish to match a method call where a block is given, add
759
- `Proc` as the last argument to `with`.
804
+ * By default, flexmock will ignore given blocks, that is it will assume that
805
+ blocks are optional.
806
+
807
+ * If you wish to verify that a method call received a block, use `with_block`
760
808
 
761
809
  Example:
762
810
 
763
811
  ```ruby
764
- m.should_receive(:foo).with(Integer,Proc).and_return(:got_block)
812
+ m.should_receive(:foo).with(Integer).with_block.and_return(:got_block)
765
813
  m.should_receive(:foo).with(Integer).and_return(:no_block)
766
814
  ```
767
815
 
@@ -772,6 +820,22 @@ The following rules are used for argument matching:
772
820
  m.foo(1) => returns :no_block
773
821
  ```
774
822
 
823
+ * If you wish to verify that a method call does not receive a block, use `with_no_block`
824
+
825
+ Example:
826
+
827
+ ```ruby
828
+ m.should_receive(:foo).with(Integer).with_no_block.and_return(:no_block)
829
+ m.should_receive(:foo).with(Integer).and_return(:got_block)
830
+ ```
831
+
832
+ will cause the mock to return the following:
833
+
834
+ ```ruby
835
+ m.foo(1) { } => returns :got_block
836
+ m.foo(1) => returns :no_block
837
+ ```
838
+
775
839
  ### Creating Partial Mocks
776
840
 
777
841
  Sometimes it is useful to mock the behavior of one or two methods in
data/flexmock.gemspec CHANGED
@@ -10,7 +10,7 @@ spec = Gem::Specification.new do |s|
10
10
  interface is simple, it is very flexible.
11
11
  }
12
12
 
13
- s.required_ruby_version = ">= 2.2"
13
+ s.required_ruby_version = ">= 3.0"
14
14
 
15
15
  s.license = 'MIT'
16
16
 
@@ -62,6 +62,9 @@ class FlexMock
62
62
  def ===(target)
63
63
  @hash.all? { |k, v| target[k] == v }
64
64
  end
65
+ def empty?
66
+ @hash.empty?
67
+ end
65
68
  def inspect
66
69
  "hsh(#{@hash.inspect})"
67
70
  end
@@ -80,19 +83,4 @@ class FlexMock
80
83
  "ducktype(#{@methods.map{|m| m.inspect}.join(',')})"
81
84
  end
82
85
  end
83
-
84
- ####################################################################
85
- # Match objects that implement all the methods in +methods+.
86
- class OptionalProcMatcher
87
- def initialize
88
- end
89
- def ===(target)
90
- ArgumentMatching.missing?(target) || Proc === target
91
- end
92
- def inspect
93
- "optional_proc"
94
- end
95
- end
96
- OPTIONAL_PROC_MATCHER = OptionalProcMatcher.new
97
-
98
86
  end
@@ -4,7 +4,13 @@ class FlexMock
4
4
 
5
5
  MISSING_ARG = Object.new
6
6
 
7
- def all_match?(expected_args, actual_args)
7
+ def all_match?(expected_args, expected_kw, expected_block, actual_args, actual_kw, actual_block)
8
+ all_match_args?(expected_args, actual_args) &&
9
+ all_match_kw?(expected_kw, actual_kw) &&
10
+ all_match_block?(expected_block, actual_block)
11
+ end
12
+
13
+ def all_match_args?(expected_args, actual_args)
8
14
  return true if expected_args.nil?
9
15
  return false if actual_args.size > expected_args.size
10
16
  i = 0
@@ -19,6 +25,30 @@ class FlexMock
19
25
  true
20
26
  end
21
27
 
28
+ def all_match_kw?(expected_kw, actual_kw)
29
+ return true if expected_kw.nil?
30
+ return expected_kw === actual_kw if expected_kw.kind_of? HashMatcher
31
+
32
+ matched_expected_k = Set.new
33
+ actual_kw.each do |actual_k, actual_v|
34
+ found_match = expected_kw.find do |k, v|
35
+ match?(k, actual_k) && match?(v, actual_v)
36
+ end
37
+ return false unless found_match
38
+ matched_expected_k << found_match
39
+ end
40
+
41
+ return false unless matched_expected_k.size == expected_kw.keys.size
42
+
43
+ true
44
+ end
45
+
46
+ def all_match_block?(expected_block, actual_block)
47
+ return true if expected_block.nil?
48
+
49
+ !(expected_block ^ actual_block)
50
+ end
51
+
22
52
  # Does the expected argument match the corresponding actual value.
23
53
  def match?(expected, actual)
24
54
  expected === actual ||
@@ -47,10 +47,6 @@ class FlexMock
47
47
  def ducktype(*methods)
48
48
  DuckMatcher.new(methods)
49
49
  end
50
-
51
- def optional_proc
52
- OPTIONAL_PROC_MATCHER
53
- end
54
50
  end
55
51
  extend ArgumentTypes
56
52
 
@@ -11,10 +11,11 @@
11
11
 
12
12
  class FlexMock
13
13
 
14
- CallRecord = Struct.new(:method_name, :args, :block_given, :expectation) do
15
- def matches?(sym, actual_args, options)
14
+ CallRecord = Struct.new(:method_name, :args, :kw, :block, :expectation) do
15
+ def matches?(sym, expected_args, expected_kw, options)
16
16
  method_name == sym &&
17
- ArgumentMatching.all_match?(actual_args, args) &&
17
+ ArgumentMatching.all_match_args?(expected_args, args) &&
18
+ ArgumentMatching.all_match_kw?(expected_kw, kw) &&
18
19
  matches_block?(options[:with_block])
19
20
  end
20
21
 
@@ -22,8 +23,12 @@ class FlexMock
22
23
 
23
24
  def matches_block?(block_option)
24
25
  block_option.nil? ||
25
- (block_option && block_given) ||
26
- (!block_option && !block_given)
26
+ (block_option && block) ||
27
+ (!block_option && !block)
28
+ end
29
+
30
+ def block_given
31
+ block
27
32
  end
28
33
  end
29
34
 
@@ -24,10 +24,10 @@ class FlexMock
24
24
  # * :on_count => n -- If given, the :and validations on only run on the
25
25
  # nth invocation.
26
26
  #
27
- def received?(calls, method_name, args, options)
27
+ def received?(calls, method_name, args, kw, options)
28
28
  count = 0
29
29
  calls.each { |call_record|
30
- if call_record.matches?(method_name, args, options)
30
+ if call_record.matches?(method_name, args, kw, options)
31
31
  count += 1
32
32
  run_additional_validations(call_record, count, options)
33
33
  end
@@ -16,9 +16,9 @@ class FlexMock
16
16
  end
17
17
 
18
18
  # Apply the constraint method to all expectations in the composite.
19
- def method_missing(sym, *args, &block)
19
+ def method_missing(sym, *args, **kw, &block)
20
20
  @expectations.each do |expectation|
21
- expectation.send(sym, *args, &block)
21
+ expectation.send(sym, *args, **kw, &block)
22
22
  end
23
23
  self
24
24
  end
@@ -38,9 +38,9 @@ class FlexMock
38
38
 
39
39
  # Start a new method expectation. The following constraints will be
40
40
  # applied to the new expectation.
41
- def should_receive(*args, &block)
41
+ def should_receive(*args, **kw, &block)
42
42
  @expectations.first.mock.
43
- flexmock_define_expectation(caller, *args, &block)
43
+ flexmock_define_expectation(caller, *args, **kw, &block)
44
44
  end
45
45
 
46
46
  # Return a string representations
data/lib/flexmock/core.rb CHANGED
@@ -137,23 +137,22 @@ class FlexMock
137
137
  end
138
138
 
139
139
  # Handle missing methods by attempting to look up a handler.
140
- def method_missing(sym, *args, &block)
140
+ def method_missing(sym, *args, **kw, &block)
141
141
  FlexMock.verify_mocking_allowed!
142
142
 
143
- enhanced_args = block_given? ? args + [block] : args
144
- call_record = CallRecord.new(sym, enhanced_args, block_given?)
143
+ call_record = CallRecord.new(sym, args, kw, block)
145
144
  @calls << call_record
146
145
  flexmock_wrap do
147
146
  if flexmock_closed?
148
147
  FlexMock.undefined
149
148
  elsif exp = flexmock_expectations_for(sym)
150
- exp.call(args, block, call_record)
149
+ exp.call(args, kw, block, call_record)
151
150
  elsif @base_class && @base_class.flexmock_defined?(sym)
152
151
  FlexMock.undefined
153
152
  elsif @ignore_missing
154
153
  FlexMock.undefined
155
154
  else
156
- super(sym, *args, &block)
155
+ super(sym, *args, **kw, &block)
157
156
  end
158
157
  end
159
158
  end
@@ -167,9 +166,9 @@ class FlexMock
167
166
  end
168
167
 
169
168
  # Find the mock expectation for method sym and arguments.
170
- def flexmock_find_expectation(method_name, *args) # :nodoc:
169
+ def flexmock_find_expectation(method_name, *args, **kw, &block) # :nodoc:
171
170
  if exp = flexmock_expectations_for(method_name)
172
- exp.find_expectation(*args)
171
+ exp.find_expectation(args, kw, block)
173
172
  end
174
173
  end
175
174
 
@@ -195,8 +194,8 @@ class FlexMock
195
194
  CALL_VALIDATOR = CallValidator.new
196
195
 
197
196
  # True if the mock received the given method and arguments.
198
- def flexmock_received?(method_name, args, options={})
199
- CALL_VALIDATOR.received?(@calls, method_name, args, options)
197
+ def flexmock_received?(method_name, args, kw, options = {})
198
+ CALL_VALIDATOR.received?(@calls, method_name, args, kw, options)
200
199
  end
201
200
 
202
201
  # Return the list of calls made on this mock. Used in formatting
@@ -207,13 +206,17 @@ class FlexMock
207
206
 
208
207
  # Invocke the original non-mocked functionality for the given
209
208
  # symbol.
210
- def flexmock_invoke_original(method_name, args, orig_block)
209
+ def flexmock_invoke_original(method_name, args, kw = {})
211
210
  return FlexMock.undefined
212
211
  end
213
212
 
214
213
  # Override the built-in +method+ to include the mocked methods.
215
214
  def method(method_name)
216
- flexmock_expectations_for(method_name) || super
215
+ if (expectations = flexmock_expectations_for(method_name))
216
+ ->(*args, **kw, &block) { expectations.call(args, kw, block) }
217
+ else
218
+ super
219
+ end
217
220
  rescue NameError => ex
218
221
  if ignore_missing?
219
222
  proc { FlexMock.undefined }
@@ -241,15 +244,15 @@ class FlexMock
241
244
  #
242
245
  # See Expectation for a list of declarators that can be used.
243
246
  #
244
- def should_receive(*args)
245
- flexmock_define_expectation(caller, *args)
247
+ def should_receive(*args, **kw)
248
+ flexmock_define_expectation(caller, *args, **kw)
246
249
  end
247
250
 
248
251
  ON_RUBY_20 = (RUBY_VERSION =~ /^2\.0\./)
249
252
 
250
253
  # Using +location+, define the expectations specified by +args+.
251
- def flexmock_define_expectation(location, *args)
252
- @last_expectation = EXP_BUILDER.parse_should_args(self, args) do |method_name|
254
+ def flexmock_define_expectation(location, *args, **kw)
255
+ @last_expectation = EXP_BUILDER.parse_should_args(self, args, kw) do |method_name|
253
256
  exp = flexmock_expectations_for(method_name) || ExpectationDirector.new(method_name)
254
257
  @expectations[method_name] = exp
255
258
  result = Expectation.new(self, method_name, location)
@@ -258,7 +261,7 @@ class FlexMock
258
261
 
259
262
  if @base_class && !@base_class.flexmock_defined?(method_name)
260
263
  if !ON_RUBY_20 || !@base_class.ancestors.include?(Class)
261
- result = ExplicitNeeded.new(result, method_name, @base_class)
264
+ result = ExplicitNeeded.new(result, method_name, @base_class)
262
265
  end
263
266
  end
264
267
  result
@@ -298,8 +301,8 @@ class FlexMock
298
301
  # to explicitly invoke the method_missing logic.
299
302
  def override_existing_method(method_name)
300
303
  sclass.class_eval <<-EOS
301
- def #{method_name}(*args, &block)
302
- method_missing(:#{method_name}, *args, &block)
304
+ def #{method_name}(*args, **kw, &block)
305
+ method_missing(:#{method_name}, *args, **kw, &block)
303
306
  end
304
307
  EOS
305
308
  end
@@ -78,23 +78,42 @@ class FlexMock
78
78
 
79
79
  # Class method to format a method name and argument list as a nice
80
80
  # looking string.
81
- def format_call(sym, args) # :nodoc:
82
- "#{sym}(#{format_args(args)})"
81
+ def format_call(sym, args, kw) # :nodoc:
82
+ "#{sym}(#{format_args(args, kw)})"
83
83
  end
84
84
 
85
85
  # Class method to format a list of args (the part between the
86
86
  # parenthesis).
87
- def format_args(args)
88
- if args
89
- args = args.map do |a|
90
- FlexMock.forbid_mocking("<recursive call to mocked method in #inspect>") do
91
- a.inspect
87
+ def format_args(args, kw)
88
+ args =
89
+ if args
90
+ args = args.map do |a|
91
+ FlexMock.forbid_mocking("<recursive call to mocked method in #inspect>") do
92
+ a.inspect
93
+ end
92
94
  end
95
+ args.join(', ')
96
+ else
97
+ "*args"
93
98
  end
94
- args.join(', ')
95
- else
96
- "*args"
97
- end
99
+
100
+ kw =
101
+ if kw.kind_of? HashMatcher
102
+ kw.inspect
103
+ elsif kw && !kw.empty?
104
+ kw = kw.transform_values do |v|
105
+ FlexMock.forbid_mocking("<recursive call to mocked method in #inspect>") do
106
+ v.inspect
107
+ end
108
+ end
109
+ kw.map { |k, v| "#{k}: #{v}" }.join(', ')
110
+ elsif kw.nil?
111
+ # Don't append **kwargs to signature if ruby version < 3
112
+ # in order to not break existing code still on ruby2
113
+ "**kwargs" unless RUBY_VERSION < "3"
114
+ end
115
+
116
+ [(args unless args.empty?), kw].compact.join(", ")
98
117
  end
99
118
 
100
119
  # Check will assert the block returns true. If it doesn't, an
@@ -37,11 +37,11 @@ class FlexMock
37
37
  @sym = sym
38
38
  @location = location
39
39
  @expected_args = nil
40
- @expected_kw_args = nil
41
- @expected_block = nil
40
+ @expected_kw = nil
42
41
  @count_validators = []
43
42
  @signature_validator = SignatureValidator.new(self)
44
43
  @count_validator_class = ExactCountValidator
44
+ @with_block = nil
45
45
  @actual_count = 0
46
46
  @return_value = nil
47
47
  @return_queue = []
@@ -52,7 +52,7 @@ class FlexMock
52
52
  end
53
53
 
54
54
  def to_s
55
- FlexMock.format_call(@sym, @expected_args)
55
+ FlexMock.format_call(@sym, @expected_args, @expected_kw)
56
56
  end
57
57
 
58
58
  # Return a description of the matching features of the
@@ -64,7 +64,9 @@ class FlexMock
64
64
  #
65
65
  def description
66
66
  result = ["should_receive(#{@sym.inspect})"]
67
- result << ".with(#{FlexMock.format_args(@expected_args)})" if @expected_args
67
+ if @expected_args || @expected_kw
68
+ result << ".with(#{FlexMock.format_args(@expected_args, @expected_kw)})"
69
+ end
68
70
  @count_validators.each do |validator|
69
71
  result << validator.describe
70
72
  end
@@ -85,63 +87,49 @@ class FlexMock
85
87
  FlexMock.framework_adapter.check(e.message) { false }
86
88
  end
87
89
 
88
- def validate_signature(args)
89
- @signature_validator.validate(args)
90
+ def validate_signature(args, kw, block)
91
+ @signature_validator.validate(args, kw, block)
90
92
  rescue SignatureValidator::ValidationFailed => e
91
93
  FlexMock.framework_adapter.check(e.message) { false }
92
94
  end
93
95
 
94
96
  # Verify the current call with the given arguments matches the
95
97
  # expectations recorded in this object.
96
- def verify_call(*args, &block)
98
+ def verify_call(args, kw, block)
97
99
  validate_eligible
98
100
  validate_order
99
- enhanced_args =
100
- if block
101
- args + [block]
102
- else
103
- args
104
- end
105
-
106
- validate_signature(enhanced_args)
101
+ validate_signature(args, kw, block)
107
102
  @actual_count += 1
108
- perform_yielding(args, block)
109
- return_value(args, block)
103
+ perform_yielding(block)
104
+ return_value(args, kw, block)
110
105
  end
111
106
 
112
107
  # Public return value (odd name to avoid accidental use as a
113
108
  # constraint).
114
- def _return_value(args, block) # :nodoc:
115
- return_value(args, block)
109
+ def _return_value(args, kw, block) # :nodoc:
110
+ return_value(args, kw, block)
116
111
  end
117
112
 
118
113
  # Find the return value for this expectation. (private version)
119
- def return_value(args, block)
114
+ def return_value(args, kw, block)
120
115
  case @return_queue.size
121
116
  when 0
122
- ret_block = lambda { |*a| @return_value }
117
+ ret_block = lambda { |*, **| @return_value }
123
118
  when 1
124
119
  ret_block = @return_queue.first
125
120
  else
126
121
  ret_block = @return_queue.shift
127
122
  end
128
-
129
- if @expected_block
130
- ret_block.call(*args, &block)
131
- elsif block && @expected_block.nil?
132
- ret_block.call(*args, block)
133
- else
134
- ret_block.call(*args)
135
- end
123
+ ret_block.call(*args, **kw, &block)
136
124
  end
137
125
  private :return_value
138
126
 
139
127
  # Yield stored values to any blocks given.
140
- def perform_yielding(args, block)
128
+ def perform_yielding(block)
141
129
  @return_value = nil
142
130
  unless @yield_queue.empty?
143
131
  values = (@yield_queue.size == 1) ? @yield_queue.first : @yield_queue.shift
144
- if block
132
+ if block && block.respond_to?(:call)
145
133
  values.each do |v|
146
134
  @return_value = block.call(*v)
147
135
  end
@@ -185,44 +173,14 @@ class FlexMock
185
173
 
186
174
  # Does the argument list match this expectation's argument
187
175
  # specification.
188
- def match_args(args)
189
- expected_args =
190
- if @expected_kw_args
191
- if proc_matcher?(@expected_args&.last) && @expected_block.nil?
192
- @expected_args[0..-2] + [@expected_kw_args, @expected_args[-1]]
193
- else
194
- (@expected_args || []) + [@expected_kw_args]
195
- end
196
- else
197
- @expected_args
198
- end
199
-
200
- if @expected_block
201
- expected_args = (expected_args || []) + [@expected_block]
202
- end
203
-
204
- ArgumentMatching.all_match?(expected_args, args)
205
- end
206
-
207
- def proc_matcher?(obj)
208
- obj == Proc || obj == OPTIONAL_PROC_MATCHER
209
- end
210
-
211
- def with_optional_block
212
- @expected_block = OPTIONAL_PROC_MATCHER
213
- end
214
-
215
- def with_block
216
- @expected_block = Proc
217
- end
218
-
219
- def with_no_block
220
- @expected_block = false
176
+ def match_args(args, kw, block)
177
+ ArgumentMatching.all_match?(@expected_args, @expected_kw, @expected_block, args, kw, block)
221
178
  end
222
179
 
223
180
  # Declare that the method should expect the given argument list.
224
- def with(*args)
181
+ def with(*args, **kw)
225
182
  @expected_args = args
183
+ @expected_kw = kw
226
184
  self
227
185
  end
228
186
 
@@ -235,42 +193,71 @@ class FlexMock
235
193
  # arguments of any type.
236
194
  def with_any_args
237
195
  @expected_args = nil
196
+ @expected_kw = nil
238
197
  self
239
198
  end
240
199
 
241
200
  # Declare that the method can be called with any number of
242
201
  # arguments of any type.
243
- def with_kw_args(matcher)
244
- @expected_kw_args = matcher
202
+ def with_any_kw_args
203
+ @expected_kw = nil
245
204
  self
246
205
  end
247
206
 
248
207
  # Declare that the method can be called with any number of
249
208
  # arguments of any type.
250
- def with_any_kw_args
251
- @expected_kw_args = FlexMock.any
209
+ def with_any_positional_args
210
+ @expected_args = nil
211
+ self
212
+ end
213
+
214
+ # Declare that the method should be called with the given
215
+ # keyword arguments
216
+ def with_kw_args(kw)
217
+ @expected_kw = kw
218
+ self
219
+ end
220
+
221
+ # Declare that the call should have a block
222
+ def with_block
223
+ @expected_block = true
224
+ self
225
+ end
226
+
227
+ # Declare that the call should have a block
228
+ def with_no_block
229
+ @expected_block = false
230
+ self
231
+ end
232
+
233
+ def with_optional_block
234
+ @expected_block = nil
252
235
  self
253
236
  end
254
237
 
255
238
  # Validate general parameters on the call signature
256
239
  def with_signature(
257
- required_arguments: 0, optional_arguments: 0, splat: false,
258
- required_keyword_arguments: [], optional_keyword_arguments: [], keyword_splat: false)
240
+ required_arguments: 0, optional_arguments: 0, splat: false,
241
+ required_keyword_arguments: [], optional_keyword_arguments: [],
242
+ keyword_splat: false
243
+ )
259
244
  @signature_validator = SignatureValidator.new(
260
- self,
261
- required_arguments: required_arguments,
262
- optional_arguments: optional_arguments,
263
- splat: splat,
264
- required_keyword_arguments: required_keyword_arguments,
265
- optional_keyword_arguments: optional_keyword_arguments,
266
- keyword_splat: keyword_splat)
245
+ self,
246
+ required_arguments: required_arguments,
247
+ optional_arguments: optional_arguments,
248
+ splat: splat,
249
+ required_keyword_arguments: required_keyword_arguments,
250
+ optional_keyword_arguments: optional_keyword_arguments,
251
+ keyword_splat: keyword_splat
252
+ )
267
253
  self
268
254
  end
269
255
 
270
256
  # Validate that the passed arguments match the method signature from the
271
257
  # given instance method
272
258
  def with_signature_matching(instance_method)
273
- @signature_validator = SignatureValidator.from_instance_method(self, instance_method)
259
+ @signature_validator =
260
+ SignatureValidator.from_instance_method(self, instance_method)
274
261
  self
275
262
  end
276
263
 
@@ -405,15 +392,9 @@ class FlexMock
405
392
 
406
393
  def pass_thru(&block)
407
394
  block ||= lambda { |value| value }
408
- and_return { |*args, &orig_block|
395
+ and_return { |*args, **kw|
409
396
  begin
410
- if @expected_block.nil? && !orig_block
411
- if Proc === args.last
412
- orig_block = args.last
413
- args = args[0..-2]
414
- end
415
- end
416
- block.call(@mock.flexmock_invoke_original(@sym, args, orig_block))
397
+ block.call(@mock.flexmock_invoke_original(@sym, args, kw))
417
398
  rescue NoMethodError => e
418
399
  if e.name == @sym
419
400
  raise e, "#{e.message} while performing #pass_thru in expectation object #{self}"
@@ -22,12 +22,12 @@ class FlexMock
22
22
  # hashes, and identifies the method names specified by each. As each
23
23
  # method name is identified, create a mock expectation for it using the
24
24
  # supplied block.
25
- def parse_should_args(mock, args, &block) # :nodoc:
25
+ def parse_should_args(mock, args, kw, &block) # :nodoc:
26
26
  result = CompositeExpectation.new
27
27
  args.each do |arg|
28
28
  case arg
29
29
  when Hash
30
- arg.each do |k,v|
30
+ arg.each do |k, v|
31
31
  exp = create_expectation(mock, k, &block).and_return(v)
32
32
  result.add(exp)
33
33
  end
@@ -35,6 +35,12 @@ class FlexMock
35
35
  result.add(create_expectation(mock, arg, &block))
36
36
  end
37
37
  end
38
+
39
+ kw.each do |k, v|
40
+ exp = create_expectation(mock, k, &block).and_return(v)
41
+ result.add(exp)
42
+ end
43
+
38
44
  result
39
45
  end
40
46
 
@@ -86,7 +92,7 @@ class FlexMock
86
92
  names.each do |name|
87
93
  exp = mock.flexmock_find_expectation(name)
88
94
  if exp
89
- next_mock = exp._return_value([], nil)
95
+ next_mock = exp._return_value([], {}, nil)
90
96
  check_proper_mock(next_mock, name)
91
97
  else
92
98
  next_mock = container.flexmock("demeter_#{name}")
@@ -35,18 +35,16 @@ class FlexMock
35
35
  # but at least we will get a good failure message). Finally,
36
36
  # check for expectations that don't have any argument matching
37
37
  # criteria.
38
- def call(args, block = nil, call_record=nil)
39
- find_args = args.dup
40
- find_args << block if block
41
- exp = find_expectation(*find_args)
38
+ def call(args, kw, block, call_record=nil)
39
+ exp = find_expectation(args, kw, block)
42
40
  call_record.expectation = exp if call_record
43
41
  FlexMock.check(
44
42
  proc { "no matching handler found for " +
45
- FlexMock.format_call(@sym, args) +
43
+ FlexMock.format_call(@sym, args, kw) +
46
44
  "\nDefined expectations:\n " +
47
45
  @expectations.map(&:description).join("\n ") }
48
46
  ) { !exp.nil? }
49
- returned_value = exp.verify_call(*args, &block)
47
+ returned_value = exp.verify_call(args, kw, block)
50
48
  returned_value
51
49
  end
52
50
 
@@ -56,11 +54,11 @@ class FlexMock
56
54
  end
57
55
 
58
56
  # Find an expectation matching the given arguments.
59
- def find_expectation(*args) # :nodoc:
57
+ def find_expectation(args, kw, block) # :nodoc:
60
58
  if @expectations.empty?
61
- find_expectation_in(@defaults, *args)
59
+ find_expectation_in(@defaults, args, kw, block)
62
60
  else
63
- find_expectation_in(@expectations, *args)
61
+ find_expectation_in(@expectations, args, kw, block)
64
62
  end
65
63
  end
66
64
 
@@ -86,9 +84,9 @@ class FlexMock
86
84
 
87
85
  private
88
86
 
89
- def find_expectation_in(expectations, *args)
90
- expectations.find { |e| e.match_args(args) && e.eligible? } ||
91
- expectations.find { |e| e.match_args(args) }
87
+ def find_expectation_in(expectations, args, kw, block)
88
+ expectations.find { |e| e.match_args(args, kw, block) && e.eligible? } ||
89
+ expectations.find { |e| e.match_args(args, kw, block) }
92
90
  end
93
91
  end
94
92
 
@@ -23,8 +23,8 @@ class FlexMock
23
23
  end
24
24
 
25
25
  # Save any incoming messages to be played back later.
26
- def method_missing(sym, *args, &block)
27
- @expectations << [sym, args, block]
26
+ def method_missing(sym, *args, **kw, &block)
27
+ @expectations << [sym, args, kw, block]
28
28
  self
29
29
  end
30
30
 
@@ -33,8 +33,8 @@ class FlexMock
33
33
  # call).
34
34
  def apply(mock)
35
35
  obj = mock
36
- @expectations.each do |sym, args, block|
37
- obj = obj.send(sym, *args, &block)
36
+ @expectations.each do |sym, args, kw, block|
37
+ obj = obj.send(sym, *args, **kw, &block)
38
38
  end
39
39
  end
40
40
  end
@@ -31,9 +31,9 @@ class FlexMock
31
31
 
32
32
  WHITELIST = [:with_signature_matching]
33
33
 
34
- def method_missing(sym, *args, &block)
34
+ def method_missing(sym, *args, **kw, &block)
35
35
  if explicit? || WHITELIST.include?(sym)
36
- @expectation.send(sym, *args, &block)
36
+ @expectation.send(sym, *args, **kw, &block)
37
37
  else
38
38
  fail NoMethodError, "Cannot stub methods not defined by the base class\n" +
39
39
  " Method: #{@method_name}\n" +
@@ -150,8 +150,8 @@ class FlexMock
150
150
  # to the result.
151
151
  #
152
152
  # See Expectation for a list of declarators that can be used.
153
- def should_receive(*args)
154
- flexmock_define_expectation(caller, *args)
153
+ def should_receive(*args, **kw)
154
+ flexmock_define_expectation(caller, *args, **kw)
155
155
  end
156
156
 
157
157
  def should_expect(*args)
@@ -161,13 +161,22 @@ class FlexMock
161
161
  # Invoke the original of a mocked method
162
162
  #
163
163
  # Usually called in a #and_return statement
164
- def invoke_original(m, *args, &block)
165
- flexmock_invoke_original(m, args, block)
164
+ def invoke_original(m, *args, **kw, &block)
165
+ if block
166
+ args << block
167
+ end
168
+ flexmock_invoke_original(m, args, kw)
166
169
  end
167
170
 
168
171
  # Whether the given method's original definition has been stored
169
172
  def find_original_method(m)
170
- it = @obj.method(m)
173
+ it =
174
+ if m.respond_to?(:to_str) || m.respond_to?(:to_sym)
175
+ @obj.method(m)
176
+ else
177
+ m
178
+ end
179
+
171
180
  while it && (it.owner != @proxy_definition_module)
172
181
  it = it.super_method
173
182
  end
@@ -200,15 +209,24 @@ class FlexMock
200
209
  @proxy_definition_module.method_defined?(m)
201
210
  end
202
211
 
203
- def flexmock_define_expectation(location, *args)
204
- EXP_BUILDER.parse_should_args(self, args) do |method_name|
212
+ def flexmock_plain_new_method?(m)
213
+ m.name == :new && m.owner == Class
214
+ end
215
+
216
+ def flexmock_define_expectation(location, *args, **kw)
217
+ EXP_BUILDER.parse_should_args(self, args, kw) do |method_name|
205
218
  if !has_proxied_method?(method_name)
206
219
  define_proxy_method(method_name)
207
220
  end
208
221
  ex = @mock.flexmock_define_expectation(location, method_name)
209
222
  if FlexMock.partials_verify_signatures
210
223
  if (existing_method = find_original_method(method_name))
211
- ex.with_signature_matching(existing_method)
224
+ if flexmock_plain_new_method?(existing_method)
225
+ # Look for the signature of `initialize` instead
226
+ ex.with_signature_matching(@obj.instance_method(:initialize))
227
+ else
228
+ ex.with_signature_matching(existing_method)
229
+ end
212
230
  end
213
231
  end
214
232
  ex.mock = self
@@ -216,17 +234,17 @@ class FlexMock
216
234
  end
217
235
  end
218
236
 
219
- def flexmock_find_expectation(*args)
220
- @mock.flexmock_find_expectation(*args)
237
+ def flexmock_find_expectation(*args, **kw, &block)
238
+ @mock.flexmock_find_expectation(*args, **kw, &block)
221
239
  end
222
240
 
223
241
  def add_mock_method(method_name)
224
242
  proxy_module_eval do
225
- define_method(method_name) { |*args, &block|
243
+ define_method(method_name) { |*args, **kw, &block|
226
244
  proxy = __flexmock_proxy or
227
245
  fail "Missing FlexMock proxy " +
228
246
  "(for method_name=#{method_name.inspect}, self=\#{self})"
229
- proxy.send(method_name, *args, &block)
247
+ proxy.send(method_name, *args, **kw, &block)
230
248
  }
231
249
  end
232
250
  end
@@ -262,9 +280,9 @@ class FlexMock
262
280
  end
263
281
 
264
282
  allocators.each do |allocate_method|
265
- flexmock_define_expectation(location, allocate_method).and_return { |*args|
283
+ flexmock_define_expectation(location, allocate_method).and_return { |*args, **kw|
266
284
  create_new_mocked_object(
267
- allocate_method, args, expectation_recorder, block)
285
+ allocate_method, args, kw, expectation_recorder, block)
268
286
  }
269
287
  end
270
288
  expectation_recorder
@@ -276,7 +294,7 @@ class FlexMock
276
294
  expectation_blocks = @initialize_expectation_blocks = Array.new
277
295
  expectation_recorders = @initialize_expectation_recorders = Array.new
278
296
  @initialize_override = Module.new do
279
- define_method :initialize do |*args, &block|
297
+ define_method :initialize do |*args, **kw, &block|
280
298
  if self.class.respond_to?(:__flexmock_proxy) && (mock = self.class.__flexmock_proxy)
281
299
  container = mock.flexmock_container
282
300
  mock = container.flexmock(self)
@@ -287,7 +305,7 @@ class FlexMock
287
305
  r.apply(mock)
288
306
  end
289
307
  end
290
- super(*args, &block)
308
+ super(*args, **kw, &block)
291
309
  end
292
310
  end
293
311
  override = @initialize_override
@@ -317,8 +335,8 @@ class FlexMock
317
335
  # (2) Pass to the block for custom configuration.
318
336
  # (3) Apply any recorded expecations
319
337
  #
320
- def create_new_mocked_object(allocate_method, args, recorder, block)
321
- new_obj = flexmock_invoke_original(allocate_method, args, nil)
338
+ def create_new_mocked_object(allocate_method, args, kw, recorder, block)
339
+ new_obj = flexmock_invoke_original(allocate_method, args, kw)
322
340
  mock = flexmock_container.flexmock(new_obj)
323
341
  block.call(mock) unless block.nil?
324
342
  recorder.apply(mock)
@@ -328,11 +346,15 @@ class FlexMock
328
346
 
329
347
  # Invoke the original definition of method on the object supported by
330
348
  # the stub.
331
- def flexmock_invoke_original(method, args, block)
349
+ def flexmock_invoke_original(method, args, kw)
332
350
  if (original_method = find_original_method(method))
333
- original_method.call(*args, &block)
351
+ if Proc === args.last
352
+ block = args.last
353
+ args = args[0..-2]
354
+ end
355
+ original_method.call(*args, **kw, &block)
334
356
  else
335
- @obj.__send__(:method_missing, method, *args, &block)
357
+ @obj.__send__(:method_missing, method, *args, **kw, &block)
336
358
  end
337
359
  end
338
360
 
@@ -366,8 +388,8 @@ class FlexMock
366
388
  end
367
389
 
368
390
  # Forward to the mock
369
- def flexmock_received?(*args)
370
- @mock.flexmock_received?(*args)
391
+ def flexmock_received?(*args, **kw)
392
+ @mock.flexmock_received?(*args, **kw)
371
393
  end
372
394
 
373
395
  # Forward to the mock
@@ -399,15 +421,15 @@ class FlexMock
399
421
 
400
422
  # Evaluate a block (or string) in the context of the singleton
401
423
  # class of the target partial object.
402
- def target_class_eval(*args, &block)
403
- target_singleton_class.class_eval(*args, &block)
424
+ def target_class_eval(*args, **kw, &block)
425
+ target_singleton_class.class_eval(*args, **kw, &block)
404
426
  end
405
427
 
406
428
  class ProxyDefinitionModule < Module
407
429
  end
408
430
 
409
431
  # Evaluate a block into the module we use to define the proxy methods
410
- def proxy_module_eval(*args, &block)
432
+ def proxy_module_eval(*args, **kw, &block)
411
433
  if !@proxy_definition_module
412
434
  obj = @obj
413
435
  @proxy_definition_module = m = ProxyDefinitionModule.new do
@@ -419,7 +441,7 @@ class FlexMock
419
441
  end
420
442
  target_class_eval { prepend m }
421
443
  end
422
- @proxy_definition_module.class_eval(*args, &block)
444
+ @proxy_definition_module.class_eval(*args, **kw, &block)
423
445
  end
424
446
 
425
447
  # Hide the existing method definition with a singleton defintion
@@ -438,15 +460,15 @@ class FlexMock
438
460
  def define_proxy_method(method_name)
439
461
  if method_name =~ /=$/
440
462
  proxy_module_eval do
441
- define_method(method_name) do |*args, &block|
442
- __flexmock_proxy.mock.__send__(method_name, *args, &block)
463
+ define_method(method_name) do |*args, **kw, &block|
464
+ __flexmock_proxy.mock.__send__(method_name, *args, **kw, &block)
443
465
  end
444
466
  end
445
467
  else
446
468
  proxy_module_eval <<-EOD
447
- def #{method_name}(*args, &block)
469
+ def #{method_name}(*args, **kw, &block)
448
470
  FlexMock.verify_mocking_allowed!
449
- __flexmock_proxy.mock.#{method_name}(*args, &block)
471
+ __flexmock_proxy.mock.#{method_name}(*args, **kw, &block)
450
472
  end
451
473
  EOD
452
474
  end
@@ -1,25 +1,25 @@
1
1
  class FlexMock
2
2
 
3
3
  module SpyDescribers
4
- def spy_description(spy, sym, args, options)
4
+ def spy_description(spy, sym, args, kw, options)
5
5
  result = "have received "
6
- result << FlexMock.format_call(sym, args)
6
+ result << FlexMock.format_call(sym, args, kw)
7
7
  result << times_description(options[:times])
8
8
  result << block_description(options[:with_block])
9
9
  result
10
10
  end
11
11
 
12
- def describe_spy_expectation(spy, sym, args, options={})
13
- describe_spy(spy, sym, args, options)
12
+ def describe_spy_expectation(spy, sym, args, kw, options={})
13
+ describe_spy(spy, sym, args, kw, options)
14
14
  end
15
15
 
16
- def describe_spy_negative_expectation(spy, sym, args, options={})
17
- describe_spy(spy, sym, args, options, " NOT")
16
+ def describe_spy_negative_expectation(spy, sym, args, kw, options={})
17
+ describe_spy(spy, sym, args, kw, options, " NOT")
18
18
  end
19
19
 
20
- def describe_spy(spy, sym, args, options, not_clause="")
20
+ def describe_spy(spy, sym, args, kw, options, not_clause="")
21
21
  result = "expected "
22
- result << FlexMock.format_call(sym, args)
22
+ result << FlexMock.format_call(sym, args, kw)
23
23
  result << " to#{not_clause} be received by " << spy.inspect
24
24
  result << times_description(options[:times])
25
25
  result << block_description(options[:with_block])
@@ -44,7 +44,7 @@ class FlexMock
44
44
  def append_call_record(result, call_record)
45
45
  result <<
46
46
  " " <<
47
- FlexMock.format_call(call_record.method_name, call_record.args)
47
+ FlexMock.format_call(call_record.method_name, call_record.args, call_record.kw)
48
48
  if call_record.expectation
49
49
  result <<
50
50
  " matched by " <<
@@ -4,29 +4,36 @@ class FlexMock
4
4
  module TestUnitAssertions
5
5
  include FlexMock::SpyDescribers
6
6
 
7
- def assert_spy_called(spy, method_name, *args)
8
- _assert_spy_called(false, spy, method_name, *args)
7
+ def assert_spy_called(spy, method_name, *args, **kw)
8
+ _assert_spy_called(false, spy, method_name, *args, **kw)
9
9
  end
10
10
 
11
- def assert_spy_not_called(spy, method_name, *args)
12
- _assert_spy_called(true, spy, method_name, *args)
11
+ def assert_spy_not_called(spy, method_name, *args, **kw)
12
+ _assert_spy_called(true, spy, method_name, *args, **kw)
13
13
  end
14
14
 
15
15
  private
16
16
 
17
- def _assert_spy_called(negative, spy, method_name, *args)
17
+ def _assert_spy_called(negative, spy, method_name, *args, **kw)
18
18
  options = {}
19
19
  if method_name.is_a?(Hash)
20
20
  options = method_name
21
21
  method_name = args.shift
22
22
  end
23
+
24
+ # Prior to ruby3, kw args would be matched in *args
25
+ # thus, expecting any args (:_) implied also expecting
26
+ # any kw args.
27
+ kw = :_ if args == [:_]
28
+
23
29
  args = nil if args == [:_]
24
- bool = spy.flexmock_received?(method_name, args, options)
30
+ kw = nil if kw == :_
31
+ bool = spy.flexmock_received?(method_name, args, kw, options)
25
32
  if negative
26
33
  bool = !bool
27
- message = describe_spy_negative_expectation(spy, method_name, args, options)
34
+ message = describe_spy_negative_expectation(spy, method_name, args, kw, options)
28
35
  else
29
- message = describe_spy_expectation(spy, method_name, args, options)
36
+ message = describe_spy_expectation(spy, method_name, args, kw, options)
30
37
  end
31
38
  assert bool, message
32
39
  end
@@ -212,74 +212,28 @@ class FlexMock
212
212
  #
213
213
  # @param [Array] args
214
214
  # @raise ValidationFailed
215
- def validate(args)
216
- args = args.dup
217
- kw_args = Hash.new
218
-
219
- last_is_proc = false
220
- begin
221
- if args.last.kind_of?(Proc)
222
- args.pop
223
- last_is_proc = true
224
- end
225
- rescue NoMethodError
226
- end
227
-
228
- last_is_kw_hash = false
229
- if expects_keyword_arguments?
230
- last_is_kw_hash =
231
- begin
232
- args.last.kind_of?(Hash)
233
- rescue NoMethodError
234
- end
215
+ def validate(args, kw, block)
216
+ kw ||= Hash.new
235
217
 
236
- if last_is_kw_hash
237
- kw_args = args.pop
238
- elsif requires_keyword_arguments?
239
- raise ValidationFailed, "#{@exp} expects keyword arguments but none were provided"
240
- end
218
+ if expects_keyword_arguments? && requires_keyword_arguments? && kw.empty?
219
+ raise ValidationFailed, "#{@exp} expects keyword arguments but none were provided"
241
220
  end
242
221
 
243
- # There is currently no way to disambiguate "given a block" from "given a
244
- # proc as last argument" ... give some leeway in this case
245
- positional_count = args.size
246
-
247
- if required_arguments > positional_count
248
- if requires_keyword_arguments?
249
- raise ValidationFailed, "#{@exp} expects at least #{required_arguments} positional arguments but got only #{positional_count}"
250
- end
251
-
252
- if (required_arguments - positional_count) == 1 && (last_is_kw_hash || last_is_proc)
253
- if last_is_kw_hash
254
- last_is_kw_hash = false
255
- kw_args = Hash.new
256
- else
257
- last_is_proc = false
258
- end
259
- positional_count += 1
260
- elsif (required_arguments - positional_count) == 2 && (last_is_kw_hash && last_is_proc)
261
- last_is_kw_hash = false
262
- kw_args = Hash.new
263
- last_is_proc = false
264
- positional_count += 2
265
- else
266
- raise ValidationFailed, "#{@exp} expects at least #{required_arguments} positional arguments but got only #{positional_count}"
267
- end
222
+ if required_arguments > args.size
223
+ raise ValidationFailed, "#{@exp} expects at least #{required_arguments} positional arguments but got only #{args.size}"
268
224
  end
269
225
 
270
- if !splat? && (required_arguments + optional_arguments) < positional_count
271
- if !last_is_proc || (required_arguments + optional_arguments) < positional_count - 1
272
- raise ValidationFailed, "#{@exp} expects at most #{required_arguments + optional_arguments} positional arguments but got #{positional_count}"
273
- end
226
+ if !splat? && (required_arguments + optional_arguments) < args.size
227
+ raise ValidationFailed, "#{@exp} expects at most #{required_arguments + optional_arguments} positional arguments but got #{args.size}"
274
228
  end
275
229
 
276
230
  missing_keyword_arguments = required_keyword_arguments.
277
- find_all { |k| !kw_args.has_key?(k) }
231
+ find_all { |k| !kw.has_key?(k) }
278
232
  if !missing_keyword_arguments.empty?
279
233
  raise ValidationFailed, "#{@exp} missing required keyword arguments #{missing_keyword_arguments.map(&:to_s).sort.join(", ")}"
280
234
  end
281
235
  if !keyword_splat?
282
- kw_args.each_key do |k|
236
+ kw.each_key do |k|
283
237
  if !optional_keyword_arguments.include?(k) && !required_keyword_arguments.include?(k)
284
238
  raise ValidationFailed, "#{@exp} given unexpected keyword argument #{k}"
285
239
  end
@@ -313,4 +267,3 @@ class FlexMock
313
267
  end
314
268
  end
315
269
  end
316
-
@@ -1,3 +1,3 @@
1
1
  class FlexMock
2
- VERSION = "2.4.2"
2
+ VERSION = "3.0.0"
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flexmock
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Weirich
8
8
  - Sylvain Joyeux
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-09-16 00:00:00.000000000 Z
12
+ date: 2024-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -157,7 +157,7 @@ homepage: https://github.com/doudou/flexmock
157
157
  licenses:
158
158
  - MIT
159
159
  metadata: {}
160
- post_install_message:
160
+ post_install_message:
161
161
  rdoc_options: []
162
162
  require_paths:
163
163
  - lib
@@ -165,15 +165,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
165
  requirements:
166
166
  - - ">="
167
167
  - !ruby/object:Gem::Version
168
- version: '2.2'
168
+ version: '3.0'
169
169
  required_rubygems_version: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
172
172
  - !ruby/object:Gem::Version
173
173
  version: '0'
174
174
  requirements: []
175
- rubygems_version: 3.1.6
176
- signing_key:
175
+ rubygems_version: 3.4.20
176
+ signing_key:
177
177
  specification_version: 4
178
178
  summary: Simple and Flexible Mock Objects for Testing
179
179
  test_files: []