rspec-expectations 3.8.6 → 3.9.4
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.tar.gz.sig +0 -0
- data/Changelog.md +56 -0
- data/README.md +35 -20
- data/lib/rspec/expectations/handler.rb +2 -2
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +27 -22
- data/lib/rspec/matchers/built_in/be.rb +15 -2
- data/lib/rspec/matchers/built_in/be_within.rb +2 -2
- data/lib/rspec/matchers/built_in/compound.rb +6 -1
- data/lib/rspec/matchers/built_in/has.rb +1 -0
- data/lib/rspec/matchers/built_in/have_attributes.rb +1 -1
- data/lib/rspec/matchers/built_in/respond_to.rb +37 -3
- data/lib/rspec/matchers/built_in/yield.rb +25 -16
- data/lib/rspec/matchers/dsl.rb +16 -3
- data/lib/rspec/matchers/english_phrasing.rb +1 -1
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +16 -7
- metadata +24 -10
- 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: 0a7b90c1caeec07d53054eb0536482494c2584e6d7cb0fc9cfd3493ebc6b27a7
|
4
|
+
data.tar.gz: 2eed511b0562ee702eb71bda98058c61d9ddda6c7b0337adde7acd72ddfb81df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d0ea4666034e2901450f23fe706d1258f0b2c37ac7edd823477e31eae7c6d56e597a0b728cea0fe5f12ab80ee43ac4ed1a5c203ef34f66d180b40713adedf81
|
7
|
+
data.tar.gz: 3b42d8706be59eb0dd511497941c34cebaff7476394f3f1ca80326d26c362bf3b37cca520ae0c6002a8efe167ee3fe7707e41e53072ac000c8c2a89f960fa6c0
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,3 +1,59 @@
|
|
1
|
+
### 3.9.4 / 2020-10-29
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4)
|
3
|
+
|
4
|
+
Bug Fixes:
|
5
|
+
|
6
|
+
* Fix regression with `be_` and `have_` matchers and arguments implementing `to_hash`
|
7
|
+
were they would act like keywords and be cast to a hash. (Jon Rowe, #1222)
|
8
|
+
|
9
|
+
### 3.9.3 / 2020-10-23
|
10
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.2...v3.9.3)
|
11
|
+
|
12
|
+
Bug Fixes:
|
13
|
+
|
14
|
+
* Swap the comparison of the delta vs the expected for the `be_within` matcher allowing
|
15
|
+
more complicated oobjects to be compared providing they provide `abs` and other
|
16
|
+
comparison methods. (Kelly Stannard, #1182)
|
17
|
+
* Properly format expected in the description of the `be_within` matcher. (Jon Rowe, #1185)
|
18
|
+
* Remove warning when using keyword arguments with `be_` and `have_` matchers on 2.7.x
|
19
|
+
(Jon Rowe, #1187)
|
20
|
+
* Prevent formatting a single hash as a list of key value pairs in default failure messages
|
21
|
+
for custom matches (fixes formatting in `EnglishPhrasing#list`). (Robert Eshleman, #1193)
|
22
|
+
* Prevent errors from causing false positives when using `be <operator>` comparison, e.g.
|
23
|
+
`expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, #1208)
|
24
|
+
|
25
|
+
### 3.9.2 / 2020-05-08
|
26
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2)
|
27
|
+
|
28
|
+
Bug Fixes:
|
29
|
+
|
30
|
+
* Issue a proper `ArgumentError` when invalid arguments are given to `yield_control`
|
31
|
+
modifiers such as `at_least` et al. (Marc-André Lafortune, #1167)
|
32
|
+
* Prevent Ruby 2.7 keyword arguments warning from being issued by custom
|
33
|
+
matcher definitions. (Jon Rowe, #1176)
|
34
|
+
|
35
|
+
### 3.9.1 / 2020-03-13
|
36
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.0...v3.9.1)
|
37
|
+
|
38
|
+
Bug Fixes:
|
39
|
+
|
40
|
+
* Issue an improved warning when using `respond_to(...).with(n).arguments` and ignore
|
41
|
+
the warning when using with `have_attributes(...)`. (Jon Rowe, #1164)
|
42
|
+
|
43
|
+
### 3.9.0 / 2019-10-08
|
44
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.6...v3.9.0)
|
45
|
+
|
46
|
+
Enhancements:
|
47
|
+
|
48
|
+
* The `respond_to` matcher now uses the signature from `initialize` to validate checks
|
49
|
+
for `new` (unless `new` is non standard). (Jon Rowe, #1072)
|
50
|
+
* Generated descriptions for matchers now use `is expected to` rather than `should` in
|
51
|
+
line with our preferred DSL. (Pete Johns, #1080, rspec/rspec-core#2572)
|
52
|
+
* Add the ability to re-raise expectation errors when matching
|
53
|
+
with `match_when_negated` blocks. (Jon Rowe, #1130)
|
54
|
+
* Add a warning when an empty diff is produce due to identical inspect output.
|
55
|
+
(Benoit Tigeot, #1126)
|
56
|
+
|
1
57
|
### 3.8.6 / 2019-10-07
|
2
58
|
|
3
59
|
Bug Fixes:
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# RSpec Expectations [](http://travis-ci.org/rspec/rspec-expectations) [](https://codeclimate.com/github/rspec/rspec-expectations)
|
2
2
|
|
3
3
|
RSpec::Expectations lets you express expected outcomes on an object in an
|
4
4
|
example.
|
@@ -15,12 +15,12 @@ rspec-core and rspec-mocks):
|
|
15
15
|
|
16
16
|
gem install rspec
|
17
17
|
|
18
|
-
Want to run against the `
|
18
|
+
Want to run against the `main` branch? You'll need to include the dependent
|
19
19
|
RSpec repos as well. Add the following to your `Gemfile`:
|
20
20
|
|
21
21
|
```ruby
|
22
22
|
%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
|
23
|
-
gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => '
|
23
|
+
gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main'
|
24
24
|
end
|
25
25
|
```
|
26
26
|
|
@@ -175,30 +175,45 @@ expect(1..10).to cover(3)
|
|
175
175
|
### Collection membership
|
176
176
|
|
177
177
|
```ruby
|
178
|
-
|
178
|
+
# exact order, entire collection
|
179
|
+
expect(actual).to eq(expected)
|
180
|
+
|
181
|
+
# exact order, partial collection (based on an exact position)
|
179
182
|
expect(actual).to start_with(expected)
|
180
183
|
expect(actual).to end_with(expected)
|
181
184
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
+
# any order, entire collection
|
186
|
+
expect(actual).to match_array(expected)
|
187
|
+
|
188
|
+
# You can also express this by passing the expected elements
|
189
|
+
# as individual arguments
|
190
|
+
expect(actual).to contain_exactly(expected_element1, expected_element2)
|
191
|
+
|
192
|
+
# any order, partial collection
|
193
|
+
expect(actual).to include(expected)
|
185
194
|
```
|
186
195
|
|
187
196
|
#### Examples
|
188
197
|
|
189
198
|
```ruby
|
190
|
-
expect([1, 2, 3]).to
|
191
|
-
expect([1, 2, 3]).to include(1,
|
192
|
-
expect([1, 2, 3]).to
|
193
|
-
expect([1, 2, 3]).to start_with(1,
|
194
|
-
expect([1, 2, 3]).to
|
195
|
-
expect([1, 2, 3]).to end_with(
|
196
|
-
expect(
|
197
|
-
expect(
|
198
|
-
expect("this string").to
|
199
|
-
expect("this string").to
|
200
|
-
expect(
|
201
|
-
expect([1, 2, 3]).to
|
199
|
+
expect([1, 2, 3]).to eq([1, 2, 3]) # Order dependent equality check
|
200
|
+
expect([1, 2, 3]).to include(1) # Exact ordering, partial collection matches
|
201
|
+
expect([1, 2, 3]).to include(2, 3) #
|
202
|
+
expect([1, 2, 3]).to start_with(1) # As above, but from the start of the collection
|
203
|
+
expect([1, 2, 3]).to start_with(1, 2) #
|
204
|
+
expect([1, 2, 3]).to end_with(3) # As above but from the end of the collection
|
205
|
+
expect([1, 2, 3]).to end_with(2, 3) #
|
206
|
+
expect({:a => 'b'}).to include(:a => 'b') # Matching within hashes
|
207
|
+
expect("this string").to include("is str") # Matching within strings
|
208
|
+
expect("this string").to start_with("this") #
|
209
|
+
expect("this string").to end_with("ring") #
|
210
|
+
expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches
|
211
|
+
expect([1, 2, 3]).to match_array([3, 2, 1]) #
|
212
|
+
|
213
|
+
# Order dependent compound matchers
|
214
|
+
expect(
|
215
|
+
[{:a => 'hash'},{:a => 'another'}]
|
216
|
+
).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')])
|
202
217
|
```
|
203
218
|
|
204
219
|
## `should` syntax
|
@@ -212,7 +227,7 @@ actual.should be > 3
|
|
212
227
|
[1, 2, 3].should_not include 4
|
213
228
|
```
|
214
229
|
|
215
|
-
See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/
|
230
|
+
See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/main/Should.md)
|
216
231
|
|
217
232
|
## Compound Matcher Expressions
|
218
233
|
|
@@ -52,7 +52,7 @@ module RSpec
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def self.verb
|
55
|
-
|
55
|
+
'is expected to'
|
56
56
|
end
|
57
57
|
|
58
58
|
def self.should_method
|
@@ -82,7 +82,7 @@ module RSpec
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def self.verb
|
85
|
-
|
85
|
+
'is expected not to'
|
86
86
|
end
|
87
87
|
|
88
88
|
def self.should_method
|
data/lib/rspec/matchers.rb
CHANGED
@@ -238,7 +238,7 @@ module RSpec
|
|
238
238
|
# best to find a more positive name for the negated form, such as
|
239
239
|
# `avoid_changing` rather than `not_change`.
|
240
240
|
#
|
241
|
-
module Matchers
|
241
|
+
module Matchers # rubocop:disable Metrics/ModuleLength
|
242
242
|
extend ::RSpec::Matchers::DSL
|
243
243
|
|
244
244
|
# @!macro [attach] alias_matcher
|
@@ -963,6 +963,7 @@ module RSpec
|
|
963
963
|
super
|
964
964
|
end
|
965
965
|
end
|
966
|
+
ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
|
966
967
|
|
967
968
|
if RUBY_VERSION.to_f >= 1.9
|
968
969
|
def respond_to_missing?(method, *)
|
@@ -1003,31 +1004,35 @@ module RSpec
|
|
1003
1004
|
is_a_matcher?(obj) && obj.respond_to?(:description)
|
1004
1005
|
end
|
1005
1006
|
|
1006
|
-
|
1007
|
-
|
1008
|
-
# Note that `included` doesn't work for this because it is triggered
|
1009
|
-
# _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
|
1010
|
-
# than _before_, like `append_features`. It's important we check this before
|
1011
|
-
# in order to find the cases where it was already previously included.
|
1012
|
-
def self.append_features(mod)
|
1013
|
-
return super if mod < self # `mod < self` indicates a re-inclusion.
|
1007
|
+
class << self
|
1008
|
+
private
|
1014
1009
|
|
1015
|
-
|
1016
|
-
|
1010
|
+
if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9'
|
1011
|
+
# Note that `included` doesn't work for this because it is triggered
|
1012
|
+
# _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
|
1013
|
+
# than _before_, like `append_features`. It's important we check this before
|
1014
|
+
# in order to find the cases where it was already previously included.
|
1015
|
+
# @api private
|
1016
|
+
def append_features(mod)
|
1017
|
+
return super if mod < self # `mod < self` indicates a re-inclusion.
|
1017
1018
|
|
1018
|
-
|
1019
|
-
|
1019
|
+
subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self }
|
1020
|
+
return super unless subclasses.any?
|
1020
1021
|
|
1021
|
-
|
1022
|
-
|
1023
|
-
"which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \
|
1024
|
-
"(https://redmine.ruby-lang.org/issues/3351). To work around this, " \
|
1025
|
-
"either upgrade to MRI 2.0+, include a dup of the module (e.g. " \
|
1026
|
-
"`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \
|
1027
|
-
"before it is included in subclasses (#{subclasses}). See " \
|
1028
|
-
"https://github.com/rspec/rspec-expectations/issues/814 for more info"
|
1022
|
+
subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor.
|
1023
|
+
subclasses = subclasses.map { |s| "`#{s}`" }.join(", ")
|
1029
1024
|
|
1030
|
-
|
1025
|
+
RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \
|
1026
|
+
"after previously being included in subclasses (#{subclasses}), " \
|
1027
|
+
"which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \
|
1028
|
+
"(https://redmine.ruby-lang.org/issues/3351). To work around this, " \
|
1029
|
+
"either upgrade to MRI 2.0+, include a dup of the module (e.g. " \
|
1030
|
+
"`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \
|
1031
|
+
"before it is included in subclasses (#{subclasses}). See " \
|
1032
|
+
"https://github.com/rspec/rspec-expectations/issues/814 for more info"
|
1033
|
+
|
1034
|
+
super
|
1035
|
+
end
|
1031
1036
|
end
|
1032
1037
|
end
|
1033
1038
|
end
|
@@ -143,8 +143,13 @@ module RSpec
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def matches?(actual)
|
146
|
-
|
147
|
-
|
146
|
+
perform_match(actual)
|
147
|
+
rescue ArgumentError, NoMethodError
|
148
|
+
false
|
149
|
+
end
|
150
|
+
|
151
|
+
def does_not_match?(actual)
|
152
|
+
!perform_match(actual)
|
148
153
|
rescue ArgumentError, NoMethodError
|
149
154
|
false
|
150
155
|
end
|
@@ -173,6 +178,13 @@ module RSpec
|
|
173
178
|
def description
|
174
179
|
"be #{@operator} #{expected_to_sentence}#{args_to_sentence}"
|
175
180
|
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def perform_match(actual)
|
185
|
+
@actual = actual
|
186
|
+
@actual.__send__ @operator, @expected
|
187
|
+
end
|
176
188
|
end
|
177
189
|
|
178
190
|
# @api private
|
@@ -186,6 +198,7 @@ module RSpec
|
|
186
198
|
@args = args
|
187
199
|
@block = block
|
188
200
|
end
|
201
|
+
ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
|
189
202
|
|
190
203
|
def matches?(actual, &block)
|
191
204
|
@actual = actual
|
@@ -23,7 +23,7 @@ module RSpec
|
|
23
23
|
# a percent comparison.
|
24
24
|
def percent_of(expected)
|
25
25
|
@expected = expected
|
26
|
-
@tolerance = @
|
26
|
+
@tolerance = @expected.abs * @delta / 100.0
|
27
27
|
@unit = '%'
|
28
28
|
self
|
29
29
|
end
|
@@ -50,7 +50,7 @@ module RSpec
|
|
50
50
|
# @api private
|
51
51
|
# @return [String]
|
52
52
|
def description
|
53
|
-
"be within #{@delta}#{@unit} of #{
|
53
|
+
"be within #{@delta}#{@unit} of #{expected_formatted}"
|
54
54
|
end
|
55
55
|
|
56
56
|
private
|
@@ -154,7 +154,12 @@ module RSpec
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def matcher_matches?(matcher)
|
157
|
-
@match_results.fetch(matcher)
|
157
|
+
@match_results.fetch(matcher) do
|
158
|
+
raise ArgumentError, "Your #{matcher.description} has no match " \
|
159
|
+
"results, this can occur when an unexpected call stack or " \
|
160
|
+
"local jump occurs. Prehaps one of your matchers needs to " \
|
161
|
+
"declare `expects_call_stack_jump?` as `true`?"
|
162
|
+
end
|
158
163
|
end
|
159
164
|
|
160
165
|
private
|
@@ -93,7 +93,7 @@ module RSpec
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def respond_to_matcher
|
96
|
-
@respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments
|
96
|
+
@respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments.tap { |m| m.ignoring_method_signature_failure! }
|
97
97
|
end
|
98
98
|
|
99
99
|
def respond_to_failure_message_or
|
@@ -1,5 +1,7 @@
|
|
1
1
|
RSpec::Support.require_rspec_support "method_signature_verifier"
|
2
2
|
|
3
|
+
# TODO: Refactor this file to be under our class length
|
4
|
+
# rubocop:disable ClassLength
|
3
5
|
module RSpec
|
4
6
|
module Matchers
|
5
7
|
module BuiltIn
|
@@ -11,6 +13,7 @@ module RSpec
|
|
11
13
|
@names = names
|
12
14
|
@expected_arity = nil
|
13
15
|
@expected_keywords = []
|
16
|
+
@ignoring_method_signature_failure = false
|
14
17
|
@unlimited_arguments = nil
|
15
18
|
@arbitrary_keywords = nil
|
16
19
|
end
|
@@ -100,6 +103,12 @@ module RSpec
|
|
100
103
|
"respond to #{pp_names}#{with_arity}"
|
101
104
|
end
|
102
105
|
|
106
|
+
# @api private
|
107
|
+
# Used by other matchers to suppress a check
|
108
|
+
def ignoring_method_signature_failure!
|
109
|
+
@ignoring_method_signature_failure = true
|
110
|
+
end
|
111
|
+
|
103
112
|
private
|
104
113
|
|
105
114
|
def find_failing_method_names(actual, filter_method)
|
@@ -109,7 +118,7 @@ module RSpec
|
|
109
118
|
end
|
110
119
|
end
|
111
120
|
|
112
|
-
def
|
121
|
+
def setup_method_signature_expectation
|
113
122
|
expectation = Support::MethodSignatureExpectation.new
|
114
123
|
|
115
124
|
if @expected_arity.is_a?(Range)
|
@@ -123,11 +132,35 @@ module RSpec
|
|
123
132
|
expectation.expect_unlimited_arguments = @unlimited_arguments
|
124
133
|
expectation.expect_arbitrary_keywords = @arbitrary_keywords
|
125
134
|
|
135
|
+
expectation
|
136
|
+
end
|
137
|
+
|
138
|
+
def matches_arity?(actual, name)
|
139
|
+
expectation = setup_method_signature_expectation
|
140
|
+
|
126
141
|
return true if expectation.empty?
|
127
142
|
|
128
|
-
|
143
|
+
begin
|
144
|
+
Support::StrictSignatureVerifier.new(method_signature_for(actual, name)).
|
145
|
+
with_expectation(expectation).valid?
|
146
|
+
rescue NameError
|
147
|
+
return true if @ignoring_method_signature_failure
|
148
|
+
raise ArgumentError, "The #{matcher_name} matcher requires that " \
|
149
|
+
"the actual object define the method(s) in " \
|
150
|
+
"order to check arity, but the method " \
|
151
|
+
"`#{name}` is not defined. Remove the arity " \
|
152
|
+
"check or define the method to continue."
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def method_signature_for(actual, name)
|
157
|
+
method_handle = Support.method_handle_for(actual, name)
|
129
158
|
|
130
|
-
|
159
|
+
if name == :new && method_handle.owner === ::Class && ::Class === actual
|
160
|
+
Support::MethodSignature.new(actual.instance_method(:initialize))
|
161
|
+
else
|
162
|
+
Support::MethodSignature.new(method_handle)
|
163
|
+
end
|
131
164
|
end
|
132
165
|
|
133
166
|
def with_arity
|
@@ -163,3 +196,4 @@ module RSpec
|
|
163
196
|
end
|
164
197
|
end
|
165
198
|
end
|
199
|
+
# rubocop:enable ClassLength
|
@@ -98,7 +98,7 @@ module RSpec
|
|
98
98
|
# Not intended to be instantiated directly.
|
99
99
|
class YieldControl < BaseMatcher
|
100
100
|
def initialize
|
101
|
-
|
101
|
+
@expectation_type = @expected_yields_count = nil
|
102
102
|
end
|
103
103
|
|
104
104
|
# @api public
|
@@ -153,7 +153,7 @@ module RSpec
|
|
153
153
|
def matches?(block)
|
154
154
|
@probe = YieldProbe.probe(block)
|
155
155
|
return false unless @probe.has_block?
|
156
|
-
|
156
|
+
return @probe.num_yields > 0 unless @expectation_type
|
157
157
|
@probe.num_yields.__send__(@expectation_type, @expected_yields_count)
|
158
158
|
end
|
159
159
|
|
@@ -182,35 +182,44 @@ module RSpec
|
|
182
182
|
private
|
183
183
|
|
184
184
|
def set_expected_yields_count(relativity, n)
|
185
|
+
raise "Multiple count constraints are not supported" if @expectation_type
|
186
|
+
|
185
187
|
@expectation_type = relativity
|
186
|
-
@expected_yields_count =
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
188
|
+
@expected_yields_count = count_constraint_to_number(n)
|
189
|
+
end
|
190
|
+
|
191
|
+
def count_constraint_to_number(n)
|
192
|
+
case n
|
193
|
+
when Numeric then n
|
194
|
+
when :once then 1
|
195
|
+
when :twice then 2
|
196
|
+
when :thrice then 3
|
197
|
+
else
|
198
|
+
raise ArgumentError, "Expected a number, :once, :twice or :thrice," \
|
199
|
+
" but got #{n}"
|
200
|
+
end
|
192
201
|
end
|
193
202
|
|
194
203
|
def failure_reason
|
195
204
|
return ' but was not a block' unless @probe.has_block?
|
196
|
-
|
197
|
-
" #{
|
198
|
-
" but yielded #{human_readable_count(@probe.num_yields)}"
|
205
|
+
"#{human_readable_expectation_type}#{human_readable_count(@expected_yields_count)}" \
|
206
|
+
" but yielded#{human_readable_count(@probe.num_yields)}"
|
199
207
|
end
|
200
208
|
|
201
209
|
def human_readable_expectation_type
|
202
210
|
case @expectation_type
|
203
|
-
when :<= then 'at most
|
204
|
-
when :>= then 'at least
|
211
|
+
when :<= then ' at most'
|
212
|
+
when :>= then ' at least'
|
205
213
|
else ''
|
206
214
|
end
|
207
215
|
end
|
208
216
|
|
209
217
|
def human_readable_count(count)
|
210
218
|
case count
|
211
|
-
when
|
212
|
-
when
|
213
|
-
|
219
|
+
when nil then ''
|
220
|
+
when 1 then ' once'
|
221
|
+
when 2 then ' twice'
|
222
|
+
else " #{count} times"
|
214
223
|
end
|
215
224
|
end
|
216
225
|
end
|
data/lib/rspec/matchers/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
RSpec::Support.require_rspec_support "with_keywords_when_needed"
|
2
|
+
|
1
3
|
module RSpec
|
2
4
|
module Matchers
|
3
5
|
# Defines the custom matcher DSL.
|
@@ -147,8 +149,14 @@ module RSpec
|
|
147
149
|
# is rarely necessary, but can be helpful, for example, when specifying
|
148
150
|
# asynchronous processes that require different timeouts.
|
149
151
|
#
|
152
|
+
# By default the match block will swallow expectation errors (e.g.
|
153
|
+
# 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
|
+
# `:notify_expectation_failures => true`.
|
156
|
+
#
|
157
|
+
# @param [Hash] options for defining the behavior of the match block.
|
150
158
|
# @yield [Object] actual the actual value (i.e. the value wrapped by `expect`)
|
151
|
-
def match_when_negated(&match_block)
|
159
|
+
def match_when_negated(options={}, &match_block)
|
152
160
|
define_user_override(:does_not_match?, match_block) do |actual|
|
153
161
|
begin
|
154
162
|
@actual = actual
|
@@ -156,6 +164,7 @@ module RSpec
|
|
156
164
|
super(*actual_arg_for(match_block))
|
157
165
|
end
|
158
166
|
rescue RSpec::Expectations::ExpectationNotMetError
|
167
|
+
raise if options[:notify_expectation_failures]
|
159
168
|
false
|
160
169
|
end
|
161
170
|
end
|
@@ -453,11 +462,12 @@ module RSpec
|
|
453
462
|
@chained_method_clauses = []
|
454
463
|
@block_arg = block_arg
|
455
464
|
|
456
|
-
class << self
|
465
|
+
klass = class << self
|
457
466
|
# See `Macros#define_user_override` above, for an explanation.
|
458
467
|
include(@user_method_defs = Module.new)
|
459
468
|
self
|
460
|
-
end
|
469
|
+
end
|
470
|
+
RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *expected, &declarations)
|
461
471
|
end
|
462
472
|
|
463
473
|
# Provides the expected value. This will return an array if
|
@@ -521,6 +531,9 @@ module RSpec
|
|
521
531
|
super(method, *args, &block)
|
522
532
|
end
|
523
533
|
end
|
534
|
+
# The method_missing method should be refactored to pass kw args in RSpec 4
|
535
|
+
# then this can be removed
|
536
|
+
ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
|
524
537
|
end
|
525
538
|
end
|
526
539
|
end
|
@@ -24,7 +24,7 @@ module RSpec
|
|
24
24
|
# list([]) #=> ""
|
25
25
|
#
|
26
26
|
def self.list(obj)
|
27
|
-
return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj
|
27
|
+
return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj || Hash === obj
|
28
28
|
items = Array(obj).map { |w| RSpec::Support::ObjectFormatter.format(w) }
|
29
29
|
case items.length
|
30
30
|
when 0
|
@@ -52,20 +52,29 @@ module RSpec
|
|
52
52
|
|
53
53
|
private
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
class << self
|
56
|
+
private
|
57
|
+
|
58
|
+
def diff_label_for(matcher)
|
59
|
+
"Diff for (#{truncated(RSpec::Support::ObjectFormatter.format(matcher))}):"
|
60
|
+
end
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
def truncated(description)
|
63
|
+
return description if description.length <= DESCRIPTION_MAX_LENGTH
|
64
|
+
description[0...DESCRIPTION_MAX_LENGTH - 3] << "..."
|
65
|
+
end
|
62
66
|
end
|
63
67
|
|
64
68
|
def diffs(differ, actual)
|
65
69
|
@expected_list.map do |(expected, diff_label)|
|
66
70
|
diff = differ.diff(actual, expected)
|
67
71
|
next if diff.strip.empty?
|
68
|
-
|
72
|
+
if diff == "\e[0m\n\e[0m"
|
73
|
+
"#{diff_label}\n" \
|
74
|
+
" <The diff is empty, are your objects producing identical `#inspect` output?>"
|
75
|
+
else
|
76
|
+
"#{diff_label}#{diff}"
|
77
|
+
end
|
69
78
|
end.compact.join("\n")
|
70
79
|
end
|
71
80
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-expectations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Baker
|
8
8
|
- David Chelimsky
|
9
9
|
- Myron Marston
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain:
|
13
13
|
- |
|
@@ -45,7 +45,7 @@ cert_chain:
|
|
45
45
|
ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
|
46
46
|
F3MdtaDehhjC
|
47
47
|
-----END CERTIFICATE-----
|
48
|
-
date:
|
48
|
+
date: 2020-10-29 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.9.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.9.0
|
64
64
|
- !ruby/object:Gem::Dependency
|
65
65
|
name: diff-lcs
|
66
66
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,6 +123,20 @@ dependencies:
|
|
123
123
|
- - "~>"
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '5.2'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rake
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 10.0.0
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 10.0.0
|
126
140
|
description: rspec-expectations provides a simple, readable API to express expected
|
127
141
|
outcomes of a code example.
|
128
142
|
email: rspec@googlegroups.com
|
@@ -188,11 +202,11 @@ licenses:
|
|
188
202
|
- MIT
|
189
203
|
metadata:
|
190
204
|
bug_tracker_uri: https://github.com/rspec/rspec-expectations/issues
|
191
|
-
changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3.
|
205
|
+
changelog_uri: https://github.com/rspec/rspec-expectations/blob/v3.9.4/Changelog.md
|
192
206
|
documentation_uri: https://rspec.info/documentation/
|
193
207
|
mailing_list_uri: https://groups.google.com/forum/#!forum/rspec
|
194
208
|
source_code_uri: https://github.com/rspec/rspec-expectations
|
195
|
-
post_install_message:
|
209
|
+
post_install_message:
|
196
210
|
rdoc_options:
|
197
211
|
- "--charset=UTF-8"
|
198
212
|
require_paths:
|
@@ -208,8 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
222
|
- !ruby/object:Gem::Version
|
209
223
|
version: '0'
|
210
224
|
requirements: []
|
211
|
-
rubygems_version: 3.
|
212
|
-
signing_key:
|
225
|
+
rubygems_version: 3.1.3
|
226
|
+
signing_key:
|
213
227
|
specification_version: 4
|
214
|
-
summary: rspec-expectations-3.
|
228
|
+
summary: rspec-expectations-3.9.4
|
215
229
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|