buildr 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/java/test.rb CHANGED
@@ -1,175 +1,308 @@
1
+ require "core/build"
2
+ require "java/compile"
3
+
1
4
  module Buildr
5
+ module Java
2
6
 
3
- class JUnitTask < Rake::Task
4
-
5
- attr_accessor :classpath
6
-
7
- def initialize(*args)
8
- super
9
- @classpath = []
10
- @paths = []
11
- @include = []
12
- @exclude = []
13
- enhance do |task|
14
- if test_cases.empty?
15
- puts "#{name}: No tests to run"
16
- else
17
- passed, failed = Java.junit(test_cases, :classpath=>classpath)
18
- fail "#{name}: The following tests failed:\n#{failed.join("\n")}" unless failed.empty?
19
- end
20
- end
21
- end
7
+ # The JUnit task executes JUnit test cases.
8
+ #
9
+ # The task requires one or more paths that contain the test cases (see #from),
10
+ # in addition to any classpath dependencies (see #with). From the test case
11
+ # directories it picks all classes that match the inclusion pattern and none
12
+ # that match the exclusion pattern and executes these in order. See #include
13
+ # for more information.
14
+ class JUnitTask < Rake::Task
22
15
 
23
- def from(*files)
24
- @paths += files
25
- self
26
- end
16
+ attr_accessor :classpath
27
17
 
28
- def include(*files)
29
- @include += files
30
- self
31
- end
18
+ def initialize(*args) #:nodoc:
19
+ super
20
+ @classpath = []
21
+ @paths = []
22
+ @include = []
23
+ @exclude = []
24
+ enhance do |task|
25
+ unless test_cases.empty?
26
+ puts "Running tests in #{name}" if verbose
27
+ passed, failed = Java.junit(test_cases, :classpath=>classpath + @paths)
28
+ fail "The following tests failed:\n#{failed.join("\n")}" unless failed.empty?
29
+ end
30
+ end
31
+ end
32
32
 
33
- def exclude(*files)
34
- @exclude += files
35
- self
36
- end
33
+ # :call-seq:
34
+ # include(*classes) => self
35
+ #
36
+ # Include only the specified test cases. Unless specified, the default is to include
37
+ # all test cases. This method accepts multiple arguments and returns self.
38
+ #
39
+ # Test cases are specified using the fully qualified class name. You can also use file-like
40
+ # patterns (glob) to specify collection of classes. For example:
41
+ # test.include "com.example.FirstTest"
42
+ # test.include "com.example.*"
43
+ # test.include "com.example.Module*"
44
+ # test.include "*.{First,Second}Test"
45
+ #
46
+ # If you do not specify any inclusion pattern explicitly, the default pattern is used.
47
+ # This pattern picks up all classes with a name ending with Test (same as test.include "*Test").
48
+ # Use the Test suffix to specify test case classes, and avoid the Test suffix for classes
49
+ # that do not implement test cases (e.g. mock objects, helpers, etc).
50
+ def include(*classes)
51
+ @include += classes
52
+ self
53
+ end
37
54
 
38
- def with(*files)
39
- @classpath |= artifacts(files.flatten).uniq
40
- self
41
- end
55
+ # :call-seq:
56
+ # exclude(*classes) => self
57
+ #
58
+ # Exclude the specified test cases. This method accepts multiple arguments and returns self.
59
+ # See #include for the type of arguments you can use.
60
+ def exclude(*classes)
61
+ @exclude += classes
62
+ self
63
+ end
42
64
 
