baretest 0.1.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/LICENSE.txt +52 -0
  2. data/MANIFEST.txt +50 -31
  3. data/README.rdoc +260 -0
  4. data/bin/baretest +82 -24
  5. data/doc/baretest.rdoc +98 -0
  6. data/doc/mocking_stubbing_test_doubles.rdoc +5 -0
  7. data/doc/quickref.rdoc +261 -0
  8. data/doc/writing_tests.rdoc +148 -0
  9. data/examples/test.rake +58 -30
  10. data/examples/tests/irb_mode/failures.rb +26 -0
  11. data/examples/tests/mock_developer/test/helper/mocks.rb +0 -0
  12. data/examples/tests/mock_developer/test/setup.rb +57 -0
  13. data/examples/tests/mock_developer/test/suite/mock_demo.rb +19 -0
  14. data/examples/tests/overview/test.rb +89 -0
  15. data/examples/tests/variations/variations_01.rb +14 -0
  16. data/examples/tests/variations/variations_02.rb +19 -0
  17. data/examples/tests/variations/variations_03.rb +19 -0
  18. data/lib/baretest/assertion/context.rb +20 -0
  19. data/lib/baretest/assertion/failure.rb +22 -0
  20. data/lib/baretest/assertion/skip.rb +21 -0
  21. data/lib/{test → baretest}/assertion/support.rb +174 -39
  22. data/lib/baretest/assertion.rb +182 -0
  23. data/lib/baretest/irb_mode.rb +263 -0
  24. data/lib/{test/assertion/failure.rb → baretest/layout.rb} +6 -5
  25. data/lib/baretest/mocha.rb +18 -0
  26. data/lib/baretest/run/cli.rb +104 -0
  27. data/lib/{test → baretest}/run/errors.rb +12 -7
  28. data/lib/{test → baretest}/run/minimal.rb +8 -3
  29. data/lib/baretest/run/profile.rb +151 -0
  30. data/lib/{test → baretest}/run/spec.rb +10 -4
  31. data/lib/baretest/run/tap.rb +44 -0
  32. data/lib/baretest/run/xml.rb +80 -0
  33. data/lib/{test → baretest}/run.rb +31 -18
  34. data/lib/baretest/setup.rb +15 -0
  35. data/lib/baretest/skipped/assertion.rb +20 -0
  36. data/lib/baretest/skipped/suite.rb +49 -0
  37. data/lib/baretest/skipped.rb +15 -0
  38. data/lib/baretest/suite.rb +234 -0
  39. data/lib/baretest/utilities.rb +43 -0
  40. data/lib/{test → baretest}/version.rb +12 -3
  41. data/lib/baretest.rb +112 -0
  42. data/test/external/bootstraptest.rb +1 -1
  43. data/test/setup.rb +1 -1
  44. data/test/{lib/test → suite/lib/baretest}/assertion/support.rb +78 -24
  45. data/test/suite/lib/baretest/assertion.rb +192 -0
  46. data/test/{lib/test → suite/lib/baretest}/irb_mode.rb +0 -0
  47. data/test/{lib/test → suite/lib/baretest}/run/cli.rb +0 -0
  48. data/test/{lib/test → suite/lib/baretest}/run/errors.rb +0 -0
  49. data/test/{lib/test → suite/lib/baretest}/run/interactive.rb +0 -0
  50. data/test/{lib/test → suite/lib/baretest}/run/spec.rb +0 -0
  51. data/test/{lib/test → suite/lib/baretest}/run/tap.rb +0 -0
  52. data/test/{lib/test → suite/lib/baretest}/run/xml.rb +0 -0
  53. data/test/{lib/test → suite/lib/baretest}/run.rb +63 -61
  54. data/test/{lib/test → suite/lib/baretest}/suite.rb +77 -54
  55. data/test/{lib/test.rb → suite/lib/baretest.rb} +37 -37
  56. metadata +61 -40
  57. data/README.markdown +0 -229
  58. data/examples/test.rb +0 -93
  59. data/lib/test/assertion.rb +0 -117
  60. data/lib/test/debug.rb +0 -34
  61. data/lib/test/irb_mode.rb +0 -104
  62. data/lib/test/run/cli.rb +0 -79
  63. data/lib/test/run/interactive.rb +0 -60
  64. data/lib/test/run/tap.rb +0 -32
  65. data/lib/test/run/xml.rb +0 -56
  66. data/lib/test/suite.rb +0 -95
  67. data/lib/test.rb +0 -118
  68. data/test/lib/test/assertion.rb +0 -142
  69. data/test/lib/test/debug.rb +0 -63
