You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by vb...@apache.org on 2008/03/19 05:20:21 UTC

svn commit: r638700 - in /incubator/buildr/trunk: Rakefile lib/buildr/cobertura.rb lib/core/common.rb lib/core/test.rb lib/java.rb lib/java/bdd_frameworks.rb lib/java/test_frameworks.rb spec/java_bdd_frameworks_spec.rb

Author: vborja
Date: Tue Mar 18 21:20:20 2008
New Revision: 638700

URL: http://svn.apache.org/viewvc?rev=638700&view=rev
Log:
BUILDR-49  BUILDR-53.

Java BDD frameworks: JBehave, EasyB

Added:
    incubator/buildr/trunk/lib/java/bdd_frameworks.rb
    incubator/buildr/trunk/spec/java_bdd_frameworks_spec.rb
Modified:
    incubator/buildr/trunk/Rakefile
    incubator/buildr/trunk/lib/buildr/cobertura.rb
    incubator/buildr/trunk/lib/core/common.rb
    incubator/buildr/trunk/lib/core/test.rb
    incubator/buildr/trunk/lib/java.rb
    incubator/buildr/trunk/lib/java/test_frameworks.rb

Modified: incubator/buildr/trunk/Rakefile
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/Rakefile?rev=638700&r1=638699&r2=638700&view=diff
==============================================================================
--- incubator/buildr/trunk/Rakefile (original)
+++ incubator/buildr/trunk/Rakefile Tue Mar 18 21:20:20 2008
@@ -54,6 +54,7 @@
 
 begin
   require 'rubygems/dependency_installer'
+  require 'rubygems/doc_manager'
   def install_gem(gem, options = {})
     say "Installing #{gem}..."
     installer = Gem::DependencyInstaller.new(gem, options.delete(:version), options)

Modified: incubator/buildr/trunk/lib/buildr/cobertura.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/cobertura.rb?rev=638700&r1=638699&r2=638700&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/cobertura.rb (original)
+++ incubator/buildr/trunk/lib/buildr/cobertura.rb Tue Mar 18 21:20:20 2008
@@ -16,7 +16,7 @@
 
 module Buildr
 
-  # Addes the <code>cobertura:html</code> and <code>cobertura:xml</code> tasks.
+  # Provides the <code>cobertura:html</code> and <code>cobertura:xml</code> tasks.
   # Require explicitly using <code>require "buildr/cobertura"</code>.
   #
   # You can generate cobertura reports for a single project 

Modified: incubator/buildr/trunk/lib/core/common.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/common.rb?rev=638700&r1=638699&r2=638700&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/common.rb (original)
+++ incubator/buildr/trunk/lib/core/common.rb Tue Mar 18 21:20:20 2008
@@ -269,13 +269,22 @@
   class Filter
 
     def initialize #:nodoc:
-      @include = []
-      @exclude = []
-      @sources = []
+      clear
     end
 
     # Returns the list of source directories (each being a file task).
     attr_reader :sources
+
+    # :call-seq: 
+    #   clear => self
+    # 
+    # Clear filter sources and include/exclude patterns
+    def clear
+      @include = []
+      @exclude = []
+      @sources = []
+      self
+    end
 
     # :call-seq:
     #   from(*sources) => self

Modified: incubator/buildr/trunk/lib/core/test.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/core/test.rb?rev=638700&r1=638699&r2=638700&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/core/test.rb (original)
+++ incubator/buildr/trunk/lib/core/test.rb Tue Mar 18 21:20:20 2008
@@ -78,7 +78,7 @@
 
         # Returns true if this framework applies to the current project.  For example, JUnit returns
         # true if the tests are written in Java.
-        def applies_to?(paths)
+        def applies_to?(project)
           raise 'Not implemented'
         end
 
@@ -92,12 +92,15 @@
 
       # Construct a new test framework with the specified options.  Note that options may
       # change before the framework is run.
-      def initialize(options)
+      def initialize(test_task, options)
         @options = options
+        @task = test_task
       end
 
       # Options for this test framework.
       attr_reader :options
+      # The test task we belong to
+      attr_reader :task
 
       # Returns a list of dependenices for this framework.  Defaults to calling the #dependencies
       # method on the class.