43
- def test_cases()
44
- unless @cases
45
- @include << "*" if @include.empty?
46
- @cases = @paths.map do |path|
47
- base = Pathname.new(path)
48
- FileList[File.join(path, "**", "*Test.class")].
49
- map { |file| Pathname.new(file).relative_path_from(base).to_s.ext("").gsub(File::SEPARATOR, ".") }.
50
- select { |name| @include.any? { |pattern| File.fnmatch(pattern, name) } }.
51
- reject { |name| @exclude.any? { |pattern| File.fnmatch(pattern, name) } }
52
- end.flatten.sort
53
- end
54
- @cases
55
- end
65
+ # :call-seq:
66
+ # from(*paths) => self
67
+ #
68
+ # Specify one or more directories that include test cases.
69
+ def from(*files)
70
+ @paths += files
71
+ self
72
+ end
56
73
 
57
- def invoke()
58
- setup
59
- begin
60
- super
61
- ensure
62
- teardown
74
+ # :call-seq:
75
+ # with(*specs) => self
76
+ #
77
+ # Specify artifacts (specs, tasks, files, etc) to include in the classpath when running
78
+ # the test cases.
79
+ def with(*files)
80
+ @classpath |= artifacts(files.flatten).uniq
81
+ self
63
82
  end
64
- end
65
83
 
66
- def needed?()
67
- return true unless ENV["TESTS"] =~ /(no|off|false|disable)/i
68
- end
84
+ private
85
+
86
+ def test_cases()
87
+ unless @cases
88
+ @include << "*Test" if @include.empty?
89
+ @cases = @paths.map do |path|
90
+ base = Pathname.new(path.to_s)
91
+ FileList["#{path}/**/*.class"].
92
+ map { |file| Pathname.new(file).relative_path_from(base).to_s.ext("").gsub(File::SEPARATOR, ".") }.
93
+ select { |name| @include.any? { |pattern| File.fnmatch(pattern, name) } }.
94
+ reject { |name| @exclude.any? { |pattern| File.fnmatch(pattern, name) } }
95
+ end.flatten.sort
96
+ end
97
+ @cases
98
+ end
69
99
 
70
- def prerequisites()
71
- super + classpath + @paths
72
100
  end
73
101
 
74
- def invoke_prerequisites()
75
- prerequisites.each { |n| application[n, @scope].invoke }
76
- end
77
102
 
78
- def setup()
79
- Rake::Task[name.sub(/run$/, "setup")].invoke
80
- end
81
-
82
- def teardown()
83
- Rake::Task[name.sub(/run$/, "teardown")].invoke
84
- end
103
+ # The test task controls the entire test lifecycle.
104
+ #
105
+ # You can use the test task in three ways. You can access and configure specific
106
+ # test tasks, e.g. enhance the #compile task, or run code during #setup/#teardown.
107
+ #
108
+ # You can use convenient methods that handle the most common settings. For example,
109
+ # add classpath dependencies using #with, or include only specific test cases
110
+ # using #include.
111
+ #
112
+ # You can also enhance this task directly. This task will first execute the #compile
113
+ # task, followed by the #setup task and #junit task, then any of your enhancements,
114
+ # and end by executing #teardown.
115
+ class TestTask < Rake::Task
116
+
117
+ def initialize(*args) #:nodoc:
118
+ super
119
+ enhance do
120
+ compile.invoke
121
+ setup.invoke
122
+ junit.invoke
123
+ enhance { teardown.invoke }
124
+ end
125
+ end
85
126
 
86
- end
127
+ # :call-seq:
128
+ # prepare(*prereqs) => task
129
+ # prepare(*prereqs) { |task| .. } => task
130
+ #
131
+ # Executes before the #compile task to prepare any source files used during compilation.
132
+ def prepare(*prereqs, &block)
133
+ @project.task("test:prepare").enhance prereqs, &block
134
+ end
87
135
 
