tapout 0.3.2 → 0.4.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.
Files changed (37) hide show
  1. data/.ruby +12 -3
  2. data/.yardopts +6 -5
  3. data/HISTORY.rdoc +16 -0
  4. data/README.rdoc +18 -16
  5. data/TAP-YJ.md +15 -15
  6. data/bin/tapout +1 -1
  7. data/demo/applique/ae.rb +1 -0
  8. data/{spec → demo}/applique/env.rb +0 -0
  9. data/{spec → demo}/issues/applique/env.rb +0 -0
  10. data/{spec → demo}/issues/default_reporter.rdoc +2 -2
  11. data/{spec → demo}/perl_adapter.rdoc +3 -3
  12. data/{spec → demo}/reporters/applique/cli.rb +1 -1
  13. data/{spec → demo}/reporters/fixtures/tapy.yml +0 -0
  14. data/{spec → demo}/reporters/reporters.rdoc +0 -0
  15. data/lib/tapout.rb +5 -101
  16. data/lib/tapout.yml +12 -3
  17. data/lib/tapout/adapters/perl.rb +1 -1
  18. data/lib/tapout/cli.rb +98 -0
  19. data/lib/tapout/config.rb +103 -0
  20. data/lib/tapout/parsers/json.rb +2 -2
  21. data/lib/tapout/parsers/perl.rb +1 -1
  22. data/lib/tapout/parsers/yaml.rb +3 -2
  23. data/lib/tapout/reporters.rb +2 -1
  24. data/lib/tapout/reporters/abstract.rb +223 -31
  25. data/lib/tapout/reporters/breakdown_reporter.rb +49 -57
  26. data/lib/tapout/reporters/dot_reporter.rb +52 -33
  27. data/lib/tapout/reporters/html_reporter.rb +3 -1
  28. data/lib/tapout/reporters/markdown_reporter.rb +101 -0
  29. data/lib/tapout/reporters/outline_reporter.rb +68 -25
  30. data/lib/tapout/reporters/pretty_reporter.rb +65 -86
  31. data/lib/tapout/reporters/progress_reporter.rb +47 -22
  32. data/lib/tapout/reporters/runtime_reporter.rb +223 -0
  33. data/lib/tapout/reporters/tap_reporter.rb +1 -1
  34. data/lib/tapout/reporters/turn_reporter.rb +26 -65
  35. data/lib/tapout/version.rb +2 -2
  36. metadata +34 -19
  37. data/test/unit/test-progressbar.rb +0 -5
@@ -1,32 +1,31 @@
1
1
  require 'tapout/core_ext'
2
2
  require 'tapout/reporters/abstract'
3
3
 
4
- module TapOut
4
+ module Tapout
5
5
 
6
6
  module Reporters
7
7
 
8
- # = Pretty Reporter (by Paydro)
8
+ # Pretty Reporter (by Paydro)
9
9
  #
10
10
  class PrettyReporter < Abstract
11
11
 
12
12
  #
13
13
  PADDING_SIZE = 4
14
14
 
15
- PASS = "PASS".ansi(:green)
16
- FAIL = "FAIL".ansi(:red)
17
- ERROR = "ERROR".ansi(:yellow)
15
+ PASS = " PASS".ansi(*Tapout.config.pass)
16
+ TODO = " TODO".ansi(*Tapout.config.todo)
17
+ OMIT = " OMIT".ansi(*Tapout.config.omit)
18
+ FAIL = " FAIL".ansi(*Tapout.config.fail)
19
+ ERROR = "ERROR".ansi(*Tapout.config.error)
18
20
 
19
21
  #
20
22
  def start_suite(suite)
21
- #old_sync, @@out.sync = @@out.sync, true if io.respond_to? :sync=
23
+ super(suite)
22
24
  @suite = suite
23
- @time = Time.now
24
- #@stdout = StringIO.new
25
- #@stderr = StringIO.new
26
25
  #files = suite.collect{ |s| s.file }.join(' ')
27
- #puts "Loaded suite #{suite.name}"
28
- puts "Suite seed: #{suite['seed']}" if suite['seed']
29
- puts "Started"
26
+ print "Running Suite" #{suite.name}
27
+ print " w/ Seed: #{suite['seed']}" if suite['seed']
28
+ puts
30
29
  end
31
30
 
32
31
  #
@@ -53,75 +52,83 @@ module TapOut
53
52
 
54
53
  #
55
54
  def pass(test)
55
+ return if config.minimal?
56
+
57
+ label = test['label'].to_s.ansi(*config.highlight)
58
+
56
59
  print pad_with_size("#{PASS}")
