rspec-expectations 2.13.0 → 3.0.0
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 +15 -0
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +413 -23
- data/License.txt +1 -0
- data/README.md +109 -80
- data/lib/rspec/{matchers → expectations}/configuration.rb +44 -14
- data/lib/rspec/expectations/expectation_target.rb +71 -38
- data/lib/rspec/expectations/fail_with.rb +12 -44
- data/lib/rspec/expectations/handler.rb +135 -35
- data/lib/rspec/expectations/minitest_integration.rb +16 -0
- data/lib/rspec/expectations/syntax.rb +60 -94
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/expectations.rb +46 -24
- data/lib/rspec/matchers/aliased_matcher.rb +41 -0
- data/lib/rspec/matchers/built_in/all.rb +78 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +63 -15
- data/lib/rspec/matchers/built_in/be.rb +170 -79
- data/lib/rspec/matchers/built_in/be_between.rb +77 -0
- data/lib/rspec/matchers/built_in/be_instance_of.rb +11 -3
- data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -0
- data/lib/rspec/matchers/built_in/be_within.rb +40 -16
- data/lib/rspec/matchers/built_in/change.rb +275 -74
- data/lib/rspec/matchers/built_in/compound.rb +122 -0
- data/lib/rspec/matchers/built_in/contain_exactly.rb +256 -0
- data/lib/rspec/matchers/built_in/cover.rb +3 -0
- data/lib/rspec/matchers/built_in/eq.rb +60 -6
- data/lib/rspec/matchers/built_in/eql.rb +17 -5
- data/lib/rspec/matchers/built_in/equal.rb +55 -21
- data/lib/rspec/matchers/built_in/exist.rb +74 -10
- data/lib/rspec/matchers/built_in/has.rb +71 -15
- data/lib/rspec/matchers/built_in/include.rb +58 -29
- data/lib/rspec/matchers/built_in/match.rb +19 -1
- data/lib/rspec/matchers/built_in/operators.rb +119 -0
- data/lib/rspec/matchers/built_in/output.rb +150 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +91 -33
- data/lib/rspec/matchers/built_in/respond_to.rb +42 -20
- data/lib/rspec/matchers/built_in/satisfy.rb +19 -3
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +54 -18
- data/lib/rspec/matchers/built_in/throw_symbol.rb +38 -8
- data/lib/rspec/matchers/built_in/yield.rb +237 -55
- data/lib/rspec/matchers/built_in.rb +45 -33
- data/lib/rspec/matchers/composable.rb +179 -0
- data/lib/rspec/matchers/dsl.rb +362 -5
- data/lib/rspec/matchers/generated_descriptions.rb +13 -6
- data/lib/rspec/matchers/matcher_delegator.rb +37 -0
- data/lib/rspec/matchers/pretty.rb +33 -20
- data/lib/rspec/matchers.rb +450 -227
- data.tar.gz.sig +1 -0
- metadata +100 -215
- metadata.gz.sig +0 -0
- data/features/README.md +0 -49
- data/features/Upgrade.md +0 -53
- data/features/built_in_matchers/README.md +0 -90
- data/features/built_in_matchers/be.feature +0 -175
- data/features/built_in_matchers/be_within.feature +0 -48
- data/features/built_in_matchers/cover.feature +0 -47
- data/features/built_in_matchers/end_with.feature +0 -48
- data/features/built_in_matchers/equality.feature +0 -139
- data/features/built_in_matchers/exist.feature +0 -45
- data/features/built_in_matchers/expect_change.feature +0 -59
- data/features/built_in_matchers/expect_error.feature +0 -144
- data/features/built_in_matchers/have.feature +0 -109
- data/features/built_in_matchers/include.feature +0 -174
- data/features/built_in_matchers/match.feature +0 -52
- data/features/built_in_matchers/operators.feature +0 -227
- data/features/built_in_matchers/predicates.feature +0 -137
- data/features/built_in_matchers/respond_to.feature +0 -84
- data/features/built_in_matchers/satisfy.feature +0 -33
- data/features/built_in_matchers/start_with.feature +0 -48
- data/features/built_in_matchers/throw_symbol.feature +0 -91
- data/features/built_in_matchers/types.feature +0 -116
- data/features/built_in_matchers/yield.feature +0 -146
- data/features/custom_matchers/access_running_example.feature +0 -53
- data/features/custom_matchers/define_diffable_matcher.feature +0 -27
- data/features/custom_matchers/define_matcher.feature +0 -368
- data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -38
- data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
- data/features/customized_message.feature +0 -22
- data/features/diffing.feature +0 -85
- data/features/implicit_docstrings.feature +0 -52
- data/features/step_definitions/additional_cli_steps.rb +0 -22
- data/features/support/env.rb +0 -5
- data/features/syntax_configuration.feature +0 -68
- data/features/test_frameworks/test_unit.feature +0 -46
- data/lib/rspec/expectations/deprecation.rb +0 -38
- data/lib/rspec/expectations/differ.rb +0 -115
- data/lib/rspec/expectations/errors.rb +0 -9
- data/lib/rspec/expectations/extensions/array.rb +0 -9
- data/lib/rspec/expectations/extensions/object.rb +0 -39
- data/lib/rspec/expectations/extensions.rb +0 -2
- data/lib/rspec/matchers/be_close.rb +0 -9
- data/lib/rspec/matchers/built_in/have.rb +0 -108
- data/lib/rspec/matchers/built_in/match_array.rb +0 -51
- data/lib/rspec/matchers/compatibility.rb +0 -14
- data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
- data/lib/rspec/matchers/matcher.rb +0 -300
- data/lib/rspec/matchers/method_missing.rb +0 -12
- data/lib/rspec/matchers/operator_matcher.rb +0 -109
- data/lib/rspec-expectations.rb +0 -1
- data/spec/rspec/expectations/differ_spec.rb +0 -170
- data/spec/rspec/expectations/expectation_target_spec.rb +0 -75
- data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
- data/spec/rspec/expectations/fail_with_spec.rb +0 -95
- data/spec/rspec/expectations/handler_spec.rb +0 -206
- data/spec/rspec/expectations/syntax_spec.rb +0 -97
- data/spec/rspec/matchers/base_matcher_spec.rb +0 -62
- data/spec/rspec/matchers/be_close_spec.rb +0 -22
- data/spec/rspec/matchers/be_instance_of_spec.rb +0 -63
- data/spec/rspec/matchers/be_kind_of_spec.rb +0 -41
- data/spec/rspec/matchers/be_spec.rb +0 -516
- data/spec/rspec/matchers/be_within_spec.rb +0 -129
- data/spec/rspec/matchers/change_spec.rb +0 -542
- data/spec/rspec/matchers/configuration_spec.rb +0 -238
- data/spec/rspec/matchers/cover_spec.rb +0 -69
- data/spec/rspec/matchers/description_generation_spec.rb +0 -176
- data/spec/rspec/matchers/dsl_spec.rb +0 -57
- data/spec/rspec/matchers/eq_spec.rb +0 -60
- data/spec/rspec/matchers/eql_spec.rb +0 -41
- data/spec/rspec/matchers/equal_spec.rb +0 -78
- data/spec/rspec/matchers/exist_spec.rb +0 -124
- data/spec/rspec/matchers/has_spec.rb +0 -122
- data/spec/rspec/matchers/have_spec.rb +0 -445
- data/spec/rspec/matchers/include_matcher_integration_spec.rb +0 -30
- data/spec/rspec/matchers/include_spec.rb +0 -531
- data/spec/rspec/matchers/match_array_spec.rb +0 -194
- data/spec/rspec/matchers/match_spec.rb +0 -61
- data/spec/rspec/matchers/matcher_spec.rb +0 -471
- data/spec/rspec/matchers/matchers_spec.rb +0 -37
- data/spec/rspec/matchers/method_missing_spec.rb +0 -28
- data/spec/rspec/matchers/operator_matcher_spec.rb +0 -223
- data/spec/rspec/matchers/raise_error_spec.rb +0 -395
- data/spec/rspec/matchers/respond_to_spec.rb +0 -292
- data/spec/rspec/matchers/satisfy_spec.rb +0 -44
- data/spec/rspec/matchers/start_with_end_with_spec.rb +0 -186
- data/spec/rspec/matchers/throw_symbol_spec.rb +0 -116
- data/spec/rspec/matchers/yield_spec.rb +0 -437
- data/spec/spec_helper.rb +0 -54
- data/spec/support/classes.rb +0 -56
- data/spec/support/in_sub_process.rb +0 -38
- data/spec/support/matchers.rb +0 -22
- data/spec/support/ruby_version.rb +0 -10
- data/spec/support/shared_examples.rb +0 -13
data/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
# RSpec Expectations [](http://travis-ci.org/rspec/rspec-expectations) [](https://codeclimate.com/github/rspec/rspec-expectations)
|
|
1
|
+
# RSpec Expectations [](http://travis-ci.org/rspec/rspec-expectations) [](https://codeclimate.com/github/rspec/rspec-expectations) [](http://inch-pages.github.io/github/rspec/rspec-expectations)
|
|
2
2
|
|
|
3
3
|
RSpec::Expectations lets you express expected outcomes on an object in an
|
|
4
4
|
example.
|
|
5
5
|
|
|
6
|
-
account.balance.
|
|
6
|
+
expect(account.balance).to eq(Money.new(37.42, :USD))
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -23,7 +23,7 @@ Minitest, or Cucumber, you can install it directly:
|
|
|
23
23
|
Here's an example using rspec-core:
|
|
24
24
|
|
|
25
25
|
```ruby
|
|
26
|
-
describe Order do
|
|
26
|
+
RSpec.describe Order do
|
|
27
27
|
it "sums the prices of the items in its line items" do
|
|
28
28
|
order = Order.new
|
|
29
29
|
order.add_entry(LineItem.new(:item => Item.new(
|
|
@@ -38,8 +38,7 @@ describe Order do
|
|
|
38
38
|
end
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`,
|
|
42
|
-
and `Item` classes would be from _your_ code. The last line of the example
|
|
41
|
+
The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`, `Item` and `Money` classes would be from _your_ code. The last line of the example
|
|
43
42
|
expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then
|
|
44
43
|
the example passes. If not, it fails with a message like:
|
|
45
44
|
|
|
@@ -51,52 +50,54 @@ the example passes. If not, it fails with a message like:
|
|
|
51
50
|
### Equivalence
|
|
52
51
|
|
|
53
52
|
```ruby
|
|
54
|
-
actual.
|
|
55
|
-
actual.
|
|
56
|
-
actual.should eql(expected) # passes if actual.eql?(expected)
|
|
53
|
+
expect(actual).to eq(expected) # passes if actual == expected
|
|
54
|
+
expect(actual).to eql(expected) # passes if actual.eql?(expected)
|
|
57
55
|
```
|
|
58
56
|
|
|
59
|
-
Note:
|
|
60
|
-
useless context" warning when the `==` matcher is used anywhere but the
|
|
61
|
-
last statement of an example.
|
|
57
|
+
Note: The new `expect` syntax no longer supports the `==` matcher.
|
|
62
58
|
|
|
63
59
|
### Identity
|
|
64
60
|
|
|
65
61
|
```ruby
|
|
66
|
-
actual.
|
|
67
|
-
actual.
|
|
62
|
+
expect(actual).to be(expected) # passes if actual.equal?(expected)
|
|
63
|
+
expect(actual).to equal(expected) # passes if actual.equal?(expected)
|
|
68
64
|
```
|
|
69
65
|
|
|
70
66
|
### Comparisons
|
|
71
67
|
|
|
72
68
|
```ruby
|
|
73
|
-
actual.
|
|
74
|
-
actual.
|
|
75
|
-
actual.
|
|
76
|
-
actual.
|
|
77
|
-
actual.
|
|
69
|
+
expect(actual).to be > expected
|
|
70
|
+
expect(actual).to be >= expected
|
|
71
|
+
expect(actual).to be <= expected
|
|
72
|
+
expect(actual).to be < expected
|
|
73
|
+
expect(actual).to be_within(delta).of(expected)
|
|
78
74
|
```
|
|
79
75
|
|
|
80
76
|
### Regular expressions
|
|
81
77
|
|
|
82
78
|
```ruby
|
|
83
|
-
actual.
|
|
84
|
-
actual.should =~ /expression/
|
|
79
|
+
expect(actual).to match(/expression/)
|
|
85
80
|
```
|
|
86
81
|
|
|
82
|
+
Note: The new `expect` syntax no longer supports the `=~` matcher.
|
|
83
|
+
|
|
87
84
|
### Types/classes
|
|
88
85
|
|
|
89
86
|
```ruby
|
|
90
|
-
actual.
|
|
91
|
-
actual.
|
|
87
|
+
expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected
|
|
88
|
+
expect(actual).to be_a(expected) # passes if actual.is_a?(expected)
|
|
89
|
+
expect(actual).to be_an(expected) # an alias for be_a
|
|
90
|
+
expect(actual).to be_a_kind_of(expected) # another alias
|
|
92
91
|
```
|
|
93
92
|
|
|
94
93
|
### Truthiness
|
|
95
94
|
|
|
96
95
|
```ruby
|
|
97
|
-
actual.
|
|
98
|
-
actual.
|
|
99
|
-
actual.
|
|
96
|
+
expect(actual).to be_truthy # passes if actual is truthy (not nil or false)
|
|
97
|
+
expect(actual).to be true # passes if actual == true
|
|
98
|
+
expect(actual).to be_falsy # passes if actual is falsy (nil or false)
|
|
99
|
+
expect(actual).to be false # passes if actual == false
|
|
100
|
+
expect(actual).to be_nil # passes if actual is nil
|
|
100
101
|
```
|
|
101
102
|
|
|
102
103
|
### Expecting errors
|
|
@@ -134,91 +135,118 @@ expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [
|
|
|
134
135
|
### Predicate matchers
|
|
135
136
|
|
|
136
137
|
```ruby
|
|
137
|
-
actual.
|
|
138
|
-
actual.
|
|
138
|
+
expect(actual).to be_xxx # passes if actual.xxx?
|
|
139
|
+
expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg)
|
|
139
140
|
```
|
|
140
141
|
|
|
141
142
|
### Ranges (Ruby >= 1.9 only)
|
|
142
143
|
|
|
143
144
|
```ruby
|
|
144
|
-
(1..10).
|
|
145
|
+
expect(1..10).to cover(3)
|
|
145
146
|
```
|
|
146
147
|
|
|
147
148
|
### Collection membership
|
|
148
149
|
|
|
149
150
|
```ruby
|
|
150
|
-
actual.
|
|
151
|
-
actual.
|
|
152
|
-
actual.
|
|
151
|
+
expect(actual).to include(expected)
|
|
152
|
+
expect(actual).to start_with(expected)
|
|
153
|
+
expect(actual).to end_with(expected)
|
|
154
|
+
|
|
155
|
+
expect(actual).to contain_exactly(individual, items)
|
|
156
|
+
# ...which is the same as:
|
|
157
|
+
expect(actual).to match_array(expected_array)
|
|
153
158
|
```
|
|
154
159
|
|
|
155
160
|
#### Examples
|
|
156
161
|
|
|
157
162
|
```ruby
|
|
158
|
-
[1,2,3].
|
|
159
|
-
[1,2,3].
|
|
160
|
-
[1,2,3].
|
|
161
|
-
[1,2,3].
|
|
162
|
-
[1,2,3].
|
|
163
|
-
[1,2,3].
|
|
164
|
-
{:a => 'b'}.
|
|
165
|
-
"this string".
|
|
166
|
-
"this string".
|
|
167
|
-
"this string".
|
|
163
|
+
expect([1, 2, 3]).to include(1)
|
|
164
|
+
expect([1, 2, 3]).to include(1, 2)
|
|
165
|
+
expect([1, 2, 3]).to start_with(1)
|
|
166
|
+
expect([1, 2, 3]).to start_with(1, 2)
|
|
167
|
+
expect([1, 2, 3]).to end_with(3)
|
|
168
|
+
expect([1, 2, 3]).to end_with(2, 3)
|
|
169
|
+
expect({:a => 'b'}).to include(:a => 'b')
|
|
170
|
+
expect("this string").to include("is str")
|
|
171
|
+
expect("this string").to start_with("this")
|
|
172
|
+
expect("this string").to end_with("ring")
|
|
173
|
+
expect([1, 2, 3]).to contain_exactly(2, 3, 1)
|
|
174
|
+
expect([1, 2, 3]).to match_array([3, 2, 1])
|
|
168
175
|
```
|
|
169
176
|
|
|
170
|
-
## `
|
|
177
|
+
## `should` syntax
|
|
171
178
|
|
|
172
|
-
In addition to the `
|
|
173
|
-
|
|
179
|
+
In addition to the `expect` syntax, rspec-expectations continues to support the
|
|
180
|
+
`should` syntax:
|
|
174
181
|
|
|
175
182
|
```ruby
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
actual.should eq expected
|
|
184
|
+
actual.should be > 3
|
|
185
|
+
[1, 2, 3].should_not include 4
|
|
179
186
|
```
|
|
180
187
|
|
|
181
|
-
|
|
182
|
-
configure it:
|
|
188
|
+
See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/master/Should.md)
|
|
183
189
|
|
|
184
|
-
|
|
185
|
-
RSpec.configure do |config|
|
|
186
|
-
config.expect_with :rspec do |c|
|
|
187
|
-
c.syntax = :expect
|
|
188
|
-
# or
|
|
189
|
-
c.syntax = :should
|
|
190
|
-
# or
|
|
191
|
-
c.syntax = [:should, :expect]
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
See
|
|
197
|
-
[RSpec::Expectations::Syntax#expect](http://rubydoc.info/gems/rspec-expectations/RSpec/Expectations/Syntax:expect)
|
|
198
|
-
for more information.
|
|
190
|
+
## Compound Matcher Expressions
|
|
199
191
|
|
|
200
|
-
|
|
192
|
+
You can also create compound matcher expressions using `and` or `or`:
|
|
201
193
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
194
|
+
``` ruby
|
|
195
|
+
expect(alphabet).to start_with("a").and end_with("z")
|
|
196
|
+
expect(stoplight.color).to eq("red").or eq("green").or eq("yellow")
|
|
197
|
+
```
|
|
206
198
|
|
|
207
|
-
|
|
208
|
-
[http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax](http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax)
|
|
209
|
-
for a detailed explanation.
|
|
199
|
+
## Composing Matchers
|
|
210
200
|
|
|
211
|
-
|
|
201
|
+
Many of the built-in matchers are designed to take matchers as
|
|
202
|
+
arguments, to allow you to flexibly specify only the essential
|
|
203
|
+
aspects of an object or data structure. In addition, all of the
|
|
204
|
+
built-in matchers have one or more aliases that provide better
|
|
205
|
+
phrasing for when they are used as arguments to another matcher.
|
|
212
206
|
|
|
213
|
-
|
|
214
|
-
[rspec-core](http://rubydoc.info/gems/rspec-core) uses `should` even when
|
|
215
|
-
`config.syntax = :expect`. It reads better than the alternative, and does not
|
|
216
|
-
require a global monkey patch:
|
|
207
|
+
### Examples
|
|
217
208
|
|
|
218
209
|
```ruby
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
210
|
+
expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) )
|
|
211
|
+
|
|
212
|
+
expect { s = "barn" }.to change { s }
|
|
213
|
+
.from( a_string_matching(/foo/) )
|
|
214
|
+
.to( a_string_matching(/bar/) )
|
|
215
|
+
|
|
216
|
+
expect(["barn", 2.45]).to contain_exactly(
|
|
217
|
+
a_value_within(0.1).of(2.5),
|
|
218
|
+
a_string_starting_with("bar")
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
expect(["barn", "food", 2.45]).to end_with(
|
|
222
|
+
a_string_matching("foo"),
|
|
223
|
+
a_value > 2
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
expect(["barn", 2.45]).to include( a_string_starting_with("bar") )
|
|
227
|
+
|
|
228
|
+
expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/))
|
|
229
|
+
|
|
230
|
+
hash = {
|
|
231
|
+
:a => {
|
|
232
|
+
:b => ["foo", 5],
|
|
233
|
+
:c => { :d => 2.05 }
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
expect(hash).to match(
|
|
238
|
+
:a => {
|
|
239
|
+
:b => a_collection_containing_exactly(
|
|
240
|
+
a_string_starting_with("f"),
|
|
241
|
+
an_instance_of(Fixnum)
|
|
242
|
+
),
|
|
243
|
+
:c => { :d => (a_value < 3) }
|
|
244
|
+
}
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
expect { |probe|
|
|
248
|
+
[1, 2, 3].each(&probe)
|
|
249
|
+
}.to yield_successive_args( a_value < 2, 2, a_value > 2 )
|
|
222
250
|
```
|
|
223
251
|
|
|
224
252
|
## Also see
|
|
@@ -226,3 +254,4 @@ end
|
|
|
226
254
|
* [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
|
|
227
255
|
* [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
|
|
228
256
|
* [http://github.com/rspec/rspec-mocks](http://github.com/rspec/rspec-mocks)
|
|
257
|
+
* [http://github.com/rspec/rspec-collection_matchers](https://github.com/rspec/rspec-collection_matchers)
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
RSpec::Support.require_rspec_expectations "syntax"
|
|
2
2
|
|
|
3
3
|
module RSpec
|
|
4
|
-
module
|
|
4
|
+
module Expectations
|
|
5
5
|
# Provides configuration options for rspec-expectations.
|
|
6
|
+
# If you are using rspec-core, you can access this via a
|
|
7
|
+
# block passed to `RSpec::Core::Configuration#expect_with`.
|
|
8
|
+
# Otherwise, you can access it via RSpec::Expectations.configuration.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# RSpec.configure do |rspec|
|
|
12
|
+
# rspec.expect_with :rspec do |c|
|
|
13
|
+
# # c is the config object
|
|
14
|
+
# end
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# # or
|
|
18
|
+
#
|
|
19
|
+
# RSpec::Expectations.configuration
|
|
6
20
|
class Configuration
|
|
7
21
|
# Configures the supported syntax.
|
|
8
22
|
# @param [Array<Symbol>, Symbol] values the syntaxes to enable
|
|
@@ -32,6 +46,10 @@ module RSpec
|
|
|
32
46
|
|
|
33
47
|
# The list of configured syntaxes.
|
|
34
48
|
# @return [Array<Symbol>] the list of configured syntaxes.
|
|
49
|
+
# @example
|
|
50
|
+
# unless RSpec::Matchers.configuration.syntax.include?(:expect)
|
|
51
|
+
# raise "this RSpec extension gem requires the rspec-expectations `:expect` syntax"
|
|
52
|
+
# end
|
|
35
53
|
def syntax
|
|
36
54
|
syntaxes = []
|
|
37
55
|
syntaxes << :should if Expectations::Syntax.should_enabled?
|
|
@@ -39,14 +57,21 @@ module RSpec
|
|
|
39
57
|
syntaxes
|
|
40
58
|
end
|
|
41
59
|
|
|
42
|
-
# color config for expectations
|
|
43
|
-
# fallback if rspec core not available
|
|
44
60
|
if ::RSpec.respond_to?(:configuration)
|
|
45
61
|
def color?
|
|
46
62
|
::RSpec.configuration.color_enabled?
|
|
47
63
|
end
|
|
48
64
|
else
|
|
49
|
-
|
|
65
|
+
# Indicates whether or not diffs should be colored.
|
|
66
|
+
# Delegates to rspec-core's color option if rspec-core
|
|
67
|
+
# is loaded; otherwise you can set it here.
|
|
68
|
+
def color=(value)
|
|
69
|
+
@color = value
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Indicates whether or not diffs should be colored.
|
|
73
|
+
# Delegates to rspec-core's color option if rspec-core
|
|
74
|
+
# is loaded; otherwise you can set it here.
|
|
50
75
|
def color?
|
|
51
76
|
@color
|
|
52
77
|
end
|
|
@@ -74,20 +99,25 @@ module RSpec
|
|
|
74
99
|
# will be used (including respecting the presence or absence of
|
|
75
100
|
# the `--backtrace` option).
|
|
76
101
|
#
|
|
77
|
-
#
|
|
78
|
-
# @return [#format_backtrace] the backtrace formatter
|
|
79
|
-
# @overload backtrace_formatter=
|
|
80
|
-
# @param value [#format_backtrace] sets the backtrace formatter
|
|
102
|
+
# @!attribute [rw] backtrace_formatter
|
|
81
103
|
attr_writer :backtrace_formatter
|
|
82
104
|
def backtrace_formatter
|
|
83
|
-
@backtrace_formatter ||= if defined?(::RSpec
|
|
84
|
-
|
|
105
|
+
@backtrace_formatter ||= if defined?(::RSpec.configuration.backtrace_formatter)
|
|
106
|
+
::RSpec.configuration.backtrace_formatter
|
|
85
107
|
else
|
|
86
108
|
NullBacktraceFormatter
|
|
87
109
|
end
|
|
88
110
|
end
|
|
89
111
|
|
|
112
|
+
# @private
|
|
113
|
+
def reset_syntaxes_to_default
|
|
114
|
+
self.syntax = [:should, :expect]
|
|
115
|
+
RSpec::Expectations::Syntax.warn_about_should!
|
|
116
|
+
end
|
|
117
|
+
|
|
90
118
|
# @api private
|
|
119
|
+
# Null implementation of a backtrace formatter used by default
|
|
120
|
+
# when rspec-core is not loaded. Does no filtering.
|
|
91
121
|
NullBacktraceFormatter = Module.new do
|
|
92
122
|
def self.format_backtrace(backtrace)
|
|
93
123
|
backtrace
|
|
@@ -95,14 +125,14 @@ module RSpec
|
|
|
95
125
|
end
|
|
96
126
|
end
|
|
97
127
|
|
|
98
|
-
# The configuration object
|
|
99
|
-
# @return [RSpec::
|
|
128
|
+
# The configuration object.
|
|
129
|
+
# @return [RSpec::Expectations::Configuration] the configuration object
|
|
100
130
|
def self.configuration
|
|
101
131
|
@configuration ||= Configuration.new
|
|
102
132
|
end
|
|
103
133
|
|
|
104
134
|
# set default syntax
|
|
105
|
-
configuration.
|
|
135
|
+
configuration.reset_syntaxes_to_default
|
|
106
136
|
end
|
|
107
137
|
end
|
|
108
138
|
|
|
@@ -1,23 +1,43 @@
|
|
|
1
1
|
module RSpec
|
|
2
2
|
module Expectations
|
|
3
3
|
# Wraps the target of an expectation.
|
|
4
|
+
#
|
|
4
5
|
# @example
|
|
5
|
-
# expect(something)
|
|
6
|
+
# expect(something) # => ExpectationTarget wrapping something
|
|
7
|
+
# expect { do_something } # => ExpectationTarget wrapping the block
|
|
6
8
|
#
|
|
7
9
|
# # used with `to`
|
|
8
10
|
# expect(actual).to eq(3)
|
|
9
11
|
#
|
|
10
|
-
# # with `
|
|
11
|
-
# expect(actual).
|
|
12
|
+
# # with `not_to`
|
|
13
|
+
# expect(actual).not_to eq(3)
|
|
14
|
+
#
|
|
15
|
+
# @note `ExpectationTarget` is not intended to be instantiated
|
|
16
|
+
# directly by users. Use `expect` instead.
|
|
12
17
|
class ExpectationTarget
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
# @private
|
|
19
|
+
# Used as a sentinel value to be able to tell when the user
|
|
20
|
+
# did not pass an argument. We can't use `nil` for that because
|
|
21
|
+
# `nil` is a valid value to pass.
|
|
22
|
+
UndefinedValue = Module.new
|
|
17
23
|
|
|
18
24
|
# @api private
|
|
19
|
-
def initialize(
|
|
20
|
-
@target =
|
|
25
|
+
def initialize(value)
|
|
26
|
+
@target = value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @private
|
|
30
|
+
def self.for(value, block)
|
|
31
|
+
if UndefinedValue.equal?(value)
|
|
32
|
+
unless block
|
|
33
|
+
raise ArgumentError, "You must pass either an argument or a block to `expect`."
|
|
34
|
+
end
|
|
35
|
+
BlockExpectationTarget.new(block)
|
|
36
|
+
elsif block
|
|
37
|
+
raise ArgumentError, "You cannot pass both an argument and a block to `expect`."
|
|
38
|
+
else
|
|
39
|
+
new(value)
|
|
40
|
+
end
|
|
21
41
|
end
|
|
22
42
|
|
|
23
43
|
# Runs the given expectation, passing if `matcher` returns true.
|
|
@@ -26,61 +46,74 @@ module RSpec
|
|
|
26
46
|
# expect { perform }.to raise_error
|
|
27
47
|
# @param [Matcher]
|
|
28
48
|
# matcher
|
|
29
|
-
# @param [String] message optional message to display when the expectation fails
|
|
49
|
+
# @param [String or Proc] message optional message to display when the expectation fails
|
|
30
50
|
# @return [Boolean] true if the expectation succeeds (else raises)
|
|
31
51
|
# @see RSpec::Matchers
|
|
32
52
|
def to(matcher=nil, message=nil, &block)
|
|
33
|
-
prevent_operator_matchers(:to
|
|
53
|
+
prevent_operator_matchers(:to) unless matcher
|
|
34
54
|
RSpec::Expectations::PositiveExpectationHandler.handle_matcher(@target, matcher, message, &block)
|
|
35
55
|
end
|
|
36
56
|
|
|
37
57
|
# Runs the given expectation, passing if `matcher` returns false.
|
|
38
58
|
# @example
|
|
39
|
-
# expect(value).to_not eq(5)
|
|
40
59
|
# expect(value).not_to eq(5)
|
|
41
60
|
# @param [Matcher]
|
|
42
61
|
# matcher
|
|
43
|
-
# @param [String] message optional message to display when the expectation fails
|
|
62
|
+
# @param [String or Proc] message optional message to display when the expectation fails
|
|
44
63
|
# @return [Boolean] false if the negative expectation succeeds (else raises)
|
|
45
64
|
# @see RSpec::Matchers
|
|
46
|
-
def
|
|
47
|
-
prevent_operator_matchers(:
|
|
65
|
+
def not_to(matcher=nil, message=nil, &block)
|
|
66
|
+
prevent_operator_matchers(:not_to) unless matcher
|
|
48
67
|
RSpec::Expectations::NegativeExpectationHandler.handle_matcher(@target, matcher, message, &block)
|
|
49
68
|
end
|
|
50
|
-
alias not_to
|
|
69
|
+
alias to_not not_to
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
return if deprecated_should_enabled?
|
|
71
|
+
private
|
|
54
72
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
def prevent_operator_matchers(verb)
|
|
74
|
+
raise ArgumentError, "The expect syntax does not support operator matchers, " +
|
|
75
|
+
"so you must pass a matcher to `##{verb}`."
|
|
76
|
+
end
|
|
77
|
+
end
|
|
59
78
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
# @private
|
|
80
|
+
# Validates the provided matcher to ensure it supports block
|
|
81
|
+
# expectations, in order to avoid user confusion when they
|
|
82
|
+
# use a block thinking the expectation will be on the return
|
|
83
|
+
# value of the block rather than the block itself.
|
|
84
|
+
class BlockExpectationTarget < ExpectationTarget
|
|
85
|
+
def to(matcher, message=nil, &block)
|
|
86
|
+
enforce_block_expectation(matcher)
|
|
87
|
+
super
|
|
88
|
+
end
|
|
64
89
|
|
|
65
|
-
|
|
90
|
+
def not_to(matcher, message=nil, &block)
|
|
91
|
+
enforce_block_expectation(matcher)
|
|
92
|
+
super
|
|
66
93
|
end
|
|
94
|
+
alias to_not not_to
|
|
67
95
|
|
|
68
|
-
|
|
69
|
-
return unless deprecated_should_enabled?
|
|
96
|
+
private
|
|
70
97
|
|
|
71
|
-
|
|
72
|
-
|
|
98
|
+
def enforce_block_expectation(matcher)
|
|
99
|
+
return if supports_block_expectations?(matcher)
|
|
73
100
|
|
|
74
|
-
|
|
101
|
+
raise ExpectationNotMetError,
|
|
102
|
+
"You must pass an argument rather than a block to use the provided " +
|
|
103
|
+
"matcher (#{description_of matcher}), or the matcher must implement " +
|
|
104
|
+
"`supports_block_expectations?`."
|
|
75
105
|
end
|
|
76
106
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
107
|
+
def supports_block_expectations?(matcher)
|
|
108
|
+
matcher.supports_block_expectations?
|
|
109
|
+
rescue NoMethodError
|
|
110
|
+
false
|
|
111
|
+
end
|
|
81
112
|
|
|
82
|
-
|
|
83
|
-
|
|
113
|
+
def description_of(matcher)
|
|
114
|
+
matcher.description
|
|
115
|
+
rescue NoMethodError
|
|
116
|
+
matcher.inspect
|
|
84
117
|
end
|
|
85
118
|
end
|
|
86
119
|
end
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
RSpec::Support.require_rspec_support 'differ'
|
|
2
|
+
|
|
1
3
|
module RSpec
|
|
2
4
|
module Expectations
|
|
3
5
|
class << self
|
|
4
6
|
# @private
|
|
5
7
|
def differ
|
|
6
|
-
|
|
8
|
+
RSpec::Support::Differ.new(
|
|
9
|
+
:object_preparer => lambda {|object| RSpec::Matchers::Composable.surface_descriptions_in(object) },
|
|
10
|
+
:color => RSpec::Matchers.configuration.color?
|
|
11
|
+
)
|
|
7
12
|
end
|
|
8
13
|
|
|
9
14
|
# Raises an RSpec::Expectations::ExpectationNotMetError with message.
|
|
@@ -16,53 +21,16 @@ module RSpec
|
|
|
16
21
|
def fail_with(message, expected=nil, actual=nil)
|
|
17
22
|
if !message
|
|
18
23
|
raise ArgumentError, "Failure message is nil. Does your matcher define the " +
|
|
19
|
-
"appropriate
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
if actual && expected
|
|
23
|
-
if all_strings?(actual, expected)
|
|
24
|
-
if any_multiline_strings?(actual, expected)
|
|
25
|
-
message << "\nDiff:" << differ.diff_as_string(coerce_to_string(actual), coerce_to_string(expected))
|
|
26
|
-
end
|
|
27
|
-
elsif no_procs?(actual, expected) && no_numbers?(actual, expected)
|
|
28
|
-
message << "\nDiff:" << differ.diff_as_object(actual, expected)
|
|
29
|
-
end
|
|
24
|
+
"appropriate failure_message[_when_negated] method to return a string?"
|
|
30
25
|
end
|
|
31
26
|
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def no_procs?(*args)
|
|
38
|
-
args.flatten.none? {|a| Proc === a}
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def all_strings?(*args)
|
|
42
|
-
args.flatten.all? {|a| String === a}
|
|
43
|
-
end
|
|
27
|
+
diff = differ.diff(actual, expected)
|
|
44
28
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def no_numbers?(*args)
|
|
50
|
-
args.flatten.none? {|a| Numeric === a}
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def coerce_to_string(string_or_array)
|
|
54
|
-
return string_or_array unless Array === string_or_array
|
|
55
|
-
string_or_array.join(',')
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
if String.method_defined?(:encoding)
|
|
59
|
-
def multiline?(string)
|
|
60
|
-
string.include?("\n".encode(string.encoding))
|
|
61
|
-
end
|
|
62
|
-
else
|
|
63
|
-
def multiline?(string)
|
|
64
|
-
string.include?("\n")
|
|
29
|
+
unless diff.empty?
|
|
30
|
+
message = "#{message}\nDiff:#{diff}"
|
|
65
31
|
end
|
|
32
|
+
|
|
33
|
+
raise RSpec::Expectations::ExpectationNotMetError.new(message)
|
|
66
34
|
end
|
|
67
35
|
end
|
|
68
36
|
end
|