rspec-expectations 3.0.0.beta1 → 3.0.0.beta2
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.
- data.tar.gz.sig +2 -2
- data/.yardopts +1 -0
- data/Changelog.md +138 -0
- data/README.md +75 -8
- data/features/README.md +2 -2
- data/features/built_in_matchers/README.md +12 -9
- data/features/built_in_matchers/comparisons.feature +2 -2
- data/features/built_in_matchers/contain_exactly.feature +46 -0
- data/features/built_in_matchers/expect_change.feature +2 -2
- data/features/built_in_matchers/include.feature +0 -48
- data/features/built_in_matchers/output.feature +70 -0
- data/features/composing_matchers.feature +250 -0
- data/features/compound_expectations.feature +45 -0
- data/features/custom_matchers/access_running_example.feature +1 -1
- data/features/custom_matchers/define_matcher.feature +6 -6
- data/features/custom_matchers/define_matcher_outside_rspec.feature +4 -8
- data/features/test_frameworks/{test_unit.feature → minitest.feature} +11 -11
- data/lib/rspec/expectations.rb +31 -42
- data/lib/rspec/expectations/diff_presenter.rb +141 -0
- data/lib/rspec/expectations/differ.rb +22 -132
- data/lib/rspec/expectations/encoded_string.rb +56 -0
- data/lib/rspec/expectations/expectation_target.rb +0 -30
- data/lib/rspec/expectations/fail_with.rb +2 -2
- data/lib/rspec/expectations/handler.rb +128 -31
- data/lib/rspec/expectations/minitest_integration.rb +16 -0
- data/lib/rspec/expectations/syntax.rb +4 -58
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +298 -60
- data/lib/rspec/matchers/aliased_matcher.rb +35 -0
- data/lib/rspec/matchers/built_in.rb +37 -33
- data/lib/rspec/matchers/built_in/base_matcher.rb +25 -15
- data/lib/rspec/matchers/built_in/be.rb +23 -31
- data/lib/rspec/matchers/built_in/be_between.rb +55 -0
- data/lib/rspec/matchers/built_in/be_within.rb +15 -11
- data/lib/rspec/matchers/built_in/change.rb +198 -81
- data/lib/rspec/matchers/built_in/compound.rb +106 -0
- data/lib/rspec/matchers/built_in/contain_exactly.rb +245 -0
- data/lib/rspec/matchers/built_in/eq.rb +43 -4
- data/lib/rspec/matchers/built_in/eql.rb +2 -2
- data/lib/rspec/matchers/built_in/equal.rb +35 -18
- data/lib/rspec/matchers/built_in/has.rb +16 -15
- data/lib/rspec/matchers/built_in/include.rb +45 -23
- data/lib/rspec/matchers/built_in/match.rb +6 -3
- data/lib/rspec/matchers/built_in/operators.rb +103 -0
- data/lib/rspec/matchers/built_in/output.rb +108 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +9 -15
- data/lib/rspec/matchers/built_in/respond_to.rb +5 -4
- data/lib/rspec/matchers/built_in/satisfy.rb +4 -3
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +37 -16
- data/lib/rspec/matchers/built_in/throw_symbol.rb +6 -5
- data/lib/rspec/matchers/built_in/yield.rb +31 -29
- data/lib/rspec/matchers/composable.rb +138 -0
- data/lib/rspec/matchers/dsl.rb +330 -0
- data/lib/rspec/matchers/generated_descriptions.rb +6 -6
- data/lib/rspec/matchers/matcher_delegator.rb +33 -0
- data/lib/rspec/matchers/pretty.rb +13 -2
- data/spec/rspec/expectations/{differ_spec.rb → diff_presenter_spec.rb} +56 -36
- data/spec/rspec/expectations/encoded_string_spec.rb +74 -0
- data/spec/rspec/expectations/extensions/kernel_spec.rb +11 -11
- data/spec/rspec/expectations/fail_with_spec.rb +8 -8
- data/spec/rspec/expectations/handler_spec.rb +27 -49
- data/spec/rspec/expectations/minitest_integration_spec.rb +27 -0
- data/spec/rspec/expectations/syntax_spec.rb +17 -67
- data/spec/rspec/expectations_spec.rb +7 -52
- data/spec/rspec/matchers/aliased_matcher_spec.rb +48 -0
- data/spec/rspec/matchers/aliases_spec.rb +449 -0
- data/spec/rspec/matchers/{base_matcher_spec.rb → built_in/base_matcher_spec.rb} +24 -3
- data/spec/rspec/matchers/built_in/be_between_spec.rb +159 -0
- data/spec/rspec/matchers/{be_instance_of_spec.rb → built_in/be_instance_of_spec.rb} +0 -0
- data/spec/rspec/matchers/{be_kind_of_spec.rb → built_in/be_kind_of_spec.rb} +0 -0
- data/spec/rspec/matchers/{be_spec.rb → built_in/be_spec.rb} +76 -32
- data/spec/rspec/matchers/{be_within_spec.rb → built_in/be_within_spec.rb} +6 -2
- data/spec/rspec/matchers/{change_spec.rb → built_in/change_spec.rb} +310 -69
- data/spec/rspec/matchers/built_in/compound_spec.rb +292 -0
- data/spec/rspec/matchers/built_in/contain_exactly_spec.rb +441 -0
- data/spec/rspec/matchers/{cover_spec.rb → built_in/cover_spec.rb} +0 -0
- data/spec/rspec/matchers/built_in/eq_spec.rb +156 -0
- data/spec/rspec/matchers/{eql_spec.rb → built_in/eql_spec.rb} +2 -2
- data/spec/rspec/matchers/built_in/equal_spec.rb +106 -0
- data/spec/rspec/matchers/{exist_spec.rb → built_in/exist_spec.rb} +1 -1
- data/spec/rspec/matchers/{has_spec.rb → built_in/has_spec.rb} +39 -0
- data/spec/rspec/matchers/{include_spec.rb → built_in/include_spec.rb} +118 -109
- data/spec/rspec/matchers/{match_spec.rb → built_in/match_spec.rb} +30 -2
- data/spec/rspec/matchers/{operator_matcher_spec.rb → built_in/operators_spec.rb} +26 -26
- data/spec/rspec/matchers/built_in/output_spec.rb +165 -0
- data/spec/rspec/matchers/{raise_error_spec.rb → built_in/raise_error_spec.rb} +81 -11
- data/spec/rspec/matchers/{respond_to_spec.rb → built_in/respond_to_spec.rb} +0 -0
- data/spec/rspec/matchers/{satisfy_spec.rb → built_in/satisfy_spec.rb} +0 -0
- data/spec/rspec/matchers/{start_with_end_with_spec.rb → built_in/start_and_end_with_spec.rb} +82 -15
- data/spec/rspec/matchers/{throw_symbol_spec.rb → built_in/throw_symbol_spec.rb} +29 -10
- data/spec/rspec/matchers/{yield_spec.rb → built_in/yield_spec.rb} +90 -0
- data/spec/rspec/matchers/configuration_spec.rb +7 -39
- data/spec/rspec/matchers/description_generation_spec.rb +22 -6
- data/spec/rspec/matchers/dsl_spec.rb +838 -0
- data/spec/rspec/matchers/legacy_spec.rb +101 -0
- data/spec/rspec/matchers_spec.rb +74 -0
- data/spec/spec_helper.rb +35 -21
- data/spec/support/shared_examples.rb +26 -4
- metadata +172 -116
- metadata.gz.sig +3 -4
- checksums.yaml +0 -15
- checksums.yaml.gz.sig +0 -0
- data/features/built_in_matchers/match_array.feature +0 -37
- data/lib/rspec/expectations/errors.rb +0 -9
- data/lib/rspec/expectations/extensions.rb +0 -1
- data/lib/rspec/expectations/extensions/object.rb +0 -29
- data/lib/rspec/matchers/built_in/match_array.rb +0 -51
- data/lib/rspec/matchers/compatibility.rb +0 -14
- data/lib/rspec/matchers/matcher.rb +0 -301
- data/lib/rspec/matchers/method_missing.rb +0 -12
- data/lib/rspec/matchers/operator_matcher.rb +0 -99
- data/lib/rspec/matchers/test_unit_integration.rb +0 -11
- data/spec/rspec/matchers/eq_spec.rb +0 -60
- data/spec/rspec/matchers/equal_spec.rb +0 -78
- data/spec/rspec/matchers/include_matcher_integration_spec.rb +0 -30
- data/spec/rspec/matchers/match_array_spec.rb +0 -194
- data/spec/rspec/matchers/matcher_spec.rb +0 -706
- data/spec/rspec/matchers/matchers_spec.rb +0 -36
- data/spec/rspec/matchers/method_missing_spec.rb +0 -28
- data/spec/support/classes.rb +0 -56
- data/spec/support/in_sub_process.rb +0 -37
- data/spec/support/ruby_version.rb +0 -10
@@ -0,0 +1,70 @@
|
|
1
|
+
Feature: output matcher
|
2
|
+
|
3
|
+
The `output` matcher provides a way to assert that the
|
4
|
+
has emitted content to either `$stdout` or `$stderr`.
|
5
|
+
|
6
|
+
With no arg, passes if the block outputs `to_stdout` or `to_stderr`.
|
7
|
+
With a string, passes if the blocks outputs that specific string
|
8
|
+
`to_stdout` or `to_stderr`. With a regexp or matcher, passes if the
|
9
|
+
blocks outputs a string `to_stdout` or `to_stderr` that matches.
|
10
|
+
|
11
|
+
Note: This matcher works by temporarily replacing `$stdout` or `$stderr`,
|
12
|
+
so it's not able to intercept stream output that explicitly uses `STDOUT`/`STDERR`
|
13
|
+
or that uses a reference to `$stdout`/`$stderr` that was stored before the
|
14
|
+
matcher is used.
|
15
|
+
|
16
|
+
Scenario: output_to_stdout matcher
|
17
|
+
Given a file named "output_to_stdout_spec.rb" with:
|
18
|
+
"""ruby
|
19
|
+
describe "output.to_stdout matcher" do
|
20
|
+
specify { expect { print('foo') }.to output.to_stdout }
|
21
|
+
specify { expect { print('foo') }.to output('foo').to_stdout }
|
22
|
+
specify { expect { print('foo') }.to output(/foo/).to_stdout }
|
23
|
+
specify { expect { }.to_not output.to_stdout }
|
24
|
+
specify { expect { print('foo') }.to_not output('bar').to_stdout }
|
25
|
+
specify { expect { print('foo') }.to_not output(/bar/).to_stdout }
|
26
|
+
|
27
|
+
# deliberate failures
|
28
|
+
specify { expect { }.to output.to_stdout }
|
29
|
+
specify { expect { }.to output('foo').to_stdout }
|
30
|
+
specify { expect { print('foo') }.to_not output.to_stdout }
|
31
|
+
specify { expect { print('foo') }.to output('bar').to_stdout }
|
32
|
+
specify { expect { print('foo') }.to output(/bar/).to_stdout }
|
33
|
+
end
|
34
|
+
"""
|
35
|
+
When I run `rspec output_to_stdout_spec.rb`
|
36
|
+
Then the output should contain all of these:
|
37
|
+
| 11 examples, 5 failures |
|
38
|
+
| expected block to output to stdout, but did not |
|
39
|
+
| expected block to not output to stdout, but did |
|
40
|
+
| expected block to output "bar" to stdout, but output "foo" |
|
41
|
+
| expected block to output "foo" to stdout, but output nothing |
|
42
|
+
| expected block to output /bar/ to stdout, but output "foo" |
|
43
|
+
|
44
|
+
Scenario: output_to_stderr matcher
|
45
|
+
Given a file named "output_to_stderr.rb" with:
|
46
|
+
"""ruby
|
47
|
+
describe "output_to_stderr matcher" do
|
48
|
+
specify { expect { warn('foo') }.to output.to_stderr }
|
49
|
+
specify { expect { warn('foo') }.to output("foo\n").to_stderr }
|
50
|
+
specify { expect { warn('foo') }.to output(/foo/).to_stderr }
|
51
|
+
specify { expect { }.to_not output.to_stderr }
|
52
|
+
specify { expect { warn('foo') }.to_not output('bar').to_stderr }
|
53
|
+
specify { expect { warn('foo') }.to_not output(/bar/).to_stderr }
|
54
|
+
|
55
|
+
# deliberate failures
|
56
|
+
specify { expect { }.to output.to_stderr }
|
57
|
+
specify { expect { }.to output('foo').to_stderr }
|
58
|
+
specify { expect { warn('foo') }.to_not output.to_stderr }
|
59
|
+
specify { expect { warn('foo') }.to output('bar').to_stderr }
|
60
|
+
specify { expect { warn('foo') }.to output(/bar/).to_stderr }
|
61
|
+
end
|
62
|
+
"""
|
63
|
+
When I run `rspec output_to_stderr.rb`
|
64
|
+
Then the output should contain all of these:
|
65
|
+
| 11 examples, 5 failures |
|
66
|
+
| expected block to output to stderr, but did not |
|
67
|
+
| expected block to not output to stderr, but did |
|
68
|
+
| expected block to output "bar" to stderr, but output "foo\n" |
|
69
|
+
| expected block to output "foo" to stderr, but output nothing |
|
70
|
+
| expected block to output /bar/ to stderr, but output "foo\n" |
|
@@ -0,0 +1,250 @@
|
|
1
|
+
Feature: Composing Matchers
|
2
|
+
|
3
|
+
RSpec's matchers are designed to be composable so that you can
|
4
|
+
combine them to express the exact details of what you expect
|
5
|
+
but nothing more. This can help you avoid writing over-specified
|
6
|
+
brittle specs, by using a matcher in place of an exact value to
|
7
|
+
specify only the essential aspects of what you expect.
|
8
|
+
|
9
|
+
The following matchers accept matchers as arguments:
|
10
|
+
|
11
|
+
* `change { }.by(matcher)`
|
12
|
+
* `change { }.from(matcher).to(matcher)`
|
13
|
+
* `contain_exactly(matcher, matcher, matcher)`
|
14
|
+
* `end_with(matcher, matcher)`
|
15
|
+
* `include(matcher, matcher)`
|
16
|
+
* `include(:key => matcher, :other => matcher)`
|
17
|
+
* `match(arbitrary_nested_structure_with_matchers)`
|
18
|
+
* `output(matcher).to_stdout`
|
19
|
+
* `output(matcher).to_stderr`
|
20
|
+
* `raise_error(ErrorClass, matcher)`
|
21
|
+
* `start_with(matcher, matcher)`
|
22
|
+
* `throw_symbol(:sym, matcher)`
|
23
|
+
* `yield_with_args(matcher, matcher)`
|
24
|
+
* `yield_successive_args(matcher, matcher)`
|
25
|
+
|
26
|
+
Note that many built-in matchers do not accept matcher arguments
|
27
|
+
because they have precise semantics that do not allow for a matcher
|
28
|
+
argument. For example, `equal(some_object)` is designed to pass only
|
29
|
+
if the actual and expected arguments are references to the same object.
|
30
|
+
It would not make sense to support a matcher argument here.
|
31
|
+
|
32
|
+
All of RSpec's built-in matchers have one or more aliases that allow
|
33
|
+
you to use a noun-phrase rather than verb form since they read better
|
34
|
+
as composed arguments. They also provide customized failure output so
|
35
|
+
that the failure message reads better as well.
|
36
|
+
|
37
|
+
A full list of these aliases is out of scope here, but here are some
|
38
|
+
of the aliases used below:
|
39
|
+
|
40
|
+
* `be < 2` => `a_value < 2`
|
41
|
+
* `be > 2` => `a_value > 2`
|
42
|
+
* `be_an_instance_of` => `an_instance_of`
|
43
|
+
* `be_within` => `a_value_within`
|
44
|
+
* `contain_exactly` => `a_collection_containing_exactly`
|
45
|
+
* `end_with` => `a_string_ending_with`, `ending_with`
|
46
|
+
* `match` => `a_string_matching`
|
47
|
+
* `start_with` => `a_string_starting_with`
|
48
|
+
|
49
|
+
For a full list, see the API docs for the `RSpec::Matchers` module.
|
50
|
+
|
51
|
+
Scenario: Composing matchers with `change`
|
52
|
+
Given a file named "change_spec.rb" with:
|
53
|
+
"""
|
54
|
+
describe "Passing matchers to `change`" do
|
55
|
+
specify "you can pass a matcher to `by`" do
|
56
|
+
k = 0
|
57
|
+
expect { k += 1.05 }.to change { k }.
|
58
|
+
by( a_value_within(0.1).of(1.0) )
|
59
|
+
end
|
60
|
+
|
61
|
+
specify "you can pass matchers to `from` and `to" do
|
62
|
+
s = "food"
|
63
|
+
expect { s = "barn" }.to change { s }.
|
64
|
+
from( a_string_matching(/foo/) ).
|
65
|
+
to( a_string_matching(/bar/) )
|
66
|
+
end
|
67
|
+
end
|
68
|
+
"""
|
69
|
+
When I run `rspec change_spec.rb`
|
70
|
+
Then the examples should all pass
|
71
|
+
|
72
|
+
Scenario: Composing matchers with `contain_exactly`
|
73
|
+
Given a file named "contain_exactly_spec.rb" with:
|
74
|
+
"""
|
75
|
+
describe "Passing matchers to `contain_exactly`" do
|
76
|
+
specify "you can pass matchers in place of exact values" do
|
77
|
+
expect(["barn", 2.45]).to contain_exactly(
|
78
|
+
a_value_within(0.1).of(2.5),
|
79
|
+
a_string_starting_with("bar")
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
"""
|
84
|
+
When I run `rspec contain_exactly_spec.rb`
|
85
|
+
Then the examples should all pass
|
86
|
+
|
87
|
+
Scenario: Composing matchers with `end_with`
|
88
|
+
Given a file named "end_with_spec.rb" with:
|
89
|
+
"""
|
90
|
+
describe "Passing matchers to `end_with`" do
|
91
|
+
specify "you can pass matchers in place of exact values" do
|
92
|
+
expect(["barn", "food", 2.45]).to end_with(
|
93
|
+
a_string_matching("foo"),
|
94
|
+
a_value > 2
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
"""
|
99
|
+
When I run `rspec end_with_spec.rb`
|
100
|
+
Then the examples should all pass
|
101
|
+
|
102
|
+
Scenario: Composing matchers with `include`
|
103
|
+
Given a file named "include_spec.rb" with:
|
104
|
+
"""
|
105
|
+
describe "Passing matchers to `contain_exactly`" do
|
106
|
+
specify "you can use matchers in place of array values" do
|
107
|
+
expect(["barn", 2.45]).to include( a_string_starting_with("bar") )
|
108
|
+
end
|
109
|
+
|
110
|
+
specify "you can use matchers in place of hash values" do
|
111
|
+
expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/))
|
112
|
+
end
|
113
|
+
|
114
|
+
specify "you can use matchers in place of hash keys" do
|
115
|
+
expect("food" => "is good").to include( a_string_matching(/foo/) )
|
116
|
+
end
|
117
|
+
end
|
118
|
+
"""
|
119
|
+
When I run `rspec include_spec.rb`
|
120
|
+
Then the examples should all pass
|
121
|
+
|
122
|
+
Scenario: Composing matchers with `match`:
|
123
|
+
Given a file named "match_spec.rb" with:
|
124
|
+
"""
|
125
|
+
describe "Passing matchers to `match`" do
|
126
|
+
specify "you can match nested data structures against matchers" do
|
127
|
+
hash = {
|
128
|
+
:a => {
|
129
|
+
:b => ["foo", 5],
|
130
|
+
:c => { :d => 2.05 }
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
expect(hash).to match(
|
135
|
+
:a => {
|
136
|
+
:b => a_collection_containing_exactly(
|
137
|
+
a_string_starting_with("f"),
|
138
|
+
an_instance_of(Fixnum)
|
139
|
+
),
|
140
|
+
:c => { :d => (a_value < 3) }
|
141
|
+
}
|
142
|
+
)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
"""
|
146
|
+
When I run `rspec match_spec.rb`
|
147
|
+
Then the examples should all pass
|
148
|
+
|
149
|
+
Scenario: Composing matchers with `output`
|
150
|
+
Given a file named "output_spec.rb" with:
|
151
|
+
"""
|
152
|
+
describe "Passing matchers to `output`" do
|
153
|
+
specify "you can pass a matcher in place of the output (to_stdout)" do
|
154
|
+
expect {
|
155
|
+
print 'foo'
|
156
|
+
}.to output(a_string_starting_with('f')).to_stdout
|
157
|
+
end
|
158
|
+
specify "you can pass a matcher in place of the output (to_stderr)" do
|
159
|
+
expect {
|
160
|
+
warn 'foo'
|
161
|
+
}.to output(a_string_starting_with('f')).to_stderr
|
162
|
+
end
|
163
|
+
end
|
164
|
+
"""
|
165
|
+
When I run `rspec output_spec.rb`
|
166
|
+
Then the examples should all pass
|
167
|
+
|
168
|
+
Scenario: Composing matchers with `raise_error`
|
169
|
+
Given a file named "raise_error_spec.rb" with:
|
170
|
+
"""
|
171
|
+
describe "Passing matchers to `raise_error`" do
|
172
|
+
specify "you can pass a matcher in place of the message" do
|
173
|
+
expect {
|
174
|
+
raise RuntimeError, "this goes boom"
|
175
|
+
}.to raise_error(RuntimeError, a_string_ending_with("boom"))
|
176
|
+
end
|
177
|
+
end
|
178
|
+
"""
|
179
|
+
When I run `rspec raise_error_spec.rb`
|
180
|
+
Then the examples should all pass
|
181
|
+
|
182
|
+
Scenario: Composing matchers with `start_with`
|
183
|
+
Given a file named "start_with_spec.rb" with:
|
184
|
+
"""
|
185
|
+
describe "Passing matchers to `start_with`" do
|
186
|
+
specify "you can pass matchers in place of exact values" do
|
187
|
+
expect(["barn", "food", 2.45]).to start_with(
|
188
|
+
a_string_matching("bar"),
|
189
|
+
a_string_matching("foo")
|
190
|
+
)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
"""
|
194
|
+
When I run `rspec start_with_spec.rb`
|
195
|
+
Then the examples should all pass
|
196
|
+
|
197
|
+
Scenario: Composing matchers with `throw_symbol`
|
198
|
+
Given a file named "throw_symbol_spec.rb" with:
|
199
|
+
"""
|
200
|
+
describe "Passing matchers to `throw_symbol`" do
|
201
|
+
specify "you can pass a matcher in place of a throw arg" do
|
202
|
+
expect {
|
203
|
+
throw :pi, Math::PI
|
204
|
+
}.to throw_symbol(:pi, a_value_within(0.01).of(3.14))
|
205
|
+
end
|
206
|
+
end
|
207
|
+
"""
|
208
|
+
When I run `rspec throw_symbol_spec.rb`
|
209
|
+
Then the examples should all pass
|
210
|
+
|
211
|
+
Scenario: Composing matchers with `yield_with_args`
|
212
|
+
Given a file named "yield_with_args_spec.rb" with:
|
213
|
+
"""
|
214
|
+
describe "Passing matchers to `yield_with_args`" do
|
215
|
+
specify "you can pass matchers in place of the args" do
|
216
|
+
expect { |probe|
|
217
|
+
"food".tap(&probe)
|
218
|
+
}.to yield_with_args(a_string_matching(/foo/))
|
219
|
+
end
|
220
|
+
end
|
221
|
+
"""
|
222
|
+
When I run `rspec yield_with_args_spec.rb`
|
223
|
+
Then the examples should all pass
|
224
|
+
|
225
|
+
Scenario: Composing matchers with `yield_successive_args`
|
226
|
+
Given a file named "yield_successive_args_spec.rb" with:
|
227
|
+
"""
|
228
|
+
describe "Passing matchers to `yield_successive_args`" do
|
229
|
+
specify "you can pass matchers in place of the args" do
|
230
|
+
expect { |probe|
|
231
|
+
[1, 2, 3].each(&probe)
|
232
|
+
}.to yield_successive_args(a_value < 2, 2, a_value > 2)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
"""
|
236
|
+
When I run `rspec yield_successive_args_spec.rb`
|
237
|
+
Then the examples should all pass
|
238
|
+
|
239
|
+
Scenario: Composing matchers using a compound `and` expression
|
240
|
+
Given a file named "include_spec.rb" with:
|
241
|
+
"""
|
242
|
+
describe "Passing a compound matcher expression to `include`" do
|
243
|
+
example do
|
244
|
+
expect(["food", "drink"]).to include( a_string_starting_with("f").and ending_with("d"))
|
245
|
+
end
|
246
|
+
end
|
247
|
+
"""
|
248
|
+
When I run `rspec include_spec.rb`
|
249
|
+
Then the examples should all pass
|
250
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
Feature: Compound Expectations
|
2
|
+
|
3
|
+
Matchers can be composed using `and` or `or` to make compound expectations.
|
4
|
+
|
5
|
+
Scenario: Use `and` to chain expectations
|
6
|
+
Given a file named "compound_and_matcher_spec.rb" with:
|
7
|
+
"""ruby
|
8
|
+
describe "A compound `and` matcher" do
|
9
|
+
let(:string) { "foo bar bazz" }
|
10
|
+
|
11
|
+
it "passes when both are true" do
|
12
|
+
expect(string).to start_with("foo").and end_with("bazz")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "fails when the first matcher fails" do
|
16
|
+
expect(string).to start_with("bar").and end_with("bazz")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "fails when the second matcher fails" do
|
20
|
+
expect(string).to start_with("foo").and end_with("bar")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
"""
|
24
|
+
When I run `rspec compound_and_matcher_spec.rb`
|
25
|
+
Then the output should contain "3 examples, 2 failures"
|
26
|
+
|
27
|
+
Scenario: Use `or` to chain expectations
|
28
|
+
Given a file named "stoplight_spec.rb" with:
|
29
|
+
"""ruby
|
30
|
+
class StopLight
|
31
|
+
def color
|
32
|
+
%w[ green yellow red ].shuffle.first
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe StopLight, "#color" do
|
37
|
+
it "is green, yellow or red" do
|
38
|
+
light = StopLight.new
|
39
|
+
expect(light.color).to eq("green").or eq("yellow").or eq("red")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
"""
|
43
|
+
When I run `rspec stoplight_spec.rb`
|
44
|
+
Then the example should pass
|
45
|
+
|
@@ -49,5 +49,5 @@ Feature: access running example
|
|
49
49
|
When I run `rspec ./example_spec.rb`
|
50
50
|
Then the output should contain "1 example, 1 failure"
|
51
51
|
And the output should match /undefined.*method/
|
52
|
-
And the output should contain "RSpec::Matchers::DSL::Matcher
|
52
|
+
And the output should contain "RSpec::Matchers::DSL::Matcher"
|
53
53
|
And the output should not contain "ExampleGroup"
|
@@ -46,7 +46,7 @@ Feature: define matcher
|
|
46
46
|
And the output should contain "expected 9 to be a multiple of 4"
|
47
47
|
And the output should contain "expected 9 not to be a multiple of 3"
|
48
48
|
|
49
|
-
Scenario: overriding the
|
49
|
+
Scenario: overriding the failure_message
|
50
50
|
Given a file named "matcher_with_failure_message_spec.rb" with:
|
51
51
|
"""ruby
|
52
52
|
require 'rspec/expectations'
|
@@ -55,7 +55,7 @@ Feature: define matcher
|
|
55
55
|
match do |actual|
|
56
56
|
actual % expected == 0
|
57
57
|
end
|
58
|
-
|
58
|
+
failure_message do |actual|
|
59
59
|
"expected that #{actual} would be a multiple of #{expected}"
|
60
60
|
end
|
61
61
|
end
|
@@ -70,7 +70,7 @@ Feature: define matcher
|
|
70
70
|
And the stdout should contain "1 example, 1 failure"
|
71
71
|
And the stdout should contain "expected that 9 would be a multiple of 4"
|
72
72
|
|
73
|
-
Scenario: overriding the
|
73
|
+
Scenario: overriding the failure_message_when_negated
|
74
74
|
Given a file named "matcher_with_failure_for_message_spec.rb" with:
|
75
75
|
"""ruby
|
76
76
|
require 'rspec/expectations'
|
@@ -79,7 +79,7 @@ Feature: define matcher
|
|
79
79
|
match do |actual|
|
80
80
|
actual % expected == 0
|
81
81
|
end
|
82
|
-
|
82
|
+
failure_message_when_negated do |actual|
|
83
83
|
"expected that #{actual} would not be a multiple of #{expected}"
|
84
84
|
end
|
85
85
|
end
|
@@ -261,11 +261,11 @@ Feature: define matcher
|
|
261
261
|
Given a file named "matcher_with_separate_should_not_logic_spec.rb" with:
|
262
262
|
"""ruby
|
263
263
|
RSpec::Matchers.define :contain do |*expected|
|
264
|
-
|
264
|
+
match do |actual|
|
265
265
|
expected.all? { |e| actual.include?(e) }
|
266
266
|
end
|
267
267
|
|
268
|
-
|
268
|
+
match_when_negated do |actual|
|
269
269
|
expected.none? { |e| actual.include?(e) }
|
270
270
|
end
|
271
271
|
end
|
@@ -7,8 +7,8 @@ Feature: define matcher outside rspec
|
|
7
7
|
Scenario: define a matcher with default messages
|
8
8
|
Given a file named "test_multiples.rb" with:
|
9
9
|
"""ruby
|
10
|
-
require "
|
11
|
-
require "
|
10
|
+
require "minitest/autorun"
|
11
|
+
require "rspec/expectations/minitest_integration"
|
12
12
|
|
13
13
|
RSpec::Matchers.define :be_a_multiple_of do |expected|
|
14
14
|
match do |actual|
|
@@ -16,11 +16,7 @@ Feature: define matcher outside rspec
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
class Test
|
20
|
-
include RSpec::Matchers
|
21
|
-
end
|
22
|
-
|
23
|
-
class TestMultiples < Test::Unit::TestCase
|
19
|
+
class TestMultiples < Minitest::Test
|
24
20
|
|
25
21
|
def test_9_should_be_a_multiple_of_3
|
26
22
|
expect(9).to be_a_multiple_of(3)
|
@@ -35,4 +31,4 @@ Feature: define matcher outside rspec
|
|
35
31
|
When I run `ruby test_multiples.rb`
|
36
32
|
Then the exit status should not be 0
|
37
33
|
And the output should contain "expected 9 to be a multiple of 4"
|
38
|
-
And the output should contain "2
|
34
|
+
And the output should contain "2 runs, 2 assertions, 1 failures, 0 errors"
|