57
- print " #{test['label']}"
60
+ print " #{label}"
58
61
  print " (%.2fs) " % (Time.now - @test_time)
62
+
59
63
  #if message
60
64
  # message = test['source'].ansi(:magenta)
61
65
  # message = message.to_s.tabto(10)
62
66
  # puts(message)
63
67
  #end
68
+
69
+ # TODO: Is there any reason to show captured output for passing test?
70
+ #if captured_output?(test)
71
+ # puts captured_output(test).tabto(tabsize)
72
+ #end
64
73
  end
65
74
 
66
75
  #
67
- def fail(test)
68
- print pad_with_size("#{FAIL}")
69
- print " #{test['label']}"
76
+ def todo(test)
77
+ label = test['label'].to_s.ansi(*config.highlight)
78
+
79
+ print pad_with_size("#{TODO}")
80
+ print " #{label}"
70
81
  print " (%.2fs) " % (Time.now - @test_time)
82
+ end
83
+
84
+ #
85
+ def omit(test)
86
+ return if config.minimal?
87
+
88
+ label = test['label'].to_s.ansi(*config.highlight)
71
89
 
72
- #message = assertion.location[0] + "\n" + assertion.message #.gsub("\n","\n")
73
- #trace = MiniTest::filter_backtrace(report[:exception].backtrace).first
90
+ print pad_with_size("#{OMIT}")
91
+ print " #{label}"
92
+ print " (%.2fs) " % (Time.now - @test_time)
93
+ end
94
+
95
+ #
96
+ def fail(test)
97
+ label = test['label'].to_s.ansi(*config.highlight)
74
98
 
75
- message = test['exception']['message']
99
+ print pad_with_size("#{FAIL}")
100
+ print " #{label}"
101
+ print " (%.2fs) " % (Time.now - @test_time)
76
102
 
77
- if bt = test['exception']['backtrace']
78
- _trace = clean_backtrace(bt)
79
- else
80
- _trace = []
81
- end
103
+ message = test['exception']['message'].to_s
82
104
 
83
- trace = _trace.shift
84
- depth = TapOut.trace || trace.size
85
105
  tabsize = 10
86
106
 
87
107
  puts
88
- #puts pad(message, tabsize)
89
108
  puts message.tabto(tabsize)
90
- puts trace.tabto(tabsize)
91
- puts _trace[0,depth].map{|l| l.tabto(tabsize) }.join("\n")
92
- #show_captured_output
109
+ puts backtrace_snippets(test).tabto(tabsize)
110
+
111
+ print captured_output(test).tabto(tabsize)
93
112
  end
94
113
 
95
114
  #
96
115
  def error(test)
116
+ label = test['label'].to_s.ansi(*config.highlight)
117
+
97
118
  print pad_with_size("#{ERROR}")
98
- print " #{test['label']}"
119
+ print " #{label}"
99
120
  print " (%.2fs) " % (Time.now - @test_time)
100
121
 
101
- #message = exception.to_s.split("\n")[2..-1].join("\n")
122
+ message = test['exception']['message'].to_s
102
123
 
103
- message = test['exception']['message']
104
-
105
- if bt = test['exception']['backtrace']
106
- _trace = clean_backtrace(bt)
107
- else
108
- _trace = filter_backtrace(bt)
109
- end
110
-
111
- trace = _trace.shift
112
- depth = TapOut.trace || trace.size
113
124
  tabsize = 10
114
125
 
115
126
  puts
116
- puts message.tabto(tabsize)
117
- puts trace.tabto(tabsize)
118
- puts _trace[0,depth].map{|l| l.tabto(tabsize) }.join("\n")
119
- end
127
+ puts message.tabto(tabsize) unless message.empty?
128
+ puts backtrace_snippets(test).tabto(tabsize)
120
129
 
121
- # TODO: skip support
122
- #def skip
123
- # puts(pad_with_size("#{SKIP}"))
124
- #end
130
+ print captured_output(test).tabto(tabsize)
131
+ end
125
132
 
126
133
  #
127
134
  def finish_test(test)
@@ -132,31 +139,7 @@ module TapOut
132
139
  #$stderr = STDERR
133
140
  end
134
141
 
