rspec 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES CHANGED
@@ -13,6 +13,15 @@
13
13
  * Make sure the PKG_VERSION constant in Rakefile.rb is
14
14
  consistent with the latest version in this document.
15
15
 
16
+ == Version 0.2.0
17
+
18
+ This release provides a tutorial for new users wishing to get started with
19
+ RSpec, and many improvements.
20
+
21
+ * improved reporting in the spec runner output
22
+ * update the examples to the new mock api
23
+ * added TUTORIAL, a getting started document for new users of RSpec
24
+
16
25
  == Version 0.1.7
17
26
 
18
27
  This release improves installation and documentation, mock integration and error reporting.
@@ -19,7 +19,7 @@ PKG_NAME = "rspec"
19
19
  # (This is subject to change - AH)
20
20
  #
21
21
  # REMEMBER TO KEEP PKG_VERSION IN SYNC WITH CHANGELOG
22
- PKG_VERSION = "0.1.7"
22
+ PKG_VERSION = "0.2.0"
23
23
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
24
24
  PKG_FILES = FileList[
25
25
  '[A-Z]*',
@@ -29,9 +29,7 @@ PKG_FILES = FileList[
29
29
  'doc/**/*'
30
30
  ]
31
31
 
32
- task :default => [:test, :test_craps_collector, :test_movie_collector,
33
- :test_rspec_craps, :test_rspec_movie, :test_rspec_craps_and_movie,
34
- :test_text_runner]
32
+ task :default => [:test, :test_text_runner]
35
33
 
36
34
  Rake::TestTask.new do |t|
37
35
  t.libs << "test"
@@ -40,45 +38,6 @@ Rake::TestTask.new do |t|
40
38
  t.verbose = true
41
39
  end
42
40
 
43
- # collector tests need to run individually
44
-
45
- Rake::TestTask.new(:test_craps_collector) do |t|
46
- t.libs << "test"
47
- t.libs << "examples"
48
- t.test_files = FileList['test/craps_collector_test.rb']
49
- t.verbose = true
50
- end
51
-
52
- Rake::TestTask.new(:test_movie_collector) do |t|
53
- t.libs << "test"
54
- t.libs << "examples"
55
- t.test_files = FileList['test/movie_collector_test.rb']
56
- t.verbose = true
57
- end
58
-
59
- # rspec tests need to run individually
60
-
61
- Rake::TestTask.new(:test_rspec_craps) do |t|
62
- t.libs << "test"
63
- t.libs << "examples"
64
- t.test_files = FileList['test/rspec_craps_test.rb']
65
- t.verbose = true
66
- end
67
-
68
- Rake::TestTask.new(:test_rspec_movie) do |t|
69
- t.libs << "test"
70
- t.libs << "examples"
71
- t.test_files = FileList['test/rspec_movie_test.rb']
72
- t.verbose = true
73
- end
74
-
75
- Rake::TestTask.new(:test_rspec_craps_and_movie) do |t|
76
- t.libs << "test"
77
- t.libs << "examples"
78
- t.test_files = FileList['test/rspec_craps_and_movie_test.rb']
79
- t.verbose = true
80
- end
81
-
82
41
  # text runner tests need to run individually
83
42
 
84
43
  Rake::TestTask.new(:test_text_runner) do |t|
@@ -0,0 +1,259 @@
1
+ = Getting Started with RSpec
2
+
3
+ RSpec is a behaviour specification framework for the Ruby Programming
4
+ Language. More information on the Ruby Programming Language can be found at
5
+ http://www.ruby-lang.org/. For more information on Behaviour Driven
6
+ Development, please see _A New Look at Test Driven Development_ which can be
7
+ found at http://www.daveastels.com/index.php?p=5.
8
+
9
+ This document is intended to help those interested in getting started with
10
+ Behaviour Driven Development using the RSpec behaviour specification
11
+ framework. Please send comments and/or corrections to me via email: srbaker at
12
+ pobox dot com.
13
+
14
+ == Installation
15
+
16
+ The first thing you need to do to start specifying your software is to install
17
+ RSpec. Thanks to the work on the Gem packaging of RSpec by Aslak Hellesoy, you
18
+ can install RSpec via RubyGems by issuing the following command:
19
+
20
+ $ gem install rspec
21
+
22
+ If you do not have RubyGems installed, see http://docs.rubygems.org/ for
23
+ information about RubyGems including how to install it.
24
+
25
+ == Usage
26
+
27
+ Once you have RSpec installed, ensure that it is correctly installed by
28
+ running the spec command from the command line without arguments. You should
29
+ get something like the following output:
30
+
31
+ Finished in 0.002726 seconds
32
+
33
+ 0 specifications, 0 expectations, 0 failures
34
+
35
+ If you get this output, you can be sure that RSpec has been installed and is
36
+ ready for use!
37
+
38
+ = Specification Anatomy
39
+
40
+ == Expectations
41
+
42
+ The simplest part of your set of specifications will be an expectation. An
43
+ expectation tells RSpec what the expected result of a piece code is. Your set of
44
+ specifications is simply a collection of expectations about how your code should
45
+ behave.
46
+
47
+ In RSpec, the expectations are methods that are available on every object in the
48
+ system. If I want to set an expectation that the value of 1 is 1, I would write:
49
+
50
+ 1.should_equal 1
51
+
52
+ And to set the expectation that 1 + 1 should be equal to 2, I would write the
53
+ following code:
54
+
55
+ (1 + 1).should_equal 2
56
+
57
+ There are many available expectation methods, and they can be found by looking
58
+ in the API documentation for RSpec. For most, if not all, of the expections
59
+ the negation is also provided. Thus, to ensure that subtracting 1 from 2 does
60
+ not equal 2, write the following:
61
+
62
+ (2 - 1).should_not_equal 2
63
+
64
+ These examples are extremely simple, but they accurately convey the simplicity
65
+ with which expectations can be written. When specifying your software, you are
66
+ simply writing expectations that specify how your software will behave. The rest
67
+ of the constructs in RSpec exist entirely to help you organize your
68
+ expectations, and to provide accurate and helpful reporting when these
69
+ expectations are not met.
70
+
71
+ Eventually, writing expectations for addition and subtraction of numbers will
72
+ get boring. When that happens, you can start writing expectations for your own
73
+ code. Let's try a slightly more involved example.
74
+
75
+ We have been asked to write a robot which will start at a given X, Y coordinate,
76
+ and will move in for directions a given number of units. If no starting
77
+ coordinate is given, the robot will start at 0,0. When the robot is moved, a
78
+ two-element array should be returned with the x and y coordinates. Some
79
+ expectations you might write for this robot might be the following:
80
+
81
+ rob = Robot.new
82
+
83
+ rob.should_not_be_nil
84
+ rob.should_be_kind_of Robot
85
+ rob.x_coordinate.should_equal 0
86
+ rob.y_coordinate.should_equal 0
87
+ rob.location.should_equal [0,0]
88
+
89
+ rob.move_north(1).should_equal [0, 1]
90
+ rob.move_south(5).should_equal [0, -4]
91
+ rob.move_east(10).should_equal [10, -4]
92
+ rob.move_west(5).should_equal [5, -4]
93
+
94
+ The code example above isn't intended to demonstrate good design, but has been
95
+ created explicitly to demonstrate the use of the expectation methods.
96
+
97
+ Also note that these expectations would be written iteratively, but the purpose
98
+ of this document is to serve as an introduction to the RSpec framework, not to
99
+ Behaviour Driven Development itself.
100
+
101
+ As you can see, writing expectations can be rather verbose, even for a simple
102
+ project like the example above. For clarity, your expectations will be grouped
103
+ into specifications, which are described in the next section.
104
+
105
+ == Specifications
106
+
107
+ Your software will be specified by writing expectations, which were explained in
108
+ the previous section. Your expectations will be grouped into specifications for
109
+ clarity. A specification is simply a method that contains expectations. The name
110
+ of your specification will be used by the Spec Runner (see Running and
111
+ Reporting) to inform you of unmet expectations, so choose your names wisely.
112
+
113
+ Consider the robot example from the previous example, but divided into
114
+ specification methods:
115
+
116
+ def initialization_without_coordinates
117
+ rob = Robot.new
118
+ rob.x_coordinate.should_equal 0
119
+ rob.y_coordinate.should_equal 0
120
+ rob.location.should_equal [0,0]
121
+ end
122
+
123
+ def initialization_with_coordinates
124
+ rob = Robot.new(10, 15)
125
+ rob.x_coordinate.should_equal 10
126
+ rob.y_coordinate.should_equal 15
127
+ rob.location.should_equal [10, 15]
128
+ end
129
+
130
+ def north_movement
131
+ rob = Robot.new
132
+ rob.move_north(1).should_equal [0, 1]
133
+ end
134
+
135
+ def west_movement
136
+ rob = Robot.new(10, 5)
137
+ rob.move_west(15).should_equal [-5, 5]
138
+ end
139
+
140
+ By dividing expectations into specification methods, our specifications for the
141
+ behaviour of our software are far easier to read and clearly express the intent.
142
+ Even those who are unfamiliar with Ruby specifically (and perhaps even some who
143
+ are relatively unfamiliar with software development in general) can easily read
144
+ our specifications.
145
+
146
+ == Fixtures
147
+
148
+ As you can see, there is some duplicated code in the example from the last
149
+ section in the creation of the Robot objects. You will find that the
150
+ initialization of objects will often be duplicated when writing specifications.
151
+ RSpec provides you with a way of setting up this data ahead of time, by
152
+ providing two methods: setup and teardown.
153
+
154
+ The setup method is called before invoking each specification to allow you to
155
+ set up resources which are required for each specification, and the teardown
156
+ method is called after invoking each specification, to allow you to
157
+ appropriately deallocate or close resources wich were required for the
158
+ specifications.
159
+
160
+ The example in the next section include a demonstration of the usage of fixtures
161
+ in Contexts.
162
+
163
+ == Contexts
164
+
165
+ The specifications described in the Specifications example are absolutely
166
+ useless if they're not placed in a context. Because you will be writing a large
167
+ number of specifications for your software, you will want a way to divide them
168
+ into logical groups. Specification methods are grouped within subclasses of
169
+ Context. You can define as many contexts as you wish, and you are encouraged to
170
+ divide your software into many well-defined contexts.
171
+
172
+ The following Context is a complete specification for the movement of the robot,
173
+ and if it were run, would produce useful output.
174
+
175
+ require 'spec'
176
+ class RobotMovement < Spec::Context
177
+ def setup
178
+ @rob = Robot.new
179
+ @rob1 = Robot.new(10, 15)
180
+ end
181
+
182
+ def movement
183
+ @rob.move_north(1).should_equal [0, 1]
184
+ @rob1.move_west(15).should_equal [-5, 5]
185
+ end
186
+
187
+ def teardown
188
+ @rob.die
189
+ @rob1.die
190
+ end
191
+ end
192
+
193
+ === Specification Naming
194
+
195
+ RSpec does not require the use of a specific naming scheme for specifications.
196
+ When a context is run, all of the public methods which you define in the context
197
+ will be executed. The only exceptions are currently methods which are used
198
+ internally by RSpec. The forbidden names are initialize, mock, violated, and
199
+ run. Because of Ruby's dynamic nature, you will not see a warning if you
200
+ override any of these methods, and unexpected behaviour may ensue.
201
+
202
+ In addition to the four aforementioned forbidden specification method names,
203
+ methods named with a leading underscore will also not be run as specifications.
204
+ This allows you a way to define methods for your own use within the Context and
205
+ not have them run as specifications.
206
+
207
+ == Running and Reporting
208
+
209
+ There currently exists a command-line runner for RSpec, called 'spec'. If you
210
+ write specifications and pass them to the runner on the command line, your
211
+ specifications will run and tell you where you have errors. You are encouraged
212
+ to try out the command line runner, first with the provided examples, and then
213
+ by writing your own specifications.
214
+
215
+ As an example of the output, if you run the movie_spec.rb file from the RSpec
216
+ examples, you will get the following output:
217
+
218
+ $ spec movie_spec.rb
219
+ ....
220
+ Finished in 0.016 seconds.
221
+
222
+ 4 specifications, 4 expectations, 0 failures.
223
+
224
+ The spec runner counts the specification as it executes them by printing a
225
+ single dot (.) to the screen. It indicates a failure with an X. For every
226
+ failure, the specification runner will provide a backtrace indicating where the
227
+ failure occured. A failure is basically a raised exception. Either an exception
228
+ raised by the software you're specifying, by Ruby itself (such as SyntaxError or
229
+ RuntimeError), or it will be an unmet expectation (ExpectationNotMet).
230
+
231
+ For instance, if you expect "Space Balls" to be in OneMovieList which actually
232
+ includes "Star Wars", you will get the following error:
233
+
234
+ $ spec movie_spec.rb
235
+ X...
236
+
237
+ 1)
238
+ <#<MovieList:0x284c1e0 @movies={"Star Wars"=>#<Movie:0x284c180 @name="Star Wars"
239
+ >}>> should include <"Space Balls"> (Spec::Exceptions::ExpectationNotMetError)
240
+ ./movie_spec.rb:34:in `should_include_space_balls'
241
+ ../bin/spec:10
242
+
243
+ Finished in 0.016 seconds
244
+
245
+ 4 specifications, 4 expectations, 1 failures
246
+
247
+ This informs you that the MovieList object should include "Space Balls", but got
248
+ an ExpectationNotMet error. The backtrace also informs you that the unmet
249
+ expectation can be found in the file 'movie_spec.rb' on line 34, in the
250
+ `should_include_space_balls' method.
251
+
252
+ == Conclusion
253
+
254
+ This document was by no means intended to provide an exhaustive overview of
255
+ Behaviour Driven Development in general, or RSpec specifically. It is intended
256
+ as a tutorial to get you started with specifying the behaviour of your software
257
+ with RSpec. More information can be found in the API documentation of RSpec
258
+ itself. Further documentation on BDD, and RSpec is on the way.
259
+
@@ -1,5 +1,5 @@
1
1
  require 'spec'
