rspec 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/CHANGES +57 -32
  2. data/EXAMPLES.rd +0 -0
  3. data/Rakefile +22 -21
  4. data/bin/spec +9 -11
  5. data/doc/README +1 -3
  6. data/doc/plugin/syntax.rb +27 -5
  7. data/doc/src/core_team.page +22 -0
  8. data/doc/src/default.css +11 -11
  9. data/doc/src/default.template +0 -1
  10. data/doc/src/documentation/index.page +183 -8
  11. data/doc/src/documentation/meta.info +7 -7
  12. data/doc/src/documentation/mocks.page +168 -109
  13. data/doc/src/documentation/underscores.page +20 -0
  14. data/doc/src/examples.page +2 -1
  15. data/doc/src/images/David_and_Aslak.jpg +0 -0
  16. data/doc/src/images/Whats_That_Dude.jpg +0 -0
  17. data/doc/src/index.page +70 -3
  18. data/doc/src/meta.info +18 -11
  19. data/doc/src/tools/index.page +40 -134
  20. data/doc/src/tools/meta.info +9 -3
  21. data/doc/src/tools/rails.page +3 -1
  22. data/doc/src/tools/rake.page +20 -3
  23. data/doc/src/tools/rcov.page +19 -0
  24. data/doc/src/tools/spec.page +99 -0
  25. data/doc/src/tools/test2rspec.page +2 -4
  26. data/doc/src/tutorials/index.page +52 -0
  27. data/doc/src/tutorials/meta.info +31 -0
  28. data/doc/src/tutorials/notes.txt +252 -0
  29. data/doc/src/tutorials/stack.rb +11 -0
  30. data/doc/src/tutorials/stack_01.page +224 -0
  31. data/doc/src/tutorials/stack_02.page +180 -0
  32. data/doc/src/tutorials/stack_03.page +291 -0
  33. data/doc/src/tutorials/stack_04.page +203 -0
  34. data/doc/src/tutorials/stack_04.page.orig +123 -0
  35. data/doc/src/tutorials/stack_05.page +90 -0
  36. data/doc/src/tutorials/stack_05.page.orig +124 -0
  37. data/doc/src/tutorials/stack_06.page +359 -0
  38. data/doc/src/tutorials/stack_06.page.orig +359 -0
  39. data/doc/src/tutorials/stack_spec.rb +41 -0
  40. data/examples/airport_spec.rb +4 -4
  41. data/examples/{spec_framework_spec.rb → bdd_framework_spec.rb} +6 -7
  42. data/examples/mocking_spec.rb +0 -5
  43. data/examples/stack_spec.rb +6 -7
  44. data/examples/sugar_spec.rb +14 -0
  45. data/lib/spec/api.rb +5 -2
  46. data/lib/spec/api/helper/should_base.rb +17 -22
  47. data/lib/spec/api/helper/should_helper.rb +4 -3
  48. data/lib/spec/api/helper/should_negator.rb +3 -2
  49. data/lib/spec/api/mocks/argument_expectation.rb +104 -0
  50. data/lib/spec/api/{mock.rb → mocks/message_expectation.rb} +47 -96
  51. data/lib/spec/api/mocks/mock.rb +63 -0
  52. data/lib/spec/api/mocks/order_group.rb +21 -0
  53. data/lib/spec/api/sugar.rb +47 -0
  54. data/lib/spec/rake/rcov_verify.rb +45 -0
  55. data/lib/spec/rake/spectask.rb +41 -56
  56. data/lib/spec/runner.rb +4 -1
  57. data/lib/spec/runner/backtrace_tweaker.rb +24 -3
  58. data/lib/spec/runner/base_text_formatter.rb +28 -0
  59. data/lib/spec/runner/context.rb +21 -18
  60. data/lib/spec/runner/context_runner.rb +20 -31
  61. data/lib/spec/runner/execution_context.rb +3 -3
  62. data/lib/spec/runner/kernel_ext.rb +10 -1
  63. data/lib/spec/runner/option_parser.rb +32 -14
  64. data/lib/spec/runner/progress_bar_formatter.rb +21 -0
  65. data/lib/spec/runner/rdoc_formatter.rb +15 -5
  66. data/lib/spec/runner/reporter.rb +100 -0
  67. data/lib/spec/runner/specdoc_formatter.rb +20 -0
  68. data/lib/spec/runner/specification.rb +42 -22
  69. data/lib/spec/version.rb +1 -1
  70. data/test/rcov/rcov_testtask.rb +1 -0
  71. data/test/spec/api/duck_type_test.rb +4 -4
  72. data/test/spec/api/helper/raising_test.rb +37 -17
  73. data/test/spec/api/{mock_arg_constraints_test.rb → mocks/mock_arg_constraints_test.rb} +10 -4
  74. data/test/spec/api/mocks/mock_ordering_test.rb +62 -0
  75. data/test/spec/api/{mock_test.rb → mocks/mock_test.rb} +30 -7
  76. data/test/spec/api/mocks/null_object_test.rb +31 -0
  77. data/test/spec/api/sugar_test.rb +71 -0
  78. data/test/spec/runner/backtrace_tweaker_test.rb +52 -4
  79. data/test/spec/runner/context_runner_test.rb +41 -21
  80. data/test/spec/runner/context_test.rb +60 -32
  81. data/test/spec/runner/execution_context_test.rb +4 -3
  82. data/test/spec/runner/failure_dump_test.rb +92 -0
  83. data/test/spec/runner/kernel_ext_test.rb +1 -2
  84. data/test/spec/runner/option_parser_test.rb +48 -28
  85. data/test/spec/runner/progress_bar_formatter_test.rb +48 -0
  86. data/test/spec/runner/rdoc_formatter_test.rb +31 -4
  87. data/test/spec/runner/reporter_test.rb +103 -0
  88. data/test/spec/runner/specdoc_formatter_test.rb +50 -0
  89. data/test/spec/runner/specification_test.rb +49 -11
  90. data/test/test_helper.rb +1 -4
  91. metadata +46 -15
  92. data/doc/src/community.page +0 -7
  93. data/doc/src/documentation/api.page +0 -185
  94. data/doc/src/why_rspec.page +0 -7
  95. data/examples/empty_stack_spec.rb +0 -22
  96. data/examples/team_spec.rb +0 -30
  97. data/lib/spec/api/duck_type.rb +0 -16
  98. data/lib/spec/runner/simple_text_reporter.rb +0 -88
  99. data/test/rcov/rcov_verify.rb +0 -28
  100. data/test/spec/runner/simple_text_reporter_test.rb +0 -123
