C0 code coverage information

Generated on Wed Oct 07 08:34:03 -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.
Name Total lines Lines of code Total coverage Code coverage
lib/buildr/java/tests.rb 333 211
92.8%  
89.1%  
  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/core/build'
 18 require 'buildr/core/compile'
 19 require 'buildr/java/ant'
 20 
 21 
 22 module Buildr
 23 
 24   class TestFramework::Java < TestFramework::Base
 25 
 26     class << self
 27       
 28       def applies_to?(project) #:nodoc:
 29         project.test.compile.language == :java
 30       end
 31       
 32     end
 33     
 34   private
 35 
 36     # Add buildr utilities (JavaTestFilter) to classpath
 37     Java.classpath << File.join(File.dirname(__FILE__))
 38 
 39     # :call-seq:
 40     #     filter_classes(dependencies, criteria)
 41     # 
 42     # Return a list of classnames that match the given criteria. 
 43     # The criteria parameter is a hash that must contain at least one of:
 44     #
 45     # * :class_names -- List of patterns to match against class name
 46     # * :interfaces -- List of java interfaces or java classes
 47     # * :class_annotations -- List of annotations on class level
 48     # * :method_annotations -- List of annotations on method level
 49     # * :fields -- List of java field names
 50     #
 51     def filter_classes(dependencies, criteria = {})
 52       return [] unless task.compile.target
 53       target = task.compile.target.to_s
 54       candidates = Dir["#{target}/**/*.class"].
 55         map { |file| Util.relative_path(file, target).ext('').gsub(File::SEPARATOR, '.') }.
 56         reject { |name| name =~ /\$./ }
 57       result = []
 58       if criteria[:class_names]
 59         result.concat candidates.select { |name| criteria[:class_names].flatten.any? { |pat| pat === name } }
 60       end
 61       begin
 62         Java.load
 63         filter = Java.org.apache.buildr.JavaTestFilter.new(dependencies.to_java(Java.java.lang.String))
 64         if criteria[:interfaces]
 65           filter.add_interfaces(criteria[:interfaces].to_java(Java.java.lang.String)) 
 66         end
 67         if criteria[:class_annotations]
 68           filter.add_class_annotations(criteria[:class_annotations].to_java(Java.java.lang.String))
 69         end
 70         if criteria[:method_annotations]
 71           filter.add_method_annotations(criteria[:method_annotations].to_java(Java.java.lang.String))
 72         end
 73         if criteria[:fields]
 74           filter.add_fields(criteria[:fields].to_java(Java.java.lang.String))
 75         end
 76         result.concat filter.filter(candidates.to_java(Java.java.lang.String)).map(&:to_s)
 77       rescue =>ex
 78         info "#{ex.class}: #{ex.message}"
 79         raise
 80       end
 81     end
 82     
 83   end
 84 
 85 
 86   # JMock is available when using JUnit and TestNG, JBehave.
 87   module JMock
 88     
 89     VERSION = '1.2.0'
 90     
 91     class << self
 92       def version
 93         Buildr.settings.build['jmock'] || VERSION
 94       end
 95 
 96       def dependencies
 97         @dependencies ||= ["jmock:jmock:jar:#{version}"]
 98       end
 99       
