turn 0.8.2 → 0.9.7
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/CONTRIBUTING.md +40 -0
- data/History.txt +81 -1
- data/Index.rb +34 -0
- data/LICENSE.txt +21 -0
- data/NOTICE.md +12 -0
- data/README.md +176 -0
- data/Release.txt +21 -1
- data/Version.txt +1 -1
- data/bin/turn +8 -2
- data/lib/turn/autoload.rb +6 -0
- data/lib/turn/autorun.rb +4 -0
- data/lib/turn/bin.rb +8 -2
- data/lib/turn/colorize.rb +50 -19
- data/lib/turn/command.rb +102 -39
- data/lib/turn/components/case.rb +7 -2
- data/lib/turn/components/method.rb +13 -2
- data/lib/turn/components/suite.rb +15 -6
- data/lib/turn/components.rb +4 -0
- data/lib/turn/configuration.rb +271 -0
- data/lib/turn/controller.rb +18 -176
- data/lib/turn/decorators/topten_decorator.rb +67 -0
- data/lib/turn/minitest.rb +25 -0
- data/lib/turn/reporter.rb +75 -13
- data/lib/turn/reporters/cue_reporter.rb +27 -11
- data/lib/turn/reporters/dot_reporter.rb +24 -28
- data/lib/turn/reporters/outline_reporter.rb +76 -39
- data/lib/turn/reporters/pretty_reporter.rb +110 -129
- data/lib/turn/reporters/progress_reporter.rb +70 -33
- data/lib/turn/runners/crossrunner.rb +2 -2
- data/lib/turn/runners/isorunner.rb +12 -10
- data/lib/turn/runners/minirunner.rb +51 -81
- data/lib/turn/runners/solorunner.rb +0 -1
- data/lib/turn/runners/testrunner.rb +12 -15
- data/lib/turn/testunit.rb +24 -0
- data/lib/turn/version.rb +1 -1
- data/lib/turn.rb +10 -15
- data/test/helper.rb +81 -5
- data/test/reporter_test.rb +35 -0
- data/test/test_framework.rb +81 -38
- data/test/test_reporters.rb +14 -14
- data/test/test_runners.rb +57 -19
- data/{demo → try}/test_autorun_minitest.rb +5 -4
- data/{demo → try}/test_autorun_testunit.rb +1 -2
- metadata +135 -112
- data/README.txt +0 -116
- data/Rakefile +0 -39
- data/lib/turn/autorun/minitest.rb +0 -173
- data/lib/turn/autorun/testunit.rb +0 -116
- data/turn.gemspec +0 -49
- /data/{demo → try}/test_counts.rb +0 -0
- /data/{demo → try}/test_sample.rb +0 -0
- /data/{demo → try}/test_sample2.rb +0 -0
|
@@ -3,28 +3,40 @@ require 'stringio'
|
|
|
3
3
|
|
|
4
4
|
module Turn
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Outline Reporter is Turn's Original.
|
|
7
7
|
#
|
|
8
8
|
#--
|
|
9
9
|
# TODO: Should we fit reporter output to width of console?
|
|
10
|
+
# y8: Yes. we should, but it's a kinda tricky, if you want to make it
|
|
11
|
+
# cross-platform. (See https://github.com/cldwalker/hirb/blob/master/lib/hirb/util.rb#L61)
|
|
10
12
|
# TODO: Running percentages?
|
|
13
|
+
# TODO: Cleanup me!
|
|
11
14
|
#++
|
|
12
15
|
class OutlineReporter < Reporter
|
|
13
16
|
|
|
17
|
+
#
|
|
18
|
+
TAB_SIZE = 8
|
|
19
|
+
|
|
14
20
|
#
|
|
15
21
|
def start_suite(suite)
|
|
16
|
-
@suite
|
|
17
|
-
@time
|
|
22
|
+
@suite = suite
|
|
23
|
+
@time = Time.now
|
|
24
|
+
# @FIXME (y8): Why we need to capture stdout and stderr?
|
|
18
25
|
@stdout = StringIO.new
|
|
19
26
|
@stderr = StringIO.new
|
|
20
|
-
#files
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
#files = suite.collect{ |s| s.file }.join(' ')
|
|
28
|
+
puts '=' * 78
|
|
29
|
+
if suite.seed
|
|
30
|
+
io.puts "SUITE #{suite.name} (SEED #{suite.seed})"
|
|
31
|
+
else
|
|
32
|
+
io.puts "SUITE #{suite.name}"
|
|
33
|
+
end
|
|
34
|
+
puts '=' * 78
|
|
23
35
|
end
|
|
24
36
|
|
|
25
37
|
#
|
|
26
38
|
def start_case(kase)
|
|
27
|
-
io.puts(Colorize.bold("#{kase.name}"))
|
|
39
|
+
io.puts(Colorize.bold("#{kase.name}")) if kase.size > 0
|
|
28
40
|
end
|
|
29
41
|
|
|
30
42
|
#
|
|
@@ -33,7 +45,11 @@ module Turn
|
|
|
33
45
|
# @file = test.file
|
|
34
46
|
# io.puts(test.file)
|
|
35
47
|
#end
|
|
36
|
-
|
|
48
|
+
|
|
49
|
+
# @FIXME: Should we move naturalized_name to test itself?
|
|
50
|
+
name = naturalized_name(test)
|
|
51
|
+
|
|
52
|
+
io.print " %-57s" % name
|
|
37
53
|
|
|
38
54
|
@stdout.rewind
|
|
39
55
|
@stderr.rewind
|
|
@@ -44,38 +60,60 @@ module Turn
|
|
|
44
60
|
|
|
45
61
|
#
|
|
46
62
|
def pass(message=nil)
|
|
47
|
-
io.puts "
|
|
63
|
+
io.puts " %s %s" % [ticktock, PASS]
|
|
64
|
+
|
|
48
65
|
if message
|
|
49
66
|
message = Colorize.magenta(message)
|
|
50
|
-
message = message.to_s.tabto(
|
|
67
|
+
message = message.to_s.tabto(TAB_SIZE)
|
|
51
68
|
io.puts(message)
|
|
52
69
|
end
|
|
53
70
|
end
|
|
54
71
|
|
|
55
72
|
#
|
|
56
73
|
def fail(assertion)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
io.puts " %s %s" % [ticktock, FAIL]
|
|
75
|
+
|
|
76
|
+
message = []
|
|
77
|
+
message << Colorize.bold(assertion.message.to_s)
|
|
78
|
+
message << "Assertion at:"
|
|
79
|
+
message << clean_backtrace(assertion.backtrace).join("\n")
|
|
80
|
+
message = message.join("\n")
|
|
81
|
+
|
|
82
|
+
io.puts(message.tabto(TAB_SIZE))
|
|
83
|
+
|
|
84
|
+
#unless backtrace.empty?
|
|
85
|
+
# io.puts "Assertion at".tabto(TAB_SIZE)
|
|
86
|
+
# io.puts backtrace.map{|l| l.tabto(TAB_SIZE)}.join("\n")
|
|
87
|
+
#end
|
|
88
|
+
|
|
89
|
+
#io.puts "STDERR:".tabto(TAB_SIZE)
|
|
67
90
|
show_captured_output
|
|
68
91
|
end
|
|
69
92
|
|
|
70
93
|
#
|
|
71
94
|
def error(exception)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
message =
|
|
75
|
-
|
|
95
|
+
io.puts " %s %s" % [ticktock, ERROR]
|
|
96
|
+
|
|
97
|
+
message = []
|
|
98
|
+
message << Colorize.bold(exception.message)
|
|
99
|
+
message << "Exception `#{exception.class}' at:"
|
|
100
|
+
message << clean_backtrace(exception.backtrace).join("\n")
|
|
101
|
+
message = message.join("\n")
|
|
102
|
+
|
|
103
|
+
io.puts(message.tabto(TAB_SIZE))
|
|
104
|
+
|
|
105
|
+
#io.puts "STDERR:".tabto(TAB_SIZE)
|
|
106
|
+
show_captured_output
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
#
|
|
110
|
+
def skip(exception)
|
|
111
|
+
io.puts " %s %s" % [ticktock, SKIP]
|
|
112
|
+
|
|
113
|
+
message = exception.message
|
|
114
|
+
|
|
76
115
|
io.puts(message.tabto(8))
|
|
77
|
-
|
|
78
|
-
io.puts(backtrace.tabto(8))
|
|
116
|
+
|
|
79
117
|
show_captured_output
|
|
80
118
|
end
|
|
81
119
|
|
|
@@ -117,28 +155,27 @@ module Turn
|
|
|
117
155
|
#def finish_case(kase)
|
|
118
156
|
#end
|
|
119
157
|
|
|
120
|
-
#
|
|
158
|
+
# TODO: pending (skip) counts
|
|
121
159
|
def finish_suite(suite)
|
|
122
|
-
total
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
160
|
+
total = suite.count_tests
|
|
161
|
+
passes = suite.count_passes
|
|
162
|
+
assertions = suite.count_assertions
|
|
163
|
+
failures = suite.count_failures
|
|
164
|
+
errors = suite.count_errors
|
|
165
|
+
skips = suite.count_skips
|
|
126
166
|
|
|
127
167
|
bar = '=' * 78
|
|
128
|
-
|
|
129
|
-
bar = if pass == total then Colorize.green(bar)
|
|
130
|
-
else Colorize.red(bar) end
|
|
131
|
-
end
|
|
168
|
+
bar = passes == total ? Colorize.green(bar) : Colorize.red(bar)
|
|
132
169
|
|
|
133
|
-
|
|
170
|
+
# @FIXME: Should we add suite.runtime, instead if this lame time calculations?
|
|
171
|
+
tally = [total, assertions, (Time.new - @time)]
|
|
134
172
|
|
|
135
173
|
io.puts bar
|
|
136
|
-
io.puts " pass: %d, fail: %d, error: %d" % [
|
|
137
|
-
io.puts " total: %d tests with %d assertions in
|
|
174
|
+
io.puts " pass: %d, fail: %d, error: %d, skip: %d" % [passes, failures, errors, skips]
|
|
175
|
+
io.puts " total: %d tests with %d assertions in %f seconds" % tally
|
|
138
176
|
io.puts bar
|
|
139
177
|
end
|
|
140
178
|
|
|
141
179
|
end
|
|
142
180
|
|
|
143
181
|
end
|
|
144
|
-
|
|
@@ -1,184 +1,165 @@
|
|
|
1
1
|
require 'turn/reporter'
|
|
2
2
|
|
|
3
3
|
module Turn
|
|
4
|
-
|
|
5
4
|
# = Pretty Reporter (by Paydro)
|
|
6
5
|
#
|
|
6
|
+
# Example output:
|
|
7
|
+
# TestCaseName:
|
|
8
|
+
# PASS test: Succesful test case. (0:00:02:059)
|
|
9
|
+
# ERROR test: Bogus test case. (0:00:02:059)
|
|
10
|
+
# FAIL test: Failed test case. (0:00:02:059)
|
|
11
|
+
#
|
|
7
12
|
class PrettyReporter < Reporter
|
|
8
|
-
#
|
|
9
|
-
|
|
13
|
+
# Second column left padding in chars.
|
|
14
|
+
TAB_SIZE = 10
|
|
10
15
|
|
|
11
|
-
#
|
|
16
|
+
# Character to put in front of backtrace.
|
|
17
|
+
TRACE_MARK = '@ '
|
|
18
|
+
|
|
19
|
+
# TODO: solo and cross runners do not have name or seed, need to fix.
|
|
20
|
+
|
|
21
|
+
# At the very start, before any testcases are run, this is called.
|
|
12
22
|
def start_suite(suite)
|
|
13
|
-
#old_sync, @@out.sync = @@out.sync, true if io.respond_to? :sync=
|
|
14
23
|
@suite = suite
|
|
15
24
|
@time = Time.now
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
|
|
26
|
+
io.puts Colorize.bold("Loaded Suite #{suite.name}")
|
|
27
|
+
io.puts
|
|
28
|
+
if suite.seed
|
|
29
|
+
io.puts "Started at #{Time.now} w/ seed #{suite.seed}."
|
|
30
|
+
else
|
|
31
|
+
io.puts "Started at #{Time.now}."
|
|
32
|
+
end
|
|
33
|
+
io.puts
|
|
22
34
|
end
|
|
23
35
|
|
|
24
|
-
#
|
|
36
|
+
# Invoked before a testcase is run.
|
|
25
37
|
def start_case(kase)
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
# Print case name if there any tests in suite
|
|
39
|
+
# TODO: Add option which will show all test cases, even without tests?
|
|
40
|
+
io.puts kase.name if kase.size > 0
|
|
29
41
|
end
|
|
30
42
|
|
|
31
|
-
#
|
|
43
|
+
# Invoked before a test is run.
|
|
32
44
|
def start_test(test)
|
|
33
45
|
@test_time = Time.now
|
|
34
46
|
@test = test
|
|
35
|
-
#if @file != test.file
|
|
36
|
-
# @file = test.file
|
|
37
|
-
# io.puts(test.file)
|
|
38
|
-
#end
|
|
39
|
-
#io.print " %-69s" % test.name
|
|
40
|
-
#$stdout = @stdout
|
|
41
|
-
#$stderr = @stderr
|
|
42
|
-
#$stdout.rewind
|
|
43
|
-
#$stderr.rewind
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
#
|
|
49
|
+
# Invoked when a test passes.
|
|
47
50
|
def pass(message=nil)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
io.print " (%.2fs) " % (Time.now - @test_time)
|
|
51
|
+
banner PASS
|
|
52
|
+
|
|
51
53
|
if message
|
|
52
54
|
message = Colorize.magenta(message)
|
|
53
|
-
message = message.to_s.tabto(
|
|
55
|
+
message = message.to_s.tabto(TAB_SIZE)
|
|
56
|
+
|
|
54
57
|
io.puts(message)
|
|
55
58
|
end
|
|
56
59
|
end
|
|
57
60
|
|
|
58
|
-
#
|
|
59
|
-
def fail(assertion)
|
|
60
|
-
|
|
61
|
-
io.print " #{@test}"
|
|
62
|
-
io.print " (%.2fs) " % (Time.now - @test_time)
|
|
63
|
-
|
|
64
|
-
#message = assertion.location[0] + "\n" + assertion.message #.gsub("\n","\n")
|
|
65
|
-
#trace = MiniTest::filter_backtrace(report[:exception].backtrace).first
|
|
61
|
+
# Invoked when a test raises an assertion.
|
|
62
|
+
def fail(assertion, message=nil)
|
|
63
|
+
banner FAIL
|
|
66
64
|
|
|
67
|
-
|
|
65
|
+
prettify(assertion, message)
|
|
66
|
+
end
|
|
68
67
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
trace = filter_backtrace(assertion.location).first
|
|
73
|
-
end
|
|
68
|
+
# Invoked when a test raises an exception.
|
|
69
|
+
def error(exception, message=nil)
|
|
70
|
+
banner ERROR
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
#io.puts pad(message, 10)
|
|
77
|
-
io.puts message.tabto(10)
|
|
78
|
-
io.puts trace.tabto(10)
|
|
79
|
-
#show_captured_output
|
|
72
|
+
prettify(exception, message)
|
|
80
73
|
end
|
|
81
74
|
|
|
82
|
-
#
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
io.print " #{@test}"
|
|
86
|
-
io.print " (%.2fs) " % (Time.now - @test_time)
|
|
87
|
-
|
|
88
|
-
#message = exception.to_s.split("\n")[2..-1].join("\n")
|
|
75
|
+
# Invoked when a test is skipped.
|
|
76
|
+
def skip(exception, message=nil)
|
|
77
|
+
banner SKIP
|
|
89
78
|
|
|
90
|
-
|
|
79
|
+
prettify(exception, message)
|
|
80
|
+
end
|
|
91
81
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
82
|
+
# Invoked after all tests in a testcase have ben run.
|
|
83
|
+
def finish_case(kase)
|
|
84
|
+
# Print newline is there any tests in suite
|
|
85
|
+
io.puts if kase.size > 0
|
|
86
|
+
end
|
|
97
87
|
|
|
88
|
+
# After all tests are run, this is the last observable action.
|
|
89
|
+
def finish_suite(suite)
|
|
90
|
+
total = colorize_count("%d tests", suite.count_tests, :bold)
|
|
91
|
+
passes = colorize_count("%d passed", suite.count_passes, :pass)
|
|
92
|
+
assertions = colorize_count("%d assertions", suite.count_assertions, nil)
|
|
93
|
+
failures = colorize_count("%d failures", suite.count_failures, :fail)
|
|
94
|
+
errors = colorize_count("%d errors", suite.count_errors, :error)
|
|
95
|
+
skips = colorize_count("%d skips", suite.count_skips, :skip)
|
|
96
|
+
|
|
97
|
+
io.puts "Finished in %.6f seconds." % (Time.now - @time)
|
|
98
98
|
io.puts
|
|
99
|
-
io.puts message.tabto(10)
|
|
100
|
-
io.puts trace.tabto(10)
|
|
101
|
-
end
|
|
102
99
|
|
|
103
|
-
|
|
104
|
-
#def skip
|
|
105
|
-
# io.puts(pad_with_size("#{SKIP}"))
|
|
106
|
-
#end
|
|
100
|
+
io.puts [ total, passes, failures, errors, skips, assertions ].join(", ")
|
|
107
101
|
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
# Please keep this newline, since it will be useful when after test case
|
|
103
|
+
# there will be other lines. For example "rake aborted!" or kind of.
|
|
110
104
|
io.puts
|
|
111
|
-
#@test_count += 1
|
|
112
|
-
#@assertion_count += inst._assertions
|
|
113
|
-
#$stdout = STDOUT
|
|
114
|
-
#$stderr = STDERR
|
|
115
105
|
end
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
#{@stdout.read}
|
|
129
|
-
output
|
|
107
|
+
private
|
|
108
|
+
# Creates an optionally-colorized string describing the number of occurances an event occurred.
|
|
109
|
+
#
|
|
110
|
+
# @param [String] str A printf-style string that expects an integer argument (i.e. the count)
|
|
111
|
+
# @param [Integer] count The number of occurances of the event being described.
|
|
112
|
+
# @param [nil, Symbol] colorize_method The method on Colorize to call in order to apply color to the result, or nil
|
|
113
|
+
# to not apply any coloring at all.
|
|
114
|
+
def colorize_count(str, count, colorize_method)
|
|
115
|
+
str= str % [count]
|
|
116
|
+
str= Colorize.send(colorize_method, str) if colorize_method and count != 0
|
|
117
|
+
str
|
|
130
118
|
end
|
|
131
119
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return if @stderr.eof?
|
|
135
|
-
STDOUT.puts(<<-output.tabto(8))
|
|
136
|
-
\nSTDERR:
|
|
137
|
-
#{@stderr.read}
|
|
138
|
-
output
|
|
139
|
-
end
|
|
140
|
-
=end
|
|
120
|
+
# TODO: Could also provide % done with time info. But it's already taking up
|
|
121
|
+
# a lot of screen realestate. Maybe use --verbose flag to offer two forms.
|
|
141
122
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
123
|
+
# Outputs test case header for given event (error, fail & etc)
|
|
124
|
+
#
|
|
125
|
+
# Example:
|
|
126
|
+
# PASS test: Test decription. (0.15s 0:00:02:059)
|
|
127
|
+
def banner(event)
|
|
128
|
+
name = naturalized_name(@test)
|
|
129
|
+
delta = Time.now - @test_time # test runtime
|
|
130
|
+
if @verbose
|
|
131
|
+
out = "%18s (%0.5fs) (%s) %s" % [event, delta, ticktock, name]
|
|
132
|
+
else
|
|
133
|
+
out = "%18s (%s) %s" % [event, ticktock, name]
|
|
134
|
+
end
|
|
135
|
+
if @mark > 0 && delta > @mark
|
|
136
|
+
out[1] = Colorize.mark('*')
|
|
145
137
|
end
|
|
138
|
+
io.puts out
|
|
146
139
|
end
|
|
147
140
|
|
|
141
|
+
# Cleanups and prints test payload
|
|
148
142
|
#
|
|
149
|
-
|
|
150
|
-
|
|
143
|
+
# Example:
|
|
144
|
+
# fail is not 1
|
|
145
|
+
# @ test/test_runners.rb:46:in `test_autorun_with_trace'
|
|
146
|
+
# bin/turn:4:in `<main>'
|
|
147
|
+
def prettify(raised, message=nil)
|
|
148
|
+
# Get message from raised, if not given
|
|
149
|
+
message ||= raised.message
|
|
151
150
|
|
|
152
|
-
|
|
153
|
-
failure = suite.count_failures
|
|
154
|
-
error = suite.count_errors
|
|
155
|
-
#pass = total - failure - error
|
|
151
|
+
backtrace = raised.respond_to?(:backtrace) ? raised.backtrace : raised.location
|
|
156
152
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
io.puts
|
|
160
|
-
|
|
161
|
-
io.print "%d tests, " % total
|
|
162
|
-
io.print "%d assertions, " % suite.count_assertions
|
|
163
|
-
io.print Colorize.fail( "%d failures" % failure) + ', '
|
|
164
|
-
io.print Colorize.error("%d errors" % error) #+ ', '
|
|
165
|
-
#io.puts Colorize.cyan( "%d skips" % skips ) #TODO
|
|
166
|
-
io.puts
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
private
|
|
153
|
+
# Filter and clean backtrace
|
|
154
|
+
backtrace = clean_backtrace(backtrace)
|
|
170
155
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
" " * size + str
|
|
174
|
-
end
|
|
156
|
+
# Add trace mark to first line.
|
|
157
|
+
backtrace.first.insert(0, TRACE_MARK)
|
|
175
158
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
159
|
+
io.puts Colorize.bold(message.tabto(TAB_SIZE))
|
|
160
|
+
io.puts backtrace.shift.tabto(TAB_SIZE - TRACE_MARK.length)
|
|
161
|
+
io.puts backtrace.join("\n").tabto(TAB_SIZE)
|
|
162
|
+
io.puts
|
|
179
163
|
end
|
|
180
|
-
|
|
181
164
|
end
|
|
182
|
-
|
|
183
165
|
end
|
|
184
|
-
|
|
@@ -6,28 +6,39 @@ module Turn
|
|
|
6
6
|
#
|
|
7
7
|
class ProgressReporter < Reporter
|
|
8
8
|
|
|
9
|
+
def initialize(io, opts={})
|
|
10
|
+
super(io, opts)
|
|
11
|
+
@fails = Hash.new{|h,k|h[k]=[]}
|
|
12
|
+
@errors = Hash.new{|h,k|h[k]=[]}
|
|
13
|
+
@skips = Hash.new{|h,k|h[k]=[]}
|
|
14
|
+
end
|
|
15
|
+
|
|
9
16
|
def start_suite(suite)
|
|
10
17
|
@pbar = ::ANSI::Progressbar.new('Testing', suite.size)
|
|
11
18
|
@pbar.inc
|
|
12
19
|
end
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
def start_case(testcase)
|
|
22
|
+
@_current_case = testcase
|
|
23
|
+
end
|
|
16
24
|
|
|
17
25
|
#def start_test(test)
|
|
18
26
|
#end
|
|
19
27
|
|
|
20
28
|
#def pass(message=nil)
|
|
21
|
-
# #@pbar.inc
|
|
22
29
|
#end
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
def fail(assertion, message=nil)
|
|
32
|
+
@fails[@_current_case] << assertion
|
|
33
|
+
end
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
def error(exception, message=nil)
|
|
36
|
+
@errors[@_current_case] << exception
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def skip(exception, message=nil)
|
|
40
|
+
@skips[@_current_case] << exception
|
|
41
|
+
end
|
|
31
42
|
|
|
32
43
|
def finish_case(kase)
|
|
33
44
|
@pbar.inc
|
|
@@ -42,13 +53,14 @@ module Turn
|
|
|
42
53
|
def post_report(suite)
|
|
43
54
|
tally = test_tally(suite)
|
|
44
55
|
|
|
45
|
-
width = suite.collect{ |tr| tr.name.size }.max
|
|
56
|
+
width = suite.collect{ |tr| tr.name.to_s.size }.max
|
|
46
57
|
|
|
47
|
-
headers = [ 'TESTCASE ', ' TESTS ', 'ASSERTIONS', ' FAILURES ', ' ERRORS ' ]
|
|
48
|
-
io.puts "\n%-#{width}s %10s %10s %10s %10s\n" % headers
|
|
58
|
+
headers = [ 'TESTCASE ', ' TESTS ', 'ASSERTIONS', ' FAILURES ', ' ERRORS ', 'SKIPS ' ]
|
|
59
|
+
io.puts "\n\n%-#{width}s %10s %10s %10s %10s %10s\n" % headers
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
io.puts ("-" * (width + 60))
|
|
51
62
|
|
|
63
|
+
files = nil
|
|
52
64
|
suite.each do |testrun|
|
|
53
65
|
if testrun.files != [testrun.name] && testrun.files != files
|
|
54
66
|
label = testrun.files.join(' ')
|
|
@@ -61,27 +73,53 @@ module Turn
|
|
|
61
73
|
|
|
62
74
|
#puts("\n%i tests, %i assertions, %i failures, %i errors\n\n" % tally)
|
|
63
75
|
|
|
64
|
-
tally_line = "
|
|
65
|
-
tally_line << "%-#{width}s " % "TOTAL"
|
|
66
|
-
tally_line << "%10s %10s %10s %10s" % tally
|
|
76
|
+
tally_line = ("-" * (width + 60))
|
|
77
|
+
tally_line << "\n%-#{width}s " % "TOTAL"
|
|
78
|
+
tally_line << "%10s %10s %10s %10s %10s" % tally
|
|
79
|
+
|
|
80
|
+
io.puts(tally_line + "\n\n\n")
|
|
67
81
|
|
|
68
|
-
io.puts
|
|
82
|
+
io.puts "-- Failures --\n\n" unless @fails.empty?
|
|
69
83
|
|
|
70
|
-
fails
|
|
71
|
-
|
|
84
|
+
@fails.each do |tc, cc|
|
|
85
|
+
cc.each do |e|
|
|
86
|
+
message = e.message.tabto(0).strip
|
|
87
|
+
message = Colorize.red(message)
|
|
88
|
+
message += "\n" + clean_backtrace(e.backtrace).join("\n")
|
|
89
|
+
io.puts(message+"\n\n")
|
|
90
|
+
end
|
|
91
|
+
io.puts
|
|
72
92
|
end
|
|
73
93
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
io.puts
|
|
94
|
+
io.puts "-- Errors --\n\n" unless @errors.empty?
|
|
95
|
+
|
|
96
|
+
@errors.each do |tc, cc|
|
|
97
|
+
cc.each do |e|
|
|
98
|
+
message = e.message.tabto(0).strip
|
|
99
|
+
message = Colorize.red(message)
|
|
100
|
+
message += "\n" + clean_backtrace(e.backtrace).join("\n")
|
|
101
|
+
io.puts(message+"\n\n")
|
|
83
102
|
end
|
|
103
|
+
io.puts
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#fails = suite.select do |testrun|
|
|
107
|
+
# testrun.fail? || testrun.error?
|
|
84
108
|
#end
|
|
109
|
+
|
|
110
|
+
##if tally[2] != 0 or tally[3] != 0
|
|
111
|
+
# unless fails.empty? # or verbose?
|
|
112
|
+
# io.puts "\n\n-- Failures and Errors --\n\n"
|
|
113
|
+
# fails.uniq.each do |testrun|
|
|
114
|
+
# message = testrun.message.tabto(0).strip
|
|
115
|
+
# message = Colorize.red(message)
|
|
116
|
+
# # backtrace ?
|
|
117
|
+
# #message += clean_backtrace(testrun.exception.backtrace).join("\n")
|
|
118
|
+
# io.puts(message+"\n\n")
|
|
119
|
+
# end
|
|
120
|
+
# io.puts
|
|
121
|
+
# end
|
|
122
|
+
##end
|
|
85
123
|
end
|
|
86
124
|
|
|
87
125
|
private
|
|
@@ -89,7 +127,7 @@ module Turn
|
|
|
89
127
|
def paint_line(testrun, width)
|
|
90
128
|
line = ''
|
|
91
129
|
line << "%-#{width}s " % [testrun.name]
|
|
92
|
-
line << "%10s %10s %10s %10s" % testrun.counts
|
|
130
|
+
line << "%10s %10s %10s %10s %10s" % testrun.counts
|
|
93
131
|
line << " " * 8
|
|
94
132
|
if testrun.fail?
|
|
95
133
|
line << "[#{FAIL}]"
|
|
@@ -103,14 +141,13 @@ module Turn
|
|
|
103
141
|
|
|
104
142
|
def test_tally(suite)
|
|
105
143
|
counts = suite.collect{ |tr| tr.counts }
|
|
106
|
-
tally = [0,0,0,0]
|
|
144
|
+
tally = [0,0,0,0,0]
|
|
107
145
|
counts.each do |count|
|
|
108
|
-
|
|
146
|
+
5.times{ |i| tally[i] += count[i] }
|
|
109
147
|
end
|
|
110
148
|
return tally
|
|
111
149
|
end
|
|
112
150
|
|
|
113
151
|
end
|
|
114
152
|
|
|
115
|
-
end
|
|
116
|
-
|
|
153
|
+
end
|
|
@@ -15,8 +15,8 @@ module Turn
|
|
|
15
15
|
def start
|
|
16
16
|
suite = TestSuite.new
|
|
17
17
|
|
|
18
|
-
files = @
|
|
19
|
-
viles = @
|
|
18
|
+
files = @config.files
|
|
19
|
+
viles = @config.files # TODO: make selectable ?
|
|
20
20
|
|
|
21
21
|
#files = files.select{ |f| File.extname(f) == '.rb' and File.file?(f) }
|
|
22
22
|
#viles = viles.select{ |f| File.extname(f) == '.rb' and File.file?(f) }
|