@@ -0,0 +1,203 @@
1
+ h2. A Simple Stack - when a new expectation passes
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 keep its mouth shut when you send it 'push'" do
24
+ lambda { @stack.push Object.new }.should.not.raise
25
+ end
26
+
27
+ specify "should not be empty after 'push'" do
28
+ @stack.push 37
29
+ @stack.should_not_be_empty
30
+ end
31
+ end
32
+
33
+ context "A stack with one item" do
34
+ setup do
35
+ @stack = Stack.new
36
+ @stack.push "one item"
37
+ end
38
+
39
+ specify "should return top when you send it 'top'" do
40
+ @stack.top.should_equal "one item"
41
+ end
42
+ end
43
+ </ruby>
44
+
45
+ stack.rb should look like this...
46
+
47
+ <ruby>
48
+ class Stack
49
+ def empty?
50
+ @item.nil?
51
+ end
52
+ def push item
53
+ @item = item
54
+ end
55
+ def top
56
+ @item
57
+ end
58
+ end
59
+ </ruby>
60
+
61
+ ...and the output should look like this:
62
+
63
+ <pre>
64
+ $ spec stack_spec.rb -f s
65
+
66
+ A new stack
67
+ - should be empty
68
+
69
+ An empty stack
70
+ - should keep its mouth shut when you send it 'push'
71
+ - should not be empty after 'push'
72
+
73
+ A stack with one item
74
+ - should return top when you send it 'top'
75
+
76
+ Finished in 0.000741 seconds
77
+
78
+ 3 contexts, 4 specifications, 0 failures
79
+ </pre>
80
+
81
+ Again, a really nice feature of using the <code>--format specdoc</code> option (<code>-f s</code> for short) is that you can easily see all of the contexts you've specified and the balance of specifications between contexts. As your specification is evolving, this helps to inform you regarding the next step. Comparing "An empty stack" to "A stack with one item", there are a couple of ways to go here, which is nice (better than having no obvious next step). On "An empty stack", we know two things about the 'push' message. Let's balance "A stack with one item" with that, and specify the 'emptiness' of the stack after 'top'.
82
+
83
+ <ruby>
84
+ context "A stack with one item" do
85
+ setup do
86
+ @stack = Stack.new
87
+ @stack.push "one item"
88
+ end
89
+
90
+ ...
91
+
92
+ specify "should not be empty after 'top'" do
93
+ @stack.top
94
+ @stack.should_not_be_empty
95
+ end
96
+ end
97
+ </ruby>
98
+ <br>
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 keep its mouth shut when you send it 'push'
107
+ - should not be empty after 'push'
108
+
109
+ A stack with one item
110
+ - should return top when you send it 'top'
111
+ - should not be empty after 'top'
112
+
113
+ Finished in 0.000853 seconds
114
+
115
+ 3 contexts, 5 specifications, 0 failures
116
+ </pre>
117
+
118
+ This one passes right away. This situation comes up a lot as you progress through a specification. You add a specification and the expectations are already met. You never saw the failure, so how do you know that you wrote the specification correctly, or that it exercises the code that you want to exercise? We should see the expectation fail before moving on. So now the question is what is the best approach to making it fail? Well, we want to see the failure so that when we make a change to the code to make it pass, we know that we've exercised the right place in the code from the spec. To ensure that, we really want to make the change in the code.
119
+
120
+ In this case, the simplest way to approach this is to return <code>true</code> from <code>empty?</code>.
121
+
122
+ <ruby>
123
+ class Stack
124
+ def empty?
125
+ true
126
+ #@item.nil?
127
+ end
128
+ def push item
129
+ @item = item
130
+ end
131
+ def top
132
+ @item
133
+ end
134
+ end
135
+ </ruby>
136
+ <br>
137
+ <pre>
138
+ $ spec stack_spec.rb -f s -s "A stack with one item should not be empty after 'top'"
139
+
140
+ A stack with one item
141
+ - should not be empty after 'top' (FAILED - 1)
142
+
143
+ 1)
144
+ ExpectationNotMetError in 'A stack with one item should not be empty after 'top''
145
+ Stack #<Stack:0x36ad18 @item="one item"> should not be empty
146
+ ./stack_spec.rb:39:in `should not be empty after 'top''
147
+
148
+ Finished in 0.000398 seconds
149
+
150
+ 1 context, 1 specification, 1 failure
151
+ </pre>
152
+
153
+ Here we used the <code>-s</code> option, which allows you to specify a single specification by supplying its full name (context name + space + spec name).
154
+
155
+ The failure tells us that there was an ExpectationNotMetError, as we expected. Revert the code ...
156
+
157
+ <ruby>
158
+ class Stack
159
+ def empty?
160
+ @item.nil?
161
+ end
162
+ ...
163
+ end
164
+ </ruby>
165
+
166
+ ... run the single spec ...
167
+
168
+ <pre>
169
+ $ spec stack_spec.rb -f s -s "A stack with one item should not be empty after 'top'"
170
+
171
+ A stack with one item
172
+ - should not be empty after 'top'
173
+
174
+ Finished in 0.00028 seconds
175
+
176
+ 1 context, 1 specification, 0 failures
177
+ </pre>
178
+
179
+ ... and then run all the specs ...
180
+
181
+ <pre>
182
+ $ spec stack_spec.rb -f s
183
+
184
+ A new stack
185
+ - should be empty
186
+
187
+ An empty stack
188
+ - should keep its mouth shut when you send it 'push'
189
+ - should not be empty after 'push'
190
+
191
+ A stack with one item
192
+ - should return top when you send it 'top'
193
+ - should not be empty after 'top'
194
+
195
+ Finished in 0.000859 seconds
196
+
197
+ 3 contexts, 5 specifications, 0 failures
198
+ </pre>
199
+
200
+ ... and we can press on with confidence that the last spec we added is really exercising and setting expectations on the code we want it to.
201
+
202
+ <a href="stack_03.html">Previous</a> |
203
+ <a href="stack_05.html">Next</a>
@@ -0,0 +1,123 @@
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>
@@ -0,0 +1,90 @@
1
+ h2. A Simple Stack - Moving specs between contexts
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
+ <br>
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>
@@ -0,0 +1,124 @@
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>