1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
require "coverage"
Coverage.start(lines: true, branches: true, methods: true)
TEST_COVERAGE_DATA_FILE = "test-coverage.dat"
FILTER_PATHS = %w[
lib/bundler/vendor
lib/rubygems/resolver/molinillo
lib/rubygems/tsort
lib/rubygems/optparse
tool
test
spec
]
def merge_coverage_data(res1, res2)
res1.each do |path, cov1|
cov2 = res2[path]
if cov2
cov1[:lines].each_with_index do |count1, i|
next unless count1
add_count(cov2[:lines], i, count1)
end
cov1[:branches].each do |base_key, targets1|
if cov2[:branches][base_key]
targets1.each do |target_key, count1|
add_count(cov2[:branches][base_key], target_key, count1)
end
else
cov2[:branches][base_key] = targets1
end
end
cov1[:methods].each do |key, count1|
add_count(cov2[:methods], key, count1)
end
else
res2[path] = cov1
end
end
res2
end
def add_count(h, key, count)
if h[key]
h[key] += count
else
h[key] = count
end
end
def save_coverage_data(res1)
res1.each do |_path, cov|
if cov[:methods]
h = {}
cov[:methods].each do |(klass, *key), count|
h[[klass.name, *key]] = count
end
cov[:methods].replace h
end
end
File.open(TEST_COVERAGE_DATA_FILE, File::RDWR | File::CREAT | File::BINARY) do |f|
f.flock(File::LOCK_EX)
s = f.read
res2 = s.size > 0 ? Marshal.load(s) : {}
res1 = merge_coverage_data(res1, res2)
f.rewind
f << Marshal.dump(res2)
f.flush
f.truncate(f.pos)
end
end
def invoke_simplecov_formatter
# XXX docile-x.y.z and simplecov-x.y.z, simplecov-html-x.y.z, simplecov_json_formatter-x.y.z
%w[simplecov simplecov-html simplecov_json_formatter docile].each do |f|
Dir.glob("#{__dir__}/../.bundle/gems/#{f}-*/lib").each do |d|
$LOAD_PATH.unshift d
end
end
require "simplecov"
res = Marshal.load(File.binread(TEST_COVERAGE_DATA_FILE))
simplecov_result = {}
base_dir = File.dirname(__dir__)
cur_dir = Dir.pwd
res.each do |path, cov|
next unless path.start_with?(base_dir) || path.start_with?(cur_dir)
next if FILTER_PATHS.any? {|dir| path.start_with?(File.join(base_dir, dir))}
simplecov_result[path] = cov
end
a, b = base_dir, cur_dir
until a == b
if a.size > b.size
a = File.dirname(a)
else
b = File.dirname(b)
end
end
root_dir = a
SimpleCov.configure do
root(root_dir)
coverage_dir(File.join(cur_dir, "coverage"))
end
res = SimpleCov::Result.new(simplecov_result)
res.command_name = "Ruby's `make test-all`"
SimpleCov::Formatter::HTMLFormatter.new.format(res)
end
pid = $$
pwd = Dir.pwd
at_exit do
exit_exc = $!
Dir.chdir(pwd) do
save_coverage_data(Coverage.result)
if pid == $$
begin
nil while Process.waitpid(-1)
rescue Errno::ECHILD
invoke_simplecov_formatter
end
end
end
raise exit_exc if exit_exc
end
|