rspec-given 2.1.0.beta.5 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # rspec-given
2
2
 
3
- Covering rspec-given, version 2.1.0.beta.5.
3
+ Covering rspec-given, version 2.1.0.
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
@@ -156,9 +156,13 @@ The _When_ clause specifies the code to be tested ... oops, excuse me
156
156
  ... specified. After the preconditions in the given section are met,
157
157
  the when code block is run.
158
158
 
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.
159
+ In general there should not be more than one _When_ clause for a given
160
+ direct context. However, a _When_ in an outer context will be run
161
+ after all the _Givens_ but before the inner _When_. You can think of
162
+ an outer _When_ as setting up additional given state for the inner
163
+ _When_.
164
+
165
+ E.g.
162
166
 
163
167
  ```ruby
164
168
  context "outer context" do
@@ -301,11 +305,10 @@ stick with _Then_ clauses.
301
305
 
302
306
  The _Invariant_ clause is a new idea that doesn't have an analog in
303
307
  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.
308
+ always be true in the scope of the invariant. In the stack example,
309
+ <tt>empty?</tt> is defined in term of <tt>size</tt>. Whenever
310
+ <tt>size</tt> is 0, <tt>empty?</tt> should be true. Whenever
311
+ <tt>size</tt> is non-zero, <tt>empty?</tt> should be false.
309
312
 
310
313
  You can conceptually think of an _Invariant_ clause as a _Then_ block
311
314
  that automatically gets added to every _Then_ within its scope.
@@ -1,7 +1,3 @@
1
1
  $LOAD_PATH << './examples/stack'
2
2
 
3
3
  require 'rspec/given'
4
-
5
- RSpec.configure do |config|
6
- # config.mock_with :flexmock
7
- end
@@ -4,8 +4,6 @@ module RSpec
4
4
  VERSION_MAJOR = 2,
5
5
  VERSION_MINOR = 1,
6
6
  VERSION_BUILD = 0,
7
- VERSION_BETA = 'beta',
8
- VERSION_BETANUM = '5'
9
7
  ]
10
8
  VERSION = VERSION_NUMBERS.join(".")
11
9
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-given
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.beta.5
5
- prerelease: 6
4
+ version: 2.1.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jim Weirich
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-20 00:00:00.000000000 Z
12
+ date: 2012-10-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -73,9 +73,7 @@ files:
73
73
  - Gemfile.lock
74
74
  - MIT-LICENSE
75
75
  - Rakefile
76
- - README
77
76
  - README.md
78
- - README.old
79
77
  - lib/rspec-given.rb
80
78
  - lib/rspec/given/configure.rb
81
79
  - lib/rspec/given/extensions.rb
@@ -114,12 +112,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
112
  - - ! '>='
115
113
  - !ruby/object:Gem::Version
116
114
  version: '0'
115
+ segments:
116
+ - 0
117
+ hash: -836562108368916480
117
118
  required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  none: false
119
120
  requirements:
120
- - - ! '>'
121
+ - - ! '>='
121
122
  - !ruby/object:Gem::Version
122
- version: 1.3.1
123
+ version: '0'
123
124
  requirements: []
124
125
  rubyforge_project: given
125
126
  rubygems_version: 1.8.24
data/README DELETED
@@ -1,367 +0,0 @@
1
- = rspec-given
2
-
3
- Covering rspec-given, version 2.1.0.beta.5.
4
-
5
- rspec-given is an RSpec extension to allow Given/When/Then notation in
6
- RSpec specifications. It is a natural extension of the experimental
7
- work done on the Given framework. It turns out that 90% of the Given
8
- framework can be trivially implemented on top of RSpec.
9
-
10
- = Why Given/When/Then
11
-
12
- RSpec has done a great job of making specifications more readable for
13
- humans. However, I really like the given / when / then nature of
14
- Cucumber stories and would like to follow the same structure in my
15
- unit tests. rspec-given allows a simple given/when/then structure
16
- RSpec specifications.
17
-
18
- == Status
19
-
20
- _rspec-given_ is ready for production use.
21
-
22
- == Example
23
-
24
- Here is a specification written in the rspec-given framework:
25
-
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 }
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
- ```
90
-
91
- Let's talk about the individual statements used in the Given
92
- framework.
93
-
94
- === Given
95
-
96
- The _Given_ section specifies a starting point, a set of preconditions
97
- that must be true before the code under test is allowed to be run. In
98
- standard test frameworks the preconditions are established with a
99
- combination of setup methods (or :before actions in RSpec) and code in
100
- the test.
101
-
102
- In the example code above the preconditions are started with _Given_
103
- statements. A top level _Given_ (that applies to the entire describe
104
- block) says that one of the preconditions is that there is a stack
105
- with some initial contents.
106
-
107
- Note that initial contents are not specified in the top level describe
108
- block, but are given in each of the nested contexts. By pushing the
109
- definition of "initial_contents" into the nested contexts, we can vary
110
- them as needed for that particular context.
111
-
112
- A precondition in the form "Given(:var) {...}" creates an accessor
113
- method named "var". The accessor is lazily initialized by the code
114
- block. If you want a non-lazy given, use "Given!(:var) {...}".
115
-
116
- A precondition in the form "Given {...}" just executes the code block
117
- for side effects. Since there is no accessor, the code block is
118
- executed immediately (i.e. no lazy evaluation).
119
-
120
- The preconditions are run in order of definition. Nested contexts
121
- will inherit the preconditions from the enclosing context, with out
122
- preconditions running before inner preconditions.
123
-
124
- ==== Given examples:
125
-
126
- ```ruby
127
- Given(:stack) { Stack.new }
128
- ```
129
-
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
-
136
- ```ruby
137
- Given!(:original_size) { stack.size }
138
- ```
139
-
140
- The code block is run unconditionally once before each test and the
141
- value of the block is bound to 'original_size'. This form is useful
142
- when you want to record the value of something that might be affected
143
- by the When code.
144
-
145
- ```ruby
146
- Given { stack.clear }
147
- ```
148
-
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.
152
-
153
- === When
154
-
155
- The _When_ clause specifies the code to be tested ... oops, excuse me
156
- ... specified. After the preconditions in the given section are met,
157
- the when code block is run.
158
-
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
- ```
178
-
179
- ==== When examples:
180
-
181
- ```ruby
182
- When { stack.push(:item) }
183
- ```
184
-
185
- The code block is executed once per test. The effect of the _When{}_
186
- block is very similar to _Given{}_. However, When is used to identify
187
- the particular code that is being specified in the current context or
188
- describe block.
189
-
190
- ```ruby
191
- When(:result) { stack.pop }
192
- ```
193
-
194
- The code block is executed once per test and the value of the code
195
- block is bound to 'result'. Use this form when the code under test
196
- returns a value that you wish to interrogate in the _Then_ code.
197
-
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.
202
-
203
- The failure object will rethrow the captured exception if anything
204
- other than have_failed matcher is used on the failure object.
205
-
206
- For example, if the stack is empty when it is popped, then it is
207
- reasonable for pop to raise an UnderflowError. This is how you might
208
- specify that behavior:
209
-
210
- ```ruby
211
- When(:result) { stack.pop }
212
- Then { result.should have_failed(UnderflowError, /empty/) }
213
- ```
214
-
215
- Note that the arguments to the 'have_failed' matcher are the same as
216
- those given to the standard RSpec matcher 'raise_error'.
217
-
218
- === Then
219
-
220
- The _Then_ clauses are the postconditions of the specification. These
221
- then conditions must be true after the code under test (the _When_
222
- clause) is run.
223
-
224
- The code in the block of a _Then_ clause should be a single _should_
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).
232
-
233
- In RSpec terms, a _Then_ clause forms a RSpec Example that runs in the
234
- context of an Example Group (defined by a describe or context clause).
235
-
236
- Each Example Group must have at least one _Then_ clause, otherwise
237
- there will be no examples to be run for that group. If all the
238
- assertions in an example group are done via Invariants, then the group
239
- should use an empty _Then_ clause, like this:
240
-
241
- ```ruby
242
- Then { }
243
- ```
244
-
245
- ==== Then examples:
246
-
247
- ```ruby
248
- Then { stack.should be_empty }
249
- ```
250
-
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.
253
-
254
- === And
255
-
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
258
- _Then_ clause. Using a single _Then_ an multiple _And_ clauses in an
259
- example group means the setup for that group is run only once (for the
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.
263
-
264
- Some things to keep in mind about _And_ clauses:
265
-
266
- 1. There must be at least one _Then_ in the example group and it must
267
- be declared before the _And_ clauses. Forgetting the _Then_ clause
268
- is an error.
269
-
270
- 1. The code in the _And_ clause is run immediately after the first
271
- (executed) _Then_ of an example group.
272
-
273
- 1. And assertion failures in a _Then_ clause or a _And_ clause will
274
- cause all the subsequent _And_ clauses to be skipped.
275
-
276
- 1. Since _And_ clauses do not form their own RSpec examples, they are
277
- not represented in the formatted output of RSpec. That means _And_
278
- clauses do not produce dots in the Progress format, nor do they
279
- appear in the documentation, html or textmate formats (options
280
- -fhtml, -fdoc, or -ftextmate).
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
-
286
- The choice to use an _And_ clause is primarily a speed consideration.
287
- If an example group has expensive setup and there are a lot of _Then_
288
- clauses, then choosing to make some of the _Then_ clauses into _And_
289
- clause will speed up the spec. Otherwise it is probably better to
290
- stick with _Then_ clauses.
291
-
292
- ==== Then/And examples:
293
-
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
- ```
299
-
300
- === Invariant
301
-
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.
309
-
310
- You can conceptually think of an _Invariant_ clause as a _Then_ block
311
- that automatically gets added to every _Then_ within its scope.
312
-
313
- Invariants nested within a context only apply to the _Then_ clauses
314
- that are in the scope of that context.
315
-
316
- Invariants that reference a _Given_ precondition accessor must only be
317
- used in contexts that define that accessor.
318
-
319
- Notes:
320
-
321
- 1. Since Invariants do not form their own RSpec example, they are not
322
- represented in the RSpec formatted output (e.g. the '--format html'
323
- option).
324
-
325
- == Configuration
326
-
327
- Just require 'rspec/given' in the spec helper of your project and it
328
- is ready to go.
329
-
330
- If the RSpec format option document, html or textmate are chosen,
331
- RSpec/Given will automatically add addition source code information to
332
- the examples to produce better looking output. If you don't care about
333
- the pretty output and wish to disable source code caching
334
- unconditionally, then add the following line to your spec helper file:
335
-
336
- ```ruby
337
- RSpec::Given.source_caching_disabled = true
338
- ```
339
-
340
- = Future Directions
341
-
342
- I really like the way the Given framework is working out. I feel my
343
- tests are much more like specifications when I use it. However, I'm
344
- not entirely happy with it.
345
-
346
- I would like to remove the need for the ".should" in all the _Then_
347
- clauses. In other words, instead of saying:
348
-
349
- ```ruby
350
- Then { x.should == y }
351
- ```
352
-
353
- we could say:
354
-
355
- ```ruby
356
- Then { x == y }
357
- ```
358
-
359
- I think the [wrong assertion library](http://rubygems.org/gems/wrong)
360
- has laid some groundwork in this area.
361
-
362
- = Links
363
-
364
- * Github: [https://github.com/jimweirich/rspec-given](https://github.com/jimweirich/rspec-given)
365
- * Clone URL: git://github.com/jimweirich/rspec-given.git
366
- * Bug/Issue Reporting: [https://github.com/jimweirich/rspec-given/issues](https://github.com/jimweirich/rspec-given/issues)
367
- * Continuous Integration: [http://travis-ci.org/#!/jimweirich/rspec-given](http://travis-ci.org/#!/jimweirich/rspec-given)
data/README.old DELETED
@@ -1,367 +0,0 @@
1
- # rspec-given
2
-
3
- Covering rspec-given, version 2.1.0.beta.4.
4
-
5
- rspec-given is an RSpec extension to allow Given/When/Then notation in
6
- RSpec specifications. It is a natural extension of the experimental
7
- work done on the Given framework. It turns out that 90% of the Given
8
- framework can be trivially implemented on top of RSpec.
9
-
10
- # Why Given/When/Then
11
-
12
- RSpec has done a great job of making specifications more readable for
13
- humans. However, I really like the given / when / then nature of
14
- Cucumber stories and would like to follow the same structure in my
15
- unit tests. rspec-given allows a simple given/when/then structure
16
- RSpec specifications.
17
-
18
- ## Status
19
-
20
- _rspec-given_ is ready for production use.
21
-
22
- ## Example
23
-
24
- Here is a specification written in the rspec-given framework:
25
-
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 }
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
- ```
90
-
91
- Let's talk about the individual statements used in the Given
92
- framework.
93
-
94
- ### Given
95
-
96
- The _Given_ section specifies a starting point, a set of preconditions
97
- that must be true before the code under test is allowed to be run. In
98
- standard test frameworks the preconditions are established with a
99
- combination of setup methods (or :before actions in RSpec) and code in
100
- the test.
101
-
102
- In the example code above the preconditions are started with _Given_
103
- statements. A top level _Given_ (that applies to the entire describe
104
- block) says that one of the preconditions is that there is a stack
105
- with some initial contents.
106
-
107
- Note that initial contents are not specified in the top level describe
108
- block, but are given in each of the nested contexts. By pushing the
109
- definition of "initial_contents" into the nested contexts, we can vary
110
- them as needed for that particular context.
111
-
112
- A precondition in the form "Given(:var) {...}" creates an accessor
113
- method named "var". The accessor is lazily initialized by the code
114
- block. If you want a non-lazy given, use "Given!(:var) {...}".
115
-
116
- A precondition in the form "Given {...}" just executes the code block
117
- for side effects. Since there is no accessor, the code block is
118
- executed immediately (i.e. no lazy evaluation).
119
-
120
- The preconditions are run in order of definition. Nested contexts
121
- will inherit the preconditions from the enclosing context, with out
122
- preconditions running before inner preconditions.
123
-
124
- #### Given examples:
125
-
126
- ```ruby
127
- Given(:stack) { Stack.new }
128
- ```
129
-
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
-
136
- ```ruby
137
- Given!(:original_size) { stack.size }
138
- ```
139
-
140
- The code block is run unconditionally once before each test and the
141
- value of the block is bound to 'original_size'. This form is useful
142
- when you want to record the value of something that might be affected
143
- by the When code.
144
-
145
- ```ruby
146
- Given { stack.clear }
147
- ```
148
-
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.
152
-
153
- ### When
154
-
155
- The _When_ clause specifies the code to be tested ... oops, excuse me
156
- ... specified. After the preconditions in the given section are met,
157
- the when code block is run.
158
-
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
- ```
178
-
179
- #### When examples:
180
-
181
- ```ruby
182
- When { stack.push(:item) }
183
- ```
184
-
185
- The code block is executed once per test. The effect of the _When{}_
186
- block is very similar to _Given{}_. However, When is used to identify
187
- the particular code that is being specified in the current context or
188
- describe block.
189
-
190
- ```ruby
191
- When(:result) { stack.pop }
192
- ```
193
-
194
- The code block is executed once per test and the value of the code
195
- block is bound to 'result'. Use this form when the code under test
196
- returns a value that you wish to interrogate in the _Then_ code.
197
-
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.
202
-
203
- The failure object will rethrow the captured exception if anything
204
- other than have_failed matcher is used on the failure object.
205
-
206
- For example, if the stack is empty when it is popped, then it is
207
- reasonable for pop to raise an UnderflowError. This is how you might
208
- specify that behavior:
209
-
210
- ```ruby
211
- When(:result) { stack.pop }
212
- Then { result.should have_failed(UnderflowError, /empty/) }
213
- ```
214
-
215
- Note that the arguments to the 'have_failed' matcher are the same as
216
- those given to the standard RSpec matcher 'raise_error'.
217
-
218
- ### Then
219
-
220
- The _Then_ clauses are the postconditions of the specification. These
221
- then conditions must be true after the code under test (the _When_
222
- clause) is run.
223
-
224
- The code in the block of a _Then_ clause should be a single _should_
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).
232
-
233
- In RSpec terms, a _Then_ clause forms a RSpec Example that runs in the
234
- context of an Example Group (defined by a describe or context clause).
235
-
236
- Each Example Group must have at least one _Then_ clause, otherwise
237
- there will be no examples to be run for that group. If all the
238
- assertions in an example group are done via Invariants, then the group
239
- should use an empty _Then_ clause, like this:
240
-
241
- ```ruby
242
- Then { }
243
- ```
244
-
245
- #### Then examples:
246
-
247
- ```ruby
248
- Then { stack.should be_empty }
249
- ```
250
-
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.
253
-
254
- ### And
255
-
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
258
- _Then_ clause. Using a single _Then_ an multiple _And_ clauses in an
259
- example group means the setup for that group is run only once (for the
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.
263
-
264
- Some things to keep in mind about _And_ clauses:
265
-
266
- 1. There must be at least one _Then_ in the example group and it must
267
- be declared before the _And_ clauses. Forgetting the _Then_ clause
268
- is an error.
269
-
270
- 1. The code in the _And_ clause is run immediately after the first
271
- (executed) _Then_ of an example group.
272
-
273
- 1. And assertion failures in a _Then_ clause or a _And_ clause will
274
- cause all the subsequent _And_ clauses to be skipped.
275
-
276
- 1. Since _And_ clauses do not form their own RSpec examples, they are
277
- not represented in the formatted output of RSpec. That means _And_
278
- clauses do not produce dots in the Progress format, nor do they
279
- appear in the documentation, html or textmate formats (options
280
- -fhtml, -fdoc, or -ftextmate).
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
-
286
- The choice to use an _And_ clause is primarily a speed consideration.
287
- If an example group has expensive setup and there are a lot of _Then_
288
- clauses, then choosing to make some of the _Then_ clauses into _And_
289
- clause will speed up the spec. Otherwise it is probably better to
290
- stick with _Then_ clauses.
291
-
292
- #### Then/And examples:
293
-
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
- ```
299
-
300
- ### Invariant
301
-
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.
309
-
310
- You can conceptually think of an _Invariant_ clause as a _Then_ block
311
- that automatically gets added to every _Then_ within its scope.
312
-
313
- Invariants nested within a context only apply to the _Then_ clauses
314
- that are in the scope of that context.
315
-
316
- Invariants that reference a _Given_ precondition accessor must only be
317
- used in contexts that define that accessor.
318
-
319
- Notes:
320
-
321
- 1. Since Invariants do not form their own RSpec example, they are not
322
- represented in the RSpec formatted output (e.g. the '--format html'
323
- option).
324
-
325
- ## Configuration
326
-
327
- Just require 'rspec/given' in the spec helper of your project and it
328
- is ready to go.
329
-
330
- If the RSpec format option document, html or textmate are chosen,
331
- RSpec/Given will automatically add addition source code information to
332
- the examples to produce better looking output. If you don't care about
333
- the pretty output and wish to disable source code caching
334
- unconditionally, then add the following line to your spec helper file:
335
-
336
- ```ruby
337
- RSpec::Given.source_caching_disabled = true
338
- ```
339
-
340
- # Future Directions
341
-
342
- I really like the way the Given framework is working out. I feel my
343
- tests are much more like specifications when I use it. However, I'm
344
- not entirely happy with it.
345
-
346
- I would like to remove the need for the ".should" in all the _Then_
347
- clauses. In other words, instead of saying:
348
-
349
- ```ruby
350
- Then { x.should == y }
351
- ```
352
-
353
- we could say:
354
-
355
- ```ruby
356
- Then { x == y }
357
- ```
358
-
359
- I think the [wrong assertion library](http://rubygems.org/gems/wrong)
360
- has laid some groundwork in this area.
361
-
362
- # Links
363
-
364
- * Github: [https://github.com/jimweirich/rspec-given](https://github.com/jimweirich/rspec-given)
365
- * Clone URL: git://github.com/jimweirich/rspec-given.git
366
- * Bug/Issue Reporting: [https://github.com/jimweirich/rspec-given/issues](https://github.com/jimweirich/rspec-given/issues)
367
- * Continuous Integration: [http://travis-ci.org/#!/jimweirich/rspec-given](http://travis-ci.org/#!/jimweirich/rspec-given)