minitap 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +2 -2
- data/HISTORY.rdoc +14 -2
- data/lib/minitap.rb +47 -54
- data/lib/minitap/ignore_callers.rb +8 -0
- data/spec/applique/cli.rb +34 -0
- data/spec/fixtures/tapy.yml +78 -0
- data/spec/minitap.rdoc +94 -0
- metadata +12 -8
data/.ruby
CHANGED
data/HISTORY.rdoc
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
= RELEASE HISTORY
|
2
2
|
|
3
|
+
== 0.3.1 / 2011-10-18
|
4
|
+
|
5
|
+
This release includes two basic improvements: better backtrace filtering,
|
6
|
+
and file fields given relative to current working directory instead of
|
7
|
+
absolute paths. In future maybe this can be configurable, if someone makes
|
8
|
+
the case that absolute paths are needed.
|
9
|
+
|
10
|
+
Changes:
|
11
|
+
|
12
|
+
* Improve backtrace filtering.
|
13
|
+
* Make file fields relative to working directory.
|
14
|
+
|
3
15
|
|
4
16
|
== 0.3.0 / 2011-10-09
|
5
17
|
|
6
|
-
Support version 3 of TAP-Y/
|
18
|
+
Support version 3 of TAP-Y/J spec. This simply entailed renaming
|
7
19
|
the `tally` document to `final`.
|
8
20
|
|
9
21
|
Changes:
|
@@ -19,7 +31,7 @@ the hood.
|
|
19
31
|
|
20
32
|
Changes:
|
21
33
|
|
22
|
-
* Adjust usage
|
34
|
+
* Adjust usage documentation.
|
23
35
|
|
24
36
|
|
25
37
|
== 0.1.0 / 2011-10-06
|
data/lib/minitap.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# MiniTest adaptor for tapout.
|
2
2
|
|
3
3
|
require 'minitest/unit'
|
4
|
+
require 'minitap/ignore_callers'
|
4
5
|
require 'stringio'
|
5
6
|
|
6
7
|
# Becuase of some wierdness in MiniTest
|
@@ -25,8 +26,13 @@ module MiniTest
|
|
25
26
|
# TAP-Y/J Revision
|
26
27
|
REVISION = 3
|
27
28
|
|
29
|
+
# Backtrace patterns to be omitted.
|
30
|
+
IGNORE_CALLERS = ::RUBY_IGNORE_CALLERS
|
31
|
+
|
32
|
+
#
|
28
33
|
attr_accessor :suite_start_time, :test_start_time, :reporters
|
29
34
|
|
35
|
+
# Initialize new MiniTap MiniTest runner.
|
30
36
|
def initialize
|
31
37
|
self.report = {}
|
32
38
|
self.errors = 0
|
@@ -225,6 +231,7 @@ module MiniTest
|
|
225
231
|
def tapout_skip(suite, test, test_runner)
|
226
232
|
e = test_runner.exeception
|
227
233
|
e_file, e_line = location(test_runner.exception)
|
234
|
+
r_file = e_file.sub(Dir.pwd+'/', '')
|
228
235
|
|
229
236
|
doc = {
|
230
237
|
'type' => 'test',
|
@@ -247,9 +254,10 @@ module MiniTest
|
|
247
254
|
# 'code' => Foo#*
|
248
255
|
'exception' => {
|
249
256
|
'message' => clean_message(e.message),
|
250
|
-
'
|
257
|
+
'class' => e.class.name,
|
258
|
+
'file' => r_file,
|
251
259
|
'line' => e_line,
|
252
|
-
|
260
|
+
'source' => source(e_file)[e_line-1].strip,
|
253
261
|
'snippet' => code_snippet(e_file, e_line),
|
254
262
|
'backtrace' => filter_backtrace(e.backtrace)
|
255
263
|
},
|
@@ -262,6 +270,7 @@ module MiniTest
|
|
262
270
|
def tapout_failure(suite, test, test_runner)
|
263
271
|
e = test_runner.exception
|
264
272
|
e_file, e_line = location(test_runner.exception)
|
273
|
+
r_file = e_file.sub(Dir.pwd+'/', '')
|
265
274
|
|
266
275
|
doc = {
|
267
276
|
'type' => 'test',
|
@@ -284,9 +293,10 @@ module MiniTest
|
|
284
293
|
# 'code' => Foo#*
|
285
294
|
'exception' => {
|
286
295
|
'message' => clean_message(e.message),
|
287
|
-
'
|
296
|
+
'class' => e.class.name,
|
297
|
+
'file' => r_file,
|
288
298
|
'line' => e_line,
|
289
|
-
|
299
|
+
'source' => source(e_file)[e_line-1].strip,
|
290
300
|
'snippet' => code_snippet(e_file, e_line),
|
291
301
|
'backtrace' => filter_backtrace(e.backtrace)
|
292
302
|
},
|
@@ -299,6 +309,7 @@ module MiniTest
|
|
299
309
|
def tapout_error(suite, test, test_runner)
|
300
310
|
e = test_runner.exception
|
301
311
|
e_file, e_line = location(test_runner.exception)
|
312
|
+
r_file = e_file.sub(Dir.pwd+'/', '')
|
302
313
|
|
303
314
|
doc = {
|
304
315
|
'type' => 'test',
|
@@ -321,9 +332,10 @@ module MiniTest
|
|
321
332
|
# 'code' => Foo#*
|
322
333
|
'exception' => {
|
323
334
|
'message' => clean_message("#{e.class}: #{e.message}"),
|
324
|
-
'
|
335
|
+
'class' => e.class.name,
|
336
|
+
'file' => r_file,
|
325
337
|
'line' => e_line,
|
326
|
-
|
338
|
+
'source' => source(e_file)[e_line-1].strip,
|
327
339
|
'snippet' => code_snippet(e_file, e_line),
|
328
340
|
'backtrace' => filter_backtrace(e.backtrace)
|
329
341
|
},
|
@@ -333,63 +345,44 @@ module MiniTest
|
|
333
345
|
end
|
334
346
|
|
335
347
|
#
|
336
|
-
|
337
|
-
|
338
|
-
#
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
+
#def filter_backtrace(backtrace)
|
349
|
+
# trace = backtrace
|
350
|
+
# trace = clean_backtrace(trace)
|
351
|
+
# trace = MiniTest::filter_backtrace(trace)
|
352
|
+
# trace
|
353
|
+
#end
|
354
|
+
|
355
|
+
# Clean the backtrace of any reference to test framework itself.
|
356
|
+
def filter_backtrace(backtrace)
|
357
|
+
## remove backtraces that match any pattern in IGNORE_CALLERS
|
358
|
+
trace = backtrace.reject{|b| IGNORE_CALLERS.any?{|i| i=~b}}
|
359
|
+
## remove `:in ...` portion of backtraces
|
348
360
|
trace = trace.map do |bt|
|
349
|
-
|
350
|
-
|
351
|
-
else
|
352
|
-
bt
|
353
|
-
end
|
361
|
+
i = bt.index(':in')
|
362
|
+
i ? bt[0...i] : bt
|
354
363
|
end
|
364
|
+
## now apply MiniTest's own filter (note: doesn't work if done first, why?)
|
365
|
+
trace = MiniTest::filter_backtrace(trace)
|
366
|
+
## if the backtrace is empty now then revert to the original
|
355
367
|
trace = backtrace if trace.empty?
|
368
|
+
## simplify paths to be relative to current workding diectory
|
356
369
|
trace = trace.map{ |bt| bt.sub(Dir.pwd+File::SEPARATOR,'') }
|
357
|
-
trace
|
370
|
+
return trace
|
358
371
|
end
|
359
372
|
|
360
373
|
# Returns a String of source code.
|
361
374
|
def code_snippet(file, line)
|
362
375
|
s = []
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
# end
|
372
|
-
#when Array
|
373
|
-
# snippet.each do |h|
|
374
|
-
# s << [h.key, h.value]
|
375
|
-
# end
|
376
|
-
#else
|
377
|
-
##backtrace = exception.backtrace.reject{ |bt| bt =~ INTERNALS }
|
378
|
-
##backtrace.first =~ /(.+?):(\d+(?=:|\z))/ or return ""
|
379
|
-
#caller =~ /(.+?):(\d+(?=:|\z))/ or return ""
|
380
|
-
#source_file, source_line = $1, $2.to_i
|
381
|
-
|
382
|
-
if File.file?(file)
|
383
|
-
source = source(file)
|
384
|
-
radius = 2 # TODO: make customizable (number of surrounding lines to show)
|
385
|
-
region = [line - radius, 1].max ..
|
386
|
-
[line + radius, source.length].min
|
387
|
-
|
388
|
-
s = region.map do |n|
|
389
|
-
{n => source[n-1].chomp}
|
390
|
-
end
|
376
|
+
if File.file?(file)
|
377
|
+
source = source(file)
|
378
|
+
radius = 2 # TODO: make customizable (number of surrounding lines to show)
|
379
|
+
region = [line - radius, 1].max ..
|
380
|
+
[line + radius, source.length].min
|
381
|
+
|
382
|
+
s = region.map do |n|
|
383
|
+
{n => source[n-1].chomp}
|
391
384
|
end
|
392
|
-
|
385
|
+
end
|
393
386
|
return s
|
394
387
|
end
|
395
388
|
|
@@ -504,7 +497,7 @@ module MiniTest
|
|
504
497
|
|
505
498
|
#
|
506
499
|
class TapJ < MiniTap
|
507
|
-
def
|
500
|
+
def initializebacktrace
|
508
501
|
require 'json'
|
509
502
|
super
|
510
503
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'tapout'
|
2
|
+
|
3
|
+
When 'Given a MiniTest testcase' do |text|
|
4
|
+
@test = text
|
5
|
+
end
|
6
|
+
|
7
|
+
When 'Running it with the (((.*?))) format' do |type|
|
8
|
+
File.open('test.rb', 'w'){ |f| f << test_helper(type) + "\n\n" + @test }
|
9
|
+
@out = `ruby test.rb`
|
10
|
+
@stream = YAML.load_documents(@out)
|
11
|
+
end
|
12
|
+
|
13
|
+
#When '(((\w+))) reporter should run without error' do |format|
|
14
|
+
# $stdin = StringIO.new(@tapy)
|
15
|
+
# $stdout = StringIO.new(out = '')
|
16
|
+
#
|
17
|
+
# TapOut.cli(format)
|
18
|
+
#end
|
19
|
+
|
20
|
+
def test_helper(type)
|
21
|
+
if type == 'TAP-Y' then
|
22
|
+
%Q{
|
23
|
+
require 'minitap'
|
24
|
+
MiniTest::Unit.runner = MiniTest::TapY.new
|
25
|
+
require 'minitest/autorun'
|
26
|
+
}
|
27
|
+
else
|
28
|
+
%Q{
|
29
|
+
require 'minitap'
|
30
|
+
MiniTest::Unit.runner = MiniTest::TapJ.new
|
31
|
+
require 'minitest/autorun'
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
---
|
2
|
+
type: suite
|
3
|
+
start: '2011-10-06 18:48:08'
|
4
|
+
count: 3
|
5
|
+
seed: 36440
|
6
|
+
rev: 2
|
7
|
+
---
|
8
|
+
type: case
|
9
|
+
subtype: ''
|
10
|
+
label: ExampleTestCase
|
11
|
+
level: 0
|
12
|
+
---
|
13
|
+
type: test
|
14
|
+
subtype: ''
|
15
|
+
status: error
|
16
|
+
label: test_error
|
17
|
+
exception:
|
18
|
+
message: ! 'RuntimeError:'
|
19
|
+
file: example.rb
|
20
|
+
line: 10
|
21
|
+
snippet:
|
22
|
+
- 8: ''
|
23
|
+
- 9: ! ' def test_error'
|
24
|
+
- 10: ! ' raise'
|
25
|
+
- 11: ! ' end'
|
26
|
+
- 12: ''
|
27
|
+
backtrace:
|
28
|
+
- example.rb:10
|
29
|
+
time: 0.001054606
|
30
|
+
---
|
31
|
+
type: test
|
32
|
+
subtype: ''
|
33
|
+
status: fail
|
34
|
+
label: test_failing
|
35
|
+
exception:
|
36
|
+
message: ! "Expected: \"1\"\n Actual: \"2\""
|
37
|
+
file: example.rb
|
38
|
+
line: 14
|
39
|
+
snippet:
|
40
|
+
- 12: ''
|
41
|
+
- 13: ! ' def test_failing'
|
42
|
+
- 14: ! ' assert_equal(''1'', ''2'')'
|
43
|
+
- 15: ! ' end'
|
44
|
+
- 16: ''
|
45
|
+
backtrace:
|
46
|
+
- example.rb:14
|
47
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:456
|
48
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:103
|
49
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:88
|
50
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:88
|
51
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:88
|
52
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:73
|
53
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:73
|
54
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:73
|
55
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:146
|
56
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:72
|
57
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:48
|
58
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:47
|
59
|
+
- /home/trans/com/programs/rubyworks/minitap/lib/minitap.rb:47
|
60
|
+
time: 0.046170916
|
61
|
+
---
|
62
|
+
type: test
|
63
|
+
subtype: ''
|
64
|
+
status: pass
|
65
|
+
label: test_passing
|
66
|
+
time: 1.04997403
|
67
|
+
---
|
68
|
+
type: tally
|
69
|
+
time: 1.000800203
|
70
|
+
counts:
|
71
|
+
total: 3
|
72
|
+
pass: 1
|
73
|
+
fail: 1
|
74
|
+
error: 1
|
75
|
+
omit: 0
|
76
|
+
todo: 0
|
77
|
+
...
|
78
|
+
|
data/spec/minitap.rdoc
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
= MiniTap
|
2
|
+
|
3
|
+
Given a MiniTest testcase:
|
4
|
+
|
5
|
+
class ExampleTestCase < MiniTest::Unit::TestCase
|
6
|
+
def test_error
|
7
|
+
raise
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_failing
|
11
|
+
assert_equal('1', '2')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_passing
|
15
|
+
sleep 1
|
16
|
+
assert_equal('1', '1')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Running it with the TAP-Y format should work without error.
|
21
|
+
|
22
|
+
The resulting document stream should exhibit the following
|
23
|
+
characteristics.
|
24
|
+
|
25
|
+
There should be six sections.
|
26
|
+
|
27
|
+
@stream.size #=> 6
|
28
|
+
|
29
|
+
The first should be a `suite` with a count of `3`.
|
30
|
+
|
31
|
+
@stream.first['type'] #=> 'suite'
|
32
|
+
@stream.first['count'] #=> 3
|
33
|
+
|
34
|
+
The second should be `case` entry.
|
35
|
+
|
36
|
+
@stream[1]['type'] #=> 'case'
|
37
|
+
@stream[1]['label'] #=> 'ExampleTestCase'
|
38
|
+
@stream[1]['level'] #=> 0
|
39
|
+
|
40
|
+
The next three documents are the unit tests, which can occur in any order.
|
41
|
+
There one that shoud have a status of `pass`, another of `fail` and the
|
42
|
+
third of `error`.
|
43
|
+
|
44
|
+
passing_test = @stream.find{ |d| d['type'] == 'test' && d['status'] == 'pass' }
|
45
|
+
failing_test = @stream.find{ |d| d['type'] == 'test' && d['status'] == 'fail' }
|
46
|
+
erring_test = @stream.find{ |d| d['type'] == 'test' && d['status'] == 'error' }
|
47
|
+
|
48
|
+
The passing test should have the following charactersitics.
|
49
|
+
|
50
|
+
passing_test['label'] #=> 'test_passing'
|
51
|
+
|
52
|
+
The failing test should
|
53
|
+
|
54
|
+
failing_test['label'] #=> "test_failing"
|
55
|
+
failing_test['exception']['class'] #=> "MiniTest::Assertion"
|
56
|
+
failing_test['exception']['file'] #=> "test.rb"
|
57
|
+
failing_test['exception']['line'] #=> 13
|
58
|
+
failing_test['exception']['source'] #=> "assert_equal('1', '2')"
|
59
|
+
|
60
|
+
The failing test should also not have any mention of minitap in the
|
61
|
+
backtrace.
|
62
|
+
|
63
|
+
failing_test['exception']['backtrace'].each do |e|
|
64
|
+
/minitap/.refute.match(e)
|
65
|
+
end
|
66
|
+
|
67
|
+
The erring test should
|
68
|
+
|
69
|
+
erring_test['label'] #=> 'test_error'
|
70
|
+
erring_test['exception']['class'] #=> 'RuntimeError'
|
71
|
+
erring_test['exception']['file'] #=> 'test.rb'
|
72
|
+
erring_test['exception']['line'] #=> 9
|
73
|
+
erring_test['exception']['source'] #=> 'raise'
|
74
|
+
|
75
|
+
The erring test should also not have any mention of minitap in the
|
76
|
+
backtrace.
|
77
|
+
|
78
|
+
erring_test['exception']['backtrace'].each do |e|
|
79
|
+
/minitap/.refute.match(e)
|
80
|
+
end
|
81
|
+
|
82
|
+
The last should a `final` document.
|
83
|
+
|
84
|
+
@stream.last['type'] #=> 'final'
|
85
|
+
|
86
|
+
And it should have the following counts.
|
87
|
+
|
88
|
+
@stream.last['counts']['total'] #=> 3
|
89
|
+
@stream.last['counts']['error'] #=> 1
|
90
|
+
@stream.last['counts']['fail'] #=> 1
|
91
|
+
@stream.last['counts']['pass'] #=> 1
|
92
|
+
@stream.last['counts']['omit'] #=> 0
|
93
|
+
@stream.last['counts']['todo'] #=> 0
|
94
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-10-
|
12
|
+
date: 2011-10-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tapout
|
16
|
-
requirement: &
|
16
|
+
requirement: &12384040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.3.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *12384040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: detroit
|
27
|
-
requirement: &
|
27
|
+
requirement: &12383440 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *12383440
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: reap
|
38
|
-
requirement: &
|
38
|
+
requirement: &12382640 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *12382640
|
47
47
|
description: MiniTap provides a custom MiniTest reporter that outs TAP-Y or TAP-J
|
48
48
|
formatted output.
|
49
49
|
email:
|
@@ -56,7 +56,11 @@ extra_rdoc_files:
|
|
56
56
|
- COPYING.rdoc
|
57
57
|
files:
|
58
58
|
- .ruby
|
59
|
+
- lib/minitap/ignore_callers.rb
|
59
60
|
- lib/minitap.rb
|
61
|
+
- spec/applique/cli.rb
|
62
|
+
- spec/fixtures/tapy.yml
|
63
|
+
- spec/minitap.rdoc
|
60
64
|
- HISTORY.rdoc
|
61
65
|
- README.rdoc
|
62
66
|
- COPYING.rdoc
|