rspec-expectations 3.12.3 → 3.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +44 -1
- data/README.md +10 -4
- data/lib/rspec/expectations/block_snippet_extractor.rb +2 -0
- data/lib/rspec/expectations/configuration.rb +5 -0
- data/lib/rspec/expectations/fail_with.rb +1 -1
- data/lib/rspec/expectations/failure_aggregator.rb +7 -0
- data/lib/rspec/expectations/handler.rb +4 -5
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers/built_in/base_matcher.rb +45 -18
- data/lib/rspec/matchers/built_in/change.rb +2 -0
- data/lib/rspec/matchers/built_in/compound.rb +6 -3
- data/lib/rspec/matchers/built_in/contain_exactly.rb +2 -0
- data/lib/rspec/matchers/built_in/count_expectation.rb +2 -0
- data/lib/rspec/matchers/built_in/eq.rb +5 -1
- data/lib/rspec/matchers/built_in/eql.rb +5 -1
- data/lib/rspec/matchers/built_in/has.rb +29 -2
- data/lib/rspec/matchers/built_in/include.rb +5 -0
- data/lib/rspec/matchers/built_in/match.rb +2 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +5 -1
- data/lib/rspec/matchers/built_in/satisfy.rb +2 -0
- data/lib/rspec/matchers/english_phrasing.rb +2 -0
- data/lib/rspec/matchers/matcher_delegator.rb +27 -1
- data/lib/rspec/matchers/{expecteds_for_multiple_diffs.rb → multi_matcher_diff.rb} +16 -16
- data/lib/rspec/matchers.rb +3 -1
- data.tar.gz.sig +0 -0
- metadata +8 -8
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2326091f61f5fccf3b86b2275c850340614475381f32a9f22417cb9f59b80ab3
|
4
|
+
data.tar.gz: 7602b8b98d0dc9fecc754156a01686a131fedd6d43fe1b8ce8f689f0fba3b469
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21d9a95f4e9cb3fa1b7fb99419861bc90a39ee33b4fa183a1018ab351d830168bd93fb02e00452344e1c8d9824bc3d0543b988e42288396c8a3091b9fc5d6f9c
|
7
|
+
data.tar.gz: ec4864365250340370d370af68dee725f3d018e414e57506d21d173e9d0a69a9df258f7d7a11e8f2ff583f4060348a76bb3251aa09a29add0ddee6fb2b0d4192
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,5 +1,48 @@
|
|
1
1
|
### Development
|
2
|
-
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.3...3-13-maintenance)
|
3
|
+
|
4
|
+
### 3.13.3 / 2024-09-07
|
5
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.2...v3.13.3)
|
6
|
+
|
7
|
+
Bug Fixes:
|
8
|
+
|
9
|
+
* Fix passing a regular expression to the `include` matcher without a count constraint.
|
10
|
+
(Jon Rowe, #1485)
|
11
|
+
|
12
|
+
### 3.13.2 / 2024-08-20
|
13
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.1...v3.13.2)
|
14
|
+
|
15
|
+
Bug Fixes:
|
16
|
+
|
17
|
+
* When using null object doubles, prevent typos triggering dynamic matchers.
|
18
|
+
(Eric Mueller, #1455)
|
19
|
+
* Use `RSpec.warning` for an expectation warning rather than `Kernel.warn`. (Jon Rowe, #1472)
|
20
|
+
* Prevent mismatched use of block and value matchers in compound expectations. (Phil Pirozhkov, #1476)
|
21
|
+
* Raise an error when passing no arguments to the `include` matcher. (Eric Mueller, #1479)
|
22
|
+
|
23
|
+
### 3.13.1 / 2024-06-13
|
24
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.0...v3.13.1)
|
25
|
+
|
26
|
+
Bug Fixes:
|
27
|
+
|
28
|
+
* Fix the "false positive" warning message when using a negated `raise_error` matcher
|
29
|
+
with a `RegExp` instance. (Eric Mueller, #1456)
|
30
|
+
|
31
|
+
### 3.13.0 / 2024-02-04
|
32
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.4...v3.13.0)
|
33
|
+
|
34
|
+
Enhancements:
|
35
|
+
|
36
|
+
* Update `eq` and `eql` matchers to better highlight difference in string encoding.
|
37
|
+
(Alan Foster, #1425)
|
38
|
+
|
39
|
+
### 3.12.4 / 2024-02-04
|
40
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.3...v3.12.4)
|
41
|
+
|
42
|
+
Bug Fixes:
|
43
|
+
|
44
|
+
* Fix the diff for redefined `actual` and reassigned `@actual` in compound
|
45
|
+
expectations failure messages. (Phil Pirozhkov, #1440)
|
3
46
|
|
4
47
|
### 3.12.3 / 2023-04-20
|
5
48
|
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.2...v3.12.3)
|
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
|
-
|
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
|
-
|
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
|
-
|
71
|
-
|
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
|
|
@@ -46,11 +46,13 @@ module RSpec
|
|
46
46
|
RSpec.world.source_from_file(file_path)
|
47
47
|
end
|
48
48
|
else
|
49
|
+
# :nocov:
|
49
50
|
RSpec::Support.require_rspec_support 'source'
|
50
51
|
def source
|
51
52
|
raise TargetNotFoundError unless File.exist?(file_path)
|
52
53
|
@source ||= RSpec::Support::Source.from_file(file_path)
|
53
54
|
end
|
55
|
+
# :nocov:
|
54
56
|
end
|
55
57
|
|
56
58
|
def file_path
|
@@ -89,6 +89,7 @@ module RSpec
|
|
89
89
|
::RSpec.configuration.color_enabled?
|
90
90
|
end
|
91
91
|
else
|
92
|
+
# :nocov:
|
92
93
|
# Indicates whether or not diffs should be colored.
|
93
94
|
# Delegates to rspec-core's color option if rspec-core
|
94
95
|
# is loaded; otherwise you can set it here.
|
@@ -100,8 +101,11 @@ module RSpec
|
|
100
101
|
def color?
|
101
102
|
defined?(@color) && @color
|
102
103
|
end
|
104
|
+
# :nocov:
|
103
105
|
end
|
104
106
|
|
107
|
+
# :nocov: Because this is only really _useful_ on 1.8, and hard to test elsewhere.
|
108
|
+
#
|
105
109
|
# Adds `should` and `should_not` to the given classes
|
106
110
|
# or modules. This can be used to ensure `should` works
|
107
111
|
# properly on things like proxy objects (particular
|
@@ -114,6 +118,7 @@ module RSpec
|
|
114
118
|
Expectations::Syntax.enable_should(mod)
|
115
119
|
end
|
116
120
|
end
|
121
|
+
# :nocov:
|
117
122
|
|
118
123
|
# Sets or gets the backtrace formatter. The backtrace formatter should
|
119
124
|
# implement `#format_backtrace(Array<String>)`. This is used
|
@@ -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::
|
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
|
@@ -6,6 +6,10 @@ module RSpec
|
|
6
6
|
|
7
7
|
# @private
|
8
8
|
class AggregatedFailure
|
9
|
+
# :nocov:
|
10
|
+
# `inspect` was apparently used by some versions early in ruby 3 while constructing
|
11
|
+
# NoMethodError, but seems to be no longer.
|
12
|
+
#
|
9
13
|
# @private
|
10
14
|
MESSAGE =
|
11
15
|
'AggregatedFailure: This method caused a failure which has been ' \
|
@@ -15,6 +19,7 @@ module RSpec
|
|
15
19
|
def inspect
|
16
20
|
MESSAGE
|
17
21
|
end
|
22
|
+
# :nocov:
|
18
23
|
end
|
19
24
|
|
20
25
|
AGGREGATED_FAILURE = AggregatedFailure.new
|
@@ -75,11 +80,13 @@ module RSpec
|
|
75
80
|
# a backtrace that has a continuous common section with the raised `MultipleExpectationsNotMetError`,
|
76
81
|
# so that rspec-core's truncation logic can work properly on it to list the backtrace
|
77
82
|
# relative to the `aggregate_failures` block.
|
83
|
+
# :nocov:
|
78
84
|
def assign_backtrace(failure)
|
79
85
|
raise failure
|
80
86
|
rescue failure.class => e
|
81
87
|
failure.set_backtrace(e.backtrace)
|
82
88
|
end
|
89
|
+
# :nocov:
|
83
90
|
else
|
84
91
|
# Using `caller` performs better (and is simpler) than `raise` on most Rubies.
|
85
92
|
def assign_backtrace(failure)
|
@@ -4,11 +4,10 @@ module RSpec
|
|
4
4
|
module ExpectationHelper
|
5
5
|
def self.check_message(msg)
|
6
6
|
unless msg.nil? || msg.respond_to?(:to_str) || msg.respond_to?(:call)
|
7
|
-
|
8
|
-
"
|
9
|
-
msg.inspect
|
10
|
-
|
11
|
-
].join
|
7
|
+
RSpec.warning(
|
8
|
+
"ignoring the provided expectation message argument" \
|
9
|
+
"(#{ msg.inspect }) since it is not a string or a proc"
|
10
|
+
)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
@@ -124,24 +124,6 @@ module RSpec
|
|
124
124
|
end
|
125
125
|
private_class_method :underscore
|
126
126
|
|
127
|
-
private
|
128
|
-
|
129
|
-
def assert_ivars(*expected_ivars)
|
130
|
-
return unless (expected_ivars - present_ivars).any?
|
131
|
-
ivar_list = EnglishPhrasing.list(expected_ivars)
|
132
|
-
raise "#{self.class.name} needs to supply#{ivar_list}"
|
133
|
-
end
|
134
|
-
|
135
|
-
if RUBY_VERSION.to_f < 1.9
|
136
|
-
# :nocov:
|
137
|
-
def present_ivars
|
138
|
-
instance_variables.map(&:to_sym)
|
139
|
-
end
|
140
|
-
# :nocov:
|
141
|
-
else
|
142
|
-
alias present_ivars instance_variables
|
143
|
-
end
|
144
|
-
|
145
127
|
# @private
|
146
128
|
module HashFormatting
|
147
129
|
# `{ :a => 5, :b => 2 }.inspect` produces:
|
@@ -161,6 +143,51 @@ module RSpec
|
|
161
143
|
|
162
144
|
include HashFormatting
|
163
145
|
|
146
|
+
# @private
|
147
|
+
module StringEncodingFormatting
|
148
|
+
# @api private
|
149
|
+
# @return [Boolean] True if the actual and expected string encoding are different.
|
150
|
+
# i.e. the failure may be related to encoding differences and the encoding
|
151
|
+
# should be shown to the user. false otherwise.
|
152
|
+
if String.method_defined?(:encoding)
|
153
|
+
def string_encoding_differs?
|
154
|
+
actual.is_a?(String) && expected.is_a?(String) && actual.encoding != expected.encoding
|
155
|
+
end
|
156
|
+
else
|
157
|
+
# @api private
|
158
|
+
# @return [Boolean] False always as the curent Ruby version does not support String encoding
|
159
|
+
# :nocov:
|
160
|
+
def string_encoding_differs?
|
161
|
+
false
|
162
|
+
end
|
163
|
+
# :nocov:
|
164
|
+
end
|
165
|
+
module_function :string_encoding_differs?
|
166
|
+
|
167
|
+
if String.method_defined?(:encoding)
|
168
|
+
# @api private
|
169
|
+
# Formats a String's encoding as a human readable string
|
170
|
+
# @param value [String]
|
171
|
+
# @return [String]
|
172
|
+
def format_encoding(value)
|
173
|
+
"#<Encoding:#{value.encoding.name}>"
|
174
|
+
end
|
175
|
+
else
|
176
|
+
# @api private
|
177
|
+
# Formats a String's encoding as a human readable string
|
178
|
+
# @param _value [String]
|
179
|
+
# @return [nil] nil as the curent Ruby version does not support String encoding
|
180
|
+
# :nocov:
|
181
|
+
def format_encoding(_value)
|
182
|
+
nil
|
183
|
+
end
|
184
|
+
# :nocov:
|
185
|
+
end
|
186
|
+
module_function :format_encoding
|
187
|
+
end
|
188
|
+
|
189
|
+
include StringEncodingFormatting
|
190
|
+
|
164
191
|
# @api private
|
165
192
|
# Provides default implementations of failure messages, based on the `description`.
|
166
193
|
module DefaultFailureMessages
|
@@ -51,10 +51,10 @@ module RSpec
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# @api private
|
54
|
-
# @return [RSpec::Matchers::
|
54
|
+
# @return [RSpec::Matchers::MultiMatcherDiff]
|
55
55
|
def expected
|
56
56
|
return nil unless evaluator
|
57
|
-
::RSpec::Matchers::
|
57
|
+
::RSpec::Matchers::MultiMatcherDiff.for_many_matchers(diffable_matcher_list)
|
58
58
|
end
|
59
59
|
|
60
60
|
protected
|
@@ -77,8 +77,11 @@ module RSpec
|
|
77
77
|
def match(_expected, actual)
|
78
78
|
evaluator_klass = if supports_block_expectations? && Proc === actual
|
79
79
|
NestedEvaluator
|
80
|
-
|
80
|
+
elsif supports_value_expectations?
|
81
81
|
SequentialEvaluator
|
82
|
+
else
|
83
|
+
# Can't raise an ArgumentError in this context, as it's rescued
|
84
|
+
raise "Block and value matchers can't be combined in a compound expectation (#{matcher_1.description}, #{matcher_2.description})"
|
82
85
|
end
|
83
86
|
|
84
87
|
@evaluator = evaluator_klass.new(actual, matcher_1, matcher_2)
|
@@ -108,12 +108,14 @@ module RSpec
|
|
108
108
|
end
|
109
109
|
|
110
110
|
if RUBY_VERSION == "1.8.7"
|
111
|
+
# :nocov:
|
111
112
|
def to_a_disallowed?(object)
|
112
113
|
case object
|
113
114
|
when NilClass, String then true
|
114
115
|
else Kernel == RSpec::Support.method_handle_for(object, :to_a).owner
|
115
116
|
end
|
116
117
|
end
|
118
|
+
# :nocov:
|
117
119
|
else
|
118
120
|
def to_a_disallowed?(object)
|
119
121
|
NilClass === object
|
@@ -8,7 +8,11 @@ module RSpec
|
|
8
8
|
# @api private
|
9
9
|
# @return [String]
|
10
10
|
def failure_message
|
11
|
-
|
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
|
-
|
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
|
@@ -46,8 +46,27 @@ module RSpec
|
|
46
46
|
|
47
47
|
private
|
48
48
|
|
49
|
+
# Catch a semi-frequent typo - if you have strict_predicate_matchers disabled and
|
50
|
+
# expect(spy).to have_receieveddd(:foo) it would be evergreen - the dynamic matcher
|
51
|
+
# queries `has_receiveddd?`, the spy _fakes_ the method, returning its (truthy) self.
|
52
|
+
if defined?(RSpec::Mocks::Double)
|
53
|
+
def really_responds_to?(method)
|
54
|
+
if RSpec::Mocks::Double === @actual
|
55
|
+
@actual.respond_to?(method) && methods_include?(method)
|
56
|
+
else
|
57
|
+
@actual.respond_to?(method)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
else
|
61
|
+
# :nocov:
|
62
|
+
def really_responds_to?(method)
|
63
|
+
@actual.respond_to?(method)
|
64
|
+
end
|
65
|
+
# :nocov:
|
66
|
+
end
|
67
|
+
|
49
68
|
def predicate_accessible?
|
50
|
-
|
69
|
+
really_responds_to?(predicate)
|
51
70
|
end
|
52
71
|
|
53
72
|
# support 1.8.7, evaluate once at load time for performance
|
@@ -56,11 +75,19 @@ module RSpec
|
|
56
75
|
def private_predicate?
|
57
76
|
@actual.private_methods.include? predicate.to_s
|
58
77
|
end
|
78
|
+
|
79
|
+
def methods_include?(method)
|
80
|
+
@actual.methods.include?(method.to_s)
|
81
|
+
end
|
59
82
|
# :nocov:
|
60
83
|
else
|
61
84
|
def private_predicate?
|
62
85
|
@actual.private_methods.include? predicate
|
63
86
|
end
|
87
|
+
|
88
|
+
def methods_include?(method)
|
89
|
+
@actual.methods.include?(method)
|
90
|
+
end
|
64
91
|
end
|
65
92
|
|
66
93
|
def predicate_result
|
@@ -155,7 +182,7 @@ module RSpec
|
|
155
182
|
end
|
156
183
|
|
157
184
|
def predicate_accessible?
|
158
|
-
super ||
|
185
|
+
super || really_responds_to?(present_tense_predicate)
|
159
186
|
end
|
160
187
|
|
161
188
|
def present_tense_predicate
|
@@ -13,6 +13,7 @@ module RSpec
|
|
13
13
|
|
14
14
|
# @api private
|
15
15
|
def initialize(*expecteds)
|
16
|
+
raise(ArgumentError, 'include() is not supported, please supply an argument') if expecteds.empty?
|
16
17
|
@expecteds = expecteds
|
17
18
|
end
|
18
19
|
|
@@ -165,6 +166,7 @@ module RSpec
|
|
165
166
|
end
|
166
167
|
|
167
168
|
def actual_collection_includes?(expected_item)
|
169
|
+
return actual.scan(expected_item).size > 0 if Regexp === expected_item && String === actual
|
168
170
|
return true if actual.include?(expected_item)
|
169
171
|
|
170
172
|
# String lacks an `any?` method...
|
@@ -174,9 +176,11 @@ module RSpec
|
|
174
176
|
end
|
175
177
|
|
176
178
|
if RUBY_VERSION < '1.9'
|
179
|
+
# :nocov:
|
177
180
|
def count_enumerable(expected_item)
|
178
181
|
actual.select { |value| values_match?(expected_item, value) }.size
|
179
182
|
end
|
183
|
+
# :nocov:
|
180
184
|
else
|
181
185
|
def count_enumerable(expected_item)
|
182
186
|
actual.count { |value| values_match?(expected_item, value) }
|
@@ -197,6 +201,7 @@ module RSpec
|
|
197
201
|
|
198
202
|
def diff_would_wrongly_highlight_matched_item?
|
199
203
|
return false unless actual.is_a?(String) && expected.is_a?(Array)
|
204
|
+
return false if Regexp === expecteds.first
|
200
205
|
|
201
206
|
lines = actual.split("\n")
|
202
207
|
expected.any? do |str|
|
@@ -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
|
@@ -45,12 +45,14 @@ module RSpec
|
|
45
45
|
# So here we replace `Kernel#Array` with our own warning-free implementation for 1.8.7.
|
46
46
|
# @private
|
47
47
|
# rubocop:disable Naming/MethodName
|
48
|
+
# :nocov:
|
48
49
|
def self.Array(obj)
|
49
50
|
case obj
|
50
51
|
when Array then obj
|
51
52
|
else [obj]
|
52
53
|
end
|
53
54
|
end
|
55
|
+
# :nocov:
|
54
56
|
# rubocop:enable Naming/MethodName
|
55
57
|
end
|
56
58
|
end
|
@@ -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
|
5
|
-
# multiple diffs. Also can handle one
|
6
|
-
class
|
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
|
-
#
|
23
|
-
#
|
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
|
-
# @
|
26
|
-
|
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
|
-
#
|
34
|
+
# MultiMatcherDiff.
|
34
35
|
# @param [Array<Any>] matchers list of matchers to wrap
|
35
|
-
# @return [RSpec::Matchers::
|
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
|
48
|
-
diff = diffs(differ
|
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
|
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"
|
data/lib/rspec/matchers.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -1018,6 +1018,7 @@ module RSpec
|
|
1018
1018
|
# than _before_, like `append_features`. It's important we check this before
|
1019
1019
|
# in order to find the cases where it was already previously included.
|
1020
1020
|
# @api private
|
1021
|
+
# :nocov:
|
1021
1022
|
def append_features(mod)
|
1022
1023
|
return super if mod < self # `mod < self` indicates a re-inclusion.
|
1023
1024
|
|
@@ -1038,6 +1039,7 @@ module RSpec
|
|
1038
1039
|
|
1039
1040
|
super
|
1040
1041
|
end
|
1042
|
+
# :nocov:
|
1041
1043
|
end
|
1042
1044
|
end
|
1043
1045
|
end
|
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.
|
4
|
+
version: 3.13.3
|
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:
|
48
|
+
date: 2024-09-07 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.
|
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.
|
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.
|
206
|
+
changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3.13.3/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.
|
226
|
+
rubygems_version: 3.4.19
|
227
227
|
signing_key:
|
228
228
|
specification_version: 4
|
229
|
-
summary: rspec-expectations-3.
|
229
|
+
summary: rspec-expectations-3.13.3
|
230
230
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|