data/doc/quickref.rdoc ADDED
@@ -0,0 +1,261 @@
1
+ = BareTest Quick Reference
2
+
3
+ This is a very condensed overview over baretest. If you're new to testing and
4
+ new to baretest, you may be more interested into doc/writing_tests.rdoc
5
+ Also look into the examples and baretests own test directory.
6
+
7
+
8
+
9
+ == Setup baretest
10
+
11
+ 1. Install baretest
12
+ a) official release: `sudo gem install baretest`
13
+ b) edge:
14
+ 1. git clone git://github.com/apeiros/baretest.git
15
+ 2. cd baretest
16
+ 3. rake gem:install
17
+ 2. Change into the project directory
18
+ 3. `baretest --init` to create the basic test-directory layout
19
+
20
+
21
+
22
+ == Location of testfiles
23
+
24
+ Your tests for PROJECT/lib/foo.rb belong into PROJECT/test/suite/lib/foo.rb.
25
+ Your tests for PROJECT/bin/bar belong into PROJECT/test/suite/bin/bar.
26
+ In other words, for every path, insert /test/suite after PROJECT to get the
27
+ path to the corresponding testfile.
28
+
29
+
30
+
31
+ == Writing tests
32
+
33
+ A testfile commonly looks like this:
34
+
35
+ BareTest.suite "module ModuleName" do
36
+ setup do
37
+ # This is run before each assert, that is in this suite or a nested suite
38
+ end
39
+
40
+ teardown do
41
+ # This is run after each assert, that is in this suite or a nested suite
42
+ end
43
+
44
+ suite "Class methods" do
45
+ setup do
46
+ # things used by most nested suites
47
+ end
48
+
49
+ suite "ModuleName::class_method_name" do
50
+ assert "does this" do
51
+ ...
52
+ end
53
+
54
+ assert "does that" do
55
+ end
56
+ end
57
+
58
+ suite "Instance methods" do
59
+ suite "ModuleName#instance_method_name" do
60
+ ...
61
+ end
62
+ end
63
+
64
+ suite "class ClassName" do # this is class ModuleName::ClassName
65
+ suite "Class methods" do
66
+ ...
67
+ end
68
+
69
+ suite "Instance methods" do
70
+ ...
71
+ end
72
+ end
73
+ end
74
+
75
+ This layout makes it easy to figure where tests for something are, and thus
76
+ makes maintaining the test-code base easier.
77
+
78
+ Setup callbacks are invoked from outermost suite to innermost suite, and
79
+ within the same suite, in the order of definition.
80
+
81
+ Teardown callbacks are invoked from innermost suite to outermost suite, and
82
+ within the same suite, in the order of definition.
83
+
84
+ BareTest.suite do
85
+ setup do puts 1 end
86
+ setup do puts 2 end
87
+ teardown do puts 7 end
88
+ teardown do puts 8 end
89
+
90
+ suite "Inner" do
91
+ setup do puts 3 end
92
+ setup do puts 4 end
93
+ teardown do puts 5 end
94
+ teardown do puts 6 end
95
+
96
+ assert "Inner - assert" do puts "Inner - assert" end
97
+ end
98
+
99
+ assert "Outer - assert" do puts "Outer - assert" end
100
+ end
101
+
102
+ Running this suite will print:
103
+
104
+ 1
105
+ 2
106
+ 3
107
+ 4
108
+ Inner - assert
109
+ 5
110
+ 6
111
+ 7
112
+ 8
113
+ 1
114
+ 2
115
+ Outer - assert
116
+ 7
117
+ 8
118
+
119
+
120
+
121
+ == Skipping Tests and Suites
122
+
123
+ A test is skipped if it does not have a block or calls 'skip'
124
+
125
+ == Assertion helper methods
126
+
127
+ See BareTest::Assertion::Support
128
+ All methods that have the method signature foo(expected, actual, message=nil)
129
+ can alternatively be used with named arguments:
130
+ foo a, b, "message" # is equivalent to:
131
+ foo :expected => a, :actual => b, :message => "message"
132
+
133
+ * skip(message, *args)
134
+ Description: Skips the assertion, uses sprintf with message and *args
135
+ Success: not possible
136
+ Failure: not possible
137
+
138
+ * failure(message, *args)
139
+ Description: Lets the assertion fail, uses sprintf with message and *args
140
+ Success: not possible
141
+ Failure: failure("%p was not the inverse of %p", 2, 5)
142
+
143
+ * same(expected, actual, message=nil)
144
+ Description: Uses expected.equal?(actual), which tests for object identity
145
+ Success: same(:foo, :foo)
146
+ Failure: same("foo", "foo")
147
+
148
+ * hash_key_equal(expected, actual, message=nil)
149
+ Description: Uses expected.eql?(actual), which is used for hash key equality.
150
+ Success: hash_key_equal("foo", "foo")
151
+ Failure: hash_key_equal(1.0, 1)
152
+
153
+ * equal(expected, actual, message=nil) (alias: order_equal)
154
+ Description: Uses expected == actual, which is used for order-equality.
155
+ Success: equal(1.0, 1)
156
+ Failure: equal(1, "1")
157
+
158
+ * case_equal(expected, actual, message=nil)
159
+ Description: Uses expected === actual, which is used in case/whens.
160
+ Success: case_equal(String, "foo")
161
+ Failure: case_equal(String, 1)
162
+
163
+ * equal_unordered(expected, actual, message=nil)
164
+ Description: Compares unordered enumerables, on the enumerable it uses each,
165
+ on the items it uses hash and eql?
166
+ Success: equal_unordered([1,2], [2,1])
167
+ Failure: equal_unordered([1,2], [2,1,2])
168
+
169
+ * within_delta(a, b, delta)
170
+ Description: Tests whether the difference between a and b is less than delta
171
+ Success: within_delta(0.5, Math.sin(Math::PI/6), 1e-6)
172
+ # equal(0.5, Math.sin(Math::PI/6)) would fail
173
+ Failure: within_delta(0.5, 0.6, 0.05)
174
+
175
+ * kind_of(expected, actual, message=nil) (alias: is_a)
176
+ Description: Uses actual.kind_of?(expected)
177
+ Success: kind_of(String, "foo")
178
+ Failure: kind_of(String, 1)
179
+
180
+ * throws(symbol)
181
+ Description: Test whether the block throws the given symbol
182
+ Success: throws(:foo) do throw(:foo) end
183
+ Failure: throws(:foo) do throw(:bar) end
184
+ throws(:foo) do nil end
185
+
186
+ * throws_nothing
187
+ Description: Test whether a piece of code really throws nothing
188
+ Success: throws_nothing do nil end
189
+ Failure: throws_nothing do throw(:foo) end
190
+
191
+ * raises(exception_class=StandardError, opts={})
192
+ Description: Test whether the block raises
193
+ Success: raises do raise "foo" end
194
+ raises ArgumentError do "12".to_i(10, :superfluous) end
195
+ Failure: raises do nil end
196
+ raises ArgumentError do "12".to_i(10) end
197
+
198
+ * raises_nothing
199
+ Description: Test whether the block doesn't raise
200
+ Success: raise_nothing do nil end
201
+ Failure: raise_nothing do raise "foo" end
202
+
203
+ * touch(thing=nil)
204
+ Description: Mark reaching a point in code, e.g. that a block was invoked
205
+ Success: -> see touched
206
+ Failure: -> see touched
207
+
208
+ * touched(thing=nil, times=nil)
209
+ Description: test whether a mark for reached code was set, optionally test
210
+ whether it was set the expected number of times
211
+ Success: touch; touched
212
+ touch :thing; touched :thing
213
+ touch :thing; touch :thing; touched :thing, 2
214
+ Failure: touched
215
+ touch :thing; touched :something
216
+ touch :thing; touched :thing, 2
217
+
218
+ * not_touched(thing=nil)
219
+ Description: same as touched(thing, 0)
220
+ Success: see touched
221
+ Failure: see touched
222
+
223
+
224
+
225
+ == Running tests
226
+
227
+ baretest's test-cycle is:
228
+
229
+ 1. Create Run instance and the toplevel suite
230
+ 2. Load everything as required by the command line flags
231
+ 3. Load PROJECT/test/setup.rb
232
+ 4. Find PROJECT/test/suite/**/*.rb
233
+ 5. Load each file found in 2., but for every file, see whether
234
+ PROJECT/test/helpers/suite/**/*.rb exists and load that first if it does
235
+ 6. Invoke run on the Run instance
236
+
237
+ From there on it depends on the loaded formatters and extenders, what really
238
+ will happen. But the norm is, that suites and assertions will be executed in
239
+ order of definition.
240
+
241
+
242
+
243
+ == Debugging tests
244
+
245
+ Use `baretest -i` to run baretest in interactive mode. When a failure or an
246
+ error occurs, you have access to the following commands:
247
+
248
+ * s! - original assertions' status
249
+ * e! - error message and full backtrace
250
+ * em! - error message
251
+ * bt! - full backtrace
252
+ * iv! - all available instance variables
253
+ * cv! - all available class variables
254
+ * gv! - all available global variables
255
+ * file - file this assertion was defined in
256
+ * line - line number in the file where this assertion's definition starts
257
+ * nesting - a '>'-separated list of suite descriptions this assertion is
258
+ nested in
259
+ * description - this assertion's description
260
+ * code - code of this assertion
261
+ * help - overview over all the commands
@@ -0,0 +1,148 @@
1
+ = Writing Tests
2
+
3
+
4
+
5
+ This tutorial assumes you have basic ruby knowledge. It is an introduction into
6
+ baretest and testing itself.
7
+ If you're a quick study and have already good knowledge about ruby and testing,
8
+ you may be more interested in just reading the examples and the
9
+ doc/quickref.rdoc.
10
+
11
+
12
+
13
+ == 1. In the beginning there was the project
14
+
15
+ The first step is of course the project. Baretest was written with the
16
+ assumption of a standard ruby project layout (should work fine without too,
17
+ though - might just require a bit more work on your part).
18
+ The standard directory layout looks like this:
19
+
20
+ |-- bin (executables)
21
+ |-- doc (additional documentation)
22
+ |-- ext (native extension code will be here)
23
+ |-- examples (for the users of the lib)
24
+ |-- lib (contains the library)
25
+ |-- rake (contains rake relevant stuff)
26
+ `-- Rakefile
27
+
28
+ In your project directory, you can invoke `baretest --init`, this will
29
+ create the 'test' directory. It will mirror your project directory. That is,
30
+ it will recreate all directories nested in bin and lib within test/suite.
31
+ The directory layout of 'test' is as follows:
32
+
33
+ `-- test
34
+ |-- external (baretest ignores this directory)
35
+ |-- helper (baretest loads helper/lib/foo.rb when loading suite/lib/foo.rb)
36
+ |-- setup.rb (setup.rb is loaded as the first file when running baretest)
37
+ `-- suite (in here are the tests itself)
38
+ |-- bin (the tests for bin, PROJECT/bin is replicated here)
39
+ `-- lib (the tests for lib, PROJECT/lib is replicated here)
40
+
41
+
42
+
43
+ == 2. Writing the tests
44
+
45
+ Assume you have `lib/foo.rb` containing the class 'Foo'. To test it, you create
46
+ the file `test/suite/lib/foo.rb`. You start out by creating a suite for your
47
+ class:
48
+
49
+ BareTest.suite "class Foo" do
50
+ end
51
+
52
+ You're in no way limited in how you name the suites. It's an arbitrary String.
53
+ Now lets assume 'lib/foo.rb' contains the following code:
54
+
55
+ class Foo
56
+ def bar
57
+ "bar"
58
+ end
59
+ end
60
+
61
+ Then follows the next step, we write the first assertion:
62
+
63
+ BareTest.suite do
64
+ suite "class Foo" do
65
+ assert "bar returns 'bar'" do
66
+ Foo.new.bar == 'bar'
67
+ end
68
+ end
69
+ end
70
+
71
+ As you can see, the assertion is plain ruby code. The return value of the block
72
+ decides whether the assertion is considered a success (trueish value, that is
73
+ all but false and nil) or a failure (falseish value, that is false or nil).
74
+
75
+
76
+
77
+ == 3. Running the tests
78
+
79
+ First you change the directory to your project's root directory.
80
+ There you run `baretest`. That's it.
81
+ Baretest will now load the 'test/setup.rb' file, then it'll search in
82
+ 'test/suite' for files and find 'test/suite/lib/foo.rb'. Before loading that
83
+ file, it'll see if there's also a file 'test/helpers/suite/lib/foo.rb'. If
84
+ there was, it'd load that first. After that, it loads the
85
+ 'test/suite/lib/foo.rb' file. When all testfiles are discovered and loaded,
86
+ it'll run the tests.
87
+
88
+
89
+
90
+ == 4. Separating parts of the test
91
+
92
+ A classical test consists of four phases:
93
+
94
+ 1. setup
95
+ 2. exercise
96
+ 3. validate
97
+ 4. teardown
98
+
99
+ Baretest has setup and teardown on suites, which will be run for every assertion
100
+ the suite contains.
101
+ Exercise and validate is currently combined in the 'assert' method.
102
+
103
+ So let's make use of that and rewrite our previous test:
104
+
105
+ BareTest.suite do
106
+ suite "class Foo" do
107
+ setup do
108
+ @foo = Foo.new
109
+ end
110
+
111
+ assert "bar returns 'bar'" do
112
+ @foo.bar == 'bar'
113
+ end
114
+ end
115
+ end
116
+
117
+ In this simplistic example, this may seem like wasted time. The more complex the
118
+ setup becomes and the more assertions need the same setup, the more time a
119
+ separate setup phase saves.
120
+ It additionally helps in making intent clear: this is setup, and this is test.
121
+
122
+
123
+ == 5. When troubles strike
124
+
125
+ If one of your assertions fails or errors, you can use `baretest -i` to
126
+ investigate the issue. It will throw you into an irb session, with
127
+ self being the failing/erroring assertion and with several helpful
128
+ methods (use `help` in the irb session to get a list of those).
129
+
130
+ == Things left to be written out
131
+ * toplevel suite may have a name/description too, it'll act the same as if
132
+ there was a suite in an unnamed toplevel suite
133
+ * [setup] They will also be run for every nested suite's assertion,
134
+ where the outermost setup is run first, the innermost last.
135
+ * using stubs & mocks
136
+ * However, suites with the same name are considered the same.
137
+
138
+ For example, this code:
139
+
140
+ BareTest.suite "class Foo" do
141
+ suite "class Bar" do
142
+ assert "foo"
143
+ end
144
+
145
+
146
+ Just like ruby's
147
+ namespacing works. That is, if you twice do `module X; class Y; ...; end; end`,
148
+ it will both times open the same class X::Y.
data/examples/test.rake CHANGED
@@ -1,37 +1,65 @@
1
+ #--
2
+ # Copyright 2009 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
1
9
  # This rake task expects to be in PROJECT_DIR/tasks/test.rake