136
+ # :call-seq:
137
+ # compile(*sources) => CompileTask
138
+ # compile(*sources) { |task| .. } => CompileTask
139
+ #
140
+ # The compile task is similar to the Project's compile task. However, it compiles all
141
+ # files found in the src/java/test directory into the target/test-classes directory.
142
+ # This task is executed by the test task before running any test cases.
143
+ #
144
+ # Once the project definition is complete, all classpath dependencies from the regular
145
+ # compile task are copied over, so you only need to specify classpath dependencies
146
+ # specific to your test cases. You can do so by calling #with on the test task.
147
+ # The classpath dependencies used here are also copied over to the junit task.
148
+ def compile(*sources, &block)
149
+ @project.task("test:compile").from(sources).enhance &block
150
+ end
151
+
152
+ # :call-seq:
153
+ # resources(*prereqs) => ResourcesTask
154
+ # resources(*prereqs) { |task| .. } => ResourcesTask
155
+ #
156
+ # Executes by the #compile task to copy resource files over. See Project#resources.
157
+ def resources(*prereqs, &block)
158
+ @project.task("test:resources").enhance prereqs, &block
159
+ end
88
160
 
89
- class Tests
161
+ # :call-seq:
162
+ # junit() => JUnitTask
163
+ #
164
+ # Returns the JUnit task. This task executes JUnit test cases, from classes compiled by
165
+ # the test task.
166
+ #
167
+ # By default it includes all classes with the suffix Test, and excludes all other classes.
168
+ # Use the Test suffix for classes that implement test cases, avoid this suffix for other
169
+ # classes (e.g. mocks, helper objects).
170
+ #
171
+ # You can also include only specific test cases, or exclude otherwise included test cases
172
+ # using #include and #exclude.
173
+ def junit()
174
+ @project.task("test:junit")
175
+ end
90
176
 
91
- def initialize(project)
92
- @project = project
93
- end
177
+ # :call-seq:
178
+ # setup(*prereqs) => task
179
+ # setup(*prereqs) { |task| .. } => task
180
+ #
181
+ # Returns the setup task. The setup task is executed at the beginning of the test task,
182
+ # after compiling the test files.
183
+ def setup(*prereqs, &block)
184
+ @project.task("test:setup").enhance prereqs, &block
185
+ end
94
186
 
95
- def prepare(*tasks, &block)
96
- @project.task("tests:prepare").enhance tasks, &block
97
- end
187
+ # :call-seq:
188
+ # teardown(*prereqs) => task
189
+ # teardown(*prereqs) { |task| .. } => task
190
+ #
191
+ # Returns the teardown task. The teardown task is executed at the end of the test task.
192
+ def teardown(*prereqs, &block)
193
+ @project.task("test.teardown").enhance prereqs, &block
194
+ end
98
195
 
99
- def compile(*sources, &block)
100
- @project.task("tests:compile").from(sources).enhance &block
101
- end
102
-
103
- def resources(*tasks, &block)
104
- @project.task("tests:resources").enhance tasks, &block
105
- end
196
+ # :call-seq:
197
+ # with(*specs) => self
198
+ #
199
+ # Specify artifacts (specs, tasks, files, etc) to include in the classpath when compiling
200
+ # and running test cases. Unless you need to limit specific classpath dependencies, use
201
+ # this instead of calling test.compile and test.junit individually.
202
+ def with(*artifacts)
203
+ compile.with artifacts
204
+ junit.with artifacts
205
+ self
206
+ end
106
207
 
107
- def setup(*tasks, &block)
108
- @project.task("tests:setup").enhance tasks, &block
109
- end
208
+ # :call-seq:
209
+ # include(*classes) => self
210
+ #
211
+ # See JUnitTask#include.
212
+ def include(*classes)
213
+ junit.include *classes
214
+ self
215
+ end
110
216
 
111
- def run(*tasks, &block)
112
- @project.task("tests:run").enhance tasks, &block
113
- end
217
+ # :call-seq:
218
+ # exclude(*classes) => self
219
+ #
220
+ # See JUnitTask#exclude.
221
+ def exclude(*classes)
222
+ junit.exclude *classes
223
+ self
224
+ end
114
225
 
115
- def teardown(*tasks, &block)
116
- @project.task("tests:teardown").enhance tasks, &block
117
226
  end
