rspec 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +57 -32
- data/EXAMPLES.rd +0 -0
- data/Rakefile +22 -21
- data/bin/spec +9 -11
- data/doc/README +1 -3
- data/doc/plugin/syntax.rb +27 -5
- data/doc/src/core_team.page +22 -0
- data/doc/src/default.css +11 -11
- data/doc/src/default.template +0 -1
- data/doc/src/documentation/index.page +183 -8
- data/doc/src/documentation/meta.info +7 -7
- data/doc/src/documentation/mocks.page +168 -109
- data/doc/src/documentation/underscores.page +20 -0
- data/doc/src/examples.page +2 -1
- data/doc/src/images/David_and_Aslak.jpg +0 -0
- data/doc/src/images/Whats_That_Dude.jpg +0 -0
- data/doc/src/index.page +70 -3
- data/doc/src/meta.info +18 -11
- data/doc/src/tools/index.page +40 -134
- data/doc/src/tools/meta.info +9 -3
- data/doc/src/tools/rails.page +3 -1
- data/doc/src/tools/rake.page +20 -3
- data/doc/src/tools/rcov.page +19 -0
- data/doc/src/tools/spec.page +99 -0
- data/doc/src/tools/test2rspec.page +2 -4
- data/doc/src/tutorials/index.page +52 -0
- data/doc/src/tutorials/meta.info +31 -0
- data/doc/src/tutorials/notes.txt +252 -0
- data/doc/src/tutorials/stack.rb +11 -0
- data/doc/src/tutorials/stack_01.page +224 -0
- data/doc/src/tutorials/stack_02.page +180 -0
- data/doc/src/tutorials/stack_03.page +291 -0
- data/doc/src/tutorials/stack_04.page +203 -0
- data/doc/src/tutorials/stack_04.page.orig +123 -0
- data/doc/src/tutorials/stack_05.page +90 -0
- data/doc/src/tutorials/stack_05.page.orig +124 -0
- data/doc/src/tutorials/stack_06.page +359 -0
- data/doc/src/tutorials/stack_06.page.orig +359 -0
- data/doc/src/tutorials/stack_spec.rb +41 -0
- data/examples/airport_spec.rb +4 -4
- data/examples/{spec_framework_spec.rb → bdd_framework_spec.rb} +6 -7
- data/examples/mocking_spec.rb +0 -5
- data/examples/stack_spec.rb +6 -7
- data/examples/sugar_spec.rb +14 -0
- data/lib/spec/api.rb +5 -2
- data/lib/spec/api/helper/should_base.rb +17 -22
- data/lib/spec/api/helper/should_helper.rb +4 -3
- data/lib/spec/api/helper/should_negator.rb +3 -2
- data/lib/spec/api/mocks/argument_expectation.rb +104 -0
- data/lib/spec/api/{mock.rb → mocks/message_expectation.rb} +47 -96
- data/lib/spec/api/mocks/mock.rb +63 -0
- data/lib/spec/api/mocks/order_group.rb +21 -0
- data/lib/spec/api/sugar.rb +47 -0
- data/lib/spec/rake/rcov_verify.rb +45 -0
- data/lib/spec/rake/spectask.rb +41 -56
- data/lib/spec/runner.rb +4 -1
- data/lib/spec/runner/backtrace_tweaker.rb +24 -3
- data/lib/spec/runner/base_text_formatter.rb +28 -0
- data/lib/spec/runner/context.rb +21 -18
- data/lib/spec/runner/context_runner.rb +20 -31
- data/lib/spec/runner/execution_context.rb +3 -3
- data/lib/spec/runner/kernel_ext.rb +10 -1
- data/lib/spec/runner/option_parser.rb +32 -14
- data/lib/spec/runner/progress_bar_formatter.rb +21 -0
- data/lib/spec/runner/rdoc_formatter.rb +15 -5
- data/lib/spec/runner/reporter.rb +100 -0
- data/lib/spec/runner/specdoc_formatter.rb +20 -0
- data/lib/spec/runner/specification.rb +42 -22
- data/lib/spec/version.rb +1 -1
- data/test/rcov/rcov_testtask.rb +1 -0
- data/test/spec/api/duck_type_test.rb +4 -4
- data/test/spec/api/helper/raising_test.rb +37 -17
- data/test/spec/api/{mock_arg_constraints_test.rb → mocks/mock_arg_constraints_test.rb} +10 -4
- data/test/spec/api/mocks/mock_ordering_test.rb +62 -0
- data/test/spec/api/{mock_test.rb → mocks/mock_test.rb} +30 -7
- data/test/spec/api/mocks/null_object_test.rb +31 -0
- data/test/spec/api/sugar_test.rb +71 -0
- data/test/spec/runner/backtrace_tweaker_test.rb +52 -4
- data/test/spec/runner/context_runner_test.rb +41 -21
- data/test/spec/runner/context_test.rb +60 -32
- data/test/spec/runner/execution_context_test.rb +4 -3
- data/test/spec/runner/failure_dump_test.rb +92 -0
- data/test/spec/runner/kernel_ext_test.rb +1 -2
- data/test/spec/runner/option_parser_test.rb +48 -28
- data/test/spec/runner/progress_bar_formatter_test.rb +48 -0
- data/test/spec/runner/rdoc_formatter_test.rb +31 -4
- data/test/spec/runner/reporter_test.rb +103 -0
- data/test/spec/runner/specdoc_formatter_test.rb +50 -0
- data/test/spec/runner/specification_test.rb +49 -11
- data/test/test_helper.rb +1 -4
- metadata +46 -15
- data/doc/src/community.page +0 -7
- data/doc/src/documentation/api.page +0 -185
- data/doc/src/why_rspec.page +0 -7
- data/examples/empty_stack_spec.rb +0 -22
- data/examples/team_spec.rb +0 -30
- data/lib/spec/api/duck_type.rb +0 -16
- data/lib/spec/runner/simple_text_reporter.rb +0 -88
- data/test/rcov/rcov_verify.rb +0 -28
- data/test/spec/runner/simple_text_reporter_test.rb +0 -123
@@ -0,0 +1,31 @@
|
|
1
|
+
index.page:
|
2
|
+
title: Overview
|
3
|
+
inMenu: true
|
4
|
+
orderInfo: 10
|
5
|
+
|
6
|
+
stack_01.page:
|
7
|
+
title: '1'
|
8
|
+
inMenu: true
|
9
|
+
orderInfo: 11
|
10
|
+
|
11
|
+
stack_02.page:
|
12
|
+
title: '2'
|
13
|
+
inMenu: true
|
14
|
+
orderInfo: 12
|
15
|
+
|
16
|
+
stack_03.page:
|
17
|
+
title: '3'
|
18
|
+
inMenu: true
|
19
|
+
orderInfo: 13
|
20
|
+
|
21
|
+
stack_04.page:
|
22
|
+
title: '4'
|
23
|
+
inMenu: true
|
24
|
+
orderInfo: 14
|
25
|
+
|
26
|
+
stack_05.page:
|
27
|
+
title: '5'
|
28
|
+
inMenu: true
|
29
|
+
orderInfo: 15
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,252 @@
|
|
1
|
+
<ruby>
|
2
|
+
context "A stack with one item" do
|
3
|
+
|
4
|
+
setup do
|
5
|
+
@stack = Stack.new
|
6
|
+
@stack.push "one item"
|
7
|
+
end
|
8
|
+
|
9
|
+
specify "should return top when you send it 'top'" do
|
10
|
+
@stack.top.should.equal "one item"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
</ruby>
|
15
|
+
|
16
|
+
Run the spec...
|
17
|
+
|
18
|
+
<pre>
|
19
|
+
$ spec stack_spec.rb -v
|
20
|
+
|
21
|
+
An empty stack
|
22
|
+
- should keep its mouth shut when you send it 'push'
|
23
|
+
|
24
|
+
A stack with one item
|
25
|
+
- should return top when you send it 'top' (FAILED - 1)
|
26
|
+
|
27
|
+
|
28
|
+
1)
|
29
|
+
NoMethodError in 'A stack with one item should return top when you send it 'top''
|
30
|
+
undefined method `top' for #<Stack:0x3703bc @item="one item">
|
31
|
+
./stack_spec.rb:35:in `should return top when you send it 'top''
|
32
|
+
|
33
|
+
Finished in 0.000677 seconds
|
34
|
+
|
35
|
+
2 contexts, 2 specifications, 1 failure
|
36
|
+
</pre>
|
37
|
+
|
38
|
+
Again, running the spec tells us what we have to implement next. <code>undefined method `top' for #<Stack:0x3703bc @item="one item"></code> tells us to implement a <code>top</code> method. So, back in stack.rb...
|
39
|
+
|
40
|
+
<ruby>
|
41
|
+
def top
|
42
|
+
end
|
43
|
+
</ruby>
|
44
|
+
|
45
|
+
Why not implement the return now? Well, this becomes a matter of taste and level of discipline. While you're learning BDD (especially if you have no prior TDD experience), you want to take very, very small steps. There's usually something to learn after each one. In this case, if we run the spec now...
|
46
|
+
|
47
|
+
<pre>
|
48
|
+
$ spec stack_spec.rb -v
|
49
|
+
|
50
|
+
An empty stack
|
51
|
+
- should keep its mouth shut when you send it 'push'
|
52
|
+
|
53
|
+
A stack with one item
|
54
|
+
- should return top when you send it 'top' (FAILED - 1)
|
55
|
+
|
56
|
+
|
57
|
+
1)
|
58
|
+
ExpectationNotMetError in 'A stack with one item should return top when you send it 'top''
|
59
|
+
nil should equal "one item"
|
60
|
+
./stack_spec.rb:35:in `should return top when you send it 'top''
|
61
|
+
|
62
|
+
Finished in 0.000531 seconds
|
63
|
+
|
64
|
+
2 contexts, 2 specifications, 1 failure
|
65
|
+
</pre>
|
66
|
+
|
67
|
+
This is a very interesting result. <code>nil should equal "one item"</code> tells us that the expression <code>@stack.top</code> returned nil. In ruby, nil is a real object to which you can send messages. <code>should.equal "one item"</code> tells rspec that the object returned by the expression (in this case nil) should be equal to the string literal "one item".
|
68
|
+
|
69
|
+
So let's get the code to meet this specification. When we do this, we want to implement the simplest thing that we can to satisfy the existing specs. Given the current set of specs, we can simply return "one item"
|
70
|
+
|
71
|
+
<ruby>
|
72
|
+
class Stack
|
73
|
+
|
74
|
+
def push item
|
75
|
+
end
|
76
|
+
|
77
|
+
def top
|
78
|
+
"one item"
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
</ruby>
|
83
|
+
|
84
|
+
Run the specs...
|
85
|
+
|
86
|
+
<pre>
|
87
|
+
$ spec stack_spec.rb -v
|
88
|
+
|
89
|
+
An empty stack
|
90
|
+
- should keep its mouth shut when you send it 'push'
|
91
|
+
|
92
|
+
A stack with one item
|
93
|
+
- should return top when you send it 'top'
|
94
|
+
|
95
|
+
|
96
|
+
Finished in 0.0004 seconds
|
97
|
+
|
98
|
+
2 contexts, 2 specifications, 0 failures
|
99
|
+
</pre>
|
100
|
+
|
101
|
+
Seems odd? We know that we don't want to always return "one item", so the implementation seems silly. But that implementation did something great. It made it so all of our expectations are met and we didn't have to change much to get there. We always want to take really small steps, with all the specs passing between each step. Now that we have passing specs, we're free to refactor - and we WANT to refactor because we've introduced duplication between the specs and the implementation.
|
102
|
+
|
103
|
+
So let's refactor to eliminate this duplication. We can use the existing push method to setup the item that top will return.
|
104
|
+
|
105
|
+
<ruby>
|
106
|
+
class Stack
|
107
|
+
|
108
|
+
def push item
|
109
|
+
@item = item
|
110
|
+
end
|
111
|
+
|
112
|
+
def top
|
113
|
+
@item
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
</ruby>
|
118
|
+
|
119
|
+
So now we have two specifications, each with their own context. We've implemented two simple methods that satisfy the existing specifications. If you've never done any TDD before this, this may seem really odd. We all know that this isn't enough to meet the specs that we intend. But right now, at this moment, as far as the code is concerned, there are only two simple specifications. To move our implementation along, we first have to specify more about how we want our stack to behave.
|
120
|
+
|
121
|
+
<a href="stack_01.html">Previous</a> |
|
122
|
+
<a href="stack_03.html">Next</a>
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
OK. That's pretty standard stuff so far, but it's all about the object's <em><b>state</b></em>, not its behaviour. We want to think about what our Stack does - how it responds to various messages that we can send it. What should an empty Stack do when you send it the push method? Absolutely nothing, right? It should just accept the object and keep its mouth shut:
|
137
|
+
|
138
|
+
<ruby>
|
139
|
+
context "An empty stack" do
|
140
|
+
...
|
141
|
+
specify "should keep its mouth shut when you send it 'push'" do
|
142
|
+
end
|
143
|
+
end
|
144
|
+
</ruby>
|
145
|
+
<pre>
|
146
|
+
$ spec stack_spec.rb -f s
|
147
|
+
|
148
|
+
A new stack
|
149
|
+
- should be empty
|
150
|
+
|
151
|
+
An empty stack
|
152
|
+
- should not be empty after 'push'
|
153
|
+
- should keep its mouth shut when you send it 'push'
|
154
|
+
|
155
|
+
Finished in 0.000552 seconds
|
156
|
+
|
157
|
+
2 contexts, 3 specifications, 0 failures
|
158
|
+
</pre>
|
159
|
+
|
160
|
+
Actually, I'd like the "keep its mouth shut" spec to come first - I think it reads better. So let's just switch them around in the context:
|
161
|
+
|
162
|
+
<ruby>
|
163
|
+
context "An empty stack" do
|
164
|
+
setup do
|
165
|
+
@stack = Stack.new
|
166
|
+
end
|
167
|
+
|
168
|
+
specify "should keep its mouth shut when you send it 'push'" do
|
169
|
+
end
|
170
|
+
|
171
|
+
specify "should not be empty after 'push'" do
|
172
|
+
@stack.push 37
|
173
|
+
@stack.should_not_be_empty
|
174
|
+
end
|
175
|
+
end
|
176
|
+
</ruby>
|
177
|
+
<br>
|
178
|
+
<pre>$ spec stack_spec.rb -f s
|
179
|
+
|
180
|
+
A new stack
|
181
|
+
- should be empty
|
182
|
+
|
183
|
+
An empty stack
|
184
|
+
- should keep its mouth shut when you send it 'push'
|
185
|
+
- should not be empty after 'push'
|
186
|
+
|
187
|
+
Finished in 0.000557 seconds
|
188
|
+
|
189
|
+
2 contexts, 3 specifications, 0 failures
|
190
|
+
</pre>
|
191
|
+
|
192
|
+
RSpec reads the contexts and specs within a given file in the order in which they appear, giving you some control over this output.
|
193
|
+
|
194
|
+
So what can we expect here? The name of the spec tells us - "should keep its mouth shut". That implies that it should not react in any way - including raising an error. So let's set the expectation that there will be no error raised:
|
195
|
+
|
196
|
+
<ruby>
|
197
|
+
specify "should keep its mouth shut when you send it 'push'" do
|
198
|
+
lambda { @stack.push Object.new }.should.not.raise
|
199
|
+
end
|
200
|
+
</ruby>
|
201
|
+
|
202
|
+
If you're not familiar, <code>lambda</code> accepts a block but does not execute it. It then constructs a Proc object, which can called at any time. So, in this case, the block <code>{ stack.push Object.new }</code> gets saved in a Proc object. <code>should.not.raise</code> then tells rSpec to call the Proc and raise an ExpectationNotMetError if it raises any errors at all. Running the spec...
|
203
|
+
|
204
|
+
<pre>
|
205
|
+
$ spec stack_spec.rb -v
|
206
|
+
|
207
|
+
An empty stack
|
208
|
+
- should keep its mouth shut when you send it 'push' (FAILED - 1)
|
209
|
+
|
210
|
+
|
211
|
+
1)
|
212
|
+
ExpectationNotMetError in 'An empty stack should keep its mouth shut when you send it 'push''
|
213
|
+
<Proc> should not raise <Exception> but raised #<NoMethodError: undefined method `push' for #<Stack:0x370d94>>
|
214
|
+
./stack_spec.rb:10:in `should keep its mouth shut when you send it 'push''
|
215
|
+
|
216
|
+
Finished in 0.000418 seconds
|
217
|
+
|
218
|
+
1 context, 1 specification, 1 failure
|
219
|
+
</pre>
|
220
|
+
|
221
|
+
The first line tells us the rSpec error that was raised: we were expecting that nothing would be raised, but something (anything) was, so we get an "ExpectationNotMetError".
|
222
|
+
|
223
|
+
The second line tells us that we specified that there should be no Exception (in this case we didn't specify what type of exception, so by default rSpec assumes Exception), but that there was a NoMethodError raised.
|
224
|
+
|
225
|
+
The third line tells us that the error was raised in the block defining the specification "should keep its mouth shut when you send it 'push'".
|
226
|
+
|
227
|
+
We get a NoMethodError because our stack doesn't know what to do with the "push" message. So we add it...
|
228
|
+
|
229
|
+
<ruby>
|
230
|
+
class Stack
|
231
|
+
def push item
|
232
|
+
end
|
233
|
+
end
|
234
|
+
</ruby>
|
235
|
+
|
236
|
+
...and run the spec and voila!...
|
237
|
+
|
238
|
+
<pre>
|
239
|
+
$ spec stack_spec.rb -v
|
240
|
+
|
241
|
+
An empty stack
|
242
|
+
- should keep its mouth shut when you send it 'push'
|
243
|
+
|
244
|
+
|
245
|
+
Finished in 0.000209 seconds
|
246
|
+
|
247
|
+
1 context, 1 specification, 0 failures
|
248
|
+
</pre>
|
249
|
+
|
250
|
+
... the code meets the first specification. Now obviously this code doesn't do much, but that's because we have more specifications to write!
|
251
|
+
|
252
|
+
One important thing to note here is that we did not begin by setting any expectations about the size or emptiness of the stack. That may feel funny to experienced TDDers, as it is standard faire to verify that an empty collection is empty. As explained in the <a href="index.html">Overview</a>, we're going to explore what it means to specify behaviour rather than testing state. Based on our existing spec thus far, there is no need to have a size or empty method. Let's see how far we can go without them...
|
@@ -0,0 +1,224 @@
|
|
1
|
+
h2. A Simple Stack - The First Specification
|
2
|
+
|
3
|
+
h3. Where do we start?
|
4
|
+
|
5
|
+
We want to start off with the simplest thing that we can specify, just as we would in TDD. Remember that in spite of some important (if subtle) distinctions, BDD <em>is</em> TDD at its core.
|
6
|
+
|
7
|
+
As discussed in the <a href="index.html">Overview</a>, a common first specification is that a new stack should be empty, and we typically verify this by checking that its size is 0. This simplicity is what we're looking for, but we want to avoid the "size" question. Well, let's think about how a client might use a stack:
|
8
|
+
|
9
|
+
<ruby>
|
10
|
+
#example usage
|
11
|
+
stack.pop unless stack.empty?
|
12
|
+
</ruby>
|
13
|
+
|
14
|
+
So let's start with "A new stack should be empty".
|
15
|
+
|
16
|
+
h3. Create a spec file
|
17
|
+
|
18
|
+
Start by creating a file called stack_spec.rb in /projects/ruby/stack/. You can use any filename and directory you wish, but the following will assume these names and locations.
|
19
|
+
|
20
|
+
h3. Add a context
|
21
|
+
|
22
|
+
Add the following to stack_spec.rb
|
23
|
+
|
24
|
+
<ruby>
|
25
|
+
context "A new stack" do
|
26
|
+
end
|
27
|
+
</ruby>
|
28
|
+
|
29
|
+
A context represents an object (or set of objects) in a known state. This is the same concept as a fixture in xUnit. For each known state from which we wish to specify behaviour, we'll add a new context.
|
30
|
+
|
31
|
+
To see what damage we've done so far, open a command shell, cd to /projects/ruby/stack/, and enter the following:
|
32
|
+
|
33
|
+
<pre>
|
34
|
+
$ spec stack_spec.rb
|
35
|
+
</pre>
|
36
|
+
|
37
|
+
You should see output similar to this
|
38
|
+
|
39
|
+
<pre>
|
40
|
+
Finished in 6.9e-05 seconds
|
41
|
+
|
42
|
+
1 context, 0 specifications, 0 failures
|
43
|
+
</pre>
|
44
|
+
|
45
|
+
The <code>spec</code> command is installed when you install rSpec. It requires (using the ruby <code>require</code> method) any file(s) (or all of the files in a directory) that you specify on the command line. The <code>context</code> method accepts a name ("An empty stack") and a block (do ... end) and processes everything inside the block. Since there's nothing in this block to process, we discover that rSpec processed 1 context, but 0 specifications.
|
46
|
+
|
47
|
+
You may wonder why bother with the name? Try adding the <code>-f s</code> option to the command
|
48
|
+
|
49
|
+
<pre>
|
50
|
+
$ spec stack_spec.rb -f s
|
51
|
+
|
52
|
+
A new stack
|
53
|
+
|
54
|
+
Finished in 6.9e-05 seconds
|
55
|
+
|
56
|
+
1 context, 0 specifications, 0 failures
|
57
|
+
</pre>
|
58
|
+
|
59
|
+
The option <code>-f s</code> is a shortcut for <code>--format specdoc</code>, which tells rSpec to print out the names of all the contexts and specifications as they are run. As we progress, you'll see how choosing these names carefully not only documents things well inside the spec files, but also in generated output.
|
60
|
+
|
61
|
+
h3. Add a specification
|
62
|
+
|
63
|
+
The spec that we are starting with is "A new stack should be empty". So far we have the context, "A new stack", but we need the specification, "should be empty" :
|
64
|
+
|
65
|
+
<ruby>
|
66
|
+
context "A new stack" do
|
67
|
+
specify "should be empty" do
|
68
|
+
end
|
69
|
+
end
|
70
|
+
</ruby>
|
71
|
+
<br>
|
72
|
+
<pre>
|
73
|
+
$ spec stack_spec.rb -f s
|
74
|
+
|
75
|
+
A new stack
|
76
|
+
- should be empty
|
77
|
+
|
78
|
+
Finished in 0.000188 seconds
|
79
|
+
|
80
|
+
1 context, 1 specification, 0 failures
|
81
|
+
</pre>
|
82
|
+
|
83
|
+
As you can see, this reads like a specification. This is just like the output you get from running jUnit tests through agiledox. Agiledox was an important part of the inception of BDD, so we built it right into rspec. Of course, we haven't actually written any code in the specification, so we need to add some. Just as we do in TDD, we're going to add one little bit at a time - just enough to produce a failed expectation - followed by just enough code to meet the expectation.
|
84
|
+
|
85
|
+
Let's start by creating the new stack.
|
86
|
+
|
87
|
+
<ruby>
|
88
|
+
context "A new stack" do
|
89
|
+
setup do
|
90
|
+
@stack = Stack.new
|
91
|
+
end
|
92
|
+
specify "should be empty" do
|
93
|
+
end
|
94
|
+
end
|
95
|
+
</ruby>
|
96
|
+
|
97
|
+
Introducing a setup here may seem a bit premature to some, but we know what the context is here: it's a new stack. We want to express that context in the setup method to clearly define it as the starting state for each of the specifications within this context.
|
98
|
+
|
99
|
+
<pre>
|
100
|
+
$ spec stack_spec.rb -f s
|
101
|
+
|
102
|
+
A new stack
|
103
|
+
- should be empty (FAILED - 1)
|
104
|
+
|
105
|
+
1)
|
106
|
+
NameError in 'A new stack should be empty'
|
107
|
+
uninitialized constant Stack
|
108
|
+
./stack_spec.rb:3:in `setup'
|
109
|
+
|
110
|
+
Finished in 0.00031 seconds
|
111
|
+
|
112
|
+
1 context, 1 specification, 1 failure
|
113
|
+
</pre>
|
114
|
+
|
115
|
+
This tells us that there is a NameError, that it can't find the name Stack, and that the problem is in the setup block of this context. To resolve this, create a new file named stack.rb and add the following:
|
116
|
+
|
117
|
+
<ruby>
|
118
|
+
class Stack
|
119
|
+
end
|
120
|
+
</ruby>
|
121
|
+
|
122
|
+
Then require that file in stack_spec.rb:
|
123
|
+
|
124
|
+
<ruby>
|
125
|
+
require 'stack'
|
126
|
+
|
127
|
+
context "A new stack" do
|
128
|
+
...
|
129
|
+
</ruby>
|
130
|
+
|
131
|
+
and run the specs.
|
132
|
+
|
133
|
+
<pre>
|
134
|
+
$ spec stack_spec.rb -f s
|
135
|
+
|
136
|
+
A new stack
|
137
|
+
- should be empty
|
138
|
+
|
139
|
+
Finished in 0.000229 seconds
|
140
|
+
|
141
|
+
1 context, 1 specification, 0 failures
|
142
|
+
</pre>
|
143
|
+
|
144
|
+
We're getting closer, but we still need more to exercise this specification.
|
145
|
+
|
146
|
+
<ruby>
|
147
|
+
context "A new stack" do
|
148
|
+
setup do
|
149
|
+
@stack = Stack.new
|
150
|
+
end
|
151
|
+
specify "should be empty" do
|
152
|
+
@stack.should_be_empty
|
153
|
+
end
|
154
|
+
end
|
155
|
+
</ruby>
|
156
|
+
<br>
|
157
|
+
<pre>
|
158
|
+
$ spec stack_spec.rb -f s
|
159
|
+
|
160
|
+
A new stack
|
161
|
+
- should be empty (FAILED - 1)
|
162
|
+
|
163
|
+
1)
|
164
|
+
NoMethodError in 'A new stack should be empty'
|
165
|
+
undefined method `empty?' for #<Stack:0x36e6fc>
|
166
|
+
./stack_spec.rb:8:in `should be empty'
|
167
|
+
|
168
|
+
Finished in 0.000361 seconds
|
169
|
+
|
170
|
+
1 context, 1 specification, 1 failure
|
171
|
+
</pre>
|
172
|
+
|
173
|
+
In this case, rspec interprets the message <code>should_be_empty</code>, and sends <code>empty?</code> to <code>stack</code>. This will work for any predicate (ruby methods that end with a "?" and return boolean).
|
174
|
+
|
175
|
+
You can think of <code>NameError</code> as the equivalent of a compilation failure in java or C#. <code>Stack</code> doesn't respond to the <code>empty?</code> message ... yet.
|
176
|
+
|
177
|
+
<ruby>
|
178
|
+
class Stack
|
179
|
+
def empty?
|
180
|
+
end
|
181
|
+
end
|
182
|
+
</ruby>
|
183
|
+
<br>
|
184
|
+
<pre>
|
185
|
+
$ spec stack_spec.rb -f s
|
186
|
+
|
187
|
+
A new stack
|
188
|
+
- should be empty (FAILED - 1)
|
189
|
+
|
190
|
+
1)
|
191
|
+
ExpectationNotMetError in 'A new stack should be empty'
|
192
|
+
Stack #<Stack:0x36e60c> should be empty
|
193
|
+
./stack_spec.rb:8:in `should be empty'
|
194
|
+
|
195
|
+
Finished in 0.000389 seconds
|
196
|
+
|
197
|
+
1 context, 1 specification, 1 failure
|
198
|
+
</pre>
|
199
|
+
|
200
|
+
... and NOW we get a failing expectation. "Stack #<Stack:0x36e60c> should be empty" is the detail of this <code>ExpectationNotMetError</code>. The expectation is that <code>empty?</code> should return <code>true</code>, but it does not. Let's make it so ...
|
201
|
+
|
202
|
+
<ruby>
|
203
|
+
class Stack
|
204
|
+
def empty?
|
205
|
+
true
|
206
|
+
end
|
207
|
+
end
|
208
|
+
</ruby>
|
209
|
+
<br>
|
210
|
+
<pre>
|
211
|
+
spec stack_spec.rb -f s
|
212
|
+
|
213
|
+
A new stack
|
214
|
+
- should be empty
|
215
|
+
|
216
|
+
Finished in 0.000256 seconds
|
217
|
+
|
218
|
+
1 context, 1 specification, 0 failures
|
219
|
+
</pre>
|
220
|
+
|
221
|
+
And thus we have completed our first specification: "A new stack should be empty"
|
222
|
+
|
223
|
+
<a href="stack_02.html">Next</a>
|
224
|
+
|