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
data/doc/src/meta.info
CHANGED
@@ -1,26 +1,33 @@
|
|
1
1
|
index.page:
|
2
2
|
orderInfo: 1
|
3
|
-
|
4
|
-
why_rspec.page:
|
5
|
-
orderInfo: 2
|
6
3
|
|
7
4
|
examples.page:
|
8
|
-
orderInfo:
|
9
|
-
|
5
|
+
orderInfo: 2
|
6
|
+
|
7
|
+
tutorials:
|
8
|
+
title: Tutorial
|
9
|
+
orderInfo: 5
|
10
|
+
|
10
11
|
documentation:
|
11
12
|
title: Documentation
|
12
|
-
orderInfo:
|
13
|
+
orderInfo: 6
|
13
14
|
|
14
15
|
download.html:
|
15
16
|
title: Download
|
16
17
|
inMenu: true
|
17
18
|
dest: http://rubyforge.org/frs/?group_id=797
|
18
|
-
orderInfo:
|
19
|
+
orderInfo: 7
|
19
20
|
|
20
21
|
tools:
|
21
22
|
title: Tools
|
22
|
-
orderInfo:
|
23
|
-
|
24
|
-
|
25
|
-
orderInfo:
|
23
|
+
orderInfo: 8
|
24
|
+
|
25
|
+
core_team.page:
|
26
|
+
orderInfo: 9
|
26
27
|
|
28
|
+
community.html:
|
29
|
+
title: Community
|
30
|
+
inMenu: true
|
31
|
+
dest: http://rubyforge.org/projects/rspec
|
32
|
+
orderInfo: 10
|
33
|
+
|
data/doc/src/tools/index.page
CHANGED
@@ -1,143 +1,49 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Seven tools in one
|
3
3
|
inMenu: true
|
4
4
|
---
|
5
|
-
h2. Processing Specifications
|
6
5
|
|
7
|
-
|
6
|
+
h2. Seven tools in one
|
8
7
|
|
9
|
-
|
10
|
-
<code>
|
11
|
-
spec [options] (FILE|DIRECTORY)+
|
12
|
-
</code>
|
13
|
-
</pre>
|
8
|
+
RSpec combines several tools in one...
|
14
9
|
|
15
|
-
|
16
|
-
that are found are loaded. Running spec on the previous example results in:
|
10
|
+
h3. 1) A language for expressing behavior
|
17
11
|
|
18
|
-
|
19
|
-
<code>
|
20
|
-
..................
|
12
|
+
RSpec provides programmers with a domain specific language for defining expected behavior of Ruby code.
|
21
13
|
|
22
|
-
|
14
|
+
h3. 2) A runner for verifying behavior
|
23
15
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
A stack with one item
|
60
|
-
- should accept an item when sent push
|
61
|
-
- should return top when sent top
|
62
|
-
- should not remove top when sent top
|
63
|
-
- should return top when sent pop
|
64
|
-
- should remove top when sent pop
|
65
|
-
|
66
|
-
An almost full stack (with one item less than capacity)
|
67
|
-
- should accept an item when sent push
|
68
|
-
- should return top when sent top
|
69
|
-
- should not remove top when sent top
|
70
|
-
- should return top when sent pop
|
71
|
-
- should remove top when sent pop
|
72
|
-
|
73
|
-
A full stack
|
74
|
-
- should complain on push
|
75
|
-
- should return top when sent top
|
76
|
-
- should not remove top when sent top
|
77
|
-
- should return top when sent pop
|
78
|
-
- should remove top when sent pop
|
79
|
-
|
80
|
-
Finished in 0.013635 seconds
|
81
|
-
|
82
|
-
4 contexts, 18 specifications, 0 failures
|
83
|
-
</code>
|
84
|
-
</pre>
|
85
|
-
|
86
|
-
Similar, here is a failing specification when the verbose opton is used:
|
87
|
-
|
88
|
-
<pre>
|
89
|
-
<code>
|
90
|
-
Spec framework
|
91
|
-
- should be adopted quickly (FAILED - 1)
|
92
|
-
- should be intuitive
|
93
|
-
|
94
|
-
|
95
|
-
1)
|
96
|
-
SpecFramework #<SpecFramework:0x3d7238> should be adopted_quickly (Spec::Api::ExpectationNotMetError)
|
97
|
-
Context: Spec framework [./examples/spec_framework_spec.rb:13]
|
98
|
-
Specification: should be adopted quickly [./examples/spec_framework_spec.rb:19]
|
99
|
-
./examples/spec_framework_spec.rb:21:in `should be adopted quickly'
|
100
|
-
|
101
|
-
Finished in 0.002726 seconds
|
102
|
-
|
103
|
-
1 context, 2 specifications, 1 failure
|
104
|
-
</code>
|
105
|
-
</pre>
|
106
|
-
|
107
|
-
The spec command does double duty as documentation generation from a set of
|
108
|
-
specifications as well as running them against your code.
|
109
|
-
|
110
|
-
h3.-d, --doc
|
111
|
-
|
112
|
-
Process the specifications in documentation generation mode. This will produce
|
113
|
-
an rdoc input file. For example here is the result of running spec -d on the
|
114
|
-
previous example:
|
115
|
-
|
116
|
-
<pre>
|
117
|
-
<code>
|
118
|
-
# An empty stack
|
119
|
-
# * should accept an item when sent push
|
120
|
-
# * should complain when sent top
|
121
|
-
# * should complain when sent pop
|
122
|
-
# A stack with one item
|
123
|
-
# * should accept an item when sent push
|
124
|
-
# * should return top when sent top
|
125
|
-
# * should not remove top when sent top
|
126
|
-
# * should return top when sent pop
|
127
|
-
# * should remove top when sent pop
|
128
|
-
# An almost full stack (with one item less than capacity)
|
129
|
-
# * should accept an item when sent push
|
130
|
-
# * should return top when sent top
|
131
|
-
# * should not remove top when sent top
|
132
|
-
# * should return top when sent pop
|
133
|
-
# * should remove top when sent pop
|
134
|
-
# A full stack
|
135
|
-
# * should complain on push
|
136
|
-
# * should return top when sent top
|
137
|
-
# * should not remove top when sent top
|
138
|
-
# * should return top when sent pop
|
139
|
-
# * should remove top when sent pop
|
140
|
-
</code>
|
141
|
-
</pre>
|
142
|
-
|
143
|
-
Rdoc renders this as "this":rdoc-output/index.html.
|
16
|
+
RSpec provides a command line utility for executing behavior specifications.
|
17
|
+
|
18
|
+
h3. 3) Mock objects
|
19
|
+
|
20
|
+
Mock objects frameworks usually come as separate add-ons to existing XUnit frameworks. In RSpec it's an integrated
|
21
|
+
part of the framework.
|
22
|
+
|
23
|
+
h3. 4) Testdox-like reports
|
24
|
+
|
25
|
+
Expressing behavior in real sentences improves communication between programmer,
|
26
|
+
analysts and testers. It also helps programmers keep a more critical mind about the code being developed.
|
27
|
+
|
28
|
+
RSpec's built in support for generating "testdox-like":http://agiledox.sourceforge.net/ reports makes the code's behavior more transparent
|
29
|
+
to everybody (assuming you publish it to a webpage where everybody who needs to can see it).
|
30
|
+
|
31
|
+
h3. 5) Coverage tool
|
32
|
+
|
33
|
+
While coverage tools cannot prove that you have verified everything there is to verify about your code,
|
34
|
+
they can prove when you have not verified everything there is to verify about your code. RCov is such a
|
35
|
+
coverage tool, and RSpec supportws it out-of the box via its Rake task.
|
36
|
+
|
37
|
+
h3. 6) Coverage threshold verification
|
38
|
+
|
39
|
+
Except for the times when programmers agree to keep a close eye on coverage and keep it at, say 90%, it
|
40
|
+
will inevitably drop when they get other things to think about and start to write code in the wild.
|
41
|
+
|
42
|
+
RSpec ships with a special Rake task that can verify that the coverage remains on a level defined by the
|
43
|
+
development team. Should the coverage drop, the build will fail, and developers are encouraged to address
|
44
|
+
it right away.
|
45
|
+
|
46
|
+
h3. 7)
|
47
|
+
|
48
|
+
Did you invest a lot
|
49
|
+
tool, which will do most
|
data/doc/src/tools/meta.info
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
index.page:
|
2
2
|
orderInfo: 10
|
3
3
|
|
4
|
-
|
4
|
+
spec.page:
|
5
5
|
orderInfo: 11
|
6
6
|
|
7
7
|
rake.page:
|
8
8
|
orderInfo: 12
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
rcov.page:
|
11
11
|
orderInfo: 13
|
12
12
|
|
13
|
+
test2rspec.page:
|
14
|
+
orderInfo: 14
|
15
|
+
|
16
|
+
rails.page:
|
17
|
+
orderInfo: 15
|
18
|
+
|
data/doc/src/tools/rails.page
CHANGED
data/doc/src/tools/rake.page
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
---
|
2
|
-
title: Rake
|
2
|
+
title: Rake Task
|
3
3
|
inMenu: true
|
4
4
|
---
|
5
|
-
h2. Rake
|
5
|
+
h2. Rake Task
|
6
6
|
|
7
|
-
|
7
|
+
RSpec's Rake task allows you to do many things.
|
8
|
+
(See the <notextile><a href="../rdoc/classes/Spec/Rake/SpecTask.html">RDoc</a></notextile> for details)
|
9
|
+
|
10
|
+
h3. Run specs
|
11
|
+
|
12
|
+
<ruby file="../test/tasks/examples.rake"/>
|
13
|
+
|
14
|
+
h3. Run specs with RCov
|
15
|
+
|
16
|
+
<ruby file="../test/tasks/examples_with_rcov.rake"/>
|
17
|
+
|
18
|
+
This will generate a coverage report like <notextile><a href="../coverage/index.html">this</a></notextile>.
|
19
|
+
|
20
|
+
h3. Generate specdocs
|
21
|
+
|
22
|
+
<ruby file="../test/tasks/examples_specdoc.rake"/>
|
23
|
+
|
24
|
+
This will output the specdocs to a file, which can be included in your RDoc. Just like <notextile><a href="../rdoc/files/EXAMPLES_rd.html">this</a></notextile>.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
title: RCov
|
3
|
+
inMenu: true
|
4
|
+
---
|
5
|
+
h2. RCov
|
6
|
+
|
7
|
+
RSpec has tight integration with <a href="http://eigenclass.org/hiki.rb?rcov=">RCov</a>. If you have RCov installed you can
|
8
|
+
use the rake task to generate a coverage report. See the <a href="../rake.html">Rake</a> for details.
|
9
|
+
|
10
|
+
h3. Coverage threshold
|
11
|
+
|
12
|
+
You can guard your codebase's coverage from dropping by adding the
|
13
|
+
<notextile><a href="../rdoc/classes/RCov/VerifyTask.html">RCov::VerifyTask</a></notextile>
|
14
|
+
task to your Rakefile. Example:
|
15
|
+
|
16
|
+
<ruby file="../test/tasks/rcov_verify.rake"/>
|
17
|
+
|
18
|
+
This will give you a :rcov_verify task that will fail your build if the
|
19
|
+
coverage drops below the threshold you define (the higher the better).
|
@@ -0,0 +1,99 @@
|
|
1
|
+
---
|
2
|
+
title: Spec Runner
|
3
|
+
inMenu: true
|
4
|
+
---
|
5
|
+
|
6
|
+
h2. Executing specs directly
|
7
|
+
|
8
|
+
Every RSpec context can be run directly from the command line:
|
9
|
+
|
10
|
+
<pre>
|
11
|
+
ruby path/to/my_spec.rb [options]
|
12
|
+
</pre>
|
13
|
+
|
14
|
+
This will print the results to STDOUT. Use the --help option for more details. This is
|
15
|
+
practical when you only want to run one context. If you want to run more, use the spec tool
|
16
|
+
or the Rake task. It should also be noted that the exitcode will always be 0 when run in standalone mode.
|
17
|
+
|
18
|
+
h2. The spec command line
|
19
|
+
|
20
|
+
After you install RSpec, you should have the spec command line tool on your PATH.
|
21
|
+
This tool can be used to process several RSpec contexts in one go.
|
22
|
+
|
23
|
+
spec will exit with the exitcode 1 if one or more specs fail.
|
24
|
+
|
25
|
+
The general form of the command is
|
26
|
+
|
27
|
+
<pre>
|
28
|
+
spec [options] (FILE|DIRECTORY)+
|
29
|
+
</pre>
|
30
|
+
|
31
|
+
Any number of files and/or directories can be provided, all ruby source files
|
32
|
+
that are found are loaded. Running spec on the previous example results in:
|
33
|
+
|
34
|
+
<pre>
|
35
|
+
bin/spec
|
36
|
+
{execute: ../bin/spec ../examples}
|
37
|
+
</pre>
|
38
|
+
|
39
|
+
Very simple and to the point. Passing specifications are indicated by a '.',
|
40
|
+
failing ones by a 'F'. Note that failure indicates a violated expectation as
|
41
|
+
well as an unexpected exception being raised. Here's an example with a failing specification:
|
42
|
+
|
43
|
+
<pre>
|
44
|
+
bin/spec failing_examples/stack_spec.rb
|
45
|
+
{execute: ../bin/spec ../failing_examples/stack_spec.rb}
|
46
|
+
</pre>
|
47
|
+
|
48
|
+
In this case, the context is named "An almost full stack (with one item less than capacity)"
|
49
|
+
and the specification is named "should return top when sent pop". These two are concatenated
|
50
|
+
on the first line of the backtrace.
|
51
|
+
|
52
|
+
h2. Command line options
|
53
|
+
|
54
|
+
Additional command line options can be passed to customize the output and behaviour of RSpec.
|
55
|
+
The following options apply whether specs are run in standalone mode (by executing the .rb files directly),
|
56
|
+
or using the spec command.
|
57
|
+
|
58
|
+
h3. -v, --verbose
|
59
|
+
|
60
|
+
Using this option tells the formatter (which by default is specdoc) to produce more verbose output:
|
61
|
+
|
62
|
+
<pre>
|
63
|
+
$ bin/spec failing_examples/team_spec.rb -v
|
64
|
+
|
65
|
+
{execute: ../bin/spec ../failing_examples/team_spec.rb -v}
|
66
|
+
</pre>
|
67
|
+
|
68
|
+
The spec command does double duty as documentation generation from a set of
|
69
|
+
specifications as well as running them against your code.
|
70
|
+
|
71
|
+
h3. -f, --format [specdoc|rdoc]
|
72
|
+
|
73
|
+
Specify the output format. Most formats will produce some form of "testdox":http://agiledox.sourceforge.net/
|
74
|
+
output. The --verbose and --dry-run options may also affect the output format.
|
75
|
+
|
76
|
+
For example, by setting the formatter to rdoc, we can output the kind of input that RDoc
|
77
|
+
needs to produce something like "this":../rdoc/files/EXAMPLES_rd.html
|
78
|
+
<pre>
|
79
|
+
$ bin/spec failing_examples/team_spec.rb -f rdoc
|
80
|
+
|
81
|
+
{execute: ../bin/spec ../failing_examples/team_spec.rb -f rdoc}
|
82
|
+
</pre>
|
83
|
+
|
84
|
+
h3. -d, --dry-run
|
85
|
+
|
86
|
+
This option tells RSpec not to execute the specs, but they are still being parsed.
|
87
|
+
This can be useful when generating "testdox":http://agiledox.sourceforge.net/ documents
|
88
|
+
|
89
|
+
h3. -b, --backtrace
|
90
|
+
|
91
|
+
In order to make it easier to identify causes of failing specifications, RSpec will filter out
|
92
|
+
the parts of the backtrace that come from RSpec itself by default. If you wish to see them,
|
93
|
+
you can use -b or --backtrace:
|
94
|
+
|
95
|
+
<pre>
|
96
|
+
$ bin/spec failing_examples/team_spec.rb -b
|
97
|
+
|
98
|
+
{execute: ../bin/spec ../failing_examples/team_spec.rb -b}
|
99
|
+
</pre>
|
@@ -4,12 +4,10 @@ inMenu: true
|
|
4
4
|
---
|
5
5
|
h2. Test::Unit migration
|
6
6
|
|
7
|
-
rSpec provides a tool for
|
7
|
+
rSpec provides a tool for translating existing Test::Unit files into specifications. Anything that cannot be converted is left in its original form. The command line is:
|
8
8
|
|
9
9
|
<pre>
|
10
|
-
<code>
|
11
10
|
test2rspec SRC [DEST]
|
12
|
-
</code>
|
13
11
|
</pre>
|
14
12
|
|
15
|
-
If DEST is not supplied, output is sent to STDOUT.
|
13
|
+
If DEST is not supplied, output is sent to STDOUT. SRC and DEST can be a file or a directory. If SRC is a directory, every test file under it will be translated.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
title: Overview
|
3
|
+
---
|
4
|
+
h2. A Simple Stack - Overview
|
5
|
+
|
6
|
+
h3. A simple (very much in progress) tutorial by David Chelimsky
|
7
|
+
|
8
|
+
In this tutorial, we're going to explore Behaviour Driven Development using rSpec. A primary goal of BDD is to think about specifications rather than testing. We'll explore what that means, and how it affects the process of specifying components in a system. For example, one of the examples I've used in TDD classes is test-driving a Stack. It would usually start with a test like this:
|
9
|
+
|
10
|
+
<ruby>
|
11
|
+
#NOT A BDD EXAMPLE
|
12
|
+
def test_new_stack_should_be_empty
|
13
|
+
stack = Stack.new
|
14
|
+
assert_equal(0, stack.size)
|
15
|
+
end
|
16
|
+
</ruby>
|
17
|
+
|
18
|
+
We start with that because it is a VERY simple place to start. To get that test to pass, you need very little code...
|
19
|
+
|
20
|
+
<ruby>
|
21
|
+
class Stack
|
22
|
+
def size
|
23
|
+
0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
</ruby>
|
27
|
+
|
28
|
+
...and you're off and running. So here's a question: what is the <em><b>behaviour</b></em> that is exhibited by <code>size</code>? You could say that the stack is answering the question correctly. But then the question becomes "what is the question?"
|
29
|
+
|
30
|
+
Think of it this way: does size really matter? Keeping focused on the Stack example, I'd say the answer is often "no". Most clients probably care about whether they can push something on to the stack, or pop something off of it. But knowing whether it has 0 or 1000 items is only helpful if the client knows what those numbers mean. And that often requires asking more questions. For example, let's say we want to push but we want to check if we can first:
|
31
|
+
|
32
|
+
<ruby>
|
33
|
+
stack.push item if stack.size < stack.capacity
|
34
|
+
</ruby>
|
35
|
+
|
36
|
+
Instead, we could ask if the stack is full...
|
37
|
+
|
38
|
+
<ruby>
|
39
|
+
stack.push item unless stack.full?
|
40
|
+
</ruby>
|
41
|
+
|
42
|
+
...but even then we have to know what it means to be full and adapt that knowledge to our real question which is "can I push something on to you"?
|
43
|
+
|
44
|
+
<ruby>
|
45
|
+
stack.push item if stack.accept? item
|
46
|
+
</ruby>
|
47
|
+
|
48
|
+
This is not to argue that "accept" is the best or right choice. The point is that all of this discussion has been about how our stack appears from the outside. We want to think about how other clients can use the object, not how the object will satisfy its clients' needs.
|
49
|
+
|
50
|
+
"Tell, Don't Ask" is a powerful guideline, but sometimes you have to ask questions. So let's extend TDA with this: "...but if you MUST ask, then ask for what you really need". Do we need to know the stack's size? Probably not. We <em>do</em>, however, need to know whether we can push onto it.
|
51
|
+
|
52
|
+
We'll be exploring these questions in this tutorial in addition to getting you started with rSpec. So <a href="stack_01.html">let's get started!</a>
|