baretest 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MANIFEST.txt +38 -0
- data/README.markdown +229 -0
- data/bin/baretest +102 -0
- data/examples/test.rake +37 -0
- data/examples/test.rb +93 -0
- data/lib/test/assertion/failure.rb +14 -0
- data/lib/test/assertion/support.rb +268 -0
- data/lib/test/assertion.rb +117 -0
- data/lib/test/debug.rb +34 -0
- data/lib/test/irb_mode.rb +104 -0
- data/lib/test/run/cli.rb +79 -0
- data/lib/test/run/errors.rb +42 -0
- data/lib/test/run/interactive.rb +60 -0
- data/lib/test/run/minimal.rb +31 -0
- data/lib/test/run/spec.rb +32 -0
- data/lib/test/run/tap.rb +32 -0
- data/lib/test/run/xml.rb +56 -0
- data/lib/test/run.rb +137 -0
- data/lib/test/suite.rb +95 -0
- data/lib/test/version.rb +19 -0
- data/lib/test.rb +118 -0
- data/test/external/bootstraptest.rb +5 -0
- data/test/external/bootstrapwrap.rb +2 -0
- data/test/helper/mocks.rb +0 -0
- data/test/lib/test/assertion/support.rb +240 -0
- data/test/lib/test/assertion.rb +142 -0
- data/test/lib/test/debug.rb +63 -0
- data/test/lib/test/irb_mode.rb +10 -0
- data/test/lib/test/run/cli.rb +9 -0
- data/test/lib/test/run/errors.rb +9 -0
- data/test/lib/test/run/interactive.rb +9 -0
- data/test/lib/test/run/spec.rb +9 -0
- data/test/lib/test/run/tap.rb +9 -0
- data/test/lib/test/run/xml.rb +9 -0
- data/test/lib/test/run.rb +235 -0
- data/test/lib/test/suite.rb +275 -0
- data/test/lib/test.rb +227 -0
- data/test/setup.rb +2 -0
- metadata +99 -0
data/MANIFEST.txt
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
MANIFEST.txt
|
2
|
+
README.markdown
|
3
|
+
bin/baretest
|
4
|
+
examples/test.rake
|
5
|
+
examples/test.rb
|
6
|
+
lib/test.rb
|
7
|
+
lib/test/assertion.rb
|
8
|
+
lib/test/assertion/failure.rb
|
9
|
+
lib/test/assertion/support.rb
|
10
|
+
lib/test/debug.rb
|
11
|
+
lib/test/irb_mode.rb
|
12
|
+
lib/test/run.rb
|
13
|
+
lib/test/run/cli.rb
|
14
|
+
lib/test/run/errors.rb
|
15
|
+
lib/test/run/interactive.rb
|
16
|
+
lib/test/run/minimal.rb
|
17
|
+
lib/test/run/spec.rb
|
18
|
+
lib/test/run/tap.rb
|
19
|
+
lib/test/run/xml.rb
|
20
|
+
lib/test/suite.rb
|
21
|
+
lib/test/version.rb
|
22
|
+
test/external/bootstraptest.rb
|
23
|
+
test/external/bootstrapwrap.rb
|
24
|
+
test/helper/mocks.rb
|
25
|
+
test/lib/test.rb
|
26
|
+
test/lib/test/assertion.rb
|
27
|
+
test/lib/test/assertion/support.rb
|
28
|
+
test/lib/test/debug.rb
|
29
|
+
test/lib/test/irb_mode.rb
|
30
|
+
test/lib/test/run.rb
|
31
|
+
test/lib/test/run/cli.rb
|
32
|
+
test/lib/test/run/errors.rb
|
33
|
+
test/lib/test/run/interactive.rb
|
34
|
+
test/lib/test/run/spec.rb
|
35
|
+
test/lib/test/run/tap.rb
|
36
|
+
test/lib/test/run/xml.rb
|
37
|
+
test/lib/test/suite.rb
|
38
|
+
test/setup.rb
|
data/README.markdown
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
Bare Test
|
2
|
+
=========
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
Summary
|
7
|
+
-------
|
8
|
+
|
9
|
+
A minimal Testframework.
|
10
|
+
Three methods to use it, Twenty to master it, about hundred lines of code[1].
|
11
|
+
Bare Test, try it and you'll love it.
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
Description
|
16
|
+
-----------
|
17
|
+
|
18
|
+
Baretest is a Testframework that tries to stay out of your way, but support you when you want it.
|
19
|
+
In order to do so it has a load of features:
|
20
|
+
|
21
|
+
* Strightforward and terse assertions (just a block whose return value defines
|
22
|
+
success/failure)
|
23
|
+
* Easy grouping of assertions into suites
|
24
|
+
* BDD style specifications/test descriptions (NOT code), also extractable
|
25
|
+
* Uncomplicated dependency testing and skipping
|
26
|
+
* Helpers to deal painlessly with raising, throwing, float imprecision,
|
27
|
+
unordered collections etc.
|
28
|
+
* Ships with colored Shell formatter, Diagnostic-, Interactive-, XML- and TAP
|
29
|
+
formatter
|
30
|
+
* Interactive formatter - drops you into an irb session within failed assertion
|
31
|
+
with all setup methods executed, so you can inspect interactively why it
|
32
|
+
failed.
|
33
|
+
* Trivial to add new formatters (the standard formatters are only roughly 20-50
|
34
|
+
lines of code each)
|
35
|
+
* Teardown and Setup for suites
|
36
|
+
* Callbacks to integrate mock libraries
|
37
|
+
* API to use it from code, such as rake tasks (comes with an example rake-task)
|
38
|
+
* baretest executable to run tests on multiple files at once
|
39
|
+
* Diagnostic assertion helpers (e.g. same(:a, :b) will give you 'Expected
|
40
|
+
:a but got :b' as diagnostic)
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
Quick Try
|
45
|
+
---------
|
46
|
+
|
47
|
+
1. Download from github and unpack (or clone)
|
48
|
+
2. Change into the baretest directory: `cd the/baretest/directory`
|
49
|
+
3. Run the examples: `./bin/baretest examples/test.rb`
|
50
|
+
|
51
|
+
That's it. Alternatively you can run baretests own tests, and play with formatters:
|
52
|
+
`./bin/baretest -f tap`
|
53
|
+
|
54
|
+
Unfortunately the installer and gem installer aren't ready yet.
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
Executable
|
59
|
+
----------
|
60
|
+
|
61
|
+
Usage: baretest [options] [glob, ...]
|
62
|
+
Glob defaults to 'test/**/*.rb'
|
63
|
+
Providing a directory as glob is equivalent to dir/**/*.rb
|
64
|
+
Options:
|
65
|
+
-f, --format FORMAT use FORMAT for output
|
66
|
+
-F, --formats show available formats
|
67
|
+
-d, --debug set debugging flags (set $DEBUG to true)
|
68
|
+
-i, --interactive drop into IRB on error or failure
|
69
|
+
-s, --setup FILE specify setup file
|
70
|
+
-v, --version print the version and exit
|
71
|
+
-w, --warn turn warnings on for your script
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
Planned Features
|
76
|
+
----------------
|
77
|
+
|
78
|
+
* --fail-all flag, to test/review diagnostics of tests
|
79
|
+
* Word-wrapping for CLI runner
|
80
|
+
* Flags for color and verbose (\[no-]color and \[no-]verbose) for the executable
|
81
|
+
* Passing on flags/options for formatters
|
82
|
+
* Alternative CLI runner with status implicit via colored/bg-colored descriptions
|
83
|
+
* Alternative CLI runner which prints the name of the test prior the label and rewrites
|
84
|
+
the line when the test has executed to add status & coloring.
|
85
|
+
* Simple stubbing with automatic cleanup at teardown. Example:
|
86
|
+
|
87
|
+
assert "Should require a single file listed in :requires option." do |a|
|
88
|
+
file = 'foo/bar'
|
89
|
+
stub(Kernel, :require) do |file, *args| a.touch(file) end
|
90
|
+
::Test::Suite.create(nil, nil, :requires => file)
|
91
|
+
|
92
|
+
touched file
|
93
|
+
end
|
94
|
+
|
95
|
+
* Inline tests via Module#describe (basically the same as Test::Suite#suite)
|
96
|
+
* YARD code to extract the specifications without running the code
|
97
|
+
* A redmine plugin
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
Rejected Features
|
102
|
+
-----------------
|
103
|
+
|
104
|
+
* Currently none
|
105
|
+
|
106
|
+
|
107
|
+
A Bit of Background
|
108
|
+
-------------------
|
109
|
+
|
110
|
+
Originally, bare-test started out as a project for shits & giggles on the flight
|
111
|
+
back from vegas (railsconf09), to prove that it is possible to have a fully
|
112
|
+
fledged test-framework in under 100 lines of source-code.
|
113
|
+
Later I realized that this project could become more. For one it was (still is)
|
114
|
+
dead simple to add another formatter, it is just as dead simple to embedd it
|
115
|
+
in code.
|
116
|
+
The principles are trivial to understand, embrace and extend.
|
117
|
+
Upon that it dawned me, that the project was viable and I began adding features
|
118
|
+
not found in other projects.
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
Example Testsuite
|
123
|
+
-----------------
|
124
|
+
|
125
|
+
From examples/test.rb:
|
126
|
+
|
127
|
+
Test.run_if_mainfile do
|
128
|
+
# assertions and refutations can be grouped in suites. They will share
|
129
|
+
# setup and teardown
|
130
|
+
# they don't have to be in suites, though
|
131
|
+
suite "Success" do
|
132
|
+
assert "An assertion returning a trueish value (non nil/false) is a success" do
|
133
|
+
true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
suite "Failure" do
|
138
|
+
assert "An assertion returning a falsish value (nil/false) is a failure" do
|
139
|
+
false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
suite "Pending" do
|
144
|
+
assert "An assertion without a block is pending"
|
145
|
+
end
|
146
|
+
|
147
|
+
suite "Error" do
|
148
|
+
assert "Uncaught exceptions in an assertion are an error" do
|
149
|
+
raise "Error!"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
suite "Special assertions" do
|
154
|
+
assert "Assert a block to raise" do
|
155
|
+
raises do
|
156
|
+
sleep(rand()/3+0.05)
|
157
|
+
raise "If this raises then the assertion is a success"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
assert "Assert a float to be close to another" do
|
162
|
+
a = 0.18 - 0.01
|
163
|
+
b = 0.17
|
164
|
+
within_delta a, b, 0.001
|
165
|
+
end
|
166
|
+
|
167
|
+
suite "Nested suite" do
|
168
|
+
assert "Assert two randomly ordered arrays to contain the same values" do
|
169
|
+
a = [*"A".."Z"] # an array with values from A to Z
|
170
|
+
b = a.sort_by { rand }
|
171
|
+
a.equal_unordered(b) # can be used with any Enumerable, uses hash-key identity
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
suite "Setup & Teardown" do
|
177
|
+
setup do
|
178
|
+
@foo = "foo"
|
179
|
+
@bar = "bar"
|
180
|
+
end
|
181
|
+
|
182
|
+
assert "@foo should be set" do
|
183
|
+
@foo == "foo"
|
184
|
+
end
|
185
|
+
|
186
|
+
suite "Nested suite" do
|
187
|
+
setup do
|
188
|
+
@bar = "inner bar"
|
189
|
+
@baz = "baz"
|
190
|
+
end
|
191
|
+
|
192
|
+
assert "@foo is inherited" do
|
193
|
+
@foo == "foo"
|
194
|
+
end
|
195
|
+
|
196
|
+
assert "@bar is overridden" do
|
197
|
+
@bar == "inner bar"
|
198
|
+
end
|
199
|
+
|
200
|
+
assert "@baz is defined only for inner" do
|
201
|
+
@baz == "baz"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
teardown do
|
206
|
+
@foo = nil # not that it'd make much sense, just to demonstrate
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
suite "Dependencies", :requires => ['foo', 'bar'] do
|
211
|
+
assert "Will be skipped, due to unsatisfied dependencies" do
|
212
|
+
raise "This code therefore will never be executed"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
Known bugs
|
220
|
+
----------
|
221
|
+
|
222
|
+
* touch/touched have to clean up after every Assertion#execute. Should use the mock hooks.
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
Foot Notes
|
227
|
+
----------
|
228
|
+
[1]: "" The abbreviated form without support code and output formatters.
|
229
|
+
The normal code is expanded to more lines for readability.
|
data/bin/baretest
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2009 by Stefan Rusterholz.
|
5
|
+
# All rights reserved.
|
6
|
+
# See LICENSE.txt for permissions.
|
7
|
+
#++
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
# Make sure the right libs are loaded, tries plain 'test' first, then a rubygem 'test', then
|
12
|
+
# the relative path it'd be if it isn't installed at all and you're just testrunning it.
|
13
|
+
require 'optparse'
|
14
|
+
begin
|
15
|
+
require 'test'
|
16
|
+
rescue LoadError
|
17
|
+
begin
|
18
|
+
require 'rubygems'
|
19
|
+
require 'test'
|
20
|
+
rescue LoadError
|
21
|
+
$LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib"))
|
22
|
+
require 'test'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
# Get all the command-line arguments and adapt options to it
|
29
|
+
format = ENV['FORMAT'] || 'cli'
|
30
|
+
interactive = ['false', nil].include?(ENV['INTERACTIVE']) ? false : true
|
31
|
+
setup_path = nil
|
32
|
+
|
33
|
+
opts = OptionParser.new("", 24, ' ') do |opts|
|
34
|
+
opts.banner = "Usage: baretest [options] [glob, ...]"
|
35
|
+
|
36
|
+
opts.separator "Glob defaults to 'test/**/*.rb'"
|
37
|
+
opts.separator "Providing a directory as glob is equivalent to dir/**/*.rb\n"
|
38
|
+
opts.separator "Options:"
|
39
|
+
|
40
|
+
opts.on("-f", "--format FORMAT", "use FORMAT for output") { |use|
|
41
|
+
format = use
|
42
|
+
}
|
43
|
+
|
44
|
+
opts.on("-F", "--formats", "show available formats") { |use|
|
45
|
+
Dir.glob("{#{$LOAD_PATH.join(',')}}/test/run/*.rb") { |path|
|
46
|
+
puts "- #{File.basename(path, '.rb')}"
|
47
|
+
}
|
48
|
+
exit
|
49
|
+
}
|
50
|
+
|
51
|
+
opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") {
|
52
|
+
$DEBUG = true
|
53
|
+
}
|
54
|
+
|
55
|
+
opts.on("-i", "--interactive", "drop into IRB on error or failure") {
|
56
|
+
interactive = true
|
57
|
+
}
|
58
|
+
|
59
|
+
opts.on("-s", "--setup FILE", "specify setup file") { |path|
|
60
|
+
setup_path = path
|
61
|
+
}
|
62
|
+
|
63
|
+
opts.on("-v", "--version", "print the version and exit") {
|
64
|
+
puts "baretest version 0.2"
|
65
|
+
exit
|
66
|
+
}
|
67
|
+
|
68
|
+
opts.on("-w", "--warn", "turn warnings on for your script") {
|
69
|
+
$VERBOSE = true
|
70
|
+
}
|
71
|
+
|
72
|
+
opts.parse! ARGV
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
# Load the setup file, all helper files and all test files
|
78
|
+
if ARGV.empty? then
|
79
|
+
setup_path ||= 'test/setup.rb'
|
80
|
+
load(setup_path) if File.exist?(setup_path)
|
81
|
+
Dir.glob('test/lib/**/*.rb') { |path|
|
82
|
+
helper_path = path.sub(%r{^test/lib/}, 'test/helper/')
|
83
|
+
puts "Loading helper file #{helper_path}" if $VERBOSE
|
84
|
+
load(helper_path) if File.exist?(helper_path)
|
85
|
+
puts "Loading test file #{path}" if $VERBOSE
|
86
|
+
load(path)
|
87
|
+
}
|
88
|
+
else
|
89
|
+
load(setup_path) if setup_path && File.exist?(setup_path)
|
90
|
+
ARGV.each { |path|
|
91
|
+
if File.directory?(path) then
|
92
|
+
Dir.glob("#{path}/**/*.rb") { load(path) }
|
93
|
+
else
|
94
|
+
Dir.glob(path) { load(path) }
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
# Run the tests
|
102
|
+
Test.run(:format => format, :interactive => interactive)
|
data/examples/test.rake
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# This rake task expects to be in PROJECT_DIR/tasks/test.rake
|
2
|
+
# It assumes that the tests are in PROJECT_DIR/test/**/*.rb
|
3
|
+
# This is relevant as it calculates the paths accordingly.
|
4
|
+
# Additionally it will add PROJECT_DIR/lib - if present - to $LOAD_PATH.
|
5
|
+
|
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")
|
17
|
+
|
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)
|
21
|
+
|
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
|
37
|
+
end
|
data/examples/test.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
Test.run_if_mainfile do
|
6
|
+
# assertions and refutations can be grouped in suites. They will share
|
7
|
+
# setup and teardown
|
8
|
+
# they don't have to be in suites, though
|
9
|
+
suite "Success" do
|
10
|
+
assert "An assertion returning a trueish value (non nil/false) is a success" do
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
suite "Failure" do
|
16
|
+
assert "An assertion returning a falsish value (nil/false) is a failure" do
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
suite "Pending" do
|
22
|
+
assert "An assertion without a block is pending"
|
23
|
+
end
|
24
|
+
|
25
|
+
suite "Error" do
|
26
|
+
assert "Uncaught exceptions in an assertion are an error" do
|
27
|
+
raise "Error!"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
suite "Special assertions" do
|
32
|
+
assert "Assert a block to raise" do
|
33
|
+
raises do
|
34
|
+
sleep(rand()/3+0.05)
|
35
|
+
raise "If this raises then the assertion is a success"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
assert "Assert a float to be close to another" do
|
40
|
+
a = 0.18 - 0.01
|
41
|
+
b = 0.17
|
42
|
+
within_delta a, b, 0.001
|
43
|
+
end
|
44
|
+
|
45
|
+
suite "Nested suite" do
|
46
|
+
assert "Assert two randomly ordered arrays to contain the same values" do
|
47
|
+
a = [*"A".."Z"] # an array with values from A to Z
|
48
|
+
b = a.sort_by { rand }
|
49
|
+
equal_unordered(a, b) # can be used with any Enumerable, uses hash-key identity
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
suite "Setup & Teardown" do
|
55
|
+
setup do
|
56
|
+
@foo = "foo"
|
57
|
+
@bar = "bar"
|
58
|
+
end
|
59
|
+
|
60
|
+
assert "@foo should be set" do
|
61
|
+
@foo == "foo"
|
62
|
+
end
|
63
|
+
|
64
|
+
suite "Nested suite" do
|
65
|
+
setup do
|
66
|
+
@bar = "inner bar"
|
67
|
+
@baz = "baz"
|
68
|
+
end
|
69
|
+
|
70
|
+
assert "@foo is inherited" do
|
71
|
+
@foo == "foo"
|
72
|
+
end
|
73
|
+
|
74
|
+
assert "@bar is overridden" do
|
75
|
+
@bar == "inner bar"
|
76
|
+
end
|
77
|
+
|
78
|
+
assert "@baz is defined only for inner" do
|
79
|
+
@baz == "baz"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
teardown do
|
84
|
+
@foo = nil # not that it'd make much sense, just to demonstrate
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
suite "Dependencies", :requires => ['foo', 'bar'] do
|
89
|
+
assert "Will be skipped, due to unsatisfied dependencies" do
|
90
|
+
failure "Why the heck do you have a 'foo/bar' file?"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|