118
227
 
119
228
  end
120
229
 
121
230
  class Project
122
- inherited_attr :test_src_dir do File.join(src_dir, "test", "java") end
123
- inherited_attr :test_resources_dir do File.join(src_dir, "test", "resources") end
124
- inherited_attr :test_target_dir do File.join(target_dir, "test-classes") end
125
231
 
126
- def tests()
127
- @tests ||= Tests.new(self)
128
- end
129
-
130
- def test(*tasks, &block)
131
- tests.run *tasks, &block
232
+ # :call-seq:
233
+ # test(*prereqs) => TestTask
234
+ # test(*prereqs) { |task| .. } => TestTask
235
+ #
236
+ # Returns the test task. The test task controls the entire test lifecycle.
237
+ #
238
+ # You can use the test task in three ways. You can access and configure specific
239
+ # test tasks, e.g. enhance the compile task by calling test.compile, setup for
240
+ # the test cases by enhancing test.setup and so forth.
241
+ #
242
+ # You can use convenient methods that handle the most common settings. For example,
243
+ # add classpath dependencies using test.with, or include only specific test cases
244
+ # using test.include.
245
+ #
246
+ # You can also enhance this task directly. This method accepts a list of arguments
247
+ # that are used as prerequisites and an optional block that will be executed by the
248
+ # test task.
249
+ #
250
+ # This task will first execute the test.compile task, followed by the test.setup
251
+ # task and test.junit task, then any of your enhancements, and end by executing
252
+ # test.teardown.
253
+ def test(*prereqs, &block)
254
+ task("test").enhance prereqs, &block
132
255
  end
256
+
133
257
  end
134
258
 
135
259
  # Global task compiles all projects.
136
260
  desc "Run all test cases"
137
- Project.local_task task("test")
261
+ Project.local_task("test") { |name| "Running tests in #{name}" }
138
262
 
139
263
  Project.on_define do |project|
140
- namespace "tests" do
141
- # Compile task requires prepare and performs resources, if anything compiled.
142
- #Java::CompileTask.define_task("compile"=>[project.compile, task("prepare")]) { |task| project.tests.resources.invoke }
143
- Java::CompileTask.define_task("compile"=>[project.compile, task("prepare")]) { |task| project.tests.resources.invoke }
144
- # Resources task is a filter.
145
- FilterTask.define_task("resources")
146
- JUnitTask.define_task("run"=>task("compile"))
147
- task("setup")
148
- task("teardown")
149
- end
150
- project.tests.compile.with Java::JUNIT_REQUIRES
151
- project.recursive_task("test"=>project.test)
264
+ # Define a recursive test task, and pass it a reference to the project so it can discover all other tasks.
265
+ Java::TestTask.define_task("test")
266
+ project.test.instance_eval { instance_variable_set :@project, project }
267
+ project.recursive_task("test")
268
+ # Similar to the regular resources task but using different paths.
269
+ resources = Java::ResourcesTask.define_task("test:resources")
270
+ project.path_to("src/test/resources").tap { |dir| resources.filter.include project.path_to(dir, "*") if File.exist?(dir) }
271
+ # Similar to the regular compile task but using different paths.
272
+ compile = Java::CompileTask.define_task("test:compile"=>[project.compile, project.test.prepare, project.test.resources])
273
+ compile.enhance { project.test.resources.invoke }
274
+ project.path_to("src/test/java").tap { |dir| compile.from dir if File.exist?(dir) }
275
+ compile.into project.path_to("target/test-classes")
276
+ resources.filter.into compile.target
277
+ # Define the JUnit task here, otherwise we get a normal task.
278
+ Java::JUnitTask.define_task("test:junit")
279
+ # Define these tasks once, otherwise we may get a namespace error.
280
+ project.test.setup ; project.test.teardown
281
+ # Include the JUnit, Mock and other commonly used dependencies.
282
+ project.test.with Java::JUNIT_REQUIRES
152
283
 