@@ -112,13 +115,13 @@
       # This method should return a list suitable for using with the #run method, but also suitable
       # for the user to manage.  For example, JUnit locates all the tests in the test.compile.target
       # directory, and returns the class names, which are easier to work with than file names.
-      def tests(project)
+      def tests(dependencies)
         raise 'Not implemented'
       end
 
       # TestTask calls this method to run the named (and only those) tests.  This method returns
       # the list of tests that ran successfully.
-      def run(tests, task, dependencies)
+      def run(tests, dependencies)
         raise 'Not implemented'
       end
 
@@ -398,7 +401,7 @@
       cls = TestFramework.select(name) or raise ArgumentError, "No #{name} test framework available. Did you install it?"
       #cls.inherit_options.reject { |name| options.has_key?(name) }.
       #  each { |name| options[name] = @parent_task.options[name] } if @parent_task.respond_to?(:options)
-      @framework = cls.new(options)
+      @framework = cls.new(self, options)
       # Test framework dependency.
       with @framework.dependencies
     end
@@ -417,12 +420,12 @@
     def run_tests
       dependencies = Buildr.artifacts(self.dependencies).map(&:to_s).uniq
       rm_rf report_to.to_s
-      @tests = @framework.tests(self, dependencies).select { |test| include?(test) }.sort
+      @tests = @framework.tests(dependencies).select { |test| include?(test) }.sort
       if @tests.empty?
         @passed_tests, @failed_tests = [], []
       else
         puts "Running tests in #{@project.name}" if verbose
-        @passed_tests = @framework.run(@tests, self, dependencies)
+        @passed_tests = @framework.run(@tests, dependencies)
         @failed_tests = @tests - @passed_tests
         unless @failed_tests.empty?
           warn "The following tests failed:\n#{@failed_tests.join("\n")}" if verbose
@@ -540,7 +543,7 @@
       # Similar to the regular resources task but using different paths.
       resources = ResourcesTask.define_task('test:resources')
       resources.send :associate_with, project, :test
-      project.path_to(:src, :test, :resources).tap { |dir| resources.from dir if File.exist?(dir) }
+      project.path_to(:source, :test, :resources).tap { |dir| resources.from dir if File.exist?(dir) }
 
       # Similar to the regular compile task but using different paths.
       compile = CompileTask.define_task('test:compile'=>[project.compile, resources])

Modified: incubator/buildr/trunk/lib/java.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java.rb?rev=638700&r1=638699&r2=638700&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java.rb (original)
+++ incubator/buildr/trunk/lib/java.rb Tue Mar 18 21:20:20 2008
@@ -16,4 +16,5 @@
 
 require 'java/compilers'
 require 'java/test_frameworks'
+require 'java/bdd_frameworks'
 require 'java/packaging'

