turn 0.8.3 → 0.9.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/.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
|