tapout 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ require 'tapout/reporters/abstract'
2
+
3
+ module TapOut::Reporters
4
+
5
+ # Traditional dot progress reporter.
6
+ class Dotprogress < Abstract
7
+
8
+ #
9
+ def start_suite(entry)
10
+ @start_time = Time.now
11
+ $stdout.puts "Started\n"
12
+ end
13
+
14
+ #
15
+ def pass(entry)
16
+ $stdout.print '.'
17
+ $stdout.flush
18
+ super(entry)
19
+ end
20
+
21
+ #
22
+ def fail(entry)
23
+ $stdout.print 'F'.ansi(:red)
24
+ $stdout.flush
25
+ super(entry)
26
+ end
27
+
28
+ #
29
+ def err(entry)
30
+ $stdout.print 'E'.ansi(:yellow)
31
+ $stdout.flush
32
+ super(entry)
33
+ end
34
+
35
+ #
36
+ def finish_suite(entry)
37
+ $stdout.puts "\n\n"
38
+
39
+ i = 1
40
+
41
+ @failed.each do |e|
42
+ #backtrace = clean_backtrace(exception.backtrace)
43
+ $stdout.puts "#{i}. " + (e['label']).ansi(:red)
44
+ $stdout.puts
45
+ $stdout.puts " #{e['message']}"
46
+ $stdout.puts " #{e['file']}:#{e['line']}" #+ backtrace[0]
47
+ $stdout.puts code_snippet(e)
48
+ $stdout.puts
49
+ i += 1
50
+ end
51
+
52
+ @raised.each do |e|
53
+ #backtrace = clean_backtrace(exception.backtrace)
54
+ $stdout.puts "#{i}. " + (e['label']).ansi(:yellow)
55
+ $stdout.puts
56
+ $stdout.puts " #{e['message']}"
57
+ $stdout.puts " #{e['file']}:#{e['line']}" #+ backtrace[0..2].join(" \n")
58
+ $stdout.puts code_snippet(e)
59
+ $stdout.puts
60
+ i += 1
61
+ end
62
+
63
+ $stdout.puts "Finished in #{Time.now - @start_time}s"
64
+ $stdout.puts tally(entry)
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,89 @@
1
+ require 'tapout/reporters/abstract'
2
+
3
+ require 'ansi/progressbar'
4
+
5
+ module TapOut
6
+
7
+ module Reporters
8
+
9
+ # The progressbar report format utilises a progress bar to indicate
10
+ # elapsed progress.
11
+ class Progressbar < Abstract
12
+
13
+ def start_suite(entry)
14
+ @pbar = ::ANSI::Progressbar.new('Testing', entry['count'].to_i + 1)
15
+ @pbar.style(:bar=>:green)
16
+ @pbar.inc
17
+ end
18
+
19
+ def start_case(entry)
20
+ end
21
+
22
+ #def test(entry)
23
+ # #@pbar.inc
24
+ #end
25
+
26
+ def pass(entry)
27
+ @pbar.inc
28
+ end
29
+
30
+ #
31
+ def fail(entry)
32
+ @pbar.clear
33
+
34
+ puts
35
+ message = entry['message'].strip
36
+ message = message.ansi(:red)
37
+ puts(message)
38
+ puts "#{entry['file']}:#{entry['line']}"
39
+ puts
40
+ puts code_snippet(entry)
41
+ puts
42
+
43
+ @pbar.style(:bar=>:red)
44
+ @pbar.inc
45
+ end
46
+
47
+ #
48
+ def error(message=nil)
49
+ @pbar.clear
50
+
51
+ puts
52
+ message = entry['message'].strip
53
+ message = message.ansi(:red)
54
+ puts(message)
55
+ puts "#{entry['file']}:#{entry['line']}"
56
+ puts
57
+ puts code_snippet(entry)
58
+ puts
59
+
60
+ @pbar.style(:bar=>:yellow)
61
+ @pbar.inc
62
+ end
63
+
64
+ #
65
+ def omit(entry)
66
+ @pbar.inc
67
+ end
68
+
69
+ #
70
+ def skip(entry)
71
+ @pbar.inc
72
+ end
73
+
74
+ #def finish_case(kase)
75
+ #end
76
+
77
+ def finish_suite(entry)
78
+ @pbar.finish
79
+ #post_report(entry)
80
+ puts
81
+ puts tally(entry)
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
@@ -0,0 +1,80 @@
1
+ require 'tapout/reporters/abstract'
2
+
3
+ module TapOut::Reporters
4
+
5
+ # Tap Reporter
6
+ class Tap < Abstract
7
+
8
+ #
9
+ def start_suite(entry)
10
+ @start = Time.now
11
+ @i = 0
12
+ #n = 0
13
+ #suite.concerns.each{ |f| f.concerns.each { |s| n += s.ok.size } }
14
+ puts "1..#{entry['count']}"
15
+ end
16
+
17
+ #
18
+ def start_case(entry)
19
+ #$stdout.puts concern.label.ansi(:bold)
20
+ end
21
+
22
+ #
23
+ #def start_ok(ok)
24
+ # @i += 1
25
+ #end
26
+
27
+ #
28
+ def pass(entry)
29
+ super(entry)
30
+
31
+ #desc = entry['message'] #+ " #{ok.arguments.inspect}"
32
+
33
+ puts "ok #{entry['index']} - #{entry['label']}"
34
+ end
35
+
36
+ #
37
+ def fail(entry)
38
+ super(entry)
39
+
40
+ #desc = #ok.concern.label + " #{ok.arguments.inspect}"
41
+
42
+ body = []
43
+ body << "FAIL #{entry['file']}:#{entry['line']}" #clean_backtrace(exception.backtrace)[0]
44
+ body << "#{entry['message']}"
45
+ body << code_snippet(entry)
46
+ body = body.join("\n").gsub(/^/, ' # ')
47
+
48
+ puts "not ok #{entry['index']} - #{entry['label']}"
49
+ puts body
50
+ end
51
+
52
+ #
53
+ def error(entry)
54
+ super(entry)
55
+
56
+ #desc = ok.concern.label + " #{ok.arguments.inspect}"
57
+
58
+ body = []
59
+ body << "ERROR #{entry['file']}:#{entry['line']}" #clean_backtrace(exception.backtrace)[0..2].join(" \n")
60
+ #body << "#{exception.class}: #{entry['message']}"
61
+ body << "#{entry['message']}"
62
+ body << ""
63
+ body << code_snippet(entry)
64
+ body << ""
65
+ body = body.join("\n").gsub(/^/, ' # ')
66
+
67
+ puts "not ok #{entry['index']} - #{entry['label']}"
68
+ puts body
69
+ end
70
+
71
+ #
72
+ #def pending(ok, exception)
73
+ # puts "not ok #{@i} - #{unit.description}"
74
+ # puts " PENDING"
75
+ # puts " #{exception.backtrace[1]}"
76
+ #end
77
+ end
78
+
79
+ end
80
+
@@ -0,0 +1,54 @@
1
+ require 'tapout/reporters/abstract'
2
+
3
+ module TapOut::Reporters
4
+
5
+ # Verbose reporter.
6
+ class Verbose < Abstract
7
+
8
+ #
9
+ def start_suite(entry)
10
+ @start_time = Time.now
11
+ end
12
+
13
+ #
14
+ def start_case(entry)
15
+ $stdout.puts entry['label'].ansi(:bold)
16
+ end
17
+
18
+ def pass(entry)
19
+ super(entry)
20
+ $stdout.puts "* " + entry['label'].ansi(:green) + " #{entry['source']}"
21
+ end
22
+
23
+ def fail(entry)
24
+ super(entry)
25
+ $stdout.puts "* " + entry['label'].ansi(:red) + " #{entry['source']}"
26
+ $stdout.puts
27
+ $stdout.puts " #{entry['message']}"
28
+ #$stdout.puts " " + ok.caller #clean_backtrace(exception.backtrace)[0]
29
+ $stdout.puts
30
+ $stdout.puts code_snippet(entry)
31
+ $stdout.puts
32
+ end
33
+
34
+ def err(entry)
35
+ super(entry)
36
+ $stdout.puts "* " + entry['label'].ansi(:yellow) + " #{entry['source']}"
37
+ $stdout.puts
38
+ $stdout.puts " #{entry['message']}" # error class?
39
+ #$stdout.puts " " + ok.caller #clean_backtrace(exception.backtrace)[0..2].join(" \n")
40
+ $stdout.puts
41
+ $stdout.puts code_snippet(entry)
42
+ $stdout.puts
43
+ end
44
+
45
+ #
46
+ def finish_suite(entry)
47
+ #$stderr.puts
48
+ $stdout.print tally(entry)
49
+ $stdout.puts " [%0.4fs] " % [Time.now - @start_time]
50
+ end
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,168 @@
1
+ require 'tapout/version'
2
+
3
+ module TapOut
4
+
5
+ # The TAP Legacy Adapter transforms traditional TAP format to
6
+ # modern TAP-Y format.
7
+ #
8
+ # NOTE: This is still a work in progress.
9
+ #
10
+ # TODO: Add support for TAP-J.
11
+
12
+ class TAPLegacyAdapter
13
+
14
+ #
15
+ def initialize(input)
16
+ @input = input
17
+ reset
18
+ end
19
+
20
+ # Reset state.
21
+ def reset
22
+ @head = false
23
+ @state = nil
24
+ @entries = []
25
+ @cache = []
26
+ end
27
+
28
+ # We need to keep an internal list of all entries
29
+ # in order to create a proper footer.
30
+ attr :entries
31
+
32
+ # Convert input stream to TAP-Y string.
33
+ def to_s
34
+ self | ""
35
+ end
36
+
37
+ # Route stream to an array of entires.
38
+ def to_a
39
+ self | []
40
+ end
41
+
42
+ # Convert input stream to TAP-Y and *pipe* to +output+ stream.
43
+ def |(output)
44
+ @out = output
45
+ reset
46
+ while line = @input.gets
47
+ self << line
48
+ end
49
+ self << nil
50
+ return @out
51
+ end
52
+
53
+ #
54
+ def <<(line)
55
+ case line
56
+ when nil
57
+ parse(@cache)
58
+ @state = :footer
59
+ finish
60
+ when /^\d+\.\.\d+/
61
+ #parse(@cache) if @state != :plan
62
+ return if @head
63
+ @head = true
64
+ @state = :plan
65
+ @cache << line
66
+ when /^ok/
67
+ parse(@cache) #if @state != :ok
68
+ @state = :ok
69
+ @cache << line
70
+ when /^not\ ok/
71
+ parse(@cache) #if @state != :not_ok
72
+ @state = :not_ok
73
+ @cache << line
74
+ when /^\#/
75
+ parse(@cache) if @state != :comment
76
+ @state = :comment
77
+ @cache << line
78
+ else
79
+ @cache << line
80
+ end
81
+ end
82
+
83
+ #
84
+ def parse(cache)
85
+ case @state
86
+ when nil
87
+ return
88
+ when :plan
89
+ line = cache[0]
90
+ md = /^(\d+)\.\.(\d+)\s*$/.match(line)
91
+ count = md[2].to_i - md[1].to_i + 1
92
+ entry = {'count'=> count, 'type'=>'header', 'version'=>TAP_Y_VERSION}
93
+ when :ok
94
+ line = cache[0]
95
+ md = /^ok\s+(\d+)\s*\-?\s*(.*?)($|#)/.match(line)
96
+ entry = {'type'=>'test','status'=>'pass','index'=>md[1].to_i, 'label'=>md[2]}
97
+ when :not_ok
98
+ line = cache[0]
99
+ yaml = cache[1..-2].join('')
100
+ data = YAML.load(yaml)
101
+ md = /^not ok\s+(\d+)\s*\-?\s*(.*?)($|#)/.match(line)
102
+ entry = convert_not_ok(md[1], md[2], data)
103
+ when :comment
104
+ desc = cache.map{ |c| c.sub(/^\#\s{0,1}/, '') }.join("\n")
105
+ entry = {'type'=>'note', 'description'=>desc.rstrip}
106
+ end
107
+ output(entry)
108
+ @cache = []
109
+ end
110
+
111
+ #
112
+ def output(entry)
113
+ @entries << entry
114
+ case @out
115
+ when String, IO
116
+ @out << entry.to_yaml
117
+ else
118
+ @out << entry
119
+ end
120
+ end
121
+
122
+ #
123
+ def finish
124
+ output(make_footer)
125
+ case @out
126
+ when String, IO
127
+ @out << '...'
128
+ end
129
+ end
130
+
131
+ private
132
+
133
+ #
134
+ def convert_not_ok(number, label, metainfo)
135
+ entry = {}
136
+ entry['type'] = 'test'
137
+ entry['status'] = 'fail'
138
+ entry['index'] = number.to_i
139
+ entry['label'] = label
140
+ if metainfo
141
+ entry['file'] = metainfo['file']
142
+ entry['line'] = metainfo['line']
143
+ entry['expected'] = metainfo['wanted']
144
+ entry['returned'] = metainfo['found']
145
+ entry['description'] = metainfo['description']
146
+ entry['source'] = metainfo['raw_test']
147
+ entry['extra'] = metainfo['extensions']
148
+ end
149
+ entry
150
+ end
151
+
152
+ #
153
+ def make_footer
154
+ groups = @entries.group_by{ |e| e['status'] }
155
+
156
+ entry = {}
157
+ entry['count'] = @count
158
+ entry['type'] = 'footer'
159
+ entry['tally'] = {
160
+ 'pass' => (groups['pass'] || []).size,
161
+ 'fail' => (groups['fail'] || []).size
162
+ }
163
+ entry
164
+ end
165
+
166
+ end
167
+
168
+ end