assaf-buildr 1.3.3

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.
Files changed (163) hide show
  1. data/CHANGELOG +887 -0
  2. data/DISCLAIMER +7 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.rdoc +146 -0
  6. data/Rakefile +62 -0
  7. data/_buildr +38 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +236 -0
  10. data/addon/buildr/emma.rb +238 -0
  11. data/addon/buildr/hibernate.rb +142 -0
  12. data/addon/buildr/javacc.rb +85 -0
  13. data/addon/buildr/jdepend.rb +60 -0
  14. data/addon/buildr/jetty.rb +248 -0
  15. data/addon/buildr/jibx.rb +86 -0
  16. data/addon/buildr/nailgun.rb +817 -0
  17. data/addon/buildr/openjpa.rb +90 -0
  18. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  21. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  25. data/addon/buildr/xmlbeans.rb +93 -0
  26. data/bin/buildr +28 -0
  27. data/buildr.buildfile +53 -0
  28. data/buildr.gemspec +58 -0
  29. data/doc/css/default.css +228 -0
  30. data/doc/css/print.css +100 -0
  31. data/doc/css/syntax.css +52 -0
  32. data/doc/images/apache-incubator-logo.png +0 -0
  33. data/doc/images/buildr-hires.png +0 -0
  34. data/doc/images/buildr.png +0 -0
  35. data/doc/images/favicon.png +0 -0
  36. data/doc/images/growl-icon.tiff +0 -0
  37. data/doc/images/note.png +0 -0
  38. data/doc/images/project-structure.png +0 -0
  39. data/doc/images/tip.png +0 -0
  40. data/doc/images/zbuildr.tif +0 -0
  41. data/doc/pages/artifacts.textile +207 -0
  42. data/doc/pages/building.textile +240 -0
  43. data/doc/pages/contributing.textile +208 -0
  44. data/doc/pages/download.textile +62 -0
  45. data/doc/pages/extending.textile +175 -0
  46. data/doc/pages/getting_started.textile +273 -0
  47. data/doc/pages/index.textile +42 -0
  48. data/doc/pages/languages.textile +407 -0
  49. data/doc/pages/mailing_lists.textile +17 -0
  50. data/doc/pages/more_stuff.textile +286 -0
  51. data/doc/pages/packaging.textile +427 -0
  52. data/doc/pages/projects.textile +274 -0
  53. data/doc/pages/recipes.textile +103 -0
  54. data/doc/pages/settings_profiles.textile +274 -0
  55. data/doc/pages/testing.textile +212 -0
  56. data/doc/pages/troubleshooting.textile +103 -0
  57. data/doc/pages/whats_new.textile +323 -0
  58. data/doc/print.haml +51 -0
  59. data/doc/print.toc.yaml +29 -0
  60. data/doc/scripts/buildr-git.rb +412 -0
  61. data/doc/scripts/install-jruby.sh +44 -0
  62. data/doc/scripts/install-linux.sh +64 -0
  63. data/doc/scripts/install-osx.sh +52 -0
  64. data/doc/site.haml +56 -0
  65. data/doc/site.toc.yaml +47 -0
  66. data/etc/KEYS +151 -0
  67. data/etc/git-svn-authors +16 -0
  68. data/lib/buildr.rb +35 -0
  69. data/lib/buildr/core.rb +27 -0
  70. data/lib/buildr/core/application.rb +489 -0
  71. data/lib/buildr/core/application_cli.rb +139 -0
  72. data/lib/buildr/core/build.rb +311 -0
  73. data/lib/buildr/core/checks.rb +382 -0
  74. data/lib/buildr/core/common.rb +154 -0
  75. data/lib/buildr/core/compile.rb +596 -0
  76. data/lib/buildr/core/environment.rb +120 -0
  77. data/lib/buildr/core/filter.rb +362 -0
  78. data/lib/buildr/core/generate.rb +195 -0
  79. data/lib/buildr/core/help.rb +118 -0
  80. data/lib/buildr/core/progressbar.rb +156 -0
  81. data/lib/buildr/core/project.rb +892 -0
  82. data/lib/buildr/core/test.rb +715 -0
  83. data/lib/buildr/core/transports.rb +558 -0
  84. data/lib/buildr/core/util.rb +289 -0
  85. data/lib/buildr/groovy.rb +18 -0
  86. data/lib/buildr/groovy/bdd.rb +105 -0
  87. data/lib/buildr/groovy/compiler.rb +138 -0
  88. data/lib/buildr/ide.rb +19 -0
  89. data/lib/buildr/ide/eclipse.rb +212 -0
  90. data/lib/buildr/ide/idea.ipr.template +300 -0
  91. data/lib/buildr/ide/idea.rb +189 -0
  92. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  93. data/lib/buildr/ide/idea7x.rb +210 -0
  94. data/lib/buildr/java.rb +23 -0
  95. data/lib/buildr/java/ant.rb +92 -0
  96. data/lib/buildr/java/bdd.rb +449 -0
  97. data/lib/buildr/java/commands.rb +211 -0
  98. data/lib/buildr/java/compiler.rb +348 -0
  99. data/lib/buildr/java/deprecated.rb +141 -0
  100. data/lib/buildr/java/jruby.rb +117 -0
  101. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  102. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  103. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +119 -0
  104. data/lib/buildr/java/packaging.rb +713 -0
  105. data/lib/buildr/java/pom.rb +178 -0
  106. data/lib/buildr/java/rjb.rb +155 -0
  107. data/lib/buildr/java/test_result.rb +308 -0
  108. data/lib/buildr/java/tests.rb +324 -0
  109. data/lib/buildr/java/version_requirement.rb +172 -0
  110. data/lib/buildr/packaging.rb +21 -0
  111. data/lib/buildr/packaging/artifact.rb +730 -0
  112. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  113. data/lib/buildr/packaging/artifact_search.rb +140 -0
  114. data/lib/buildr/packaging/gems.rb +102 -0
  115. data/lib/buildr/packaging/package.rb +233 -0
  116. data/lib/buildr/packaging/tar.rb +104 -0
  117. data/lib/buildr/packaging/zip.rb +722 -0
  118. data/lib/buildr/resources/buildr.icns +0 -0
  119. data/lib/buildr/scala.rb +19 -0
  120. data/lib/buildr/scala/compiler.rb +109 -0
  121. data/lib/buildr/scala/tests.rb +203 -0
  122. data/rakelib/apache.rake +191 -0
  123. data/rakelib/changelog.rake +57 -0
  124. data/rakelib/doc.rake +103 -0
  125. data/rakelib/package.rake +73 -0
  126. data/rakelib/release.rake +65 -0
  127. data/rakelib/rspec.rake +83 -0
  128. data/rakelib/rubyforge.rake +53 -0
  129. data/rakelib/scm.rake +49 -0
  130. data/rakelib/setup.rake +86 -0
  131. data/rakelib/stage.rake +48 -0
  132. data/spec/addon/cobertura_spec.rb +77 -0
  133. data/spec/addon/emma_spec.rb +120 -0
  134. data/spec/addon/test_coverage_spec.rb +255 -0
  135. data/spec/core/application_spec.rb +412 -0
  136. data/spec/core/artifact_namespace_spec.rb +646 -0
  137. data/spec/core/build_spec.rb +415 -0
  138. data/spec/core/checks_spec.rb +537 -0
  139. data/spec/core/common_spec.rb +664 -0
  140. data/spec/core/compile_spec.rb +566 -0
  141. data/spec/core/generate_spec.rb +33 -0
  142. data/spec/core/project_spec.rb +754 -0
  143. data/spec/core/test_spec.rb +1091 -0
  144. data/spec/core/transport_spec.rb +500 -0
  145. data/spec/groovy/bdd_spec.rb +80 -0
  146. data/spec/groovy/compiler_spec.rb +239 -0
  147. data/spec/ide/eclipse_spec.rb +243 -0
  148. data/spec/java/ant.rb +28 -0
  149. data/spec/java/bdd_spec.rb +358 -0
  150. data/spec/java/compiler_spec.rb +446 -0
  151. data/spec/java/java_spec.rb +88 -0
  152. data/spec/java/packaging_spec.rb +1103 -0
  153. data/spec/java/tests_spec.rb +466 -0
  154. data/spec/packaging/archive_spec.rb +503 -0
  155. data/spec/packaging/artifact_spec.rb +754 -0
  156. data/spec/packaging/packaging_helper.rb +63 -0
  157. data/spec/packaging/packaging_spec.rb +589 -0
  158. data/spec/sandbox.rb +137 -0
  159. data/spec/scala/compiler_spec.rb +228 -0
  160. data/spec/scala/tests_spec.rb +215 -0
  161. data/spec/spec_helpers.rb +304 -0
  162. data/spec/version_requirement_spec.rb +123 -0
  163. metadata +369 -0