2
10
  # It assumes that the tests are in PROJECT_DIR/test/**/*.rb
3
11
  # This is relevant as it calculates the paths accordingly.
4
- # Additionally it will add PROJECT_DIR/lib - if present - to $LOAD_PATH.
12
+ # It uses BareTest.load_standard_test_files to load setup and test files.
13
+ # This means it will also load a test/setup.rb file if present, where
14
+ # you can add paths to $LOAD_PATH.
5
15
 
6
- desc "Run testsuite. Set FORMAT env variable to change the formatter used."
7
- task :test do
8
- begin
9
- require 'test'
10
- rescue LoadError => e
11
- puts "Could not run tests: #{e}"
12
- else
13
- # Prepare paths
14
- rake_file = File.expand_path(__FILE__)
15
- test_dir = File.expand_path("#{rake_file}/../../test")
16
- lib_dir = File.expand_path("#{rake_file}/../../lib")
16
+ namespace :test do
17
+ desc "Information about how your test directory should look."
18
+ task :structure do
19
+ wd = File.expand_path(Dir.getwd)
20
+ rake_file = File.expand_path(__FILE__)
21
+ test_dir = ['./test', "#{rake_file}/../../test"].map { |path|
22
+ full = File.expand_path(path)
23
+ relative = full[(wd.size+1)..-1]
24
+ "* #{relative} (#{full})"
25
+ }
17
26
 