Added: incubator/buildr/trunk/lib/java/bdd_frameworks.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/bdd_frameworks.rb?rev=638700&view=auto
==============================================================================
--- incubator/buildr/trunk/lib/java/bdd_frameworks.rb (added)
+++ incubator/buildr/trunk/lib/java/bdd_frameworks.rb Tue Mar 18 21:20:20 2008
@@ -0,0 +1,210 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with this
+# work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+
+require 'java/test_frameworks'
+
+module Buildr
+
+  # Mixin for test frameworks using src/spec/{lang}
+  module TestFramework::JavaBDD #:nodoc:
+    
+    class << self
+      def included(mod)
+        mod.module_eval do
+          include TestFramework::JavaTest
+          include ClassMethods
+        end
+        mod.extend ClassMethods
+        mod.bdd_dir = :spec
+        mod.lang = :java
+        super
+      end
+    end
+
+    module ClassMethods
+      attr_accessor :lang, :bdd_dir
+    end
+
+    def initialize(task, options)
+      self.bdd_dir = self.class.bdd_dir
+      project = task.project
+      project.task('test:compile').tap do |comp| 
+        comp.send :associate_with, project, bdd_dir
+        self.lang = comp.language || self.class.lang
+      end
+      project.task('test:resources').tap do |res|
+        res.send :associate_with, project, bdd_dir
+        res.filter.clear
+        project.path_to(:source, bdd_dir, :resources).tap { |dir| resources.from dir if File.exist?(dir) }
+      end
+      super
+    end
+  end
+  
+  class RSpec < TestFramework::Base
+    include TestFramework::JavaBDD
+    self.lang = :ruby
+
+    REQUIRES = ['org.jruby:jruby-complete:jar:1.1RC2']
+    TESTS_PATTERN = [ /_spec.rb$/ ]
+    OPTIONS = [:properties, :java_args]
+
+    def self.applies_to?(project) #:nodoc:
+      !Dir[project.path_to(:source, bdd_dir, lang, '**/*_spec.rb')].empty?
+    end
+
+    def tests(dependencies) #:nodoc:
+      if ENV['SPEC']
+        FileList[Env['SPEC']]
+      else
+        Dir[task.project.path_to(:source, bdd_dir, "ruby/**/*_spec.rb")]
+      end
+    end
+
+    def run(tests, dependencies) #:nodoc:
+      tests # TODO
+    end
+  end
+
+  class JtestR < TestFramework::Base
+    include TestFramework::JavaBDD
+    self.lang = :ruby
+  end
+  
+  # JBehave is a Java BDD framework. To use in your project:
+  #   test.using :jbehave
+  # 
+  # This framework will search in your project for:
+  #   src/spec/java/**/*Behaviour.java
+  # 
+  # JMock libraries are included on runtime.
+  #
+  # Support the following options:
+  # * :properties -- Hash of properties to the test suite
+  # * :java_args -- Arguments passed to the JVM
+  class JBehave < TestFramework::Base
+    include TestFramework::JavaBDD
+
+    VERSION = "1.0.1" unless const_defined?('VERSION')
+    REQUIRES = ["org.jbehave:jbehave:jar:#{VERSION}",
+                "jmock:jmock-cglib:jar:#{JMock::VERSION}",
+                "cglib:cglib-full:jar:2.0.2",
+               ] + JUnit::REQUIRES
+    TESTS_PATTERN = [ /Behaviou?r$/ ]
+
+    def self.applies_to?(project) #:nodoc:
+      %w{
+        **/*Behaviour.java **/*Behavior.java
+      }.any? { |glob| !Dir[project.path_to(:source, bdd_dir, lang, glob)].empty? }
+    end
+
+    def tests(dependencies) #:nodoc:
+      filter_classes(dependencies, :class_names => TESTS_PATTERN,
+                     :interfaces => %w{ org.jbehave.core.behaviour.Behaviours })
+    end
+    
+    def run(tests, dependencies) #:nodoc:
+      cmd_args = ['org.jbehave.core.BehaviourRunner']
+      cmd_options = { :properties=>options[:properties], :java_args=>options[:java_args], :classpath=>dependencies }
+      tests.inject([]) do |passed, test|
+        begin
+          Java::Commands.java cmd_args, test, cmd_options
+          passed << test
+        rescue
+          passed
+        end
+      end
+    end
+    
+  end
+
+  # EasyB is a Groovy based BDD framework.
+  # To use in your project:
+  #
+  #   test.using :easyb
+  # 
+  # This framework will search in your project for:
+  #   src/spec/groovy/**/*Story.groovy
+  #   src/spec/groovy/**/*Behavior.groovy
+  #
+  # Support the following options:
+  # * :format -- Report format :txt or :xml, default is :txt
+  # * :properties -- Hash of properties passed to the test suite.
+  # * :java_args -- Arguments passed to the JVM.
+  class EasyB < TestFramework::Base
+    include TestFramework::JavaBDD
+    self.lang = :groovy
+
+    VERSION = "0.7" unless const_defined?(:VERSION)
+    REQUIRES = ["org.easyb:easyb:jar:#{VERSION}",
+                'org.codehaus.groovy:groovy:jar:1.5.3',
+                'asm:asm:jar:2.2.3',
+                'commons-cli:commons-cli:jar:1.0',
+                'antlr:antlr:jar:2.7.7']
+    TESTS_PATTERN = [ /(Story|Behavior).groovy$/ ]
+    OPTIONS = [:format, :properties, :java_args]
+
+    def self.applies_to?(project) #:nodoc:
+      %w{
+        **/*Behaviour.groovy **/*Behavior.groovy **/*Story.groovy
+      }.any? { |glob| !Dir[project.path_to(:source, bdd_dir, lang, glob)].empty? }
+    end
+   
+    def tests(dependencies) #:nodoc:
+      Dir[task.project.path_to(:source, bdd_dir, "groovy/**/*.groovy")].
+        select { |name| TESTS_PATTERN.any? { |pat| pat === name } }
+    end
+
+    def run(tests, dependencies) #:nodoc:
+      options = { :format => :txt }.merge(self.options).only(*OPTIONS)
+      
+      if :txt == options[:format]
+        easyb_format, ext = 'txtstory', '.txt'
+      elsif :xml == options[:format]
+        easyb_format, ext = 'xmlbehavior', '.xml'
+      else
+        raise "Invalid format #{options[:format]} expected one of :txt :xml"
+      end
+      
+      cmd_args = [ 'org.disco.easyb.SpecificationRunner' ]
+      cmd_options = { :properties => options[:properties],
+                      :java_args => options[:java_args],
+                      :classpath => dependencies }
+
+      tests.inject([]) do |passed, test|
+        name = test.sub(/.*?groovy[\/\\]/, '').pathmap('%X')
+        report = File.join(task.report_to.to_s, name + ext)
+        mkpath report.pathmap('%d'), :verbose => false
+        begin
+          Java::Commands.java cmd_args,
+             "-#{easyb_format}", report,
+             test, cmd_options.merge(:name => name)
+        rescue => e
+          passed
+        else
+          passed << test
+        end
+      end
+    end
+    
+  end # EasyB
+
+end
+
+Buildr::TestFramework << Buildr::RSpec
+Buildr::TestFramework << Buildr::JtestR
+Buildr::TestFramework << Buildr::JBehave
+Buildr::TestFramework << Buildr::EasyB

Modified: incubator/buildr/trunk/lib/java/test_frameworks.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/java/test_frameworks.rb?rev=638700&r1=638699&r2=638700&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/java/test_frameworks.rb (original)
+++ incubator/buildr/trunk/lib/java/test_frameworks.rb Tue Mar 18 21:20:20 2008
@@ -21,7 +21,69 @@
 
 module Buildr
 
-  # JMock is available when using JUnit and TestNG.
+  class TestFramework
+    module JavaTest
+
+      # Add buildr utilities (JavaTestFilter) to classpath
+      Java.classpath << File.join(File.dirname(__FILE__))
+
+      def self.included(mod)
+        super
+        mod.extend ClassMethods
+      end
+
+      private
+      # :call-seq:
+      #     filter_classes(dependencies, criteria)
+      # 
+      # Return a list of classnames that match the given criteria. 
+      # The criteria parameter is a hash that must contain at least one of:
+      #
+      # * :class_names -- List of patterns to match against class name
+      # * :interfaces -- List of java interfaces or java classes
+      # * :class_annotations -- List of annotations on class level
+      # * :method_annotations -- List of annotations on method level
+      #
+      def filter_classes(dependencies, criteria = {})
+        return [] unless task.compile.target
+        target = Pathname.new(task.compile.target.to_s)
+        candidates = Dir["#{target}/**/*.class"].
+          map { |file| Pathname.new(file).relative_path_from(target).to_s.ext('').gsub(File::SEPARATOR, '.') }.
+          reject { |name| name =~ /\$/ }
+        result = []
+        if criteria[:class_names]
+          result.concat candidates.select { |name| criteria[:class_names].flatten.any? { |pat| pat === name } }
+        end
+        begin
+          Java.load
+          filter = Java.org.apache.buildr.JavaTestFilter.new(dependencies.to_java(Java.java.lang.String))
+          if criteria[:interfaces]
+            filter.add_interfaces(criteria[:interfaces].to_java(Java.java.lang.String)) 
+          end
+          if criteria[:class_annotations]
+            filter.add_class_annotations(criteria[:class_annotations].to_java(Java.java.lang.String))
+          end
+          if criteria[:method_annotations]
+            filter.add_method_annotations(criteria[:method_annotations].to_java(Java.java.lang.String))
+          end
+          result.concat filter.filter(candidates.to_java(Java.java.lang.String)).map(&:to_s)
+        rescue =>ex
+          puts "#{ex.class}: #{ex.message}" if verbose
+          raise
+        end
+        result.uniq
+      end
+      
+      module ClassMethods
+        def applies_to?(project) #:nodoc:
+          project.test.compile.language == :java
+        end        
+      end
+      
+    end
+  end
+
+  # JMock is available when using JUnit and TestNG, JBehave.
   module JMock
     # JMock version.
     VERSION = '1.2.0' unless const_defined?('VERSION')
@@ -105,44 +167,24 @@
 
     end
 
-
-    # Ant-JUnit requires for JUnit and JUnit reports tasks.  Also requires JavaTestFilter.
-    Java.classpath << "org.apache.ant:ant-junit:jar:#{Ant::VERSION}"
-    Java.classpath << File.join(File.dirname(__FILE__))
-
     # JUnit version number.
     VERSION = '4.3.1' unless const_defined?('VERSION')
-    # JUnit specification.
+    
     REQUIRES = ["junit:junit:jar:#{VERSION}"] + JMock::REQUIRES
 
-    class << self
-
-      def applies_to?(project) #:nodoc:
-        project.test.compile.language == :java
-      end
-
-    end
+    # Ant-JUnit requires for JUnit and JUnit reports tasks.
+    Java.classpath << "org.apache.ant:ant-junit:jar:#{Ant::VERSION}"
 
-    def tests(task, dependencies) #:nodoc:
-      return [] unless task.compile.target
-      target = Pathname.new(task.compile.target.to_s)
-      candidates = Dir["#{target}/**/*.class"].
-        map { |file| Pathname.new(file).relative_path_from(target).to_s.ext('').gsub(File::SEPARATOR, '.') }.
-        reject { |name| name =~ /\$/ }
-      begin
-        Java.load
-        Java.org.apache.buildr.JavaTestFilter.new(dependencies.to_java(Java.java.lang.String)).
-          add_interfaces(['junit.framework.TestCase'].to_java(Java.java.lang.String)).
-          add_class_annotations(['org.junit.Test'].to_java(Java.java.lang.String)).
-          add_method_annotations(['org.junit.Test'].to_java(Java.java.lang.String)).
-          filter(candidates.to_java(Java.java.lang.String)).map(&:to_s)
-      rescue =>ex
-        puts "#{ex.class}: #{ex.message}" if verbose
-        raise
-      end
+    include TestFramework::JavaTest
+    
+    def tests(dependencies) #:nodoc:
+      filter_classes(dependencies, 
+                     :interfaces => %w{junit.framework.TestCase},
+                     :class_annotations => %w{org.junit.Test},
+                     :method_annotations => %w{org.junit.Test})
     end
 
-    def run(tests, task, dependencies) #:nodoc:
+    def run(tests, dependencies) #:nodoc:
       # Use Ant to execute the Junit tasks, gives us performance and reporting.
       Buildr.ant('junit') do |ant|
         case options[:fork]
@@ -211,33 +253,15 @@
     # TestNG specification.
     REQUIRES = ["org.testng:testng:jar:jdk15:#{VERSION}"] + JMock::REQUIRES
 
-    class << self
-
-      def applies_to?(project) #:nodoc:
-        project.test.compile.language == :java
-      end
-
-    end
+    include TestFramework::JavaTest
 
-    def tests(task, dependencies) #:nodoc:
-      return [] unless task.compile.target
-      target = Pathname.new(task.compile.target.to_s)
-      candidates = Dir["#{target}/**/*.class"].
-        map { |file| Pathname.new(file).relative_path_from(target).to_s.ext('').gsub(File::SEPARATOR, '.') }.
-        reject { |name| name =~ /\$/ }
-      begin
-        Java.load
-        Java.org.apache.buildr.JavaTestFilter.new(dependencies.to_java(Java.java.lang.String)).
-          add_class_annotations(['org.testng.annotations.Test'].to_java(Java.java.lang.String)).
-          add_method_annotations(['org.testng.annotations.Test'].to_java(Java.java.lang.String)).
-          filter(candidates.to_java(Java.java.lang.String)).map(&:to_s)
-      rescue =>ex
-        puts "#{ex.class}: #{ex.message}" if verbose
-        raise
-      end
+    def tests(dependencies) #:nodoc:
+      filter_classes(dependencies, 
+                     :class_annotations => %w{org.testng.annotations.Test},
+                     :method_annotations => %w{org.testng.annotations.Test})
     end
 
-    def run(tests, task, dependencies) #:nodoc:
+    def run(tests, dependencies) #:nodoc:
       cmd_args = [ 'org.testng.TestNG', '-sourcedir', task.compile.sources.join(';'), '-suitename', task.send(:project).name ]
       cmd_args << '-d' << task.report_to.to_s
       cmd_options = { :properties=>options[:properties], :java_args=>options[:java_args],

Added: incubator/buildr/trunk/spec/java_bdd_frameworks_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/java_bdd_frameworks_spec.rb?rev=638700&view=auto
==============================================================================
--- incubator/buildr/trunk/spec/java_bdd_frameworks_spec.rb (added)
+++ incubator/buildr/trunk/spec/java_bdd_frameworks_spec.rb Tue Mar 18 21:20:20 2008
@@ -0,0 +1,238 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with this
+# work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+
+require File.join(File.dirname(__FILE__), 'spec_helpers')
+
+describe Buildr::RSpec do
+
+  def foo(*args, &prc)
+    define('foo', *args) do 
+      test.using :rspec
+      if prc
+        instance_eval(&prc)
+      else
+        self
+      end
+    end
+  end
+
+  it 'should be selected by :rspec name' do
+    foo { test.framework.should eql(:rspec) }
+  end
+
+  it 'should include src/spec/ruby/**/*_spec.rb' do
+    foo do 
+      spec = _(:source, :spec, :ruby, 'some_spec.rb')
+      write spec, 'true'
+      test.invoke
+      test.tests.should include(spec)
+    end
+  end
+
+
+end # RSpec
+
+describe Buildr::JtestR do
+
+  def foo(*args, &prc)
+    define('foo', *args) do
+      test.using :jtestr
+      if prc
+        instance_eval(&prc)
+      else
+        self
+      end
+    end
+  end
+
+  it 'should be selected by :jtestr name' do
+    foo { test.framework.should eql(:jtestr) }
+  end
+
+  it 'should include src/spec/ruby/**/*_spec.rb'
+  it 'should auto generate jtestr configuration'
+  it 'should run runit test cases'
+  it 'should use a java compiler if java sources found'
+  it 'should run junit test cases'
+
+end # JtestR
+
+describe Buildr::JBehave do
+  def foo(*args, &prc)
+    define('foo', *args) do 
+      test.using :jbehave
+      if prc
+        instance_eval(&prc)
+      else
+        self
+      end
+    end
+  end
+
+  it 'should apply to projects having JBehave sources' do
+    define('one', :base_dir => 'one') do
+      write _(:source, :spec, :java, 'SomeBehaviour.java'), 'public class SomeBehaviour {}'
+      JBehave.applies_to?(self).should be_true
+    end
+    define('two', :base_dir => 'two') do
+      write _(:source, :test, :java, 'SomeBehaviour.java'), 'public class SomeBehaviour {}'
+      JBehave.applies_to?(self).should be_false
+    end
+    define('three', :base_dir => 'three') do
+      write _(:source, :spec, :java, 'SomeBehavior.java'), 'public class SomeBehavior {}'
+      JBehave.applies_to?(self).should be_true
+    end
+    define('four', :base_dir => 'four') do
+      write _(:source, :test, :java, 'SomeBehavior.java'), 'public class SomeBehavior {}'
+      JBehave.applies_to?(self).should be_false
+    end
+  end
+
+  it 'should be selected by :jbehave name' do
+    foo { test.framework.should eql(:jbehave) }
+  end
+
+  it 'should select a java compiler for its sources' do 
+    foo do
+      write _(:source, :spec, :java, 'SomeBehavior.java'), 'public class SomeBehavior {}'
+      test.compile.language.should eql(:java)
+    end
+  end
+
+  it 'should include JBehave dependencies' do
+    foo do
+      test.compile.dependencies.should include(*artifacts(JBehave::REQUIRES))
+      test.dependencies.should include(*artifacts(JBehave::REQUIRES))
+    end
+  end
+
+  it 'should include JMock dependencies' do
+    foo do
+      test.compile.dependencies.should include(*artifacts(JMock::REQUIRES))
+      test.dependencies.should include(*artifacts(JMock::REQUIRES))
+    end
+  end
+
+  it 'should include classes whose name ends with Behavior' do
+    write 'src/spec/java/some/FooBehavior.java', <<-JAVA
+      package some;
+      public class FooBehavior {
+        public void shouldFoo() { assert true; }
+      }
+    JAVA
+    write 'src/spec/java/some/NotATest.java', <<-JAVA
+      package some;
+      public class NotATest { }
+    JAVA
+    foo.tap do |project|
+      project.test.invoke
+      project.test.tests.should include('some.FooBehavior')
+    end
+  end
+
+
+  it 'should include classes implementing Behaviours' do
+    write 'src/spec/java/some/MyBehaviours.java',  <<-JAVA
+      package some;
+      public class MyBehaviours implements 
+      org.jbehave.core.behaviour.Behaviours {
+        public Class[] getBehaviours() {
+           return new Class[] { some.FooBehave.class };
+        }
+      }
+    JAVA
+    write 'src/spec/java/some/FooBehave.java', <<-JAVA
+      package some;
+      public class FooBehave {
+        public void shouldFoo() { assert true; }
+      }
+    JAVA
+    write 'src/spec/java/some/NotATest.java', <<-JAVA
+      package some;
+      public class NotATest { }
+    JAVA
+    foo.tap do |project|
+      project.test.invoke
+      project.test.tests.should include('some.MyBehaviours')
+    end
+  end
+
+end # JBehave
+
+describe Buildr::EasyB do
+  
+  def foo(*args, &prc)
+    define('foo', *args) do
+      test.using :easyb
+      if prc
+        instance_eval(&prc)
+      else
+        self
+      end
+    end
+  end
+
+  it 'should apply to a project having EasyB sources' do
+    define('one', :base_dir => 'one') do
+      write _(:source, :spec, :groovy, 'SomeBehaviour.groovy'), 'true;'
+      EasyB.applies_to?(self).should be_true
+    end
+    define('two', :base_dir => 'two') do
+      write _(:source, :test, :groovy, 'SomeBehaviour.groovy'), 'true;'
+      EasyB.applies_to?(self).should be_false
+    end
+    define('three', :base_dir => 'three') do
+      write _(:source, :spec, :groovy, 'SomeStory.groovy'), 'true;'
+      EasyB.applies_to?(self).should be_true
+    end
+    define('four', :base_dir => 'four') do
+      write _(:source, :test, :groovy, 'SomeStory.groovy'), 'true;'
+      EasyB.applies_to?(self).should be_false
+    end
+  end
+
+  it 'should be selected by :easyb name' do
+    foo { test.framework.should eql(:easyb) }
+  end
+
+  it 'should select a java compiler if java sources are found' do
+    foo do
+      write _(:source, :spec, :java, 'SomeBehavior.java'), 'public class SomeBehavior {}'
+      test.compile.language.should eql(:java)
+    end
+  end
+  
+  it 'should include src/spec/groovy/*Behavior.groovy' do
+    foo do 
+      spec = _(:source, :spec, :groovy, 'SomeBehavior.groovy')
+      write spec, 'true'
+      test.invoke
+      test.tests.should include(spec)
+    end
+  end
+
+  it 'should include src/spec/groovy/*Story.groovy' do
+    foo do 
+      spec = _(:source, :spec, :groovy, 'SomeStory.groovy')
+      write spec, 'true'
+      test.invoke
+      test.tests.should include(spec)
+    end
+  end
+  
+end # EasyB
+
+