100     private
101       def const_missing(const)
102         return super unless const == :REQUIRES # TODO: remove in 1.5
103         Buildr.application.deprecated "Please use JMock.dependencies/.version instead of JMock::REQUIRES/VERSION"
104         dependencies
105       end
106     end    
107   end
108 
109 
110   # JUnit test framework, the default test framework for Java tests.
111   #
112   # Support the following options:
113   # * :fork        -- If true/:once (default), fork for each test class.  If :each, fork for each individual
114   #                   test case.  If false, run all tests in the same VM (fast, but dangerous).
115   # * :clonevm     -- If true clone the VM each time it is forked.
116   # * :properties  -- Hash of system properties available to the test case.
117   # * :environment -- Hash of environment variables available to the test case.
118   # * :java_args   -- Arguments passed as is to the JVM.
119   class JUnit < TestFramework::Java
120 
121     # Used by the junit:report task. Access through JUnit#report if you want to set various
122     # options for that task, for example:
123     #   JUnit.report.frames = false
124     class Report
125 
126       # Parameters passed to the Ant JUnitReport task.
127       attr_reader :params
128       # True (default) to produce a report using frames, false to produce a single-page report.
129       attr_accessor :frames
130       # Directory for the report style (defaults to using the internal style).
131       attr_accessor :style_dir
132       # Target directory for generated report.
133       attr_accessor :target
134 
135       def initialize
136         @params = {}
137         @frames = true
138         @target = 'reports/junit'
139       end
140 
141       # :call-seq:
142       #   generate(projects, target?)
143       #
144       # Generates a JUnit report for these projects (must run JUnit tests first) into the
145       # target directory. You can specify a target, or let it pick the default one from the
146       # target attribute.
147       def generate(projects, target = @target.to_s)
148         html_in = File.join(target, 'html')
149         rm_rf html_in ; mkpath html_in
150         
151         Buildr.ant('junit-report') do |ant|
152           ant.taskdef :name=>'junitreport', :classname=>'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
153             :classpath=>Buildr.artifacts(JUnit.ant_taskdef).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
154           ant.junitreport :todir=>target do
155             projects.select { |project| project.test.framework == :junit }.
156               map { |project| project.test.report_to.to_s }.select { |path| File.exist?(path) }.
157               each { |path| ant.fileset(:dir=>path) { ant.include :name=>'TEST-*.xml' }  }
158             options = { :format=>frames ? 'frames' : 'noframes' }
159             options[:styledir] = style_dir if style_dir
160             ant.report options.merge(:todir=>html_in) do
161               params.each { |key, value| ant.param :name=>key, :expression=>value }
162             end
163           end
164         end
165       end
166 
167     end
168 
169     # JUnit version number.
170     VERSION = '4.5'
171 
172     class << self
173       # :call-seq:
174       #    report()
175       #
176       # Returns the Report object used by the junit:report task. You can use this object to set
177       # various options that affect your report, for example:
178       #   JUnit.report.frames = false
179       #   JUnit.report.params['title'] = 'My App'
180       def report
181         @report ||= Report.new
182       end
183 
184       def version
185         Buildr.settings.build['junit'] || VERSION
186       end
187       
188       def dependencies
189         @dependencies ||= ["junit:junit:jar:#{version}"]+ JMock.dependencies
190       end
191       
192       def ant_taskdef #:nodoc:
193         "org.apache.ant:ant-junit:jar:#{Ant.version}"
194       end
195       
196     private
197       def const_missing(const)
198         return super unless const == :REQUIRES # TODO: remove in 1.5
199         Buildr.application.deprecated "Please use JUnit.dependencies/.version instead of JUnit::REQUIRES/VERSION"
200         dependencies
201       end
202     end          
203 
204     def tests(dependencies) #:nodoc:
205       filter_classes(dependencies, 
206                      :interfaces => %w{junit.framework.TestCase},
207                      :class_annotations => %w{org.junit.runner.RunWith},
208                      :method_annotations => %w{org.junit.Test})
209     end
210 
211     def run(tests, dependencies) #:nodoc:
212       # Use Ant to execute the Junit tasks, gives us performance and reporting.
213       Buildr.ant('junit') do |ant|
214         case options[:fork]
215         when false
216           forking = {}
217         when :each
218           forking = { :fork=>true, :forkmode=>'perTest' }
219         when true, :once
220           forking = { :fork=>true, :forkmode=>'once' }
221         else
222           fail 'Option fork must be :once, :each or false.'
223         end
224         mkpath task.report_to.to_s
225 
226         taskdef = Buildr.artifact(JUnit.ant_taskdef)
227         taskdef.invoke
228         ant.taskdef :name=>'junit', :classname=>'org.apache.tools.ant.taskdefs.optional.junit.JUnitTask', :classpath=>taskdef.to_s
229 
230         ant.junit forking.merge(:clonevm=>options[:clonevm] || false, :dir=>task.send(:project).path_to) do
231           ant.classpath :path=>dependencies.join(File::PATH_SEPARATOR)
232           (options[:properties] || []).each { |key, value| ant.sysproperty :key=>key, :value=>value }
233           (options[:environment] || []).each { |key, value| ant.env :key=>key, :value=>value }
234           Array(options[:java_args]).each { |value| ant.jvmarg :value=>value }
235           ant.formatter :type=>'plain'
236           ant.formatter :type=>'plain', :usefile=>false # log test
237           ant.formatter :type=>'xml'
238           ant.batchtest :todir=>task.report_to.to_s, :failureproperty=>'failed' do
239             ant.fileset :dir=>task.compile.target.to_s do
240               tests.each { |test| ant.include :name=>File.join(*test.split('.')).ext('class') }
241             end
242           end
243         end
244         return tests unless ant.project.getProperty('failed')
245       end
246       # But Ant doesn't tell us what went kaput, so we'll have to parse the test files.
247       tests.inject([]) do |passed, test|
248         report_file = File.join(task.report_to.to_s, "TEST-#{test}.txt")
249         if File.exist?(report_file)
250           report = File.read(report_file)
251           # The second line (if exists) is the status line and we scan it for its values.
252           status = (report.split("\n")[1] || '').scan(/(run|failures|errors):\s*(\d+)/i).
253             inject(Hash.new(0)) { |hash, pair| hash[pair[0].downcase.to_sym] = pair[1].to_i ; hash }
254           passed << test if status[:failures] == 0 && status[:errors] == 0
255         end
256         passed
257       end
258     end
259 
260     namespace 'junit' do
261       desc "Generate JUnit tests report in #{report.target}"
262       task('report') do |task|
263         report.generate Project.projects
264         info "Generated JUnit tests report in #{report.target}"
265       end
266     end
267 
268     task('clean') { rm_rf report.target.to_s }
269 
270   end
271 
272 
273   # TestNG test framework.  To use in your project:
274   #   test.using :testng
275   #
276   # Support the following options:
277   # * :properties -- Hash of properties passed to the test suite.
278   # * :java_args -- Arguments passed to the JVM.
279   class TestNG < TestFramework::Java
280 
281     VERSION = '5.10'
282 
283     class << self
284       def version
285         Buildr.settings.build['testng'] || VERSION
286       end
287       
288       def dependencies
289         ["org.testng:testng:jar:jdk15:#{version}"]+ JMock.dependencies
290       end  
291       
292     private
293       def const_missing(const)
294         return super unless const == :REQUIRES # TODO: remove in 1.5
295         Buildr.application.deprecated "Please use TestNG.dependencies/.version instead of TestNG::REQUIRES/VERSION"
296         dependencies
297       end
298     end          
299 
300     def tests(dependencies) #:nodoc:
301       filter_classes(dependencies, 
302                      :class_annotations => %w{org.testng.annotations.Test},
303                      :method_annotations => %w{org.testng.annotations.Test})
304     end
305 
306     def run(tests, dependencies) #:nodoc:
307       cmd_args = [ 'org.testng.TestNG', '-log', '2', '-sourcedir', task.compile.sources.join(';'), '-suitename', task.project.id ]
308       cmd_args << '-d' << task.report_to.to_s
309       # run all tests in the same suite
310       cmd_args << '-testclass' << tests
311       cmd_options = { :properties=>options[:properties], :java_args=>options[:java_args],
312         :classpath=>dependencies, :name => "TestNG in #{task.send(:project).name}" }
313 
314       begin
315         Java::Commands.java cmd_args, cmd_options
316         return tests
317       rescue
318         # testng-failed.xml contains the list of failed tests *only*
319         report = File.read(File.join(task.report_to.to_s, 'testng-failed.xml'))
320         failed = report.scan(/<class name="(.*?)">/im).flatten
321         error "TestNG regexp returned unexpected failed tests #{failed.inspect}" unless (failed - tests).empty?
322         # return the list of passed tests
323         return tests - failed
324       end
325     end
326 
327   end
328 
329 end # Buildr
330 
331 
332 Buildr::TestFramework << Buildr::JUnit
333 Buildr::TestFramework << Buildr::TestNG

Generated using the rcov code coverage analysis tool for Ruby version 0.8.2.1.

Valid XHTML 1.0! Valid CSS!