18
- # Verify that the test directory exists
19
- raise "Could not determine test directory, please adapt this rake task to " \
20
- "your directory structure first." unless File.directory?(test_dir)
27
+ puts "rake test:run expects to find one of the these directories:", *test_dir
28
+ end
21
29
 
22
- # Add PROJECT_DIR/lib to $LOAD_PATH if the dir exists
23
- if File.directory?(lib_dir) && !$LOAD_PATH.include?(lib_dir) then
24
- $LOAD_PATH.unshift(lib_dir)
25
- puts "Added '#{lib_dir}' to $LOAD_PATH" if $VERBOSE
26
- end
27
-
28
- # Load all test definitions
29
- Dir.glob(File.expand_path("#{test_dir}/**/*.rb")) { |path|
30
- require path
31
- }
32
-
33
- # Run all tests
34
- formatter = ENV["FORMAT"] || 'cli'
35
- Test.run.run(formatter)
36
- end
30
+ desc "Run testsuite. Set FORMAT env variable to change the formatter used, INTERACTIVE to have irb mode."
31
+ task :run do
32
+ begin
33
+ require 'baretest'
34
+ rescue LoadError => e
35
+ puts "Could not run tests: #{e}"
36
+ else
37
+ # Prepare paths
38
+ rake_file = File.expand_path(__FILE__)
39
+ test_dir = ["#{rake_file}/../../test", './test'].map { |path|
40
+ File.expand_path(path)
41
+ }.find { |path|
42
+ File.directory?(path)
43
+ }
44
+
45
+ # Verify that the test directory exists
46
+ raise "Could not determine test directory, please adapt this rake task to " \
47
+ "your directory structure first (see rake test:structure)." unless test_dir
48
+
49
+ # Load all test definitions
50
+ BareTest.load_standard_test_files(
51
+ :verbose => $VERBOSE,
52
+ :setup_file => 'test/setup.rb',
53
+ :chdir => File.dirname(test_dir) # must chdir to 1 above the 'test' dir
54
+ )
55
+
56
+ # Run all tests
57
+ format = ENV["FORMAT"] || 'cli'
58
+ interactive = ENV["INTERACTIVE"] == 'true'
59
+ BareTest.run(:format => format, :interactive => interactive)
60
+ end
61
+ end
37
62
  end
