simplecov 0.3.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.
- 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
|
+
|