135
- =begin
136
- def show_captured_output
137
- show_captured_stdout
138
- show_captured_stderr
139
- end
140
-
141
- def show_captured_stdout
142
- @stdout.rewind
143
- return if @stdout.eof?
144
- STDOUT.puts(<<-output.tabto(8))
145
- \nSTDOUT:
146
- #{@stdout.read}
147
- output
148
- end
149
-
150
- def show_captured_stderr
151
- @stderr.rewind
152
- return if @stderr.eof?
153
- STDOUT.puts(<<-output.tabto(8))
154
- \nSTDERR:
155
- #{@stderr.read}
156
- output
157
- end
158
- =end
159
-
142
+ #
160
143
  def finish_case(kase)
161
144
  #if kase.size == 0
162
145
  # puts pad("(No Tests)")
@@ -167,22 +150,18 @@ module TapOut
167
150
  def finish_suite(final)
168
151
  #@@out.sync = old_sync if @@out.respond_to? :sync=
169
152
 
170
- total = final['counts']['total'] || 0
171
- failure = final['counts']['fail'] || 0
172
- error = final['counts']['error'] || 0
173
- skip = final['counts']['skip'] || 0
174
- omit = final['counts']['omit'] || 0
175
- #pass = total - failure - error
153
+ total, pass, fail, error, todo, omit = count_tally(final)
176
154
 
177
155
  puts
178
- puts "Finished in #{'%.6f' % (Time.now - @time)} seconds."
156
+ puts "Finished in #{'%.6f' % (Time.now - @start_time)} seconds."
179
157
  puts
180
158
 
181
- print "%d tests, " % total
159
+ print "%d tests: " % total
182
160
  #print "%d assertions, " % suite.count_assertions
183
- print ("%d failures" % failure).ansi(:red) + ', '
184
- print ("%d errors" % error).ansi(:yellow) + ', '
185
- print ("%d pending" % skip).ansi(:cyan)
161
+ print ("%d failures" % fail).ansi(*config.fail) + ', '
162
+ print ("%d errors" % error).ansi(*config.error) + ', '
163
+ print ("%d pending" % todo).ansi(*config.todo) + ', '
164
+ print ("%d omitted" % omit).ansi(*config.omit)
186
165
  puts
187
166
  end
188
167
 
@@ -1,7 +1,7 @@
1
1
  require 'tapout/reporters/abstract'
2
2
  require 'ansi/progressbar'
3
3
 
4
- module TapOut
4
+ module Tapout
5
5
 
6
6
  module Reporters
7
7
 
@@ -10,10 +10,18 @@ module TapOut
10
10
  #
11
11
  class ProgressReporter < Abstract
12
12
 
13
+ FAIL = "FAIL".ansi(*Tapout.config.fail)
14
+ ERROR = "ERROR".ansi(*Tapout.config.error)
15
+
16
+ #
13
17
  def start_suite(entry)
14
18
  @pbar = ::ANSI::Progressbar.new('Testing', entry['count'].to_i + 1)
15
- @pbar.style(:bar=>:green)
19
+ @pbar.style(:bar=>[:invert, *config.pass])
16
20
  @pbar.inc
21
+
22
+ @i = 0
23
+
24
+ super(entry)
17
25
  end
18
26
 
19
27
  def start_case(entry)
@@ -24,54 +32,65 @@ module TapOut
24
32
  #end
25
33
 
26
34
  def pass(entry)
35
+ @pbar.style(:bar=>config.pass)
27
36
  @pbar.inc
28
37
  end
29
38
 
30
39
  #
31
- def fail(entry)
40
+ def fail(test)
32
41
  @pbar.clear
33
42
 
34
- e = entry['exception']
43
+ err = test['exception']
35
44
 
45
+ label = test['label'].to_s
46
+ errclass = err['class']
47
+ message = err['message']
48
+ trace = backtrace_snippets(test)
49
+ capture = captured_output(err)
50
+
51
+ parts = [errclass, message, trace, capture].compact.reject{ |x| x.strip.empty? }
52
+
53
+ puts "#{@i+=1}. #{FAIL} #{label}"
36
54
  puts
37
- message = e['message'].strip
38
- message = message.ansi(:red)
39
- puts(message)
40
- puts "#{e['file']}:#{e['line']}"
41
- puts
42
- puts code_snippet(e)
55
+ puts parts.join("\n\n").tabto(4)
43
56
  puts
44
57
 
45
- @pbar.style(:bar=>:red)
58
+ @pbar.style(:bar=>config.fail)
46
59
  @pbar.inc
47
60
  end
48
61
 
49
62
  #
50
- def error(entry) #message=nil)
63
+ def error(test)
51
64
  @pbar.clear
52
65
 
53
- e = entry['exception']
66
+ err = test['exception']
54
67
 