@@ -0,0 +1,86 @@
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 'rubygems/source_info_cache'
18
+ require 'stringio' # for Gem::RemoteFetcher
19
+ require 'jruby' if RUBY_PLATFORM[/java/]
20
+
21
+ # True if running on the Windows operating sytem. Different from Gem.win_platform?
22
+ # which returns true if running on the Windows platform of MRI, false when using JRuby.
23
+ def windows?
24
+ Config::CONFIG['host_os'] =~ /windows|cygwin|bccwin|cygwin|djgpp|mingw|mswin|wince/i
25
+ end
26
+
27
+ def set_java_home
28
+ if !ENV['JAVA_HOME'] && RUBY_PLATFORM[/java/]
29
+ ENV['JAVA_HOME'] = java.lang.System.getProperty('java.home')
30
+ end
31
+ fail "Please set JAVA_HOME first #{'(no need to run as sudo)' if ENV['USER'] == 'root'}" unless ENV['JAVA_HOME']
32
+ end
33
+
34
+ def set_gem_home
35
+ ENV['GEM_HOME'] ||= Gem.path.find { |f| File.writable?(f) }
36
+ end
37
+
38
+ def sudo_needed?
39
+ !( windows? || ENV['GEM_HOME'] )
40
+ end
41
+
42
+ # Finds and returns path to executable. Consults PATH environment variable.
43
+ # Returns nil if executable not found.
44
+ def which(name)
45
+ if windows?
46
+ path = ENV['PATH'].split(File::PATH_SEPARATOR).map { |path| path.gsub('\\', '/') }.map { |path| "#{path}/#{name}.{exe,bat,com}" }
47
+ else
48
+ path = ENV['PATH'].split(File::PATH_SEPARATOR).map { |path| "#{path}/#{name}" }
49
+ end
50
+ FileList[path].existing.first
51
+ end
52
+
53
+ # Execute a GemRunner command
54
+ def gem_run(*args)
55
+ rb_bin = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
56
+ args.unshift rb_bin, '-S', 'gem'
57
+ args.unshift 'sudo', 'env', 'JAVA_HOME=' + ENV['JAVA_HOME'] if sudo_needed?
58
+ sh *args.map{ |a| a.inspect }.join(' ')
59
+ end
60
+
61
+ def install_gem(name, ver_requirement = ['> 0'])
62
+ dep = Gem::Dependency.new(name, ver_requirement)
63
+ @load_cache = true
64
+ if Gem::SourceIndex.from_installed_gems.search(dep).empty?
65
+ spec = Gem::SourceInfoCache.search(dep, true, @load_cache).last
66
+ fail "#{dep} not found in local or remote repository!" unless spec
67
+ puts "Installing #{spec.full_name} ..."
68
+ args = ['install']
69
+ args.push '--install-dir', ENV['GEM_HOME'] if ENV['GEM_HOME']
70
+ args.push spec.name, '-v', spec.version.to_s
71
+ gem_run *args
72
+ @load_cache = false # Just update the Gem cache once
73
+ end
74
+ end
75
+
76
+ # Setup environment for running this Rakefile (RSpec, Docter, etc).
77
+ desc "If you're building from sources, run this task first to setup the necessary dependencies."
78
+ missing = spec.dependencies.select { |dep| Gem::SourceIndex.from_installed_gems.search(dep).empty? }
79
+ task 'setup' do
80
+ set_java_home
81
+ set_gem_home
82
+ missing.each do |dep|
83
+ install_gem dep.name, dep.version_requirements
84
+ end
85
+ end
86
+ puts "Missing Gems #{missing.join(', ')}, please run rake setup first!" unless missing.empty?
@@ -0,0 +1,48 @@
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
+ # Staged files are copied to this directory first, and from there uploaded to the staging server.
18
+ directory 'staged'
19
+
20
+ task 'clobber' do
21
+ rm_rf 'staged'
22
+ end
23
+
24
+ namespace 'stage' do
25
+ # stage:check verifies that we're able to stage a release: check for a changelog,
26
+ # local changes, run all the test cases, etc. You can add more actions, e.g.
27
+ # checking license files, spell checking documentation.
28
+ task 'check'=>['setup', 'clobber']
29
+
30
+ # stage:prepare prepares all the files necessary for making a successful release:
31
+ # binary and source packages, documentation, Web site, change file, checksums, etc.
32
+ # This task depends on stage:check, and also performs its own verification of the
33
+ # produced artifacts. Staged files are placed in the staged directory.
34
+ task 'prepare'=>'staged'
35
+
36
+ # stage:upload moves the stage directory to the staging server.
37
+ task 'upload' do |task, args|
38
+ puts "Uploading staged directory to #{args.staging} ..."
39
+ sh 'rsync', '--progress', '--recursive', 'staged/', args.staging
40
+ puts 'Done'
41
+ end
42
+
43
+ # Put anything that happens post staging here, e.g. release vote email template.
44
+ task 'wrapup'
45
+ end
46
+
47
+ desc 'Stage files for the release, upload them to staging server'
48
+ task 'stage'=>['stage:check', 'stage:prepare', 'stage:upload', 'stage:wrapup']
@@ -0,0 +1,77 @@
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 File.join(File.dirname(__FILE__), 'test_coverage_spec')
18
+ Sandbox.require_addon 'buildr/cobertura'
19
+
20
+ Buildr::Cobertura::requires
21
+
22
+
23
+ describe Buildr::Cobertura do
24
+ before do
25
+ # Reloading the addon because the sandbox removes all its actions
26
+ load File.expand_path('../addon/buildr/cobertura.rb')
27
+ @tool_module = Buildr::Cobertura
28
+ end
29
+
30
+ it_should_behave_like 'test coverage tool'
31
+
32
+ describe 'project-specific' do
33
+
34
+ describe 'data file' do
35
+ it 'should have a default value' do
36
+ define('foo').cobertura.data_file.should point_to_path('reports/cobertura.ser')
37
+ end
38
+
39
+ it 'should be overridable' do
40
+ define('foo') { cobertura.data_file = path_to('target/data.cobertura') }
41
+ project('foo').cobertura.data_file.should point_to_path('target/data.cobertura')
42
+ end
43
+
44
+ it 'should be created during instrumentation' do
45
+ write 'src/main/java/Foo.java', 'public class Foo {}'
46
+ define('foo')
47
+ task('foo:cobertura:instrument').invoke
48
+ file(project('foo').cobertura.data_file).should exist
49
+ end
50
+ end
51
+
52
+ describe 'instrumentation' do
53
+ before do
54
+ ['Foo', 'Bar'].each { |cls| write File.join('src/main/java', "#{cls}.java"), "public class #{cls} {}" }
55
+ end
56
+
57
+ it 'should instrument only included classes' do
58
+ define('foo') { cobertura.include 'Foo' }
59
+ task("foo:cobertura:instrument").invoke
60
+ Dir.chdir('target/instrumented/classes') { Dir.glob('*').sort.should == ['Foo.class'] }
61
+ end
62
+
63
+ it 'should not instrument excluded classes' do
64
+ define('foo') { cobertura.exclude 'Foo' }
65
+ task("foo:cobertura:instrument").invoke
66
+ Dir.chdir('target/instrumented/classes') { Dir.glob('*').sort.should == ['Bar.class'] }
67
+ end
68
+
69
+ it 'should instrument classes that are included but not excluded' do
70
+ write 'src/main/java/Baz.java', 'public class Baz {}'
71
+ define('foo') { cobertura.include('Ba').exclude('ar') }
72
+ task("foo:cobertura:instrument").invoke
73
+ Dir.chdir('target/instrumented/classes') { Dir.glob('*').sort.should == ['Baz.class'] }
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,120 @@
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 File.join(File.dirname(__FILE__), 'test_coverage_spec')
18
+ Sandbox.require_addon 'buildr/emma'
19
+
20
+
21
+ Buildr::Emma::requires
22
+
23
+
24
+ describe Buildr::Emma do
25
+ before do
26
+ # Reloading the addon because the sandbox removes all its actions
27
+ load File.expand_path('../addon/buildr/emma.rb')
28
+ @tool_module = Buildr::Emma
29
+ end
30
+
31
+ it_should_behave_like 'test coverage tool'
32
+
33
+ describe 'project-specific' do
34
+ describe 'metadata file' do
35
+ it 'should have a default value' do
36
+ define('foo').emma.metadata_file.should point_to_path('reports/emma/coverage.em')
37
+ end
38
+
39
+ it 'should be overridable' do
40
+ define('foo') { emma.metadata_file = path_to('target/metadata.emma') }
41
+ project('foo').emma.metadata_file.should point_to_path('target/metadata.emma')
42
+ end
43
+
44
+ it 'should be created during instrumentation' do
45
+ write 'src/main/java/Foo.java', 'public class Foo {}'
46
+ define('foo')
47
+ task('foo:emma:instrument').invoke
48
+ file(project('foo').emma.metadata_file).should exist
49
+ end
50
+ end
51
+
52
+ describe 'coverage file' do
53
+ it 'should have a default value' do
54
+ define('foo').emma.coverage_file.should point_to_path('reports/emma/coverage.ec')
55
+ end
56
+
57
+ it 'should be overridable' do
58
+ define('foo') { emma.coverage_file = path_to('target/coverage.emma') }
59
+ project('foo').emma.coverage_file.should point_to_path('target/coverage.emma')
60
+ end
61
+
62
+ it 'should be created during test' do
63
+ write 'src/main/java/Foo.java', 'public class Foo {}'
64
+ write_test :for=>'Foo', :in=>'src/test/java'
65
+ define('foo')
66
+ task('foo:test').invoke
67
+ file(project('foo').emma.coverage_file).should exist
68
+ end
69
+ end
70
+
71
+ describe 'instrumentation' do
72
+ before do
73
+ ['Foo', 'Bar'].each { |cls| write File.join('src/main/java', "#{cls}.java"), "public class #{cls} {}" }
74
+ end
75
+
76
+ it 'should instrument only included classes' do
77
+ define('foo') { emma.include 'Foo' }
78
+ task("foo:emma:instrument").invoke
79
+ Dir.chdir('target/instrumented/classes') { Dir.glob('*').sort.should == ['Foo.class'] }
80
+ end
81
+
82
+ it 'should not instrument excluded classes' do
83
+ define('foo') { emma.exclude 'Foo' }
84
+ task("foo:emma:instrument").invoke
85
+ Dir.chdir('target/instrumented/classes') { Dir.glob('*').sort.should == ['Bar.class'] }
86
+ end
87
+
88
+ it 'should instrument classes that are included but not excluded' do
89
+ write 'src/main/java/Baz.java', 'public class Baz {}'
90
+ define('foo') { emma.include('Ba*').exclude('*ar') }
91
+ task("foo:emma:instrument").invoke
92
+ Dir.chdir('target/instrumented/classes') { Dir.glob('*').sort.should == ['Baz.class'] }
93
+ end
94
+ end
95
+
96
+ describe 'reports' do
97
+ before do
98
+ write 'src/main/java/Foo.java', 'public class Foo {}'
99
+ write_test :for=>'Foo', :in=>'src/test/java'
100
+ end
101
+
102
+ describe 'in html' do
103
+ it 'should inform the user if no coverage data' do
104
+ rm 'src/test/java/FooTest.java'
105
+ define('foo')
106
+ lambda { task('foo:emma:html').invoke }.
107
+ should show_info(/No test coverage report for foo. Missing: #{project('foo').emma.coverage_file}/)
108
+ end
109
+ end
110
+
111
+ describe 'in xml' do
112
+ it 'should have an xml file' do
113
+ define('foo')
114
+ task('foo:emma:xml').invoke
115
+ file(File.join(project('foo').emma.report_dir, 'coverage.xml')).should exist
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,255 @@
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 File.join(File.dirname(__FILE__), '../spec_helpers')
18
+
19
+
20
+ module TestCoverageHelper
21
+ def write_test options
22
+ write File.join(options[:in], "#{options[:for]}Test.java"),
23
+ "public class #{options[:for]}Test extends junit.framework.TestCase { public void test#{options[:for]}() { new #{options[:for]}(); } }"
24
+ end
25
+
26
+ # Rspec matcher using file glob patterns.
27
+ class FileNamePatternMatcher
28
+ def initialize(pattern)
29
+ @expected_pattern = pattern
30
+ @pattern_matcher = lambda { |filename| File.fnmatch? pattern, filename }
31
+ end
32
+
33
+ def matches?(directory)
34
+ @actual_filenames = Dir[File.join(directory,'*')]
35
+ @actual_filenames.any? &@pattern_matcher
36
+ end
37
+
38
+ def failure_message
39
+ "Expected to find at least one element matching '#{@expected_pattern}' among #{@actual_filenames.inspect}, but found none"
40
+ end
41
+
42
+ def negative_failure_message
43
+ "Expected to find no element matching '#{@expected_pattern}' among #{@actual_filenames.inspect}, but found matching element(s) #{@actual_filenames.select(&@pattern_matcher).inspect}"
44
+ end
45
+ end
46
+
47
+ # Test if a directory contains at least one file matching a given glob pattern.
48
+ #
49
+ # For example, to check that a directory contains at least one HTML file:
50
+ # '/path/to/some/directory'.should have_files_matching('*.html')
51
+ def have_files_matching pattern
52
+ FileNamePatternMatcher.new pattern
53
+ end
54
+ end
55
+
56
+ describe 'test coverage tool', :shared=>true do
57
+ include TestCoverageHelper
58
+
59
+ def toolname
60
+ @tool_module.name.split('::').last.downcase
61
+ end
62
+
63
+ def test_coverage_config
64
+ project('foo').send(toolname)
65
+ end
66
+
67
+ describe 'project-specific' do
68
+
69
+ before do
70
+ write 'src/main/java/Foo.java', 'public class Foo {}'
71
+ write_test :for=>'Foo', :in=>'src/test/java'
72
+ end
73
+
74
+ describe 'clean' do
75
+ before { define('foo') }
76
+
77
+ it 'should remove the instrumented directory' do
78
+ mkdir_p test_coverage_config.instrumented_dir.to_s
79
+ task('foo:clean').invoke
80
+ file(test_coverage_config.instrumented_dir).should_not exist
81
+ end
82
+
83
+ it 'should remove the reporting directory' do
84
+ mkdir_p test_coverage_config.report_dir
85
+ task('foo:clean').invoke
86
+ file(test_coverage_config.report_dir).should_not exist
87
+ end
88
+ end
89
+
90
+ describe 'instrumented directory' do
91
+ it 'should have a default value' do
92
+ define('foo')
93
+ test_coverage_config.instrumented_dir.should point_to_path('target/instrumented/classes')
94
+ end
95
+
96
+ it 'should be overridable' do
97
+ toolname = toolname()
98
+ define('foo') { send(toolname).instrumented_dir = path_to('target/coverage/classes') }
99
+ test_coverage_config.instrumented_dir.should point_to_path('target/coverage/classes')
100
+ end
101
+
102
+ it 'should be created during instrumentation' do
103
+ define('foo')
104
+ task("foo:#{toolname}:instrument").invoke
105
+ file(test_coverage_config.instrumented_dir).should exist
106
+ end
107
+ end
108
+
109
+ describe 'instrumentation' do
110
+ def instrumented_dir
111
+ file(test_coverage_config.instrumented_dir)
112
+ end
113
+
114
+ it 'should happen after compile' do
115
+ define('foo')
116
+ lambda { task("foo:#{toolname}:instrument").invoke }.should run_task('foo:compile')
117
+ end
118
+
119
+ it 'should put classes from compile.target in the instrumented directory' do
120
+ define('foo')
121
+ task("foo:#{toolname}:instrument").invoke
122
+ Dir.entries(instrumented_dir.to_s).should == Dir.entries(project('foo').compile.target.to_s)
123
+ end
124
+
125
+ it 'should touch instrumented directory if anything instrumented' do
126
+ a_long_time_ago = Time.now - 10
127
+ define('foo')
128
+ mkpath instrumented_dir.to_s
129
+ File.utime(a_long_time_ago, a_long_time_ago, instrumented_dir.to_s)
130
+ task("foo:#{toolname}:instrument").invoke
131
+ instrumented_dir.timestamp.should be_close(Time.now, 2)
132
+ end
133
+
134
+ it 'should not touch instrumented directory if nothing instrumented' do
135
+ a_long_time_ago = Time.now - 10
136
+ define('foo').compile.invoke
137
+ mkpath instrumented_dir.to_s
138
+ [project('foo').compile.target, instrumented_dir].map(&:to_s).each { |dir| File.utime(a_long_time_ago, a_long_time_ago, dir) }
139
+ task("foo:#{toolname}:instrument").invoke
140
+ instrumented_dir.timestamp.should be_close(a_long_time_ago, 2)
141
+ end
142
+ end
143
+
144
+ describe 'testing classpath' do
145
+ it 'should give priority to instrumented classes over non-instrumented ones' do
146
+ define('foo')
147
+ depends = project('foo').test.dependencies
148
+ depends.index(test_coverage_config.instrumented_dir).should < depends.index(project('foo').compile.target)
149
+ end
150
+
151
+ it 'should have the test coverage tools artifacts' do
152
+ define('foo')
153
+ @tool_module.requires.each { |artifact| project('foo').test.dependencies.should include(artifact) }
154
+ end
155
+ end
156
+
157
+ describe 'html report' do
158
+ it 'should have html files' do
159
+ define('foo')
160
+ task("foo:#{toolname}:html").invoke
161
+ test_coverage_config.report_to(:html).should have_files_matching('*.html')
162
+ end
163
+
164
+ it 'should contain full source code, including comments' do
165
+ write 'src/main/java/Foo.java',
166
+ 'public class Foo { /* This comment is a TOKEN to check that test coverage reports include the source code */ }'
167
+ define('foo')
168
+ task("foo:#{toolname}:html").invoke
169
+ htlm_report_contents = Dir[File.join(test_coverage_config.report_dir, '**/*.html')].map{|path|File.open(path).read}.join
170
+ htlm_report_contents.should =~ /TOKEN/
171
+ end
172
+ end
173
+ end
174
+
175
+ describe 'cross-project' do
176
+ describe 'reporting' do
177
+ before do
178
+ write 'src/main/java/Foo.java', 'public class Foo {}'
179
+ write 'bar/src/main/java/Bar.java', 'public class Bar {}'
180
+ write_test :for=>'Bar', :in=>'bar/src/test/java'
181
+ define('foo') { define('bar') }
182
+ end
183
+
184
+ it 'should have a default target' do
185
+ @tool_module.report_to.should point_to_path(File.join('reports', toolname))
186
+ end
187
+
188
+ describe 'in html' do
189
+ it 'should be a defined task' do
190
+ Rake::Task.task_defined?("#{toolname}:html").should be(true)
191
+ end
192
+
193
+ it 'should happen after project instrumentation and testing' do
194
+ lambda { task("#{toolname}:html").invoke }.should run_tasks(["foo:#{toolname}:instrument", 'foo:bar:test'])
195
+ end
196
+
197
+ it 'should have html files' do
198
+ task("#{toolname}:html").invoke
199
+ @tool_module.report_to(:html).should have_files_matching('*.html')
200
+ end
201
+
202
+ it 'should contain full source code, including comments' do
203
+ write 'bar/src/main/java/Bar.java',
204
+ 'public class Bar { /* This comment is a TOKEN to check that test coverage reports include the source code */ }'
205
+ task("#{toolname}:html").invoke
206
+ htlm_report_contents = Dir[File.join(@tool_module.report_to(:html), '**/*.html')].map{|path|File.open(path).read}.join
207
+ htlm_report_contents.should =~ /TOKEN/
208
+ end
209
+
210
+ it 'should handle gracefully a project with no source' do
211
+ define 'baz', :base_dir=>'baz'
212
+ task("#{toolname}:html").invoke
213
+ lambda { task("#{toolname}:html").invoke }.should_not raise_error
214
+ end
215
+ end
216
+ end
217
+
218
+ describe 'clean' do
219
+ it 'should remove the report directory' do
220
+ define('foo')
221
+ mkdir_p @tool_module.report_to
222
+ task("#{toolname}:clean").invoke
223
+ file(@tool_module.report_to).should_not exist
224
+ end
225
+
226
+ it 'should be called when calling global clean' do
227
+ define('foo')
228
+ lambda { task('clean').invoke }.should run_task("#{toolname}:clean")
229
+ end
230
+ end
231
+ end
232
+
233
+ describe 'project with no source' do
234
+ it 'should not define an html report task' do
235
+ define 'foo'
236
+ Rake::Task.task_defined?("foo:#{toolname}:html").should be(false)
237
+ end
238
+
239
+ it 'should not raise an error when instrumenting' do
240
+ define('foo')
241
+ lambda { task("foo:#{toolname}:instrument").invoke }.should_not raise_error
242
+ end
243
+
244
+ it 'should not add the instrumented directory to the testing classpath' do
245
+ define 'foo'
246
+ depends = project('foo').test.dependencies
247
+ depends.should_not include(test_coverage_config.instrumented_dir)
248
+ end
249
+
250
+ it 'should not add the test coverage tools artifacts to the testing classpath' do
251
+ define('foo')
252
+ @tool_module.requires.each { |artifact| project('foo').test.dependencies.should_not include(artifact) }
253
+ end
254
+ end
255
+ end