Author: boisvert
Date: Wed Jul 14 01:40:46 2010
New Revision: 963919

URL: http://svn.apache.org/viewvc?rev=963919&view=rev
Log:
BUILDR-415 Ability to exclude tests from command line

Modified:
    buildr/trunk/CHANGELOG
    buildr/trunk/lib/buildr/core/test.rb
    buildr/trunk/spec/core/test_spec.rb

Modified: buildr/trunk/CHANGELOG
URL: 
http://svn.apache.org/viewvc/buildr/trunk/CHANGELOG?rev=963919&r1=963918&r2=963919&view=diff
==============================================================================
--- buildr/trunk/CHANGELOG (original)
+++ buildr/trunk/CHANGELOG Wed Jul 14 01:40:46 2010
@@ -1,4 +1,5 @@
 1.4.2 (pending)
+* Added:  BUILDR-415 Ability to exclude tests from command line
 * Change: BUILDR-473 Update jruby-openssl dependency version or support a 
range of versions
 * Fixed:  BUILDR-302 Move out-of-date Nailgun documentation to wiki (Shane 
Witbeck)
 * Fixed:  BUILDR-144 Filter does not preserve file permissions

Modified: buildr/trunk/lib/buildr/core/test.rb
URL: 
http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/core/test.rb?rev=963919&r1=963918&r2=963919&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/core/test.rb (original)
+++ buildr/trunk/lib/buildr/core/test.rb Wed Jul 14 01:40:46 2010
@@ -171,7 +171,7 @@ module Buildr
 
       # Used by the test/integration rule to only run tests that match the 
specified names.
       def only_run(tests) #:nodoc:
-        tests = tests.map { |name| name =~ /\*/ ? name : "*#{name}*" }
+        tests = wildcardify(tests)
         # Since the tests may reside in a sub-project, we need to set the 
include/exclude pattern on
         # all sub-projects, but only invoke test on the local project.
         Project.projects.each { |project| project.test.send :only_run, tests }
@@ -183,6 +183,37 @@ module Buildr
         # all sub-projects, but only invoke test on the local project.
         Project.projects.each { |project| project.test.send :only_run_failed }
       end
+
+      # Used by the test/integration rule to clear all previously 
included/excluded tests.
+      def clear()
+        Project.projects.each do |project|
+          project.test.send :clear
+        end
+      end
+
+      # Used by the test/integration to include specific tests
+      def include(includes)
+        Project.projects.each do |project|
+          includes = wildcardify(includes)
+          project.test.send :include, *includes if includes.size > 0
+          project.test.send :forced_need=, true
+        end
+      end
+
+      # Used by the test/integration to exclude specific tests
+      def exclude(excludes)
+        Project.projects.each do |project|
+          excludes = wildcardify(excludes)
+          project.test.send :exclude, *excludes if excludes.size > 0
+          project.test.send :forced_need=, true
+        end
+      end
+
+    private
+
+      def wildcardify(strings)
+        strings.map { |name| name =~ /\*/ ? name : "*#{name}*" }
+      end
     end
 
     # Default options already set on each test task.
@@ -367,6 +398,13 @@ module Buildr
       self
     end
 
+    # Clear all test includes and excludes and returns self
+    def clear
+      @include = []
+      @exclude = []
+      self
+    end
+
     # *Deprecated*: Use tests instead.
     def classes
       Buildr.application.deprecated 'Call tests instead of classes'
@@ -439,6 +477,9 @@ module Buildr
     # The project this task belongs to.
     attr_reader :project
 
+    # Whether the tests are forced
+    attr_accessor :forced_need
+
   protected
 
     def associate_with(project)
@@ -596,7 +637,16 @@ module Buildr
       # (* and ?) patterns to match multiple tests, see the TestTask#include 
method.
       rule /^test:.*$/ do |task|
         # The map works around a JRuby bug whereby the string looks fine, but 
fails in fnmatch.
-        TestTask.only_run task.name.scan(/test:(.*)/)[0][0].split(',').map { 
|t| "#{t}" }
+        tests = task.name.scan(/test:(.*)/)[0][0].split(',').map(&:to_s)
+        excludes, includes = tests.partition { |t| t =~ /^-/ }
+        if excludes.empty?
+          TestTask.only_run includes
+        else
+          excludes.map! { |t| t[1..-1] }
+          TestTask.clear
+          TestTask.include includes
+          TestTask.exclude excludes
+        end
         task('test').invoke
       end
 

Modified: buildr/trunk/spec/core/test_spec.rb
URL: 
http://svn.apache.org/viewvc/buildr/trunk/spec/core/test_spec.rb?rev=963919&r1=963918&r2=963919&view=diff
==============================================================================
--- buildr/trunk/spec/core/test_spec.rb (original)
+++ buildr/trunk/spec/core/test_spec.rb Wed Jul 14 01:40:46 2010
@@ -758,25 +758,25 @@ describe Rake::Task, 'test' do
     options.test = :all
     lambda { task('test').invoke rescue nil }.should run_tasks('foo:test', 
'bar:test')
   end
