rspec 0.5.11 → 0.5.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/CHANGES +12 -0
  2. data/README +4 -2
  3. data/Rakefile +14 -4
  4. data/bin/spec +7 -7
  5. data/bin/test2spec +13 -8
  6. data/lib/spec/api/helper/diff.rb +53 -0
  7. data/lib/spec/api/helper/instance_helper.rb +11 -11
  8. data/lib/spec/api/helper/instance_negator.rb +11 -11
  9. data/lib/spec/api/helper/kind_helper.rb +11 -11
  10. data/lib/spec/api/helper/kind_negator.rb +11 -11
  11. data/lib/spec/api/helper/respond_helper.rb +11 -11
  12. data/lib/spec/api/helper/respond_negator.rb +11 -11
  13. data/lib/spec/api/helper/should_base.rb +6 -6
  14. data/lib/spec/api/helper/should_helper.rb +35 -35
  15. data/lib/spec/api/helper/should_negator.rb +20 -20
  16. data/lib/spec/rake/spectask.rb +15 -6
  17. data/lib/spec/runner.rb +1 -0
  18. data/lib/spec/runner/backtrace_tweaker.rb +2 -0
  19. data/lib/spec/runner/base_text_formatter.rb +3 -1
  20. data/lib/spec/runner/html_formatter.rb +153 -0
  21. data/lib/spec/runner/option_parser.rb +9 -2
  22. data/lib/spec/runner/progress_bar_formatter.rb +4 -0
  23. data/lib/spec/runner/rdoc_formatter.rb +3 -0
  24. data/lib/spec/runner/reporter.rb +5 -5
  25. data/lib/spec/runner/specdoc_formatter.rb +3 -0
  26. data/lib/spec/test_to_spec/sexp_transformer.rb +1 -0
  27. data/lib/spec/test_to_spec/translation_test_runner.rb +10 -2
  28. data/lib/spec/version.rb +1 -1
  29. data/test/spec/api/helper/arbitrary_predicate_test.rb +49 -73
  30. data/test/spec/api/helper/diff_test.rb +60 -0
  31. data/test/spec/api/helper/equality_test.rb +14 -0
  32. data/test/spec/api/helper/should_have_test.rb +0 -29
  33. data/test/spec/api/helper/typing_test.rb +87 -87
  34. data/test/spec/api/sugar_test.rb +0 -6
  35. data/test/spec/runner/backtrace_tweaker_test.rb +8 -2
  36. data/test/spec/runner/html_formatter_test.rb +47 -0
  37. data/test/spec/runner/option_parser_test.rb +0 -5
  38. data/test/test_classes.rb +73 -0
  39. data/test/test_helper.rb +3 -0
  40. metadata +8 -49
  41. data/doc/README +0 -3
  42. data/doc/config.yaml +0 -2
  43. data/doc/plugin/syntax.rb +0 -60
  44. data/doc/plugin/version.rb +0 -19
  45. data/doc/src/core_team.page +0 -31
  46. data/doc/src/default.css +0 -199
  47. data/doc/src/default.template +0 -31
  48. data/doc/src/documentation/index.page +0 -188
  49. data/doc/src/documentation/meta.info +0 -22
  50. data/doc/src/documentation/mocks.page +0 -287
  51. data/doc/src/documentation/underscores.page +0 -21
  52. data/doc/src/examples.page +0 -9
  53. data/doc/src/images/David_and_Aslak.jpg +0 -0
  54. data/doc/src/images/Whats_That_Dude.jpg +0 -0
  55. data/doc/src/images/ducks1.png +0 -0
  56. data/doc/src/images/ul.gif +0 -0
  57. data/doc/src/index.page +0 -74
  58. data/doc/src/meta.info +0 -33
  59. data/doc/src/tools/index.page +0 -49
  60. data/doc/src/tools/meta.info +0 -18
  61. data/doc/src/tools/rails.page +0 -132
  62. data/doc/src/tools/rake.page +0 -21
  63. data/doc/src/tools/rcov.page +0 -28
  64. data/doc/src/tools/spec.page +0 -129
  65. data/doc/src/tools/test2spec.page +0 -103
  66. data/doc/src/tutorials/index.page +0 -52
  67. data/doc/src/tutorials/meta.info +0 -36
  68. data/doc/src/tutorials/notes.txt +0 -263
  69. data/doc/src/tutorials/stack.rb +0 -11
  70. data/doc/src/tutorials/stack_01.page +0 -226
  71. data/doc/src/tutorials/stack_02.page +0 -182
  72. data/doc/src/tutorials/stack_03.page +0 -283
  73. data/doc/src/tutorials/stack_04.page +0 -164
  74. data/doc/src/tutorials/stack_04.page.orig +0 -123
  75. data/doc/src/tutorials/stack_05.page +0 -90
  76. data/doc/src/tutorials/stack_05.page.orig +0 -124
  77. data/doc/src/tutorials/stack_06.page +0 -359
  78. data/doc/src/tutorials/stack_06.page.orig +0 -359
  79. data/doc/src/tutorials/stack_spec.rb +0 -25
  80. 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>