68
+ label = test['label'].to_s
69
+ errclass = err['class']
70
+ message = err['message']
71
+ trace = backtrace_snippets(test)
72
+ capture = captured_output(err)
73
+
74
+ parts = [errclass, message, trace, capture].compact.reject{ |x| x.strip.empty? }
75
+
76
+ puts "#{@i+=1}. #{ERROR} #{label}"
55
77
  puts
56
- message = [e['class'], e['message']].compact.join(': ').strip
57
- message = message.ansi(:red)
58
- puts(message)
59
- puts "#{e['file']}:#{e['line']}"
60
- puts
61
- puts code_snippet(e)
78
+ puts parts.join("\n\n").tabto(4)
62
79
  puts
63
80
 
64
- @pbar.style(:bar=>:yellow)
81
+ @pbar.style(:bar=>config.error)
65
82
  @pbar.inc
66
83
  end
67
84
 
68
85
  #
69
- def omit(entry)
86
+ def todo(entry)
87
+ @pbar.style(:bar=>config.todo)
70
88
  @pbar.inc
71
89
  end
72
90
 
73
91
  #
74
- def skip(entry)
92
+ def omit(entry)
93
+ @pbar.style(:bar=>config.omit)
75
94
  @pbar.inc
76
95
  end
77
96
 
@@ -79,7 +98,13 @@ module TapOut
79
98
  #end
80
99
 
81
100
  def finish_suite(entry)
101
+ total, pass, fail, error, todo, omit = count_tally(entry)
102
+
103
+ @pbar.style(:bar=>config.pass) if pass > 0
104
+ @pbar.style(:bar=>config.error) if error > 0
105
+ @pbar.style(:bar=>config.fail) if fail > 0
82
106
  @pbar.finish
107
+
83
108
  #post_report(entry)
84
109
  puts
85
110
  puts tally_message(entry)
