buildr 1.3.2-java → 1.3.3-java
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +66 -4
- data/{README → README.rdoc} +29 -16
- data/Rakefile +16 -20
- data/_buildr +38 -0
- data/addon/buildr/cobertura.rb +49 -45
- data/addon/buildr/emma.rb +238 -0
- data/addon/buildr/jetty.rb +1 -1
- data/addon/buildr/nailgun.rb +585 -661
- data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail$Main.class +0 -0
- data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail.class +0 -0
- data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail.java +0 -0
- data/bin/buildr +9 -2
- data/buildr.buildfile +53 -0
- data/buildr.gemspec +21 -14
- data/doc/css/default.css +51 -48
- data/doc/css/print.css +60 -55
- data/doc/images/favicon.png +0 -0
- data/doc/images/growl-icon.tiff +0 -0
- data/doc/images/project-structure.png +0 -0
- data/doc/pages/artifacts.textile +46 -156
- data/doc/pages/building.textile +63 -323
- data/doc/pages/contributing.textile +112 -102
- data/doc/pages/download.textile +19 -27
- data/doc/pages/extending.textile +27 -81
- data/doc/pages/getting_started.textile +44 -119
- data/doc/pages/index.textile +26 -47
- data/doc/pages/languages.textile +407 -0
- data/doc/pages/more_stuff.textile +92 -173
- data/doc/pages/packaging.textile +71 -239
- data/doc/pages/projects.textile +58 -233
- data/doc/pages/recipes.textile +19 -43
- data/doc/pages/settings_profiles.textile +39 -104
- data/doc/pages/testing.textile +41 -304
- data/doc/pages/troubleshooting.textile +29 -47
- data/doc/pages/whats_new.textile +69 -167
- data/doc/print.haml +0 -1
- data/doc/print.toc.yaml +1 -0
- data/doc/scripts/buildr-git.rb +1 -1
- data/doc/site.haml +1 -0
- data/doc/site.toc.yaml +8 -5
- data/{KEYS → etc/KEYS} +0 -0
- data/etc/git-svn-authors +16 -0
- data/lib/buildr.rb +2 -5
- data/lib/buildr/core/application.rb +192 -98
- data/lib/buildr/core/build.rb +140 -91
- data/lib/buildr/core/checks.rb +5 -5
- data/lib/buildr/core/common.rb +1 -1
- data/lib/buildr/core/compile.rb +12 -10
- data/lib/buildr/core/filter.rb +151 -46
- data/lib/buildr/core/generate.rb +9 -9
- data/lib/buildr/core/progressbar.rb +1 -1
- data/lib/buildr/core/project.rb +8 -7
- data/lib/buildr/core/test.rb +51 -26
- data/lib/buildr/core/transports.rb +22 -38
- data/lib/buildr/core/util.rb +78 -26
- data/lib/buildr/groovy.rb +18 -0
- data/lib/buildr/groovy/bdd.rb +105 -0
- data/lib/buildr/groovy/compiler.rb +138 -0
- data/lib/buildr/ide/eclipse.rb +102 -71
- data/lib/buildr/ide/idea.rb +7 -12
- data/lib/buildr/ide/idea7x.rb +7 -8
- data/lib/buildr/java.rb +4 -7
- data/lib/buildr/java/ant.rb +26 -5
- data/lib/buildr/java/bdd.rb +449 -0
- data/lib/buildr/java/commands.rb +9 -9
- data/lib/buildr/java/{compilers.rb → compiler.rb} +8 -90
- data/lib/buildr/java/jruby.rb +29 -11
- data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
- data/lib/buildr/java/packaging.rb +23 -16
- data/lib/buildr/java/pom.rb +1 -1
- data/lib/buildr/java/rjb.rb +21 -8
- data/lib/buildr/java/test_result.rb +308 -0
- data/lib/buildr/java/tests.rb +324 -0
- data/lib/buildr/packaging/artifact.rb +12 -11
- data/lib/buildr/packaging/artifact_namespace.rb +7 -4
- data/lib/buildr/packaging/gems.rb +3 -3
- data/lib/buildr/packaging/zip.rb +13 -10
- data/lib/buildr/resources/buildr.icns +0 -0
- data/lib/buildr/scala.rb +19 -0
- data/lib/buildr/scala/compiler.rb +109 -0
- data/lib/buildr/scala/tests.rb +203 -0
- data/rakelib/apache.rake +71 -45
- data/rakelib/doc.rake +2 -2
- data/rakelib/package.rake +3 -2
- data/rakelib/rspec.rake +23 -21
- data/rakelib/setup.rake +34 -9
- data/rakelib/stage.rake +4 -1
- data/spec/addon/cobertura_spec.rb +77 -0
- data/spec/addon/emma_spec.rb +120 -0
- data/spec/addon/test_coverage_spec.rb +255 -0
- data/spec/{application_spec.rb → core/application_spec.rb} +82 -4
- data/spec/{artifact_namespace_spec.rb → core/artifact_namespace_spec.rb} +12 -1
- data/spec/core/build_spec.rb +415 -0
- data/spec/{checks_spec.rb → core/checks_spec.rb} +2 -2
- data/spec/{common_spec.rb → core/common_spec.rb} +119 -30
- data/spec/{compile_spec.rb → core/compile_spec.rb} +17 -13
- data/spec/core/generate_spec.rb +33 -0
- data/spec/{project_spec.rb → core/project_spec.rb} +9 -6
- data/spec/{test_spec.rb → core/test_spec.rb} +222 -28
- data/spec/{transport_spec.rb → core/transport_spec.rb} +5 -9
- data/spec/groovy/bdd_spec.rb +80 -0
- data/spec/{groovy_compilers_spec.rb → groovy/compiler_spec.rb} +1 -1
- data/spec/ide/eclipse_spec.rb +243 -0
- data/spec/{java_spec.rb → java/ant.rb} +7 -17
- data/spec/java/bdd_spec.rb +358 -0
- data/spec/{java_compilers_spec.rb → java/compiler_spec.rb} +1 -1
- data/spec/java/java_spec.rb +88 -0
- data/spec/{java_packaging_spec.rb → java/packaging_spec.rb} +65 -4
- data/spec/{java_test_frameworks_spec.rb → java/tests_spec.rb} +31 -10
- data/spec/{archive_spec.rb → packaging/archive_spec.rb} +12 -2
- data/spec/{artifact_spec.rb → packaging/artifact_spec.rb} +12 -5
- data/spec/{packaging_helper.rb → packaging/packaging_helper.rb} +0 -0
- data/spec/{packaging_spec.rb → packaging/packaging_spec.rb} +1 -1
- data/spec/sandbox.rb +22 -5
- data/spec/{scala_compilers_spec.rb → scala/compiler_spec.rb} +1 -1
- data/spec/{scala_test_frameworks_spec.rb → scala/tests_spec.rb} +11 -12
- data/spec/spec_helpers.rb +38 -17
- metadata +93 -70
- data/lib/buildr/java/bdd_frameworks.rb +0 -265
- data/lib/buildr/java/groovyc.rb +0 -137
- data/lib/buildr/java/test_frameworks.rb +0 -450
- data/spec/build_spec.rb +0 -193
- data/spec/java_bdd_frameworks_spec.rb +0 -238
- data/spec/spec.opts +0 -6
data/lib/buildr/java/rjb.rb
CHANGED
@@ -71,9 +71,13 @@ module Java
|
|
71
71
|
end
|
72
72
|
|
73
73
|
end
|
74
|
+
|
75
|
+
# On OS X we know where the default JDK is. We can try to guess for other OS.
|
76
|
+
# We set JAVA_HOME early so we can use it without calling Java.load first.
|
77
|
+
ENV['JAVA_HOME'] ||= '/System/Library/Frameworks/JavaVM.framework/Home' if Config::CONFIG['host_os'] =~ /darwin/i
|
74
78
|
|
75
79
|
class << self
|
76
|
-
|
80
|
+
|
77
81
|
# Returns the classpath, an array listing directories, JAR files and
|
78
82
|
# artifacts. Use when loading the extension to add any additional
|
79
83
|
# libraries used by that extension.
|
@@ -83,19 +87,28 @@ module Java
|
|
83
87
|
def classpath
|
84
88
|
@classpath ||= []
|
85
89
|
end
|
86
|
-
|
90
|
+
|
91
|
+
# Most platforms requires tools.jar to be on the classpath, tools.jar contains the
|
92
|
+
# Java compiler (OS X and AIX are two exceptions we know about, may be more).
|
93
|
+
# Guess where tools.jar is from JAVA_HOME, which hopefully points to the JDK,
|
94
|
+
# but maybe the JRE. Return nil if not found.
|
95
|
+
def tools_jar #:nodoc:
|
96
|
+
@tools_jar ||= begin
|
97
|
+
home = ENV['JAVA_HOME'] or fail 'Are we forgetting something? JAVA_HOME not set.'
|
98
|
+
['lib/tools.jar', '../lib/tools.jar'].map { |path| File.expand_path(path, home) }.
|
99
|
+
find { |path| File.exist?(path) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
87
103
|
# Loads the JVM and all the libraries listed on the classpath. Call this
|
88
104
|
# method before accessing any Java class, but only call it from methods
|
89
105
|
# used in the build, giving the Buildfile a chance to load all extensions
|
90
106
|
# that append to the classpath and specify which remote repositories to use.
|
91
107
|
def load
|
92
108
|
return self if @loaded
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
raise "I need tools.jar to compile, can't find it in #{home}/lib" unless File.exist?(tools)
|
97
|
-
classpath << tools
|
98
|
-
end
|
109
|
+
classpath << tools_jar if tools_jar
|
110
|
+
|
111
|
+
classpath.map! { |path| Proc === path ? path.call : path }
|
99
112
|
cp = Buildr.artifacts(classpath).map(&:to_s).each { |path| file(path).invoke }
|
100
113
|
java_opts = (ENV['JAVA_OPTS'] || ENV['JAVA_OPTIONS']).to_s.split
|
101
114
|
::Rjb.load cp.join(File::PATH_SEPARATOR), java_opts
|
@@ -0,0 +1,308 @@
|
|
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
|
+
require 'yaml'
|
17
|
+
|
18
|
+
module Buildr #:nodoc:
|
19
|
+
module TestFramework
|
20
|
+
|
21
|
+
# A class used by buildr for jruby based frameworks, so that buildr can know
|
22
|
+
# which tests succeeded/failed.
|
23
|
+
class TestResult
|
24
|
+
|
25
|
+
class Error < ::Exception
|
26
|
+
attr_reader :message, :backtrace
|
27
|
+
def initialize(message, backtrace)
|
28
|
+
@message = message
|
29
|
+
@backtrace = backtrace
|
30
|
+
set_backtrace backtrace
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.dump_yaml(file, e)
|
34
|
+
require 'fileutils'
|
35
|
+
FileUtils.mkdir_p(File.dirname(file))
|
36
|
+
File.open(file, 'w') { |f| f.puts(YAML.dump(Error.new(e.message, e.backtrace))) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.guard(file)
|
40
|
+
begin
|
41
|
+
yield
|
42
|
+
rescue
|
43
|
+
dump_yaml(file)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_accessor :failed, :succeeded
|
49
|
+
|
50
|
+
def initialize
|
51
|
+
@failed, @succeeded = [], []
|
52
|
+
end
|
53
|
+
|
54
|
+
# An Rspec formatter used by buildr
|
55
|
+
class YamlFormatter
|
56
|
+
attr_reader :result
|
57
|
+
|
58
|
+
attr_accessor :example_group, :options, :where
|
59
|
+
|
60
|
+
def initialize(options, where)
|
61
|
+
@options = options
|
62
|
+
@where = where
|
63
|
+
@result = Hash.new
|
64
|
+
@result[:succeeded] = []
|
65
|
+
@result[:failed] = []
|
66
|
+
end
|
67
|
+
|
68
|
+
%w[ example_started
|
69
|
+
start_dump dump_failure dump_summary dump_pending ].each do |meth|
|
70
|
+
module_eval "def #{meth}(*args); end"
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_example_group(example_group)
|
74
|
+
@example_group = example_group
|
75
|
+
end
|
76
|
+
|
77
|
+
def example_passed(example)
|
78
|
+
end
|
79
|
+
|
80
|
+
def example_pending(example, counter, failure)
|
81
|
+
end
|
82
|
+
|
83
|
+
def example_failed(example, counter, failure)
|
84
|
+
if example_group.respond_to?(:spec_path)
|
85
|
+
result.failed << example_group.spec_path.gsub(/:\d+$/, '')
|
86
|
+
else
|
87
|
+
path = path_from_bt(failure.exception.backtrace)
|
88
|
+
result.failed << path if path
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def start(example_count)
|
93
|
+
@result = TestResult.new
|
94
|
+
end
|
95
|
+
|
96
|
+
def path_from_bt(ary)
|
97
|
+
files = options.files
|
98
|
+
test = nil
|
99
|
+
ary.find do |bt|
|
100
|
+
bt = bt.split(':').first.strip
|
101
|
+
test = bt if files.include?(bt)
|
102
|
+
end
|
103
|
+
test
|
104
|
+
end
|
105
|
+
|
106
|
+
def close
|
107
|
+
files = options.files
|
108
|
+
result.succeeded = files - result.failed
|
109
|
+
|
110
|
+
FileUtils.mkdir_p(File.dirname(where))
|
111
|
+
File.open(where, 'w') { |f| f.puts YAML.dump(result) }
|
112
|
+
end
|
113
|
+
end # YamlFormatter
|
114
|
+
|
115
|
+
# A JtestR ResultHandler
|
116
|
+
# Using this handler we can use RSpec formatters, like html/ci_reporter with JtestR
|
117
|
+
# Created for YamlFormatter
|
118
|
+
class RSpecResultHandler
|
119
|
+
|
120
|
+
# Workaround for http://jira.codehaus.org/browse/JTESTR-68
|
121
|
+
module TestNGResultHandlerMixin
|
122
|
+
def onTestSuccess(test_result)
|
123
|
+
@result_handler.succeed_single(test_result.name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class BacktraceTweaker
|
128
|
+
attr_reader :ignore_patterns
|
129
|
+
def initialize
|
130
|
+
@ignore_patterns = ::Spec::Runner::QuietBacktraceTweaker::IGNORE_PATTERNS.dup
|
131
|
+
# ignore jruby/jtestr backtrace
|
132
|
+
ignore_patterns << /org\.jruby\.javasupport\.JavaMethod\./
|
133
|
+
ignore_patterns << /jtestr.*\.jar!/i << /runner\.rb/
|
134
|
+
end
|
135
|
+
|
136
|
+
def clean_up_double_slashes(line)
|
137
|
+
line.gsub!('//','/')
|
138
|
+
end
|
139
|
+
|
140
|
+
def tweak_backtrace(error)
|
141
|
+
return if error.backtrace.nil?
|
142
|
+
error.backtrace.collect! do |line|
|
143
|
+
clean_up_double_slashes(line)
|
144
|
+
ignore_patterns.each do |ignore|
|
145
|
+
if line =~ ignore
|
146
|
+
line = nil
|
147
|
+
break
|
148
|
+
end
|
149
|
+
end
|
150
|
+
line
|
151
|
+
end
|
152
|
+
error.backtrace.compact!
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class << self
|
157
|
+
# an rspec reporter used to proxy events to rspec formatters
|
158
|
+
attr_reader :reporter
|
159
|
+
|
160
|
+
def init(argv = [], out = STDOUT, err = STDERR)
|
161
|
+
::JtestR::TestNGResultHandler.module_eval { include TestNGResultHandlerMixin }
|
162
|
+
rspec_parser = ::Spec::Runner::OptionParser.new(err, out)
|
163
|
+
rspec_parser.order!(argv)
|
164
|
+
rspec_parser.options.backtrace_tweaker = BacktraceTweaker.new
|
165
|
+
@reporter = Spec::Runner::Reporter.new(rspec_parser.options)
|
166
|
+
end
|
167
|
+
|
168
|
+
def before
|
169
|
+
reporter.start(reporter.options.files.size)
|
170
|
+
end
|
171
|
+
|
172
|
+
def after
|
173
|
+
reporter.end
|
174
|
+
reporter.dump
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
module ExampleMethods
|
179
|
+
attr_accessor :name, :description, :__full_description
|
180
|
+
end
|
181
|
+
|
182
|
+
def reporter
|
183
|
+
self.class.reporter
|
184
|
+
end
|
185
|
+
|
186
|
+
attr_accessor :example_group, :current_example, :current_failure
|
187
|
+
|
188
|
+
def initialize(name, desc, *args)
|
189
|
+
self.example_group = ::Spec::Example::ExampleGroup.new(desc)
|
190
|
+
example_group.extend ExampleMethods
|
191
|
+
example_group.name = name.to_s
|
192
|
+
if example_group.name[/Spec/]
|
193
|
+
example_group.description = desc.to_s
|
194
|
+
else
|
195
|
+
example_group.description = name.to_s
|
196
|
+
end
|
197
|
+
reporter.add_example_group(example_group)
|
198
|
+
end
|
199
|
+
|
200
|
+
def starting
|
201
|
+
end
|
202
|
+
|
203
|
+
def ending
|
204
|
+
end
|
205
|
+
|
206
|
+
def add_fault(fault)
|
207
|
+
self.current_failure = fault
|
208
|
+
end
|
209
|
+
|
210
|
+
def add_pending(pending)
|
211
|
+
end
|
212
|
+
|
213
|
+
def starting_single(name = nil)
|
214
|
+
self.current_failure = nil
|
215
|
+
self.current_example = Object.new
|
216
|
+
current_example.extend ::Spec::Example::ExampleMethods
|
217
|
+
current_example.extend ExampleMethods
|
218
|
+
name = name.to_s
|
219
|
+
name[/\((pen?ding|error|failure|success)\)?$/]
|
220
|
+
name = $`
|
221
|
+
current_example.description = name
|
222
|
+
if example_group.name[/Spec/]
|
223
|
+
current_example.__full_description = "#{example_group.description} #{name}"
|
224
|
+
else
|
225
|
+
current_example.__full_description = "#{example_group.name}: #{name}"
|
226
|
+
end
|
227
|
+
reporter.example_started(current_example)
|
228
|
+
#puts "STARTED #{name} #{current_example.__full_description}"
|
229
|
+
end
|
230
|
+
|
231
|
+
def succeed_single(name = nil)
|
232
|
+
#puts "SUCC SINGLE #{name}"
|
233
|
+
reporter.example_finished(current_example, nil)
|
234
|
+
end
|
235
|
+
|
236
|
+
def fail_single(name = nil)
|
237
|
+
#puts "FAIL SINGLE #{name}"
|
238
|
+
reporter.example_finished(current_example, current_error)
|
239
|
+
end
|
240
|
+
|
241
|
+
def error_single(name = nil)
|
242
|
+
#puts "ERR SINGLE #{name}"
|
243
|
+
reporter.example_finished(current_example, current_error)
|
244
|
+
end
|
245
|
+
|
246
|
+
def pending_single(name = nil)
|
247
|
+
#puts "PEND SINGLE #{name}"
|
248
|
+
error = ::Spec::Example::ExamplePendingError.new(name)
|
249
|
+
reporter.example_finished(current_example, error)
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
def current_error(fault = current_failure)
|
254
|
+
case fault
|
255
|
+
when nil
|
256
|
+
nil
|
257
|
+
when Test::Unit::Failure
|
258
|
+
Error.new(fault.message, fault.location)
|
259
|
+
when Test::Unit::Error
|
260
|
+
if fault.exception.is_a?(NativeException)
|
261
|
+
exception = fault.exception.cause
|
262
|
+
bt = exception.stack_trace.to_a
|
263
|
+
else
|
264
|
+
exception = fault.exception
|
265
|
+
bt = exception.backtrace
|
266
|
+
end
|
267
|
+
Error.new(exception.message, bt)
|
268
|
+
when Expectations::Results::Error
|
269
|
+
fault.exception
|
270
|
+
when Spec::Runner::Reporter::Failure
|
271
|
+
ex = fault.exception
|
272
|
+
fault.example.instance_variable_get(:@_implementation).to_s =~ /@(.+:\d+)/
|
273
|
+
Error.new(ex.message, [$1.to_s] + ex.backtrace)
|
274
|
+
when Expectations::Results
|
275
|
+
file = fault.file
|
276
|
+
line = fault.line
|
277
|
+
Error.new(fault.message, ["#{fault.file}:#{fault.line}"])
|
278
|
+
else
|
279
|
+
if fault.respond_to?(:test_header)
|
280
|
+
fault.test_header[/\((.+)\)/]
|
281
|
+
test_cls, test_meth = $1.to_s, $`.to_s
|
282
|
+
exception = fault.exception
|
283
|
+
(class << exception; self; end).module_eval do
|
284
|
+
define_method(:backtrace) do
|
285
|
+
(["#{test_cls}:in `#{test_meth}'"] + stackTrace).map { |s| s.to_s }
|
286
|
+
end
|
287
|
+
end
|
288
|
+
exception
|
289
|
+
elsif fault.respond_to?(:method)
|
290
|
+
test_cls, test_meth = fault.method.test_class.name, fault.method.method_name
|
291
|
+
exception = fault.throwable
|
292
|
+
(class << exception; self; end).module_eval do
|
293
|
+
define_method(:backtrace) do
|
294
|
+
(["#{test_cls}:in `#{test_meth}'"] + stackTrace).map { |s| s.to_s }
|
295
|
+
end
|
296
|
+
end
|
297
|
+
exception
|
298
|
+
else
|
299
|
+
raise "Cannot handle fault #{fault.class}: #{fault.inspect}"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
end # RSpecResultHandler
|
305
|
+
|
306
|
+
end # TestResult
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,324 @@
|
|
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
|
+
#
|
50
|
+
def filter_classes(dependencies, criteria = {})
|
51
|
+
return [] unless task.compile.target
|
52
|
+
target = task.compile.target.to_s
|
53
|
+
candidates = Dir["#{target}/**/*.class"].
|
54
|
+
map { |file| Util.relative_path(file, target).ext('').gsub(File::SEPARATOR, '.') }.
|
55
|
+
reject { |name| name =~ /\$/ }
|
56
|
+
result = []
|
57
|
+
if criteria[:class_names]
|
58
|
+
result.concat candidates.select { |name| criteria[:class_names].flatten.any? { |pat| pat === name } }
|
59
|
+
end
|
60
|
+
begin
|
61
|
+
Java.load
|
62
|
+
filter = Java.org.apache.buildr.JavaTestFilter.new(dependencies.to_java(Java.java.lang.String))
|
63
|
+
if criteria[:interfaces]
|
64
|
+
filter.add_interfaces(criteria[:interfaces].to_java(Java.java.lang.String))
|
65
|
+
end
|
66
|
+
if criteria[:class_annotations]
|
67
|
+
filter.add_class_annotations(criteria[:class_annotations].to_java(Java.java.lang.String))
|
68
|
+
end
|
69
|
+
if criteria[:method_annotations]
|
70
|
+
filter.add_method_annotations(criteria[:method_annotations].to_java(Java.java.lang.String))
|
71
|
+
end
|
72
|
+
result.concat filter.filter(candidates.to_java(Java.java.lang.String)).map(&:to_s)
|
73
|
+
rescue =>ex
|
74
|
+
info "#{ex.class}: #{ex.message}"
|
75
|
+
raise
|
76
|
+
end
|
77
|
+
result.uniq
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# JMock is available when using JUnit and TestNG, JBehave.
|
84
|
+
module JMock
|
85
|
+
|
86
|
+
VERSION = '1.2.0'
|
87
|
+
|
88
|
+
class << self
|
89
|
+
def version
|
90
|
+
Buildr.settings.build['jmock'] || VERSION
|
91
|
+
end
|
92
|
+
|
93
|
+
def dependencies
|
94
|
+
@dependencies ||= ["jmock:jmock:jar:#{version}"]
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def const_missing(const)
|
99
|
+
return super unless const == :REQUIRES # TODO: remove in 1.5
|
100
|
+
Buildr.application.deprecated "Please use JMock.dependencies/.version instead of JMock::REQUIRES/VERSION"
|
101
|
+
dependencies
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# JUnit test framework, the default test framework for Java tests.
|
108
|
+
#
|
109
|
+
# Support the following options:
|
110
|
+
# * :fork -- If true/:once (default), fork for each test class. If :each, fork for each individual
|
111
|
+
# test case. If false, run all tests in the same VM (fast, but dangerous).
|
112
|
+
# * :clonevm -- If true clone the VM each time it is forked.
|
113
|
+
# * :properties -- Hash of system properties available to the test case.
|
114
|
+
# * :environment -- Hash of environment variables available to the test case.
|
115
|
+
# * :java_args -- Arguments passed as is to the JVM.
|
116
|
+
class JUnit < TestFramework::Java
|
117
|
+
|
118
|
+
# Used by the junit:report task. Access through JUnit#report if you want to set various
|
119
|
+
# options for that task, for example:
|
120
|
+
# JUnit.report.frames = false
|
121
|
+
class Report
|
122
|
+
|
123
|
+
# Parameters passed to the Ant JUnitReport task.
|
124
|
+
attr_reader :params
|
125
|
+
# True (default) to produce a report using frames, false to produce a single-page report.
|
126
|
+
attr_accessor :frames
|
127
|
+
# Directory for the report style (defaults to using the internal style).
|
128
|
+
attr_accessor :style_dir
|
129
|
+
# Target directory for generated report.
|
130
|
+
attr_accessor :target
|
131
|
+
|
132
|
+
def initialize
|
133
|
+
@params = {}
|
134
|
+
@frames = true
|
135
|
+
@target = 'reports/junit'
|
136
|
+
end
|
137
|
+
|
138
|
+
# :call-seq:
|
139
|
+
# generate(projects, target?)
|
140
|
+
#
|
141
|
+
# Generates a JUnit report for these projects (must run JUnit tests first) into the
|
142
|
+
# target directory. You can specify a target, or let it pick the default one from the
|
143
|
+
# target attribute.
|
144
|
+
def generate(projects, target = @target.to_s)
|
145
|
+
html_in = File.join(target, 'html')
|
146
|
+
rm_rf html_in ; mkpath html_in
|
147
|
+
|
148
|
+
Buildr.ant('junit-report') do |ant|
|
149
|
+
ant.taskdef :name=>'junitreport', :classname=>'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
|
150
|
+
:classpath=>Buildr.artifacts(JUnit.ant_taskdef).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
|
151
|
+
ant.junitreport :todir=>target do
|
152
|
+
projects.select { |project| project.test.framework == :junit }.
|
153
|
+
map { |project| project.test.report_to.to_s }.select { |path| File.exist?(path) }.
|
154
|
+
each { |path| ant.fileset(:dir=>path) { ant.include :name=>'TEST-*.xml' } }
|
155
|
+
options = { :format=>frames ? 'frames' : 'noframes' }
|
156
|
+
options[:styledir] = style_dir if style_dir
|
157
|
+
ant.report options.merge(:todir=>html_in) do
|
158
|
+
params.each { |key, value| ant.param :name=>key, :expression=>value }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
# JUnit version number.
|
167
|
+
VERSION = '4.4'
|
168
|
+
|
169
|
+
class << self
|
170
|
+
# :call-seq:
|
171
|
+
# report()
|
172
|
+
#
|
173
|
+
# Returns the Report object used by the junit:report task. You can use this object to set
|
174
|
+
# various options that affect your report, for example:
|
175
|
+
# JUnit.report.frames = false
|
176
|
+
# JUnit.report.params['title'] = 'My App'
|
177
|
+
def report
|
178
|
+
@report ||= Report.new
|
179
|
+
end
|
180
|
+
|
181
|
+
def version
|
182
|
+
Buildr.settings.build['junit'] || VERSION
|
183
|
+
end
|
184
|
+
|
185
|
+
def dependencies
|
186
|
+
@dependencies ||= ["junit:junit:jar:#{version}"]+ JMock.dependencies
|
187
|
+
end
|
188
|
+
|
189
|
+
def ant_taskdef #:nodoc:
|
190
|
+
"org.apache.ant:ant-junit:jar:#{Ant.version}"
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
def const_missing(const)
|
195
|
+
return super unless const == :REQUIRES # TODO: remove in 1.5
|
196
|
+
Buildr.application.deprecated "Please use JUnit.dependencies/.version instead of JUnit::REQUIRES/VERSION"
|
197
|
+
dependencies
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def tests(dependencies) #:nodoc:
|
202
|
+
filter_classes(dependencies,
|
203
|
+
:interfaces => %w{junit.framework.TestCase},
|
204
|
+
:class_annotations => %w{org.junit.runner.RunWith},
|
205
|
+
:method_annotations => %w{org.junit.Test})
|
206
|
+
end
|
207
|
+
|
208
|
+
def run(tests, dependencies) #:nodoc:
|
209
|
+
# Use Ant to execute the Junit tasks, gives us performance and reporting.
|
210
|
+
Buildr.ant('junit') do |ant|
|
211
|
+
case options[:fork]
|
212
|
+
when false
|
213
|
+
forking = {}
|
214
|
+
when :each
|
215
|
+
forking = { :fork=>true, :forkmode=>'perTest' }
|
216
|
+
when true, :once
|
217
|
+
forking = { :fork=>true, :forkmode=>'once' }
|
218
|
+
else
|
219
|
+
fail 'Option fork must be :once, :each or false.'
|
220
|
+
end
|
221
|
+
mkpath task.report_to.to_s
|
222
|
+
|
223
|
+
taskdef = Buildr.artifact(JUnit.ant_taskdef)
|
224
|
+
taskdef.invoke
|
225
|
+
ant.taskdef :name=>'junit', :classname=>'org.apache.tools.ant.taskdefs.optional.junit.JUnitTask', :classpath=>taskdef.to_s
|
226
|
+
|
227
|
+
ant.junit forking.merge(:clonevm=>options[:clonevm] || false, :dir=>task.send(:project).path_to) do
|
228
|
+
ant.classpath :path=>dependencies.join(File::PATH_SEPARATOR)
|
229
|
+
(options[:properties] || []).each { |key, value| ant.sysproperty :key=>key, :value=>value }
|
230
|
+
(options[:environment] || []).each { |key, value| ant.env :key=>key, :value=>value }
|
231
|
+
Array(options[:java_args]).each { |value| ant.jvmarg :value=>value }
|
232
|
+
ant.formatter :type=>'plain'
|
233
|
+
ant.formatter :type=>'plain', :usefile=>false # log test
|
234
|
+
ant.formatter :type=>'xml'
|
235
|
+
ant.batchtest :todir=>task.report_to.to_s, :failureproperty=>'failed' do
|
236
|
+
ant.fileset :dir=>task.compile.target.to_s do
|
237
|
+
tests.each { |test| ant.include :name=>File.join(*test.split('.')).ext('class') }
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
return tests unless ant.project.getProperty('failed')
|
242
|
+
end
|
243
|
+
# But Ant doesn't tell us what went kaput, so we'll have to parse the test files.
|
244
|
+
tests.inject([]) do |passed, test|
|
245
|
+
report_file = File.join(task.report_to.to_s, "TEST-#{test}.txt")
|
246
|
+
if File.exist?(report_file)
|
247
|
+
report = File.read(report_file)
|
248
|
+
# The second line (if exists) is the status line and we scan it for its values.
|
249
|
+
status = (report.split("\n")[1] || '').scan(/(run|failures|errors):\s*(\d+)/i).
|
250
|
+
inject(Hash.new(0)) { |hash, pair| hash[pair[0].downcase.to_sym] = pair[1].to_i ; hash }
|
251
|
+
passed << test if status[:failures] == 0 && status[:errors] == 0
|
252
|
+
end
|
253
|
+
passed
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
namespace 'junit' do
|
258
|
+
desc "Generate JUnit tests report in #{report.target}"
|
259
|
+
task('report') do |task|
|
260
|
+
report.generate Project.projects
|
261
|
+
info "Generated JUnit tests report in #{report.target}"
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
task('clean') { rm_rf report.target.to_s }
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
# TestNG test framework. To use in your project:
|
271
|
+
# test.using :testng
|
272
|
+
#
|
273
|
+
# Support the following options:
|
274
|
+
# * :properties -- Hash of properties passed to the test suite.
|
275
|
+
# * :java_args -- Arguments passed to the JVM.
|
276
|
+
class TestNG < TestFramework::Java
|
277
|
+
|
278
|
+
VERSION = '5.7'
|
279
|
+
|
280
|
+
class << self
|
281
|
+
def version
|
282
|
+
Buildr.settings.build['testng'] || VERSION
|
283
|
+
end
|
284
|
+
|
285
|
+
def dependencies
|
286
|
+
["org.testng:testng:jar:jdk15:#{version}"]+ JMock.dependencies
|
287
|
+
end
|
288
|
+
|
289
|
+
private
|
290
|
+
def const_missing(const)
|
291
|
+
return super unless const == :REQUIRES # TODO: remove in 1.5
|
292
|
+
Buildr.application.deprecated "Please use TestNG.dependencies/.version instead of TestNG::REQUIRES/VERSION"
|
293
|
+
dependencies
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def tests(dependencies) #:nodoc:
|
298
|
+
filter_classes(dependencies,
|
299
|
+
:class_annotations => %w{org.testng.annotations.Test},
|
300
|
+
:method_annotations => %w{org.testng.annotations.Test})
|
301
|
+
end
|
302
|
+
|
303
|
+
def run(tests, dependencies) #:nodoc:
|
304
|
+
cmd_args = [ 'org.testng.TestNG', '-sourcedir', task.compile.sources.join(';'), '-suitename', task.send(:project).name ]
|
305
|
+
cmd_args << '-d' << task.report_to.to_s
|
306
|
+
cmd_options = { :properties=>options[:properties], :java_args=>options[:java_args],
|
307
|
+
:classpath=>dependencies }
|
308
|
+
tests.inject([]) do |passed, test|
|
309
|
+
begin
|
310
|
+
Java::Commands.java cmd_args, '-testclass', test, cmd_options.merge(:name=>test)
|
311
|
+
passed << test
|
312
|
+
rescue
|
313
|
+
passed
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
end # Buildr
|
321
|
+
|
322
|
+
|
323
|
+
Buildr::TestFramework << Buildr::JUnit
|
324
|
+
Buildr::TestFramework << Buildr::TestNG
|