coco 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +674 -0
- data/NEWS +34 -0
- data/README.rdoc +48 -0
- data/Rakefile +32 -0
- data/TODO +3 -0
- data/VERSION +1 -0
- data/lib/coco.rb +33 -0
- data/lib/coco/configuration.rb +35 -0
- data/lib/coco/cover.rb +4 -0
- data/lib/coco/cover/coverage_result.rb +48 -0
- data/lib/coco/cover/coverage_stat.rb +33 -0
- data/lib/coco/formatter.rb +9 -0
- data/lib/coco/formatter/colored_string.rb +33 -0
- data/lib/coco/formatter/console_formatter.rb +46 -0
- data/lib/coco/formatter/context.rb +35 -0
- data/lib/coco/formatter/formatter.rb +22 -0
- data/lib/coco/formatter/html_formatter.rb +39 -0
- data/lib/coco/formatter/html_index_formatter.rb +37 -0
- data/lib/coco/formatter/template.rb +17 -0
- data/lib/coco/helpers.rb +36 -0
- data/lib/coco/lister.rb +4 -0
- data/lib/coco/lister/source_lister.rb +47 -0
- data/lib/coco/lister/uncovered_lister.rb +26 -0
- data/lib/coco/writer.rb +6 -0
- data/lib/coco/writer/file_writer.rb +14 -0
- data/lib/coco/writer/html_directory.rb +39 -0
- data/lib/coco/writer/html_files_writer.rb +32 -0
- data/lib/coco/writer/html_index_writer.rb +21 -0
- data/template/css/LICENCE +5 -0
- data/template/css/base-min.css +1 -0
- data/template/css/coco.css +96 -0
- data/template/css/ext.css +5 -0
- data/template/css/fonts-min.css +1 -0
- data/template/css/reset-min.css +1 -0
- data/template/file.erb +35 -0
- data/template/img/coconut16.png +0 -0
- data/template/img/licenses +19 -0
- data/template/index.erb +58 -0
- metadata +113 -0
data/NEWS
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
v0.4.1 (2011-02-27)
|
2
|
+
|
3
|
+
* Quick fix, add forgotten images for html menu
|
4
|
+
|
5
|
+
|
6
|
+
v0.4 (2011-02-26)
|
7
|
+
|
8
|
+
* add colors to console output (*nix only)
|
9
|
+
|
10
|
+
* it can exclude unwanted files from the report
|
11
|
+
|
12
|
+
|
13
|
+
v0.3 (2011-02-25)
|
14
|
+
|
15
|
+
* Report sources not covered at all
|
16
|
+
|
17
|
+
* Configurable via a simple yaml file
|
18
|
+
+ threeshold
|
19
|
+
+ source directories
|
20
|
+
|
21
|
+
* UTF-8 compliant
|
22
|
+
|
23
|
+
* Misc
|
24
|
+
+ sort index.html and console output by percentage
|
25
|
+
+ display coco's version in index.html
|
26
|
+
|
27
|
+
|
28
|
+
v0.2 (2011-02-24)
|
29
|
+
|
30
|
+
* Use coco from rspec with a simple require 'coco'
|
31
|
+
|
32
|
+
* Display filenames covered < 90% on console
|
33
|
+
|
34
|
+
* Build simple html report only for files covered < 90%
|
data/README.rdoc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
= coco
|
2
|
+
|
3
|
+
Another COde COverage for ruby 1.9 (from the famous post of Aaron Patterson).
|
4
|
+
This one suits my needs.
|
5
|
+
|
6
|
+
== Features
|
7
|
+
* Use it from rspec with a simple <code>require 'coco'</code>
|
8
|
+
* Display filenames covered < 90% on console
|
9
|
+
* Build <em>simple</em> html report <em>only</em> for files covered < 90%
|
10
|
+
* Report sources that have no tests
|
11
|
+
* UTF-8 compliant
|
12
|
+
* Configuration could be done via a simple yaml file
|
13
|
+
* Colorized console output (*nix only)
|
14
|
+
|
15
|
+
<em>Note: I have tested coco only on debian linux. I have not tested it with the test/unit
|
16
|
+
framework.</em>
|
17
|
+
|
18
|
+
== Documentation
|
19
|
+
|
20
|
+
require 'coco'
|
21
|
+
|
22
|
+
at the beginning of your tests, usually in a \*helper\*.rb file.
|
23
|
+
|
24
|
+
See {the wiki}[https://github.com/lkdjiin/coco/wiki] for more information on using coco.
|
25
|
+
|
26
|
+
To generate the developper's documentation in YARD format:
|
27
|
+
rake doc
|
28
|
+
|
29
|
+
== Dependencies
|
30
|
+
|
31
|
+
ruby >= 1.9.2
|
32
|
+
|
33
|
+
To contribute:
|
34
|
+
|
35
|
+
* reek
|
36
|
+
* rspec
|
37
|
+
|
38
|
+
== Installing coco
|
39
|
+
Download and
|
40
|
+
rake install
|
41
|
+
|
42
|
+
== License
|
43
|
+
GPLv3, see COPYING.
|
44
|
+
|
45
|
+
== Questions and/or Comments
|
46
|
+
|
47
|
+
Feel free to email {Xavier Nayrac}[mailto:xavier.nayrac@gmail.com]
|
48
|
+
with any questions.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc 'Test coco'
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
desc 'Test coco'
|
10
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
11
|
+
t.rspec_opts = ['--color']
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Check for code smells'
|
15
|
+
task :reek do
|
16
|
+
puts 'Checking for code smells...'
|
17
|
+
files = Dir.glob 'lib/**/*.rb'
|
18
|
+
args = files.join(' ')
|
19
|
+
sh "reek --quiet #{args} | ./reek.sed"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Build the gem & install it'
|
23
|
+
task :install do
|
24
|
+
sh "gem build coco.gemspec"
|
25
|
+
f = FileList['coco*gem'].to_a
|
26
|
+
sh "gem install #{f.first} --no-rdoc --no-ri"
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Generate yard documentation for developpers'
|
30
|
+
task :doc do
|
31
|
+
exec 'yardoc --title "Coco Documentation" - NEWS COPYING VERSION'
|
32
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.1
|
data/lib/coco.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
4
|
+
$COCO_PATH = File.expand_path(File.expand_path(File.dirname(__FILE__)) + '/..')
|
5
|
+
require 'coco/formatter'
|
6
|
+
require 'coco/cover'
|
7
|
+
require 'coco/writer'
|
8
|
+
require 'coco/helpers'
|
9
|
+
require 'coco/configuration'
|
10
|
+
require 'coco/lister'
|
11
|
+
require 'coverage'
|
12
|
+
|
13
|
+
module Coco
|
14
|
+
end
|
15
|
+
|
16
|
+
Coverage.start
|
17
|
+
|
18
|
+
at_exit do
|
19
|
+
config = Coco::Configuration.new
|
20
|
+
result = Coco::CoverageResult.new(config, Coverage.result)
|
21
|
+
covered = result.covered_from_domain
|
22
|
+
|
23
|
+
sources = Coco::SourceLister.new(config).list
|
24
|
+
uncovered = Coco::UncoveredLister.new(sources, result.all_from_domain).list
|
25
|
+
|
26
|
+
puts Coco::ConsoleFormatter.new(covered, uncovered).format
|
27
|
+
|
28
|
+
html_files = Coco::HtmlFormatter.new(covered).format
|
29
|
+
Coco::HtmlFilesWriter.new(html_files).write
|
30
|
+
|
31
|
+
index = Coco::HtmlIndexFormatter.new(covered, uncovered).format
|
32
|
+
Coco::HtmlIndexWriter.new(index).write
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Coco
|
6
|
+
|
7
|
+
# I know the configuration of coco.
|
8
|
+
#
|
9
|
+
# @example read the threeshold value
|
10
|
+
# config = Configuration.new
|
11
|
+
# config[:threeshold]
|
12
|
+
# => 90
|
13
|
+
#
|
14
|
+
# You can override the default configuration by putting a '.coco' file
|
15
|
+
# in YAML format in the project root directory.
|
16
|
+
# @example to override the threeshold put this line in a '.coco' file:
|
17
|
+
# :threeshold: 70
|
18
|
+
#
|
19
|
+
# @note You can set the threeshold above 100% (to be sure to see all files) but you
|
20
|
+
# cannot set it under 0.
|
21
|
+
class Configuration < Hash
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
self[:threeshold] = 90
|
25
|
+
self[:directories] = ['lib']
|
26
|
+
self[:excludes] = []
|
27
|
+
if File.exist?('.coco')
|
28
|
+
conf = YAML.load_file '.coco'
|
29
|
+
self.merge!(conf)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/coco/cover.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Coco
|
4
|
+
|
5
|
+
# Compute results of interest from the big results information (from Coverage.result)
|
6
|
+
class CoverageResult
|
7
|
+
# @return [Hash] Coverage for all the sources that live in the root project folder.
|
8
|
+
attr_reader :all_from_domain
|
9
|
+
# @return [Hash] Coverage for sources that are not sufficiently covered.
|
10
|
+
# More technically, the sources that live in the root project folder and for
|
11
|
+
# which the coverage percentage is under the threeshold.
|
12
|
+
attr_reader :covered_from_domain
|
13
|
+
|
14
|
+
# @param [Hash] config
|
15
|
+
# @param [Hash] raw_results Results obtained from Coverage.result
|
16
|
+
def initialize config, raw_results
|
17
|
+
@exclude_files = config[:excludes]
|
18
|
+
@threeshold = config[:threeshold]
|
19
|
+
raise ArgumentError if @threeshold < 0
|
20
|
+
@result = raw_results
|
21
|
+
exclude_external_sources
|
22
|
+
exclude_files_user_dont_want
|
23
|
+
exclude_sources_above_threeshold
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def exclude_external_sources
|
29
|
+
here = Dir.pwd
|
30
|
+
@all_from_domain = @result.select {|key, value| key.start_with? here}
|
31
|
+
end
|
32
|
+
|
33
|
+
def exclude_files_user_dont_want
|
34
|
+
return if @exclude_files.nil?
|
35
|
+
@exclude_files.each do |filename|
|
36
|
+
@all_from_domain.delete(File.expand_path(filename))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def exclude_sources_above_threeshold
|
41
|
+
@covered_from_domain = @all_from_domain.select {|key, value|
|
42
|
+
CoverageStat.coverage_percent(value) < @threeshold
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Coco
|
4
|
+
|
5
|
+
# Give statistics about an array of lines hit.
|
6
|
+
#
|
7
|
+
# An "array of lines hit" is an array of integers, possibly nil.
|
8
|
+
# Such array is obtain from Coverage.result.
|
9
|
+
#
|
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
|
+
class CoverageStat
|
15
|
+
|
16
|
+
def CoverageStat.remove_nil_from hits
|
17
|
+
hits.select {|elem| not elem.nil?}
|
18
|
+
end
|
19
|
+
|
20
|
+
def CoverageStat.number_of_covered_lines hits
|
21
|
+
hits.select {|elem| elem > 0}.size
|
22
|
+
end
|
23
|
+
|
24
|
+
def CoverageStat.coverage_percent hits
|
25
|
+
hits = CoverageStat.remove_nil_from hits
|
26
|
+
return 0 if hits.empty?
|
27
|
+
one_percent = 100.0 / hits.size
|
28
|
+
(CoverageStat.number_of_covered_lines(hits) * one_percent).to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'coco/formatter/formatter'
|
2
|
+
|
3
|
+
require 'coco/formatter/console_formatter'
|
4
|
+
require 'coco/formatter/context'
|
5
|
+
|
6
|
+
require 'coco/formatter/html_formatter'
|
7
|
+
require 'coco/formatter/html_index_formatter'
|
8
|
+
require 'coco/formatter/template'
|
9
|
+
require 'coco/formatter/colored_string'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Coco
|
4
|
+
|
5
|
+
# Extend String with ANSI colorization.
|
6
|
+
# Do nothing on Windows.
|
7
|
+
class ColoredString < String
|
8
|
+
|
9
|
+
def initialize(str="")
|
10
|
+
super(str)
|
11
|
+
end
|
12
|
+
|
13
|
+
def red
|
14
|
+
colorize "\033[31m"
|
15
|
+
end
|
16
|
+
|
17
|
+
def yellow
|
18
|
+
colorize "\033[33m"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def colorize color_code
|
24
|
+
if RUBY_PLATFORM =~ /win32/
|
25
|
+
self
|
26
|
+
else
|
27
|
+
"#{color_code}#{self}\033[0m"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Coco
|
4
|
+
|
5
|
+
# I format coverages information for console output
|
6
|
+
class ConsoleFormatter < Formatter
|
7
|
+
|
8
|
+
# return [string] percent covered and associated filenames
|
9
|
+
def format
|
10
|
+
@formatted_output.join("\n")
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param [Hash] covered
|
14
|
+
# @param [Array] uncovered
|
15
|
+
def initialize covered, uncovered
|
16
|
+
super(covered, uncovered)
|
17
|
+
@formatted_output = []
|
18
|
+
compute_percentage
|
19
|
+
add_percentage_to_uncovered
|
20
|
+
@formatted_output.sort!
|
21
|
+
@formatted_output.map! do |percentage, filename|
|
22
|
+
text = ColoredString.new "#{percentage}% #{filename}"
|
23
|
+
if percentage <= 50
|
24
|
+
text.red
|
25
|
+
else
|
26
|
+
text.yellow
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def compute_percentage
|
34
|
+
@raw_coverages.each do |filename, coverage|
|
35
|
+
percentage = CoverageStat.coverage_percent(coverage)
|
36
|
+
@formatted_output << [percentage, filename]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_percentage_to_uncovered
|
41
|
+
@uncovered.each do |filename| @formatted_output << [0, filename] end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Coco
|
4
|
+
|
5
|
+
# Contextual information for ERB template, representing each covered files.
|
6
|
+
class Context
|
7
|
+
|
8
|
+
# @param [String] filename Name of the source file
|
9
|
+
# @param [Array] lines
|
10
|
+
def initialize filename, lines
|
11
|
+
@filename = filename
|
12
|
+
@lines = lines
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_binding
|
16
|
+
binding
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Contextual information for ERB template, representing index.html.
|
21
|
+
class IndexContext
|
22
|
+
|
23
|
+
# @todo doc, inheritance (with Context)
|
24
|
+
def initialize title, covered, uncovered
|
25
|
+
@title = title
|
26
|
+
@covered = covered
|
27
|
+
@uncovered = uncovered
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_binding
|
31
|
+
binding
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Coco
|
4
|
+
|
5
|
+
# My childs will format coverages information.
|
6
|
+
# @abstract
|
7
|
+
class Formatter
|
8
|
+
|
9
|
+
# @param [Hash] raw_coverages The hash from Coverage.result
|
10
|
+
# @param [Array] uncovered List on uncovered files
|
11
|
+
# @todo I think covered is a better name than raw_coverages
|
12
|
+
def initialize raw_coverages, uncovered
|
13
|
+
@raw_coverages = raw_coverages
|
14
|
+
@uncovered = uncovered
|
15
|
+
end
|
16
|
+
|
17
|
+
def format
|
18
|
+
"Implement me in child"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Coco
|
6
|
+
|
7
|
+
# I format coverages information into html files.
|
8
|
+
# @todo document and change name to HtmlFilesFormatter
|
9
|
+
class HtmlFormatter < Formatter
|
10
|
+
|
11
|
+
def initialize raw_coverages
|
12
|
+
super(raw_coverages, [])
|
13
|
+
@formatted_output_files = {}
|
14
|
+
@context = nil
|
15
|
+
@template = Template.open File.join($COCO_PATH,'template/file.erb')
|
16
|
+
end
|
17
|
+
|
18
|
+
def format
|
19
|
+
@raw_coverages.each do |filename, coverage|
|
20
|
+
build_html filename, coverage
|
21
|
+
end
|
22
|
+
@formatted_output_files
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def build_html filename, coverage
|
28
|
+
source = File.readlines filename
|
29
|
+
lines = []
|
30
|
+
source.each_with_index do |line, index|
|
31
|
+
lines << [index+1, line.chomp, coverage[index]]
|
32
|
+
end
|
33
|
+
@context = Context.new filename, lines
|
34
|
+
@formatted_output_files[filename] = @template.result(@context.get_binding)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|