buildr 1.2.10 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/CHANGELOG +566 -268
  2. data/DISCLAIMER +7 -1
  3. data/KEYS +151 -0
  4. data/NOTICE +23 -8
  5. data/README +122 -22
  6. data/Rakefile +49 -229
  7. data/{lib → addon}/buildr/antlr.rb +23 -10
  8. data/addon/buildr/cobertura.rb +232 -0
  9. data/{lib → addon}/buildr/hibernate.rb +20 -4
  10. data/{lib → addon}/buildr/javacc.rb +27 -12
  11. data/addon/buildr/jdepend.rb +60 -0
  12. data/{lib → addon}/buildr/jetty.rb +34 -18
  13. data/addon/buildr/nailgun.rb +892 -0
  14. data/{lib → addon}/buildr/openjpa.rb +23 -6
  15. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  16. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  17. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  18. data/{lib/buildr/jetty → addon/buildr/org/apache/buildr}/JettyWrapper.java +19 -0
  19. data/{lib → addon}/buildr/xmlbeans.rb +39 -14
  20. data/bin/buildr +21 -7
  21. data/buildr.gemspec +50 -0
  22. data/doc/css/default.css +225 -0
  23. data/doc/css/print.css +95 -0
  24. data/doc/css/syntax.css +43 -0
  25. data/doc/images/apache-incubator-logo.png +0 -0
  26. data/doc/images/buildr-hires.png +0 -0
  27. data/doc/images/buildr.png +0 -0
  28. data/doc/images/note.png +0 -0
  29. data/doc/images/tip.png +0 -0
  30. data/doc/images/zbuildr.tif +0 -0
  31. data/doc/pages/artifacts.textile +317 -0
  32. data/doc/pages/building.textile +501 -0
  33. data/doc/pages/contributing.textile +178 -0
  34. data/doc/pages/download.textile +25 -0
  35. data/doc/pages/extending.textile +229 -0
  36. data/doc/pages/getting_started.textile +337 -0
  37. data/doc/pages/index.textile +63 -0
  38. data/doc/pages/mailing_lists.textile +17 -0
  39. data/doc/pages/more_stuff.textile +367 -0
  40. data/doc/pages/packaging.textile +592 -0
  41. data/doc/pages/projects.textile +449 -0
  42. data/doc/pages/recipes.textile +127 -0
  43. data/doc/pages/settings_profiles.textile +339 -0
  44. data/doc/pages/testing.textile +475 -0
  45. data/doc/pages/troubleshooting.textile +121 -0
  46. data/doc/pages/whats_new.textile +389 -0
  47. data/doc/print.haml +52 -0
  48. data/doc/print.toc.yaml +28 -0
  49. data/doc/scripts/buildr-git.rb +411 -0
  50. data/doc/scripts/install-jruby.sh +44 -0
  51. data/doc/scripts/install-linux.sh +64 -0
  52. data/doc/scripts/install-osx.sh +52 -0
  53. data/doc/site.haml +55 -0
  54. data/doc/site.toc.yaml +44 -0
  55. data/lib/buildr.rb +28 -45
  56. data/lib/buildr/core.rb +27 -0
  57. data/lib/buildr/core/application.rb +373 -0
  58. data/lib/buildr/core/application_cli.rb +134 -0
  59. data/lib/{core → buildr/core}/build.rb +91 -77
  60. data/lib/{core → buildr/core}/checks.rb +116 -95
  61. data/lib/buildr/core/common.rb +155 -0
  62. data/lib/buildr/core/compile.rb +594 -0
  63. data/lib/buildr/core/environment.rb +120 -0
  64. data/lib/buildr/core/filter.rb +258 -0
  65. data/lib/{core → buildr/core}/generate.rb +22 -5
  66. data/lib/buildr/core/help.rb +118 -0
  67. data/lib/buildr/core/progressbar.rb +156 -0
  68. data/lib/{core → buildr/core}/project.rb +468 -213
  69. data/lib/buildr/core/test.rb +690 -0
  70. data/lib/{core → buildr/core}/transports.rb +107 -127
  71. data/lib/buildr/core/util.rb +235 -0
  72. data/lib/buildr/ide.rb +19 -0
  73. data/lib/{java → buildr/ide}/eclipse.rb +86 -60
  74. data/lib/{java → buildr/ide}/idea.ipr.template +16 -0
  75. data/lib/buildr/ide/idea.rb +194 -0
  76. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  77. data/lib/buildr/ide/idea7x.rb +210 -0
  78. data/lib/buildr/java.rb +26 -0
  79. data/lib/buildr/java/ant.rb +71 -0
  80. data/lib/buildr/java/bdd_frameworks.rb +267 -0
  81. data/lib/buildr/java/commands.rb +210 -0
  82. data/lib/buildr/java/compilers.rb +432 -0
  83. data/lib/buildr/java/deprecated.rb +141 -0
  84. data/lib/buildr/java/groovyc.rb +137 -0
  85. data/lib/buildr/java/jruby.rb +99 -0
  86. data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
  87. data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
  88. data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
  89. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  90. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
  91. data/lib/buildr/java/packaging.rb +706 -0
  92. data/lib/{java → buildr/java}/pom.rb +20 -4
  93. data/lib/buildr/java/rjb.rb +142 -0
  94. data/lib/buildr/java/test_frameworks.rb +290 -0
  95. data/lib/buildr/java/version_requirement.rb +172 -0
  96. data/lib/buildr/packaging.rb +21 -0
  97. data/lib/{java → buildr/packaging}/artifact.rb +170 -179
  98. data/lib/buildr/packaging/artifact_namespace.rb +957 -0
  99. data/lib/buildr/packaging/artifact_search.rb +140 -0
  100. data/lib/buildr/packaging/gems.rb +102 -0
  101. data/lib/buildr/packaging/package.rb +233 -0
  102. data/lib/{tasks → buildr/packaging}/tar.rb +18 -1
  103. data/lib/{tasks → buildr/packaging}/zip.rb +153 -105
  104. data/rakelib/apache.rake +126 -0
  105. data/rakelib/changelog.rake +56 -0
  106. data/rakelib/doc.rake +103 -0
  107. data/rakelib/package.rake +44 -0
  108. data/rakelib/release.rake +53 -0
  109. data/rakelib/rspec.rake +81 -0
  110. data/rakelib/rubyforge.rake +45 -0
  111. data/rakelib/scm.rake +49 -0
  112. data/rakelib/setup.rake +59 -0
  113. data/rakelib/stage.rake +45 -0
  114. data/spec/application_spec.rb +316 -0
  115. data/spec/archive_spec.rb +494 -0
  116. data/spec/artifact_namespace_spec.rb +635 -0
  117. data/spec/artifact_spec.rb +738 -0
  118. data/spec/build_spec.rb +193 -0
  119. data/spec/checks_spec.rb +537 -0
  120. data/spec/common_spec.rb +579 -0
  121. data/spec/compile_spec.rb +561 -0
  122. data/spec/groovy_compilers_spec.rb +239 -0
  123. data/spec/java_bdd_frameworks_spec.rb +238 -0
  124. data/spec/java_compilers_spec.rb +446 -0
  125. data/spec/java_packaging_spec.rb +1042 -0
  126. data/spec/java_test_frameworks_spec.rb +414 -0
  127. data/spec/packaging_helper.rb +63 -0
  128. data/spec/packaging_spec.rb +589 -0
  129. data/spec/project_spec.rb +739 -0
  130. data/spec/sandbox.rb +116 -0
  131. data/spec/scala_compilers_spec.rb +239 -0
  132. data/spec/spec.opts +6 -0
  133. data/spec/spec_helpers.rb +283 -0
  134. data/spec/test_spec.rb +871 -0
  135. data/spec/transport_spec.rb +300 -0
  136. data/spec/version_requirement_spec.rb +115 -0
  137. metadata +188 -77
  138. data/lib/buildr/cobertura.rb +0 -89
  139. data/lib/buildr/jdepend.rb +0 -40
  140. data/lib/buildr/jetty/JettyWrapper$1.class +0 -0
  141. data/lib/buildr/jetty/JettyWrapper$BuildrHandler.class +0 -0
  142. data/lib/buildr/jetty/JettyWrapper.class +0 -0
  143. data/lib/buildr/scala.rb +0 -368
  144. data/lib/core/application.rb +0 -188
  145. data/lib/core/common.rb +0 -562
  146. data/lib/core/help.rb +0 -72
  147. data/lib/core/rake_ext.rb +0 -81
  148. data/lib/java/ant.rb +0 -71
  149. data/lib/java/compile.rb +0 -589
  150. data/lib/java/idea.rb +0 -159
  151. data/lib/java/java.rb +0 -432
  152. data/lib/java/packaging.rb +0 -581
  153. data/lib/java/test.rb +0 -795
  154. data/lib/tasks/concat.rb +0 -35
