gcov2x 0.2.2 → 0.2.3
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +9 -1
- data/bin/gcov2x +2 -5
- data/lib/file.rb +18 -2
- data/lib/html_formatter.rb +15 -7
- data/lib/html_view.html.erb +27 -7
- data/lib/line.rb +0 -3
- data/lib/project.rb +60 -28
- data/lib/version.rb +1 -1
- data/spec/file_spec.rb +9 -1
- data/spec/project_spec.rb +39 -0
- data/spec/spec_helper.rb +3 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a051bec21f907b37d3ff469c65e53854dbd711b5
|
4
|
+
data.tar.gz: 651d542e2a2afc95ebf79c9ad6c9e88ce88d8c94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71db31ffc9c095e681ce72d9784851ecdf14793f53cc6a292fdde681cae9fccc4f1f3609f6d5365b9b25659bdb87c9c2ed8d5920af8f66249f5844f80e801305
|
7
|
+
data.tar.gz: b7aa7ba5fc36665e383c13102da3ae9fd5bd3646b09f84fcb0057b4242e254de88b54bc2b8ca32fe8948b5d1b7f198a6bf67882c29f305a5c0d4fb79e8eaf7f6
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -3,10 +3,12 @@ GEM
|
|
3
3
|
specs:
|
4
4
|
builder (3.2.2)
|
5
5
|
diff-lcs (1.2.5)
|
6
|
+
docile (1.1.5)
|
6
7
|
gyoku (1.2.2)
|
7
8
|
builder (>= 2.1.2)
|
8
9
|
mixlib-cli (1.5.0)
|
9
|
-
|
10
|
+
multi_json (1.10.1)
|
11
|
+
rake (10.4.2)
|
10
12
|
rspec (3.1.0)
|
11
13
|
rspec-core (~> 3.1.0)
|
12
14
|
rspec-expectations (~> 3.1.0)
|
@@ -20,6 +22,11 @@ GEM
|
|
20
22
|
rspec-support (~> 3.1.0)
|
21
23
|
rspec-support (3.1.2)
|
22
24
|
rubygems-tasks (0.2.4)
|
25
|
+
simplecov (0.9.1)
|
26
|
+
docile (~> 1.1.0)
|
27
|
+
multi_json (~> 1.0)
|
28
|
+
simplecov-html (~> 0.8.0)
|
29
|
+
simplecov-html (0.8.0)
|
23
30
|
term-ansicolor (1.3.0)
|
24
31
|
tins (~> 1.0)
|
25
32
|
terminal-table (1.4.5)
|
@@ -34,5 +41,6 @@ DEPENDENCIES
|
|
34
41
|
rake
|
35
42
|
rspec
|
36
43
|
rubygems-tasks
|
44
|
+
simplecov
|
37
45
|
term-ansicolor
|
38
46
|
terminal-table
|
data/bin/gcov2x
CHANGED
@@ -63,18 +63,15 @@ filenames = cli.parse_options
|
|
63
63
|
|
64
64
|
fail "Got no filename" unless filenames.is_a? Array and filenames.count > 0
|
65
65
|
|
66
|
-
STDERR.puts "filter: #{cli.config[:filter]}"
|
67
|
-
|
68
66
|
proj = GCOV::Project.new
|
69
67
|
|
70
68
|
filter = case cli.config[:filter]
|
71
|
-
when :xcode then /Developer\/Toolchains\/.*\/usr\/include\//
|
69
|
+
when :xcode then /Developer\/(Toolchains|Platforms)\/.*\/usr\/include\//
|
72
70
|
when :linux then /\/usr\/include\//
|
71
|
+
when nil then nil
|
73
72
|
else /#{cli.config[:filter]}/
|
74
73
|
end
|
75
74
|
|
76
|
-
STDERR.puts "filter regex: #{filter}"
|
77
|
-
|
78
75
|
filenames.each do |filename|
|
79
76
|
if File.directory? filename
|
80
77
|
proj.add_dir filename, :recursive => cli.config[:recursive], :filter => filter
|
data/lib/file.rb
CHANGED
@@ -24,6 +24,7 @@ module GCOV
|
|
24
24
|
@lines = []
|
25
25
|
@meta = {}
|
26
26
|
@stats = {}
|
27
|
+
_update_stats
|
27
28
|
end
|
28
29
|
|
29
30
|
def add_lines &block
|
@@ -42,7 +43,8 @@ module GCOV
|
|
42
43
|
:total_exec => 0,
|
43
44
|
:total_lines => 0,
|
44
45
|
:lines => 0,
|
45
|
-
:coverage => 0.0
|
46
|
+
:coverage => 0.0,
|
47
|
+
:hits_per_line => 0.0
|
46
48
|
}
|
47
49
|
|
48
50
|
@lines.each do |line|
|
@@ -56,6 +58,8 @@ module GCOV
|
|
56
58
|
@stats[:total_lines] = @stats[:lines] + @stats[:empty_lines]
|
57
59
|
@stats[:coverage] = @stats[:exec_lines].to_f / @stats[:lines].to_f
|
58
60
|
@stats[:coverage_s] = sprintf("%0.01f%",100.0*@stats[:coverage])
|
61
|
+
@stats[:hits_per_line] = @stats[:total_exec].to_f / @stats[:lines]
|
62
|
+
@stats[:hits_per_line_s] = sprintf("%0.02f",@stats[:hits_per_line])
|
59
63
|
end
|
60
64
|
|
61
65
|
def <<(line)
|
@@ -79,6 +83,18 @@ module GCOV
|
|
79
83
|
end
|
80
84
|
file
|
81
85
|
end
|
82
|
-
|
86
|
+
|
87
|
+
def self.demangle filename
|
88
|
+
result = filename
|
89
|
+
if start = result.index(/###/)
|
90
|
+
result = result[start..-1]
|
91
|
+
end
|
92
|
+
|
93
|
+
result.gsub!( /(###|#|\^|\.gcov$)/, {"###"=>"/","#"=>"/","^"=>"..",".gcov"=>""} )
|
94
|
+
result = ::File.realpath(result)
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
end # class File
|
83
99
|
|
84
100
|
end
|
data/lib/html_formatter.rb
CHANGED
@@ -39,15 +39,23 @@ EOF
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
def class_of_stat value,
|
43
|
-
|
44
|
-
|
42
|
+
def class_of_stat value, error_level, warning_level=nil
|
43
|
+
if value <= error_level
|
44
|
+
return "value_error"
|
45
|
+
elsif !warning_level.nil? and value < warning_level
|
46
|
+
return "value_warning"
|
47
|
+
else
|
48
|
+
return "value_ok"
|
49
|
+
end
|
45
50
|
end
|
46
51
|
|
47
|
-
def class_of_file file
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
def class_of_file file, error_level, warning_level=nil
|
53
|
+
if file.stats[:coverage] <= error_level
|
54
|
+
return "header error"
|
55
|
+
elsif !warning_level.nil? and file.stats[:coverage] < warning_level
|
56
|
+
return "header warning"
|
57
|
+
else
|
58
|
+
return "header ok"
|
51
59
|
end
|
52
60
|
end
|
53
61
|
|
data/lib/html_view.html.erb
CHANGED
@@ -38,14 +38,18 @@ if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c
|
|
38
38
|
font-family: Sans-serif;
|
39
39
|
}
|
40
40
|
|
41
|
-
.container .
|
41
|
+
.container .ok {
|
42
42
|
background-color:#bbffbb;
|
43
43
|
}
|
44
44
|
|
45
|
-
.container .
|
45
|
+
.container .error {
|
46
46
|
background-color:#ffbbbb;
|
47
47
|
}
|
48
48
|
|
49
|
+
.container .warning {
|
50
|
+
background-color:#ffdd99;
|
51
|
+
}
|
52
|
+
|
49
53
|
.container .content {
|
50
54
|
display: none;
|
51
55
|
padding : 5px;
|
@@ -124,10 +128,14 @@ if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c
|
|
124
128
|
.stats .value {
|
125
129
|
}
|
126
130
|
|
127
|
-
.stats .
|
131
|
+
.stats .value_error {
|
128
132
|
color:red;
|
129
133
|
}
|
130
134
|
|
135
|
+
.stats .value_warning {
|
136
|
+
color:orange;
|
137
|
+
}
|
138
|
+
|
131
139
|
.stats .stats_header {
|
132
140
|
background-color:#d3d3d3;
|
133
141
|
padding: 2px;
|
@@ -162,17 +170,29 @@ if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c
|
|
162
170
|
</div>
|
163
171
|
|
164
172
|
<div class="toplevel">
|
173
|
+
<div class="stats">
|
174
|
+
<div class="stats_header">Project Statistics</div>
|
175
|
+
<div class="stats_line"><div class="title">Files</div><div class="value"><%=@project.files.count%></div></div>
|
176
|
+
<div class="stats_line"><div class="title">Coverage</div><div class="<%= class_of_stat(@project.stats[:coverage], 0.9, 1)%>"><%=@project.stats[:coverage_s]%></div></div>
|
177
|
+
<div class="stats_line"><div class="title">Total lines</div><div class="value"><%=@project.stats[:total_lines]%></div></div>
|
178
|
+
<div class="stats_line"><div class="title">Executable lines</div><div class="value"><%=@project.stats[:lines]%></div></div>
|
179
|
+
<div class="stats_line"><div class="title">Executed lines</div><div class="value"><%=@project.stats[:exec_lines]%></div></div>
|
180
|
+
<div class="stats_line"><div class="title">Missed lines</div><div class="<%= class_of_stat(@project.stats[:missed_lines],0) %>"><%=@project.stats[:missed_lines]%></div></div>
|
181
|
+
<div class="stats_line"><div class="title">Hits per line</div><div class="value"><%=@project.stats[:hits_per_line_s]%></div></div>
|
182
|
+
</div>
|
183
|
+
<br/ >
|
165
184
|
<% @project.files.each do |file| %>
|
166
185
|
<div class="container">
|
167
|
-
<div class="<%=class_of_file
|
186
|
+
<div class="<%=class_of_file(file,0.9,1)%>"><%=file.meta['Source']%> (<%=file.stats[:coverage_s]%>)</div>
|
168
187
|
<div class="content">
|
169
188
|
<div class="stats">
|
170
|
-
<div class="stats_header">Statistics</div>
|
171
|
-
<div class="stats_line"><div class="title">Coverage</div><div class="<%= class_of_stat(file.stats[:coverage]
|
189
|
+
<div class="stats_header">File Statistics</div>
|
190
|
+
<div class="stats_line"><div class="title">Coverage</div><div class="<%= class_of_stat(file.stats[:coverage], 0.9, 1) %>"><%=file.stats[:coverage_s]%></div></div>
|
172
191
|
<div class="stats_line"><div class="title">Total lines</div><div class="value"><%=file.stats[:total_lines]%></div></div>
|
173
192
|
<div class="stats_line"><div class="title">Executable lines</div><div class="value"><%=file.stats[:lines]%></div></div>
|
174
193
|
<div class="stats_line"><div class="title">Executed lines</div><div class="value"><%=file.stats[:exec_lines]%></div></div>
|
175
|
-
<div class="stats_line"><div class="title">Missed lines</div><div class="<%= class_of_stat(file.stats[:missed_lines])
|
194
|
+
<div class="stats_line"><div class="title">Missed lines</div><div class="<%= class_of_stat(file.stats[:missed_lines],0) %>"><%=file.stats[:missed_lines]%></div></div>
|
195
|
+
<div class="stats_line"><div class="title">Hits per line</div><div class="value"><%=file.stats[:hits_per_line_s]%></div></div>
|
176
196
|
</div>
|
177
197
|
<div class="code">
|
178
198
|
<% file.lines.each do |line| %><div class="<%= class_of line %>"><%= encode(line.text) %></div><% end %>
|
data/lib/line.rb
CHANGED
data/lib/project.rb
CHANGED
@@ -5,54 +5,86 @@ module GCOV
|
|
5
5
|
|
6
6
|
class Project
|
7
7
|
|
8
|
-
attr_reader :files
|
8
|
+
attr_reader :files, :stats
|
9
9
|
attr_accessor :name
|
10
10
|
|
11
11
|
def initialize name=""
|
12
12
|
@name = name
|
13
13
|
@files = []
|
14
|
+
@adding = false
|
14
15
|
end
|
15
16
|
|
16
17
|
def <<(file)
|
17
18
|
@files << file
|
19
|
+
_update_stats unless @adding
|
18
20
|
end
|
19
21
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def add_files &block
|
23
|
+
# suspend stat updates until done adding files
|
24
|
+
fail "add_files requires a block" unless block_given?
|
25
|
+
|
26
|
+
# guard against nested calls
|
27
|
+
was_adding = @adding
|
28
|
+
@adding = true
|
29
|
+
yield
|
30
|
+
@adding = was_adding
|
31
|
+
|
32
|
+
_update_stats unless @adding
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def _update_stats
|
37
|
+
@stats = {
|
38
|
+
:missed_lines => 0,
|
39
|
+
:exec_lines => 0,
|
40
|
+
:empty_lines => 0,
|
41
|
+
:total_exec => 0,
|
42
|
+
:total_lines => 0,
|
43
|
+
:lines => 0,
|
44
|
+
:coverage => 0.0,
|
45
|
+
:hits_per_line => 0
|
46
|
+
}
|
47
|
+
|
48
|
+
@files.each do |file|
|
49
|
+
@stats[:missed_lines] += file.stats[:missed_lines]
|
50
|
+
@stats[:exec_lines] += file.stats[:exec_lines]
|
51
|
+
@stats[:total_exec] += file.stats[:total_exec]
|
52
|
+
@stats[:empty_lines] += file.stats[:empty_lines]
|
24
53
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
54
|
+
|
55
|
+
@stats[:lines] = @stats[:exec_lines] + @stats[:missed_lines]
|
56
|
+
@stats[:total_lines] = @stats[:lines] + @stats[:empty_lines]
|
57
|
+
@stats[:coverage] = @stats[:exec_lines].to_f / @stats[:lines].to_f
|
58
|
+
@stats[:coverage_s] = sprintf("%0.01f%",100.0*@stats[:coverage])
|
59
|
+
@stats[:hits_per_line] = @stats[:total_exec].to_f / @stats[:lines]
|
60
|
+
@stats[:hits_per_line_s] = sprintf("%0.02f",@stats[:hits_per_line])
|
31
61
|
end
|
32
62
|
|
33
63
|
def add_dir path, hash={}
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
STDERR.puts "filenames: #{filenames}"
|
40
|
-
|
41
|
-
filenames.select{|filename| ( hash[:filter].nil? or !hash[:filter].match(demangle(filename))) }.map{|filename| GCOV::File.load filename }.each do |file|
|
42
|
-
if hash[:filter].nil? or !hash[:filter].match( ::File.realpath(file.meta['Source']) )
|
43
|
-
self << file
|
64
|
+
add_files do
|
65
|
+
if hash[:recursive] == true
|
66
|
+
filenames = Dir["#{path}/**/*.gcov"]
|
67
|
+
else
|
68
|
+
filenames = Dir["#{path}/*.gcov"]
|
44
69
|
end
|
45
|
-
|
46
|
-
|
70
|
+
|
71
|
+
filenames.select{|filename| ( hash[:filter].nil? or !hash[:filter].match(GCOV::File.demangle(filename))) }.map{|filename| GCOV::File.load filename }.each do |file|
|
72
|
+
if hash[:filter].nil? or !hash[:filter].match( ::File.realpath(file.meta['Source']) )
|
73
|
+
self << file
|
74
|
+
end
|
75
|
+
end # files
|
76
|
+
end
|
47
77
|
end
|
48
78
|
|
49
79
|
def add_file path, hash={}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
80
|
+
add_files do
|
81
|
+
if hash[:filter].nil? or !hash[:filter].match(GCOV::File.demangle(path))
|
82
|
+
file = GCOV::File.load(path)
|
83
|
+
if hash[:filter].nil? or !hash[:filter].match( ::File.realpath(file.meta['Source']) )
|
84
|
+
self << file
|
85
|
+
end # if
|
54
86
|
end # if
|
55
|
-
end #
|
87
|
+
end # add_files
|
56
88
|
end # add_file
|
57
89
|
|
58
90
|
def self.load_dir path, hash={}
|
data/lib/version.rb
CHANGED
data/spec/file_spec.rb
CHANGED
@@ -39,7 +39,7 @@ describe GCOV::File do
|
|
39
39
|
expect(file.stats[:exec_lines]).to eq(2)
|
40
40
|
expect(file.stats[:missed_lines]).to eq(2)
|
41
41
|
expect(file.stats[:coverage]).to eq(0.5)
|
42
|
-
expect(file.stats[:
|
42
|
+
expect(file.stats[:hits_per_line]).to eq(27.0/4)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -70,4 +70,12 @@ describe GCOV::File do
|
|
70
70
|
expect(file.meta["Runs"].to_i).to eq(1)
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
74
|
+
describe ".demangle" do
|
75
|
+
it "should demangle file names" do
|
76
|
+
demangled = GCOV::File.demangle( "stringutil.cpp.###Applications#Xcode.app#Contents#Developer#Toolchains#XcodeDefault.xctoolchain#usr#bin#^#include#c++#v1#streambuf.gcov" )
|
77
|
+
expect( demangled ).to eq("/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/streambuf")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
73
81
|
end
|
data/spec/project_spec.rb
CHANGED
@@ -81,4 +81,43 @@ describe GCOV::Project do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
|
84
|
+
describe "#stats" do
|
85
|
+
it "should be computed based on file stats" do
|
86
|
+
project = GCOV::Project.new
|
87
|
+
|
88
|
+
project.add_files do
|
89
|
+
file = GCOV::File.new "myfile.cpp"
|
90
|
+
file.add_lines do
|
91
|
+
file << GCOV::Line.new(1,4,"line 1")
|
92
|
+
file << GCOV::Line.new(2,23,"line 2")
|
93
|
+
file << GCOV::Line.new(3,:none,"line 3")
|
94
|
+
file << GCOV::Line.new(4,:missed,"line 4")
|
95
|
+
file << GCOV::Line.new(5,:none,"line 5")
|
96
|
+
end
|
97
|
+
|
98
|
+
project << file
|
99
|
+
|
100
|
+
file = GCOV::File.new "myfile.cpp"
|
101
|
+
file.add_lines do
|
102
|
+
file << GCOV::Line.new(1,:missed,"line 1")
|
103
|
+
file << GCOV::Line.new(2,40,"line 2")
|
104
|
+
file << GCOV::Line.new(3,:none,"line 3")
|
105
|
+
file << GCOV::Line.new(4,:none,"line 4")
|
106
|
+
end
|
107
|
+
|
108
|
+
project << file
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
expect(project.stats[:lines]).to eq(5)
|
113
|
+
expect(project.stats[:total_lines]).to eq(9)
|
114
|
+
expect(project.stats[:total_exec]).to eq(67)
|
115
|
+
expect(project.stats[:empty_lines]).to eq(4)
|
116
|
+
expect(project.stats[:exec_lines]).to eq(3)
|
117
|
+
expect(project.stats[:missed_lines]).to eq(2)
|
118
|
+
expect(project.stats[:coverage]).to eq(3.0/5)
|
119
|
+
expect(project.stats[:hits_per_line]).to eq(67.0/5)
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
84
123
|
end
|
data/spec/spec_helper.rb
CHANGED