simplecov 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +24 -0
- data/LICENSE +20 -0
- data/README.rdoc +43 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/simplecov.rb +107 -0
- data/lib/simplecov/adapters.rb +47 -0
- data/lib/simplecov/configuration.rb +174 -0
- data/lib/simplecov/filter.rb +35 -0
- data/lib/simplecov/formatter.rb +7 -0
- data/lib/simplecov/formatter/simple_formatter.rb +15 -0
- data/lib/simplecov/merge_helpers.rb +37 -0
- data/lib/simplecov/result.rb +73 -0
- data/lib/simplecov/result_merger.rb +46 -0
- data/lib/simplecov/source_file.rb +68 -0
- data/simple_cov.gemspec +81 -0
- data/simplecov.gemspec +82 -0
- data/test/fixtures/app/controllers/sample_controller.rb +10 -0
- data/test/fixtures/app/models/user.rb +10 -0
- data/test/fixtures/resultset1.rb +4 -0
- data/test/fixtures/resultset2.rb +5 -0
- data/test/fixtures/sample.rb +10 -0
- data/test/helper.rb +14 -0
- data/test/test_filters.rb +73 -0
- data/test/test_merge_helpers.rb +92 -0
- data/test/test_result.rb +133 -0
- data/test/test_source_file.rb +49 -0
- data/test/test_source_file_line.rb +110 -0
- metadata +117 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
module SimpleCov
|
2
|
+
#
|
3
|
+
# Base filter class. Inherit from this to create custom filters,
|
4
|
+
# and overwrite the passes?(source_file) instance method
|
5
|
+
#
|
6
|
+
# # A sample class that rejects all source files.
|
7
|
+
# class StupidFilter < SimpleCov::Filter
|
8
|
+
# def passes?(source_file)
|
9
|
+
# false
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
class Filter
|
14
|
+
attr_reader :filter_argument
|
15
|
+
def initialize(filter_argument)
|
16
|
+
@filter_argument = filter_argument
|
17
|
+
end
|
18
|
+
|
19
|
+
def passes?(source_file)
|
20
|
+
raise "The base filter class is not intended for direct use"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class StringFilter < SimpleCov::Filter
|
25
|
+
def passes?(source_file)
|
26
|
+
!(source_file.filename =~ /#{filter_argument}/)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class BlockFilter < SimpleCov::Filter
|
31
|
+
def passes?(source_file)
|
32
|
+
!filter_argument.call(source_file)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class SimpleCov::Formatter::SimpleFormatter
|
2
|
+
def format(result)
|
3
|
+
output = ""
|
4
|
+
result.groups.each do |name, files|
|
5
|
+
output << "Group: #{name}\n"
|
6
|
+
output << "="*40
|
7
|
+
output << "\n"
|
8
|
+
files.each do |file|
|
9
|
+
output << "#{file.filename} (coverage: #{file.covered_percent.round(2)}%)\n"
|
10
|
+
end
|
11
|
+
output << "\n"
|
12
|
+
end
|
13
|
+
output
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SimpleCov::ArrayMergeHelper
|
2
|
+
def merge_resultset(array)
|
3
|
+
new_array = []
|
4
|
+
|
5
|
+
self.each_with_index do |element, i|
|
6
|
+
new_array[i] = element
|
7
|
+
end
|
8
|
+
|
9
|
+
array.each_with_index do |element, i|
|
10
|
+
if element.nil? and new_array[i].nil?
|
11
|
+
new_array[i] = nil
|
12
|
+
else
|
13
|
+
local_value = element || 0
|
14
|
+
other_value = new_array[i] || 0
|
15
|
+
new_array[i] = local_value + other_value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
new_array
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module SimpleCov::HashMergeHelper
|
23
|
+
def merge_resultset(hash)
|
24
|
+
new_resultset = {}
|
25
|
+
(self.keys + hash.keys).each do |filename|
|
26
|
+
new_resultset[filename] = []
|
27
|
+
end
|
28
|
+
|
29
|
+
new_resultset.each do |filename, data|
|
30
|
+
new_resultset[filename] = (self[filename] || []).merge_resultset(hash[filename] || [])
|
31
|
+
end
|
32
|
+
new_resultset
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Array.send :include, SimpleCov::ArrayMergeHelper
|
37
|
+
Hash.send :include, SimpleCov::HashMergeHelper
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SimpleCov
|
5
|
+
class Result
|
6
|
+
attr_reader :original_result, :files
|
7
|
+
attr_writer :created_at, :command_name
|
8
|
+
alias_method :source_files, :files
|
9
|
+
|
10
|
+
def initialize(original_result)
|
11
|
+
@original_result = original_result.freeze
|
12
|
+
@files = original_result.map {|filename, coverage| SimpleCov::SourceFile.new(filename, coverage)}.sort_by(&:filename)
|
13
|
+
filter!
|
14
|
+
end
|
15
|
+
|
16
|
+
def filenames
|
17
|
+
files.map(&:filename)
|
18
|
+
end
|
19
|
+
|
20
|
+
def groups
|
21
|
+
@groups ||= SimpleCov.grouped(files)
|
22
|
+
end
|
23
|
+
|
24
|
+
def covered_percent
|
25
|
+
files.map(&:covered_percent).inject(:+) / files.count.to_f
|
26
|
+
end
|
27
|
+
|
28
|
+
def format!
|
29
|
+
SimpleCov.formatter.new.format(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Defines when this result has been created
|
33
|
+
def created_at
|
34
|
+
@created_at ||= Time.now
|
35
|
+
end
|
36
|
+
|
37
|
+
# The command name that launched this result.
|
38
|
+
# Retrieved from SimpleCov.command_name
|
39
|
+
def command_name
|
40
|
+
@command_name ||= SimpleCov.command_name
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a hash representation of this Result
|
44
|
+
def to_hash
|
45
|
+
{command_name => {:original_result => original_result.reject {|filename, result| !filenames.include?(filename) }, :created_at => created_at}}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns a yaml dump of this result, which then can be reloaded using SimpleCov::Result.from_yaml
|
49
|
+
def to_yaml
|
50
|
+
to_hash.to_yaml
|
51
|
+
end
|
52
|
+
|
53
|
+
# Loads a SimpleCov::Result#to_hash dump
|
54
|
+
def self.from_hash(hash)
|
55
|
+
command_name, data = hash.first
|
56
|
+
result = SimpleCov::Result.new(data[:original_result])
|
57
|
+
result.command_name = command_name
|
58
|
+
result.created_at = data[:created_at]
|
59
|
+
result
|
60
|
+
end
|
61
|
+
|
62
|
+
# Loads a SimpleCov::Result#to_yaml dump
|
63
|
+
def self.from_yaml(yaml)
|
64
|
+
from_hash(YAML.load(yaml))
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def filter!
|
70
|
+
@files = SimpleCov.filtered(files)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
module SimpleCov::ResultMerger
|
3
|
+
class << self
|
4
|
+
def resultset_path
|
5
|
+
File.join(SimpleCov.coverage_path, 'resultset.yml')
|
6
|
+
end
|
7
|
+
|
8
|
+
def resultset
|
9
|
+
return {} unless File.exist?(resultset_path)
|
10
|
+
YAML.load(File.read(resultset_path))
|
11
|
+
end
|
12
|
+
|
13
|
+
def results
|
14
|
+
results = []
|
15
|
+
resultset.each do |command_name, data|
|
16
|
+
result = SimpleCov::Result.from_hash(command_name => data)
|
17
|
+
# Only add result if the timeout is above the configured threshold
|
18
|
+
if (Time.now - result.created_at) < SimpleCov.merge_timeout
|
19
|
+
results << result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
results
|
23
|
+
end
|
24
|
+
|
25
|
+
def merged_result
|
26
|
+
merged = {}
|
27
|
+
results.each do |result|
|
28
|
+
merged = result.original_result.merge_resultset(merged)
|
29
|
+
end
|
30
|
+
result = SimpleCov::Result.new(merged)
|
31
|
+
# Specify the command name
|
32
|
+
result.command_name = results.map(&:command_name).join(", ")
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def store_result(result)
|
37
|
+
new_set = resultset
|
38
|
+
command_name, data = result.to_hash.first
|
39
|
+
new_set[command_name] = data
|
40
|
+
File.open(resultset_path, "w+") do |f|
|
41
|
+
f.puts new_set.to_yaml
|
42
|
+
end
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module SimpleCov
|
2
|
+
class SourceFile
|
3
|
+
# Representation of a single line in a source file including
|
4
|
+
# this specific line's source code, line_number and code coverage,
|
5
|
+
# with the coverage being either nil (coverage not applicable, e.g. comment
|
6
|
+
# line), 0 (line not covered) or >1 (the amount of times the line was
|
7
|
+
# executed)
|
8
|
+
class Line
|
9
|
+
attr_reader :src, :line_number, :coverage
|
10
|
+
# Lets grab some fancy aliases, shall we?
|
11
|
+
alias_method :source, :src
|
12
|
+
alias_method :line, :line_number
|
13
|
+
alias_method :number, :line_number
|
14
|
+
|
15
|
+
def initialize(src, line_number, coverage)
|
16
|
+
raise ArgumentError, "Only String accepted for source" unless src.kind_of?(String)
|
17
|
+
raise ArgumentError, "Only Fixnum accepted for line_number" unless line_number.kind_of?(Fixnum)
|
18
|
+
raise ArgumentError, "Only Fixnum and nil accepted for coverage" unless coverage.kind_of?(Fixnum) or coverage.nil?
|
19
|
+
@src, @line_number, @coverage = src, line_number, coverage
|
20
|
+
end
|
21
|
+
|
22
|
+
def missed?
|
23
|
+
not never? and coverage == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def covered?
|
27
|
+
not never? and coverage > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def never?
|
31
|
+
coverage.nil?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :filename, :coverage, :src, :lines
|
36
|
+
alias_method :source, :src
|
37
|
+
alias_method :source_lines, :lines
|
38
|
+
|
39
|
+
def initialize(filename, coverage)
|
40
|
+
@filename, @coverage, @src = filename, coverage, File.readlines(filename)
|
41
|
+
@lines = []
|
42
|
+
coverage.each_with_index do |coverage, i|
|
43
|
+
@lines << SimpleCov::SourceFile::Line.new(src[i], i+1, coverage)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def line(number)
|
48
|
+
lines[number-1]
|
49
|
+
end
|
50
|
+
|
51
|
+
def covered_percent
|
52
|
+
return 100.0 if lines.length == 0 or lines.length == never_lines.count
|
53
|
+
(covered_lines.count) * 100 / (lines.count-never_lines.count).to_f
|
54
|
+
end
|
55
|
+
|
56
|
+
def covered_lines
|
57
|
+
@covered_lines ||= lines.select {|c| c.covered? }
|
58
|
+
end
|
59
|
+
|
60
|
+
def missed_lines
|
61
|
+
@missed_lines ||= lines.select {|c| c.missed? }
|
62
|
+
end
|
63
|
+
|
64
|
+
def never_lines
|
65
|
+
@never_lines ||= lines.select {|c| c.never? }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/simple_cov.gemspec
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{simple_cov}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Christoph Olszowka"]
|
12
|
+
s.date = %q{2010-08-20}
|
13
|
+
s.description = %q{Makes ruby 1.9's code coverage library's results more accessible in an object-oriented manner and adds some sugar on top}
|
14
|
+
s.email = %q{christoph at olszowka.de}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/simple_cov.rb",
|
27
|
+
"lib/simple_cov/adapters.rb",
|
28
|
+
"lib/simple_cov/configuration.rb",
|
29
|
+
"lib/simple_cov/filter.rb",
|
30
|
+
"lib/simple_cov/formatter.rb",
|
31
|
+
"lib/simple_cov/formatter/simple_formatter.rb",
|
32
|
+
"lib/simple_cov/merge_helpers.rb",
|
33
|
+
"lib/simple_cov/result.rb",
|
34
|
+
"lib/simple_cov/result_merger.rb",
|
35
|
+
"lib/simple_cov/source_file.rb",
|
36
|
+
"simple_cov.gemspec",
|
37
|
+
"test/fixtures/app/controllers/sample_controller.rb",
|
38
|
+
"test/fixtures/app/models/user.rb",
|
39
|
+
"test/fixtures/resultset1.rb",
|
40
|
+
"test/fixtures/resultset2.rb",
|
41
|
+
"test/fixtures/sample.rb",
|
42
|
+
"test/helper.rb",
|
43
|
+
"test/test_filters.rb",
|
44
|
+
"test/test_merge_helpers.rb",
|
45
|
+
"test/test_result.rb",
|
46
|
+
"test/test_source_file.rb",
|
47
|
+
"test/test_source_file_line.rb"
|
48
|
+
]
|
49
|
+
s.homepage = %q{http://github.com/colszowka/simple_cov}
|
50
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
51
|
+
s.require_paths = ["lib"]
|
52
|
+
s.rubygems_version = %q{1.3.7}
|
53
|
+
s.summary = %q{Makes ruby 1.9's code coverage library's results more accessible in an object-oriented manner and adds some sugar on top}
|
54
|
+
s.test_files = [
|
55
|
+
"test/fixtures/app/controllers/sample_controller.rb",
|
56
|
+
"test/fixtures/app/models/user.rb",
|
57
|
+
"test/fixtures/resultset1.rb",
|
58
|
+
"test/fixtures/resultset2.rb",
|
59
|
+
"test/fixtures/sample.rb",
|
60
|
+
"test/helper.rb",
|
61
|
+
"test/test_filters.rb",
|
62
|
+
"test/test_merge_helpers.rb",
|
63
|
+
"test/test_result.rb",
|
64
|
+
"test/test_source_file.rb",
|
65
|
+
"test/test_source_file_line.rb"
|
66
|
+
]
|
67
|
+
|
68
|
+
if s.respond_to? :specification_version then
|
69
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
70
|
+
s.specification_version = 3
|
71
|
+
|
72
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
73
|
+
s.add_development_dependency(%q<shoulda>, ["= 2.10.3"])
|
74
|
+
else
|
75
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
76
|
+
end
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
data/simplecov.gemspec
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{simplecov}
|
8
|
+
s.version = "0.3.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Christoph Olszowka"]
|
12
|
+
s.date = %q{2010-08-22}
|
13
|
+
s.description = %q{Code coverage for Ruby 1.9}
|
14
|
+
s.email = %q{christoph at olszowka.de}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/simplecov.rb",
|
27
|
+
"lib/simplecov/adapters.rb",
|
28
|
+
"lib/simplecov/configuration.rb",
|
29
|
+
"lib/simplecov/filter.rb",
|
30
|
+
"lib/simplecov/formatter.rb",
|
31
|
+
"lib/simplecov/formatter/simple_formatter.rb",
|
32
|
+
"lib/simplecov/merge_helpers.rb",
|
33
|
+
"lib/simplecov/result.rb",
|
34
|
+
"lib/simplecov/result_merger.rb",
|
35
|
+
"lib/simplecov/source_file.rb",
|
36
|
+
"simple_cov.gemspec",
|
37
|
+
"simplecov.gemspec",
|
38
|
+
"test/fixtures/app/controllers/sample_controller.rb",
|
39
|
+
"test/fixtures/app/models/user.rb",
|
40
|
+
"test/fixtures/resultset1.rb",
|
41
|
+
"test/fixtures/resultset2.rb",
|
42
|
+
"test/fixtures/sample.rb",
|
43
|
+
"test/helper.rb",
|
44
|
+
"test/test_filters.rb",
|
45
|
+
"test/test_merge_helpers.rb",
|
46
|
+
"test/test_result.rb",
|
47
|
+
"test/test_source_file.rb",
|
48
|
+
"test/test_source_file_line.rb"
|
49
|
+
]
|
50
|
+
s.homepage = %q{http://github.com/colszowka/simplecov}
|
51
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.3.7}
|
54
|
+
s.summary = %q{Code coverage for Ruby 1.9}
|
55
|
+
s.test_files = [
|
56
|
+
"test/fixtures/app/controllers/sample_controller.rb",
|
57
|
+
"test/fixtures/app/models/user.rb",
|
58
|
+
"test/fixtures/resultset1.rb",
|
59
|
+
"test/fixtures/resultset2.rb",
|
60
|
+
"test/fixtures/sample.rb",
|
61
|
+
"test/helper.rb",
|
62
|
+
"test/test_filters.rb",
|
63
|
+
"test/test_merge_helpers.rb",
|
64
|
+
"test/test_result.rb",
|
65
|
+
"test/test_source_file.rb",
|
66
|
+
"test/test_source_file_line.rb"
|
67
|
+
]
|
68
|
+
|
69
|
+
if s.respond_to? :specification_version then
|
70
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
71
|
+
s.specification_version = 3
|
72
|
+
|
73
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
74
|
+
s.add_development_dependency(%q<shoulda>, ["= 2.10.3"])
|
75
|
+
else
|
76
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
77
|
+
end
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|