baretest 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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)
@@ -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
@@ -0,0 +1,14 @@
1
+ #--
2
+ # Copyright 2009 by Stefan Rusterholz.
3
+ # All rights reserved.
4
+ # See LICENSE.txt for permissions.
5
+ #++
6
+
7
+
8
+
9
+ module Test
10
+ class Assertion
11
+ class Failure < StandardError
12
+ end
13
+ end
14
+ end