153
284
  project.enhance do |project|
154
- project.tests.compile.from project.path_to(:test_src_dir) if File.exist?(project.path_to(:test_src_dir))
155
- project.tests.compile.into project.path_to(:test_target_dir) unless project.tests.compile.target
156
- project.tests.resources.include project.path_to(:test_resources_dir, "*") if File.exists?(project.path_to(:test_resources_dir))
157
- project.tests.resources.into project.tests.compile.target unless project.tests.resources.target
158
-
159
- project.tests.compile.classpath += project.compile.classpath
160
- project.tests.compile.classpath << project.compile.target
161
- project.tests.run.from project.tests.compile.target
162
- project.tests.run.classpath += project.tests.compile.classpath
163
- project.tests.run.classpath << project.tests.compile.target
285
+ # Copy the regular compile classpath over, and also include the generated classes.
286
+ project.test.with project.compile.classpath, project.compile.target
287
+ project.test.junit.with project.test.compile.classpath
288
+ # Tell the JUnit task where to pick the test cases from.
289
+ project.test.junit.from project.test.compile.target
164
290
  end
165
-
166
291
  end
167
292
 
293
+ # This rule takes a suffix and runs that test case in the current project. For example;
294
+ # rake test:MyTest
295
+ # will run the test case class com.example.MyTest, if found in the current project.
168
296
  rule /^test:.*$/ do |task|
169
297
  test = task.name.scan(/test:(.*)/)[0][0]
170
298
  Project.projects.select { |project| project.base_dir == Rake.application.original_dir }.
171
- map { |project| project.task("tests:run") }.
172
- each { |task| task.include("*#{test}").invoke }
299
+ map { |project| project.test }.each { |task| task.include("*#{test}").invoke }
173
300
  end
174
301
 
302
+ # Require tests after build unless TEST option is off.
303
+ # For example:
304
+ # rake build
305
+ # rake build TEST=off
306
+ task("build") { task("test").invoke } unless ENV["TEST"] =~ /(off|false|no)/
307
+
175
308
  end
data/lib/java/xmlbeans.rb CHANGED
@@ -1,66 +1,72 @@
1
+ require "java/java"
2
+
1
3
  module Buildr
4
+ module Java
5
+ module XMLBeans
2
6
 
3
- module XMLBeans
7
+ REQUIRES = [ "xmlbeans:xbean:jar:2.2.0", "stax:stax-api:jar:1.0" ]
4
8
 
5
- REQUIRES = [ "xmlbeans:xbean:jar:2.2.0", "stax:stax-api:jar:1.0" ]
9
+ class << self
6
10
 
7
- def self.compile(*args)
8
- options = Hash === args.last ? args.pop : {}
9
- options[:verbose] ||= Rake.application.options.trace || false
10
- fu_check_options options, :verbose, :noop, :javasource, :jar, :classes, :output
11
+ def compile(*args)
12
+ options = Hash === args.last ? args.pop : {}
13
+ options[:verbose] ||= Rake.application.options.trace || false
14
+ fu_check_options options, :verbose, :noop, :javasource, :jar, :compile, :output, :xsb
11
15
 
12
- # Options for SchemaCompiler.
13
- cmd_args = [ options[:verbose] ? "-verbose" : "-quiet" ]
14
- cmd_args << "-javasource" << options[:javasource].collect.join(File::PATH_SEPARATOR) if options[:javasource]
15
- cmd_args << "-out" << options[:jar] if options[:jar]
16
- cmd_args << "-d" << options[:classes] if options[:classes]
17
- cmd_args << "-src" << options[:output] if options[:output]
18
- cmd_args += args
19
- cmd_args << { :verbose=>options[:verbose] }
16
+ # Options for SchemaCompiler.
17
+ output = options[:output].to_s
18
+ cmd_args = [ options[:verbose] ? "-verbose" : "-quiet" ]
19
+ cmd_args << "-javasource" << options[:javasource].collect.join(File::PATH_SEPARATOR) if options[:javasource]
20
+ cmd_args << "-out" << options[:jar] if options[:jar]
21
+ cmd_args << "-d" << output
22
+ cmd_args << "-srconly" unless options[:compile]
23
+ cmd_args << "-src" << output
24
+ cmd_args += args.flatten
25
+ cmd_args << { :verbose=>options[:verbose] }
20
26
 