2
- require 'craps'
2
+ require File.dirname(__FILE__) + '/craps'
3
3
 
4
4
  class CrapsSpecification < Spec::Context
5
5
 
@@ -94,7 +94,7 @@ class CrapsSpecification < Spec::Context
94
94
  end
95
95
 
96
96
  def _load_die(die, rolls)
97
- rolls.each {| each | die.__expects(:roll).once.with_no_args.returns(each) }
97
+ rolls.each { |roll| die.should_receive(:roll).once.with_no_args.and_return(roll) }
98
98
  end
99
99
 
100
100
  end
@@ -56,7 +56,7 @@ module Spec
56
56
  end
57
57
 
58
58
  def dump_backtrace(trace)
59
- lines = trace.reject {|line| line.include? "lib/spec"}
59
+ lines = trace.reject {|line| line.include? "lib/spec"}.reject {|line | line.include? "./spec:"}
60
60
  @output << lines.join("\n")
61
61
  @output << "\n\n"
62
62
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.8.10
3
3
  specification_version: 1
4
4
  name: rspec
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.7
7
- date: 2005-08-30 00:00:00 -04:00
6
+ version: 0.2.0
7
+ date: 2005-09-27
8
8
  summary: Behaviour Specification Framework for Ruby
9
9
  require_paths:
10
10
  - lib
@@ -27,8 +27,6 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
27
27
  version: 0.0.0
28
28
  version:
29
29
  platform: ruby
30
- signing_key:
31
- cert_chain:
32
30
  authors:
33
31
  - Steven Baker
34
32
  files:
@@ -37,6 +35,7 @@ files:
37
35
  - Rakefile.rb
38
36
  - README
39
37
  - TODO
38
+ - TUTORIAL
40
39
  - lib/spec.rb
41
40
  - lib/spec/collector.rb
42
41
  - lib/spec/context.rb
@@ -46,18 +45,12 @@ files:
46
45
  - lib/spec/text_runner.rb
47
46
  - test/context_fixtures_test.rb
48
47
  - test/context_run_test.rb
49
- - test/craps_collector_test.rb
50
48
  - test/error_reporting_test.rb
51
49
  - test/expectations_test.rb
52
50
  - test/get_classes.rb
53
51
  - test/mock_test.rb
54
- - test/movie_collector_test.rb
55
- - test/rspec_craps_and_movie_test.rb
56
- - test/rspec_craps_test.rb
57
- - test/rspec_movie_test.rb
58
52
  - test/spec_collection_test.rb
59
53
  - test/specification_identification_test.rb
60
- - test/test_unit_ext_spec.rb
61
54
  - test/text_runner_test.rb