-  
+
   it 'should ignore failure in subprojects if options.test is :all' do
     define('foo') {
-      define('p1') { test { fail } } 
-      define('p2') { test {  } } 
-      define('p3') { test { fail } } 
+      define('p1') { test { fail } }
+      define('p2') { test {  } }
+      define('p3') { test { fail } }
     }
-    define('bar') { test { fail } } 
+    define('bar') { test { fail } }
     options.test = :all
     lambda { task('test').invoke rescue nil }.should run_tasks('foo:p1:test', 
'foo:p2:test', 'foo:p3:test', 'bar:test')
   end
-  
+
   it 'should ignore failure in subprojects if environment variable test is 
\'all\'' do
     define('foo') {
-      define('p1') { test { fail } } 
-      define('p2') { test {  } } 
-      define('p3') { test { fail } } 
+      define('p1') { test { fail } }
+      define('p2') { test {  } }
+      define('p3') { test { fail } }
     }
-    define('bar') { test { fail } } 
+    define('bar') { test { fail } }
     ENV['test'] = 'all'
     lambda { task('test').invoke rescue nil }.should run_tasks('foo:p1:test', 
'foo:p2:test', 'foo:p3:test', 'bar:test')
   end
@@ -904,6 +904,80 @@ describe 'test rule' do
     project('foo').test.tests.should include('something')
   end
 
+  it 'should not execute excluded tests' do
+    define 'foo' do
+      test.using(:junit)
+      test.instance_eval { @framework.stub!(:tests).and_return(['something', 
'nothing']) }
+    end
+    task('test:*,-nothing').invoke
+    project('foo').test.tests.should include('something')
+    project('foo').test.tests.should_not include('nothing')
+  end
+
+  it 'should not execute tests in excluded package' do
+    write 'src/test/java/com/example/foo/TestSomething.java',
+      'package com.example.foo; public class TestSomething extends 
junit.framework.TestCase { public void testNothing() {} }'
+    write 'src/test/java/com/example/bar/TestFails.java',
+      'package com.example.bar; public class TestFails extends 
junit.framework.TestCase { public void testFailure() { fail(); } }'
+    define 'foo' do
+      test.using(:junit)
+    end
+    task('test:-com.example.bar').invoke
+    project('foo').test.tests.should include('com.example.foo.TestSomething')
+    project('foo').test.tests.should_not include('com.example.bar.TestFails')
+  end
+
+  it 'should not execute excluded tests with wildcards' do
+    define 'foo' do
+      test.using(:junit)
+      test.instance_eval { @framework.stub!(:tests).and_return(['something', 
'nothing']) }
+    end
+    task('test:something,-s*,-n*').invoke
+    project('foo').test.tests.should_not include('something')
+    project('foo').test.tests.should_not include('nothing')
+  end
+
+  it 'should execute all tests except excluded tests' do
+    define 'foo' do
+      test.using(:junit)
+      test.instance_eval { @framework.stub!(:tests).and_return(['something', 
'anything', 'nothing']) }
+    end
+    task('test:-nothing').invoke
+    project('foo').test.tests.should include('something', 'anything')
+    project('foo').test.tests.should_not include('nothing')
+  end
+
+  it 'should ignore exclusions in buildfile' do
+    define 'foo' do
+      test.using(:junit)
+      test.exclude 'something'
+      test.instance_eval { @framework.stub!(:tests).and_return(['something', 
'anything', 'nothing']) }
+    end
+    task('test:-nothing').invoke
+    project('foo').test.tests.should include('something', 'anything')
+    project('foo').test.tests.should_not include('nothing')
+  end
+
+  it 'should ignore inclusions in buildfile' do
+    define 'foo' do
+      test.using(:junit)
+      test.include 'something'
+      test.instance_eval { @framework.stub!(:tests).and_return(['something', 
'nothing']) }
+    end
+    task('test:nothing').invoke
+    project('foo').test.tests.should include('nothing')
+    project('foo').test.tests.should_not include('something')
+  end
+
+  it 'should not execute a test if it''s both included and excluded' do
+    define 'foo' do
+      test.using(:junit)
+      test.instance_eval { @framework.stub!(:tests).and_return(['nothing']) }
+    end
+    task('test:nothing,-nothing').invoke
+    project('foo').test.tests.should_not include('nothing')
+  end
+
   it 'should not update the last successful test run timestamp' do
     define 'foo' do
       test.using(:junit)
@@ -945,7 +1019,7 @@ describe 'test failed' do
     project('foo').test.tests.should include('FailingTest')
     project('foo').test.tests.should_not include('PassingTest')
   end
-  
+
   it 'should run failed tests, respecting excluded tests' do
     define 'foo' do
       test.using(:junit).exclude('ExcludedTest')


Reply via email to