cover-up 0.1

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.
Files changed (2) hide show
  1. data/lib/cover-up.rb +127 -0
  2. metadata +53 -0
@@ -0,0 +1,127 @@
1
+ module CoverUp
2
+ # This tracks overall coverage results for a run
3
+ class Result
4
+ attr_accessor :files
5
+
6
+ # This initializes the result with the individual file results
7
+ def initialize(files)
8
+ self.files = files
9
+ end
10
+
11
+ # This returns the total amount of lines in this coverage report
12
+ def lines
13
+ sum = 0
14
+ self.files.collect { |f| f.lines }.each { |i| sum += i }
15
+ sum
16
+ end
17
+
18
+ # This returns the total amount of lines without exclusions in this coverage report
19
+ def lines_without_exclusions
20
+ sum = 0
21
+ self.files.collect { |f| f.lines_without_exclusions }.each { |i| sum += i }
22
+ sum
23
+ end
24
+
25
+ # This calculates the overall hit percentage for the run
26
+ def hit_percentage
27
+ return 0 if self.lines_without_exclusions.to_f == 0.0
28
+ hit = self.files.collect { |f| f.hit }.flatten
29
+ (hit.length.to_f / self.lines_without_exclusions.to_f) * 100.0
30
+ end
31
+
32
+ # This calculates the overall miss percentage for the run
33
+ def missed_percentage
34
+ return 0 if self.lines_without_exclusions.to_f == 0.0
35
+ missed = self.files.collect { |f| f.missed }.flatten
36
+ (missed.length.to_f / self.lines_without_exclusions.to_f) * 100.0
37
+ end
38
+ end
39
+
40
+ # This tracks coverage results for an individual file
41
+ class FileResult
42
+ attr_accessor :name, :lines, :hit, :missed, :excluded
43
+
44
+ # This initializes the file result with the amount of lines, and the hit/missed/excluded lines for the file, along with the name
45
+ def initialize(name, lines, hit, missed, excluded)
46
+ self.name = name
47
+ self.lines = lines
48
+ self.hit = hit
49
+ self.missed = missed
50
+ self.excluded = excluded
51
+ end
52
+
53
+ # This returns the amount of lines after the excluded lines have been removed
54
+ def lines_without_exclusions
55
+ self.lines - excluded.length
56
+ end
57
+
58
+ # This calculates the percentage of lines that were hit by the code being covered
59
+ def hit_percentage
60
+ return 0 if self.lines_with_exclusions.to_f == 0.0
61
+ (self.hit.length.to_f / self.lines_with_exclusions.to_f) * 100.0
62
+ end
63
+
64
+ # This calculates the percentage of lines that were missed by the code being covered
65
+ def missed_percentage
66
+ return 0 if self.lines_with_exclusions.to_f == 0.0
67
+ (self.missed.length.to_f / self.lines_with_exclusions.to_f) * 100.0
68
+ end
69
+ end
70
+ end
71
+
72
+ # This is the wrapper call that is used to run code coverage on Ruby code
73
+ def coverage(options = {}, &block)
74
+ # We default the coverage scan to any Ruby files in the current directory, but that can be over-ridden
75
+ files = options[:include].nil? ? Dir.glob("*.rb") : Dir.glob(options[:include])
76
+ # This will hold the trace information
77
+ trace = {}
78
+ # Let's set a trace function so that every method call can be tracked
79
+ set_trace_func(proc do |event, file, line, id, binding, klass|
80
+ # We unify the filename to it's absolute path
81
+ file = File.expand_path(file)
82
+ # Add the line number that was hit for this file, if it hasn't already been hit
83
+ trace[file] ||= []
84
+ trace[file] << line unless trace[file].include?(line)
85
+ end)
86
+ # Now that we've set up the trace function, we can execute the code (trapping any exceptions)
87
+ begin
88
+ yield
89
+ rescue Exception => ex
90
+ puts "ERROR: exception \"#{ex.message}\" while running code coverage"
91
+ end
92
+ # Once that's run, we stop the trace function
93
+ set_trace_func(nil)
94
+ # Now we collate the results
95
+ results = []
96
+ # Loop through all files
97
+ files.each do |file|
98
+ # Expand the path, to unify it as we did before
99
+ file = File.expand_path(file)
100
+ # Grab the file data
101
+ data = File.read(file)
102
+ # Grab the amount of lines for the file
103
+ lines = data.split("\n")
104
+ # Keep track of which lines are hit, missed or excluded
105
+ hit = []
106
+ missed = []
107
+ excluded = []
108
+ # Loop through and analyse lines
109
+ lines.each_with_index do |line, index|
110
+ number = index + 1
111
+ # If the line is a comment or an empty line, or it's the last line and it's "end", it's excluded
112
+ if line.strip[0...1] == "#" || line.strip.empty? || (number == lines.length && line.strip == "end")
113
+ excluded << number
114
+ elsif (trace[file] || []).include?(number)
115
+ # Otherwise, if it was in the trace, it was hit
116
+ hit << number
117
+ else
118
+ # Lastly, if it isn't excluded or hit, it was missed
119
+ missed << number
120
+ end
121
+ end
122
+ # Create the file result with the file name, the total lines, the lines hit, the lines that weren't hit, and the lines that were excluded
123
+ results << CoverUp::FileResult.new(file, lines.length, hit, missed, excluded)
124
+ end
125
+ # Return the coverage results
126
+ CoverUp::Result.new(results)
127
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cover-up
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - El Draper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-13 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: el@ejdraper.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/cover-up.rb
26
+ has_rdoc: false
27
+ homepage: http://github.com/edraper/cover-up
28
+ post_install_message:
29
+ rdoc_options: []
30
+
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: "0"
38
+ version:
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ requirements: []
46
+
47
+ rubyforge_project:
48
+ rubygems_version: 1.3.1
49
+ signing_key:
50
+ specification_version: 2
51
+ summary: Provides dynamic coverage for Ruby code
52
+ test_files: []
53
+