63
+
64
+ desc 'Alias for test:run'
65
+ task :test => 'test:run'
@@ -0,0 +1,26 @@
1
+ #--
2
+ # Copyright 2009 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ BareTest.suite "Failure" do
10
+ setup do
11
+ @a = 1
12
+ @b = 2
13
+ end
14
+
15
+ assert "This one should fail and thus drop you into irb" do
16
+ c = 3
17
+ d = 4
18
+ @a == d
19
+ end
20
+
21
+ assert "This one should error and thus drop you into irb" do
22
+ c = 3
23
+ d = 4
24
+ raise "error!"
25
+ end
26
+ end
@@ -0,0 +1,57 @@
1
+ $LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib"))
2
+ require 'baretest'
3
+
4
+ BareTest.toplevel_suite.setup do
5
+ @_mymockname = {
6
+ :mocks => [],
7
+ :failures => [],
8
+ :exceptions => []
9
+ }
10
+ end
11
+ BareTest.toplevel_suite.teardown do
12
+ @_mymockname[:mocks].each { |mock|
13
+ mock.teardown(@_mymockname)
14
+ }
15
+ unless @_mymockname[:exceptions].empty? then
16
+ @reason = "An error occurred"
17
+ @exception = @_mymockname[:exceptions].first
18
+ @status = :error
19
+ end
20
+ unless @status == :error || @_mymockname[:failures].empty?
21
+ @reason = @_mymockname[:failures].first
22
+ @status = :failure
23
+ end
24
+ end
25
+
26
+ class DemoMock
27
+ class Error < StandardError; end
28
+
29
+ def initialize(action, message)
30
+ @action, @message = action, message
31
+ end
32
+
33
+ def teardown(recorder)
34
+ case @action
35
+ when :fail
36
+ recorder[:failures] << @message
37
+ when :raise
38
+ raise @message
39
+ end
40
+ rescue Error => e
41
+ recorder[:exceptions] << e
42
+ end
43
+ end
44
+
45
+ module MockSupport
46
+ def demo_mock(*args, &block)
47
+ mock = DemoMock.new(*args, &block)
48
+ @_mymockname[:mocks] << mock
49
+ mock
50
+ end
51
+ end
52
+
53
+ module BareTest
54
+ class Assertion
55
+ include MockSupport
56
+ end
57
+ end
@@ -0,0 +1,19 @@
1
+ BareTest.suite "MockDemo" do
2
+ suite "nothing happens" do
3
+ assert "Success" do
4
+ demo_mock(nil, nil)
5
+ end
6
+ end
7
+
8
+ suite "mock fails" do
9
+ assert "Failure" do
10
+ demo_mock(:fail, "this is the mock failure message")
11
+ end
12
+ end
13
+
14
+ suite "mock errors" do
15
+ assert "Exception" do
16
+ demo_mock(:raise, DemoMock::Error.new("mock errors message"))
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,89 @@
1
+ BareTest.suite do
2
+ # assertions and refutations can be grouped in suites. They will share
3
+ # setup and teardown
4
+ # they don't have to be in suites, though
5
+ suite "Success" do
6
+ assert "An assertion returning a trueish value (non nil/false) is a success" do
7
+ true
8
+ end
9
+ end
10
+
11
+ suite "Failure" do
12
+ assert "An assertion returning a falsish value (nil/false) is a failure" do
13
+ false
14
+ end
15
+ end
16
+
17
+ suite "Pending" do
18
+ assert "An assertion without a block is pending"
19
+ end
20
+
21
+ suite "Error" do
22
+ assert "Uncaught exceptions in an assertion are an error" do
23
+ raise "Error!"
24
+ end
25
+ end
26
+
27
+ suite "Special assertions" do
28
+ assert "Assert a block to raise" do
29
+ raises do
30
+ sleep(rand()/3+0.05)
31
+ raise "If this raises then the assertion is a success"
32
+ end
33
+ end
34
+
35
+ assert "Assert a float to be close to another" do
36
+ a = 0.18 - 0.01
37
+ b = 0.17
38
+ within_delta a, b, 0.001
39
+ end
40
+
41
+ suite "Nested suite" do
42
+ assert "Assert two randomly ordered arrays to contain the same values" do
43
+ a = [*"A".."Z"] # an array with values from A to Z
44
+ b = a.sort_by { rand }
45
+ equal_unordered(a, b) # can be used with any Enumerable, uses hash-key identity
46
+ end
47
+ end
48
+ end
49
+
50
+ suite "Setup & Teardown" do
51
+ setup do
52
+ @foo = "foo"
53
+ @bar = "bar"
54
+ end
55
+
56
+ assert "@foo should be set" do
57
+ @foo == "foo"
58
+ end
59
+
60
+ suite "Nested suite" do
61
+ setup do
62
+ @bar = "inner bar"
63
+ @baz = "baz"
64
+ end
65
+
66
+ assert "@foo is inherited" do
67
+ @foo == "foo"
68
+ end
69
+
70
+ assert "@bar is overridden" do
71
+ @bar == "inner bar"
72
+ end
73
+
74
+ assert "@baz is defined only for inner" do
75
+ @baz == "baz"
76
+ end
77
+ end
78
+
79
+ teardown do
80
+ @foo = nil # not that it'd make much sense, just to demonstrate
81
+ end
82
+ end
83
+
84
+ suite "Dependencies", :requires => ['foo', 'bar'] do
85
+ assert "Will be skipped, due to unsatisfied dependencies" do
86
+ failure "Why the heck do you have a 'foo/bar' file?"
87
+ end
88
+ end
89
+ end