rspec-expectations 3.8.6 → 3.9.4
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://secure.travis-ci.org/rspec/rspec-expectations.svg?branch=
|
1
|
+
# RSpec Expectations [![Build Status](https://secure.travis-ci.org/rspec/rspec-expectations.svg?branch=main)](http://travis-ci.org/rspec/rspec-expectations) [![Code Climate](https://codeclimate.com/github/rspec/rspec-expectations.svg)](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
|