rspec-expectations 3.11.0 → 3.13.1

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: e651e80dd869915779a72a9ea43b38d20327f3dbfaf94a4851eff7974d1f3d0a
4
- data.tar.gz: e1788055c911b97cbad1b3747fe9b9be005a999e2e97e6c361df4c91fa4fda25
3
+ metadata.gz: de739c3ced3dfe0c29aad887b8aefef44b04b826a0315265289f21f7a9bcf4de
4
+ data.tar.gz: 969d3de594cc6061f2f197df757abb248359d139594ce23087c10f5c565ba88d
5
5
  SHA512:
6
- metadata.gz: ec1b6b68b80fddae764dbf88312817c35c1e76228c29748e2b89d8d9a69d95384aa4fe9daf7b8a650dd307dd32aca13bae590d8960f0989beea67c54f7f6d7d5
7
- data.tar.gz: 7a8a129e74ccec6299ab3af1c728cab2754a1cc98911507704c3f52a01c33b321250bfe715deef835b61963e22c66ec878500d10c6fea93d4fda7cc39b101676
6
+ metadata.gz: 4fde1836ea6689705e559d087433f4f7f3d239555e79e6f9d5f65b3c3d1cccb671e8dd40e60b88ae223fba347d59afc1e502c48f7ccceccb6dfbcf875abd46a7
7
+ data.tar.gz: f68303aaa957bdd48e2062bc0b00c43810740712879a8e93343eb602e58218958133cd9b55a25c4f006fb10fad295b204b404b1b5bf428a945bf5b3c719624ff
checksums.yaml.gz.sig CHANGED
Binary file
data/Changelog.md CHANGED
@@ -1,5 +1,73 @@
1
1
  ### Development
