micro-fast-hub 0.0.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.
Potentially problematic release.
This version of micro-fast-hub might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/micro-fast-hub.gemspec +12 -0
- data/test-unit-3.7.8/BSDL +24 -0
- data/test-unit-3.7.8/COPYING +64 -0
- data/test-unit-3.7.8/PSFL +271 -0
- data/test-unit-3.7.8/README.md +108 -0
- data/test-unit-3.7.8/Rakefile +74 -0
- data/test-unit-3.7.8/bin/test-unit +5 -0
- data/test-unit-3.7.8/doc/text/getting-started.md +120 -0
- data/test-unit-3.7.8/doc/text/how-to.md +90 -0
- data/test-unit-3.7.8/doc/text/news.md +2070 -0
- data/test-unit-3.7.8/lib/test/unit/assertion-failed-error.rb +60 -0
- data/test-unit-3.7.8/lib/test/unit/assertions.rb +2536 -0
- data/test-unit-3.7.8/lib/test/unit/attribute-matcher.rb +26 -0
- data/test-unit-3.7.8/lib/test/unit/attribute.rb +228 -0
- data/test-unit-3.7.8/lib/test/unit/auto-runner-loader.rb +17 -0
- data/test-unit-3.7.8/lib/test/unit/autorunner.rb +654 -0
- data/test-unit-3.7.8/lib/test/unit/code-snippet-fetcher.rb +58 -0
- data/test-unit-3.7.8/lib/test/unit/collector/descendant.rb +20 -0
- data/test-unit-3.7.8/lib/test/unit/collector/dir.rb +110 -0
- data/test-unit-3.7.8/lib/test/unit/collector/load.rb +201 -0
- data/test-unit-3.7.8/lib/test/unit/collector/objectspace.rb +35 -0
- data/test-unit-3.7.8/lib/test/unit/collector/xml.rb +249 -0
- data/test-unit-3.7.8/lib/test/unit/collector.rb +104 -0
- data/test-unit-3.7.8/lib/test/unit/color-scheme.rb +225 -0
- data/test-unit-3.7.8/lib/test/unit/color.rb +134 -0
- data/test-unit-3.7.8/lib/test/unit/data-sets.rb +127 -0
- data/test-unit-3.7.8/lib/test/unit/data.rb +371 -0
- data/test-unit-3.7.8/lib/test/unit/diff.rb +745 -0
- data/test-unit-3.7.8/lib/test/unit/error.rb +158 -0
- data/test-unit-3.7.8/lib/test/unit/exception-handler.rb +82 -0
- data/test-unit-3.7.8/lib/test/unit/failure.rb +169 -0
- data/test-unit-3.7.8/lib/test/unit/fault-location-detector.rb +104 -0
- data/test-unit-3.7.8/lib/test/unit/fixture.rb +304 -0
- data/test-unit-3.7.8/lib/test/unit/notification.rb +138 -0
- data/test-unit-3.7.8/lib/test/unit/omission.rb +198 -0
- data/test-unit-3.7.8/lib/test/unit/pending.rb +155 -0
- data/test-unit-3.7.8/lib/test/unit/priority.rb +194 -0
- data/test-unit-3.7.8/lib/test/unit/process-test-result.rb +55 -0
- data/test-unit-3.7.8/lib/test/unit/process-worker.rb +87 -0
- data/test-unit-3.7.8/lib/test/unit/runner/console.rb +86 -0
- data/test-unit-3.7.8/lib/test/unit/runner/emacs.rb +8 -0
- data/test-unit-3.7.8/lib/test/unit/runner/xml.rb +15 -0
- data/test-unit-3.7.8/lib/test/unit/sub-test-result.rb +59 -0
- data/test-unit-3.7.8/lib/test/unit/test-process-run-context.rb +21 -0
- data/test-unit-3.7.8/lib/test/unit/test-run-context.rb +16 -0
- data/test-unit-3.7.8/lib/test/unit/test-suite-creator.rb +103 -0
- data/test-unit-3.7.8/lib/test/unit/test-suite-process-runner.rb +205 -0
- data/test-unit-3.7.8/lib/test/unit/test-suite-runner.rb +132 -0
- data/test-unit-3.7.8/lib/test/unit/test-suite-thread-runner.rb +96 -0
- data/test-unit-3.7.8/lib/test/unit/test-thread-run-context.rb +23 -0
- data/test-unit-3.7.8/lib/test/unit/testcase.rb +1058 -0
- data/test-unit-3.7.8/lib/test/unit/testresult.rb +132 -0
- data/test-unit-3.7.8/lib/test/unit/testsuite.rb +133 -0
- data/test-unit-3.7.8/lib/test/unit/ui/console/outputlevel.rb +15 -0
- data/test-unit-3.7.8/lib/test/unit/ui/console/testrunner.rb +891 -0
- data/test-unit-3.7.8/lib/test/unit/ui/emacs/testrunner.rb +49 -0
- data/test-unit-3.7.8/lib/test/unit/ui/testrunner.rb +53 -0
- data/test-unit-3.7.8/lib/test/unit/ui/testrunnermediator.rb +131 -0
- data/test-unit-3.7.8/lib/test/unit/ui/testrunnerutilities.rb +41 -0
- data/test-unit-3.7.8/lib/test/unit/ui/xml/testrunner.rb +225 -0
- data/test-unit-3.7.8/lib/test/unit/util/backtracefilter.rb +65 -0
- data/test-unit-3.7.8/lib/test/unit/util/memory-usage.rb +47 -0
- data/test-unit-3.7.8/lib/test/unit/util/method-owner-finder.rb +28 -0
- data/test-unit-3.7.8/lib/test/unit/util/observable.rb +86 -0
- data/test-unit-3.7.8/lib/test/unit/util/output.rb +32 -0
- data/test-unit-3.7.8/lib/test/unit/util/procwrapper.rb +48 -0
- data/test-unit-3.7.8/lib/test/unit/version.rb +5 -0
- data/test-unit-3.7.8/lib/test/unit/warning.rb +3 -0
- data/test-unit-3.7.8/lib/test/unit/worker-context.rb +20 -0
- data/test-unit-3.7.8/lib/test/unit.rb +521 -0
- data/test-unit-3.7.8/lib/test-unit.rb +167 -0
- data/test-unit-3.7.8/sample/adder.rb +13 -0
- data/test-unit-3.7.8/sample/subtracter.rb +12 -0
- data/test-unit-3.7.8/sample/test_adder.rb +20 -0
- data/test-unit-3.7.8/sample/test_subtracter.rb +20 -0
- data/test-unit-3.7.8/sample/test_user.rb +23 -0
- metadata +117 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require_relative '../collector'
|
|
2
|
+
|
|
3
|
+
module Test
|
|
4
|
+
module Unit
|
|
5
|
+
module Collector
|
|
6
|
+
class Descendant
|
|
7
|
+
include Collector
|
|
8
|
+
|
|
9
|
+
NAME = 'collected from the subclasses of TestCase'
|
|
10
|
+
|
|
11
|
+
def collect(name=NAME)
|
|
12
|
+
suite = TestSuite.new(name)
|
|
13
|
+
add_test_cases(suite, TestCase::DESCENDANTS)
|
|
14
|
+
adjust_ractor_tests(suite)
|
|
15
|
+
suite
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require_relative '../testsuite'
|
|
2
|
+
require_relative '../collector'
|
|
3
|
+
|
|
4
|
+
module Test
|
|
5
|
+
module Unit
|
|
6
|
+
module Collector
|
|
7
|
+
class Dir
|
|
8
|
+
include Collector
|
|
9
|
+
|
|
10
|
+
attr_reader :pattern, :exclude
|
|
11
|
+
attr_accessor :base
|
|
12
|
+
|
|
13
|
+
def initialize(dir=::Dir, file=::File, object_space=::ObjectSpace, req=nil)
|
|
14
|
+
super()
|
|
15
|
+
@dir = dir
|
|
16
|
+
@file = file
|
|
17
|
+
@object_space = object_space
|
|
18
|
+
@req = req
|
|
19
|
+
@pattern = [/\btest_.*\.rb\Z/m]
|
|
20
|
+
@exclude = []
|
|
21
|
+
@base = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def collect(*from)
|
|
25
|
+
basedir = @base
|
|
26
|
+
$:.push(basedir) if basedir
|
|
27
|
+
if(from.empty?)
|
|
28
|
+
suite = recursive_collect('.', find_test_cases)
|
|
29
|
+
elsif(from.size == 1)
|
|
30
|
+
suite = recursive_collect(from.first, find_test_cases)
|
|
31
|
+
else
|
|
32
|
+
suites = []
|
|
33
|
+
from.each do |f|
|
|
34
|
+
suite = recursive_collect(f, find_test_cases)
|
|
35
|
+
suites << suite unless(suite.tests.empty?)
|
|
36
|
+
end
|
|
37
|
+
suite = TestSuite.new("[#{from.join(', ')}]")
|
|
38
|
+
sort(suites).each{|s| suite << s}
|
|
39
|
+
suite
|
|
40
|
+
end
|
|
41
|
+
adjust_ractor_tests(suite)
|
|
42
|
+
suite
|
|
43
|
+
ensure
|
|
44
|
+
$:.delete_at($:.rindex(basedir)) if basedir
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def find_test_cases(ignore=[])
|
|
48
|
+
cases = []
|
|
49
|
+
@object_space.each_object(Class) do |c|
|
|
50
|
+
cases << c if(c < TestCase && !ignore.include?(c))
|
|
51
|
+
end
|
|
52
|
+
ignore.concat(cases)
|
|
53
|
+
cases
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def recursive_collect(name, already_gathered)
|
|
57
|
+
sub_suites = []
|
|
58
|
+
path = realdir(name)
|
|
59
|
+
if @file.directory?(path)
|
|
60
|
+
dir_name = name unless name == '.'
|
|
61
|
+
@dir.entries(path).each do |e|
|
|
62
|
+
next if(e == '.' || e == '..')
|
|
63
|
+
e_name = dir_name ? @file.join(dir_name, e) : e
|
|
64
|
+
if @file.directory?(realdir(e_name))
|
|
65
|
+
next if /\A(?:CVS|\.svn|\.git)\z/ =~ e
|
|
66
|
+
sub_suite = recursive_collect(e_name, already_gathered)
|
|
67
|
+
sub_suites << sub_suite unless(sub_suite.empty?)
|
|
68
|
+
else
|
|
69
|
+
next if /~\z/ =~ e_name or /\A\.\#/ =~ e
|
|
70
|
+
if @pattern and !@pattern.empty?
|
|
71
|
+
next unless @pattern.any? {|pat| pat =~ e_name}
|
|
72
|
+
end
|
|
73
|
+
if @exclude and !@exclude.empty?
|
|
74
|
+
next if @exclude.any? {|pat| pat =~ e_name}
|
|
75
|
+
end
|
|
76
|
+
collect_file(e_name, sub_suites, already_gathered)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
else
|
|
80
|
+
collect_file(name, sub_suites, already_gathered)
|
|
81
|
+
end
|
|
82
|
+
suite = TestSuite.new(@file.basename(name))
|
|
83
|
+
sort(sub_suites).each{|s| suite << s}
|
|
84
|
+
suite
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def collect_file(name, suites, already_gathered)
|
|
88
|
+
dir = @file.dirname(@file.expand_path(name, @base))
|
|
89
|
+
$:.unshift(dir)
|
|
90
|
+
if(@req)
|
|
91
|
+
@req.require(name)
|
|
92
|
+
else
|
|
93
|
+
require(name)
|
|
94
|
+
end
|
|
95
|
+
find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)}
|
|
96
|
+
ensure
|
|
97
|
+
$:.delete_at($:.rindex(dir)) if(dir)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def realdir(path)
|
|
101
|
+
if @base
|
|
102
|
+
@file.join(@base, path)
|
|
103
|
+
else
|
|
104
|
+
path
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
require_relative '../testsuite'
|
|
4
|
+
require_relative '../collector'
|
|
5
|
+
|
|
6
|
+
module Test
|
|
7
|
+
module Unit
|
|
8
|
+
module Collector
|
|
9
|
+
class Load
|
|
10
|
+
include Collector
|
|
11
|
+
|
|
12
|
+
attr_reader :patterns, :excludes, :base
|
|
13
|
+
attr_reader :default_test_paths
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
super
|
|
17
|
+
@system_excludes = [/~\z/, /\A\.\#/]
|
|
18
|
+
@system_directory_excludes = [/\A(?:CVS|\.svn|\.git)\z/]
|
|
19
|
+
@patterns = [/\Atest[_\-].+\.rb\z/m, /[_\-]test\.rb\z/]
|
|
20
|
+
@excludes = []
|
|
21
|
+
@base = nil
|
|
22
|
+
@default_test_paths = []
|
|
23
|
+
@require_failed_infos = []
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def base=(base)
|
|
27
|
+
base = Pathname(base) unless base.nil?
|
|
28
|
+
@base = base
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def default_test_paths=(paths)
|
|
32
|
+
@default_test_paths = paths.collect do |path|
|
|
33
|
+
Pathname(path)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def collect(*froms)
|
|
38
|
+
add_load_path(@base) do
|
|
39
|
+
froms = @default_test_paths if froms.empty?
|
|
40
|
+
froms = ["."] if froms.empty?
|
|
41
|
+
test_suites = []
|
|
42
|
+
already_gathered = {}
|
|
43
|
+
find_test_cases(already_gathered)
|
|
44
|
+
froms.each do |from|
|
|
45
|
+
from = resolve_path(from)
|
|
46
|
+
if from.directory?
|
|
47
|
+
test_suite = collect_recursive(from, already_gathered)
|
|
48
|
+
test_suites << test_suite unless test_suite.tests.empty?
|
|
49
|
+
else
|
|
50
|
+
collect_file(from, test_suites, already_gathered)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
add_require_failed_test_suite(test_suites)
|
|
54
|
+
|
|
55
|
+
if test_suites.size > 1
|
|
56
|
+
test_suite = TestSuite.new("[#{froms.join(', ')}]")
|
|
57
|
+
sort(test_suites).each do |sub_test_suite|
|
|
58
|
+
test_suite << sub_test_suite
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
test_suite = test_suites.first
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
adjust_ractor_tests(test_suite)
|
|
65
|
+
|
|
66
|
+
test_suite
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def find_test_cases(already_gathered)
|
|
71
|
+
test_cases = []
|
|
72
|
+
TestCase::DESCENDANTS.each do |test_case|
|
|
73
|
+
next if already_gathered.key?(test_case)
|
|
74
|
+
test_cases << test_case
|
|
75
|
+
already_gathered[test_case] = true
|
|
76
|
+
end
|
|
77
|
+
test_cases
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
def collect_recursive(path, already_gathered)
|
|
82
|
+
sub_test_suites = []
|
|
83
|
+
|
|
84
|
+
if path.directory?
|
|
85
|
+
directories, files = path.children.partition do |child|
|
|
86
|
+
child.directory?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
files.each do |child|
|
|
90
|
+
next if excluded_file?(child.basename.to_s)
|
|
91
|
+
collect_file(child, sub_test_suites, already_gathered)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
directories.each do |child|
|
|
95
|
+
next if excluded_directory?(child.basename.to_s)
|
|
96
|
+
sub_test_suite = collect_recursive(child, already_gathered)
|
|
97
|
+
sub_test_suites << sub_test_suite unless sub_test_suite.empty?
|
|
98
|
+
end
|
|
99
|
+
else
|
|
100
|
+
unless excluded_file?(path.basename.to_s)
|
|
101
|
+
collect_file(path, sub_test_suites, already_gathered)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
test_suite = TestSuite.new(path.basename.to_s)
|
|
106
|
+
sort(sub_test_suites).each do |sub_test_suite|
|
|
107
|
+
test_suite << sub_test_suite
|
|
108
|
+
end
|
|
109
|
+
test_suite
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def collect_file(path, test_suites, already_gathered)
|
|
113
|
+
@program_file ||= File.expand_path($0)
|
|
114
|
+
expanded_path = path.expand_path
|
|
115
|
+
return if @program_file == expanded_path.to_s
|
|
116
|
+
add_load_path(expanded_path.dirname) do
|
|
117
|
+
begin
|
|
118
|
+
require(expanded_path.to_s)
|
|
119
|
+
rescue LoadError
|
|
120
|
+
@require_failed_infos << {:path => expanded_path, :exception => $!}
|
|
121
|
+
end
|
|
122
|
+
add_test_cases(test_suites, find_test_cases(already_gathered))
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def resolve_path(path)
|
|
127
|
+
if @base
|
|
128
|
+
@base + path
|
|
129
|
+
else
|
|
130
|
+
Pathname(path)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def add_load_path(path)
|
|
135
|
+
return yield if path.nil?
|
|
136
|
+
|
|
137
|
+
path = path.to_s
|
|
138
|
+
begin
|
|
139
|
+
$LOAD_PATH.unshift(path)
|
|
140
|
+
yield
|
|
141
|
+
ensure
|
|
142
|
+
index = $LOAD_PATH.index(path)
|
|
143
|
+
$LOAD_PATH.delete_at(index) if index
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def excluded_directory?(base)
|
|
148
|
+
@system_directory_excludes.any? {|pattern| pattern =~ base}
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def excluded_file?(base)
|
|
152
|
+
return true if @system_excludes.any? {|pattern| pattern =~ base}
|
|
153
|
+
|
|
154
|
+
patterns = @patterns || []
|
|
155
|
+
unless patterns.empty?
|
|
156
|
+
return true unless patterns.any? {|pattern| pattern =~ base}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
excludes = @excludes || []
|
|
160
|
+
unless excludes.empty?
|
|
161
|
+
return true if excludes.any? {|pattern| pattern =~ base}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
false
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def add_require_failed_test_suite(test_suites)
|
|
168
|
+
return if @require_failed_infos.empty?
|
|
169
|
+
|
|
170
|
+
require_failed_infos = @require_failed_infos
|
|
171
|
+
require_failed_errors = Class.new(Test::Unit::TestCase)
|
|
172
|
+
require_failed_errors.class_eval do
|
|
173
|
+
class << self
|
|
174
|
+
def name
|
|
175
|
+
"RequireFailedErrors"
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
require_failed_infos.each do |info|
|
|
180
|
+
path = info[:path]
|
|
181
|
+
normalized_path = path.to_s.gsub(/[^a-z0-9\_]+/i, '_')
|
|
182
|
+
normalized_path = normalized_path.gsub(/\A_+/, '')
|
|
183
|
+
exception = info[:exception]
|
|
184
|
+
define_method("test_require_#{normalized_path}") do
|
|
185
|
+
raise(exception.class,
|
|
186
|
+
"failed to load <#{path}>: #{exception.message}",
|
|
187
|
+
exception.backtrace)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def priority
|
|
192
|
+
100
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
add_suite(test_suites, require_failed_errors.suite)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Author:: Nathaniel Talbott.
|
|
2
|
+
# Copyright:: Copyright (c) 2000-2003 Nathaniel Talbott. All rights reserved.
|
|
3
|
+
# License:: Ruby license.
|
|
4
|
+
|
|
5
|
+
require_relative '../collector'
|
|
6
|
+
|
|
7
|
+
module Test
|
|
8
|
+
module Unit
|
|
9
|
+
module Collector
|
|
10
|
+
class ObjectSpace
|
|
11
|
+
include Collector
|
|
12
|
+
|
|
13
|
+
NAME = 'collected from the ObjectSpace'
|
|
14
|
+
|
|
15
|
+
def initialize(source=::ObjectSpace)
|
|
16
|
+
super()
|
|
17
|
+
@source = source
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def collect(name=NAME)
|
|
21
|
+
suite = TestSuite.new(name)
|
|
22
|
+
sub_suites = []
|
|
23
|
+
@source.each_object(Class) do |klass|
|
|
24
|
+
if(Test::Unit::TestCase > klass)
|
|
25
|
+
add_suite(sub_suites, klass.suite)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
sort(sub_suites).each{|s| suite << s}
|
|
29
|
+
adjust_ractor_tests(suite)
|
|
30
|
+
suite
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#--
|
|
2
|
+
#
|
|
3
|
+
# Author:: Kouhei Sutou
|
|
4
|
+
# Copyright::
|
|
5
|
+
# * Copyright (c) 2011 Kouhei Sutou <kou@clear-code.com>
|
|
6
|
+
# License:: Ruby license.
|
|
7
|
+
|
|
8
|
+
# just test!!! don't use it yet!!!
|
|
9
|
+
|
|
10
|
+
require_relative '../collector'
|
|
11
|
+
|
|
12
|
+
require 'rexml/document'
|
|
13
|
+
require 'rexml/streamlistener'
|
|
14
|
+
|
|
15
|
+
module Test
|
|
16
|
+
module Unit
|
|
17
|
+
module Collector
|
|
18
|
+
class XML
|
|
19
|
+
include Collector
|
|
20
|
+
|
|
21
|
+
def collect(xml_log_path)
|
|
22
|
+
listener = Listener.new
|
|
23
|
+
File.open(xml_log_path) do |xml_log|
|
|
24
|
+
parser = REXML::Parsers::StreamParser.new(xml_log, listener)
|
|
25
|
+
parser.parse
|
|
26
|
+
end
|
|
27
|
+
suite = TestSuite.new("tests in #{xml_log_path}")
|
|
28
|
+
suites = listener.test_suites
|
|
29
|
+
sort(suites).each {|s| add_suite(suite, s)}
|
|
30
|
+
suite
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class Listener
|
|
34
|
+
include REXML::StreamListener
|
|
35
|
+
|
|
36
|
+
attr_reader :test_suites
|
|
37
|
+
def initialize
|
|
38
|
+
@ns_stack = [{"xml" => :xml}]
|
|
39
|
+
@tag_stack = [["", :root]]
|
|
40
|
+
@text_stack = ['']
|
|
41
|
+
@state_stack = [:root]
|
|
42
|
+
@values = {}
|
|
43
|
+
@test_suites = []
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def tag_start(name, attributes)
|
|
47
|
+
@text_stack.push('')
|
|
48
|
+
|
|
49
|
+
ns = @ns_stack.last.dup
|
|
50
|
+
attrs = {}
|
|
51
|
+
attributes.each do |n, v|
|
|
52
|
+
if /\Axmlns(?:\z|:)/ =~ n
|
|
53
|
+
ns[$POSTMATCH] = v
|
|
54
|
+
else
|
|
55
|
+
attrs[n] = v
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
@ns_stack.push(ns)
|
|
59
|
+
|
|
60
|
+
_parent_tag = parent_tag
|
|
61
|
+
prefix, local = split_name(name)
|
|
62
|
+
uri = _ns(ns, prefix)
|
|
63
|
+
@tag_stack.push([uri, local])
|
|
64
|
+
|
|
65
|
+
state = next_state(@state_stack.last, uri, local)
|
|
66
|
+
@state_stack.push(state)
|
|
67
|
+
@values = {}
|
|
68
|
+
case state
|
|
69
|
+
when :test_suite, :test_case
|
|
70
|
+
# do nothing
|
|
71
|
+
when :test
|
|
72
|
+
@n_pass_assertions = 0 if _parent_tag == "start-test"
|
|
73
|
+
when :backtrace
|
|
74
|
+
@backtrace = []
|
|
75
|
+
@values_backup = @values
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def tag_end(name)
|
|
80
|
+
state = @state_stack.pop
|
|
81
|
+
text = @text_stack.pop
|
|
82
|
+
uri, local = @tag_stack.pop
|
|
83
|
+
no_action_states = [:root, :stream]
|
|
84
|
+
case state
|
|
85
|
+
when *no_action_states
|
|
86
|
+
# do nothing
|
|
87
|
+
when :test_suite
|
|
88
|
+
test_suite_end
|
|
89
|
+
when :complete_test_case
|
|
90
|
+
@test_suites.last << @test_case.suite
|
|
91
|
+
when :test_case
|
|
92
|
+
test_case_end
|
|
93
|
+
when :result
|
|
94
|
+
@result = @values
|
|
95
|
+
when :test
|
|
96
|
+
test_end
|
|
97
|
+
when :pass_assertion
|
|
98
|
+
@n_pass_assertions += 1
|
|
99
|
+
when :backtrace
|
|
100
|
+
@values = @values_backup
|
|
101
|
+
@values["backtrace"] = @backtrace
|
|
102
|
+
when :entry
|
|
103
|
+
file = @values['file']
|
|
104
|
+
line = @values['line']
|
|
105
|
+
info = @values['info']
|
|
106
|
+
@backtrace << "#{file}:#{line}: #{info}"
|
|
107
|
+
@values = {}
|
|
108
|
+
else
|
|
109
|
+
local = normalize_local(local)
|
|
110
|
+
@values[local] = text
|
|
111
|
+
end
|
|
112
|
+
@ns_stack.pop
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def text(data)
|
|
116
|
+
@text_stack.last << data
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
def _ns(ns, prefix)
|
|
121
|
+
ns.fetch(prefix, "")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
NAME_SPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/
|
|
125
|
+
def split_name(name)
|
|
126
|
+
name =~ NAME_SPLIT
|
|
127
|
+
[$1 || '', $2]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
STATE_TABLE = {
|
|
131
|
+
:root => [:stream],
|
|
132
|
+
:stream => [:ready_test_suite,
|
|
133
|
+
:start_test_suite,
|
|
134
|
+
:ready_test_case,
|
|
135
|
+
:start_test_case,
|
|
136
|
+
:start_test,
|
|
137
|
+
:pass_assertion,
|
|
138
|
+
:test_result,
|
|
139
|
+
:complete_test,
|
|
140
|
+
:complete_test_case,
|
|
141
|
+
:complete_test_suite,
|
|
142
|
+
:success],
|
|
143
|
+
:ready_test_suite => [:n_tests],
|
|
144
|
+
:start_test_suite => [:test_suite],
|
|
145
|
+
:ready_test_case => [:test_case,
|
|
146
|
+
:n_tests],
|
|
147
|
+
:start_test_case => [:test_case],
|
|
148
|
+
:start_test => [:test],
|
|
149
|
+
:pass_assertion => [:test],
|
|
150
|
+
:complete_test => [:test, :success],
|
|
151
|
+
:complete_test_case => [:test_case,
|
|
152
|
+
:elapsed,
|
|
153
|
+
:success],
|
|
154
|
+
:complete_test_suite => [:test_suite,
|
|
155
|
+
:success],
|
|
156
|
+
:test_suite => [:start_time,
|
|
157
|
+
:elapsed],
|
|
158
|
+
:test_case => [:name,
|
|
159
|
+
:start_time,
|
|
160
|
+
:elapsed],
|
|
161
|
+
:test => [:name,
|
|
162
|
+
:start_time,
|
|
163
|
+
:elapsed],
|
|
164
|
+
:test_result => [:test,
|
|
165
|
+
:result],
|
|
166
|
+
:result => [:test_case,
|
|
167
|
+
:test,
|
|
168
|
+
:status,
|
|
169
|
+
:backtrace,
|
|
170
|
+
:detail],
|
|
171
|
+
:backtrace => [:entry],
|
|
172
|
+
:entry => [:file,
|
|
173
|
+
:line,
|
|
174
|
+
:info],
|
|
175
|
+
}
|
|
176
|
+
def next_state(current_state, uri, local)
|
|
177
|
+
local = normalize_local(local)
|
|
178
|
+
valid_elements = STATE_TABLE[current_state]
|
|
179
|
+
if valid_elements.nil?
|
|
180
|
+
raise "unexpected element: #{current_path}"
|
|
181
|
+
end
|
|
182
|
+
next_state = local.to_sym
|
|
183
|
+
unless valid_elements.include?(next_state)
|
|
184
|
+
raise "unexpected element: #{current_path}"
|
|
185
|
+
end
|
|
186
|
+
next_state
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def current_path
|
|
190
|
+
locals = @tag_stack.collect do |uri, local|
|
|
191
|
+
local
|
|
192
|
+
end
|
|
193
|
+
["", *locals].join("/")
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def normalize_local(local)
|
|
197
|
+
local.gsub(/-/, "_")
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def parent_tag
|
|
201
|
+
@tag_stack.last[1]
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def test_suite_end
|
|
205
|
+
return unless parent_tag == "start-test-suite"
|
|
206
|
+
suite = TestSuite.new
|
|
207
|
+
["start_time", "elapsed_time", "n_tests"].each do |key|
|
|
208
|
+
if @values.has_key?(key)
|
|
209
|
+
suite.instance_variable_set("@#{key}", @values[key])
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
@test_suites << suite
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def test_case_end
|
|
216
|
+
return unless parent_tag == "start-test-case"
|
|
217
|
+
name = @values["name"]
|
|
218
|
+
@test_case = Class.new(TestCase) do
|
|
219
|
+
define_method(:name) do
|
|
220
|
+
name
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_end
|
|
226
|
+
return unless parent_tag == "complete-test"
|
|
227
|
+
name = @values["name"]
|
|
228
|
+
n_pass_assertions = @n_pass_assertions
|
|
229
|
+
result = @result
|
|
230
|
+
@test_case.module_eval do
|
|
231
|
+
test
|
|
232
|
+
define_method(name) do
|
|
233
|
+
n_pass_assertions.times do
|
|
234
|
+
add_assertion
|
|
235
|
+
end
|
|
236
|
+
case result["status"]
|
|
237
|
+
when "omission"
|
|
238
|
+
add_omission(Omission.new(name,
|
|
239
|
+
result["backtrace"],
|
|
240
|
+
result["detail"]))
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|