C0 code coverage information
Generated on Wed Oct 07 08:34:01 -0700 2009 with rcov 0.8.2.1
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements. See the NOTICE file distributed with this
3 # work for additional information regarding copyright ownership. The ASF
4 # licenses this file to you under the Apache License, Version 2.0 (the
5 # "License"); you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations under
14 # the License.
15
16
17 require 'buildr/java'
18
19
20 module Buildr
21
22 # Provides the <code>cobertura:html</code>, <code>cobertura:xml</code> and <code>cobertura:check</code> tasks.
23 # Require explicitly using <code>require "buildr/cobertura"</code>.
24 #
25 # You can generate cobertura reports for a single project
26 # using the project name as prefix:
27 #
28 # project_name:cobertura:html
29 #
30 # You can also specify which classes to include/exclude from instrumentation by
31 # passing a class name regexp to the <code>cobertura.include</code> or
32 # <code>cobertura.exclude</code> methods.
33 #
34 # define 'someModule' do
35 # cobertura.include 'some.package.*'
36 # cobertura.include /some.(foo|bar).*/
37 # cobertura.exclude 'some.foo.util.SimpleUtil'
38 # cobertura.exclude /*.Const(ants)?/i
39 # end
40 #
41 module Cobertura
42
43 VERSION = '1.9'
44
45 class << self
46
47 def version
48 Buildr.settings.build['cobertura'] || VERSION
49 end
50
51 def dependencies
52 @dependencies ||= [ "net.sourceforge.cobertura:cobertura:jar:#{version}", "log4j:log4j:jar:1.2.9",
53 "asm:asm:jar:2.2.1", "asm:asm-tree:jar:2.2.1", "oro:oro:jar:2.0.8"]
54 end
55
56 def report_to(file = nil)
57 File.expand_path(File.join(*["reports/cobertura", file.to_s].compact))
58 end
59
60 def data_file()
61 File.expand_path("reports/cobertura.ser")
62 end
63
64 end
65
66 class CoberturaConfig # :nodoc:
67
68 def initialize(project)
69 @project = project
70 end
71
72 attr_reader :project
73 private :project
74
75 attr_writer :data_file, :instrumented_dir, :report_dir
76
77 def data_file
78 @data_file ||= project.path_to(:reports, 'cobertura.ser')
79 end
80
81 def instrumented_dir
82 @instrumented_dir ||= project.path_to(:target, :instrumented, :classes)
83 end
84
85 def report_dir
86 @report_dir ||= project.path_to(:reports, :cobertura)
87 end
88
89 def report_to(file = nil)
90 File.expand_path(File.join(*[report_dir, file.to_s].compact))
91 end
92
93 # :call-seq:
94 # project.cobertura.include(*classPatterns)
95 #
96 def include(*classPatterns)
97 includes.push(*classPatterns.map { |p| String === p ? Regexp.new(p) : p })
98 self
99 end
100
101 def includes
102 @includeClasses ||= []
103 end
104
105 # :call-seq:
106 # project.cobertura.exclude(*classPatterns)
107 #
108 def exclude(*classPatterns)
109 excludes.push(*classPatterns.map { |p| String === p ? Regexp.new(p) : p })
110 self
111 end
112
113 def excludes
114 @excludeClasses ||= []
115 end
116
117 def sources
118 project.compile.sources
119 end
120
121 def check
122 @check ||= CoberturaCheck.new
123 end
124 end
125
126 class CoberturaCheck
127 attr_writer :branch_rate, :line_rate, :total_branch_rate, :total_line_rate, :package_line_rate, :package_branch_rate
128 attr_reader :branch_rate, :line_rate, :total_branch_rate, :total_line_rate, :package_line_rate, :package_branch_rate
129 end
130
131 module CoberturaExtension # :nodoc:
132 include Buildr::Extension
133
134 def cobertura
135 @cobertura_config ||= CoberturaConfig.new(self)
136 end
137
138 after_define do |project|
139 cobertura = project.cobertura
140
141 namespace 'cobertura' do
142 unless project.compile.target.nil?
143 # Instrumented bytecode goes in a different directory. This task creates before running the test
144 # cases and monitors for changes in the generate bytecode.
145 instrumented = project.file(cobertura.instrumented_dir => project.compile.target) do |task|
146 mkdir_p task.to_s
147 unless project.compile.sources.empty?
148 info "Instrumenting classes with cobertura data file #{cobertura.data_file}"
149 Buildr.ant "cobertura" do |ant|
150 ant.taskdef :resource=>"tasks.properties",
151 :classpath=>Buildr.artifacts(Cobertura.dependencies).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
152 ant.send "cobertura-instrument", :todir=>task.to_s, :datafile=>cobertura.data_file do
153 includes, excludes = cobertura.includes, cobertura.excludes
154
155 classes_dir = project.compile.target.to_s
156 if includes.empty? && excludes.empty?
157 ant.fileset :dir => classes_dir do
158 ant.include :name => "**/*.class"
159 end
160 else
161 includes = [//] if includes.empty?
162 Dir.glob(File.join(classes_dir, "**/*.class")) do |cls|
163 cls_name = cls.gsub(/#{classes_dir}\/?|\.class$/, '').gsub('/', '.')
164 if includes.any? { |p| p === cls_name } && !excludes.any? { |p| p === cls_name }
165 ant.fileset :file => cls
166 end
167 end
168 end
169 end
170 end
171 end
172 touch task.to_s
173 end
174
175 task 'instrument' => instrumented
176
177 # We now have two target directories with bytecode. It would make sense to remove compile.target
178 # and add instrumented instead, but apparently Cobertura only creates some of the classes, so
179 # we need both directories and instrumented must come first.
180 project.test.dependencies.unshift cobertura.instrumented_dir
181 project.test.with Cobertura.dependencies
182 project.test.options[:properties]["net.sourceforge.cobertura.datafile"] = cobertura.data_file
183
184 unless project.compile.sources.empty?
185 [:xml, :html].each do |format|
186 task format => ['instrument', 'test'] do
187 info "Creating test coverage reports in #{cobertura.report_to(format)}"
188 Buildr.ant "cobertura" do |ant|
189 ant.taskdef :resource=>"tasks.properties",
190 :classpath=>Buildr.artifacts(Cobertura.dependencies).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
191 ant.send "cobertura-report", :format=>format,
192 :destdir=>cobertura.report_to(format), :datafile=>cobertura.data_file do
193 cobertura.sources.flatten.each do |src|
194 ant.fileset(:dir=>src.to_s) if File.exist?(src.to_s)
195 end
196 end
197 end
198 end
199 end
200 end
201
202 task :check => [:instrument, :test] do
203 Buildr.ant "cobertura" do |ant|
204 ant.taskdef :classpath=>Cobertura.requires.join(File::PATH_SEPARATOR), :resource=>"tasks.properties"
205
206 params = { :datafile => Cobertura.data_file }
207
208 # oh so ugly...
209 params[:branchrate] = cobertura.check.branch_rate if cobertura.check.branch_rate
210 params[:linerate] = cobertura.check.line_rate if cobertura.check.line_rate
211 params[:totalbranchrate] = cobertura.check.total_branch_rate if cobertura.check.total_branch_rate
212 params[:totallinerate] = cobertura.check.total_line_rate if cobertura.check.total_line_rate
213 params[:packagebranchrate] = cobertura.check.package_branch_rate if cobertura.check.package_branch_rate
214 params[:packagelinerate] = cobertura.check.package_line_rate if cobertura.check.package_line_rate
215
216 ant.send("cobertura-check", params) do
217 end
218 end
219 end
220
221 end
222 end
223
224 project.clean do
225 rm_rf [cobertura.report_to, cobertura.data_file, cobertura.instrumented_dir]
226 end
227
228 end
229
230 end
231
232 class Buildr::Project
233 include CoberturaExtension
234 end
235
236 namespace "cobertura" do
237
238 task "instrument" do
239 Buildr.projects.each do |project|
240 project.cobertura.data_file = data_file
241 project.test.options[:properties]["net.sourceforge.cobertura.datafile"] = data_file
242 instrument_task ="#{project.name}:cobertura:instrument"
243 task(instrument_task).invoke if Rake::Task.task_defined?(instrument_task)
244 end
245 end
246
247 [:xml, :html].each do |format|
248 report_target = report_to(format)
249 desc "Run the test cases and produce code coverage reports in #{report_target}"
250 task format => ["instrument", "test"] do
251 info "Creating test coverage reports in #{report_target}"
252 Buildr.ant "cobertura" do |ant|
253 ant.taskdef :resource=>"tasks.properties",
254 :classpath=>Buildr.artifacts(Cobertura.dependencies).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
255 ant.send "cobertura-report", :destdir=>report_target, :format=>format, :datafile=>data_file do
256 Buildr.projects.map(&:cobertura).map(&:sources).flatten.each do |src|
257 ant.fileset :dir=>src.to_s if File.exist?(src.to_s)
258 end
259 end
260 end
261 end
262 end
263
264 task "clean" do
265 rm_rf [report_to, data_file]
266 end
267 end
268
269 task "clean" do
270 task("cobertura:clean").invoke if Dir.pwd == Rake.application.original_dir
271 end
272
273 end
274 end
Generated using the rcov code coverage analysis tool for Ruby
version 0.8.2.1.