2
- [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.0...3-11-maintenance)
2
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.1...3-13-maintenance)
3
+
4
+ ### 3.13.1 / 2024-06-13
5
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.0...v3.13.1)
6
+
7
+ Bug Fixes:
8
+
9
+ * Fix the "false positive" warning message when using a negated `raise_error` matcher
10
+ with a `RegExp` instance. (Eric Mueller, #1456)
11
+
12
+ ### 3.13.0 / 2024-02-04
13
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.4...v3.13.0)
14
+
15
+ Enhancements:
16
+
17
+ * Update `eq` and `eql` matchers to better highlight difference in string encoding.
18
+ (Alan Foster, #1425)
19
+
20
+ ### 3.12.4 / 2024-02-04
21
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.3...v3.12.4)
22
+
23
+ Bug Fixes:
24
+
25
+ * Fix the diff for redefined `actual` and reassigned `@actual` in compound
26
+ expectations failure messages. (Phil Pirozhkov, #1440)
27
+
28
+ ### 3.12.3 / 2023-04-20
29
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.2...v3.12.3)
30
+
31
+ Bug Fixes:
32
+
33
+ * Fix `include` matcher when fuzzy matching on keys with a hash-like actual which
34
+ has a non standard `key?` method which may raise.
35
+ (Jon Rowe, #1416)
36
+
37
+ ### 3.12.2 / 2023-01-07
38
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.1...v3.12.2)
39
+
40
+ Bug Fixes:
41
+
42
+ * Prevent deprecation warning when using the `exist` matcher with `Dir`.
43
+ (Steve Dierker, #1398)
44
+
45
+ ### 3.12.1 / 2022-12-16
46
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.0...v3.12.1)
47
+
48
+ Bug Fixes:
49
+
50
+ * Pass keyword arguments through to aliased (and thus negated) matchers. (Jon Rowe, #1394)
51
+ * When handling failures in an aggregated_failures block (or example) prevent
52
+ the failure list leaking out. (Maciek Rząsa, #1392)
53
+
54
+ ### 3.12.0 / 2022-10-26
55
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.1...v3.12.0)
56
+
57
+ Enhancements:
58
+
59
+ * Add `an_array_matching` alias for `match_array` to improve readability as an argument
60
+ matcher. (Mark Schneider, #1361)
61
+
62
+ ### 3.11.1 / 2022-09-12
63
+ [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.0...v3.11.1)
64
+
65
+ Bug Fixes:
66
+
67
+ * Allow the `contain_exactly` matcher to be reused by resetting its
68
+ internals on `matches?` (@bclayman-sq, #1326)
69
+ * Using the exist matcher on `FileTest` no longer produces a deprecation warning.
70
+ (Ryo Nakamura, #1383)
3
71
 
4
72
  ### 3.11.0 / 2022-02-09
5
73
  [Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.2...v3.11.0)
@@ -296,10 +364,8 @@ Enhancements:
296
364
  can cause uses of `super` to trigger infinite recursion. (Myron Marston, #816)
297
365
  * Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and
298
366
  `SystemExit`. It is dangerous to interfere with these. (Myron Marston, #845)
299
- * Add `#with_captures` to the
300
- [match matcher](https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/match-matcher)
301
- which allows a user to specify expected captures when matching a regex
302
- against a string. (Sam Phippen, #848)
367
+ * Add `#with_captures` to the match matcher which allows a user to specify expected
368
+ captures when matching a regex against a string. (Sam Phippen, #848)
303
369
  * Always print compound failure messages in the multi-line form. Trying
304
370
  to print it all on a single line didn't read very well. (Myron Marston, #859)
305
371
 
data/README.md CHANGED
@@ -13,7 +13,9 @@ If you want to use rspec-expectations with rspec, just install the rspec gem
13
13
  and RubyGems will also install rspec-expectations for you (along with
14
14
  rspec-core and rspec-mocks):
15
15
 
16
- gem install rspec
16
+ ```shell
17
+ gem install rspec
18
+ ```
17
19
 
18
20
  Want to run against the `main` branch? You'll need to include the dependent
19
21
  RSpec repos as well. Add the following to your `Gemfile`:
@@ -27,7 +29,9 @@ end
27
29
  If you want to use rspec-expectations with another tool, like Test::Unit,
28
30
  Minitest, or Cucumber, you can install it directly:
29
31
 
30
- gem install rspec-expectations
32
+ ```shell
33
+ gem install rspec-expectations
34
+ ```
31
35
 
32
36
  ## Contributing
33
37
 
@@ -67,8 +71,10 @@ The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`,
67
71
  expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then
68
72
  the example passes. If not, it fails with a message like:
69
73
 
70
- expected: #<Money @value=5.55 @currency=:USD>
71
- got: #<Money @value=1.11 @currency=:USD>
74
+ ```
75
+ expected: #<Money @value=5.55 @currency=:USD>
76
+ got: #<Money @value=1.11 @currency=:USD>
77
+ ```
72
78
 
73
79
  ## Built-in matchers
74
80
 
@@ -30,7 +30,7 @@ module RSpec
30
30
  "appropriate failure_message[_when_negated] method to return a string?"
31
31
  end
32
32
 
33
- message = ::RSpec::Matchers::ExpectedsForMultipleDiffs.from(expected).message_with_diff(message, differ, actual)
33
+ message = ::RSpec::Matchers::MultiMatcherDiff.from(expected, actual).message_with_diff(message, differ)
34
34
 
35
35
  RSpec::Support.notify_failure(RSpec::Expectations::ExpectationNotMetError.new message)
36
36
  end
@@ -4,6 +4,21 @@ module RSpec
4
4
  class FailureAggregator
5
5
  attr_reader :block_label, :metadata
6
6
 
7
+ # @private
8
+ class AggregatedFailure
9
+ # @private
10
+ MESSAGE =
11
+ 'AggregatedFailure: This method caused a failure which has been ' \
12
+ 'suppressed to be aggregated into our failure report by returning ' \
13
+ 'this value, further errors can be ignored.'
14
+
15
+ def inspect
16
+ MESSAGE
17
+ end
18
+ end
19
+
20
+ AGGREGATED_FAILURE = AggregatedFailure.new
21
+
7
22
  def aggregate
8
23
  RSpec::Support.with_failure_notifier(self) do
9
24
  begin
@@ -48,6 +63,8 @@ module RSpec
48
63
  @seen_source_ids[source_id] = true
49
64
  assign_backtrace(failure) unless failure.backtrace
50
65
  failures << failure
66
+
67
+ AGGREGATED_FAILURE
51
68
  end
52
69
 
53
70
  private
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Expectations
3
3
  # @private
4
4
  module Version
5
- STRING = '3.11.0'
5
+ STRING = '3.13.1'
6
6
  end
7
7
  end
8
8
  end
@@ -99,14 +99,14 @@ module RSpec
99
99
  # by going through the effort of defining a negated matcher.
100
100
  #
101
101
  # However, if the override didn't actually change anything, then we
102
- # should return the opposite failure message instead -- the overriden
102
+ # should return the opposite failure message instead -- the overridden
103
103
  # message is going to be confusing if we return it as-is, as it represents
104
104
  # the non-negated failure message for a negated match (or vice versa).
105
105
  def optimal_failure_message(same, inverted)
106
106
  if DefaultFailureMessages.has_default_failure_messages?(@base_matcher)
107
107
  base_message = @base_matcher.__send__(same)
108
- overriden = @description_block.call(base_message)
109
- return overriden if overriden != base_message
108
+ overridden = @description_block.call(base_message)
109
+ return overridden if overridden != base_message
110
110
  end
111
111
 
112
112
  @base_matcher.__send__(inverted)
@@ -161,6 +161,47 @@ module RSpec
161
161
 
162
162
  include HashFormatting
163
163
 
164
+ # @private
165
+ module StringEncodingFormatting
166
+ # @api private
167
+ # @return [Boolean] True if the actual and expected string encoding are different.
168
+ # i.e. the failure may be related to encoding differences and the encoding
169
+ # should be shown to the user. false otherwise.
170
+ if String.method_defined?(:encoding)
171
+ def string_encoding_differs?
172
+ actual.is_a?(String) && expected.is_a?(String) && actual.encoding != expected.encoding
173
+ end
174
+ else
175
+ # @api private
176
+ # @return [Boolean] False always as the curent Ruby version does not support String encoding
177
+ def string_encoding_differs?
178
+ false
179
+ end
180
+ end
181
+ module_function :string_encoding_differs?
182
+
183
+ if String.method_defined?(:encoding)
184
+ # @api private
185
+ # Formats a String's encoding as a human readable string
186
+ # @param value [String]
187
+ # @return [String]
188
+ def format_encoding(value)
189
+ "#<Encoding:#{value.encoding.name}>"
190
+ end
191
+ else
192
+ # @api private
193
+ # Formats a String's encoding as a human readable string
194
+ # @param _value [String]
195
+ # @return [nil] nil as the curent Ruby version does not support String encoding
196
+ def format_encoding(_value)
197
+ nil
198
+ end
199
+ end
200
+ module_function :format_encoding
201
+ end
202
+
203
+ include StringEncodingFormatting
204
+
164
205
  # @api private
165
206
  # Provides default implementations of failure messages, based on the `description`.
166
207
  module DefaultFailureMessages
@@ -51,10 +51,10 @@ module RSpec
51
51
  end
52
52
 
53
53
  # @api private
54
- # @return [RSpec::Matchers::ExpectedsForMultipleDiffs]
54
+ # @return [RSpec::Matchers::MultiMatcherDiff]
55
55
  def expected
56
56
  return nil unless evaluator
57
- ::RSpec::Matchers::ExpectedsForMultipleDiffs.for_many_matchers(diffable_matcher_list)
57
+ ::RSpec::Matchers::MultiMatcherDiff.for_many_matchers(diffable_matcher_list)
58
58
  end
59
59
 
60
60
  protected
@@ -171,7 +171,7 @@ module RSpec
171
171
  @match_results.fetch(matcher) do
172
172
  raise ArgumentError, "Your #{matcher.description} has no match " \
173
173
  "results, this can occur when an unexpected call stack or " \
174
- "local jump occurs. Prehaps one of your matchers needs to " \
174
+ "local jump occurs. Perhaps one of your matchers needs to " \
175
175
  "declare `expects_call_stack_jump?` as `true`?"
176
176
  end
177
177
  end
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  module BuiltIn
4
- # rubocop:disable ClassLength
4
+ # rubocop:disable Metrics/ClassLength
5
5
  # @api private
6
6
  # Provides the implementation for `contain_exactly` and `match_array`.
7
7
  # Not intended to be instantiated directly.
@@ -31,6 +31,14 @@ module RSpec
31
31
  "contain exactly#{list}"
32
32
  end
33
33
 
34
+ def matches?(actual)
35
+ @pairings_maximizer = nil
36
+ @best_solution = nil
37
+ @extra_items = nil
38
+ @missing_items = nil
39
+ super(actual)
40
+ end
41
+
34
42
  private
35
43
 
36
44
  def generate_failure_message
@@ -296,7 +304,7 @@ module RSpec
296
304
  end
297
305
  end
298
306
  end
299
- # rubocop:enable ClassLength
307
+ # rubocop:enable Metrics/ClassLength
300
308
  end
301
309
  end
302
310
  end
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Matchers
3
3
  module BuiltIn
4
4
  # @api private
5
- # Asbtract class to implement `once`, `at_least` and other
5
+ # Abstract class to implement `once`, `at_least` and other
6
6
  # count constraints.
7
7
  module CountExpectation
8
8
  # @api public
@@ -8,7 +8,11 @@ module RSpec
8
8
  # @api private
9
9
  # @return [String]
10
10
  def failure_message
11
- "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n"
11
+ if string_encoding_differs?
12
+ "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using ==)\n"
13
+ else
14
+ "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n"
15
+ end
12
16
  end
13
17
 
14
18
  # @api private
@@ -8,7 +8,11 @@ module RSpec
8
8
  # @api private
9
9
  # @return [String]
10
10
  def failure_message
11
- "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n"
11
+ if string_encoding_differs?
12
+ "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using eql?)\n"
13
+ else
14
+ "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n"
15
+ end
12
16
  end
13
17
 
14
18
  # @api private
@@ -81,7 +81,7 @@ module RSpec
81
81
  end
82
82
 
83
83
  def deprecated(predicate, actual)
84
- predicate == :exists? && File == actual
84
+ predicate == :exists? && (File == actual || FileTest == actual || Dir == actual)
85
85
  end
86
86
  end
87
87
  end
@@ -153,8 +153,15 @@ module RSpec
153
153
  def actual_hash_has_key?(expected_key)
154
154
  # We check `key?` first for perf:
155
155
  # `key?` is O(1), but `any?` is O(N).
156
- actual.key?(expected_key) ||
157
- actual.keys.any? { |key| values_match?(expected_key, key) }
156
+
157
+ has_exact_key =
158
+ begin
159
+ actual.key?(expected_key)
160
+ rescue
161
+ false
162
+ end
163
+
164
+ has_exact_key || actual.keys.any? { |key| values_match?(expected_key, key) }
158
165
  end
159
166
 
160
167
  def actual_collection_includes?(expected_item)
@@ -4,8 +4,8 @@ module RSpec
4
4
  # @api private
5
5
  # Provides the implementation for `raise_error`.
6
6
  # Not intended to be instantiated directly.
7
- # rubocop:disable ClassLength
8
- # rubocop:disable RescueException
7
+ # rubocop:disable Metrics/ClassLength
8
+ # rubocop:disable Lint/RescueException
9
9
  class RaiseError
10
10
  include Composable
11
11
 
@@ -13,6 +13,10 @@ module RSpec
13
13
  # argument. We can't use `nil` for that because we need to warn when `nil` is
14
14
  # passed in a different way. It's an Object, not a Module, since Module's `===`
15
15
  # does not evaluate to true when compared to itself.
16
+ #
17
+ # Note; this _is_ the default value supplied for expected_error_or_message, but
18
+ # because there are two method-calls involved, that default is actually supplied
19
+ # in the definition of the _matcher_ method, `RSpec::Matchers#raise_error`
16
20
  UndefinedValue = Object.new.freeze
17
21
 
18
22
  def initialize(expected_error_or_message, expected_message, &block)
@@ -25,7 +29,7 @@ module RSpec
25
29
  when nil, UndefinedValue
26
30
  @expected_error = Exception
27
31
  @expected_message = expected_message
28
- when String
32
+ when String, Regexp
29
33
  @expected_error = Exception
30
34
  @expected_message = expected_error_or_message
31
35
  else
@@ -43,7 +47,7 @@ module RSpec
43
47
  self
44
48
  end
45
49
 
46
- # rubocop:disable MethodLength
50
+ # rubocop:disable Metrics/MethodLength
47
51
  # @private
48
52
  def matches?(given_proc, negative_expectation=false, &block)
49
53
  @given_proc = given_proc
@@ -73,7 +77,7 @@ module RSpec
73
77
 
74
78
  expectation_matched?
75
79
  end
76
- # rubocop:enable MethodLength
80
+ # rubocop:enable Metrics/MethodLength
77
81
 
78
82
  # @private
79
83
  def does_not_match?(given_proc)
@@ -264,8 +268,8 @@ module RSpec
264
268
  warning if @actual_error
265
269
  end
266
270
  end
267
- # rubocop:enable RescueException
268
- # rubocop:enable ClassLength
271
+ # rubocop:enable Lint/RescueException
272
+ # rubocop:enable Metrics/ClassLength
269
273
  end
270
274
  end
271
275
  end
@@ -13,7 +13,7 @@ module RSpec
13
13
  @caught_symbol = @caught_arg = nil
14
14
  end
15
15
 
16
- # rubocop:disable MethodLength
16
+ # rubocop:disable Metrics/MethodLength
17
17
  # @private
18
18
  def matches?(given_proc)
19
19
  @block = given_proc
@@ -48,7 +48,7 @@ module RSpec
48
48
  rescue => other_exception
49
49
  raise
50
50
  ensure
51
- # rubocop:disable EnsureReturn
51
+ # rubocop:disable Lint/EnsureReturn
52
52
  unless other_exception
53
53
  if @expected_symbol.nil?
54
54
  return !!@caught_symbol
@@ -60,10 +60,10 @@ module RSpec
60
60
  end
61
61
  end
62
62
  end
63
- # rubocop:enable EnsureReturn
63
+ # rubocop:enable Lint/EnsureReturn
64
64
  end
65
65
  end
66
- # rubocop:enable MethodLength
66
+ # rubocop:enable Metrics/MethodLength
67
67
 
68
68
  def does_not_match?(given_proc)
69
69
  !matches?(given_proc) && Proc === given_proc
@@ -83,7 +83,7 @@ module RSpec
83
83
  RSpec::Support::ObjectFormatter.format(object)
84
84
  end
85
85
 
86
- # Transforms the given data structue (typically a hash or array)
86
+ # Transforms the given data structure (typically a hash or array)
87
87
  # into a new data structure that, when `#inspect` is called on it,
88
88
  # will provide descriptions of any contained matchers rather than
89
89
  # the normal `#inspect` output.
@@ -4,7 +4,7 @@ module RSpec
4
4
  module Matchers
5
5
  # Defines the custom matcher DSL.
6
6
  module DSL
7
- # Defines a matcher alias. The returned matcher's `description` will be overriden
7
+ # Defines a matcher alias. The returned matcher's `description` will be overridden
8
8
  # to reflect the phrasing of the new name, which will be used in failure messages
9
9
  # when passed as an argument to another matcher in a composed matcher expression.
10
10
  #
@@ -25,7 +25,7 @@ module RSpec
25
25
  # @param old_name [Symbol] the original name for the matcher
26
26
  # @param options [Hash] options for the aliased matcher
27
27
  # @option options [Class] :klass the ruby class to use as the decorator. (Not normally used).
28
- # @yield [String] optional block that, when given, is used to define the overriden
28
+ # @yield [String] optional block that, when given, is used to define the overridden
29
29
  # logic. The yielded arg is the original description or failure message. If no
30
30
  # block is provided, a default override is used based on the old and new names.
31
31
  # @see RSpec::Matchers
@@ -40,10 +40,11 @@ module RSpec
40
40
  matcher.matcher_name = new_name if matcher.respond_to?(:matcher_name=)
41
41
  klass.new(matcher, description_override)
42
42
  end
43
+ ruby2_keywords new_name if respond_to?(:ruby2_keywords, true)
43
44
  end
44
45
 
45
46
  # Defines a negated matcher. The returned matcher's `description` and `failure_message`
46
- # will be overriden to reflect the phrasing of the new name, and the match logic will
47
+ # will be overridden to reflect the phrasing of the new name, and the match logic will
47
48
  # be based on the original matcher but negated.
48
49
  #
49
50
  # @example
@@ -53,7 +54,7 @@ module RSpec
53
54
  #
54
55
  # @param negated_name [Symbol] the name for the negated matcher
55
56
  # @param base_name [Symbol] the name of the original matcher that will be negated
56
- # @yield [String] optional block that, when given, is used to define the overriden
57
+ # @yield [String] optional block that, when given, is used to define the overridden
57
58
  # logic. The yielded arg is the original description or failure message. If no
58
59
  # block is provided, a default override is used based on the old and new names.
59
60
  # @see RSpec::Matchers
@@ -122,7 +123,7 @@ module RSpec
122
123
  #
123
124
  # By default the match block will swallow expectation errors (e.g.
124
125
  # caused by using an expectation such as `expect(1).to eq 2`), if you
125
- # with to allow these to bubble up, pass in the option
126
+ # wish to allow these to bubble up, pass in the option
126
127
  # `:notify_expectation_failures => true`.
127
128
  #
128
129
  # @param [Hash] options for defining the behavior of the match block.
@@ -151,7 +152,7 @@ module RSpec
151
152
  #
152
153
  # By default the match block will swallow expectation errors (e.g.
153
154
  # caused by using an expectation such as `expect(1).to eq 2`), if you
154
- # with to allow these to bubble up, pass in the option
155
+ # wish to allow these to bubble up, pass in the option
155
156
  # `:notify_expectation_failures => true`.
156
157
  #
157
158
  # @param [Hash] options for defining the behavior of the match block.
@@ -197,7 +198,7 @@ module RSpec
197
198
  end
198
199
  end
199
200
 
200
- # Customizes the failure messsage to use when this matcher is
201
+ # Customizes the failure message to use when this matcher is
201
202
  # asked to positively match. Only use this when the message
202
203
  # generated by default doesn't suit your needs.
203
204
  #
@@ -216,7 +217,7 @@ module RSpec
216
217
  define_user_override(__method__, definition)
217
218
  end
218
219
 
219
- # Customize the failure messsage to use when this matcher is asked
220
+ # Customize the failure message to use when this matcher is asked
220
221
  # to negatively match. Only use this when the message generated by
221
222
  # default doesn't suit your needs.
222
223
  #
@@ -330,7 +331,7 @@ module RSpec
330
331
  # - Defines the named method using a user-provided block
331
332
  # in @user_method_defs, which is included as an ancestor
332
333
  # in the singleton class in which we eval the `define` block.
333
- # - Defines an overriden definition for the same method
334
+ # - Defines an overridden definition for the same method
334
335
  # usign the provided `our_def` block.
335
336
  # - Provides a default `our_def` block for the common case
336
337
  # of needing to call the user's definition with `@actual`
@@ -1,8 +1,34 @@
1
1
  module RSpec
2
2
  module Matchers
3
+ # Provides a base class with as little methods as possible, so that
4
+ # most methods can be delegated via `method_missing`.
5
+ #
6
+ # On Ruby 2.0+ BasicObject could be used for this purpose, but it
7
+ # introduce some extra complexity with constant resolution, so the
8
+ # BlankSlate pattern was prefered.
9
+ # @private
10
+ class BaseDelegator
11
+ kept_methods = [
12
+ # Methods that raise warnings if removed.
13
+ :__id__, :__send__, :object_id,
14
+
15
+ # Methods that are explicitly undefined in some subclasses.
16
+ :==, :===,
17
+
18
+ # Methods we keep on purpose.
19
+ :class, :respond_to?, :__method__, :method, :dup,
20
+ :clone, :initialize_dup, :initialize_copy, :initialize_clone,
21
+ ]
22
+ instance_methods.each do |method|
23
+ unless kept_methods.include?(method.to_sym)
24
+ undef_method(method)
25
+ end
26
+ end
27
+ end
28
+
3
29
  # Provides the necessary plumbing to wrap a matcher with a decorator.
4
30
  # @private
5
- class MatcherDelegator
31
+ class MatcherDelegator < BaseDelegator
6
32
  include Composable
7
33
  attr_reader :base_matcher
8
34
 
@@ -1,9 +1,9 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  # @api private
4
- # Handles list of expected values when there is a need to render
5
- # multiple diffs. Also can handle one value.
6
- class ExpectedsForMultipleDiffs
4
+ # Handles list of expected and actual value pairs when there is a need
5
+ # to render multiple diffs. Also can handle one pair.
6
+ class MultiMatcherDiff
7
7
  # @private
8
8
  # Default diff label when there is only one matcher in diff
9
9
  # output
@@ -19,22 +19,23 @@ module RSpec
19
19
 
20
20
  # @api private
21
21
  # Wraps provided expected value in instance of
22
- # ExpectedForMultipleDiffs. If provided value is already an
23
- # ExpectedForMultipleDiffs then it just returns it.
22
+ # MultiMatcherDiff. If provided value is already an
23
+ # MultiMatcherDiff then it just returns it.
24
24
  # @param [Any] expected value to be wrapped
25
- # @return [RSpec::Matchers::ExpectedsForMultipleDiffs]
26
- def self.from(expected)
25
+ # @param [Any] actual value
26
+ # @return [RSpec::Matchers::MultiMatcherDiff]
27
+ def self.from(expected, actual)
27
28
  return expected if self === expected
28
- new([[expected, DEFAULT_DIFF_LABEL]])
29
+ new([[expected, DEFAULT_DIFF_LABEL, actual]])
29
30
  end
30
31
 
31
32
  # @api private
32
33
  # Wraps provided matcher list in instance of
33
- # ExpectedForMultipleDiffs.
34
+ # MultiMatcherDiff.
34
35
  # @param [Array<Any>] matchers list of matchers to wrap
35
- # @return [RSpec::Matchers::ExpectedsForMultipleDiffs]
36
+ # @return [RSpec::Matchers::MultiMatcherDiff]
36
37
  def self.for_many_matchers(matchers)
37
- new(matchers.map { |m| [m.expected, diff_label_for(m)] })
38
+ new(matchers.map { |m| [m.expected, diff_label_for(m), m.actual] })
38
39
  end
39
40
 
40
41
  # @api private
@@ -42,10 +43,9 @@ module RSpec
42
43
  # factory and actual value if there are any
43
44
  # @param [String] message original failure message
44
45
  # @param [Proc] differ
45
- # @param [Any] actual value
46
46
  # @return [String]
47
- def message_with_diff(message, differ, actual)
48
- diff = diffs(differ, actual)
47
+ def message_with_diff(message, differ)
48
+ diff = diffs(differ)
49
49
  message = "#{message}\n#{diff}" unless diff.empty?
50
50
  message
51
51
  end
@@ -65,8 +65,8 @@ module RSpec
65
65
  end
66
66
  end
67
67
 
68
- def diffs(differ, actual)
69
- @expected_list.map do |(expected, diff_label)|
68
+ def diffs(differ)
69
+ @expected_list.map do |(expected, diff_label, actual)|
70
70
  diff = differ.diff(actual, expected)
71
71
  next if diff.strip.empty?
72
72
  if diff == "\e[0m\n\e[0m"
@@ -10,7 +10,7 @@ RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relat
10
10
  dsl
11
11
  matcher_delegator
12
12
  aliased_matcher
13
- expecteds_for_multiple_diffs
13
+ multi_matcher_diff
14
14
  ].each { |file| RSpec::Support.require_rspec_matchers(file) }
15
15
 
16
16
  # RSpec's top level namespace. All of rspec-expectations is contained
@@ -36,7 +36,7 @@ module RSpec
36
36
  # expect([]).to be_empty # => [].empty?() | passes
37
37
  # expect([]).not_to be_empty # => [].empty?() | fails
38
38
  #
39
- # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
39
+ # In addition to prefixing the predicate matchers with "be_", you can also use "be_a_"
40
40
  # and "be_an_", making your specs read much more naturally:
41
41
  #
42
42
  # expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes
@@ -704,7 +704,7 @@ module RSpec
704
704
 
705
705
  # An alternate form of `contain_exactly` that accepts
706
706
  # the expected contents as a single array arg rather
707
- # that splatted out as individual items.
707
+ # than splatted out as individual items.
708
708
  #
709
709
  # @example
710
710
  # expect(results).to contain_exactly(1, 2)
@@ -715,6 +715,9 @@ module RSpec
715
715
  def match_array(items)
716
716
  contain_exactly(*items)
717
717
  end
718
+ alias_matcher :an_array_matching, :match_array do |desc|
719
+ desc.sub("contain exactly", "an array containing exactly")
720
+ end
718
721
 
719
722
  # With no arg, passes if the block outputs `to_stdout` or `to_stderr`.
720
723
  # With a string, passes if the block outputs that specific string `to_stdout` or `to_stderr`.
@@ -753,8 +756,8 @@ module RSpec
753
756
 
754
757
  # With no args, matches if any error is raised.
755
758
  # With a named error, matches only if that specific error is raised.
756
- # With a named error and messsage specified as a String, matches only if both match.
757
- # With a named error and messsage specified as a Regexp, matches only if both match.
759
+ # With a named error and message specified as a String, matches only if both match.
760
+ # With a named error and message specified as a Regexp, matches only if both match.
758
761
  # Pass an optional block to perform extra verifications on the exception matched
759
762
  #
760
763
  # @example
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-expectations
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Baker
@@ -45,7 +45,7 @@ cert_chain:
45
45
  ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
46
46
  F3MdtaDehhjC
47
47
  -----END CERTIFICATE-----
48
- date: 2022-02-09 00:00:00.000000000 Z
48
+ date: 2024-06-13 00:00:00.000000000 Z
49
49
  dependencies:
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: rspec-support
@@ -53,14 +53,14 @@ dependencies:
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: 3.11.0
56
+ version: 3.13.0
57
57
  type: :runtime
58
58
  prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: 3.11.0
63
+ version: 3.13.0
64
64
  - !ruby/object:Gem::Dependency
65
65
  name: diff-lcs
66
66
  requirement: !ruby/object:Gem::Requirement
@@ -193,17 +193,17 @@ files:
193
193
  - lib/rspec/matchers/composable.rb
194
194
  - lib/rspec/matchers/dsl.rb
195
195
  - lib/rspec/matchers/english_phrasing.rb
196
- - lib/rspec/matchers/expecteds_for_multiple_diffs.rb
197
196
  - lib/rspec/matchers/fail_matchers.rb
198
197
  - lib/rspec/matchers/generated_descriptions.rb
199
198
  - lib/rspec/matchers/matcher_delegator.rb
200
199
  - lib/rspec/matchers/matcher_protocol.rb
200
+ - lib/rspec/matchers/multi_matcher_diff.rb
201
201
  homepage: https://github.com/rspec/rspec-expectations
202
202
  licenses:
203
203
  - MIT
204
204
  metadata:
205
205
  bug_tracker_uri: https://github.com/rspec/rspec-expectations/issues
206
- changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3.11.0/Changelog.md
206
+ changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3.13.1/Changelog.md
207
207
  documentation_uri: https://rspec.info/documentation/
208
208
  mailing_list_uri: https://groups.google.com/forum/#!forum/rspec
209
209
  source_code_uri: https://github.com/rspec/rspec-expectations
@@ -223,8 +223,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
223
  - !ruby/object:Gem::Version
224
224
  version: '0'
225
225
  requirements: []
226
- rubygems_version: 3.3.3
226
+ rubygems_version: 3.3.26
227
227
  signing_key:
228
228
  specification_version: 4
229
- summary: rspec-expectations-3.11.0
229
+ summary: rspec-expectations-3.13.1
230
230
  test_files: []
metadata.gz.sig CHANGED
Binary file