rubytest 0.5.4 → 0.6.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/.index +15 -3
- data/HISTORY.md +30 -0
- data/README.md +62 -38
- data/bin/ruby-test +7 -2
- data/bin/rubytest +7 -2
- data/lib/rubytest.rb +18 -3
- data/lib/rubytest.yml +65 -0
- data/lib/rubytest/autorun.rb +2 -14
- data/lib/rubytest/cli.rb +86 -87
- data/lib/rubytest/config.rb +381 -46
- data/lib/rubytest/rake.rb +72 -59
- data/lib/rubytest/runner.rb +80 -159
- data/test/basic_case.rb +2 -0
- data/{.ruby → test/helper.rb} +0 -0
- metadata +53 -4
- data/lib/rubytest/rc.rb +0 -8
data/lib/rubytest/rake.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
require 'rubytest'
|
1
2
|
require 'rake/tasklib'
|
2
3
|
|
3
|
-
module
|
4
|
+
module Test
|
4
5
|
|
6
|
+
##
|
7
|
+
# Rake subspace.
|
5
8
|
#
|
6
9
|
module Rake
|
7
10
|
|
8
|
-
|
9
|
-
# Or provide the option for either?
|
10
|
-
|
11
|
+
##
|
11
12
|
# Define a test rake task.
|
12
13
|
#
|
13
14
|
# The `TEST` environment variable can be used to select tests
|
14
|
-
# when using
|
15
|
+
# when using this task. Note, this is just a more convenient
|
16
|
+
# way than using `RUBYTEST_FILES`.
|
15
17
|
#
|
16
18
|
class TestTask < ::Rake::TaskLib
|
17
19
|
|
@@ -23,77 +25,67 @@ module Ruth
|
|
23
25
|
'test/**/*_test.rb'
|
24
26
|
]
|
25
27
|
|
26
|
-
# Test
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
attr_accessor :loadpath
|
31
|
-
|
32
|
-
# Scripts to load prior to loading tests.
|
33
|
-
attr_accessor :requires
|
34
|
-
|
35
|
-
# Report format to use.
|
36
|
-
attr_accessor :format
|
37
|
-
|
38
|
-
# Filter tests based by tags.
|
39
|
-
attr_accessor :tags
|
40
|
-
|
41
|
-
# Filter tests by matching description.
|
42
|
-
attr_accessor :match
|
43
|
-
|
44
|
-
# From Rake's own TestTask.
|
45
|
-
alias_method :libs, :loadpath
|
46
|
-
alias_method :test_files, :tests
|
28
|
+
# Test run configuration.
|
29
|
+
#
|
30
|
+
# @return [Config]
|
31
|
+
attr :config
|
47
32
|
|
33
|
+
# Initialize new Rake::TestTask instance.
|
48
34
|
#
|
49
|
-
def initialize(name='test', desc=
|
50
|
-
@name
|
51
|
-
@desc
|
35
|
+
def initialize(name='test', desc='run tests', &block)
|
36
|
+
@name = name || 'test'
|
37
|
+
@desc = desc
|
38
|
+
|
39
|
+
@config = Test::Config.new
|
52
40
|
|
53
|
-
@
|
54
|
-
@
|
55
|
-
@tests = [ENV['TEST'] || DEFAULT_TESTS].flatten
|
56
|
-
@format = nil
|
57
|
-
@match = nil
|
58
|
-
@tags = []
|
41
|
+
@config.files << default_tests if @config.files.empty?
|
42
|
+
@config.loadpath << 'lib' if @config.loadpath.empty?
|
59
43
|
|
60
|
-
block.call(
|
44
|
+
block.call(@config)
|
61
45
|
|
62
46
|
define_task
|
63
47
|
end
|
64
48
|
|
49
|
+
# Define rake task for testing.
|
65
50
|
#
|
51
|
+
# @return nothing
|
66
52
|
def define_task
|
67
53
|
desc @desc
|
68
54
|
task @name do
|
69
|
-
|
70
|
-
run
|
55
|
+
config.mode == 'shell' ? run_shell : run
|
71
56
|
end
|
72
57
|
end
|
73
58
|
|
59
|
+
# Run tests, via fork is possible, otherwise straight out.
|
74
60
|
#
|
61
|
+
# @return nothing
|
75
62
|
def run
|
76
|
-
fork
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
runner = new(suite, :format=>format, :tags=>tags, :match=>match)
|
63
|
+
if Process.respond_to?(:fork)
|
64
|
+
fork {
|
65
|
+
runner = Test::Runner.new(config)
|
66
|
+
success = runner.run
|
67
|
+
exit -1 unless success
|
68
|
+
}
|
69
|
+
Process.wait
|
70
|
+
else
|
71
|
+
runner = Test::Runner.new(config)
|
86
72
|
success = runner.run
|
87
|
-
|
88
73
|
exit -1 unless success
|
89
|
-
|
90
|
-
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Run test via command line shell.
|
78
|
+
#
|
79
|
+
# @return nothing
|
80
|
+
def shell_run
|
81
|
+
success = ruby(*config.to_shellwords)
|
82
|
+
exit -1 unless success
|
91
83
|
end
|
92
84
|
|
93
85
|
# Resolve test globs.
|
94
|
-
|
95
|
-
#
|
96
|
-
|
86
|
+
#
|
87
|
+
# @todo Implementation probably cna be simplified.
|
88
|
+
# @return [Array<String>] List of test files.
|
97
89
|
def test_files
|
98
90
|
files = tests
|
99
91
|
files = files.map{ |f| Dir[f] }.flatten
|
@@ -103,19 +95,40 @@ module Ruth
|
|
103
95
|
files
|
104
96
|
end
|
105
97
|
|
98
|
+
# Default test globs. For extra convenience will look for list in
|
99
|
+
# `ENV['TEST']` first.
|
106
100
|
#
|
101
|
+
# @return [Array<String>]
|
107
102
|
def default_tests
|
108
|
-
if ENV['
|
109
|
-
ENV['
|
103
|
+
if ENV['TEST']
|
104
|
+
ENV['TEST'].split(/[:;]/)
|
110
105
|
else
|
111
106
|
DEFAULT_TESTS
|
112
107
|
end
|
113
108
|
end
|
114
109
|
|
110
|
+
=begin
|
111
|
+
# Shell out to current ruby command.
|
115
112
|
#
|
116
|
-
#
|
117
|
-
|
118
|
-
|
113
|
+
# @return [Boolean] Success of shell call.
|
114
|
+
def ruby(*argv)
|
115
|
+
system(ruby_command, *argv)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get current ruby shell command.
|
119
|
+
#
|
120
|
+
# @return [String] Ruby shell command.
|
121
|
+
def ruby_command
|
122
|
+
@ruby_command ||= (
|
123
|
+
require 'rbconfig'
|
124
|
+
ENV['RUBY'] ||
|
125
|
+
File.join(
|
126
|
+
RbConfig::CONFIG['bindir'],
|
127
|
+
RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT']
|
128
|
+
).sub(/.*\s.*/m, '"\&"')
|
129
|
+
)
|
130
|
+
end
|
131
|
+
=end
|
119
132
|
|
120
133
|
end
|
121
134
|
|
data/lib/rubytest/runner.rb
CHANGED
@@ -1,136 +1,58 @@
|
|
1
1
|
module Test
|
2
2
|
|
3
|
+
# Currently this is an alias for configure, however it is likely
|
4
|
+
# to become an alias for `Runner.run` in the future.
|
5
|
+
#
|
6
|
+
# @deprecated Will probably change behavior in future.
|
7
|
+
def self.run(config=nil, &config_proc)
|
8
|
+
$stderr.puts "configuration profiles no longer supported." if config
|
9
|
+
configure(&config_proc)
|
10
|
+
end
|
11
|
+
|
3
12
|
# The Test::Runner class handles the execution of tests.
|
4
13
|
#
|
5
14
|
class Runner
|
6
15
|
|
7
|
-
#
|
8
|
-
|
16
|
+
# TODO: Wrap run in at_exit ?
|
17
|
+
def self.run(config=nil, &config_proc)
|
18
|
+
runner = Runner.new(config, &config_proc)
|
19
|
+
begin
|
20
|
+
success = runner.run
|
21
|
+
exit -1 unless success
|
22
|
+
rescue => error
|
23
|
+
raise error if $DEBUG
|
24
|
+
$stderr.puts('ERROR: ' + error.to_s)
|
25
|
+
exit -1
|
26
|
+
end
|
27
|
+
end
|
9
28
|
|
10
29
|
# Exceptions that are not caught by test runner.
|
11
30
|
OPEN_ERRORS = [NoMemoryError, SignalException, Interrupt, SystemExit]
|
12
31
|
|
13
|
-
#
|
14
|
-
|
15
|
-
# Default test suite ($TEST_SUITE).
|
16
|
-
def self.suite
|
17
|
-
$TEST_SUITE
|
18
|
-
end
|
19
|
-
|
20
|
-
# Default list of test files to load.
|
21
|
-
def self.files
|
22
|
-
@files ||= []
|
23
|
-
end
|
24
|
-
|
25
|
-
#
|
26
|
-
def self.format
|
27
|
-
@format || DEFAULT_FORMAT
|
28
|
-
end
|
29
|
-
|
30
|
-
#
|
31
|
-
def self.format=(format)
|
32
|
-
@format = format
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
def self.verbose
|
37
|
-
@verbose
|
38
|
-
end
|
39
|
-
|
40
|
-
#
|
41
|
-
def self.verbose=(boolean)
|
42
|
-
@verbose = !!boolean
|
43
|
-
end
|
44
|
-
|
45
|
-
# Default description match for filtering tests.
|
46
|
-
def self.match
|
47
|
-
@match ||= []
|
48
|
-
end
|
49
|
-
|
50
|
-
# Default selection of tags for filtering tests.
|
51
|
-
def self.tags
|
52
|
-
@tags ||= []
|
53
|
-
end
|
32
|
+
# Handle all configuration via the config instance.
|
33
|
+
attr :config
|
54
34
|
|
55
|
-
#
|
56
|
-
def
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
#
|
61
|
-
def self.hard
|
62
|
-
@hard
|
35
|
+
# Test suite to run. This is a list of compliant test units and test cases.
|
36
|
+
def suite
|
37
|
+
config.suite
|
63
38
|
end
|
64
39
|
|
65
40
|
#
|
66
|
-
|
67
|
-
@hard = !!boolean
|
68
|
-
end
|
69
|
-
|
41
|
+
# TODO: Cache or not?
|
70
42
|
#
|
71
|
-
def
|
72
|
-
|
43
|
+
def test_files
|
44
|
+
#@test_files ||= resolve_test_files
|
45
|
+
resolve_test_files
|
73
46
|
end
|
74
47
|
|
75
|
-
#
|
76
|
-
def self.autopath=(boolean)
|
77
|
-
@autopath = !!boolean
|
78
|
-
end
|
79
|
-
|
80
|
-
# / / / A T T R I B U T E S / / /
|
81
|
-
|
82
|
-
# Test suite to run. This is a list of compliant test units and test cases.
|
83
|
-
attr :suite
|
84
|
-
|
85
|
-
# Test files to load.
|
86
|
-
attr :files
|
87
|
-
|
88
48
|
# Reporter format name, or name fragment, used to look up reporter class.
|
89
|
-
|
90
|
-
|
91
|
-
#
|
92
|
-
def format=(name)
|
93
|
-
@format = name.to_s
|
49
|
+
def format
|
50
|
+
config.format
|
94
51
|
end
|
95
52
|
|
96
|
-
# Matching text used to filter which tests are run.
|
97
|
-
attr :match
|
98
|
-
|
99
|
-
# Selected tags used to filter which tests are run.
|
100
|
-
attr :tags
|
101
|
-
|
102
|
-
# List of units with which to filter tests. It is an array of strings
|
103
|
-
# which are matched against module, class and method names.
|
104
|
-
attr :units
|
105
|
-
|
106
53
|
# Show extra details in reports.
|
107
54
|
def verbose?
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
#
|
112
|
-
def verbose=(boolean)
|
113
|
-
@verbose = !!boolean
|
114
|
-
end
|
115
|
-
|
116
|
-
# Use "hard" test mode?
|
117
|
-
def hard?
|
118
|
-
@hard
|
119
|
-
end
|
120
|
-
|
121
|
-
#
|
122
|
-
def hard=(boolean)
|
123
|
-
@hard = !!boolean
|
124
|
-
end
|
125
|
-
|
126
|
-
# Automatically assume local loadpaths?
|
127
|
-
def autopath?
|
128
|
-
@autopath
|
129
|
-
end
|
130
|
-
|
131
|
-
#
|
132
|
-
def autopath=(boolean)
|
133
|
-
@autopath = !!boolean
|
55
|
+
config.verbose?
|
134
56
|
end
|
135
57
|
|
136
58
|
# Instance of Advice is a special customizable observer.
|
@@ -158,23 +80,19 @@ module Test
|
|
158
80
|
|
159
81
|
# New Runner.
|
160
82
|
#
|
161
|
-
# @param [
|
162
|
-
#
|
83
|
+
# @param [Config] config
|
84
|
+
# Config instance.
|
163
85
|
#
|
164
|
-
def initialize(
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
@
|
172
|
-
|
173
|
-
@
|
174
|
-
|
175
|
-
@advice = Advice.new
|
176
|
-
|
177
|
-
block.call(self) if block
|
86
|
+
def initialize(config=nil, &block)
|
87
|
+
if config
|
88
|
+
@config = Hash === config ? Config.new(config) : config
|
89
|
+
else
|
90
|
+
@config = Test.configuration
|
91
|
+
end
|
92
|
+
|
93
|
+
block.call(@config) if block
|
94
|
+
|
95
|
+
@advice = Advice.new
|
178
96
|
end
|
179
97
|
|
180
98
|
# The reporter to use for ouput.
|
@@ -193,22 +111,27 @@ module Test
|
|
193
111
|
# That the tests ran without error or failure.
|
194
112
|
#
|
195
113
|
def run
|
196
|
-
|
114
|
+
cd_chdir do
|
115
|
+
Test::Config.load_path_setup if config.autopath?
|
197
116
|
|
198
|
-
|
199
|
-
require file
|
200
|
-
end
|
117
|
+
ignore_callers
|
201
118
|
|
202
|
-
|
203
|
-
|
119
|
+
config.loadpath.each{ |path| $LOAD_PATH.unshift(path) }
|
120
|
+
config.requires.each{ |file| require file }
|
204
121
|
|
205
|
-
|
122
|
+
test_files.each do |test_file|
|
123
|
+
require test_file
|
124
|
+
end
|
125
|
+
|
126
|
+
@reporter = reporter_load(format)
|
127
|
+
@recorder = Recorder.new
|
128
|
+
|
129
|
+
@observers = [advice, @recorder, @reporter]
|
206
130
|
|
207
|
-
#cd_tmp do
|
208
131
|
observers.each{ |o| o.begin_suite(suite) }
|
209
132
|
run_thru(suite)
|
210
133
|
observers.each{ |o| o.end_suite(suite) }
|
211
|
-
|
134
|
+
end
|
212
135
|
|
213
136
|
recorder.success?
|
214
137
|
end
|
@@ -273,7 +196,7 @@ module Test
|
|
273
196
|
observers.each{ |o| o.begin_test(test) }
|
274
197
|
begin
|
275
198
|
success = test.call
|
276
|
-
if hard? && !success # TODO: separate run_test method to speed things up?
|
199
|
+
if config.hard? && !success # TODO: separate run_test method to speed things up?
|
277
200
|
raise Assertion, "failure of #{test}"
|
278
201
|
else
|
279
202
|
observers.each{ |o| o.pass(test) }
|
@@ -312,17 +235,17 @@ module Test
|
|
312
235
|
else
|
313
236
|
cases.each do |tc|
|
314
237
|
next if tc.respond_to?(:skip?) && tc.skip?
|
315
|
-
next if !match.empty? && !match.any?{ |m| m =~ tc.to_s }
|
238
|
+
next if !config.match.empty? && !config.match.any?{ |m| m =~ tc.to_s }
|
316
239
|
|
317
|
-
if !units.empty?
|
240
|
+
if !config.units.empty?
|
318
241
|
next unless tc.respond_to?(:unit)
|
319
|
-
next unless units.find{ |u| tc.unit.start_with?(u) }
|
242
|
+
next unless config.units.find{ |u| tc.unit.start_with?(u) }
|
320
243
|
end
|
321
244
|
|
322
|
-
if !tags.empty?
|
245
|
+
if !config.tags.empty?
|
323
246
|
next unless tc.respond_to?(:tags)
|
324
247
|
tc_tags = [tc.tags].flatten.map{ |t| t.to_s }
|
325
|
-
next if (tags & tc_tags).empty?
|
248
|
+
next if (config.tags & tc_tags).empty?
|
326
249
|
end
|
327
250
|
|
328
251
|
selected << tc
|
@@ -335,7 +258,6 @@ module Test
|
|
335
258
|
#
|
336
259
|
# @return [Reporter::Abstract]
|
337
260
|
# The test reporter instance.
|
338
|
-
#
|
339
261
|
def reporter_load(format)
|
340
262
|
format = DEFAULT_REPORT_FORMAT unless format
|
341
263
|
format = format.to_s.downcase
|
@@ -357,7 +279,6 @@ module Test
|
|
357
279
|
#
|
358
280
|
# @return [Array<String>]
|
359
281
|
# The names of available reporters.
|
360
|
-
#
|
361
282
|
def reporter_list
|
362
283
|
list = Dir[File.dirname(__FILE__) + '/reporters/*.rb']
|
363
284
|
list = list.map{ |r| File.basename(r).chomp('.rb') }
|
@@ -368,8 +289,9 @@ module Test
|
|
368
289
|
# Files can be globs and directories which need to be
|
369
290
|
# resolved to a list of files.
|
370
291
|
#
|
371
|
-
|
372
|
-
|
292
|
+
# @return [Array<String>]
|
293
|
+
def resolve_test_files
|
294
|
+
list = config.files.flatten
|
373
295
|
list = list.map{ |f| Dir[f] }.flatten
|
374
296
|
list = list.map{ |f| File.directory?(f) ? Dir[File.join(f, '**/*.rb')] : f }
|
375
297
|
list = list.flatten.uniq
|
@@ -377,21 +299,20 @@ module Test
|
|
377
299
|
list
|
378
300
|
end
|
379
301
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
302
|
+
# Change to directory and run block.
|
303
|
+
#
|
304
|
+
# @raise [Errno::ENOENT] If directory does not exist.
|
305
|
+
def cd_chdir(&block)
|
306
|
+
if dir = config.chdir
|
307
|
+
unless File.directory?(dir)
|
308
|
+
raise Errno::ENOENT, "change directory doesn't exist -- `#{dir}'"
|
309
|
+
end
|
310
|
+
Dir.chdir(dir, &block)
|
311
|
+
else
|
312
|
+
block.call
|
313
|
+
end
|
389
314
|
end
|
390
315
|
|
391
|
-
Dir.chdir(dir, &block)
|
392
|
-
end
|
393
|
-
=end
|
394
|
-
|
395
316
|
end
|
396
317
|
|
397
318
|
end
|