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.
Files changed (124) hide show
  1. data/CHANGELOG +66 -4
  2. data/{README → README.rdoc} +29 -16
  3. data/Rakefile +16 -20
  4. data/_buildr +38 -0
  5. data/addon/buildr/cobertura.rb +49 -45
  6. data/addon/buildr/emma.rb +238 -0
  7. data/addon/buildr/jetty.rb +1 -1
  8. data/addon/buildr/nailgun.rb +585 -661
  9. data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail$Main.class +0 -0
  10. data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail.class +0 -0
  11. data/{lib/buildr/java → addon/buildr}/org/apache/buildr/BuildrNail.java +0 -0
  12. data/bin/buildr +9 -2
  13. data/buildr.buildfile +53 -0
  14. data/buildr.gemspec +21 -14
  15. data/doc/css/default.css +51 -48
  16. data/doc/css/print.css +60 -55
  17. data/doc/images/favicon.png +0 -0
  18. data/doc/images/growl-icon.tiff +0 -0
  19. data/doc/images/project-structure.png +0 -0
  20. data/doc/pages/artifacts.textile +46 -156
  21. data/doc/pages/building.textile +63 -323
  22. data/doc/pages/contributing.textile +112 -102
  23. data/doc/pages/download.textile +19 -27
  24. data/doc/pages/extending.textile +27 -81
  25. data/doc/pages/getting_started.textile +44 -119
  26. data/doc/pages/index.textile +26 -47
  27. data/doc/pages/languages.textile +407 -0
  28. data/doc/pages/more_stuff.textile +92 -173
  29. data/doc/pages/packaging.textile +71 -239
  30. data/doc/pages/projects.textile +58 -233
  31. data/doc/pages/recipes.textile +19 -43
  32. data/doc/pages/settings_profiles.textile +39 -104
  33. data/doc/pages/testing.textile +41 -304
  34. data/doc/pages/troubleshooting.textile +29 -47
  35. data/doc/pages/whats_new.textile +69 -167
  36. data/doc/print.haml +0 -1
  37. data/doc/print.toc.yaml +1 -0
  38. data/doc/scripts/buildr-git.rb +1 -1
  39. data/doc/site.haml +1 -0
  40. data/doc/site.toc.yaml +8 -5
  41. data/{KEYS → etc/KEYS} +0 -0
  42. data/etc/git-svn-authors +16 -0
  43. data/lib/buildr.rb +2 -5
  44. data/lib/buildr/core/application.rb +192 -98
  45. data/lib/buildr/core/build.rb +140 -91
  46. data/lib/buildr/core/checks.rb +5 -5
  47. data/lib/buildr/core/common.rb +1 -1
  48. data/lib/buildr/core/compile.rb +12 -10
  49. data/lib/buildr/core/filter.rb +151 -46
  50. data/lib/buildr/core/generate.rb +9 -9
  51. data/lib/buildr/core/progressbar.rb +1 -1
  52. data/lib/buildr/core/project.rb +8 -7
  53. data/lib/buildr/core/test.rb +51 -26
  54. data/lib/buildr/core/transports.rb +22 -38
  55. data/lib/buildr/core/util.rb +78 -26
  56. data/lib/buildr/groovy.rb +18 -0
  57. data/lib/buildr/groovy/bdd.rb +105 -0
  58. data/lib/buildr/groovy/compiler.rb +138 -0
  59. data/lib/buildr/ide/eclipse.rb +102 -71
  60. data/lib/buildr/ide/idea.rb +7 -12
  61. data/lib/buildr/ide/idea7x.rb +7 -8
  62. data/lib/buildr/java.rb +4 -7
  63. data/lib/buildr/java/ant.rb +26 -5
  64. data/lib/buildr/java/bdd.rb +449 -0
  65. data/lib/buildr/java/commands.rb +9 -9
  66. data/lib/buildr/java/{compilers.rb → compiler.rb} +8 -90
  67. data/lib/buildr/java/jruby.rb +29 -11
  68. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  69. data/lib/buildr/java/packaging.rb +23 -16
  70. data/lib/buildr/java/pom.rb +1 -1
  71. data/lib/buildr/java/rjb.rb +21 -8
  72. data/lib/buildr/java/test_result.rb +308 -0
  73. data/lib/buildr/java/tests.rb +324 -0
  74. data/lib/buildr/packaging/artifact.rb +12 -11
  75. data/lib/buildr/packaging/artifact_namespace.rb +7 -4
  76. data/lib/buildr/packaging/gems.rb +3 -3
  77. data/lib/buildr/packaging/zip.rb +13 -10
  78. data/lib/buildr/resources/buildr.icns +0 -0
  79. data/lib/buildr/scala.rb +19 -0
  80. data/lib/buildr/scala/compiler.rb +109 -0
  81. data/lib/buildr/scala/tests.rb +203 -0
  82. data/rakelib/apache.rake +71 -45
  83. data/rakelib/doc.rake +2 -2
  84. data/rakelib/package.rake +3 -2
  85. data/rakelib/rspec.rake +23 -21
  86. data/rakelib/setup.rake +34 -9
  87. data/rakelib/stage.rake +4 -1
  88. data/spec/addon/cobertura_spec.rb +77 -0
  89. data/spec/addon/emma_spec.rb +120 -0
  90. data/spec/addon/test_coverage_spec.rb +255 -0
  91. data/spec/{application_spec.rb → core/application_spec.rb} +82 -4
  92. data/spec/{artifact_namespace_spec.rb → core/artifact_namespace_spec.rb} +12 -1
  93. data/spec/core/build_spec.rb +415 -0
  94. data/spec/{checks_spec.rb → core/checks_spec.rb} +2 -2
  95. data/spec/{common_spec.rb → core/common_spec.rb} +119 -30
  96. data/spec/{compile_spec.rb → core/compile_spec.rb} +17 -13
  97. data/spec/core/generate_spec.rb +33 -0
  98. data/spec/{project_spec.rb → core/project_spec.rb} +9 -6
  99. data/spec/{test_spec.rb → core/test_spec.rb} +222 -28
  100. data/spec/{transport_spec.rb → core/transport_spec.rb} +5 -9
  101. data/spec/groovy/bdd_spec.rb +80 -0
  102. data/spec/{groovy_compilers_spec.rb → groovy/compiler_spec.rb} +1 -1
  103. data/spec/ide/eclipse_spec.rb +243 -0
  104. data/spec/{java_spec.rb → java/ant.rb} +7 -17
  105. data/spec/java/bdd_spec.rb +358 -0
  106. data/spec/{java_compilers_spec.rb → java/compiler_spec.rb} +1 -1
  107. data/spec/java/java_spec.rb +88 -0
  108. data/spec/{java_packaging_spec.rb → java/packaging_spec.rb} +65 -4
  109. data/spec/{java_test_frameworks_spec.rb → java/tests_spec.rb} +31 -10
  110. data/spec/{archive_spec.rb → packaging/archive_spec.rb} +12 -2
  111. data/spec/{artifact_spec.rb → packaging/artifact_spec.rb} +12 -5
  112. data/spec/{packaging_helper.rb → packaging/packaging_helper.rb} +0 -0
  113. data/spec/{packaging_spec.rb → packaging/packaging_spec.rb} +1 -1
  114. data/spec/sandbox.rb +22 -5
  115. data/spec/{scala_compilers_spec.rb → scala/compiler_spec.rb} +1 -1
  116. data/spec/{scala_test_frameworks_spec.rb → scala/tests_spec.rb} +11 -12
  117. data/spec/spec_helpers.rb +38 -17
  118. metadata +93 -70
  119. data/lib/buildr/java/bdd_frameworks.rb +0 -265
  120. data/lib/buildr/java/groovyc.rb +0 -137
  121. data/lib/buildr/java/test_frameworks.rb +0 -450
  122. data/spec/build_spec.rb +0 -193
  123. data/spec/java_bdd_frameworks_spec.rb +0 -238
  124. data/spec/spec.opts +0 -6
@@ -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
- unless RUBY_PLATFORM =~ /darwin/i
94
- home = ENV['JAVA_HOME'] or fail 'Are we forgetting something? JAVA_HOME not set.'
95
- tools = File.expand_path('lib/tools.jar', home)
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