jemc-reporter 0.1.1

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 (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/jemc/reporter.rb +262 -0
  3. metadata +100 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 42a6eeb8aa5c5298010b82b4a8779df07decba0b
4
+ data.tar.gz: 0968f1f538660c5e398257533680ac8fd61a7f4a
5
+ SHA512:
6
+ metadata.gz: 88786f897e0fc75efa9fd054b3358904754da93c549e58bd1810ba261861ea7ce69cf010f40f20a3be8af07ebbaefd1a136e07efc9a0da5f0c38389a728f5519
7
+ data.tar.gz: 62ee8bddee4166470e53fc8a616e62088622fc1269ea11e160fe82090f033f2ed773236d2608c5519530a08cb5cf5cbd796d3afa63aa61520ba665cd59cf84bc
@@ -0,0 +1,262 @@
1
+ gem 'minitest-reporters'
2
+ require 'minitest/reporters'
3
+ gem 'ansi'
4
+ require 'ansi/code'
5
+
6
+ module JEMC; class Reporter
7
+ include Minitest::Reporter
8
+
9
+ attr_accessor :color, :columns, :max_tests
10
+
11
+ def initialize(options = {})
12
+ # @detailed_skip = options.fetch(:detailed_skip, true)
13
+ # @slow_count = options.fetch(:slow_count, 0)
14
+ # @slow_suite_count = options.fetch(:slow_suite_count, 0)
15
+ # @fast_fail = options.fetch(:fast_fail, false)
16
+ # @test_times = []
17
+ # @suite_times = []
18
+ @color = options.fetch(:color) do
19
+ output.tty? && (
20
+ ENV["TERM"] =~ /^screen|color/ ||
21
+ ENV["EMACS"] == "t"
22
+ )
23
+ end
24
+
25
+ @columns = ENV['COLUMNS'] || `tput cols`.to_i || 80
26
+
27
+ end
28
+
29
+ def before_suites(suites, type)
30
+ puts
31
+
32
+ self.max_tests = suites.map{|x| x.test_methods.size}.max
33
+
34
+ for suite in suites do
35
+
36
+ class << suite
37
+ attr_accessor :reporter
38
+ attr_accessor :tests
39
+ end
40
+
41
+ suite.reporter = self
42
+
43
+ suite.tests = Hash.new
44
+ suite.tests[:pass] = []
45
+ suite.tests[:fail] = []
46
+ suite.tests[:error] = []
47
+ suite.tests[:skip] = []
48
+
49
+ def suite.suffix
50
+ dig = reporter.max_tests.to_s.size
51
+ groups = [:pass, :fail, :error]
52
+ colors = [:green,:red,:magenta]
53
+
54
+ (' ' + groups
55
+ .map { |x| self.tests[x].size }
56
+ .map { |x,e| (x > 0) ? ("%0#{dig}d" % x) : dig.times.map{' '}.join }
57
+ .each_with_index
58
+ .map { |x,i| reporter.send(colors[i], x) }
59
+ .join('/'))
60
+ end
61
+
62
+ def suite.suffix_size
63
+ ANSI::Code.uncolor(self.suffix).size
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ def before_suite(suite)
71
+ return if suite.test_methods.size <= 0
72
+ length = @columns-suite.test_methods.size-suite.suffix_size
73
+ print str_fit(suite.name, length-1)+' '
74
+
75
+ end
76
+
77
+ def after_suite(suite)
78
+ return if suite.test_methods.size <= 0
79
+ puts suite.suffix
80
+ suite.tests[:skip].each { |x| skipped_show(*x) }
81
+ suite.tests[:fail].each { |x| failure_show(*x) }
82
+ suite.tests[:error].each { |x| error_show(*x) }
83
+ end
84
+
85
+ def after_suites(suites, type)
86
+ puts
87
+ puts '%d tests, %d assertions, %d failures, %d errors, %d skips' %
88
+ [runner.test_count, runner.assertion_count, \
89
+ runner.failures, runner.errors, runner.skips]
90
+ end
91
+
92
+ def pass(suite, test, test_runner)
93
+ print green('.')
94
+ suite.tests[:pass] << [test, test_runner.exception]
95
+ end
96
+
97
+ def skip(suite, test, test_runner)
98
+ print blue('s')
99
+ suite.tests[:skip] << [test, test_runner.exception]
100
+ end
101
+
102
+ def failure(suite, test, test_runner)
103
+ print red('F')
104
+ suite.tests[:fail] << [test, test_runner.exception]
105
+ end
106
+
107
+ def error(suite, test, test_runner)
108
+ print magenta('E')
109
+ suite.tests[:error] << [test, test_runner.exception]
110
+ end
111
+
112
+ def skipped_show(test, exc)
113
+ pre = black('>')+blue('>')+bold(blue('s'))+' '
114
+ pre_size = ANSI::Code.uncolor(pre).size
115
+ puts pre+blue(str_fit(test, @columns-pre_size))
116
+ end
117
+
118
+ def failure_show(test, exc)
119
+ pre = black('>')+red('>')+bold(red('F'))+' '
120
+ pre_size = ANSI::Code.uncolor(pre).size
121
+ puts pre+red(str_fit(test, @columns-pre_size))
122
+
123
+ exc.backtrace.unshift runner.location(exc)+":in `'"
124
+ puts backtrace(exc)
125
+
126
+ puts yellow(exc)
127
+
128
+ puts
129
+ end
130
+
131
+ def error_show(test, exc)
132
+ pre = black('>')+magenta('>')+bold(magenta('E'))+' '
133
+ pre_size = ANSI::Code.uncolor(pre).size
134
+ puts pre+magenta(str_fit(test, @columns-pre_size))
135
+
136
+ puts backtrace(exc)
137
+
138
+ puts yellow(exc)
139
+
140
+ puts
141
+ end
142
+
143
+ def backtrace(exception)
144
+ index = exception.backtrace \
145
+ .find_index {|x| x=~/\/minitest\/(?=[^\/]*$).*['`]run['`]$/}
146
+
147
+ exception.backtrace.map do |line|
148
+ m = line.match(/(.*)(?<=\/)([^\:\/]*):(\d+)(?=:in):in ['`](.*)['`]/)
149
+
150
+ str_fit(m[1], columns/3, :keep=>:tail, :align=>:right) \
151
+ + white(str_fit(m[2], columns/3-m[3].size-1, :keep=>:head))+':'+white(m[3]) \
152
+ + bold(cyan(str_fit(' '+m[4], (columns-2*(columns/3)),
153
+ :keep=>:head, :align=>:right))) \
154
+ end[0...index].reverse
155
+ end
156
+
157
+ # [:black, :red, :green, :yellow, :blue, :magenta, :cyan, :white]
158
+ for color in ANSI::Code.colors+[:bold]
159
+ eval <<-CODE
160
+
161
+ def #{color}(string)
162
+ @color ? ANSI::Code.#{color}(string) : string
163
+ end
164
+
165
+ CODE
166
+ end
167
+
168
+ # Pad or truncate a string intelligently
169
+ def str_fit(str, length, keep: :both, align: :left, pad:' ', mid:'...')
170
+
171
+ str = str.to_s
172
+
173
+ raise ArgumentError, "Keyword argument :keep must be :head, :tail, or :both."\
174
+ unless [:head, :tail, :both].include? keep
175
+
176
+ raise ArgumentError, "Keyword argument :align must be :left, :right, or :center."\
177
+ unless [:left, :right, :center].include? align
178
+
179
+ length = [0,length].max
180
+ diff = length - str.size
181
+
182
+ # Return padded string if length is the same or to be increased
183
+
184
+ if diff>=0
185
+ padstr = diff.times.map{pad}.join[0..diff]
186
+ case align
187
+ when :left
188
+ return str + padstr
189
+ when :right
190
+ return padstr + str
191
+ when :center
192
+
193
+ return padstr[0...(padstr.size/2)] + str + padstr[0...(padstr.size-(padstr.size/2))]
194
+ end
195
+ end
196
+
197
+ # Return truncated midstring if length is the same or smaller than mid's size
198
+ return mid[0...length] if length<=mid.size
199
+
200
+ boundary_re = /((?<=[a-zA-Z])(?![a-zA-Z]))|((?<![a-zA-Z])(?=[a-zA-Z]))/
201
+
202
+ indices = str.to_enum(:scan, boundary_re).map{$`.size}-[0,str.size]
203
+ # p indices
204
+
205
+ # Collect pairs of indices closest to desired diff
206
+ nearest = [[str.size,0,str.size]]
207
+ for x in indices
208
+ x = 0 if keep==:tail
209
+ for y in indices
210
+ y = str.size if keep==:head
211
+ if (y>x)
212
+ candidate = [(y-x+diff-mid.size).abs,(y-x+diff-mid.size),x,y]
213
+
214
+ if nearest[0][0]> candidate[0]
215
+ nearest = [candidate]
216
+ elsif nearest[0][0]==candidate[0]
217
+ nearest << candidate
218
+ end
219
+
220
+ end
221
+ end
222
+ end
223
+ nearest.uniq!
224
+
225
+ # Choose the most appropriate pair of indices from nearest
226
+ case keep
227
+ when :both
228
+ nearest.sort!{|a,b| (str.size-(a[2]+a[3])).abs <=> (str.size-(b[2]+b[3])).abs}
229
+ when :tail
230
+ nearest.reverse!
231
+ end
232
+ nearest = nearest.first
233
+
234
+ if nearest[0]!=0
235
+ case keep
236
+ when :both
237
+ nearest[2]+=(nearest[1]/2)
238
+ nearest[3]-=(nearest[1]-(nearest[1]/2))
239
+ when :head
240
+ nearest[2]+=nearest[1]
241
+ when :tail
242
+ nearest[3]-=nearest[1]
243
+ end
244
+ if nearest[2]<0
245
+ nearest[2]+=(0-nearest[2])
246
+ nearest[3]+=(0-nearest[2])
247
+ elsif nearest[3]>str.size
248
+ nearest[3]+=(str.size-nearest[2])
249
+ nearest[3]+=(str.size-nearest[2])
250
+ end
251
+
252
+ nearest[1]=(y-x+diff-mid.size)
253
+ nearest[0]=nearest[1].abs
254
+ end
255
+
256
+ return str[0...nearest[2]]+mid+str[nearest[3]..str.size]
257
+
258
+ end
259
+
260
+ end end
261
+
262
+ Minitest::Reporters.use! JEMC::Reporter.new
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jemc-reporter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Joe McIlvain
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '4.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest-reporters
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ansi
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A custom minitest reporter made to my personal aesthetic specifications.
70
+ email: joe.eli.mac@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/jemc/reporter.rb
76
+ homepage: https://github.com/jemc/jemc-reporter/
77
+ licenses:
78
+ - 'Copyright (c) Joe McIlvain. All rights reserved '
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.0.3
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: jemc-reporter
100
+ test_files: []