Buildr C0 Coverage Information - RCov

lib/buildr/java/tests.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/buildr/java/tests.rb 362 236
27.07%
24.15%

Key

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.

Coverage Details

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

Generated on 2011-07-06 23:35:37 -0700 with rcov 0.9.8