@@ -0,0 +1,690 @@
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/project'
18
+ require 'buildr/core/build'
19
+ require 'buildr/core/compile'
20
+
21
+
22
+ module Buildr
23
+
24
+ # The underlying test framework used by TestTask.
25
+ # To add a new test framework, extend TestFramework::Base and add your framework using:
26
+ # Buildr::TestFramework << MyFramework
27
+ class TestFramework
28
+
29
+ class << self
30
+
31
+ # Returns true if the specified test framework exists.
32
+ def has?(name)
33
+ frameworks.any? { |framework| framework.to_sym == name.to_sym }
34
+ end
35
+
36
+ # Select a test framework by its name.
37
+ def select(name)
38
+ frameworks.detect { |framework| framework.to_sym == name.to_sym }
39
+ end
40
+
41
+ # Identify which test framework applies for this project.
42
+ def select_from(project)
43
+ # Look for a suitable test framework based on the compiled language,
44
+ # which may return multiple candidates, e.g. JUnit and TestNG for Java.
45
+ # Pick the one used in the parent project, if not, whichever comes first.
46
+ candidates = frameworks.select { |framework| framework.applies_to?(project) }
47
+ parent = project.parent
48
+ parent && candidates.detect { |framework| framework.to_sym == parent.test.framework } || candidates.first
49
+ end
50
+
51
+ # Adds a test framework to the list of supported frameworks.
52
+ #
53
+ # For example:
54
+ # Buildr::TestFramework << Buildr::JUnit
55
+ def add(framework)
56
+ @frameworks ||= []
57
+ @frameworks |= [framework]
58
+ end
59
+ alias :<< :add
60
+
61
+ # Returns a list of available test frameworks.
62
+ def frameworks
63
+ @frameworks ||= []
64
+ end
65
+
66
+ end
67
+
68
+ # Base class for all test frameworks, with common functionality. Extend and over-ride as you see fit
69
+ # (see JUnit as an example).
70
+ class Base
71
+
72
+ class << self
73
+
74
+ # The framework's identifier (e.g. :junit). Inferred from the class name.
75
+ def to_sym
76
+ @symbol ||= name.split('::').last.downcase.to_sym
77
+ end
78
+
79
+ # Returns true if this framework applies to the current project. For example, JUnit returns
80
+ # true if the tests are written in Java.
81
+ def applies_to?(project)
82
+ raise 'Not implemented'
83
+ end
84
+
85
+ # Returns a list of dependencies for this framework. Defaults to obtaining a list of
86
+ # artifact specifications from the REQUIRES constant.
87
+ def dependencies
88
+ @dependencies ||= FileList[*(const_get('REQUIRES') rescue [])]
89
+ end
90
+
91
+ end
92
+
93
+ # Construct a new test framework with the specified options. Note that options may
94
+ # change before the framework is run.
95
+ def initialize(test_task, options)
96
+ @options = options
97
+ @task = test_task
98
+ end
99
+
100
+ # Options for this test framework.
101
+ attr_reader :options
102
+ # The test task we belong to
103
+ attr_reader :task
104
+
105
+ # Returns a list of dependenices for this framework. Defaults to calling the #dependencies
106
+ # method on the class.
107
+ def dependencies
108
+ self.class.dependencies
109
+ end
110
+
111
+ # TestTask calls this method to return a list of test names that can be run in this project.
112
+ # It then applies the include/exclude patterns to arrive at the list of tests that will be
113
+ # run, and call the #run method with that list.
114
+ #
115
+ # This method should return a list suitable for using with the #run method, but also suitable
116
+ # for the user to manage. For example, JUnit locates all the tests in the test.compile.target
117
+ # directory, and returns the class names, which are easier to work with than file names.
118
+ def tests(dependencies)
119
+ raise 'Not implemented'
120
+ end
121
+
122
+ # TestTask calls this method to run the named (and only those) tests. This method returns
123
+ # the list of tests that ran successfully.
124
+ def run(tests, dependencies)
125
+ raise 'Not implemented'
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
132
+
133
+ # The test task controls the entire test lifecycle.
134
+ #
135
+ # You can use the test task in three ways. You can access and configure specific test tasks,
136
+ # e.g. enhance the #compile task, or run code during #setup/#teardown.
137
+ #
138
+ # You can use convenient methods that handle the most common settings. For example,
139
+ # add dependencies using #with, or include only specific tests using #include.
140
+ #
141
+ # You can also enhance this task directly. This task will first execute the #compile task, followed
142
+ # by the #setup task, run the unit tests, any other enhancements, and end by executing #teardown.
143
+ #
144
+ # The test framework is determined based on the available test files, for example, if the test
145
+ # cases are written in Java, then JUnit is selected as the test framework. You can also select
146
+ # a specific test framework, for example, to use TestNG instead of JUnit:
147
+ # test.using :testng
148
+ class TestTask < Rake::Task
149
+
150
+ class << self
151
+
152
+ # Used by the local test and integration tasks to
153
+ # a) Find the local project(s),
154
+ # b) Find all its sub-projects and narrow down to those that have either unit or integration tests,
155
+ # c) Run all the (either unit or integration) tests, and
156
+ # d) Ignore failure if necessary.
157
+ def run_local_tests(integration) #:nodoc:
158
+ Project.local_projects do |project|
159
+ # !(foo ^ bar) tests for equality and accepts nil as false (and select is less obfuscated than reject on ^).
160
+ projects = ([project] + project.projects).select { |project| !(project.test.options[:integration] ^ integration) }
161
+ projects.each do |project|
162
+ puts "Testing #{project.name}" if verbose
163
+ begin
164
+ project.test.invoke
165
+ rescue
166
+ raise unless Buildr.options.test == :all
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ # Used by the test/integration rule to only run tests that match the specified names.
173
+ def only_run(tests) #:nodoc:
174
+ tests = tests.map { |name| name =~ /\*/ ? name : "*#{name}*" }
175
+ # Since the tests may reside in a sub-project, we need to set the include/exclude pattern on
176
+ # all sub-projects, but only invoke test on the local project.
177
+ Project.projects.each { |project| project.test.send :only_run, tests }
178
+ end
179
+ end
180
+
181
+ # Default options already set on each test task.
182
+ DEFAULT_OPTIONS = { :fail_on_failure=>true, :fork=>:once, :properties=>{}, :environment=>{} }
183
+
184
+ def initialize(*args) #:nodoc:
185
+ super
186
+ @dependencies = FileList[]
187
+ @include = []
188
+ @exclude = []
189
+ parent_task = Project.parent_task(name)
190
+ if parent_task.respond_to?(:options)
191
+ @options = OpenObject.new { |hash, key| parent_task.options[key] }
192
+ else
193
+ @options = OpenObject.new(DEFAULT_OPTIONS)
194
+ end
195
+ enhance do
196
+ run_tests if framework
197
+ end
198
+ end
199
+
200
+ # The dependencies used for running the tests. Includes the compiled files (compile.target)
201
+ # and their dependencies. Will also include anything you pass to #with, shared between the
202
+ # testing compile and run dependencies.
203
+ attr_reader :dependencies
204
+
205
+ # *Deprecated*: Use dependencies instead.
206
+ def classpath
207
+ Buildr.application.deprecated 'Use dependencies instead.'
208
+ dependencies
209
+ end
210
+
211
+ # *Deprecated*: Use dependencies= instead.
212
+ def classpath=(artifacts)
213
+ Buildr.application.deprecated 'Use dependencies= instead.'
214
+ self.dependencies = artifacts
215
+ end
216
+
217
+ def execute(args) #:nodoc:
218
+ setup.invoke
219
+ begin
220
+ super
221
+ rescue RuntimeError
222
+ raise if options[:fail_on_failure]
223
+ ensure
224
+ teardown.invoke
225
+ end
226
+ end
227
+
228
+ # :call-seq:
229
+ # compile(*sources) => CompileTask
230
+ # compile(*sources) { |task| .. } => CompileTask
231
+ #
232
+ # The compile task is similar to the Project's compile task. However, it compiles all
233
+ # files found in the src/test/{source} directory into the target/test/{code} directory.
234
+ # This task is executed by the test task before running any tests.
235
+ #
236
+ # Once the project definition is complete, all dependencies from the regular
237
+ # compile task are copied over, so you only need to specify dependencies
238
+ # specific to your tests. You can do so by calling #with on the test task.
239
+ # The dependencies used here are also copied over to the junit task.
240
+ def compile(*sources, &block)
241
+ @project.task('test:compile').from(sources).enhance &block
242
+ end
243
+
244
+ # :call-seq:
245
+ # resources(*prereqs) => ResourcesTask
246
+ # resources(*prereqs) { |task| .. } => ResourcesTask
247
+ #
248
+ # Executes by the #compile task to copy resource files over. See Project#resources.
249
+ def resources(*prereqs, &block)
250
+ @project.task('test:resources').enhance prereqs, &block
251
+ end
252
+
253
+ # :call-seq:
254
+ # setup(*prereqs) => task
255
+ # setup(*prereqs) { |task| .. } => task
256
+ #
257
+ # Returns the setup task. The setup task is executed at the beginning of the test task,
258
+ # after compiling the test files.
259
+ def setup(*prereqs, &block)
260
+ @project.task('test:setup').enhance prereqs, &block
261
+ end
262
+
263
+ # :call-seq:
264
+ # teardown(*prereqs) => task
265
+ # teardown(*prereqs) { |task| .. } => task
266
+ #
267
+ # Returns the teardown task. The teardown task is executed at the end of the test task.
268
+ def teardown(*prereqs, &block)
269
+ @project.task('test:teardown').enhance prereqs, &block
270
+ end
271
+
272
+ # :call-seq:
273
+ # with(*specs) => self
274
+ #
275
+ # Specify artifacts (specs, tasks, files, etc) to include in the depdenenciest list
276
+ # when compiling and running tests.
277
+ def with(*artifacts)
278
+ @dependencies |= Buildr.artifacts(artifacts.flatten).uniq
279
+ compile.with artifacts
280
+ self
281
+ end
282
+
283
+ # Returns various test options.
284
+ attr_reader :options
285
+
286
+ # :call-seq:
287
+ # using(options) => self
288
+ #
289
+ # Sets various test options from a hash and returns self. For example:
290
+ # test.using :fork=>:each, :properties=>{ 'url'=>'http://localhost:8080' }
291
+ #
292
+ # Can also be used to select the test framework, or to run these tests as
293
+ # integration tests. For example:
294
+ # test.using :testng
295
+ # test.using :integration
296
+ #
297
+ # The :fail_on_failure option specifies whether the task should fail if
298
+ # any of the tests fail (default), or should report the failures but continue
299
+ # running the build (when set to false).
300
+ #
301
+ # All other options depend on the capability of the test framework. These options
302
+ # should be used the same way across all frameworks that support them:
303
+ # * :fork -- Fork once for each project (:once, default), for each test in each
304
+ # project (:each), or don't fork at all (false).
305
+ # * :properties -- Properties pass to the test, e.g. in Java as system properties.
306
+ # * :environment -- Environment variables. This hash is made available in the
307
+ # form of environment variables.
308
+ def using(*args)
309
+ args.pop.each { |key, value| options[key.to_sym] = value } if Hash === args.last
310
+ args.each do |name|
311
+ if TestFramework.has?(name)
312
+ self.framework = name
313
+ elsif name == :integration
314
+ options[:integration] = true
315
+ else
316
+ Buildr.application.deprecated "Please replace with using(:#{name}=>true)"
317
+ options[name.to_sym] = true
318
+ end
319
+ end
320
+ self
321
+ end
322
+
323
+ # :call-seq:
324
+ # include(*names) => self
325
+ #
326
+ # Include only the specified tests. Unless specified, the default is to include
327
+ # all tests identified by the test framework. This method accepts multiple arguments
328
+ # and returns self.
329
+ #
330
+ # Tests are specified by their full name, but you can use glob patterns to select
331
+ # multiple tests, for example:
332
+ # test.include 'com.example.FirstTest' # FirstTest only
333
+ # test.include 'com.example.*' # All tests under com/example
334
+ # test.include 'com.example.Module*' # All tests starting with Module
335
+ # test.include '*.{First,Second}Test' # FirstTest, SecondTest
336
+ def include(*names)
337
+ @include += names
338
+ self
339
+ end
340
+
341
+ # :call-seq:
342
+ # exclude(*names) => self
343
+ #
344
+ # Exclude the specified tests. This method accepts multiple arguments and returns self.
345
+ # See #include for the type of arguments you can use.
346
+ def exclude(*names)
347
+ @exclude += names
348
+ self
349
+ end
350
+
351
+ # *Deprecated*: Use tests instead.
352
+ def classes
353
+ Buildr.application.deprecated 'Call tests instead of classes'
354
+ tests
355
+ end
356
+
357
+ # After running the task, returns all tests selected to run, based on availability and include/exclude pattern.
358
+ attr_reader :tests
359
+ # After running the task, returns all the tests that failed, empty array if all tests passed.
360
+ attr_reader :failed_tests
361
+ # After running the task, returns all the tests that passed, empty array if no tests passed.
362
+ attr_reader :passed_tests
363
+
364
+ # :call-seq:
365
+ # framework => symbol
366
+ #
367
+ # Returns the test framework, e.g. :junit, :testng.
368
+ def framework
369
+ unless @framework
370
+ # Start with all frameworks that apply (e.g. JUnit and TestNG for Java),
371
+ # and pick the first (default) one, unless already specified in parent project.
372
+ candidates = TestFramework.frameworks.select { |cls| cls.applies_to?(@project) }
373
+ candidate = @project.parent && candidates.detect { |framework| framework.to_sym == @project.parent.test.framework } ||
374
+ candidates.first
375
+ self.framework = candidate if candidate
376
+ end
377
+ @framework && @framework.class.to_sym
378
+ end
379
+
380
+ # :call-seq:
381
+ # report_to => file
382
+ #
383
+ # Test frameworks that can produce reports, will write them to this directory.
384
+ #
385
+ # This is framework dependent, so unless you use the default test framework, call this method
386
+ # after setting the test framework.
387
+ def report_to
388
+ @report_to ||= file(@project.path_to(:reports, framework)=>self)
389
+ end
390
+
391
+ # The project this task belongs to.
392
+ attr_reader :project
393
+
394
+ protected
395
+
396
+ def associate_with(project)
397
+ @project = project
398
+ end
399
+
400
+ def framework=(name)
401
+ cls = TestFramework.select(name) or raise ArgumentError, "No #{name} test framework available. Did you install it?"
402
+ #cls.inherit_options.reject { |name| options.has_key?(name) }.
403
+ # each { |name| options[name] = @parent_task.options[name] } if @parent_task.respond_to?(:options)
404
+ @framework = cls.new(self, options)
405
+ # Test framework dependency.
406
+ with @framework.dependencies
407
+ end
408
+
409
+ # :call-seq:
410
+ # include?(name) => boolean
411
+ #
412
+ # Returns true if the specified test name matches the inclusion/exclusion pattern. Used to determine
413
+ # which tests to execute.
414
+ def include?(name)
415
+ (@include.empty? || @include.any? { |pattern| File.fnmatch(pattern, name) }) &&
416
+ !@exclude.any? { |pattern| File.fnmatch(pattern, name) }
417
+ end
418
+
419
+ # Runs the tests using the selected test framework.
420
+ def run_tests
421
+ dependencies = Buildr.artifacts(self.dependencies).map(&:to_s).uniq
422
+ rm_rf report_to.to_s
423
+ @tests = @framework.tests(dependencies).select { |test| include?(test) }.sort
424
+ if @tests.empty?
425
+ @passed_tests, @failed_tests = [], []
426
+ else
427
+ puts "Running tests in #{@project.name}" if verbose
428
+ @passed_tests = @framework.run(@tests, dependencies)
429
+ @failed_tests = @tests - @passed_tests
430
+ unless @failed_tests.empty?
431
+ warn "The following tests failed:\n#{@failed_tests.join("\n")}" if verbose
432
+ fail 'Tests failed!'
433
+ end
434
+ end
435
+ end
436
+
437
+ # Limit running tests to specific list.
438
+ def only_run(tests)
439
+ @include = Array(tests)
440
+ @exclude.clear
441
+ end
442
+
443
+ def invoke_prerequisites(args, chain) #:nodoc:
444
+ @prerequisites |= FileList[@dependencies.uniq]
445
+ super
446
+ end
447
+
448
+ end
449
+
450
+
451
+ # The integration tests task. Buildr has one such task (see Buildr#integration) that runs
452
+ # all tests marked with :integration=>true, and has a setup/teardown tasks separate from
453
+ # the unit tests.
454
+ class IntegrationTestsTask < Rake::Task
455
+
456
+ def initialize(*args) #:nodoc:
457
+ super
458
+ @setup = task("#{name}:setup")
459
+ @teardown = task("#{name}:teardown")
460
+ enhance do
461
+ puts 'Running integration tests...' if verbose
462
+ TestTask.run_local_tests true
463
+ end
464
+ end
465
+
466
+ def execute(args) #:nodoc:
467
+ setup.invoke
468
+ begin
469
+ super
470
+ ensure
471
+ teardown.invoke
472
+ end
473
+ end
474
+
475
+ # :call-seq:
476
+ # setup(*prereqs) => task
477
+ # setup(*prereqs) { |task| .. } => task
478
+ #
479
+ # Returns the setup task. The setup task is executed before running the integration tests.
480
+ def setup(*prereqs, &block)
481
+ @setup.enhance prereqs, &block
482
+ end
483
+
484
+ # :call-seq:
485
+ # teardown(*prereqs) => task
486
+ # teardown(*prereqs) { |task| .. } => task
487
+ #
488
+ # Returns the teardown task. The teardown task is executed after running the integration tests.
489
+ def teardown(*prereqs, &block)
490
+ @teardown.enhance prereqs, &block
491
+ end
492
+
493
+ end
494
+
495
+
496
+ # Methods added to Project to support compilation and running of tests.
497
+ module Test
498
+
499
+ include Extension
500
+
501
+ first_time do
502
+ desc 'Run all tests'
503
+ task('test') { TestTask.run_local_tests false }
504
+
505
+ # This rule takes a suffix and runs that tests in the current project. For example;
506
+ # buildr test:MyTest
507
+ # will run the test com.example.MyTest, if such a test exists for this project.
508
+ #
509
+ # If you want to run multiple test, separate tham with a comma. You can also use glob
510
+ # (* and ?) patterns to match multiple tests, see the TestTask#include method.
511
+ rule /^test:.*$/ do |task|
512
+ # The map works around a JRuby bug whereby the string looks fine, but fails in fnmatch.
513
+ TestTask.only_run task.name.scan(/test:(.*)/)[0][0].split(',').map { |t| "#{t}" }
514
+ task('test').invoke
515
+ end
516
+
517
+ task 'build' do |task|
518
+ # Make sure this happens as the last action on the build, so all other enhancements
519
+ # are made to run before starting the tests.
520
+ task.enhance do
521
+ task('test').invoke unless Buildr.options.test == false
522
+ end
523
+ end
524
+
525
+ IntegrationTestsTask.define_task('integration')
526
+
527
+ # Similar to test:[pattern] but for integration tests.
528
+ rule /^integration:.*$/ do |task|
529
+ unless task.name.split(':')[1] =~ /^(setup|teardown)$/
530
+ # The map works around a JRuby bug whereby the string looks fine, but fails in fnmatch.
531
+ TestTask.only_run task.name[/integration:(.*)/, 1].split(',').map { |t| "#{t}" }
532
+ task('integration').invoke
533
+ end
534
+ end
535
+
536
+ end
537
+
538
+ before_define do |project|
539
+ # Define a recursive test task, and pass it a reference to the project so it can discover all other tasks.
540
+ test = TestTask.define_task('test')
541
+ test.send :associate_with, project
542
+
543
+ # Similar to the regular resources task but using different paths.
544
+ resources = ResourcesTask.define_task('test:resources')
545
+ resources.send :associate_with, project, :test
546
+ project.path_to(:source, :test, :resources).tap { |dir| resources.from dir if File.exist?(dir) }
547
+
548
+ # Similar to the regular compile task but using different paths.
549
+ compile = CompileTask.define_task('test:compile'=>[project.compile, resources])
550
+ compile.send :associate_with, project, :test
551
+ test.enhance [compile]
552
+
553
+ # Define these tasks once, otherwise we may get a namespace error.
554
+ test.setup ; test.teardown
555
+ end
556
+
557
+ after_define do |project|
558
+ test = project.test
559
+ # Dependency on compiled code, its dependencies and resources.
560
+ test.with project.compile.dependencies
561
+ test.with [project.compile.target, project.resources.target].compact
562
+ # Dependency on compiled tests and resources. Dependencies added using with.
563
+ test.dependencies.concat [test.compile.target, test.resources.target].compact
564
+ # Picking up the test frameworks adds further dependencies.
565
+ test.framework
566
+
567
+ project.clean do
568
+ verbose(false) do
569
+ rm_rf test.compile.target.to_s if test.compile.target
570
+ rm_rf test.report_to.to_s
571
+ end
572
+ end
573
+ end
574
+
575
+
576
+ # :call-seq:
577
+ # test(*prereqs) => TestTask
578
+ # test(*prereqs) { |task| .. } => TestTask
579
+ #
580
+ # Returns the test task. The test task controls the entire test lifecycle.
581
+ #
582
+ # You can use the test task in three ways. You can access and configure specific
583
+ # test tasks, e.g. enhance the compile task by calling test.compile, setup for
584
+ # the tests by enhancing test.setup and so forth.
585
+ #
586
+ # You can use convenient methods that handle the most common settings. For example,
587
+ # add dependencies using test.with, or include only specific tests using test.include.
588
+ #
589
+ # You can also enhance this task directly. This method accepts a list of arguments
590
+ # that are used as prerequisites and an optional block that will be executed by the
591
+ # test task.
592
+ #
593
+ # This task compiles the project and the tests (in that order) before running any tests.
594
+ # It execute the setup task, runs all the tests, any enhancements, and ends with the
595
+ # teardown tasks.
596
+ def test(*prereqs, &block)
597
+ task('test').enhance prereqs, &block
598
+ end
599
+
600
+ # :call-seq:
601
+ # integration { |task| .... }
602
+ # integration => IntegrationTestTask
603
+ #
604
+ # Use this method to return the integration tests task, or enhance it with a block to execute.
605
+ #
606
+ # There is one integration tests task you can execute directly, or as a result of running the package
607
+ # task (or tasks that depend on it, like install and deploy). It contains all the tests marked with
608
+ # :integration=>true, all other tests are considered unit tests and run by the test task before packaging.
609
+ # So essentially: build=>test=>packaging=>integration=>install/deploy.
610
+ #
611
+ # You add new tests from projects that define integration tests using the regular test task,
612
+ # but with the following addition:
613
+ # test.using :integration
614
+ #
615
+ # Use this method to enhance the setup and teardown tasks that are executed before (and after) all
616
+ # integration tests are run, for example, to start a Web server or create a database.
617
+ def integration(*deps, &block)
618
+ Rake::Task['rake:integration'].enhance deps, &block
619
+ end
620
+
621
+ end
622
+
623
+
624
+ # :call-seq:
625
+ # integration { |task| .... }
626
+ # integration => IntegrationTestTask
627
+ #
628
+ # Use this method to return the integration tests task.
629
+ def integration(*deps, &block)
630
+ Rake::Task['rake:integration'].enhance deps, &block
631
+ end
632
+
633
+ class Options
634
+
635
+ # Runs tests after the build when true (default). This forces tests to execute
636
+ # after the build, including when running build related tasks like install, deploy and release.
637
+ #
638
+ # Set to false to not run any tests. Set to :all to run all tests, ignoring failures.
639
+ #
640
+ # This option is set from the environment variable 'test', so you can also do:
641
+
642
+ # Returns the test option (environment variable TEST). Possible values are:
643
+ # * :false -- Do not run any tests (also accepts 'no' and 'skip').
644
+ # * :true -- Run all tests, stop on failure (default if not set).
645
+ # * :all -- Run all tests, ignore failures.
646
+ def test
647
+ case value = ENV['TEST'] || ENV['test']
648
+ when /^(no|off|false|skip)$/i
649
+ false
650
+ when /^all$/i
651
+ :all
652
+ when /^(yes|on|true)$/i, nil
653
+ true
654
+ else
655
+ warn "Expecting the environment variable test to be 'no' or 'all', not sure what to do with #{value}, so I'm just going to run all the tests and stop at failure."
656
+ true
657
+ end
658
+ end
659
+
660
+ # Sets the test option (environment variable TEST). Possible values are true, false or :all.
661
+ #
662
+ # You can also set this from the environment variable, e.g.:
663
+ #
664
+ # buildr # With tests
665
+ # buildr test=no # Without tests
666
+ # buildr test=all # Ignore failures
667
+ # set TEST=no
668
+ # buildr # Without tests
669
+ def test=(flag)
670
+ ENV['test'] = nil
671
+ ENV['TEST'] = flag.to_s
672
+ end
673
+
674
+ end
675
+
676
+ Buildr.help << <<-HELP
677
+ To run a full build without running any tests:
678
+ buildr test=no
679
+ To run specific test:
680
+ buildr test:MyTest
681
+ To run integration tests:
682
+ buildr integration
683
+ HELP
684
+
685
+ end
686
+
687
+
688
+ class Buildr::Project
689
+ include Buildr::Test
690
+ end