turn 0.8.3 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +1 -8
- data/History.txt +16 -0
- data/{license/GPLv2.txt → LICENSE-GPL2.txt} +0 -0
- data/{license/MIT-LICENSE.txt → LICENSE-MIT.txt} +0 -0
- data/{license/RUBY-LICENSE.txt → LICENSE-RUBY.txt} +0 -0
- data/{NOTICE.txt → LICENSE.txt} +1 -1
- data/README.md +26 -0
- data/Rakefile +1 -0
- data/Version.txt +1 -1
- data/bin/turn +7 -1
- data/lib/turn.rb +20 -11
- data/lib/turn/autoload.rb +1 -1
- data/lib/turn/autorun.rb +8 -0
- data/lib/turn/bin.rb +7 -1
- data/lib/turn/colorize.rb +26 -10
- data/lib/turn/command.rb +32 -13
- data/lib/turn/components.rb +4 -0
- data/lib/turn/components/case.rb +1 -1
- data/lib/turn/components/suite.rb +9 -3
- data/lib/turn/configuration.rb +197 -0
- data/lib/turn/controller.rb +15 -206
- data/lib/turn/{autorun/minitest.rb → minitest.rb} +7 -3
- data/lib/turn/reporter.rb +65 -10
- data/lib/turn/reporters/cue_reporter.rb +13 -2
- data/lib/turn/reporters/dot_reporter.rb +12 -11
- data/lib/turn/reporters/outline_reporter.rb +57 -36
- data/lib/turn/reporters/pretty_reporter.rb +37 -24
- data/lib/turn/reporters/progress_reporter.rb +64 -26
- data/lib/turn/runners/minirunner.rb +7 -32
- data/lib/turn/testunit.rb +5 -0
- data/test/helper.rb +11 -2
- data/test/test_framework.rb +39 -30
- data/test/test_runners.rb +9 -7
- data/{demo → try}/test_autorun_minitest.rb +0 -0
- data/{demo → try}/test_autorun_testunit.rb +0 -0
- data/{demo → try}/test_counts.rb +0 -0
- data/{demo → try}/test_sample.rb +0 -0
- data/{demo → try}/test_sample2.rb +0 -0
- data/turn.gemspec +2 -2
- metadata +42 -29
- data/lib/turn/autorun/minitest0.rb +0 -163
- data/lib/turn/autorun/testunit.rb +0 -9
- data/lib/turn/autorun/testunit0.rb +0 -116
data/lib/turn/controller.rb
CHANGED
@@ -1,197 +1,6 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
1
|
module Turn
|
4
2
|
|
5
|
-
|
6
|
-
require 'turn/autoload'
|
7
|
-
require 'turn/components/suite.rb'
|
8
|
-
require 'turn/components/case.rb'
|
9
|
-
require 'turn/components/method.rb'
|
10
|
-
|
11
|
-
# Configure Turn
|
12
|
-
def self.config(&block)
|
13
|
-
@config ||= Configuration.new
|
14
|
-
block.call(@config) if block
|
15
|
-
@config
|
16
|
-
end
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#--
|
21
|
-
# TODO: Add support to test run loggging.
|
22
|
-
#++
|
23
|
-
class Configuration
|
24
|
-
|
25
|
-
# List of if file names or glob pattern of tests to run.
|
26
|
-
attr_accessor :tests
|
27
|
-
|
28
|
-
# List of file names or globs to exclude from +tests+ list.
|
29
|
-
attr_accessor :exclude
|
30
|
-
|
31
|
-
# Regexp pattern that all test name's must
|
32
|
-
# match to be eligible to run.
|
33
|
-
attr_accessor :pattern
|
34
|
-
|
35
|
-
# Regexp pattern that all test cases must
|
36
|
-
# match to be eligible to run.
|
37
|
-
attr_accessor :matchcase
|
38
|
-
|
39
|
-
# Add these folders to the $LOAD_PATH.
|
40
|
-
attr_accessor :loadpath
|
41
|
-
|
42
|
-
# Libs to require when running tests.
|
43
|
-
attr_accessor :requires
|
44
|
-
|
45
|
-
# Reporter type.
|
46
|
-
attr_accessor :format
|
47
|
-
|
48
|
-
# Run mode.
|
49
|
-
attr_accessor :runmode
|
50
|
-
|
51
|
-
# Test against live install (i.e. Don't use loadpath option)
|
52
|
-
attr_accessor :live
|
53
|
-
|
54
|
-
# Log results? May be true/false or log file name. (TODO)
|
55
|
-
attr_accessor :log
|
56
|
-
|
57
|
-
# Verbose output?
|
58
|
-
attr_accessor :verbose
|
59
|
-
|
60
|
-
# Test framework, either :minitest or :testunit
|
61
|
-
attr_accessor :framework
|
62
|
-
|
63
|
-
# Enable full backtrace
|
64
|
-
attr_accessor :trace
|
65
|
-
|
66
|
-
# Use natural language case names.
|
67
|
-
attr_accessor :natural
|
68
|
-
|
69
|
-
def verbose? ; @verbose ; end
|
70
|
-
def live? ; @live ; end
|
71
|
-
def natural? ; @natural ; end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def initialize
|
76
|
-
yield(self) if block_given?
|
77
|
-
initialize_defaults
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
def initialize_defaults
|
82
|
-
@loadpath ||= ['lib']
|
83
|
-
@tests ||= ["test/**/{test,}*{,test}.rb"]
|
84
|
-
@exclude ||= []
|
85
|
-
@requires ||= []
|
86
|
-
@live ||= false
|
87
|
-
@log ||= true
|
88
|
-
#@format ||= nil
|
89
|
-
#@runner ||= RUBY_VERSION >= "1.9" ? MiniRunner : TestRunner
|
90
|
-
@matchcase ||= nil
|
91
|
-
@pattern ||= /.*/
|
92
|
-
@natural ||= false
|
93
|
-
|
94
|
-
@files = nil # reset files just in case
|
95
|
-
end
|
96
|
-
|
97
|
-
# Collect test configuation.
|
98
|
-
#def test_configuration(options={})
|
99
|
-
# #options = configure_options(options, 'test')
|
100
|
-
# #options['loadpath'] ||= metadata.loadpath
|
101
|
-
# options['tests'] ||= self.tests
|
102
|
-
# options['loadpath'] ||= self.loadpath
|
103
|
-
# options['requires'] ||= self.requires
|
104
|
-
# options['live'] ||= self.live
|
105
|
-
# options['exclude'] ||= self.exclude
|
106
|
-
# #options['tests'] = list_option(options['tests'])
|
107
|
-
# options['loadpath'] = list_option(options['loadpath'])
|
108
|
-
# options['exclude'] = list_option(options['exclude'])
|
109
|
-
# options['require'] = list_option(options['require'])
|
110
|
-
# return options
|
111
|
-
#end
|
112
|
-
|
113
|
-
#
|
114
|
-
def list_option(list)
|
115
|
-
case list
|
116
|
-
when nil
|
117
|
-
[]
|
118
|
-
when Array
|
119
|
-
list
|
120
|
-
else
|
121
|
-
list.split(/[:;]/)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
public
|
126
|
-
|
127
|
-
def tests=(paths)
|
128
|
-
@tests = list_option(paths)
|
129
|
-
end
|
130
|
-
|
131
|
-
def loadpath=(paths)
|
132
|
-
@loadpath = list_option(paths)
|
133
|
-
end
|
134
|
-
|
135
|
-
def exclude=(paths)
|
136
|
-
@exclude = list_option(paths)
|
137
|
-
end
|
138
|
-
|
139
|
-
def requires=(paths)
|
140
|
-
@requires = list_option(paths)
|
141
|
-
end
|
142
|
-
|
143
|
-
# Test files.
|
144
|
-
def files
|
145
|
-
@files ||= (
|
146
|
-
fs = tests.map do |t|
|
147
|
-
File.directory?(t) ? Dir[File.join(t, '**', '*')] : Dir[t]
|
148
|
-
end
|
149
|
-
fs = fs.flatten.reject{ |f| File.directory?(f) }
|
150
|
-
|
151
|
-
ex = exclude.map do |x|
|
152
|
-
File.directory?(x) ? Dir[File.join(x, '**', '*')] : Dir[x]
|
153
|
-
end
|
154
|
-
ex = ex.flatten.reject{ |f| File.directory?(f) }
|
155
|
-
|
156
|
-
(fs - ex).uniq.map{ |f| File.expand_path(f) }
|
157
|
-
).flatten
|
158
|
-
end
|
159
|
-
|
160
|
-
# TODO: Better name ?
|
161
|
-
def suite_name
|
162
|
-
files.map{ |path| File.dirname(path).sub(Dir.pwd+'/','') }.uniq.join(',')
|
163
|
-
end
|
164
|
-
|
165
|
-
# Select reporter based on output mode.
|
166
|
-
def reporter
|
167
|
-
@reporter ||= (
|
168
|
-
opts = { :trace=>trace, :natural=>natural? }
|
169
|
-
case format
|
170
|
-
when :marshal
|
171
|
-
require 'turn/reporters/marshal_reporter'
|
172
|
-
Turn::MarshalReporter.new($stdout, opts)
|
173
|
-
when :progress
|
174
|
-
require 'turn/reporters/progress_reporter'
|
175
|
-
Turn::ProgressReporter.new($stdout, opts)
|
176
|
-
when :dotted
|
177
|
-
require 'turn/reporters/dot_reporter'
|
178
|
-
Turn::DotReporter.new($stdout, opts)
|
179
|
-
when :pretty
|
180
|
-
require 'turn/reporters/pretty_reporter'
|
181
|
-
Turn::PrettyReporter.new($stdout, opts)
|
182
|
-
when :cue
|
183
|
-
require 'turn/reporters/cue_reporter'
|
184
|
-
Turn::CueReporter.new($stdout, opts)
|
185
|
-
else
|
186
|
-
require 'turn/reporters/outline_reporter'
|
187
|
-
Turn::OutlineReporter.new($stdout, opts)
|
188
|
-
end
|
189
|
-
)
|
190
|
-
end
|
191
|
-
|
192
|
-
end
|
193
|
-
|
194
|
-
# = Controller
|
3
|
+
# Controls execution of test run.
|
195
4
|
#
|
196
5
|
class Controller
|
197
6
|
|
@@ -223,23 +32,23 @@ module Turn
|
|
223
32
|
config.files.each{ |path| require(path) }
|
224
33
|
end
|
225
34
|
|
226
|
-
#
|
35
|
+
# Insatance of Runner, selected based on format and runmode.
|
227
36
|
def runner
|
228
37
|
@runner ||= (
|
229
|
-
case config.framework
|
230
|
-
when :minitest
|
38
|
+
#case config.framework
|
39
|
+
#when :minitest
|
231
40
|
require 'turn/runners/minirunner'
|
232
|
-
else
|
233
|
-
|
234
|
-
end
|
41
|
+
#else
|
42
|
+
# require 'turn/runners/testrunner'
|
43
|
+
#end
|
235
44
|
|
236
45
|
case config.runmode
|
237
46
|
when :marshal
|
238
|
-
if config.framework == :minitest
|
47
|
+
#if config.framework == :minitest
|
239
48
|
Turn::MiniRunner
|
240
|
-
else
|
241
|
-
|
242
|
-
end
|
49
|
+
#else
|
50
|
+
# Turn::TestRunner
|
51
|
+
#end
|
243
52
|
when :solo
|
244
53
|
require 'turn/runners/solorunner'
|
245
54
|
Turn::SoloRunner
|
@@ -247,11 +56,11 @@ module Turn
|
|
247
56
|
require 'turn/runners/crossrunner'
|
248
57
|
Turn::CrossRunner
|
249
58
|
else
|
250
|
-
if config.framework == :minitest
|
59
|
+
#if config.framework == :minitest
|
251
60
|
Turn::MiniRunner
|
252
|
-
else
|
253
|
-
|
254
|
-
end
|
61
|
+
#else
|
62
|
+
# Turn::TestRunner
|
63
|
+
#end
|
255
64
|
end
|
256
65
|
)
|
257
66
|
end
|
@@ -1,12 +1,16 @@
|
|
1
|
-
require 'turn
|
1
|
+
#require 'turn'
|
2
2
|
|
3
|
+
# make sure latest verison is used, rather than ruby's built-in
|
4
|
+
begin; gem 'minitest'; rescue Exception; end
|
5
|
+
|
6
|
+
# we save the developer the trouble of having to load these (TODO: should we?)
|
3
7
|
require 'minitest/unit'
|
4
8
|
require 'minitest/spec'
|
5
9
|
|
6
|
-
|
7
|
-
require 'turn/controller'
|
10
|
+
# load Turn's minitest runner
|
8
11
|
require 'turn/runners/minirunner'
|
9
12
|
|
13
|
+
# set MiniTest's runner to Turn::MiniRunner instance
|
10
14
|
if MiniTest::Unit.respond_to?(:runner=)
|
11
15
|
MiniTest::Unit.runner = Turn::MiniRunner.new
|
12
16
|
else
|
data/lib/turn/reporter.rb
CHANGED
@@ -2,8 +2,6 @@ module Turn
|
|
2
2
|
require 'turn/colorize'
|
3
3
|
require 'turn/core_ext'
|
4
4
|
|
5
|
-
# = Reporter
|
6
|
-
#
|
7
5
|
# There are two distinct way in which a report may be utilized
|
8
6
|
# by a Runner: per-call or per-file. The method #pass, #fail
|
9
7
|
# and #error are generic, and will be used in either case.
|
@@ -16,6 +14,7 @@ module Turn
|
|
16
14
|
|
17
15
|
include Colorize
|
18
16
|
|
17
|
+
# Where to send report, defaults to `$stdout`.
|
19
18
|
attr :io
|
20
19
|
|
21
20
|
def initialize(io, opts={})
|
@@ -26,46 +25,102 @@ module Turn
|
|
26
25
|
|
27
26
|
# These methods are called in the process of running the tests.
|
28
27
|
|
28
|
+
# At the very start, before any testcases are run, this is called.
|
29
29
|
def start_suite(test_suite)
|
30
30
|
end
|
31
31
|
|
32
|
+
# Invoked before a testcase is run.
|
32
33
|
def start_case(test_case)
|
33
34
|
end
|
34
35
|
|
36
|
+
# Invoked before a test is run.
|
35
37
|
def start_test(test)
|
36
38
|
end
|
37
39
|
|
40
|
+
# Invoked when a test passes.
|
38
41
|
def pass(message=nil)
|
39
42
|
end
|
40
43
|
|
44
|
+
# Invoked when a test raises an assertion.
|
41
45
|
def fail(assertion, message=nil)
|
42
46
|
end
|
43
47
|
|
48
|
+
# Invoked when a test raises an exception.
|
44
49
|
def error(exception, message=nil)
|
45
50
|
end
|
46
51
|
|
52
|
+
# Invoked when a test is skipped.
|
53
|
+
def skip(exception, message=nil)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Invoked after a test has been run.
|
47
57
|
def finish_test(test)
|
48
58
|
end
|
49
59
|
|
60
|
+
# Invoked after all tests in a testcase have ben run.
|
50
61
|
def finish_case(test_case)
|
51
62
|
end
|
52
63
|
|
64
|
+
# After all tests are run, this is the last observable action.
|
53
65
|
def finish_suite(test_suite)
|
54
66
|
end
|
55
67
|
|
56
68
|
private
|
57
69
|
|
58
|
-
#
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
70
|
+
# Apply filter_backtrace and limit_backtrace in one go.
|
71
|
+
def clean_backtrace(backtrace)
|
72
|
+
limit_backtrace(filter_backtrace(backtrace))
|
73
|
+
end
|
74
|
+
|
75
|
+
$RUBY_IGNORE_CALLERS ||= []
|
76
|
+
$RUBY_IGNORE_CALLERS.concat([
|
77
|
+
/\/turn.*\.rb/,
|
78
|
+
/\/bin\/turn/,
|
79
|
+
/\/minitest.*\.rb/,
|
80
|
+
/\/test\/unit.*\.rb/
|
81
|
+
])
|
82
|
+
|
83
|
+
# Filter backtrace of unimportant entries, and applies count limit if set in
|
84
|
+
# configuration. Setting $DEBUG to true will deactivate filter, or if the filter
|
85
|
+
# happens to remove all backtrace entries it will revert to the full backtrace,
|
86
|
+
# as that probably means there was an issue with the test harness itself.
|
87
|
+
def filter_backtrace(backtrace)
|
88
|
+
return [] unless backtrace
|
89
|
+
bt = backtrace.dup
|
90
|
+
bt.reject!{ |line| $RUBY_IGNORE_CALLERS.any?{ |re| re =~ line } } unless $DEBUG
|
91
|
+
#bt.reject!{ |line| line.rindex('minitest') }
|
92
|
+
#bt.reject!{ |line| line.rindex('test/unit') }
|
93
|
+
#bt.reject!{ |line| line.rindex('lib/turn') }
|
94
|
+
#bt.reject!{ |line| line.rindex('bin/turn') }
|
95
|
+
bt = backtrace if bt.empty? # if empty just dump the whole thing
|
65
96
|
bt.map{ |line| line.sub(Dir.pwd+'/', '') }
|
66
97
|
end
|
67
98
|
|
99
|
+
# Limit backtrace to number of lines if `trace` configuration option is set.
|
100
|
+
def limit_backtrace(backtrace)
|
101
|
+
return [] unless backtrace
|
102
|
+
@trace ? backtrace[0, @trace.to_i] : backtrace
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
def naturalized_name(test)
|
107
|
+
if @natural
|
108
|
+
" #{test.name.gsub("test_", "").gsub(/_/, " ")}"
|
109
|
+
else
|
110
|
+
" #{test.name}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
def ticktock
|
116
|
+
t = Time.now - @time
|
117
|
+
h, t = t.divmod(60)
|
118
|
+
m, t = t.divmod(60)
|
119
|
+
s = t.truncate
|
120
|
+
f = ((t - s) * 1000).to_i
|
121
|
+
|
122
|
+
"%01d:%02d:%02d:%03d" % [h,m,s,f]
|
123
|
+
end
|
68
124
|
end
|
69
125
|
|
70
126
|
end
|
71
|
-
|
@@ -67,6 +67,15 @@ module Turn
|
|
67
67
|
prompt
|
68
68
|
end
|
69
69
|
|
70
|
+
def skip(exception, message=nil)
|
71
|
+
message = message || exception.to_s
|
72
|
+
io.puts("#{SKIP}")
|
73
|
+
io.puts(message) #if message
|
74
|
+
|
75
|
+
#prompt
|
76
|
+
end
|
77
|
+
|
78
|
+
|
70
79
|
def finish_test(test)
|
71
80
|
$stdout = STDOUT
|
72
81
|
$stderr = STDERR
|
@@ -130,9 +139,11 @@ module Turn
|
|
130
139
|
when 'c', ''
|
131
140
|
when 'r'
|
132
141
|
# how to reload and start over?
|
142
|
+
io.puts "restart has not been implemented yet"
|
133
143
|
when 'i'
|
134
144
|
# how to drop into an interactive console?
|
135
|
-
|
145
|
+
io.puts "irb support has not been implemented yet"
|
146
|
+
when 'b', 't'
|
136
147
|
io.puts $@
|
137
148
|
raise ArgumentError
|
138
149
|
when /^\d+$/
|
@@ -155,7 +166,7 @@ module Turn
|
|
155
166
|
c continue
|
156
167
|
r restart
|
157
168
|
i irb
|
158
|
-
|
169
|
+
b backtrace
|
159
170
|
# backtrace lines
|
160
171
|
q quit
|
161
172
|
? help
|
@@ -19,17 +19,21 @@ module Turn
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def pass(message=nil)
|
22
|
-
io.print Colorize.pass('
|
22
|
+
io.print Colorize.pass('S'); io.flush
|
23
23
|
end
|
24
24
|
|
25
|
-
def fail(message=nil)
|
25
|
+
def fail(assertion, message=nil)
|
26
26
|
io.print Colorize.fail('F'); io.flush
|
27
27
|
end
|
28
28
|
|
29
|
-
def error(message=nil)
|
29
|
+
def error(exception, message=nil)
|
30
30
|
io.print Colorize.error('E'); io.flush
|
31
31
|
end
|
32
32
|
|
33
|
+
def skip(exception, message=nil)
|
34
|
+
io.print Colorize.skip('-'); io.flush
|
35
|
+
end
|
36
|
+
|
33
37
|
def finish_test(test)
|
34
38
|
end
|
35
39
|
|
@@ -53,14 +57,11 @@ module Turn
|
|
53
57
|
unless list.empty? # or verbose?
|
54
58
|
#report << "\n\n-- Failures and Errors --\n\n"
|
55
59
|
list.uniq.each do |testunit|
|
56
|
-
message =
|
57
|
-
message
|
58
|
-
|
59
|
-
message << "\n"
|
60
|
-
|
61
|
-
message << "\n" + backtrace.join("\n")
|
62
|
-
end
|
63
|
-
report << "\n" << message << "\n"
|
60
|
+
message = []
|
61
|
+
message << (testunit.fail? ? FAIL : ERROR)
|
62
|
+
message << testunit.message.tabto(2)
|
63
|
+
message << clean_backtrace(testunit.backtrace).join("\n").tabto(2)
|
64
|
+
report << "\n" << message.join("\n") << "\n"
|
64
65
|
end
|
65
66
|
report << "\n"
|
66
67
|
end
|