coco 0.13.0 → 0.14.0
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/CONTRIBUTORS +9 -0
- data/Changelog.markdown +42 -0
- data/Gemfile.lock +36 -55
- data/LICENSE +7 -0
- data/README.markdown +124 -73
- data/Rakefile +10 -37
- data/VERSION +1 -1
- data/lib/coco.rb +9 -21
- data/lib/coco/configuration.rb +59 -20
- data/lib/coco/cover.rb +1 -0
- data/lib/coco/cover/coverage_result.rb +72 -16
- data/lib/coco/cover/coverage_stat.rb +20 -8
- data/lib/coco/cover/summary.rb +50 -0
- data/lib/coco/deprecated_message.rb +31 -0
- data/lib/coco/formatter.rb +2 -2
- data/lib/coco/formatter/colored_string.rb +1 -1
- data/lib/coco/formatter/console_formatter.rb +24 -19
- data/lib/coco/formatter/context.rb +10 -39
- data/lib/coco/formatter/html_formatter.rb +7 -13
- data/lib/coco/formatter/html_index_formatter.rb +20 -16
- data/lib/coco/formatter/index_context.rb +37 -0
- data/lib/coco/formatter/index_line.rb +21 -0
- data/lib/coco/formatter/template.rb +2 -3
- data/lib/coco/helpers.rb +88 -68
- data/lib/coco/lister/source_lister.rb +23 -26
- data/lib/coco/lister/uncovered_lister.rb +6 -9
- data/lib/coco/project.rb +65 -0
- data/lib/coco/theme.rb +15 -0
- data/lib/coco/writer/file_writer.rb +5 -5
- data/lib/coco/writer/html_directory.rb +16 -8
- data/lib/coco/writer/html_files_writer.rb +9 -6
- data/lib/coco/writer/html_index_writer.rb +6 -3
- data/template/css/dark.css +178 -0
- data/template/css/{coco.css → light.css} +22 -9
- data/template/file.erb +3 -3
- data/template/index.erb +35 -33
- data/template/js/coco.js +18 -0
- metadata +34 -58
- data/COPYING +0 -674
- data/lib/coco/formatter/formatter.rb +0 -23
- data/template/img/coconut16.png +0 -0
- data/template/img/licenses +0 -19
@@ -2,16 +2,12 @@ module Coco
|
|
2
2
|
|
3
3
|
# I retrieve the .rb files from a list of directories.
|
4
4
|
class SourceLister
|
5
|
-
|
5
|
+
|
6
6
|
# config - Hash.
|
7
7
|
def initialize(config)
|
8
|
-
@exclude_files = config[:
|
9
|
-
dirs = config[:
|
10
|
-
|
11
|
-
@folders = [dirs]
|
12
|
-
else
|
13
|
-
@folders = dirs
|
14
|
-
end
|
8
|
+
@exclude_files = config[:exclude]
|
9
|
+
dirs = config[:include]
|
10
|
+
@folders = [*dirs]
|
15
11
|
@folders.each do |folder|
|
16
12
|
unless File.directory?(folder)
|
17
13
|
raise ArgumentError, "Not a folder: #{folder}"
|
@@ -19,41 +15,42 @@ module Coco
|
|
19
15
|
end
|
20
16
|
@list = []
|
21
17
|
end
|
22
|
-
|
18
|
+
|
23
19
|
# Returns Array of String, that is a list of all `.rb` files from
|
24
20
|
# the directories found in configuration.
|
25
21
|
def list
|
26
22
|
look_for_sources
|
27
|
-
@list.map! {|file| File.expand_path(file) }
|
28
|
-
exclude_files_user_dont_want
|
23
|
+
@list.map! { |file| File.expand_path(file) }
|
24
|
+
exclude_files_user_dont_want if @exclude_files
|
29
25
|
@list
|
30
26
|
end
|
31
|
-
|
27
|
+
|
32
28
|
private
|
33
|
-
|
29
|
+
|
34
30
|
def look_for_sources
|
35
|
-
@folders.each
|
31
|
+
@folders.each do |folder|
|
32
|
+
@list += Helpers.rb_files_from folder
|
33
|
+
end
|
36
34
|
end
|
37
|
-
|
35
|
+
|
38
36
|
def exclude_files_user_dont_want
|
39
|
-
return if @exclude_files.nil?
|
40
|
-
|
41
37
|
@exclude_files.each do |filename|
|
42
|
-
|
43
|
-
if File.file?(full_path)
|
44
|
-
@list.delete full_path
|
45
|
-
elsif File.directory?(full_path)
|
46
|
-
exclude_all_from_dir full_path
|
47
|
-
end
|
38
|
+
exclude_path(File.expand_path(filename))
|
48
39
|
end
|
49
40
|
end
|
50
|
-
|
41
|
+
|
42
|
+
def exclude_path(full_path)
|
43
|
+
if File.file?(full_path)
|
44
|
+
@list.delete full_path
|
45
|
+
elsif File.directory?(full_path)
|
46
|
+
exclude_all_from_dir full_path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
51
50
|
def exclude_all_from_dir(full_path)
|
52
51
|
Helpers.rb_files_from(full_path).each do |file|
|
53
52
|
@list.delete File.expand_path(file)
|
54
53
|
end
|
55
54
|
end
|
56
|
-
|
57
55
|
end
|
58
|
-
|
59
56
|
end
|
@@ -1,24 +1,21 @@
|
|
1
1
|
module Coco
|
2
2
|
|
3
3
|
# I retrieve the list of uncovered (0%) .rb files.
|
4
|
+
#
|
4
5
|
class UncoveredLister
|
5
|
-
|
6
|
+
|
6
7
|
# sources - Array of String list of filenames.
|
7
8
|
# covered - Hash raw coverage from the domain.
|
9
|
+
#
|
8
10
|
def initialize(sources, covered)
|
9
11
|
@source_files = Helpers.expand(sources)
|
10
12
|
@covered_files = Helpers.expand(covered.keys)
|
11
13
|
end
|
12
|
-
|
14
|
+
|
13
15
|
# Returns Array of String list of uncovered filenames.
|
16
|
+
#
|
14
17
|
def list
|
15
|
-
|
16
|
-
@source_files.each do |elem|
|
17
|
-
list << elem unless @covered_files.include?(elem)
|
18
|
-
end
|
19
|
-
list
|
18
|
+
@source_files.select { |elem| !@covered_files.include?(elem) }
|
20
19
|
end
|
21
|
-
|
22
20
|
end
|
23
|
-
|
24
21
|
end
|
data/lib/coco/project.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Coco
|
2
|
+
|
3
|
+
# A project reports statistics about the code coverage.
|
4
|
+
#
|
5
|
+
class Project
|
6
|
+
|
7
|
+
# raw_result - The hash obtain by the call to `Coverage.result`.
|
8
|
+
# out - The output where results will be displayed, by
|
9
|
+
# default this is stdout.
|
10
|
+
#
|
11
|
+
def self.run(raw_result, out = STDOUT)
|
12
|
+
new(raw_result, out).run
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(raw_result, out)
|
16
|
+
@raw_result = raw_result
|
17
|
+
@out = out
|
18
|
+
@config = Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
return unless @config.run_this_time?
|
23
|
+
|
24
|
+
report_on_console
|
25
|
+
report_in_html
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def report_on_console
|
31
|
+
formatter = ConsoleFormatter.new(uncovered, @config[:threshold],
|
32
|
+
result, @config)
|
33
|
+
@out.puts formatter.format
|
34
|
+
@out.puts formatter.link if @config[:show_link_in_terminal]
|
35
|
+
end
|
36
|
+
|
37
|
+
def report_in_html
|
38
|
+
report_code_files
|
39
|
+
report_index
|
40
|
+
end
|
41
|
+
|
42
|
+
def report_code_files
|
43
|
+
files = HtmlFormatter.new(result.coverable_files).format
|
44
|
+
HtmlFilesWriter.new(files, @config[:theme]).write
|
45
|
+
end
|
46
|
+
|
47
|
+
def report_index
|
48
|
+
index = HtmlIndexFormatter.new(uncovered, result,
|
49
|
+
@config[:threshold]).format
|
50
|
+
HtmlIndexWriter.new(index).write
|
51
|
+
end
|
52
|
+
|
53
|
+
def result
|
54
|
+
@result ||= CoverageResult.new(@config, @raw_result)
|
55
|
+
end
|
56
|
+
|
57
|
+
def uncovered
|
58
|
+
@uncovered ||= UncoveredLister.new(sources, result.coverable_files).list
|
59
|
+
end
|
60
|
+
|
61
|
+
def sources
|
62
|
+
SourceLister.new(@config).list
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/coco/theme.rb
ADDED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Coco
|
2
|
-
|
2
|
+
|
3
3
|
# Public: I write a single file.
|
4
|
+
#
|
4
5
|
module FileWriter
|
5
|
-
extend self
|
6
6
|
|
7
7
|
# Public: Write a file.
|
8
8
|
#
|
@@ -10,9 +10,9 @@ module Coco
|
|
10
10
|
# content - String content to put in the file.
|
11
11
|
#
|
12
12
|
# Returns nothing.
|
13
|
-
|
14
|
-
|
13
|
+
#
|
14
|
+
def self.write(filename, content)
|
15
|
+
File.open(filename, 'w') { |file| file.write(content) }
|
15
16
|
end
|
16
17
|
end
|
17
|
-
|
18
18
|
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module Coco
|
2
2
|
|
3
3
|
# Public: I prepare the coverage/ directory for html files.
|
4
|
+
#
|
4
5
|
class HtmlDirectory
|
5
|
-
COVERAGE_DIR = 'coverage'
|
6
|
+
COVERAGE_DIR = 'coverage'.freeze
|
6
7
|
|
7
8
|
# Public: Initialize a new HtmlDirectory object.
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
#
|
10
|
+
# theme - The String name of the theme. There is 2 builtin themes :
|
11
|
+
# light & dark. The default one is light.
|
12
|
+
#
|
13
|
+
def initialize(theme = 'light')
|
14
|
+
@theme = Theme.new(theme)
|
11
15
|
img = File.join(Coco::ROOT, 'template/img')
|
12
16
|
@img_files = Dir.glob(img + '/*')
|
13
17
|
end
|
@@ -32,10 +36,10 @@ module Coco
|
|
32
36
|
#
|
33
37
|
# Returns nothing.
|
34
38
|
def setup
|
35
|
-
FileUtils.makedirs(css_dir)
|
36
|
-
FileUtils.
|
37
|
-
FileUtils.cp(@css_files, css_dir)
|
39
|
+
FileUtils.makedirs([css_dir, image_dir, js_dir])
|
40
|
+
FileUtils.cp(@theme.filename, File.join(css_dir, 'coco.css'))
|
38
41
|
FileUtils.cp(@img_files, image_dir)
|
42
|
+
FileUtils.cp(File.join(Coco::ROOT, 'template/js/coco.js'), js_dir)
|
39
43
|
end
|
40
44
|
|
41
45
|
# Public: I list the html files from the directory where the HTML
|
@@ -44,7 +48,7 @@ module Coco
|
|
44
48
|
# Returns nothing.
|
45
49
|
def list
|
46
50
|
files = Dir.glob("#{coverage_dir}/*.html")
|
47
|
-
files.map {|file| File.basename(file) }
|
51
|
+
files.map { |file| File.basename(file) }
|
48
52
|
end
|
49
53
|
|
50
54
|
private
|
@@ -56,5 +60,9 @@ module Coco
|
|
56
60
|
def image_dir
|
57
61
|
"#{COVERAGE_DIR}/img"
|
58
62
|
end
|
63
|
+
|
64
|
+
def js_dir
|
65
|
+
"#{COVERAGE_DIR}/js"
|
66
|
+
end
|
59
67
|
end
|
60
68
|
end
|
@@ -6,20 +6,23 @@ module Coco
|
|
6
6
|
# Public: Initialize a new HtmlFilesWriter.
|
7
7
|
#
|
8
8
|
# html_files - Hash, key is filename, value is html content.
|
9
|
-
|
9
|
+
# theme - The String name of the theme. Default is light.
|
10
|
+
#
|
11
|
+
def initialize(html_files, theme = 'light')
|
10
12
|
@html_files = html_files
|
11
|
-
@html_dir = HtmlDirectory.new
|
13
|
+
@html_dir = HtmlDirectory.new(theme)
|
12
14
|
end
|
13
15
|
|
14
16
|
# Public: Write HTML files in the right place.
|
15
17
|
#
|
16
18
|
# Returns nothing.
|
19
|
+
#
|
17
20
|
def write
|
18
21
|
@html_dir.clean
|
19
|
-
if @html_files.
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
return if @html_files.empty?
|
23
|
+
|
24
|
+
@html_dir.setup
|
25
|
+
write_each_file
|
23
26
|
end
|
24
27
|
|
25
28
|
private
|
@@ -1,19 +1,22 @@
|
|
1
1
|
module Coco
|
2
|
-
|
2
|
+
|
3
3
|
# Public: I write the index.html
|
4
|
+
#
|
4
5
|
class HtmlIndexWriter
|
5
|
-
|
6
|
+
|
6
7
|
# Public: Initialize a new HtmlIndexWriter object.
|
7
8
|
#
|
8
9
|
# index - A String HTML document.
|
10
|
+
#
|
9
11
|
def initialize(index)
|
10
12
|
@index = index
|
11
13
|
@dir = HtmlDirectory.new.coverage_dir
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
# Public: Write the index file in the right place.
|
15
17
|
#
|
16
18
|
# Returns nothing.
|
19
|
+
#
|
17
20
|
def write
|
18
21
|
if File.exist?(@dir)
|
19
22
|
FileWriter.write File.join(@dir, 'index.html'), @index
|
@@ -0,0 +1,178 @@
|
|
1
|
+
@charset "UTF-8";
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Dark theme for Coco.
|
5
|
+
*/
|
6
|
+
|
7
|
+
table.source {
|
8
|
+
border-collapse:collapse;
|
9
|
+
border-spacing: 0;
|
10
|
+
}
|
11
|
+
|
12
|
+
table.index tr {
|
13
|
+
height: 1.8em;
|
14
|
+
}
|
15
|
+
|
16
|
+
table.index td {
|
17
|
+
padding-left: 0.5em;
|
18
|
+
}
|
19
|
+
|
20
|
+
html {
|
21
|
+
background-color: #505050;
|
22
|
+
color: #F5F5F5;
|
23
|
+
}
|
24
|
+
|
25
|
+
body {
|
26
|
+
margin: 0;
|
27
|
+
}
|
28
|
+
|
29
|
+
h2 {
|
30
|
+
padding: 10px;
|
31
|
+
background-color: #6A9FB5;
|
32
|
+
color: #F5F5F5;
|
33
|
+
font-size: 1.1em;
|
34
|
+
}
|
35
|
+
|
36
|
+
a {
|
37
|
+
color: #F5F5F5;
|
38
|
+
text-decoration: none;
|
39
|
+
}
|
40
|
+
|
41
|
+
p {
|
42
|
+
margin: 1em;
|
43
|
+
}
|
44
|
+
|
45
|
+
p.menu a {
|
46
|
+
font-weight: bold;
|
47
|
+
}
|
48
|
+
|
49
|
+
p.date {
|
50
|
+
font-size: 80%;
|
51
|
+
}
|
52
|
+
|
53
|
+
table {
|
54
|
+
width: 100%;
|
55
|
+
}
|
56
|
+
|
57
|
+
table td {
|
58
|
+
border-width: 0;
|
59
|
+
}
|
60
|
+
|
61
|
+
table.source td {
|
62
|
+
padding-top: 0;
|
63
|
+
padding-bottom: 0;
|
64
|
+
padding-left: 0;
|
65
|
+
}
|
66
|
+
|
67
|
+
thead {
|
68
|
+
font-weight: bold;
|
69
|
+
background-color: #404040;
|
70
|
+
text-align: center;
|
71
|
+
}
|
72
|
+
|
73
|
+
td,
|
74
|
+
td a {
|
75
|
+
color: #B0B0B0;
|
76
|
+
}
|
77
|
+
|
78
|
+
td b,
|
79
|
+
td a b {
|
80
|
+
color: #F5F5F5;
|
81
|
+
}
|
82
|
+
|
83
|
+
tr.never {
|
84
|
+
background-color: #505050;
|
85
|
+
}
|
86
|
+
|
87
|
+
tr.hit {
|
88
|
+
background-color: #506939;
|
89
|
+
}
|
90
|
+
|
91
|
+
tr.hit:hover {
|
92
|
+
background-color: #90A959;
|
93
|
+
}
|
94
|
+
|
95
|
+
tr.miss {
|
96
|
+
background-color: #AC4142;
|
97
|
+
}
|
98
|
+
|
99
|
+
tr.miss:hover {
|
100
|
+
background-color: #E65758;
|
101
|
+
}
|
102
|
+
|
103
|
+
td.yellow, td.red, td.black, td.green {
|
104
|
+
width: 45px;
|
105
|
+
}
|
106
|
+
|
107
|
+
td.yellow {
|
108
|
+
background-color: #F4BF75;
|
109
|
+
color: #202020;
|
110
|
+
}
|
111
|
+
|
112
|
+
td.red {
|
113
|
+
background-color: #AC4142;
|
114
|
+
color: #F5F5F5;
|
115
|
+
}
|
116
|
+
|
117
|
+
td.black {
|
118
|
+
background-color: #404040;
|
119
|
+
color: #F5F5F5;
|
120
|
+
}
|
121
|
+
|
122
|
+
td.green {
|
123
|
+
background-color: #90A959;
|
124
|
+
color: #F5F5F5;
|
125
|
+
}
|
126
|
+
|
127
|
+
td.percentage {
|
128
|
+
text-align: right;
|
129
|
+
padding-right: 20px;
|
130
|
+
}
|
131
|
+
|
132
|
+
td.line-num,
|
133
|
+
td.line-hits,
|
134
|
+
td.line-source {
|
135
|
+
color: #F5F5F5;
|
136
|
+
}
|
137
|
+
|
138
|
+
td.line-num,
|
139
|
+
td.line-hits {
|
140
|
+
width: 10%;
|
141
|
+
text-align: right;
|
142
|
+
}
|
143
|
+
|
144
|
+
td.line-source {
|
145
|
+
padding-right: 0;
|
146
|
+
}
|
147
|
+
|
148
|
+
td.line-num {
|
149
|
+
padding-right: 5px;
|
150
|
+
}
|
151
|
+
|
152
|
+
td.line-hits {
|
153
|
+
padding-right: 20px;
|
154
|
+
}
|
155
|
+
|
156
|
+
th {
|
157
|
+
padding-bottom: 5px;
|
158
|
+
padding-top: 5px;
|
159
|
+
}
|
160
|
+
|
161
|
+
pre {
|
162
|
+
margin: 6px 0;
|
163
|
+
}
|
164
|
+
|
165
|
+
.summary {
|
166
|
+
font-size: 150%;
|
167
|
+
color: #F5F5F5;
|
168
|
+
}
|
169
|
+
|
170
|
+
.summary-rate, .summary-uncovered, .summary-files {
|
171
|
+
background-color: #6A9FB5;
|
172
|
+
padding: 5px 10px;
|
173
|
+
margin-right: 20px;
|
174
|
+
}
|
175
|
+
|
176
|
+
#bis {
|
177
|
+
display: none;
|
178
|
+
}
|