rspec-given 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +135 -51
- data/Rakefile +5 -2
- data/examples/stack/stack_spec.rb +16 -23
- data/examples/wrong/wrong_spec.rb +26 -0
- data/lib/rspec/given/version.rb +1 -1
- metadata +4 -3
data/README.md
CHANGED
@@ -15,51 +15,31 @@ RSpec specifications.
|
|
15
15
|
|
16
16
|
## Status
|
17
17
|
|
18
|
-
|
19
|
-
several features.
|
18
|
+
_rspec-given_ is ready for production use.
|
20
19
|
|
21
|
-
|
22
|
-
* Then assertions without _should_ are not supported yet.
|
20
|
+
## Example
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
Here's the spec that I've been playing with. Its gone through
|
27
|
-
mulitple revisions and several prototype implementations. And this is
|
28
|
-
probably not the final form.
|
29
|
-
|
30
|
-
With all that in mind, here's a specification in my imaginary
|
31
|
-
framework:
|
22
|
+
Here is a specification written in the rspec-given framework:
|
32
23
|
|
33
24
|
<pre>
|
25
|
+
require 'rspec/given'
|
34
26
|
require 'spec_helper'
|
35
27
|
require 'stack'
|
36
28
|
|
37
29
|
describe Stack do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
Given(:an_empty_stack) { Stack.new }
|
43
|
-
|
44
|
-
Given(:a_stack_with_one_item) do
|
45
|
-
Stack.new.tap do |s|
|
46
|
-
s.push(:an_item)
|
47
|
-
end
|
30
|
+
def stack_with(initial_contents)
|
31
|
+
stack = Stack.new
|
32
|
+
initial_contents.each do |item| stack.push(item) end
|
33
|
+
stack
|
48
34
|
end
|
49
35
|
|
50
|
-
Given(:
|
51
|
-
Stack.new.tap do |s|
|
52
|
-
s.push(:second_item)
|
53
|
-
s.push(:top_item)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context "an empty stack" do
|
58
|
-
Given(:stack) { an_empty_stack }
|
36
|
+
Given(:stack) { stack_with(initial_contents) }
|
59
37
|
|
38
|
+
context "when empty" do
|
39
|
+
Given(:initial_contents) { [] }
|
60
40
|
Then { stack.depth.should == 0 }
|
61
41
|
|
62
|
-
context "
|
42
|
+
context "when pushing" do
|
63
43
|
When { stack.push(:an_item) }
|
64
44
|
|
65
45
|
Then { stack.depth.should == 1 }
|
@@ -67,10 +47,10 @@ describe Stack do
|
|
67
47
|
end
|
68
48
|
end
|
69
49
|
|
70
|
-
context "
|
71
|
-
Given(:
|
50
|
+
context "with one item" do
|
51
|
+
Given(:initial_contents) { [:an_item] }
|
72
52
|
|
73
|
-
context "popping
|
53
|
+
context "when popping" do
|
74
54
|
When(:pop_result) { stack.pop }
|
75
55
|
|
76
56
|
Then { pop_result.should == :an_item }
|
@@ -78,18 +58,18 @@ describe Stack do
|
|
78
58
|
end
|
79
59
|
end
|
80
60
|
|
81
|
-
context "
|
82
|
-
Given(:
|
61
|
+
context "with several items" do
|
62
|
+
Given(:initial_contents) { [:second_item, :top_item] }
|
83
63
|
Given!(:original_depth) { stack.depth }
|
84
64
|
|
85
|
-
context "pushing
|
65
|
+
context "when pushing" do
|
86
66
|
When { stack.push(:new_item) }
|
87
67
|
|
88
68
|
Then { stack.top.should == :new_item }
|
89
69
|
Then { stack.depth.should == original_depth + 1 }
|
90
70
|
end
|
91
71
|
|
92
|
-
context "popping
|
72
|
+
context "when popping" do
|
93
73
|
When(:pop_result) { stack.pop }
|
94
74
|
|
95
75
|
Then { pop_result.should == :top_item }
|
@@ -100,7 +80,8 @@ describe Stack do
|
|
100
80
|
end
|
101
81
|
</pre>
|
102
82
|
|
103
|
-
Let's talk about the individual
|
83
|
+
Let's talk about the individual statements used in the Given
|
84
|
+
framework.
|
104
85
|
|
105
86
|
### Given
|
106
87
|
|
@@ -110,10 +91,15 @@ standard test frameworks the preconditions are established with a
|
|
110
91
|
combination of setup methods (or :before actions in RSpec) and code in
|
111
92
|
the test.
|
112
93
|
|
113
|
-
In the example code above
|
114
|
-
|
115
|
-
|
116
|
-
|
94
|
+
In the example code above the preconditions are started with _Given_
|
95
|
+
statements. A top level _Given_ (that applies to the entire describe
|
96
|
+
block) says that one of the preconditions is that there is a stack
|
97
|
+
with some initial contents.
|
98
|
+
|
99
|
+
Note that initial contents are not specified in the top level describe
|
100
|
+
block, but are given in each of the nested contexts. By pushing the
|
101
|
+
definition of "initial_contents" into the nested contexts, we can vary
|
102
|
+
them as needed for that particular context.
|
117
103
|
|
118
104
|
A precondition in the form "Given(:var) {...}" creates an accessor
|
119
105
|
method named "var". The accessor is lazily initialized by the code
|
@@ -127,13 +113,78 @@ The preconditions are run in order of definition. Nested contexts
|
|
127
113
|
will inherit the preconditions from the enclosing context, with out
|
128
114
|
preconditions running before inner preconditions.
|
129
115
|
|
116
|
+
#### Given examples:
|
117
|
+
|
118
|
+
<pre>
|
119
|
+
Given(:stack) { Stack.new }
|
120
|
+
</pre>
|
121
|
+
|
122
|
+
The given block is lazily run if 'stack' is ever referenced in the
|
123
|
+
test and the value of the block is bound to 'stack'. The first
|
124
|
+
reference to 'stack' in the specification will cause the code block to
|
125
|
+
execute. Futher references to 'stack' will reuse the previously
|
126
|
+
generated value.
|
127
|
+
|
128
|
+
<pre>
|
129
|
+
Given!(:original_size) { stack.size }
|
130
|
+
</pre>
|
131
|
+
|
132
|
+
The code block is run unconditionally once before each test and the
|
133
|
+
value of the block is bound to 'original_size'. This form is useful
|
134
|
+
when you want to record the value of something that might be affected
|
135
|
+
by the When code.
|
136
|
+
|
137
|
+
<pre>
|
138
|
+
Given { stack.clear }
|
139
|
+
</pre>
|
140
|
+
|
141
|
+
The given block is run unconditionally once before each test. This
|
142
|
+
form of given is used for code that is executed for side effects.
|
143
|
+
|
130
144
|
### When
|
131
145
|
|
132
146
|
The _When_ block specifies the code to be tested ... oops, excuse me
|
133
147
|
... specified. After the preconditions in the given section are met,
|
134
148
|
the when code block is run.
|
135
149
|
|
136
|
-
There should only be one _When_ block for a given context.
|
150
|
+
There should only be one _When_ block for a given context. However, a
|
151
|
+
_When_ in an outer context shoud be treated as a _Given_ in an inner
|
152
|
+
context. E.g.
|
153
|
+
|
154
|
+
<pre>
|
155
|
+
context "outer context" do
|
156
|
+
When { code specified in the outer context }
|
157
|
+
Then { assert something about the outer context }
|
158
|
+
|
159
|
+
context "inner context" do
|
160
|
+
|
161
|
+
# At this point, the _When_ of the outer context
|
162
|
+
# should be treated as a _Given_ of the inner context
|
163
|
+
|
164
|
+
When { code specified in the inner context }
|
165
|
+
Then { assert something about the inner context }
|
166
|
+
end
|
167
|
+
end
|
168
|
+
</pre>
|
169
|
+
|
170
|
+
#### When examples:
|
171
|
+
|
172
|
+
<pre>
|
173
|
+
When { stack.push(:item) }
|
174
|
+
</pre>
|
175
|
+
|
176
|
+
The code block is executed once per test. The effect of the _When{}_
|
177
|
+
block is very similar to _Given{}_. However, When is used to identify
|
178
|
+
the particular code that is being specified in the current context or
|
179
|
+
describe block.
|
180
|
+
|
181
|
+
<pre>
|
182
|
+
When(:result) { stack.pop }
|
183
|
+
</pre>
|
184
|
+
|
185
|
+
The code block is executed once per test and the value of the code
|
186
|
+
block is bound to 'result'. Use this form when the code under test
|
187
|
+
returns a value that you wish to interrogate in the _Then_ code.
|
137
188
|
|
138
189
|
### Then
|
139
190
|
|
@@ -141,10 +192,19 @@ The _Then_ sections are the postconditions of the specification. These
|
|
141
192
|
then conditions must be true after the code under test (the _When_
|
142
193
|
block) is run.
|
143
194
|
|
144
|
-
The code in the _Then_ block should be a single
|
145
|
-
|
146
|
-
|
195
|
+
The code in the _Then_ block should be a single _should_
|
196
|
+
assertion. Code in _Then_ blocks should not have any side effects.
|
197
|
+
|
198
|
+
#### Then examples:
|
147
199
|
|
200
|
+
<pre>
|
201
|
+
Then { stack.should be_empty }
|
202
|
+
</pre>
|
203
|
+
|
204
|
+
After the related _When_ block is run, the stack should be empty. If
|
205
|
+
it is not empty, the test will fail.
|
206
|
+
|
207
|
+
<!--
|
148
208
|
### Invariant
|
149
209
|
|
150
210
|
The _Invariant_ block is a new idea that doesn't have an analog in
|
@@ -158,7 +218,7 @@ You can conceptually think of an _Invariant_ block as a _Then_ block
|
|
158
218
|
that automatically gets added to every _When_ within its scope.
|
159
219
|
|
160
220
|
Invariants nested within a context only apply to the _When_ blocks in
|
161
|
-
that context.
|
221
|
+
that context.
|
162
222
|
|
163
223
|
Invariants that reference a _Given_ precondition accessor must only be
|
164
224
|
used in contexts that define that accessor.
|
@@ -166,9 +226,33 @@ used in contexts that define that accessor.
|
|
166
226
|
NOTE: Invariants are not yet implemented in the current version of
|
167
227
|
rspec-given.
|
168
228
|
|
229
|
+
-->
|
230
|
+
|
231
|
+
# Future Directions
|
232
|
+
|
233
|
+
I really like the way the Given framework is working out. I feel my
|
234
|
+
tests are much more like specifications when I use it. However, I'm
|
235
|
+
not entirely happy with it.
|
236
|
+
|
237
|
+
First, I would like to introduce invariants. An _Invariant_ block
|
238
|
+
would essentially be a post-conditions that should be true after
|
239
|
+
_Then_ block in the same (or nested) context as the invariant.
|
240
|
+
|
241
|
+
Second, I would like to remove the need for the ".should" in all the
|
242
|
+
_Then_ blocks. In other words, instead of saying:
|
243
|
+
|
244
|
+
Then { x.should == y }
|
245
|
+
|
246
|
+
we could say:
|
247
|
+
|
248
|
+
Then { x == y }
|
249
|
+
|
250
|
+
I think the [wrong assertion library](http://rubygems.org/gems/wrong)
|
251
|
+
has laid some groundwork in this area.
|
252
|
+
|
169
253
|
# Links
|
170
254
|
|
171
|
-
* Github: [https://github.com/jimweirich/rspec-given](https://github.com/jimweirich/rspec-given)
|
255
|
+
* Github: [https://github.com/jimweirich/rspec-given](https://github.com/jimweirich/rspec-given)
|
172
256
|
* Clone URL: git://github.com/jimweirich/rspec-given.git
|
173
|
-
* Bug/Issue Reporting: [http://onestepback.org/cgi-bin/bugs.cgi?project=rspec-given](http://onestepback.org/cgi-bin/bugs.cgi?project=rspec-given)
|
257
|
+
* Bug/Issue Reporting: [http://onestepback.org/cgi-bin/bugs.cgi?project=rspec-given](http://onestepback.org/cgi-bin/bugs.cgi?project=rspec-given)
|
174
258
|
|
data/Rakefile
CHANGED
@@ -7,8 +7,11 @@ CLOBBER.include("*.gemspec", "html")
|
|
7
7
|
|
8
8
|
# README Formatting --------------------------------------------------
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
begin
|
11
|
+
require 'bluecloth'
|
12
|
+
rescue LoadError => ex
|
13
|
+
puts "WARNING: BlueCloth not available"
|
14
|
+
end
|
12
15
|
|
13
16
|
task :default => :examples
|
14
17
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rspec/given'
|
1
2
|
require 'spec_helper'
|
2
3
|
require 'stack'
|
3
4
|
|
@@ -6,27 +7,19 @@ describe Stack do
|
|
6
7
|
# Invariant { stack.depth >= 0 }
|
7
8
|
# Invariant { stack.empty? == (stack.depth == 0) }
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
s.push(:an_item)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
Given(:a_stack_with_several_items) do
|
18
|
-
Stack.new.tap do |s|
|
19
|
-
s.push(:second_item)
|
20
|
-
s.push(:top_item)
|
21
|
-
end
|
10
|
+
def stack_with(initial_contents)
|
11
|
+
stack = Stack.new
|
12
|
+
initial_contents.each do |item| stack.push(item) end
|
13
|
+
stack
|
22
14
|
end
|
23
15
|
|
24
|
-
|
25
|
-
Given(:stack) { an_empty_stack }
|
16
|
+
Given(:stack) { stack_with(initial_contents) }
|
26
17
|
|
18
|
+
context "when empty" do
|
19
|
+
Given(:initial_contents) { [] }
|
27
20
|
Then { stack.depth.should == 0 }
|
28
21
|
|
29
|
-
|
22
|
+
context "when pushing" do
|
30
23
|
When { stack.push(:an_item) }
|
31
24
|
|
32
25
|
Then { stack.depth.should == 1 }
|
@@ -34,10 +27,10 @@ describe Stack do
|
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
37
|
-
context "
|
38
|
-
Given(:
|
30
|
+
context "with one item" do
|
31
|
+
Given(:initial_contents) { [:an_item] }
|
39
32
|
|
40
|
-
|
33
|
+
context "when popping" do
|
41
34
|
When(:pop_result) { stack.pop }
|
42
35
|
|
43
36
|
Then { pop_result.should == :an_item }
|
@@ -45,18 +38,18 @@ describe Stack do
|
|
45
38
|
end
|
46
39
|
end
|
47
40
|
|
48
|
-
context "
|
49
|
-
Given(:
|
41
|
+
context "with several items" do
|
42
|
+
Given(:initial_contents) { [:second_item, :top_item] }
|
50
43
|
Given!(:original_depth) { stack.depth }
|
51
44
|
|
52
|
-
|
45
|
+
context "when pushing" do
|
53
46
|
When { stack.push(:new_item) }
|
54
47
|
|
55
48
|
Then { stack.top.should == :new_item }
|
56
49
|
Then { stack.depth.should == original_depth + 1 }
|
57
50
|
end
|
58
51
|
|
59
|
-
|
52
|
+
context "when popping" do
|
60
53
|
When(:pop_result) { stack.pop }
|
61
54
|
|
62
55
|
Then { pop_result.should == :top_item }
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rspec/given'
|
2
|
+
require 'wrong'
|
3
|
+
|
4
|
+
include Wrong
|
5
|
+
|
6
|
+
describe "Using Wrong" do
|
7
|
+
def self.Should(&block)
|
8
|
+
specify do
|
9
|
+
assert(&block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Scenario "trying wrong's assert" do
|
14
|
+
# Given(:a) { 1 }
|
15
|
+
# Given(:b) { 1 }
|
16
|
+
# Then { a == b }
|
17
|
+
# end
|
18
|
+
|
19
|
+
context "trying wrong's assert" do
|
20
|
+
Given(:a) { 1 }
|
21
|
+
Given(:b) { 2 }
|
22
|
+
puts "DBG: BEFORE THEN"
|
23
|
+
Should { a == b }
|
24
|
+
puts "DBG: AFTER THEN"
|
25
|
+
end
|
26
|
+
end
|
data/lib/rspec/given/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 1.3.
|
8
|
+
- 1
|
9
|
+
version: 1.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jim Weirich
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2011-02-01 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- examples/spec_helper.rb
|
65
65
|
- examples/stack/stack.rb
|
66
66
|
- examples/stack/stack_spec.rb
|
67
|
+
- examples/wrong/wrong_spec.rb
|
67
68
|
has_rdoc: true
|
68
69
|
homepage: http://github.com/jimweirich/rspec-given
|
69
70
|
licenses: []
|