21
- unless options[:noop]
22
- puts "Running XMLBeans schema compiler" if verbose
23
- mkpath options[:classes], :verbose=>false rescue nil if options[:classes]
24
- mkpath options[:output], :verbose=>false rescue nil if options[:output]
25
- sh(Java.path_to_bin("java"), "-Xmx256m", "-cp", requires.join(File::PATH_SEPARATOR),
26
- "org.apache.xmlbeans.impl.tool.SchemaCompiler", *cmd_args) { |ok, res|
27
- fail "Failed to compile schemas, see errors above" unless ok }
28
- # Touch paths to let other tasks know there's an update.
29
- touch options[:classes], :verbose=>false if options[:classes]
30
- touch options[:output], :verbose=>false if options[:output]
31
- end
32
- end
27
+ unless options[:noop]
28
+ puts "Running XMLBeans schema compiler" if verbose
29
+ mkpath output, :verbose=>false rescue nil
30
+ sh(Java.path_to_bin("java"), "-Xmx256m", "-cp", requires.join(File::PATH_SEPARATOR),
31
+ "org.apache.xmlbeans.impl.tool.SchemaCompiler", *cmd_args) { |ok, res|
32
+ fail "Failed to compile schemas, see errors above" unless ok }
33
+ # Touch paths to let other tasks know there's an update.
34
+ touch output, :verbose=>false
35
+ end
36
+ end
33
37
 
34
- def self.requires()
35
- @requires ||= artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
36
- end
37
-
38
- class CompileTask < Rake::FileTask
38
+ private
39
39
 
40
- def initialize(*args)
41
- super
42
- enhance do |task|
43
- XMLBeans.compile *task.prerequisites + [options.merge(:output=>task.name)]
40
+ def requires()
41
+ @requires ||= artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
44
42
  end
43
+
45
44
  end
46
45
 
47
- def options()
48
- @options ||= {}
49
- end
50
-
51
- def using(options)
52
- self.options.merge!(options)
53
- self
46
+ def compile_xml_beans(*args)
47
+ # Generate sources and add them to the compile task.
48
+ generated = file(path_to("target/generated/xmlbeans")=>FileList[args.flatten]) do |task|
49
+ Java::XMLBeans.compile task.prerequisites, :output=>task.name,
50
+ :javasource=>compile.options.source, :xsb=>compile.target
51
+ end
52
+ compile.from(generated).with(JAVAX.stream, XMLBEANS)
53
+ # Once compiled, we need to copy the generated XSB/XSD and one (magical?) class file
54
+ # into the target directory, or the rest is useless.
55
+ compile do |task|
56
+ verbose(false) do
57
+ base = Pathname.new(generated.to_s)
58
+ FileList["#{base}/**/*.{class,xsb,xsd}"].each do |file|
59
+ target = File.join(compile.target.to_s, Pathname.new(file).relative_path_from(base))
60
+ mkpath File.dirname(target) ; cp file, target
61
+ end
62
+ end
63
+ end
54
64
  end
55
65
 
56
66
  end
57
-
58
- def self.compile_task(args)
59
- output = args.keys.first
60
- files = args.values.first.collect { |f| File.directory?(f) ? FileList[f + "/**/*"] : f }.flatten
61
- CompileTask.define_task(output=>files)
62
- end
63
-
64
67
  end
65
68
 
69
+ class Project
70
+ include Java::XMLBeans
71
+ end
66
72
  end