coco 0.10.0 → 0.11.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/Changelog.markdown +20 -9
- data/Gemfile +0 -3
- data/README.markdown +9 -0
- data/Rakefile +10 -9
- data/VERSION +1 -1
- data/lib/coco.rb +4 -2
- data/lib/coco/configuration.rb +9 -3
- data/lib/coco/cover/coverage_result.rb +4 -4
- data/lib/coco/cover/coverage_stat.rb +26 -19
- data/lib/coco/formatter/colored_string.rb +16 -9
- data/lib/coco/formatter/console_formatter.rb +4 -8
- data/lib/coco/formatter/context.rb +29 -7
- data/lib/coco/formatter/formatter.rb +6 -9
- data/lib/coco/formatter/html_formatter.rb +11 -10
- data/lib/coco/formatter/html_index_formatter.rb +13 -12
- data/lib/coco/formatter/template.rb +1 -1
- data/lib/coco/helpers.rb +5 -5
- data/lib/coco/lister/source_lister.rb +3 -3
- data/lib/coco/lister/uncovered_lister.rb +1 -1
- data/lib/coco/writer/file_writer.rb +12 -6
- data/lib/coco/writer/html_directory.rb +45 -22
- data/lib/coco/writer/html_files_writer.rb +12 -9
- data/lib/coco/writer/html_index_writer.rb +8 -4
- data/template/css/coco.css +35 -3
- data/template/file.erb +18 -9
- data/template/index.erb +6 -12
- metadata +44 -4
- data/Gemfile.lock +0 -43
- data/TODO +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f3f3919f636ca63d3f48631e04e2f5a2d803844
|
4
|
+
data.tar.gz: cf8c9967b7790f2c9794fa92006b1a818265c68e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95d444f5b8268451ab0f3e2ae044233a6540f0741b41d68adf7089a0b48f708db9e5365e722affde368c0e9748874d45533d55405d90a02f01992f8bc1130f4e
|
7
|
+
data.tar.gz: ca9e2c8ac2e133c3c2ff13d281b0c1c266333b85755ad16cd5ce7259436b043f7005cb4e7faf93a5dabe09afafa8731eb8ad9121538cd4959286e38e70194bca
|
data/Changelog.markdown
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
v0.11.0 (2014-05-24)
|
2
|
+
=================================================
|
3
|
+
|
4
|
+
* Properly escape HTML in report.
|
5
|
+
* Implements hit counters.
|
6
|
+
* Output warnings for deprecated features.
|
7
|
+
* Development/test
|
8
|
+
- Improve documentation for developers.
|
9
|
+
- Add Rake tasks for documentation.
|
10
|
+
- Fix a random failing test
|
11
|
+
- Remove command line garbage after tests
|
12
|
+
- Update developer dependencies
|
13
|
+
|
1
14
|
v0.10.0 (2014-05-03)
|
2
15
|
=================================================
|
3
16
|
|
@@ -39,7 +52,7 @@ v0.7.1 (2013-07-05)
|
|
39
52
|
v0.7 (2013-06-19)
|
40
53
|
=================================================
|
41
54
|
|
42
|
-
* Bugfix: single_line_report option is now silent if there is nothing to
|
55
|
+
* Bugfix: `single_line_report` option is now silent if there is nothing to
|
43
56
|
report
|
44
57
|
* Improve report styling (a bit)
|
45
58
|
* Default threshold is now 100%
|
@@ -49,7 +62,7 @@ v0.7 (2013-06-19)
|
|
49
62
|
v0.6 (2011-10-30)
|
50
63
|
=================================================
|
51
64
|
|
52
|
-
* Added an option
|
65
|
+
* Added an option `single_line_report`
|
53
66
|
|
54
67
|
|
55
68
|
v0.5.1 (2011-08-08)
|
@@ -68,11 +81,9 @@ v0.5 (2011-03-14)
|
|
68
81
|
v0.4.2 (2011-03-01)
|
69
82
|
=================================================
|
70
83
|
|
71
|
-
|
72
|
-
|
73
|
-
*
|
74
|
-
* #13: '<' and '>' are not escaped in hml report
|
75
|
-
* #12: no link to web site in html files
|
84
|
+
* Fix bug #14 Sometimes text exit on the right from table in html report
|
85
|
+
* Fix bug #13 '<' and '>' are not escaped in hml report
|
86
|
+
* Fix bug #12 No link to web site in html files
|
76
87
|
|
77
88
|
|
78
89
|
v0.4.1 (2011-02-27)
|
@@ -84,8 +95,8 @@ v0.4.1 (2011-02-27)
|
|
84
95
|
v0.4 (2011-02-26)
|
85
96
|
=================================================
|
86
97
|
|
87
|
-
*
|
88
|
-
*
|
98
|
+
* Add colors to console output (nix only)
|
99
|
+
* It can exclude unwanted files from the report
|
89
100
|
|
90
101
|
|
91
102
|
v0.3 (2011-02-25)
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -19,8 +19,15 @@ Features
|
|
19
19
|
Install
|
20
20
|
--------------------------------
|
21
21
|
|
22
|
+
In your Gemfile:
|
23
|
+
|
24
|
+
gem coco
|
25
|
+
|
26
|
+
Or directly:
|
27
|
+
|
22
28
|
gem install coco
|
23
29
|
|
30
|
+
|
24
31
|
Usage
|
25
32
|
--------------------------------
|
26
33
|
Require the coco library at the beginning of your tests:
|
@@ -174,3 +181,5 @@ Contributors
|
|
174
181
|
[sunaku (Suraj N. Kurapati)](https://github.com/sunaku)
|
175
182
|
|
176
183
|
[Daniel Rice](https://github.com/BigNerdRanchDan)
|
184
|
+
|
185
|
+
[Gioele](https://github.com/gioele)
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'bundler/gem_tasks'
|
3
4
|
require 'rake/dsl_definition'
|
4
5
|
require 'rake'
|
5
6
|
require 'rspec/core/rake_task'
|
@@ -39,14 +40,14 @@ task :metrics do
|
|
39
40
|
Rake::Task['flay'].execute
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
43
|
+
namespace :doc do
|
44
|
+
desc 'Generate documentation for developpers'
|
45
|
+
task :create do
|
46
|
+
exec 'yardoc'
|
47
|
+
end
|
48
48
|
|
49
|
-
desc '
|
50
|
-
task :
|
51
|
-
|
49
|
+
desc 'Delete documentation'
|
50
|
+
task :clean do
|
51
|
+
rm_rf 'doc'
|
52
|
+
end
|
52
53
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.11.0
|
data/lib/coco.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
-
$LOAD_PATH.unshift File.dirname(__FILE__)
|
4
|
-
$COCO_PATH = File.expand_path(File.expand_path(File.dirname(__FILE__)) + '/..')
|
5
3
|
require 'coco/formatter'
|
6
4
|
require 'coco/cover'
|
7
5
|
require 'coco/writer'
|
8
6
|
require 'coco/helpers'
|
9
7
|
require 'coco/configuration'
|
10
8
|
require 'coco/lister'
|
9
|
+
|
11
10
|
require 'coverage'
|
12
11
|
|
12
|
+
# Public: Main namespace of Coco, a code coverage utilily for
|
13
|
+
# Ruby from 1.9.3 to 2.1.
|
13
14
|
module Coco
|
15
|
+
ROOT = File.expand_path(File.dirname(__FILE__) + '/..').freeze
|
14
16
|
end
|
15
17
|
|
16
18
|
Coverage.start
|
data/lib/coco/configuration.rb
CHANGED
@@ -34,6 +34,8 @@ module Coco
|
|
34
34
|
self.merge!(YAML.load_file('.coco.yml'))
|
35
35
|
# Deprecated: Support of '.coco' file will be removed in v1.0.
|
36
36
|
elsif File.exist?('.coco')
|
37
|
+
warn('Please use `.coco.yml` instead of `.coco`.')
|
38
|
+
warn('Support for `.coco` will be removed in future versions.')
|
37
39
|
self.merge!(YAML.load_file('.coco'))
|
38
40
|
end
|
39
41
|
|
@@ -70,16 +72,20 @@ module Coco
|
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
73
|
-
def add_files
|
75
|
+
def add_files(dir)
|
74
76
|
Helpers.rb_files_from(dir).each {|file| self[:excludes] << file }
|
75
77
|
end
|
76
78
|
|
77
79
|
def remove_directories
|
78
|
-
self[:excludes].delete_if {|file_or_dir| File.directory?(file_or_dir)}
|
80
|
+
self[:excludes].delete_if {|file_or_dir| File.directory?(file_or_dir) }
|
79
81
|
end
|
80
82
|
|
81
83
|
def ensure_threeshold_compatibility
|
82
|
-
|
84
|
+
if !self[:threeshold].nil?
|
85
|
+
warn('Please change `threeshold` to `threshold`.')
|
86
|
+
warn('Support for the misspelt `threeshold` configuration key will be removed in future COCO versions.')
|
87
|
+
self[:threshold] = self[:threeshold]
|
88
|
+
end
|
83
89
|
end
|
84
90
|
|
85
91
|
end
|
@@ -20,7 +20,7 @@ module Coco
|
|
20
20
|
#
|
21
21
|
# config - Hash
|
22
22
|
# raw_results - Hash results obtained from Coverage.result.
|
23
|
-
def initialize
|
23
|
+
def initialize(config, raw_results)
|
24
24
|
@exclude_files = config[:excludes]
|
25
25
|
@threshold = config[:threshold]
|
26
26
|
raise ArgumentError if @threshold < 0
|
@@ -34,7 +34,7 @@ module Coco
|
|
34
34
|
|
35
35
|
def exclude_external_sources
|
36
36
|
here = Dir.pwd
|
37
|
-
@all_from_domain = @result.select {|key, value| key.start_with?
|
37
|
+
@all_from_domain = @result.select {|key, value| key.start_with?(here) }
|
38
38
|
end
|
39
39
|
|
40
40
|
def exclude_files_user_dont_want
|
@@ -45,9 +45,9 @@ module Coco
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def exclude_sources_above_threshold
|
48
|
-
@covered_from_domain = @all_from_domain.select
|
48
|
+
@covered_from_domain = @all_from_domain.select do |key, value|
|
49
49
|
CoverageStat.coverage_percent(value) < @threshold
|
50
|
-
|
50
|
+
end
|
51
51
|
end
|
52
52
|
|
53
53
|
end
|
@@ -2,32 +2,39 @@
|
|
2
2
|
|
3
3
|
module Coco
|
4
4
|
|
5
|
-
# Give statistics about an array of lines hit.
|
5
|
+
# Public: Give statistics about an array of lines hit.
|
6
6
|
#
|
7
7
|
# An "array of lines hit" is an array of integers, possibly nil.
|
8
8
|
# Such array is obtain from Coverage.result.
|
9
9
|
#
|
10
10
|
# Each integer represent the state of a source line:
|
11
|
-
# * nil: source line will never be reached (like comments)
|
12
|
-
# * 0: source line could be reached, but was not
|
13
|
-
# * 1 and above: number of time the source line has been reached
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
hits = CoverageStat.remove_nil_from hits
|
11
|
+
# * nil: source line will never be reached (like comments).
|
12
|
+
# * 0: source line could be reached, but was not.
|
13
|
+
# * 1 and above: number of time the source line has been reached.
|
14
|
+
module CoverageStat
|
15
|
+
extend self
|
16
|
+
|
17
|
+
# Public: Compute the percentage of code coverage for a file.
|
18
|
+
# The file is represented by an array of hits.
|
19
|
+
#
|
20
|
+
# hits - Array of Integer.
|
21
|
+
#
|
22
|
+
# Returns a Integer (rounded) percentage.
|
23
|
+
def coverage_percent(hits)
|
24
|
+
hits = hits.compact
|
26
25
|
return 0 if hits.empty?
|
27
26
|
one_percent = 100.0 / hits.size
|
28
|
-
(
|
27
|
+
(number_of_covered_lines(hits) * one_percent).to_i
|
29
28
|
end
|
30
|
-
|
29
|
+
|
30
|
+
# Compute the total of covered lines in a hits array.
|
31
|
+
#
|
32
|
+
# hits - Array of Integer.
|
33
|
+
#
|
34
|
+
# Returns Integer.
|
35
|
+
def number_of_covered_lines(hits)
|
36
|
+
hits.select {|hit| hit > 0 }.size
|
37
|
+
end
|
38
|
+
|
31
39
|
end
|
32
|
-
|
33
40
|
end
|
@@ -2,32 +2,39 @@
|
|
2
2
|
|
3
3
|
module Coco
|
4
4
|
|
5
|
-
#
|
5
|
+
# Public: Build String with ANSI colorization.
|
6
6
|
# Do nothing on Windows.
|
7
7
|
class ColoredString < String
|
8
|
-
|
8
|
+
|
9
|
+
# Public: Initialize a new ColoredString object.
|
10
|
+
#
|
11
|
+
# str - A String.
|
9
12
|
def initialize(str="")
|
10
13
|
super(str)
|
11
14
|
end
|
12
|
-
|
15
|
+
|
16
|
+
# Public: Make a red string.
|
17
|
+
#
|
18
|
+
# Returns String ANSIfied in red.
|
13
19
|
def red
|
14
20
|
colorize "\033[31m"
|
15
21
|
end
|
16
|
-
|
22
|
+
|
23
|
+
# Public: Make a yellow string.
|
24
|
+
#
|
25
|
+
# Returns String ANSIfied in yellow.
|
17
26
|
def yellow
|
18
27
|
colorize "\033[33m"
|
19
28
|
end
|
20
|
-
|
29
|
+
|
21
30
|
private
|
22
|
-
|
23
|
-
def colorize
|
31
|
+
|
32
|
+
def colorize(color_code)
|
24
33
|
if RUBY_PLATFORM =~ /win32/
|
25
34
|
self
|
26
35
|
else
|
27
36
|
"#{color_code}#{self}\033[0m"
|
28
37
|
end
|
29
38
|
end
|
30
|
-
|
31
39
|
end
|
32
|
-
|
33
40
|
end
|
@@ -9,11 +9,7 @@ module Coco
|
|
9
9
|
#
|
10
10
|
# Returns percent covered and associated filenames as a String.
|
11
11
|
def format(single_line_report = false)
|
12
|
-
|
13
|
-
single_line_message
|
14
|
-
else
|
15
|
-
@formatted_output.join("\n")
|
16
|
-
end
|
12
|
+
single_line_report ? single_line_message : @formatted_output.join("\n")
|
17
13
|
end
|
18
14
|
|
19
15
|
# Returns String.
|
@@ -27,8 +23,8 @@ module Coco
|
|
27
23
|
|
28
24
|
# covered - Hash
|
29
25
|
# uncovered - Array
|
30
|
-
def initialize
|
31
|
-
super
|
26
|
+
def initialize(covered, uncovered)
|
27
|
+
super
|
32
28
|
@formatted_output = []
|
33
29
|
compute_percentage
|
34
30
|
add_percentage_to_uncovered
|
@@ -53,7 +49,7 @@ module Coco
|
|
53
49
|
end
|
54
50
|
|
55
51
|
def add_percentage_to_uncovered
|
56
|
-
@uncovered.each
|
52
|
+
@uncovered.each {|filename| @formatted_output << [0, filename] }
|
57
53
|
end
|
58
54
|
|
59
55
|
def single_line_message
|
@@ -1,32 +1,54 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
module Coco
|
4
|
-
|
4
|
+
|
5
5
|
# Contextual information for ERB template, representing each covered files.
|
6
6
|
class Context
|
7
|
-
|
7
|
+
|
8
|
+
# Public: Initialize a Context for a covered file shown in the HTML
|
9
|
+
# report.
|
10
|
+
#
|
8
11
|
# filename - A String name of the source file.
|
9
12
|
# lines - An Array of lines.
|
10
|
-
def initialize
|
13
|
+
def initialize(filename, lines)
|
11
14
|
@filename = filename
|
12
15
|
@lines = lines
|
13
16
|
end
|
14
17
|
|
18
|
+
# Public: Get the object's binding.
|
19
|
+
#
|
20
|
+
# Returns Binding.
|
15
21
|
def get_binding
|
16
22
|
binding
|
17
23
|
end
|
18
24
|
end
|
19
|
-
|
25
|
+
|
20
26
|
# Contextual information for ERB template, representing index.html.
|
21
27
|
class IndexContext
|
22
|
-
|
23
|
-
#
|
24
|
-
|
28
|
+
|
29
|
+
# Public: Initialize an IndexContext for the index file in the HTML
|
30
|
+
# report.
|
31
|
+
#
|
32
|
+
# title - The String title for the report.
|
33
|
+
# covered - Array of subarrays. Each subarray is:
|
34
|
+
# [
|
35
|
+
# Fixnum coverage percentage,
|
36
|
+
# String formatted filename (HTML ready),
|
37
|
+
# String real filename
|
38
|
+
# ]
|
39
|
+
# FIXME Need a class to handle subarrays.
|
40
|
+
# uncovered - Array of String filenames. The filenames are already
|
41
|
+
# formatted, ready to be display in an HTML file.
|
42
|
+
#
|
43
|
+
def initialize(title, covered, uncovered)
|
25
44
|
@title = title
|
26
45
|
@covered = covered
|
27
46
|
@uncovered = uncovered
|
28
47
|
end
|
29
48
|
|
49
|
+
# Public: Get the object's binding.
|
50
|
+
#
|
51
|
+
# Returns Binding.
|
30
52
|
def get_binding
|
31
53
|
binding
|
32
54
|
end
|
@@ -1,22 +1,19 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
module Coco
|
4
|
-
|
4
|
+
|
5
5
|
# My childs will format coverages information.
|
6
|
-
# Kind of abstract class
|
6
|
+
# Kind of abstract class, my childs must implements the `format`
|
7
|
+
# method.
|
7
8
|
class Formatter
|
8
|
-
|
9
|
+
|
9
10
|
# raw_coverages - The Hash from Coverage.result.
|
10
11
|
# uncovered - An Array list of uncovered files.
|
11
|
-
#
|
12
|
-
def initialize
|
12
|
+
# TODO I think covered is a better name than raw_coverages
|
13
|
+
def initialize(raw_coverages, uncovered)
|
13
14
|
@raw_coverages = raw_coverages
|
14
15
|
@uncovered = uncovered
|
15
16
|
end
|
16
|
-
|
17
|
-
def format
|
18
|
-
"Implement me in child"
|
19
|
-
end
|
20
17
|
end
|
21
18
|
|
22
19
|
end
|
@@ -1,39 +1,40 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'cgi'
|
3
4
|
require 'erb'
|
4
5
|
|
5
6
|
module Coco
|
6
|
-
|
7
|
+
|
7
8
|
# I format coverages information into html files.
|
8
9
|
# @todo document and change name to HtmlFilesFormatter
|
9
10
|
class HtmlFormatter < Formatter
|
10
|
-
|
11
|
-
def initialize
|
11
|
+
|
12
|
+
def initialize(raw_coverages)
|
12
13
|
super(raw_coverages, [])
|
13
14
|
@formatted_output_files = {}
|
14
15
|
@context = nil
|
15
|
-
@template = Template.open File.join(
|
16
|
+
@template = Template.open File.join(Coco::ROOT, 'template/file.erb')
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
def format
|
19
20
|
@raw_coverages.each do |filename, coverage|
|
20
21
|
build_html filename, coverage
|
21
22
|
end
|
22
23
|
@formatted_output_files
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
private
|
26
|
-
|
27
|
-
def build_html
|
27
|
+
|
28
|
+
def build_html(filename, coverage)
|
28
29
|
source = File.readlines filename
|
29
30
|
lines = []
|
30
31
|
source.each_with_index do |line, index|
|
31
|
-
lines << [index+1, line.chomp
|
32
|
+
lines << [index+1, CGI.escapeHTML(line.chomp), coverage[index]]
|
32
33
|
end
|
33
34
|
@context = Context.new filename, lines
|
34
35
|
@formatted_output_files[filename] = @template.result(@context.get_binding)
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
end
|
38
39
|
|
39
40
|
end
|
@@ -3,28 +3,29 @@
|
|
3
3
|
require 'erb'
|
4
4
|
|
5
5
|
module Coco
|
6
|
-
|
6
|
+
|
7
7
|
# I format the index.html
|
8
8
|
class HtmlIndexFormatter < Formatter
|
9
|
-
|
9
|
+
|
10
10
|
def initialize(raw_coverages, uncovered)
|
11
|
-
super
|
11
|
+
super
|
12
12
|
@context = nil
|
13
|
-
@template = Template.open File.join(
|
13
|
+
@template = Template.open File.join(Coco::ROOT, 'template/index.erb')
|
14
14
|
@lines = []
|
15
15
|
build_lines_for_context
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def format
|
19
|
-
@context = IndexContext.new(Helpers.index_title,
|
20
|
-
@
|
19
|
+
@context = IndexContext.new(Helpers.index_title,
|
20
|
+
@lines,
|
21
|
+
@uncovered.map{|e| emphasize(e) })
|
21
22
|
@template.result(@context.get_binding)
|
22
23
|
end
|
23
|
-
|
24
|
+
|
24
25
|
private
|
25
|
-
|
26
|
+
|
26
27
|
def build_lines_for_context
|
27
|
-
@raw_coverages.each do |filename, coverage|
|
28
|
+
@raw_coverages.each do |filename, coverage|
|
28
29
|
filename = File.expand_path(filename)
|
29
30
|
percentage = CoverageStat.coverage_percent(coverage)
|
30
31
|
on_disk_filename = Helpers.rb2html(filename)
|
@@ -32,12 +33,12 @@ module Coco
|
|
32
33
|
end
|
33
34
|
@lines.sort!
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
def emphasize(filename)
|
37
38
|
base = File.basename filename
|
38
39
|
filename.sub(base, "<b>#{base}</b>")
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
end
|
42
43
|
|
43
44
|
end
|
data/lib/coco/helpers.rb
CHANGED
@@ -21,7 +21,7 @@ module Coco
|
|
21
21
|
# #=> '_lib_source.rb.html'
|
22
22
|
#
|
23
23
|
# Returns String HTML filename.
|
24
|
-
def rb2html
|
24
|
+
def rb2html(name)
|
25
25
|
name.sub(Dir.pwd, '').tr('/\\', '_') + '.html'
|
26
26
|
end
|
27
27
|
|
@@ -30,7 +30,7 @@ module Coco
|
|
30
30
|
# Returns String.
|
31
31
|
def index_title
|
32
32
|
project_name = File.basename(Dir.pwd)
|
33
|
-
version = File.read(File.join(
|
33
|
+
version = File.read(File.join(Coco::ROOT, 'VERSION')).strip
|
34
34
|
"#{project_name} - Code coverage (coco #{version})"
|
35
35
|
end
|
36
36
|
|
@@ -39,8 +39,8 @@ module Coco
|
|
39
39
|
# files - List of filenames as an Array of String.
|
40
40
|
#
|
41
41
|
# Returns an Array of String.
|
42
|
-
def expand
|
43
|
-
files.map {|file| File.expand_path
|
42
|
+
def expand(files)
|
43
|
+
files.map {|file| File.expand_path(file) }
|
44
44
|
end
|
45
45
|
|
46
46
|
# Public: Get all ruby files from a directory, including
|
@@ -49,7 +49,7 @@ module Coco
|
|
49
49
|
# directory - String directory to look into.
|
50
50
|
#
|
51
51
|
# Returns an Array of String.
|
52
|
-
def rb_files_from
|
52
|
+
def rb_files_from(directory)
|
53
53
|
rb_files = File.join(directory, "**", "*.rb")
|
54
54
|
Dir.glob(rb_files)
|
55
55
|
end
|
@@ -6,7 +6,7 @@ module Coco
|
|
6
6
|
class SourceLister
|
7
7
|
|
8
8
|
# config - Hash.
|
9
|
-
def initialize
|
9
|
+
def initialize(config)
|
10
10
|
@exclude_files = config[:excludes]
|
11
11
|
dirs = config[:directories]
|
12
12
|
unless dirs.is_a? Array
|
@@ -26,7 +26,7 @@ module Coco
|
|
26
26
|
# the directories found in configuration.
|
27
27
|
def list
|
28
28
|
look_for_sources
|
29
|
-
@list.map! {|file| File.expand_path(file)}
|
29
|
+
@list.map! {|file| File.expand_path(file) }
|
30
30
|
exclude_files_user_dont_want
|
31
31
|
@list
|
32
32
|
end
|
@@ -50,7 +50,7 @@ module Coco
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
def exclude_all_from_dir
|
53
|
+
def exclude_all_from_dir(full_path)
|
54
54
|
Helpers.rb_files_from(full_path).each do |file|
|
55
55
|
@list.delete File.expand_path(file)
|
56
56
|
end
|
@@ -7,7 +7,7 @@ module Coco
|
|
7
7
|
|
8
8
|
# sources - Array of String list of filenames.
|
9
9
|
# covered - Hash raw coverage from the domain.
|
10
|
-
def initialize
|
10
|
+
def initialize(sources, covered)
|
11
11
|
@source_files = Helpers.expand(sources)
|
12
12
|
@covered_files = Helpers.expand(covered.keys)
|
13
13
|
end
|
@@ -2,12 +2,18 @@
|
|
2
2
|
|
3
3
|
module Coco
|
4
4
|
|
5
|
-
# I write
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
# Public: I write a single file.
|
6
|
+
module FileWriter
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# Public: Write a file.
|
10
|
+
#
|
11
|
+
# filename - String path+name of the file.
|
12
|
+
# content - String content to put in the file.
|
13
|
+
#
|
14
|
+
# Returns nothing.
|
15
|
+
def write(filename, content)
|
16
|
+
File.open(filename, 'w') {|file| file.write(content) }
|
11
17
|
end
|
12
18
|
end
|
13
19
|
|
@@ -2,38 +2,61 @@
|
|
2
2
|
|
3
3
|
module Coco
|
4
4
|
|
5
|
-
# I prepare the coverage/ directory for html files.
|
5
|
+
# Public: I prepare the coverage/ directory for html files.
|
6
6
|
class HtmlDirectory
|
7
|
-
|
8
|
-
|
7
|
+
COVERAGE_DIR = 'coverage'
|
8
|
+
|
9
|
+
# Public: Initialize a new HtmlDirectory object.
|
9
10
|
def initialize
|
10
|
-
|
11
|
-
@css_dir = 'coverage/css'
|
12
|
-
@img_dir = 'coverage/img'
|
13
|
-
css = File.join($COCO_PATH, 'template/css')
|
11
|
+
css = File.join(Coco::ROOT, 'template/css')
|
14
12
|
@css_files = Dir.glob(css + '/*')
|
15
|
-
img = File.join(
|
13
|
+
img = File.join(Coco::ROOT, 'template/img')
|
16
14
|
@img_files = Dir.glob(img + '/*')
|
17
15
|
end
|
18
|
-
|
19
|
-
#
|
16
|
+
|
17
|
+
# Public: Get the name of the directory where the HTML report is
|
18
|
+
# stored.
|
19
|
+
#
|
20
|
+
# Returns String.
|
21
|
+
def coverage_dir
|
22
|
+
COVERAGE_DIR
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Delete the directory where the HTML report is stored.
|
26
|
+
#
|
27
|
+
# Returns nothing.
|
20
28
|
def clean
|
21
|
-
FileUtils.remove_dir
|
29
|
+
FileUtils.remove_dir(coverage_dir) if File.exist?(coverage_dir)
|
22
30
|
end
|
23
|
-
|
31
|
+
|
32
|
+
# Public: Make all directories needed to store the HTML report, then
|
33
|
+
# copy media files (css, images, etc.).
|
34
|
+
#
|
35
|
+
# Returns nothing.
|
24
36
|
def setup
|
25
|
-
FileUtils.makedirs
|
26
|
-
FileUtils.makedirs
|
27
|
-
FileUtils.cp
|
28
|
-
FileUtils.cp
|
37
|
+
FileUtils.makedirs(css_dir)
|
38
|
+
FileUtils.makedirs(image_dir)
|
39
|
+
FileUtils.cp(@css_files, css_dir)
|
40
|
+
FileUtils.cp(@img_files, image_dir)
|
29
41
|
end
|
30
|
-
|
31
|
-
# I list the html files from the
|
42
|
+
|
43
|
+
# Public: I list the html files from the directory where the HTML
|
44
|
+
# report is stored.
|
45
|
+
#
|
46
|
+
# Returns nothing.
|
32
47
|
def list
|
33
|
-
files = Dir.glob("#{
|
34
|
-
files.map {|file| File.basename(file)}
|
48
|
+
files = Dir.glob("#{coverage_dir}/*.html")
|
49
|
+
files.map {|file| File.basename(file) }
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def css_dir
|
55
|
+
"#{COVERAGE_DIR}/css"
|
35
56
|
end
|
36
|
-
|
37
|
-
end
|
38
57
|
|
58
|
+
def image_dir
|
59
|
+
"#{COVERAGE_DIR}/img"
|
60
|
+
end
|
61
|
+
end
|
39
62
|
end
|
@@ -1,16 +1,21 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
module Coco
|
4
|
-
|
5
|
-
# I populate the coverage/ directory with files, if any.
|
4
|
+
|
5
|
+
# Public: I populate the coverage/ directory with files, if any.
|
6
6
|
class HtmlFilesWriter
|
7
|
-
|
7
|
+
|
8
|
+
# Public: Initialize a new HtmlFilesWriter.
|
9
|
+
#
|
8
10
|
# html_files - Hash, key is filename, value is html content.
|
9
|
-
def initialize
|
11
|
+
def initialize(html_files)
|
10
12
|
@html_files = html_files
|
11
13
|
@html_dir = HtmlDirectory.new
|
12
14
|
end
|
13
|
-
|
15
|
+
|
16
|
+
# Public: Write HTML files in the right place.
|
17
|
+
#
|
18
|
+
# Returns nothing.
|
14
19
|
def write
|
15
20
|
@html_dir.clean
|
16
21
|
if @html_files.size > 0
|
@@ -18,16 +23,14 @@ module Coco
|
|
18
23
|
write_each_file
|
19
24
|
end
|
20
25
|
end
|
21
|
-
|
26
|
+
|
22
27
|
private
|
23
|
-
|
28
|
+
|
24
29
|
def write_each_file
|
25
30
|
@html_files.each do |filename, html|
|
26
31
|
FileWriter.write File.join(
|
27
32
|
@html_dir.coverage_dir, Helpers.rb2html(filename)), html
|
28
33
|
end
|
29
34
|
end
|
30
|
-
|
31
35
|
end
|
32
|
-
|
33
36
|
end
|
@@ -2,20 +2,24 @@
|
|
2
2
|
|
3
3
|
module Coco
|
4
4
|
|
5
|
-
# I write the index.html
|
5
|
+
# Public: I write the index.html
|
6
6
|
class HtmlIndexWriter
|
7
7
|
|
8
|
-
|
8
|
+
# Public: Initialize a new HtmlIndexWriter object.
|
9
|
+
#
|
10
|
+
# index - A String HTML document.
|
11
|
+
def initialize(index)
|
9
12
|
@index = index
|
10
13
|
@dir = HtmlDirectory.new.coverage_dir
|
11
14
|
end
|
12
15
|
|
16
|
+
# Public: Write the index file in the right place.
|
17
|
+
#
|
18
|
+
# Returns nothing.
|
13
19
|
def write
|
14
20
|
if File.exist?(@dir)
|
15
21
|
FileWriter.write File.join(@dir, 'index.html'), @index
|
16
22
|
end
|
17
23
|
end
|
18
|
-
|
19
24
|
end
|
20
|
-
|
21
25
|
end
|
data/template/css/coco.css
CHANGED
@@ -29,7 +29,7 @@ h2 {
|
|
29
29
|
font-size: 1.1em;
|
30
30
|
}
|
31
31
|
|
32
|
-
a {
|
32
|
+
a {
|
33
33
|
color:#446;
|
34
34
|
text-decoration: none;
|
35
35
|
}
|
@@ -63,7 +63,15 @@ table td {
|
|
63
63
|
}
|
64
64
|
|
65
65
|
table.source td {
|
66
|
-
padding: 0;
|
66
|
+
padding-top: 0;
|
67
|
+
padding-bottom: 0;
|
68
|
+
padding-left: 0;
|
69
|
+
}
|
70
|
+
|
71
|
+
thead {
|
72
|
+
font-weight: bold;
|
73
|
+
background-color: #eee;
|
74
|
+
text-align: center;
|
67
75
|
}
|
68
76
|
|
69
77
|
tr.never {
|
@@ -106,11 +114,35 @@ td.black {
|
|
106
114
|
font-weight: bold;
|
107
115
|
}
|
108
116
|
|
109
|
-
td
|
117
|
+
td.percentage {
|
118
|
+
text-align: right;
|
119
|
+
padding-right: 20px;
|
120
|
+
}
|
121
|
+
|
122
|
+
td.line-source {
|
123
|
+
padding-right: 0;
|
124
|
+
}
|
125
|
+
|
126
|
+
td.line-num, td.line-hits {
|
127
|
+
width: 10%;
|
128
|
+
}
|
129
|
+
|
130
|
+
td.line-num {
|
131
|
+
color: #444;
|
132
|
+
text-align: right;
|
133
|
+
padding-right: 5px;
|
134
|
+
}
|
135
|
+
|
136
|
+
td.line-hits {
|
110
137
|
text-align: right;
|
111
138
|
padding-right: 20px;
|
112
139
|
}
|
113
140
|
|
141
|
+
th {
|
142
|
+
padding-bottom: 5px;
|
143
|
+
padding-top: 5px;
|
144
|
+
}
|
145
|
+
|
114
146
|
pre {
|
115
147
|
margin: 6px 0;
|
116
148
|
}
|
data/template/file.erb
CHANGED
@@ -16,18 +16,27 @@
|
|
16
16
|
<p class="date"><%= "#{Time.now}" %></p>
|
17
17
|
|
18
18
|
<table class="source">
|
19
|
+
|
20
|
+
<thead>
|
21
|
+
<tr>
|
22
|
+
<th>line num</th>
|
23
|
+
<th>source code</th>
|
24
|
+
<th>
|
25
|
+
<abbr title="Number of time this line has been hit during test.">
|
26
|
+
line hits
|
27
|
+
</abbr>
|
28
|
+
</th>
|
29
|
+
</tr>
|
30
|
+
</thead>
|
19
31
|
|
20
32
|
<% @lines.each do |num, text, hit|%>
|
21
|
-
|
22
|
-
|
23
|
-
<% elsif hit.zero? %>
|
24
|
-
<tr class="miss">
|
25
|
-
<% elsif hit > 0 %>
|
26
|
-
<tr class="hit" %>
|
27
|
-
<% end %>
|
28
|
-
|
29
|
-
<%= "<td><pre>#{num} </pre></td><td><pre>#{text}</pre></td>" %>
|
33
|
+
<% classes = { nil => 'never', 0 => 'miss' } %>
|
34
|
+
<% hit_class = classes[hit] || 'hit' %>
|
30
35
|
|
36
|
+
<tr class="<%= hit_class %>">
|
37
|
+
<td class='line-num'><pre><%= num %> </pre></td>
|
38
|
+
<td class='line-source'><pre><%= text %></pre></td>
|
39
|
+
<td class='line-hits'><%= hit %></td>
|
31
40
|
</tr>
|
32
41
|
<% end%>
|
33
42
|
|
data/template/index.erb
CHANGED
@@ -19,28 +19,22 @@
|
|
19
19
|
<table class="index">
|
20
20
|
|
21
21
|
<% @uncovered.each do |filename| %>
|
22
|
-
|
22
|
+
<tr><td class="percentage black">0%</td><td><%= filename %></td></tr>
|
23
23
|
<% end %>
|
24
24
|
|
25
25
|
<% @covered.each do |percentage, filename, href| %>
|
26
|
+
<% level_class = case percentage; when 80..100; 'yellow'; when 70..79; 'orange'; when 69..50; 'pink'; else 'red'; end %>
|
26
27
|
<tr>
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
<td class="orange">
|
31
|
-
<% elsif percentage > 50 %>
|
32
|
-
<td class="pink">
|
33
|
-
<% else %>
|
34
|
-
<td class="red">
|
35
|
-
<% end %>
|
36
|
-
<%= "#{percentage}%</td><td><a href=\"#{href}\">#{filename}</a></td></tr>\n" %>
|
28
|
+
<td class="percentage <%= level_class %>"><%= percentage %>%</td>
|
29
|
+
<td><a href="<%= href %>"><%= filename %></a></td>
|
30
|
+
</tr>
|
37
31
|
<% end%>
|
38
32
|
|
39
33
|
</table>
|
40
34
|
|
41
35
|
<p class="license">
|
42
36
|
Coco, code coverage for ruby.<br/>
|
43
|
-
Copyright 2011-
|
37
|
+
Copyright 2011-2014, Xavier Nayrac<br/>
|
44
38
|
<br/>
|
45
39
|
This program is free software: you can redistribute it and/or modify<br/>
|
46
40
|
it under the terms of the GNU General Public License as published by<br/>
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Nayrac
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rspec
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +38,20 @@ dependencies:
|
|
24
38
|
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '2.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.1'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: reek
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +80,20 @@ dependencies:
|
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '2.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard-tomdoc
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.7'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.7'
|
55
97
|
description: |-
|
56
98
|
"Code coverage tool for ruby 1.9.3 to 2.1.
|
57
99
|
Use it by "require 'coco'" from rspec or unit/test.
|
@@ -67,10 +109,8 @@ files:
|
|
67
109
|
- COPYING
|
68
110
|
- Changelog.markdown
|
69
111
|
- Gemfile
|
70
|
-
- Gemfile.lock
|
71
112
|
- README.markdown
|
72
113
|
- Rakefile
|
73
|
-
- TODO
|
74
114
|
- VERSION
|
75
115
|
- lib/coco.rb
|
76
116
|
- lib/coco/configuration.rb
|
data/Gemfile.lock
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
coco (0.10.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
diff-lcs (1.2.4)
|
10
|
-
flay (2.4.0)
|
11
|
-
ruby_parser (~> 3.0)
|
12
|
-
sexp_processor (~> 4.0)
|
13
|
-
rainbow (2.0.0)
|
14
|
-
rake (10.1.1)
|
15
|
-
reek (1.3.7)
|
16
|
-
rainbow
|
17
|
-
ruby2ruby (~> 2.0.8)
|
18
|
-
ruby_parser (~> 3.3)
|
19
|
-
sexp_processor
|
20
|
-
rspec (2.13.0)
|
21
|
-
rspec-core (~> 2.13.0)
|
22
|
-
rspec-expectations (~> 2.13.0)
|
23
|
-
rspec-mocks (~> 2.13.0)
|
24
|
-
rspec-core (2.13.1)
|
25
|
-
rspec-expectations (2.13.0)
|
26
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
27
|
-
rspec-mocks (2.13.1)
|
28
|
-
ruby2ruby (2.0.8)
|
29
|
-
ruby_parser (~> 3.1)
|
30
|
-
sexp_processor (~> 4.0)
|
31
|
-
ruby_parser (3.5.0)
|
32
|
-
sexp_processor (~> 4.1)
|
33
|
-
sexp_processor (4.4.3)
|
34
|
-
|
35
|
-
PLATFORMS
|
36
|
-
ruby
|
37
|
-
|
38
|
-
DEPENDENCIES
|
39
|
-
coco!
|
40
|
-
flay (~> 2.4)
|
41
|
-
rake (>= 10.1.0)
|
42
|
-
reek (~> 1.3)
|
43
|
-
rspec
|
data/TODO
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
[x] Release 0.10.0
|
2
|
-
[ ] release gem
|
3
|
-
|
4
|
-
[ ] Update website
|
5
|
-
|
6
|
-
[ ] Review PRs
|
7
|
-
|
8
|
-
[ ] A task to build/install/push a gem
|
9
|
-
|
10
|
-
[ ] BUG #22 rails 4.1 / minitest / spring
|
11
|
-
[x] test with rails 4.1 / spring / rspec
|
12
|
-
[x] coco outside dev group
|
13
|
-
[x] test with 4.1 / spring / minitest
|
14
|
-
[ ] retest with a .coco.yml file
|
15
|
-
|
16
|
-
[ ] refactor with reek
|
17
|
-
|
18
|
-
[ ] en gras: def, class, module
|
19
|
-
|
20
|
-
[ ] rakefile task: tomdoc
|
21
|
-
|
22
|
-
[ ] exclure spec et test par défaut
|
23
|
-
|
24
|
-
[ ] le wiki dit que seul le dossier lib est inspecté par défaut, je pense
|
25
|
-
que c'est en fait toute l'application.
|
26
|
-
|
27
|
-
|
28
|
-
Bump Version
|
29
|
-
=============
|
30
|
-
|
31
|
-
- Update `VERSION` file.
|
32
|
-
- `bundle install`
|
33
|
-
- Update Changelog.
|