rspec 0.5.11 → 0.5.12
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +12 -0
- data/README +4 -2
- data/Rakefile +14 -4
- data/bin/spec +7 -7
- data/bin/test2spec +13 -8
- data/lib/spec/api/helper/diff.rb +53 -0
- data/lib/spec/api/helper/instance_helper.rb +11 -11
- data/lib/spec/api/helper/instance_negator.rb +11 -11
- data/lib/spec/api/helper/kind_helper.rb +11 -11
- data/lib/spec/api/helper/kind_negator.rb +11 -11
- data/lib/spec/api/helper/respond_helper.rb +11 -11
- data/lib/spec/api/helper/respond_negator.rb +11 -11
- data/lib/spec/api/helper/should_base.rb +6 -6
- data/lib/spec/api/helper/should_helper.rb +35 -35
- data/lib/spec/api/helper/should_negator.rb +20 -20
- data/lib/spec/rake/spectask.rb +15 -6
- data/lib/spec/runner.rb +1 -0
- data/lib/spec/runner/backtrace_tweaker.rb +2 -0
- data/lib/spec/runner/base_text_formatter.rb +3 -1
- data/lib/spec/runner/html_formatter.rb +153 -0
- data/lib/spec/runner/option_parser.rb +9 -2
- data/lib/spec/runner/progress_bar_formatter.rb +4 -0
- data/lib/spec/runner/rdoc_formatter.rb +3 -0
- data/lib/spec/runner/reporter.rb +5 -5
- data/lib/spec/runner/specdoc_formatter.rb +3 -0
- data/lib/spec/test_to_spec/sexp_transformer.rb +1 -0
- data/lib/spec/test_to_spec/translation_test_runner.rb +10 -2
- data/lib/spec/version.rb +1 -1
- data/test/spec/api/helper/arbitrary_predicate_test.rb +49 -73
- data/test/spec/api/helper/diff_test.rb +60 -0
- data/test/spec/api/helper/equality_test.rb +14 -0
- data/test/spec/api/helper/should_have_test.rb +0 -29
- data/test/spec/api/helper/typing_test.rb +87 -87
- data/test/spec/api/sugar_test.rb +0 -6
- data/test/spec/runner/backtrace_tweaker_test.rb +8 -2
- data/test/spec/runner/html_formatter_test.rb +47 -0
- data/test/spec/runner/option_parser_test.rb +0 -5
- data/test/test_classes.rb +73 -0
- data/test/test_helper.rb +3 -0
- metadata +8 -49
- data/doc/README +0 -3
- data/doc/config.yaml +0 -2
- data/doc/plugin/syntax.rb +0 -60
- data/doc/plugin/version.rb +0 -19
- data/doc/src/core_team.page +0 -31
- data/doc/src/default.css +0 -199
- data/doc/src/default.template +0 -31
- data/doc/src/documentation/index.page +0 -188
- data/doc/src/documentation/meta.info +0 -22
- data/doc/src/documentation/mocks.page +0 -287
- data/doc/src/documentation/underscores.page +0 -21
- data/doc/src/examples.page +0 -9
- data/doc/src/images/David_and_Aslak.jpg +0 -0
- data/doc/src/images/Whats_That_Dude.jpg +0 -0
- data/doc/src/images/ducks1.png +0 -0
- data/doc/src/images/ul.gif +0 -0
- data/doc/src/index.page +0 -74
- data/doc/src/meta.info +0 -33
- data/doc/src/tools/index.page +0 -49
- data/doc/src/tools/meta.info +0 -18
- data/doc/src/tools/rails.page +0 -132
- data/doc/src/tools/rake.page +0 -21
- data/doc/src/tools/rcov.page +0 -28
- data/doc/src/tools/spec.page +0 -129
- data/doc/src/tools/test2spec.page +0 -103
- data/doc/src/tutorials/index.page +0 -52
- data/doc/src/tutorials/meta.info +0 -36
- data/doc/src/tutorials/notes.txt +0 -263
- data/doc/src/tutorials/stack.rb +0 -11
- data/doc/src/tutorials/stack_01.page +0 -226
- data/doc/src/tutorials/stack_02.page +0 -182
- data/doc/src/tutorials/stack_03.page +0 -283
- data/doc/src/tutorials/stack_04.page +0 -164
- data/doc/src/tutorials/stack_04.page.orig +0 -123
- data/doc/src/tutorials/stack_05.page +0 -90
- data/doc/src/tutorials/stack_05.page.orig +0 -124
- data/doc/src/tutorials/stack_06.page +0 -359
- data/doc/src/tutorials/stack_06.page.orig +0 -359
- data/doc/src/tutorials/stack_spec.rb +0 -25
- data/doc/src/ul.gif +0 -0
@@ -1,164 +0,0 @@
|
|
1
|
-
h2. A Simple Stack - when a new expectation passes - IN PROGRESS - DISREGARD THIS PAGE
|
2
|
-
|
3
|
-
At this point stack_spec.rb should look like this...
|
4
|
-
|
5
|
-
<ruby>
|
6
|
-
require 'stack'
|
7
|
-
|
8
|
-
context "A new stack" do
|
9
|
-
setup do
|
10
|
-
@stack = Stack.new
|
11
|
-
end
|
12
|
-
|
13
|
-
specify "should be empty" do
|
14
|
-
@stack.should_be_empty
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context "An empty stack" do
|
19
|
-
setup do
|
20
|
-
@stack = Stack.new
|
21
|
-
end
|
22
|
-
|
23
|
-
specify "should not be empty after 'push'" do
|
24
|
-
@stack.push 37
|
25
|
-
@stack.should_not_be_empty
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
context "A stack with one item" do
|
30
|
-
setup do
|
31
|
-
@stack = Stack.new
|
32
|
-
@stack.push "one item"
|
33
|
-
end
|
34
|
-
|
35
|
-
specify "should return top when you send it 'top'" do
|
36
|
-
@stack.top.should_equal "one item"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
</ruby>
|
40
|
-
|
41
|
-
stack.rb should look like this...
|
42
|
-
|
43
|
-
<ruby>
|
44
|
-
class Stack
|
45
|
-
def empty?
|
46
|
-
@item.nil?
|
47
|
-
end
|
48
|
-
def push item
|
49
|
-
@item = item
|
50
|
-
end
|
51
|
-
def top
|
52
|
-
@item
|
53
|
-
end
|
54
|
-
end
|
55
|
-
</ruby>
|
56
|
-
|
57
|
-
...and the output should look like this:
|
58
|
-
|
59
|
-
<pre>
|
60
|
-
$ spec stack_spec.rb -f s
|
61
|
-
|
62
|
-
A new stack
|
63
|
-
- should be empty
|
64
|
-
|
65
|
-
An empty stack
|
66
|
-
- should not be empty after 'push'
|
67
|
-
|
68
|
-
A stack with one item
|
69
|
-
- should return top when you send it 'top'
|
70
|
-
|
71
|
-
Finished in 0.000741 seconds
|
72
|
-
|
73
|
-
3 contexts, 4 specifications, 0 failures
|
74
|
-
</pre>
|
75
|
-
|
76
|
-
Again, a really nice feature of using the <code>--format specdoc</code> option (<code>-f s</code> for short) is that you can see the big picture very clearly.
|
77
|
-
|
78
|
-
Look closely at the "An empty stack" context. We say that it "should not be empty after 'push'". Does that strike you as confusing? It may not, but if you think about it, we're taking an object in one state ("An empty stack"), changing its state by pushing an item onto it and THEN setting an expectation about it. You could argue that we're not really specifying behaviour of an empty stack at all here, but rather behaviour of a stack with one element when you call push.
|
79
|
-
|
80
|
-
So let's add that spec to "A stack with one item".
|
81
|
-
|
82
|
-
<ruby>
|
83
|
-
context "A stack with one item" do
|
84
|
-
setup do
|
85
|
-
@stack = Stack.new
|
86
|
-
@stack.push "one item"
|
87
|
-
end
|
88
|
-
|
89
|
-
specify "should return top when you send it 'top'" do
|
90
|
-
@stack.top.should_equal "one item"
|
91
|
-
end
|
92
|
-
|
93
|
-
specify "should not be empty" do
|
94
|
-
@stack.should_not_be_empty
|
95
|
-
end
|
96
|
-
end
|
97
|
-
</ruby>
|
98
|
-
|
99
|
-
<pre>
|
100
|
-
$ spec stack_spec.rb -f s
|
101
|
-
|
102
|
-
A new stack
|
103
|
-
- should be empty
|
104
|
-
|
105
|
-
An empty stack
|
106
|
-
- should not be empty after 'push'
|
107
|
-
|
108
|
-
A stack with one item
|
109
|
-
- should return top when you send it 'top'
|
110
|
-
- should not be empty
|
111
|
-
|
112
|
-
Finished in 0.000849 seconds
|
113
|
-
|
114
|
-
3 contexts, 4 specifications, 0 failures
|
115
|
-
</pre>
|
116
|
-
|
117
|
-
And now we can just remove "An empty spec" from stack_spec.rb.
|
118
|
-
|
119
|
-
<ruby>
|
120
|
-
require 'stack'
|
121
|
-
|
122
|
-
context "A new stack" do
|
123
|
-
setup do
|
124
|
-
@stack = Stack.new
|
125
|
-
end
|
126
|
-
specify "should be empty" do
|
127
|
-
@stack.should_be_empty
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context "A stack with one item" do
|
132
|
-
setup do
|
133
|
-
@stack = Stack.new
|
134
|
-
@stack.push "one item"
|
135
|
-
end
|
136
|
-
|
137
|
-
specify "should return top when you send it 'top'" do
|
138
|
-
@stack.top.should_equal "one item"
|
139
|
-
end
|
140
|
-
|
141
|
-
specify "should not be empty" do
|
142
|
-
@stack.should_not_be_empty
|
143
|
-
end
|
144
|
-
end
|
145
|
-
</ruby>
|
146
|
-
|
147
|
-
<pre>
|
148
|
-
$ spec stack_spec.rb -f s
|
149
|
-
|
150
|
-
A new stack
|
151
|
-
- should be empty
|
152
|
-
|
153
|
-
A stack with one item
|
154
|
-
- should return top when you send it 'top'
|
155
|
-
- should not be empty
|
156
|
-
|
157
|
-
Finished in 0.000565 seconds
|
158
|
-
|
159
|
-
2 contexts, 3 specifications, 0 failures
|
160
|
-
</pre>
|
161
|
-
|
162
|
-
So keep your eye on the contexts and specifications as they evolve. Don't be afraid to move specs around. There are many different benefits that we get from these executable specifications. One is that it helps us to drive code, resulting in very simple and well tested code. Another very important benefit is that future developers can look at them and understand how to use a component (module, class, method, etc). Keep them in mind. "They" may even be you!
|
163
|
-
|
164
|
-
<a href="stack_03.html">Previous</a>
|
@@ -1,123 +0,0 @@
|
|
1
|
-
h2. A Simple Stack - Top - IN PROGRESS - DISREGARD THIS PAGE
|
2
|
-
|
3
|
-
What should happen when you call top on an empty stack? We could just return nil,
|
4
|
-
but how does the client know whether the stack was empty or contained nil as an element?
|
5
|
-
Perhaps the client doesn't care. Let's assume the client does care, in which case we'd want to raise an error.
|
6
|
-
|
7
|
-
We already have our "empty stack" context, so let's add a specification to it.
|
8
|
-
|
9
|
-
<ruby>
|
10
|
-
context "An empty stack" do
|
11
|
-
|
12
|
-
setup do
|
13
|
-
@stack = Stack.new
|
14
|
-
end
|
15
|
-
|
16
|
-
specify "should keep its mouth shut when you send it 'push'" do
|
17
|
-
lambda { @stack.push Object.new }.should_not_raise Exception
|
18
|
-
end
|
19
|
-
|
20
|
-
specify "should raise a StackUnderflowError when you send it 'top'" do
|
21
|
-
lambda { @stack.top }.should_raise StackUnderflowError
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
</ruby>
|
26
|
-
|
27
|
-
Running the spec...
|
28
|
-
|
29
|
-
<pre>
|
30
|
-
$ spec stack_spec.rb -v
|
31
|
-
|
32
|
-
An empty stack
|
33
|
-
- should keep its mouth shut when you send it 'push'
|
34
|
-
- should raise a StackUnderflowError when you send it 'top' (FAILED - 1)
|
35
|
-
|
36
|
-
A stack with one item
|
37
|
-
- should return top when you send it 'top'
|
38
|
-
|
39
|
-
|
40
|
-
1)
|
41
|
-
NameError in 'An empty stack should raise a StackUnderflowError when you send it 'top''
|
42
|
-
uninitialized constant StackUnderflowError
|
43
|
-
./stack_spec.rb:14:in `should raise a StackUnderflowError when you send it 'top''
|
44
|
-
|
45
|
-
Finished in 0.000582 seconds
|
46
|
-
|
47
|
-
2 contexts, 3 specifications, 1 failure
|
48
|
-
</pre>
|
49
|
-
|
50
|
-
"uninitialized constant StackUnderflowError" tells us that we need to create a StackUndeflowError. We'll just stick that in the file with the Stack:
|
51
|
-
|
52
|
-
<ruby>
|
53
|
-
class StackUnderflowError < RuntimeError
|
54
|
-
end
|
55
|
-
</ruby>
|
56
|
-
|
57
|
-
and run the spec again.
|
58
|
-
|
59
|
-
<pre>
|
60
|
-
$ spec stack_spec.rb -v
|
61
|
-
|
62
|
-
An empty stack
|
63
|
-
- should keep its mouth shut when you send it 'push'
|
64
|
-
- should raise a StackUnderflowError when you send it 'top' (FAILED - 1)
|
65
|
-
|
66
|
-
A stack with one item
|
67
|
-
- should return top when you send it 'top'
|
68
|
-
|
69
|
-
|
70
|
-
1)
|
71
|
-
ExpectationNotMetError in 'An empty stack should raise a StackUnderflowError when you send it 'top''
|
72
|
-
<Proc> should raise <StackUnderflowError> but raised nothing
|
73
|
-
./stack_spec.rb:14:in `should raise a StackUnderflowError when you send it 'top''
|
74
|
-
|
75
|
-
Finished in 0.000788 seconds
|
76
|
-
|
77
|
-
2 contexts, 3 specifications, 1 failure
|
78
|
-
</pre>
|
79
|
-
|
80
|
-
Now the error report tells us that the expectation was not met - executing the block did not
|
81
|
-
raise the error we specified. Now we can implement code to meet this specification. Sticking
|
82
|
-
with the principle that we want to implement the least amount of code to meet the specification,
|
83
|
-
we enhance our top method:
|
84
|
-
|
85
|
-
<ruby>
|
86
|
-
def top
|
87
|
-
raise StackUnderflowError if @item.nil?
|
88
|
-
@item
|
89
|
-
end
|
90
|
-
</ruby>
|
91
|
-
|
92
|
-
run the specs and they all pass.
|
93
|
-
|
94
|
-
<pre>
|
95
|
-
$ spec stack_spec.rb -v
|
96
|
-
|
97
|
-
An empty stack
|
98
|
-
- should keep its mouth shut when you send it 'push'
|
99
|
-
- should raise a StackUnderflowError when you send it 'top'
|
100
|
-
|
101
|
-
A stack with one item
|
102
|
-
- should return top when you send it 'top'
|
103
|
-
|
104
|
-
|
105
|
-
Finished in 0.000557 seconds
|
106
|
-
|
107
|
-
2 contexts, 3 specifications, 0 failures
|
108
|
-
</pre>
|
109
|
-
|
110
|
-
Do you see how the verbose output is looking more and more like a specification? That's pretty nice, but as your projects grow, you may not want all of that output all of the time. You can, if you wish, run the specs without the <code>-v</code> flag, in which case you get a "." for every passing spec and an "F" for every failing spec. Run them now and you'll see nothing but dots.
|
111
|
-
|
112
|
-
<pre>
|
113
|
-
$ spec stack_spec.rb
|
114
|
-
|
115
|
-
...
|
116
|
-
|
117
|
-
Finished in 0.000458 seconds
|
118
|
-
|
119
|
-
2 contexts, 3 specifications, 0 failures
|
120
|
-
</pre>
|
121
|
-
|
122
|
-
<a href="stack_02.html">Previous</a> |
|
123
|
-
<a href="stack_04.html">Next</a>
|
@@ -1,90 +0,0 @@
|
|
1
|
-
h2. A Simple Stack - Moving specs between contexts - IN PROGRESS - DISREGARD THIS PAGE
|
2
|
-
|
3
|
-
So we now have the following spec.
|
4
|
-
|
5
|
-
<pre>
|
6
|
-
$ spec stack_spec.rb -f s
|
7
|
-
|
8
|
-
A new stack
|
9
|
-
- should be empty
|
10
|
-
|
11
|
-
An empty stack
|
12
|
-
- should keep its mouth shut when you send it 'push'
|
13
|
-
- should not be empty after 'push'
|
14
|
-
|
15
|
-
A stack with one item
|
16
|
-
- should return top when you send it 'top'
|
17
|
-
- should not be empty after 'top'
|
18
|
-
|
19
|
-
Finished in 0.000882 seconds
|
20
|
-
|
21
|
-
3 contexts, 5 specifications, 0 failures
|
22
|
-
</pre>
|
23
|
-
|
24
|
-
One thing that's odd about this is that "An empty stack should not be empty after 'push'". If you think about it, "An empty stack" is no longer empty after sending it 'push'. It's now "A stack with one item". Conveniently, we already have a context that expresses that. So it may make more sense to move that spec to the "one item" context. Remove it from "An empty stack" ...
|
25
|
-
|
26
|
-
<ruby>
|
27
|
-
context "An empty stack" do
|
28
|
-
specify "should not be empty after 'push'" do
|
29
|
-
@stack.push 37
|
30
|
-
@stack.should_not_be_empty
|
31
|
-
end
|
32
|
-
end
|
33
|
-
</ruby>
|
34
|
-
|
35
|
-
... add it to "A stack with one item" ...
|
36
|
-
|
37
|
-
<ruby>
|
38
|
-
context "A stack with one item" do
|
39
|
-
setup do
|
40
|
-
@stack = Stack.new
|
41
|
-
@stack.push "one item"
|
42
|
-
end
|
43
|
-
|
44
|
-
specify "should not be empty after 'push'" do
|
45
|
-
@stack.push 37
|
46
|
-
@stack.should_not_be_empty
|
47
|
-
end
|
48
|
-
|
49
|
-
...
|
50
|
-
end
|
51
|
-
</ruby>
|
52
|
-
|
53
|
-
... and adjust so it works better in this context. We're already pushing "one item", so we don't have to push 37. And we can adjust the name as well:
|
54
|
-
|
55
|
-
<ruby>
|
56
|
-
context "A stack with one item" do
|
57
|
-
setup do
|
58
|
-
@stack = Stack.new
|
59
|
-
@stack.push "one item"
|
60
|
-
end
|
61
|
-
|
62
|
-
specify "should not be empty" do
|
63
|
-
@stack.should_not_be_empty
|
64
|
-
end
|
65
|
-
...
|
66
|
-
end
|
67
|
-
</ruby>
|
68
|
-
|
69
|
-
<pre>
|
70
|
-
$ spec stack_spec.rb -f s
|
71
|
-
|
72
|
-
A new stack
|
73
|
-
- should be empty
|
74
|
-
|
75
|
-
An empty stack
|
76
|
-
- should keep its mouth shut when you send it 'push'
|
77
|
-
|
78
|
-
A stack with one item
|
79
|
-
- should not be empty
|
80
|
-
- should return top when you send it 'top'
|
81
|
-
- should not be empty after 'top'
|
82
|
-
|
83
|
-
Finished in 0.000838 seconds
|
84
|
-
|
85
|
-
3 contexts, 5 specifications, 0 failures
|
86
|
-
</pre>
|
87
|
-
|
88
|
-
So keep your eye out for misplaced specifications like this. Feel free to move things around - carefully, of course. It may seem trivial at this point, but as your spec grows it's going to become more and more important. These specifications are documentation of your system. They must be clear, well organized, and readable.
|
89
|
-
|
90
|
-
<a href="stack_04.html">Previous</a>
|
@@ -1,124 +0,0 @@
|
|
1
|
-
h2. A Simple Stack - Organization and Documentation - IN PROGRESS - DISREGARD THIS PAGE
|
2
|
-
|
3
|
-
h3. Spec organization
|
4
|
-
|
5
|
-
Let's take a look at the spec thus far...
|
6
|
-
|
7
|
-
<ruby>
|
8
|
-
require File.dirname(__FILE__) + "/stack"
|
9
|
-
|
10
|
-
context "An empty stack" do
|
11
|
-
|
12
|
-
setup do
|
13
|
-
@stack = Stack.new
|
14
|
-
end
|
15
|
-
|
16
|
-
specify "should keep its mouth shut when you send it 'push'" do
|
17
|
-
lambda { @stack.push Object.new }.should_not_raise Exception
|
18
|
-
end
|
19
|
-
|
20
|
-
specify "should raise a StackUnderflowError when you send it 'top'" do
|
21
|
-
lambda { @stack.top }.should_raise StackUnderflowError
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
context "A stack with one item" do
|
27
|
-
|
28
|
-
setup do
|
29
|
-
@stack = Stack.new
|
30
|
-
@stack.push "one item"
|
31
|
-
end
|
32
|
-
|
33
|
-
specify "should return top when sent the 'top' message" do
|
34
|
-
@stack.top.should_equal "one item"
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
</ruby>
|
39
|
-
|
40
|
-
..and the result of executing them. First in default mode...
|
41
|
-
|
42
|
-
<pre>
|
43
|
-
$ spec stack_spec.rb
|
44
|
-
|
45
|
-
...
|
46
|
-
|
47
|
-
Finished in 0.000439 seconds
|
48
|
-
|
49
|
-
2 contexts, 3 specifications, 0 failures
|
50
|
-
</pre>
|
51
|
-
|
52
|
-
...and then in verbose mode...
|
53
|
-
|
54
|
-
<pre>
|
55
|
-
$ spec stack_spec.rb -v
|
56
|
-
|
57
|
-
An empty stack
|
58
|
-
- should keep its mouth shut when you send it 'push'
|
59
|
-
- should raise a StackUnderflowError when you send it 'top'
|
60
|
-
|
61
|
-
A stack with one item
|
62
|
-
- should return top when you send it 'top'
|
63
|
-
|
64
|
-
|
65
|
-
Finished in 0.000533 seconds
|
66
|
-
|
67
|
-
2 contexts, 3 specifications, 0 failures
|
68
|
-
</pre>
|
69
|
-
|
70
|
-
We've got two contexts. In both we exercise the 'top' message, but we only exercise 'push' in one. This is a wonderful aspect of organizing the specs this way. By looking at the contexts themselves, or by looking at the generated output, and by having only one setup for each context (a guideline often suggested for xUnit, but violated just as often), we can clearly see the imbalance in what messages we're specifying in the different contexts.
|
71
|
-
|
72
|
-
So now, in addition to using the principle of the simplest thing to help us decide what to specify next, we've also got this feedback that tells us that we have yet to specify how a stack with one item should respond to the 'push' message. Using both tools to guide us, that is an obvious next choice.
|
73
|
-
|
74
|
-
<ruby>
|
75
|
-
context "A stack with one item" do
|
76
|
-
|
77
|
-
setup do
|
78
|
-
@stack = Stack.new
|
79
|
-
@stack.push "one item"
|
80
|
-
end
|
81
|
-
|
82
|
-
specify "should keep its mouth shut when you send it 'push'" do
|
83
|
-
lambda { @stack.push Object.new }.should_not_raise Exception
|
84
|
-
end
|
85
|
-
|
86
|
-
specify "should return top when you send it 'top'" do
|
87
|
-
@stack.top.should_equal "one item"
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
</ruby>
|
92
|
-
|
93
|
-
To add that, I actually copied the spec from the "new stack" context. Cut and paste? Blasphemy! Exact duplication? More blasphemy! Well, it is blasphemy if you think of these structures as tests, or even as code. Yes, they are executable. Yes, they are code - sort of. But they also serve other very important purpose - they are documentation.
|
94
|
-
|
95
|
-
h3. Specs as documentation
|
96
|
-
|
97
|
-
The whole structure of contexts and specifications was deliberately chosen to feel less like the tests that we're all used to seeing in xUnit frameworks so that we wouldn't think of specs in the same way as we do tests. So while we might think of them as executable, we don't want to think of them as code.
|
98
|
-
|
99
|
-
We talk about tests as documentation in TDD as well. But I can tell you that when I've tried to read them as such and found myself searching through hierarchies to find the setup for a test that was failing, my eyes have just glazed over and I've ended up looking directly at the code. Serving as documentation requires of these executable specifications that they be simple, clear and easy to understand. All the context you need to understand the test should be in one place.
|
100
|
-
|
101
|
-
Also, the perception that "all duplication is evil" is based on industry-wide experience in which changes that needed to happen to duplicated code didn't happen everywhere it should have. In the case of specifications, that doesn't really fly because each specification is autonomous. If the rules change for a message in a given context, then you'd only want to make the change in that context.
|
102
|
-
|
103
|
-
So we've now got 4 specifications, 2 each in 2 contexts. Run the specs...
|
104
|
-
|
105
|
-
<pre>$ spec stack_spec.rb -v
|
106
|
-
|
107
|
-
An empty stack
|
108
|
-
- should keep its mouth shut when you send it 'push'
|
109
|
-
- should raise a StackUnderflowError when you send it 'top'
|
110
|
-
|
111
|
-
A stack with one item
|
112
|
-
- should keep its mouth shut when you send it 'push'
|
113
|
-
- should return top when you send it 'top'
|
114
|
-
|
115
|
-
|
116
|
-
Finished in 0.000657 seconds
|
117
|
-
|
118
|
-
2 contexts, 4 specifications, 0 failures
|
119
|
-
</pre>
|
120
|
-
|
121
|
-
...and there are no failures. So in this case, since 'push' results in the same behavior for an empty stack and a one-item stack, we don't have anything additional to implement.
|
122
|
-
|
123
|
-
<a href="stack_03.html">Previous</a> |
|
124
|
-
<a href="stack_05.html">Next</a>
|