@@ -0,0 +1,223 @@
1
+ require 'tapout/core_ext'
2
+ require 'tapout/reporters/abstract'
3
+
4
+ module Tapout
5
+
6
+ module Reporters
7
+
8
+ #
9
+ #
10
+ class RuntimeReporter < Abstract
11
+
12
+ #
13
+ PADDING_SIZE = 4
14
+
15
+ #
16
+ TABSIZE = 4
17
+
18
+ # TODO: Fix ANSI for this
19
+ WIDTH = `tput cols`.to_i - 1 #::ANSI::Terminal.terminal_width || ENV['COLUMNS'].to_i
20
+
21
+ PASS = " PASS "
22
+ SKIP = " TODO "
23
+ OMIT = " SKIP "
24
+ FAIL = " FAIL "
25
+ ERROR = " ERROR "
26
+
27
+ #
28
+ def start_suite(suite)
29
+ super(suite)
30
+
31
+ @suite = suite
32
+ @count = 0
33
+ @index = 0
34
+
35
+ @suite_size = suite['count'].to_i
36
+ @case_stack = []
37
+
38
+ # pad for index based on how big the index number will get
39
+ @index_pad = @suite_size.zero? ? '' : @suite_size.to_s.size
40
+
41
+ #files = suite['files'].collect{ |s| s.file }.join(' ')
42
+
43
+ print "Started Suite (#{@suite_size})" ##{suite.name}"
44
+ print " w/ Seed: #{suite['seed']}" if suite['seed']
45
+ puts
46
+ end
47
+
48
+ #
49
+ def start_case(kase)
50
+ #return if kase.size == 0 # TODO: Don't have size yet?
51
+ last = @case_stack.pop
52
+ while last
53
+ break if last['level'].to_i <= kase['level'].to_i
54
+ last = @case_stack.pop
55
+ end
56
+
57
+ @case_stack << kase
58
+ end
59
+
60
+ #
61
+ def start_test(test)
62
+ @test_time = Time.now
63
+ @test = test
64
+ @count = @count + 1
65
+ end
66
+
67
+ # TODO: Only show if in verbose mode.
68
+ def pass(test)
69
+ stamp_it(test, PASS, :green) unless config.minimal?
70
+
71
+ #if message
72
+ # message = test['source'].ansi(:magenta)
73
+ # message = message.to_s.tabto(10)
74
+ # puts(message)
75
+ #end
76
+
77
+ # TODO: Is there any reason to show captured output for passing test?
78
+ #if captured_output?(test)
79
+ # puts captured_output(test).tabto(TABSIZE)
80
+ #end
81
+ end
82
+
83
+ #
84
+ def skip(test)
85
+ stamp_it(test, SKIP, :cyan) #unless config.minimal?
86
+ end
87
+
88
+ #
89
+ def omit(test)
90
+ stamp_it(test, OMIT, :blue) unless config.minimal?
91
+ end
92
+
93
+ #
94
+ def fail(test)
95
+ stamp_it(test, FAIL, :red)
96
+
97
+ #message = assertion.location[0] + "\n" + assertion.message #.gsub("\n","\n")
98
+ #trace = MiniTest::filter_backtrace(report[:exception].backtrace).first
99
+
100
+ message = test['exception']['message']
101
+
102
+ puts
103
+ if message
104
+ puts
105
+ puts message.tabto(TABSIZE)
106
+ end
107
+ puts
108
+
109
+ puts backtrace_snippets(test).tabto(TABSIZE)
110
+
111
+ print captured_output(test).tabto(TABSIZE)
112
+ end
113
+
114
+ #
115
+ def error(test)
116
+ stamp_it(test, ERROR, :red)
117
+
118
+ message = test['exception']['message']
119
+
120
+ puts
121
+ if message && !message.empty?
122
+ puts
123
+ puts message.tabto(TABSIZE)
124
+ end
125
+ puts
126
+
127
+ puts backtrace_snippets(test).tabto(TABSIZE)
128
+
129
+ print captured_output(test).tabto(TABSIZE)
130
+ end
131
+
132
+ #
133
+ def finish_test(test)
134
+ puts unless config.minimal?
135
+ end
136
+
137
+ #
138
+ def finish_case(kase)
139
+ #if kase.size == 0
140
+ # puts pad("(No Tests)")
141
+ #end
142
+ end
143
+
144
+ #
145
+ def finish_suite(final)
146
+ #@@out.sync = old_sync if @@out.respond_to? :sync=
147
+
148
+ total, pass, fail, error, todo, omit = count_tally(final)
149
+
150
+ time, rate, avg = time_tally(final)
151
+
152
+ puts
153
+ puts "Finished in %.6f seconds. %.3f tests per second." % [time, rate]
154
+ puts
155
+
156
+ print ("%d tests: " % total)
157
+ #print "%d assertions, " % suite.count_assertions
158
+ print ("%d failures" % fail).ansi(*config.fail) + ', '
159
+ print ("%d errors" % error).ansi(*config.error) + ', '
160
+ print ("%d pending" % todo).ansi(*config.todo) + ', '
161
+ print ("%d omitted" % omit).ansi(*config.omit)
162
+ puts
163
+ end
164
+
165
+ private
166
+
167
+ #
168
+ def pad(str, size=PADDING_SIZE)
169
+ " " * size + str
170
+ end
171
+
172
+ #
173
+ def pad_with_size(str)
174
+ " " * (18 - str.size) + str
175
+ end
176
+
177
+ NOMINAL = []
178
+
179
+ #
180
+ def stamp_it(test, type, *color)
181
+ @index += 1
182
+
183
+ cases = @case_stack.map{ |k| k['label'] }.join(' ')
184
+ time = Time.now
185
+ delta = time - @test_time
186
+ #label = test['label']
187
+ label = [cases, test['label']].join(' ').strip
188
+
189
+ indexS = @index
190
+ prcntS = " %3s%% " % [@count * 100 / @suite_size]
191
+ ratioS = " #{@count}/#{@suite_size} "
192
+ deltaS = " %.6f " % [time - @test_time]
193
+ timeS = " " + duration(time - @start_time) #time.strftime(' %H:%M:%S.%L ')
194
+ typeS = type.to_s
195
+
196
+ width = WIDTH - (ratioS.size + prcntS.size + deltaS.size + timeS.size + indexS.size + typeS.size + 9)
197
+
198
+ typeS = typeS.ansi(*color)
199
+
200
+ prcntS = prcntS.ansi(*NOMINAL)
201
+ ratioS = ratioS.ansi(*NOMINAL)
202
+
203
+ if delta > 30
204
+ delteS = deltaS.ansi(:yellow)
205
+ elsif delta > 60
206
+ deltaS = deltaS.ansi(:red)
207
+ else
208
+ deltaS = deltaS.ansi(*NOMINAL)
209
+ end
210
+
211
+ timeS = timeS.ansi(*NOMINAL)
212
+
213
+ stuff = [indexS, typeS, label.ansi(:bold), ratioS, prcntS, deltaS, timeS]
214
+
215
+ print " %#{@index_pad}d |%s| %-#{width}s %s|%s|%s|%s" % stuff
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+
222
+ end
223
+