rspec-given 2.1.0.beta.4 → 2.1.0.beta.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -2
- data/README +164 -122
- data/README.md +76 -58
- data/README.old +80 -62
- data/Rakefile +0 -1
- data/examples/{spec_helper.rb → example_helper.rb} +4 -3
- data/examples/integration/and_spec.rb +5 -4
- data/examples/integration/focused_line_spec.rb +1 -1
- data/examples/other/line_example.rb +1 -1
- data/examples/stack/stack_spec.rb +1 -1
- data/lib/rspec/given.rb +2 -1
- data/lib/rspec/given/extensions.rb +3 -3
- data/lib/rspec/given/file_cache.rb +19 -0
- data/lib/rspec/given/line_extractor.rb +43 -0
- data/lib/rspec/given/version.rb +1 -1
- metadata +27 -11
- data/lib/rspec/given/line_cache.rb +0 -34
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= rspec-given
|
2
2
|
|
3
|
-
Covering rspec-given, version 2.1.0.beta.
|
3
|
+
Covering rspec-given, version 2.1.0.beta.5.
|
4
4
|
|
5
5
|
rspec-given is an RSpec extension to allow Given/When/Then notation in
|
6
6
|
RSpec specifications. It is a natural extension of the experimental
|
@@ -23,68 +23,70 @@ _rspec-given_ is ready for production use.
|
|
23
23
|
|
24
24
|
Here is a specification written in the rspec-given framework:
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
context "with several items" do
|
69
|
-
Given(:initial_contents) { [:second_item, :top_item] }
|
70
|
-
Given!(:original_depth) { stack.depth }
|
71
|
-
|
72
|
-
context "when pushing" do
|
73
|
-
When { stack.push(:new_item) }
|
74
|
-
|
75
|
-
Then { stack.top.should == :new_item }
|
76
|
-
Then { stack.depth.should == original_depth + 1 }
|
77
|
-
end
|
78
|
-
|
79
|
-
context "when popping" do
|
80
|
-
When(:pop_result) { stack.pop }
|
81
|
-
|
82
|
-
Then { pop_result.should == :top_item }
|
83
|
-
Then { stack.top.should == :second_item }
|
84
|
-
Then { stack.depth.should == original_depth - 1 }
|
85
|
-
end
|
86
|
-
end
|
26
|
+
```ruby
|
27
|
+
require 'rspec/given'
|
28
|
+
require 'spec_helper'
|
29
|
+
require 'stack'
|
30
|
+
|
31
|
+
describe Stack do
|
32
|
+
def stack_with(initial_contents)
|
33
|
+
stack = Stack.new
|
34
|
+
initial_contents.each do |item| stack.push(item) end
|
35
|
+
stack
|
36
|
+
end
|
37
|
+
|
38
|
+
Given(:stack) { stack_with(initial_contents) }
|
39
|
+
Invariant { stack.empty?.should == (stack.depth == 0) }
|
40
|
+
|
41
|
+
context "when empty" do
|
42
|
+
Given(:initial_contents) { [] }
|
43
|
+
Then { stack.depth.should == 0 }
|
44
|
+
|
45
|
+
context "when pushing" do
|
46
|
+
When { stack.push(:an_item) }
|
47
|
+
|
48
|
+
Then { stack.depth.should == 1 }
|
49
|
+
Then { stack.top.should == :an_item }
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when popping" do
|
53
|
+
When(:result) { stack.pop }
|
54
|
+
Then { result.should have_failed(Stack::UnderflowError, /empty/) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with one item" do
|
59
|
+
Given(:initial_contents) { [:an_item] }
|
60
|
+
|
61
|
+
context "when popping" do
|
62
|
+
When(:pop_result) { stack.pop }
|
63
|
+
|
64
|
+
Then { pop_result.should == :an_item }
|
65
|
+
Then { stack.depth.should == 0 }
|
87
66
|
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with several items" do
|
70
|
+
Given(:initial_contents) { [:second_item, :top_item] }
|
71
|
+
Given!(:original_depth) { stack.depth }
|
72
|
+
|
73
|
+
context "when pushing" do
|
74
|
+
When { stack.push(:new_item) }
|
75
|
+
|
76
|
+
Then { stack.top.should == :new_item }
|
77
|
+
Then { stack.depth.should == original_depth + 1 }
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when popping" do
|
81
|
+
When(:pop_result) { stack.pop }
|
82
|
+
|
83
|
+
Then { pop_result.should == :top_item }
|
84
|
+
Then { stack.top.should == :second_item }
|
85
|
+
Then { stack.depth.should == original_depth - 1 }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
88
90
|
|
89
91
|
Let's talk about the individual statements used in the Given
|
90
92
|
framework.
|
@@ -121,68 +123,82 @@ preconditions running before inner preconditions.
|
|
121
123
|
|
122
124
|
==== Given examples:
|
123
125
|
|
124
|
-
|
126
|
+
```ruby
|
127
|
+
Given(:stack) { Stack.new }
|
128
|
+
```
|
125
129
|
|
126
|
-
The given
|
127
|
-
test and the value of the block is bound to 'stack'.
|
128
|
-
reference to 'stack' in the specification will cause the
|
129
|
-
execute.
|
130
|
-
generated value.
|
130
|
+
The block for the given clause is lazily run if 'stack' is ever
|
131
|
+
referenced in the test and the value of the block is bound to 'stack'.
|
132
|
+
The first reference to 'stack' in the specification will cause the
|
133
|
+
code block to execute. Futher references to 'stack' will reuse the
|
134
|
+
previously generated value.
|
131
135
|
|
132
|
-
|
136
|
+
```ruby
|
137
|
+
Given!(:original_size) { stack.size }
|
138
|
+
```
|
133
139
|
|
134
140
|
The code block is run unconditionally once before each test and the
|
135
141
|
value of the block is bound to 'original_size'. This form is useful
|
136
142
|
when you want to record the value of something that might be affected
|
137
143
|
by the When code.
|
138
144
|
|
139
|
-
|
145
|
+
```ruby
|
146
|
+
Given { stack.clear }
|
147
|
+
```
|
140
148
|
|
141
|
-
The given
|
142
|
-
form of given is used for code that is executed for side
|
149
|
+
The block for the given clause is run unconditionally once before each
|
150
|
+
test. This form of given is used for code that is executed for side
|
151
|
+
effects.
|
143
152
|
|
144
153
|
=== When
|
145
154
|
|
146
|
-
The _When_
|
155
|
+
The _When_ clause specifies the code to be tested ... oops, excuse me
|
147
156
|
... specified. After the preconditions in the given section are met,
|
148
157
|
the when code block is run.
|
149
158
|
|
150
|
-
There should
|
151
|
-
_When_ in an outer context shoud be treated as a
|
152
|
-
context.
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
159
|
+
There should not be more than one _When_ clause for a given direct
|
160
|
+
context. However, a _When_ in an outer context shoud be treated as a
|
161
|
+
_Given_ in an inner context. E.g.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
context "outer context" do
|
165
|
+
When { code specified in the outer context }
|
166
|
+
Then { assert something about the outer context }
|
167
|
+
|
168
|
+
context "inner context" do
|
169
|
+
|
170
|
+
# At this point, the _When_ of the outer context
|
171
|
+
# should be treated as a _Given_ of the inner context
|
172
|
+
|
173
|
+
When { code specified in the inner context }
|
174
|
+
Then { assert something about the inner context }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
```
|
167
178
|
|
168
179
|
==== When examples:
|
169
180
|
|
170
|
-
|
181
|
+
```ruby
|
182
|
+
When { stack.push(:item) }
|
183
|
+
```
|
171
184
|
|
172
185
|
The code block is executed once per test. The effect of the _When{}_
|
173
186
|
block is very similar to _Given{}_. However, When is used to identify
|
174
187
|
the particular code that is being specified in the current context or
|
175
188
|
describe block.
|
176
189
|
|
177
|
-
|
190
|
+
```ruby
|
191
|
+
When(:result) { stack.pop }
|
192
|
+
```
|
178
193
|
|
179
194
|
The code block is executed once per test and the value of the code
|
180
195
|
block is bound to 'result'. Use this form when the code under test
|
181
196
|
returns a value that you wish to interrogate in the _Then_ code.
|
182
197
|
|
183
|
-
If an exception occurs during the execution of the
|
184
|
-
exception is caught and a failure object is bound to
|
185
|
-
failure can be checked in a then block with the
|
198
|
+
If an exception occurs during the execution of the block for the When
|
199
|
+
clause, the exception is caught and a failure object is bound to
|
200
|
+
'result'. The failure can be checked in a then block with the
|
201
|
+
'have_failed' matcher.
|
186
202
|
|
187
203
|
The failure object will rethrow the captured exception if anything
|
188
204
|
other than have_failed matcher is used on the failure object.
|
@@ -191,8 +207,10 @@ For example, if the stack is empty when it is popped, then it is
|
|
191
207
|
reasonable for pop to raise an UnderflowError. This is how you might
|
192
208
|
specify that behavior:
|
193
209
|
|
194
|
-
|
195
|
-
|
210
|
+
```ruby
|
211
|
+
When(:result) { stack.pop }
|
212
|
+
Then { result.should have_failed(UnderflowError, /empty/) }
|
213
|
+
```
|
196
214
|
|
197
215
|
Note that the arguments to the 'have_failed' matcher are the same as
|
198
216
|
those given to the standard RSpec matcher 'raise_error'.
|
@@ -204,7 +222,13 @@ then conditions must be true after the code under test (the _When_
|
|
204
222
|
clause) is run.
|
205
223
|
|
206
224
|
The code in the block of a _Then_ clause should be a single _should_
|
207
|
-
assertion. Code in _Then_
|
225
|
+
assertion. Code in _Then_ clauses should not have any side effects.
|
226
|
+
|
227
|
+
Let me repeat that: <b>_Then_ clauses should not have any side
|
228
|
+
effects!</b> _Then_ clauses with side effects are erroneous. _Then_
|
229
|
+
clauses need to be idempotent, so that running them once, twice, a
|
230
|
+
hundred times, or never does not change the state of the program. (The
|
231
|
+
same is true of _And_ clauses).
|
208
232
|
|
209
233
|
In RSpec terms, a _Then_ clause forms a RSpec Example that runs in the
|
210
234
|
context of an Example Group (defined by a describe or context clause).
|
@@ -214,23 +238,28 @@ there will be no examples to be run for that group. If all the
|
|
214
238
|
assertions in an example group are done via Invariants, then the group
|
215
239
|
should use an empty _Then_ clause, like this:
|
216
240
|
|
217
|
-
|
241
|
+
```ruby
|
242
|
+
Then { }
|
243
|
+
```
|
218
244
|
|
219
245
|
==== Then examples:
|
220
246
|
|
221
|
-
|
247
|
+
```ruby
|
248
|
+
Then { stack.should be_empty }
|
249
|
+
```
|
222
250
|
|
223
|
-
After the related _When_
|
224
|
-
it is not empty, the test will fail.
|
251
|
+
After the related block for the _When_ clause is run, the stack should
|
252
|
+
be empty. If it is not empty, the test will fail.
|
225
253
|
|
226
254
|
=== And
|
227
255
|
|
228
|
-
The _And_ clause is similar to _Then_, but
|
229
|
-
|
256
|
+
The _And_ clause is similar to _Then_, but does not form its own RSpec
|
257
|
+
example. This means that _And_ clauses reuse the setup from a sibling
|
230
258
|
_Then_ clause. Using a single _Then_ an multiple _And_ clauses in an
|
231
259
|
example group means the setup for that group is run only once (for the
|
232
|
-
_Then_ clause). This can be a
|
233
|
-
setup for an example group is
|
260
|
+
_Then_ clause) and reused for all the _And_s. This can be a
|
261
|
+
significant speed savings where the setup for an example group is
|
262
|
+
expensive.
|
234
263
|
|
235
264
|
Some things to keep in mind about _And_ clauses:
|
236
265
|
|
@@ -239,7 +268,7 @@ Some things to keep in mind about _And_ clauses:
|
|
239
268
|
is an error.
|
240
269
|
|
241
270
|
1. The code in the _And_ clause is run immediately after the first
|
242
|
-
_Then_ of an example group.
|
271
|
+
(executed) _Then_ of an example group.
|
243
272
|
|
244
273
|
1. And assertion failures in a _Then_ clause or a _And_ clause will
|
245
274
|
cause all the subsequent _And_ clauses to be skipped.
|
@@ -250,6 +279,10 @@ Some things to keep in mind about _And_ clauses:
|
|
250
279
|
appear in the documentation, html or textmate formats (options
|
251
280
|
-fhtml, -fdoc, or -ftextmate).
|
252
281
|
|
282
|
+
1. Like _Then_ clauses, _And_ clauses must be idempotent. That means
|
283
|
+
they should not execute any code that changes global program state.
|
284
|
+
(See the section on the _Then_ clause).
|
285
|
+
|
253
286
|
The choice to use an _And_ clause is primarily a speed consideration.
|
254
287
|
If an example group has expensive setup and there are a lot of _Then_
|
255
288
|
clauses, then choosing to make some of the _Then_ clauses into _And_
|
@@ -258,24 +291,27 @@ stick with _Then_ clauses.
|
|
258
291
|
|
259
292
|
==== Then/And examples:
|
260
293
|
|
261
|
-
|
262
|
-
|
263
|
-
|
294
|
+
```ruby
|
295
|
+
Then { pop_result.should == :top_item } # Required
|
296
|
+
And { stack.top.should == :second_item } # No Setup rerun
|
297
|
+
And { stack.depth.should == original_depth - 1 } # ... for these
|
298
|
+
```
|
264
299
|
|
265
300
|
=== Invariant
|
266
301
|
|
267
|
-
The _Invariant_
|
268
|
-
RSpec or Test::Unit.
|
269
|
-
|
270
|
-
|
271
|
-
<tt>
|
272
|
-
<tt>empty?</tt> should be
|
302
|
+
The _Invariant_ clause is a new idea that doesn't have an analog in
|
303
|
+
RSpec or Test::Unit. The invariant allows you specify things that must
|
304
|
+
always be true (or at least always be true in the scope of the
|
305
|
+
invariant). In the stack example, <tt>empty?</tt> is defined in term
|
306
|
+
of <tt>size</tt>. Whenever <tt>size</tt> is 0, <tt>empty?</tt> should
|
307
|
+
be true. Whenever <tt>size</tt> is non-zero, <tt>empty?</tt> should be
|
308
|
+
false.
|
273
309
|
|
274
|
-
You can conceptually think of an _Invariant_
|
310
|
+
You can conceptually think of an _Invariant_ clause as a _Then_ block
|
275
311
|
that automatically gets added to every _Then_ within its scope.
|
276
312
|
|
277
|
-
Invariants nested within a context only apply to the _Then_
|
278
|
-
that context.
|
313
|
+
Invariants nested within a context only apply to the _Then_ clauses
|
314
|
+
that are in the scope of that context.
|
279
315
|
|
280
316
|
Invariants that reference a _Given_ precondition accessor must only be
|
281
317
|
used in contexts that define that accessor.
|
@@ -297,7 +333,9 @@ the examples to produce better looking output. If you don't care about
|
|
297
333
|
the pretty output and wish to disable source code caching
|
298
334
|
unconditionally, then add the following line to your spec helper file:
|
299
335
|
|
300
|
-
|
336
|
+
```ruby
|
337
|
+
RSpec::Given.source_caching_disabled = true
|
338
|
+
```
|
301
339
|
|
302
340
|
= Future Directions
|
303
341
|
|
@@ -305,14 +343,18 @@ I really like the way the Given framework is working out. I feel my
|
|
305
343
|
tests are much more like specifications when I use it. However, I'm
|
306
344
|
not entirely happy with it.
|
307
345
|
|
308
|
-
I would like to remove the need for the ".should" in all the
|
309
|
-
|
346
|
+
I would like to remove the need for the ".should" in all the _Then_
|
347
|
+
clauses. In other words, instead of saying:
|
310
348
|
|
349
|
+
```ruby
|
311
350
|
Then { x.should == y }
|
351
|
+
```
|
312
352
|
|
313
353
|
we could say:
|
314
354
|
|
355
|
+
```ruby
|
315
356
|
Then { x == y }
|
357
|
+
```
|
316
358
|
|
317
359
|
I think the [wrong assertion library](http://rubygems.org/gems/wrong)
|
318
360
|
has laid some groundwork in this area.
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# rspec-given
|
2
2
|
|
3
|
-
Covering rspec-given, version 2.1.0.beta.
|
3
|
+
Covering rspec-given, version 2.1.0.beta.5.
|
4
4
|
|
5
5
|
rspec-given is an RSpec extension to allow Given/When/Then notation in
|
6
6
|
RSpec specifications. It is a natural extension of the experimental
|
@@ -23,7 +23,7 @@ _rspec-given_ is ready for production use.
|
|
23
23
|
|
24
24
|
Here is a specification written in the rspec-given framework:
|
25
25
|
|
26
|
-
|
26
|
+
```ruby
|
27
27
|
require 'rspec/given'
|
28
28
|
require 'spec_helper'
|
29
29
|
require 'stack'
|
@@ -86,7 +86,7 @@ describe Stack do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
```
|
90
90
|
|
91
91
|
Let's talk about the individual statements used in the Given
|
92
92
|
framework.
|
@@ -123,43 +123,44 @@ preconditions running before inner preconditions.
|
|
123
123
|
|
124
124
|
#### Given examples:
|
125
125
|
|
126
|
-
|
126
|
+
```ruby
|
127
127
|
Given(:stack) { Stack.new }
|
128
|
-
|
128
|
+
```
|
129
129
|
|
130
|
-
The given
|
131
|
-
test and the value of the block is bound to 'stack'.
|
132
|
-
reference to 'stack' in the specification will cause the
|
133
|
-
execute.
|
134
|
-
generated value.
|
130
|
+
The block for the given clause is lazily run if 'stack' is ever
|
131
|
+
referenced in the test and the value of the block is bound to 'stack'.
|
132
|
+
The first reference to 'stack' in the specification will cause the
|
133
|
+
code block to execute. Futher references to 'stack' will reuse the
|
134
|
+
previously generated value.
|
135
135
|
|
136
|
-
|
136
|
+
```ruby
|
137
137
|
Given!(:original_size) { stack.size }
|
138
|
-
|
138
|
+
```
|
139
139
|
|
140
140
|
The code block is run unconditionally once before each test and the
|
141
141
|
value of the block is bound to 'original_size'. This form is useful
|
142
142
|
when you want to record the value of something that might be affected
|
143
143
|
by the When code.
|
144
144
|
|
145
|
-
|
145
|
+
```ruby
|
146
146
|
Given { stack.clear }
|
147
|
-
|
147
|
+
```
|
148
148
|
|
149
|
-
The given
|
150
|
-
form of given is used for code that is executed for side
|
149
|
+
The block for the given clause is run unconditionally once before each
|
150
|
+
test. This form of given is used for code that is executed for side
|
151
|
+
effects.
|
151
152
|
|
152
153
|
### When
|
153
154
|
|
154
|
-
The _When_
|
155
|
+
The _When_ clause specifies the code to be tested ... oops, excuse me
|
155
156
|
... specified. After the preconditions in the given section are met,
|
156
157
|
the when code block is run.
|
157
158
|
|
158
|
-
There should
|
159
|
-
_When_ in an outer context shoud be treated as a
|
160
|
-
context.
|
159
|
+
There should not be more than one _When_ clause for a given direct
|
160
|
+
context. However, a _When_ in an outer context shoud be treated as a
|
161
|
+
_Given_ in an inner context. E.g.
|
161
162
|
|
162
|
-
|
163
|
+
```ruby
|
163
164
|
context "outer context" do
|
164
165
|
When { code specified in the outer context }
|
165
166
|
Then { assert something about the outer context }
|
@@ -173,30 +174,31 @@ context. E.g.
|
|
173
174
|
Then { assert something about the inner context }
|
174
175
|
end
|
175
176
|
end
|
176
|
-
|
177
|
+
```
|
177
178
|
|
178
179
|
#### When examples:
|
179
180
|
|
180
|
-
|
181
|
+
```ruby
|
181
182
|
When { stack.push(:item) }
|
182
|
-
|
183
|
+
```
|
183
184
|
|
184
185
|
The code block is executed once per test. The effect of the _When{}_
|
185
186
|
block is very similar to _Given{}_. However, When is used to identify
|
186
187
|
the particular code that is being specified in the current context or
|
187
188
|
describe block.
|
188
189
|
|
189
|
-
|
190
|
+
```ruby
|
190
191
|
When(:result) { stack.pop }
|
191
|
-
|
192
|
+
```
|
192
193
|
|
193
194
|
The code block is executed once per test and the value of the code
|
194
195
|
block is bound to 'result'. Use this form when the code under test
|
195
196
|
returns a value that you wish to interrogate in the _Then_ code.
|
196
197
|
|
197
|
-
If an exception occurs during the execution of the
|
198
|
-
exception is caught and a failure object is bound to
|
199
|
-
failure can be checked in a then block with the
|
198
|
+
If an exception occurs during the execution of the block for the When
|
199
|
+
clause, the exception is caught and a failure object is bound to
|
200
|
+
'result'. The failure can be checked in a then block with the
|
201
|
+
'have_failed' matcher.
|
200
202
|
|
201
203
|
The failure object will rethrow the captured exception if anything
|
202
204
|
other than have_failed matcher is used on the failure object.
|
@@ -205,10 +207,10 @@ For example, if the stack is empty when it is popped, then it is
|
|
205
207
|
reasonable for pop to raise an UnderflowError. This is how you might
|
206
208
|
specify that behavior:
|
207
209
|
|
208
|
-
|
210
|
+
```ruby
|
209
211
|
When(:result) { stack.pop }
|
210
212
|
Then { result.should have_failed(UnderflowError, /empty/) }
|
211
|
-
|
213
|
+
```
|
212
214
|
|
213
215
|
Note that the arguments to the 'have_failed' matcher are the same as
|
214
216
|
those given to the standard RSpec matcher 'raise_error'.
|
@@ -220,7 +222,13 @@ then conditions must be true after the code under test (the _When_
|
|
220
222
|
clause) is run.
|
221
223
|
|
222
224
|
The code in the block of a _Then_ clause should be a single _should_
|
223
|
-
assertion. Code in _Then_
|
225
|
+
assertion. Code in _Then_ clauses should not have any side effects.
|
226
|
+
|
227
|
+
Let me repeat that: <b>_Then_ clauses should not have any side
|
228
|
+
effects!</b> _Then_ clauses with side effects are erroneous. _Then_
|
229
|
+
clauses need to be idempotent, so that running them once, twice, a
|
230
|
+
hundred times, or never does not change the state of the program. (The
|
231
|
+
same is true of _And_ clauses).
|
224
232
|
|
225
233
|
In RSpec terms, a _Then_ clause forms a RSpec Example that runs in the
|
226
234
|
context of an Example Group (defined by a describe or context clause).
|
@@ -230,27 +238,28 @@ there will be no examples to be run for that group. If all the
|
|
230
238
|
assertions in an example group are done via Invariants, then the group
|
231
239
|
should use an empty _Then_ clause, like this:
|
232
240
|
|
233
|
-
|
241
|
+
```ruby
|
234
242
|
Then { }
|
235
|
-
|
243
|
+
```
|
236
244
|
|
237
245
|
#### Then examples:
|
238
246
|
|
239
|
-
|
247
|
+
```ruby
|
240
248
|
Then { stack.should be_empty }
|
241
|
-
|
249
|
+
```
|
242
250
|
|
243
|
-
After the related _When_
|
244
|
-
it is not empty, the test will fail.
|
251
|
+
After the related block for the _When_ clause is run, the stack should
|
252
|
+
be empty. If it is not empty, the test will fail.
|
245
253
|
|
246
254
|
### And
|
247
255
|
|
248
|
-
The _And_ clause is similar to _Then_, but
|
249
|
-
|
256
|
+
The _And_ clause is similar to _Then_, but does not form its own RSpec
|
257
|
+
example. This means that _And_ clauses reuse the setup from a sibling
|
250
258
|
_Then_ clause. Using a single _Then_ an multiple _And_ clauses in an
|
251
259
|
example group means the setup for that group is run only once (for the
|
252
|
-
_Then_ clause). This can be a
|
253
|
-
setup for an example group is
|
260
|
+
_Then_ clause) and reused for all the _And_s. This can be a
|
261
|
+
significant speed savings where the setup for an example group is
|
262
|
+
expensive.
|
254
263
|
|
255
264
|
Some things to keep in mind about _And_ clauses:
|
256
265
|
|
@@ -259,7 +268,7 @@ Some things to keep in mind about _And_ clauses:
|
|
259
268
|
is an error.
|
260
269
|
|
261
270
|
1. The code in the _And_ clause is run immediately after the first
|
262
|
-
_Then_ of an example group.
|
271
|
+
(executed) _Then_ of an example group.
|
263
272
|
|
264
273
|
1. And assertion failures in a _Then_ clause or a _And_ clause will
|
265
274
|
cause all the subsequent _And_ clauses to be skipped.
|
@@ -270,6 +279,10 @@ Some things to keep in mind about _And_ clauses:
|
|
270
279
|
appear in the documentation, html or textmate formats (options
|
271
280
|
-fhtml, -fdoc, or -ftextmate).
|
272
281
|
|
282
|
+
1. Like _Then_ clauses, _And_ clauses must be idempotent. That means
|
283
|
+
they should not execute any code that changes global program state.
|
284
|
+
(See the section on the _Then_ clause).
|
285
|
+
|
273
286
|
The choice to use an _And_ clause is primarily a speed consideration.
|
274
287
|
If an example group has expensive setup and there are a lot of _Then_
|
275
288
|
clauses, then choosing to make some of the _Then_ clauses into _And_
|
@@ -278,26 +291,27 @@ stick with _Then_ clauses.
|
|
278
291
|
|
279
292
|
#### Then/And examples:
|
280
293
|
|
281
|
-
|
294
|
+
```ruby
|
282
295
|
Then { pop_result.should == :top_item } # Required
|
283
296
|
And { stack.top.should == :second_item } # No Setup rerun
|
284
297
|
And { stack.depth.should == original_depth - 1 } # ... for these
|
285
|
-
|
298
|
+
```
|
286
299
|
|
287
300
|
### Invariant
|
288
301
|
|
289
|
-
The _Invariant_
|
290
|
-
RSpec or Test::Unit.
|
291
|
-
|
292
|
-
|
293
|
-
<tt>
|
294
|
-
<tt>empty?</tt> should be
|
302
|
+
The _Invariant_ clause is a new idea that doesn't have an analog in
|
303
|
+
RSpec or Test::Unit. The invariant allows you specify things that must
|
304
|
+
always be true (or at least always be true in the scope of the
|
305
|
+
invariant). In the stack example, <tt>empty?</tt> is defined in term
|
306
|
+
of <tt>size</tt>. Whenever <tt>size</tt> is 0, <tt>empty?</tt> should
|
307
|
+
be true. Whenever <tt>size</tt> is non-zero, <tt>empty?</tt> should be
|
308
|
+
false.
|
295
309
|
|
296
|
-
You can conceptually think of an _Invariant_
|
310
|
+
You can conceptually think of an _Invariant_ clause as a _Then_ block
|
297
311
|
that automatically gets added to every _Then_ within its scope.
|
298
312
|
|
299
|
-
Invariants nested within a context only apply to the _Then_
|
300
|
-
that context.
|
313
|
+
Invariants nested within a context only apply to the _Then_ clauses
|
314
|
+
that are in the scope of that context.
|
301
315
|
|
302
316
|
Invariants that reference a _Given_ precondition accessor must only be
|
303
317
|
used in contexts that define that accessor.
|
@@ -319,9 +333,9 @@ the examples to produce better looking output. If you don't care about
|
|
319
333
|
the pretty output and wish to disable source code caching
|
320
334
|
unconditionally, then add the following line to your spec helper file:
|
321
335
|
|
322
|
-
|
336
|
+
```ruby
|
323
337
|
RSpec::Given.source_caching_disabled = true
|
324
|
-
|
338
|
+
```
|
325
339
|
|
326
340
|
# Future Directions
|
327
341
|
|
@@ -329,14 +343,18 @@ I really like the way the Given framework is working out. I feel my
|
|
329
343
|
tests are much more like specifications when I use it. However, I'm
|
330
344
|
not entirely happy with it.
|
331
345
|
|
332
|
-
I would like to remove the need for the ".should" in all the
|
333
|
-
|
346
|
+
I would like to remove the need for the ".should" in all the _Then_
|
347
|
+
clauses. In other words, instead of saying:
|
334
348
|
|
349
|
+
```ruby
|
335
350
|
Then { x.should == y }
|
351
|
+
```
|
336
352
|
|
337
353
|
we could say:
|
338
354
|
|
355
|
+
```ruby
|
339
356
|
Then { x == y }
|
357
|
+
```
|
340
358
|
|
341
359
|
I think the [wrong assertion library](http://rubygems.org/gems/wrong)
|
342
360
|
has laid some groundwork in this area.
|