rspec-expectations 3.8.1 → 3.12.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +203 -4
- data/README.md +35 -20
- data/lib/rspec/expectations/configuration.rb +15 -0
- data/lib/rspec/expectations/expectation_target.rb +42 -6
- data/lib/rspec/expectations/failure_aggregator.rb +41 -6
- data/lib/rspec/expectations/handler.rb +20 -8
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers/aliased_matcher.rb +3 -3
- data/lib/rspec/matchers/built_in/all.rb +1 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +5 -0
- data/lib/rspec/matchers/built_in/be.rb +10 -107
- data/lib/rspec/matchers/built_in/be_instance_of.rb +5 -1
- data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -1
- data/lib/rspec/matchers/built_in/be_within.rb +2 -2
- data/lib/rspec/matchers/built_in/change.rb +26 -2
- data/lib/rspec/matchers/built_in/compound.rb +20 -1
- data/lib/rspec/matchers/built_in/contain_exactly.rb +10 -2
- data/lib/rspec/matchers/built_in/count_expectation.rb +169 -0
- data/lib/rspec/matchers/built_in/exist.rb +1 -1
- data/lib/rspec/matchers/built_in/has.rb +88 -24
- data/lib/rspec/matchers/built_in/have_attributes.rb +1 -1
- data/lib/rspec/matchers/built_in/include.rb +82 -18
- data/lib/rspec/matchers/built_in/output.rb +7 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +63 -22
- data/lib/rspec/matchers/built_in/respond_to.rb +53 -18
- data/lib/rspec/matchers/built_in/throw_symbol.rb +10 -4
- data/lib/rspec/matchers/built_in/yield.rb +26 -83
- data/lib/rspec/matchers/built_in.rb +2 -1
- data/lib/rspec/matchers/composable.rb +1 -1
- data/lib/rspec/matchers/dsl.rb +29 -11
- data/lib/rspec/matchers/english_phrasing.rb +1 -1
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +16 -7
- data/lib/rspec/matchers/matcher_protocol.rb +6 -0
- data/lib/rspec/matchers.rb +78 -68
- data.tar.gz.sig +0 -0
- metadata +29 -24
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d167a03fcf6e4519b628fefcf03b644e6436e1f6769058d84431fab3181e5119
|
4
|
+
data.tar.gz: dccb3d8b5ed822e523989e59e897085584173d65a503be30166b9d14bba675ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc027c3d982da4f60e13924ef494fe4df964ee64ccd405eaf69a522494e23d394d0560dfa32c2007a8f43831118ad20df6480ed5692dbe70b389dfcc724e7266
|
7
|
+
data.tar.gz: 61e1c4f7ce7514869e63d24e7eb3270861ea4ad6343c34127b04f757bd80009dd599ae94be25c925b1de265fb4dc5a68f9619b9e3293de46b4aabd0cd1595dae
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,3 +1,204 @@
|
|
1
|
+
### Development
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.3...3-12-maintenance)
|
3
|
+
|
4
|
+
### 3.12.3 / 2023-04-20
|
5
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.2...v3.12.3)
|
6
|
+
|
7
|
+
Bug Fixes:
|
8
|
+
|
9
|
+
* Fix `include` matcher when fuzzy matching on keys with a hash-like actual which
|
10
|
+
has a non standard `key?` method which may raise.
|
11
|
+
(Jon Rowe, #1416)
|
12
|
+
|
13
|
+
### 3.12.2 / 2023-01-07
|
14
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.1...v3.12.2)
|
15
|
+
|
16
|
+
Bug Fixes:
|
17
|
+
|
18
|
+
* Prevent deprecation warning when using the `exist` matcher with `Dir`.
|
19
|
+
(Steve Dierker, #1398)
|
20
|
+
|
21
|
+
### 3.12.1 / 2022-12-16
|
22
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.0...v3.12.1)
|
23
|
+
|
24
|
+
Bug Fixes:
|
25
|
+
|
26
|
+
* Pass keyword arguments through to aliased (and thus negated) matchers. (Jon Rowe, #1394)
|
27
|
+
* When handling failures in an aggregated_failures block (or example) prevent
|
28
|
+
the failure list leaking out. (Maciek Rząsa, #1392)
|
29
|
+
|
30
|
+
### 3.12.0 / 2022-10-26
|
31
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.1...v3.12.0)
|
32
|
+
|
33
|
+
Enhancements:
|
34
|
+
|
35
|
+
* Add `an_array_matching` alias for `match_array` to improve readability as an argument
|
36
|
+
matcher. (Mark Schneider, #1361)
|
37
|
+
|
38
|
+
### 3.11.1 / 2022-09-12
|
39
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.0...v3.11.1)
|
40
|
+
|
41
|
+
Bug Fixes:
|
42
|
+
|
43
|
+
* Allow the `contain_exactly` matcher to be reused by resetting its
|
44
|
+
internals on `matches?` (@bclayman-sq, #1326)
|
45
|
+
* Using the exist matcher on `FileTest` no longer produces a deprecation warning.
|
46
|
+
(Ryo Nakamura, #1383)
|
47
|
+
|
48
|
+
### 3.11.0 / 2022-02-09
|
49
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.2...v3.11.0)
|
50
|
+
|
51
|
+
Enhancements:
|
52
|
+
|
53
|
+
* Return `true` from `aggregate_failures` when no exception occurs. (Jon Rowe, #1225)
|
54
|
+
|
55
|
+
Deprecations:
|
56
|
+
|
57
|
+
* Print a deprecation message when using the implicit block expectation syntax.
|
58
|
+
(Phil Pirozhkov, #1139)
|
59
|
+
|
60
|
+
### 3.10.2 / 2022-01-14
|
61
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.1...v3.10.2)
|
62
|
+
|
63
|
+
Bug Fixes:
|
64
|
+
|
65
|
+
* Fix support for dynamic matchers for expectation target checks (Phil Pirozhkov, #1294)
|
66
|
+
* Fix `expect(array).to include(hash).times`, previously this would fail due to
|
67
|
+
matching the entire array as a single hash, rather than a member of the hash.
|
68
|
+
(Slava Kardakov, #1322)
|
69
|
+
* Ensure `raise_error` matches works with the `error_highlight` option from Ruby 3.1.
|
70
|
+
(Peter Goldstein, #1339)
|
71
|
+
|
72
|
+
### 3.10.1 / 2020-12-27
|
73
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.0...v3.10.1)
|
74
|
+
|
75
|
+
Bug Fixes:
|
76
|
+
|
77
|
+
* Allow JRuby 9.2.x.x to generate backtraces normally rather than via our
|
78
|
+
backfill workaround. (#1230, Jon Rowe)
|
79
|
+
|
80
|
+
### 3.10.0 / 2020-10-30
|
81
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.10.0)
|
82
|
+
|
83
|
+
Enhancements:
|
84
|
+
|
85
|
+
* Allow `include` matcher to be chained with `once`, `at_least`, etc. for simple cases.
|
86
|
+
(Marc-André Lafortune, #1168)
|
87
|
+
* Add an explicit warning when `nil` is passed to `raise_error`. (Phil Pirozhkov, #1143)
|
88
|
+
* Improve `include` matcher's composability. (Phil Pirozhkov, #1155)
|
89
|
+
* Mocks expectations can now set a custom failure message.
|
90
|
+
(Benoit Tigeot and Nicolas Zermati, #1156)
|
91
|
+
* `aggregate_failures` now shows the backtrace line for each failure. (Fabricio Bedin, #1163)
|
92
|
+
* Support multiple combinations of `yield_control` modifiers like `at_least`, `at_most`.
|
93
|
+
(Jon Rowe, #1169)
|
94
|
+
* Dynamic `have_<n>` matchers now have output consistent with other dynamic matchers.
|
95
|
+
(Marc-André Lafortune, #1195)
|
96
|
+
* New config option `strict_predicate_matchers` allows predicate matcher to be strict
|
97
|
+
(i.e. match for `true` or `false`) instead of the default (match truthy vs `false` or `nil`).
|
98
|
+
(Marc-André Lafortune, #1196)
|
99
|
+
|
100
|
+
### 3.9.4 / 2020-10-29
|
101
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4)
|
102
|
+
|
103
|
+
Bug Fixes:
|
104
|
+
|
105
|
+
* Fix regression with `be_` and `have_` matchers and arguments implementing `to_hash`
|
106
|
+
were they would act like keywords and be cast to a hash. (Jon Rowe, #1222)
|
107
|
+
|
108
|
+
### 3.9.3 / 2020-10-23
|
109
|
+
|
110
|
+
Bug Fixes:
|
111
|
+
|
112
|
+
* Swap the comparison of the delta vs the expected for the `be_within` matcher allowing
|
113
|
+
more complicated oobjects to be compared providing they provide `abs` and other
|
114
|
+
comparison methods. (Kelly Stannard, #1182)
|
115
|
+
* Properly format expected in the description of the `be_within` matcher. (Jon Rowe, #1185)
|
116
|
+
* Remove warning when using keyword arguments with `be_` and `have_` matchers on 2.7.x
|
117
|
+
(Jon Rowe, #1187)
|
118
|
+
* Prevent formatting a single hash as a list of key value pairs in default failure messages
|
119
|
+
for custom matches (fixes formatting in `EnglishPhrasing#list`). (Robert Eshleman, #1193)
|
120
|
+
* Prevent errors from causing false positives when using `be <operator>` comparison, e.g.
|
121
|
+
`expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, #1208)
|
122
|
+
|
123
|
+
|
124
|
+
### 3.9.2 / 2020-05-08
|
125
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2)
|
126
|
+
|
127
|
+
Bug Fixes:
|
128
|
+
|
129
|
+
* Issue a proper `ArgumentError` when invalid arguments are given to `yield_control`
|
130
|
+
modifiers such as `at_least` et al. (Marc-André Lafortune, #1167)
|
131
|
+
* Prevent Ruby 2.7 keyword arguments warning from being issued by custom
|
132
|
+
matcher definitions. (Jon Rowe, #1176)
|
133
|
+
|
134
|
+
### 3.9.1 / 2020-03-13
|
135
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.0...v3.9.1)
|
136
|
+
|
137
|
+
Bug Fixes:
|
138
|
+
|
139
|
+
* Issue an improved warning when using `respond_to(...).with(n).arguments` and ignore
|
140
|
+
the warning when using with `have_attributes(...)`. (Jon Rowe, #1164)
|
141
|
+
|
142
|
+
### 3.9.0 / 2019-10-08
|
143
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.6...v3.9.0)
|
144
|
+
|
145
|
+
Enhancements:
|
146
|
+
|
147
|
+
* The `respond_to` matcher now uses the signature from `initialize` to validate checks
|
148
|
+
for `new` (unless `new` is non standard). (Jon Rowe, #1072)
|
149
|
+
* Generated descriptions for matchers now use `is expected to` rather than `should` in
|
150
|
+
line with our preferred DSL. (Pete Johns, #1080, rspec/rspec-core#2572)
|
151
|
+
* Add the ability to re-raise expectation errors when matching
|
152
|
+
with `match_when_negated` blocks. (Jon Rowe, #1130)
|
153
|
+
* Add a warning when an empty diff is produce due to identical inspect output.
|
154
|
+
(Benoit Tigeot, #1126)
|
155
|
+
|
156
|
+
### 3.8.6 / 2019-10-07
|
157
|
+
|
158
|
+
Bug Fixes:
|
159
|
+
|
160
|
+
* Revert #1125 due to the change being incompatible with our semantic versioning
|
161
|
+
policy.
|
162
|
+
|
163
|
+
### 3.8.5 / 2019-10-02
|
164
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.4...v3.8.5)
|
165
|
+
|
166
|
+
Bug Fixes:
|
167
|
+
|
168
|
+
* Prevent unsupported implicit block expectation syntax from being used.
|
169
|
+
(Phil Pirozhkov, #1125)
|
170
|
+
|
171
|
+
### 3.8.4 / 2019-06-10
|
172
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.3...v3.8.4)
|
173
|
+
|
174
|
+
Bug Fixes:
|
175
|
+
|
176
|
+
* Prevent false negatives when checking objects for the methods required to run the
|
177
|
+
the `be_an_instance_of` and `be_kind_of` matchers. (Nazar Matus, #1112)
|
178
|
+
|
179
|
+
### 3.8.3 / 2019-04-20
|
180
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.2...v3.8.3)
|
181
|
+
|
182
|
+
Bug Fixes:
|
183
|
+
|
184
|
+
* Prevent composed `all` matchers from leaking into their siblings leading to duplicate
|
185
|
+
failures. (Jamie English, #1086)
|
186
|
+
* Prevent objects which change their hash on comparison from failing change checks.
|
187
|
+
(Phil Pirozhkov, #1100)
|
188
|
+
* Issue an `ArgumentError` rather than a `NoMethodError` when `be_an_instance_of` and
|
189
|
+
`be_kind_of` matchers encounter objects not supporting those methods.
|
190
|
+
(Taichi Ishitani, #1107)
|
191
|
+
|
192
|
+
### 3.8.2 / 2018-10-09
|
193
|
+
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.1...v3.8.2)
|
194
|
+
|
195
|
+
Bug Fixes:
|
196
|
+
|
197
|
+
* Change `include` matcher to rely on a `respond_to?(:include?)` check rather than a direct
|
198
|
+
Hash comparison before calling `to_hash` to convert to a hash. (Jordan Owens, #1073)
|
199
|
+
* Prevent unexpected call stack jumps from causing an obscure error (`IndexError`), and
|
200
|
+
replace that error with a proper informative message. (Jon Rowe, #1076)
|
201
|
+
|
1
202
|
### 3.8.1 / 2018-08-06
|
2
203
|
[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.0...v3.8.1)
|
3
204
|
|
@@ -139,10 +340,8 @@ Enhancements:
|
|
139
340
|
can cause uses of `super` to trigger infinite recursion. (Myron Marston, #816)
|
140
341
|
* Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and
|
141
342
|
`SystemExit`. It is dangerous to interfere with these. (Myron Marston, #845)
|
142
|
-
* Add `#with_captures` to the
|
143
|
-
|
144
|
-
which allows a user to specify expected captures when matching a regex
|
145
|
-
against a string. (Sam Phippen, #848)
|
343
|
+
* Add `#with_captures` to the match matcher which allows a user to specify expected
|
344
|
+
captures when matching a regex against a string. (Sam Phippen, #848)
|
146
345
|
* Always print compound failure messages in the multi-line form. Trying
|
147
346
|
to print it all on a single line didn't read very well. (Myron Marston, #859)
|
148
347
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# RSpec Expectations [](https://github.com/rspec/rspec-expectations/actions) [](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
|
|
@@ -28,6 +28,7 @@ module RSpec
|
|
28
28
|
|
29
29
|
def initialize
|
30
30
|
@on_potential_false_positives = :warn
|
31
|
+
@strict_predicate_matchers = false
|
31
32
|
end
|
32
33
|
|
33
34
|
# Configures the supported syntax.
|
@@ -185,6 +186,20 @@ module RSpec
|
|
185
186
|
@on_potential_false_positives = behavior
|
186
187
|
end
|
187
188
|
|
189
|
+
# Configures RSpec to check predicate matchers to `be(true)` / `be(false)` (strict),
|
190
|
+
# or `be_truthy` / `be_falsey` (not strict).
|
191
|
+
# Historically, the default was `false`, but `true` is recommended.
|
192
|
+
def strict_predicate_matchers=(flag)
|
193
|
+
raise ArgumentError, "Pass `true` or `false`" unless flag == true || flag == false
|
194
|
+
@strict_predicate_matchers = flag
|
195
|
+
end
|
196
|
+
|
197
|
+
attr_reader :strict_predicate_matchers
|
198
|
+
|
199
|
+
def strict_predicate_matchers?
|
200
|
+
@strict_predicate_matchers
|
201
|
+
end
|
202
|
+
|
188
203
|
# Indicates what RSpec will do about matcher use which will
|
189
204
|
# potentially cause false positives in tests, generally you want to
|
190
205
|
# avoid such scenarios so this defaults to `true`.
|
@@ -42,7 +42,7 @@ module RSpec
|
|
42
42
|
elsif block
|
43
43
|
raise ArgumentError, "You cannot pass both an argument and a block to `expect`."
|
44
44
|
else
|
45
|
-
new(value)
|
45
|
+
ValueExpectationTarget.new(value)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -57,7 +57,7 @@ module RSpec
|
|
57
57
|
# expect { perform }.to raise_error
|
58
58
|
# @param [Matcher]
|
59
59
|
# matcher
|
60
|
-
# @param [String
|
60
|
+
# @param [String, Proc] message optional message to display when the expectation fails
|
61
61
|
# @return [Boolean] true if the expectation succeeds (else raises)
|
62
62
|
# @see RSpec::Matchers
|
63
63
|
def to(matcher=nil, message=nil, &block)
|
@@ -70,7 +70,7 @@ module RSpec
|
|
70
70
|
# expect(value).not_to eq(5)
|
71
71
|
# @param [Matcher]
|
72
72
|
# matcher
|
73
|
-
# @param [String
|
73
|
+
# @param [String, Proc] message optional message to display when the expectation fails
|
74
74
|
# @return [Boolean] false if the negative expectation succeeds (else raises)
|
75
75
|
# @see RSpec::Matchers
|
76
76
|
def not_to(matcher=nil, message=nil, &block)
|
@@ -90,6 +90,44 @@ module RSpec
|
|
90
90
|
include InstanceMethods
|
91
91
|
end
|
92
92
|
|
93
|
+
# @private
|
94
|
+
# Validates the provided matcher to ensure it supports block
|
95
|
+
# expectations, in order to avoid user confusion when they
|
96
|
+
# use a block thinking the expectation will be on the return
|
97
|
+
# value of the block rather than the block itself.
|
98
|
+
class ValueExpectationTarget < ExpectationTarget
|
99
|
+
def to(matcher=nil, message=nil, &block)
|
100
|
+
enforce_value_expectation(matcher)
|
101
|
+
super
|
102
|
+
end
|
103
|
+
|
104
|
+
def not_to(matcher=nil, message=nil, &block)
|
105
|
+
enforce_value_expectation(matcher)
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def enforce_value_expectation(matcher)
|
112
|
+
return if supports_value_expectations?(matcher)
|
113
|
+
|
114
|
+
RSpec.deprecate(
|
115
|
+
"expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}",
|
116
|
+
:message =>
|
117
|
+
"The implicit block expectation syntax is deprecated, you should pass " \
|
118
|
+
"a block rather than an argument to `expect` to use the provided " \
|
119
|
+
"block expectation matcher or the matcher must implement " \
|
120
|
+
"`supports_value_expectations?`. e.g `expect { value }.to " \
|
121
|
+
"#{RSpec::Support::ObjectFormatter.format(matcher)}` not " \
|
122
|
+
"`expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}`"
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
def supports_value_expectations?(matcher)
|
127
|
+
!matcher.respond_to?(:supports_value_expectations?) || matcher.supports_value_expectations?
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
93
131
|
# @private
|
94
132
|
# Validates the provided matcher to ensure it supports block
|
95
133
|
# expectations, in order to avoid user confusion when they
|
@@ -118,9 +156,7 @@ module RSpec
|
|
118
156
|
end
|
119
157
|
|
120
158
|
def supports_block_expectations?(matcher)
|
121
|
-
matcher.supports_block_expectations?
|
122
|
-
rescue NoMethodError
|
123
|
-
false
|
159
|
+
matcher.respond_to?(:supports_block_expectations?) && matcher.supports_block_expectations?
|
124
160
|
end
|
125
161
|
end
|
126
162
|
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,14 +63,16 @@ 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
|
54
71
|
|
55
|
-
if RSpec::Support::Ruby.jruby?
|
56
|
-
# On JRuby, `caller` and `raise` produce different backtraces with
|
57
|
-
# stack frames. It's important that we use `raise` for JRuby to produce
|
58
|
-
# that has a continuous common section with the raised `MultipleExpectationsNotMetError`,
|
72
|
+
if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version < '9.2.0.0'
|
73
|
+
# On JRuby 9.1.x.x and before, `caller` and `raise` produce different backtraces with
|
74
|
+
# regards to `.java` stack frames. It's important that we use `raise` for JRuby to produce
|
75
|
+
# a backtrace that has a continuous common section with the raised `MultipleExpectationsNotMetError`,
|
59
76
|
# so that rspec-core's truncation logic can work properly on it to list the backtrace
|
60
77
|
# relative to the `aggregate_failures` block.
|
61
78
|
def assign_backtrace(failure)
|
@@ -80,7 +97,7 @@ module RSpec
|
|
80
97
|
all_errors = failures + other_errors
|
81
98
|
|
82
99
|
case all_errors.size
|
83
|
-
when 0 then return
|
100
|
+
when 0 then return true
|
84
101
|
when 1 then RSpec::Support.notify_failure all_errors.first
|
85
102
|
else RSpec::Support.notify_failure MultipleExpectationsNotMetError.new(self)
|
86
103
|
end
|
@@ -150,11 +167,29 @@ module RSpec
|
|
150
167
|
def enumerated(exceptions, index_offset)
|
151
168
|
exceptions.each_with_index.map do |exception, index|
|
152
169
|
index += index_offset
|
153
|
-
formatted_message = yield exception
|
170
|
+
formatted_message = "#{yield exception}\n#{format_backtrace(exception.backtrace).first}"
|
154
171
|
"#{index_label index}#{indented formatted_message, index}"
|
155
172
|
end
|
156
173
|
end
|
157
174
|
|
175
|
+
def exclusion_patterns
|
176
|
+
patterns = %w[/lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle:]
|
177
|
+
patterns << "org/jruby/" if RSpec::Support::Ruby.jruby?
|
178
|
+
patterns.map! { |s| Regexp.new(s.gsub('/', File::SEPARATOR)) }
|
179
|
+
end
|
180
|
+
|
181
|
+
def format_backtrace(backtrace)
|
182
|
+
backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? }
|
183
|
+
end
|
184
|
+
|
185
|
+
def backtrace_line(line)
|
186
|
+
return if [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *exclusion_patterns)].any? { |p| line =~ p }
|
187
|
+
|
188
|
+
# It changes the current path that is relative to
|
189
|
+
# system root to be relative to the project root.
|
190
|
+
line.sub(/(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/, '\\1.\\2'.freeze).sub(/\A([^:]+:\d+)$/, '\\1'.freeze)
|
191
|
+
end
|
192
|
+
|
158
193
|
def enumerated_failures
|
159
194
|
enumerated(failures, 0, &:message)
|
160
195
|
end
|
@@ -44,15 +44,21 @@ module RSpec
|
|
44
44
|
|
45
45
|
# @private
|
46
46
|
class PositiveExpectationHandler
|
47
|
-
def self.handle_matcher(actual, initial_matcher,
|
48
|
-
ExpectationHelper.with_matcher(self, initial_matcher,
|
47
|
+
def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block)
|
48
|
+
ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher|
|
49
49
|
return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher
|
50
|
-
|
50
|
+
|
51
|
+
match_result = matcher.matches?(actual, &block)
|
52
|
+
if custom_message && match_result.respond_to?(:error_generator)
|
53
|
+
match_result.error_generator.opts[:message] = custom_message
|
54
|
+
end
|
55
|
+
|
56
|
+
match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message)
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
54
60
|
def self.verb
|
55
|
-
|
61
|
+
'is expected to'
|
56
62
|
end
|
57
63
|
|
58
64
|
def self.should_method
|
@@ -66,10 +72,16 @@ module RSpec
|
|
66
72
|
|
67
73
|
# @private
|
68
74
|
class NegativeExpectationHandler
|
69
|
-
def self.handle_matcher(actual, initial_matcher,
|
70
|
-
ExpectationHelper.with_matcher(self, initial_matcher,
|
75
|
+
def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block)
|
76
|
+
ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher|
|
71
77
|
return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher
|
72
|
-
|
78
|
+
|
79
|
+
negated_match_result = does_not_match?(matcher, actual, &block)
|
80
|
+
if custom_message && negated_match_result.respond_to?(:error_generator)
|
81
|
+
negated_match_result.error_generator.opts[:message] = custom_message
|
82
|
+
end
|
83
|
+
|
84
|
+
negated_match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message_when_negated)
|
73
85
|
end
|
74
86
|
end
|
75
87
|
|
@@ -82,7 +94,7 @@ module RSpec
|
|
82
94
|
end
|
83
95
|
|
84
96
|
def self.verb
|
85
|
-
|
97
|
+
'is expected not to'
|
86
98
|
end
|
87
99
|
|
88
100
|
def self.should_method
|
@@ -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
|
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
|
-
|
109
|
-
return
|
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)
|