test-unit-runner-html 0.0.2

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/History.txt ADDED
@@ -0,0 +1,11 @@
1
+ === 0.0.1 / 2012-01-12
2
+
3
+ * Fixes & Improvements
4
+ * New config parameters:
5
+ - report_dir - Where place reports
6
+ - same-report - Overwrites the same report file if set in true (default),
7
+ generate new file in each run ({timestamp}_{output_file option}) otherwise.
8
+
9
+ === 0.0.1 / 2011-11-29
10
+
11
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/test/unit/runner/html.rb
6
+ lib/test/unit/ui/html/testrunner.rb
data/README.txt ADDED
@@ -0,0 +1,25 @@
1
+ = Test::Unit::Runner::HTML
2
+
3
+ * http://rubyforge.org/projects/test-unit/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Test::Unit::Runner::HTML - Generates reports in HTML format.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * This provides "--runner=html" option to use HTML UI.
12
+
13
+ == INSTALL:
14
+
15
+ * sudo gem install test-unit-runner-html
16
+
17
+ == USAGE:
18
+
19
+ require 'test/unit/runner/html'
20
+
21
+ == LICENSE:
22
+
23
+ (The Ruby License)
24
+
25
+ This software is distributed under the same terms as ruby.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ gem 'test-unit'
5
+ require 'hoe'
6
+ require './lib/test/unit/runner/html'
7
+
8
+ Test::Unit.run = true
9
+
10
+ version = Test::Unit::Runner::HTML::VERSION
11
+ ENV["VERSION"] = version
12
+ Hoe.new('test-unit-runner-html', version) do |p|
13
+ p.developer('Ilya Cherepanov', 'ilya.cherepanov@nevosoft.ru')
14
+
15
+ p.rubyforge_name = "test-unit"
16
+ end
17
+
18
+ task :tag do
19
+ message = "Released Test::Unit::Runner::HTML #{version}!"
20
+ base = "svn+ssh://#{ENV['USER']}@rubyforge.org/var/svn/test-unit/extensions/test-unit-runner-html/"
21
+ sh 'svn', 'copy', '-m', message, "#{base}trunk", "#{base}tags/#{version}"
22
+ end
23
+
24
+ # vim: syntax=Ruby
@@ -0,0 +1,46 @@
1
+ module Test
2
+ module Unit
3
+ AutoRunner.register_runner(:html) do |auto_runner|
4
+ require 'test/unit/ui/html/testrunner'
5
+ Test::Unit::UI::HTML::TestRunner
6
+ end
7
+
8
+ AutoRunner.setup_option do |auto_runner, opts|
9
+ opts.on("--html-report=FILE", String,
10
+ "Outputs to file FILE") do |file|
11
+ auto_runner.runner_options[:output_file] = file
12
+ end
13
+ report_options = [
14
+ ["-", false],
15
+ ["no", false],
16
+ ["false", false],
17
+ ["+", true],
18
+ ["yes", true],
19
+ ["true", true],
20
+ ]
21
+ opts.on("--same-report=FILE", report_options,
22
+ "Write report in the same file if set, in filename_timestamp.html otherwise.",
23
+ "(default is false)") do |val|
24
+ val = false if val.nil?
25
+ auto_runner.runner_options[:same_report] = val
26
+ end
27
+ opts.on("--report-dir=DIR", report_options,
28
+ "Reports directory") do |val|
29
+ Dir.mkdir_p val unless Dir.exist? val
30
+ unless val =~ /[\\\/]$/
31
+ val =+ File.PATH_SEPARATOR
32
+ end
33
+ auto_runner.runner_options[:report_dir] = val
34
+ end
35
+ end
36
+ end
37
+ end
38
+ module Test
39
+ module Unit
40
+ module Assertions
41
+ def assert_fail msg
42
+ assert false, build_message(msg)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,343 @@
1
+ #--
2
+ #
3
+ # Author:: Ilya Cherepanov
4
+ # Copyright::
5
+ # * Copyright (c) 2011 Ilya Cherepanov <ilya.cherepanov@nevosoft.ru>
6
+ # * Copyright (c) 2011 Kouhei Sutou <kou@clear-code.com>
7
+ # License:: Ruby license.
8
+
9
+ # encode: utf-8
10
+
11
+ require 'erb'
12
+ require 'time'
13
+ require 'test/unit/ui/testrunner'
14
+ require 'test/unit/ui/testrunnermediator'
15
+
16
+ module Test
17
+ module Unit
18
+ module UI
19
+ module HTML
20
+
21
+ # Runs a Test::Unit::TestSuite and outputs HTML.
22
+ class TestRunner < UI::TestRunner
23
+ include ERB::Util
24
+ # Creates a new TestRunner for running the passed
25
+ # suite. :output option specifies where runner
26
+ # output should go to; defaults to STDOUT.
27
+ def initialize(suite, options={})
28
+ super
29
+ Dir.mkdir @options[:report_dir] unless Dir.exist? @options[:report_dir]
30
+ unless @options[:report_dir] =~ /[\\\/]$/
31
+ @options[:report_dir] = @options[:report_dir] + '/'
32
+ end
33
+ dir = @options[:report_dir] || ''
34
+ of = "#{Time.now.to_i.to_s}_#{@options[:output_file]}" if (@options[:output_file] && !@options[:same_report])
35
+ of ||= @options[:output_file]
36
+ @output = File.new(dir+of, "w") if of
37
+ @output ||= STDOUT
38
+ @already_outputted = false
39
+ @indent = 0
40
+ @top_level = true
41
+ @current_test = nil
42
+ @current_test_suite = nil
43
+ @already_outputted = false
44
+ @summary = []
45
+ @cur_suite = nil
46
+ @cur_suite_cases = []
47
+ @cur_case = nil
48
+ @cur_case_tests = []
49
+ @cur_test = nil
50
+ end
51
+
52
+ private
53
+ def attach_to_mediator
54
+ @mediator.add_listener(TestResult::PASS_ASSERTION,
55
+ &method(:result_pass_assertion))
56
+ @mediator.add_listener(TestResult::FAULT,
57
+ &method(:result_fault))
58
+ @mediator.add_listener(TestRunnerMediator::STARTED,
59
+ &method(:started))
60
+ @mediator.add_listener(TestRunnerMediator::FINISHED,
61
+ &method(:finished))
62
+ @mediator.add_listener(TestCase::STARTED_OBJECT,
63
+ &method(:test_started))
64
+ @mediator.add_listener(TestCase::FINISHED_OBJECT,
65
+ &method(:test_finished))
66
+ @mediator.add_listener(TestSuite::STARTED_OBJECT,
67
+ &method(:test_suite_started))
68
+ @mediator.add_listener(TestSuite::FINISHED_OBJECT,
69
+ &method(:test_suite_finished))
70
+ end
71
+
72
+ def store_test test
73
+ unless @already_outputted
74
+ @cur_test.started = test.start_time
75
+ @cur_test.elapsed = test.elapsed_time
76
+ @cur_test.passed = test.passed?
77
+ @cur_test.interrupted = test.interrupted?
78
+ @cur_test.status = @result.status
79
+
80
+ @cur_case_tests << @cur_test
81
+ @cur_test = []
82
+ @already_outputted = true
83
+ end
84
+ end
85
+
86
+ def store_case ca
87
+ @cur_case_tests.each do |t|
88
+ @cur_case << t
89
+ end
90
+ @cur_case.started = ca.start_time
91
+ @cur_case.elapsed = ca.elapsed_time
92
+ @cur_case.passed = ca.passed?
93
+ @cur_case.status = @result.status
94
+ @cur_suite_cases << @cur_case
95
+ @cur_case = []
96
+ @cur_case_tests = []
97
+ end
98
+
99
+ def store_suite suite
100
+ @cur_suite_cases.each do |c|
101
+ @cur_suite << c
102
+ end
103
+ @cur_suite.started = suite.start_time
104
+ @cur_suite.elapsed = suite.elapsed_time
105
+ @cur_suite.passed = suite.passed?
106
+ @cur_suite.status = @result.status
107
+ @cur_suite.result = @result
108
+ @summary << @cur_suite
109
+ @cur_suite_cases = []
110
+ @cur_suite = []
111
+ end
112
+
113
+ def started(result)
114
+ @result = result
115
+ end
116
+
117
+ def test_suite_started(suite)
118
+ @current_test_suite = suite
119
+
120
+ if suite.test_case.nil?
121
+ @cur_suite = ResultSuite.new suite.name
122
+ else
123
+ @cur_case = ResultCase.new suite.name
124
+ end
125
+ end
126
+
127
+ def test_started(test)
128
+ @already_outputted = false
129
+ @current_test = test
130
+ @cur_test = ResultTest.new test.name
131
+ end
132
+
133
+ def result_pass_assertion(result)
134
+ @cur_test.assertion
135
+ end
136
+
137
+ def result_fault(fault)
138
+ @cur_test << fault
139
+ store_test @current_test
140
+ end
141
+
142
+ def test_finished(test)
143
+ store_test test
144
+ @current_test = nil
145
+ end
146
+
147
+ def test_suite_finished(suite)
148
+ if suite.test_case.nil?
149
+ store_suite suite
150
+ else
151
+ store_case suite
152
+ end
153
+ @current_test_suite = nil
154
+ end
155
+
156
+ def finished(elapsed_time)
157
+ if $DEBUG
158
+ o = File.new 'debug.log', 'w'
159
+ o.puts YAML.dump @summary
160
+ end
161
+ head
162
+ @summary.each do |suite|
163
+ output_suite suite
164
+ end
165
+ footer
166
+ end
167
+
168
+ def output_suite suite
169
+ open_tag 'article', 'box suite rounded '+suite.status do
170
+ content '', 'div', 'light rounded'
171
+ content suite.name, 'div', 'name'
172
+ open_tag 'div', 'stats' do
173
+ content 'Started: '+suite.started.ctime.to_s, 'div', 'time'
174
+ content 'Elapsed: '+suite.elapsed.to_s, 'div', 'time'
175
+ content "#{suite.n_test} tests in #{suite.n_case} cases", 'div', 'num-info'
176
+ end
177
+ button suite.passed
178
+ open_tag 'section', 'more' do
179
+ suite.cases.each do |ca|
180
+ output_case ca
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ def output_case ca
187
+ open_tag 'article', 'box rounded case '+ca.status do
188
+ content '', 'div', 'light rounded'
189
+ content ca.name, 'div', 'name'
190
+ open_tag 'div', 'stats' do
191
+ content 'Started: '+ca.started.ctime.to_s, 'div', 'time'
192
+ content 'Elapsed: '+ca.elapsed.to_s, 'div', 'time'
193
+ content "#{ca.n_test} tests", 'div', 'num-info'
194
+ end
195
+ button ca.passed
196
+ open_tag 'section', 'more' do
197
+ ca.tests.each do |t|
198
+ output_test t
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ def output_test test
205
+ open_tag 'article', 'box rounded test '+test.status do
206
+ content '', 'div', 'light rounded'
207
+ content test.name, 'div', 'name'
208
+ open_tag 'div', 'stats' do
209
+ content 'Started: '+test.started.ctime.to_s, 'div', 'time'
210
+ content 'Elapsed: '+test.elapsed.to_s, 'div', 'time'
211
+ end
212
+ if !test.passed && !test.faults.nil? && !test.faults.empty?
213
+ button test.passed
214
+ open_tag 'section', 'more_test' do
215
+ test.faults.each do |f|
216
+ open_tag 'div', 'box error' do
217
+ file, line = f.location[0].scan( /(.*):(?!\/)(\d+)/)[0]
218
+ content f.message, 'div', 'message'
219
+ content 'in '+(File.basename file), 'div', 'file'
220
+ content 'on line # '+line.to_s, 'div', 'line'
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ def head
229
+ @output.puts "<!DOCTYPE html>
230
+ <html>
231
+ <head>
232
+ <meta charset='utf-8'>
233
+ <title>Test report created at #{Time.now.ctime}</title>
234
+ <link rel='stylesheet' type='text/css' href='css/main.css' />
235
+ <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js'></script>
236
+ <script type='text/javascript' src='js/main.js'></script>
237
+ </head>
238
+ <body>
239
+ <section class='container'>"
240
+ end
241
+
242
+ def footer
243
+ @output.puts " </section>
244
+ <footer>
245
+ <a href='#'>Link</a>
246
+ </footer>
247
+ </body>\n</html>"
248
+ end
249
+
250
+ def button passed
251
+ content passed ? '+' : '-', 'div', 'expand button'
252
+ end
253
+ def indent
254
+ " " * @indent
255
+ end
256
+
257
+ def open_tag(tag, classname=nil)
258
+ @output.puts "#{indent}<#{tag}#{classname.nil? ? '' : ' class="'+classname+'"'}>"
259
+ @indent += 2
260
+ if block_given?
261
+ yield
262
+ close_tag(tag)
263
+ end
264
+ end
265
+
266
+ def content(cont, tag=nil, classname=nil)
267
+ return if cont.nil?
268
+ case cont
269
+ when Time
270
+ cont = cont.ctime
271
+ end
272
+ if tag.nil?
273
+ @output.puts "#{indent}#{h(cont)}"
274
+ elsif
275
+ @output.puts "#{indent}<#{tag}#{classname.nil? ? '' : ' class="'+classname+'"'}>#{h(cont)}</#{tag}>"
276
+ end
277
+ end
278
+
279
+ def close_tag(tag)
280
+ @indent -= 2
281
+ @output.puts("#{indent}</#{tag}>")
282
+ end
283
+
284
+ end
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ class Result
291
+ attr_accessor :name, :status, :result
292
+ attr_accessor :started, :elapsed, :passed
293
+ def initialize n
294
+ @name = n if n =~ /^test/
295
+ @name ||= File.basename n, '.rb'
296
+ @status = ''
297
+ @result = ''
298
+ end
299
+ def name= n
300
+ @name = nil
301
+ @name = n if n =~ /^test/
302
+ @name ||= File.basename n, '.rb'
303
+ end
304
+ end
305
+
306
+ class ResultSuite < Result
307
+ attr_accessor :cases, :n_case, :n_test
308
+
309
+ def << (suite_case)
310
+ @cases ||= []
311
+ @cases.push suite_case
312
+ @n_case ||= 0
313
+ @n_case += 1
314
+ @n_test ||= 0
315
+ @n_test += suite_case.n_test
316
+ end
317
+ end
318
+
319
+ class ResultCase < Result
320
+ attr_accessor :tests, :n_test
321
+
322
+ def << (test)
323
+ @tests ||= []
324
+ @tests.push test
325
+ @n_test ||= 0
326
+ @n_test += 1
327
+ end
328
+ end
329
+
330
+ class ResultTest < Result
331
+ attr_accessor :assertions, :faults, :interrupted
332
+
333
+ def << (fault)
334
+ @faults ||= []
335
+ @faults.push fault
336
+ end
337
+
338
+ def assertion
339
+ @assertions ||= 0
340
+ @assertions += 1
341
+ end
342
+ end
343
+
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test-unit-runner-html
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Cherepanov Ilya
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: &19148484 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.4.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *19148484
25
+ description: A Ruby library to generate Test::Unit reports in HTML format
26
+ email: ilya.cherepanov@nevosoft.ru
27
+ executables: []
28
+ extensions: []
29
+ extra_rdoc_files: []
30
+ files:
31
+ - History.txt
32
+ - README.txt
33
+ - Rakefile
34
+ - Manifest.txt
35
+ - lib/test/unit/runner/html.rb
36
+ - lib/test/unit/ui/html/testrunner.rb
37
+ homepage: http://nevosoft.ru
38
+ licenses: []
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.6
55
+ requirements: []
56
+ rubyforge_project: test-unit-runner-html
57
+ rubygems_version: 1.8.11
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Generates Test::Unit reports in HTML format
61
+ test_files: []