62
55
  - examples/craps.rb
63
56
  - examples/craps_spec.rb
@@ -1,17 +0,0 @@
1
- require 'test/unit'
2
-
3
- require 'spec'
4
-
5
-
6
- class CrapsCollectorTest < Test::Unit::TestCase
7
-
8
- def setup
9
- require 'examples/craps_spec'
10
- end
11
-
12
- def test_should_collect_only_craps_specification
13
- assert_equal CrapsSpecification.specifications.length, Spec::Collector.collection.length
14
- end
15
-
16
- end
17
-
@@ -1,19 +0,0 @@
1
- require 'test/unit'
2
-
3
- require 'spec'
4
-
5
-
6
- class MovieCollectorTest < Test::Unit::TestCase
7
-
8
- def setup
9
- require 'examples/movie_spec'
10
- end
11
-
12
- def test_should_collect_only_movie_specs
13
- specifications = EmptyMovieList.specifications.length
14
- specifications += OneMovieList.specifications.length
15
- assert_equal specifications, Spec::Collector.collection.length
16
- end
17
-
18
- end
19
-
@@ -1,32 +0,0 @@
1
- require 'test/unit'
2
-
3
- require 'rspec'
4
- require 'get_classes'
5
-
6
- class RSpecCrapsAndMovieTest < Test::Unit::TestCase
7
-
8
- def setup
9
- @rspec = RSpec.new(["examples/craps_spec.rb", "examples/movie_spec.rb"])
10
- end
11
-
12
- def test_should_load_craps_and_movie_specs
13
- assert_equal true, get_classes.include?('CrapsSpecification')
14
- assert_equal true, get_classes.include?('EmptyMovieList')
15
- assert_equal true, get_classes.include?('OneMovieList')
16
- end
17
-
18
- def test_should_include_all_specifications
19
- specifications = CrapsSpecification.collection.length
20
- specifications += EmptyMovieList.collection.length
21
- specifications += OneMovieList.collection.length
22
- assert_equal specifications, Spec::Collector.collection.length
23
- end
24
-
25
- def test_should_run_all_specifications
26
- buffer = ""
27
- @rspec.run(Spec::TextRunner.new(buffer))
28
- assert_equal true, buffer.include?("16 specifications, 16 expectations, 0 failures")
29
- end
30
-
31
- end
32
-
@@ -1,35 +0,0 @@
1
- require 'test/unit'
2
-
3
- require 'spec'
4
-
5
- require 'rspec'
6
-
7
- require 'get_classes'
8
-
9
- class RSpecCrapsTest < Test::Unit::TestCase
10
-
11
- def setup
12
- @rspec = RSpec.new(["examples/craps_spec.rb"])
13
- end
14
-
15
- def test_should_load_craps_spec
16
- assert_equal true, get_classes.include?('CrapsSpecification')
17
- end
18
-
19
- def test_should_not_load_movie_specs
20
- assert_equal false, get_classes.include?('OneMovieList')
21
- assert_equal false, get_classes.include?('EmptyMovieList')
22
- end
23
-
24
- def test_should_include_craps_specifications
25
- assert_equal CrapsSpecification.collection.length, Spec::Collector.collection.length
26
- end
27
-
28
- def test_should_run_craps_specifications
29
- buffer = ""
30
- @rspec.run(Spec::TextRunner.new(buffer))
31
- assert_equal true, buffer.include?("12 specifications, 12 expectations, 0 failures")
32
- end
33
-
34
- end
35
-
@@ -1,33 +0,0 @@
1
- require 'test/unit'
2
-
3
- require 'rspec'
4
- require 'get_classes'
5
-
6
- class RSpecMovieTest < Test::Unit::TestCase
7
-
8
- def setup
9
- @rspec = RSpec.new(["examples/movie_spec.rb"])
10
- end
11
-
12
- def test_should_load_movie_spec
13
- assert_equal true, get_classes.include?('EmptyMovieList')
14
- assert_equal true, get_classes.include?('OneMovieList')
15
- end
16
-
17
- def test_should_not_load_craps_spec
18
- assert_equal false, get_classes.include?('CrapsSpecification')
19
- end
20
-
21
- def test_should_include_movie_specifications
22
- specifications = EmptyMovieList.collection.length + OneMovieList.collection.length
23
- assert_equal specifications, Spec::Collector.collection.length
24
- end
25
-
26
- def test_should_run_movie_specifications
27
- buffer = ""
28
- @rspec.run(Spec::TextRunner.new(buffer))
29
- assert_equal true, buffer.include?("4 specifications, 4 expectations, 0 failures")
30
- end
31
-
32
- end
33
-
@@ -1,9 +0,0 @@
1
- require 'spec'
2
-
3
- module Foo
4
- class BarSpec < Spec::Context
5
- def should_fail
6
- raise "ERRORRRR"
7
- end
8
- end
9
- end