Title: [1571] trunk/core: JBEHAVE-241: Added Guice support.
Revision
1571
Author
mauro
Date
2010-02-19 04:22:24 -0600 (Fri, 19 Feb 2010)

Log Message

JBEHAVE-241:  Added Guice support.

Modified Paths

Added Paths

Diff

Modified: trunk/core/distribution/pom.xml (1570 => 1571)

--- trunk/core/distribution/pom.xml	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/distribution/pom.xml	2010-02-19 10:22:24 UTC (rev 1571)
@@ -29,6 +29,11 @@
     </dependency>
     <dependency>
       <groupId>${pom.groupId}</groupId>
+      <artifactId>jbehave-guice</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
       <artifactId>jbehave-ant</artifactId>
       <version>${pom.version}</version>
     </dependency>
@@ -132,6 +137,26 @@
             </configuration>
           </execution>
           <execution>
+            <id>unpack-javadoc-guice</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/site/javadoc/guice</outputDirectory>
+              <overWriteReleases>false</overWriteReleases>
+              <overWriteSnapshots>true</overWriteSnapshots>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>${pom.groupId}</groupId>
+                  <artifactId>jbehave-guice</artifactId>
+                  <version>${pom.version}</version>
+                  <classifier>javadoc</classifier>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+          <execution>
             <id>unpack-javadoc-ant</id>
             <phase>generate-resources</phase>
             <goals>

Modified: trunk/core/distribution/src/site/content/dependency-injection.html (1570 => 1571)

--- trunk/core/distribution/src/site/content/dependency-injection.html	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/distribution/src/site/content/dependency-injection.html	2010-02-19 10:22:24 UTC (rev 1571)
@@ -20,8 +20,8 @@
 
 <h3>Using PicoContainer</h3>
 
-<p>Steps can be instantiated via PicoContainer using the <a
-    href=""
+<p>Steps can be instantiated via <a href="" using the <a
+    href=""
 (the extension module <b>jbehave-pico</b> needs to be added to the classpath):
 </p>
 
@@ -52,8 +52,8 @@
 
 <h3>Using Spring</h3>
 
-<p>Steps can be instantiated via Spring using the <a
-    href=""
+<p>Steps can be instantiated via <a href="" using the <a
+    href=""
 (the extension module <b>jbehave-spring</b> needs to be added to the classpath):
 </p>
 
@@ -78,6 +78,51 @@
 }
 </pre>
 
+<h3>Using Guice</h3>
+
+<p>Steps can be instantiated via Using <a href="" using the <a
+    href=""
+(the extension module <b>jbehave-guice</b> needs to be added to the classpath):
+</p>
+
+<pre class="brush: java">
+public class GuiceTraderScenario extends TraderScenario {
+
+    public GuiceTraderScenario(Class scenarioClass) {
+        super(scenarioClass);
+    }
+
+    @Override
+    protected CandidateSteps[] createSteps(StepsConfiguration configuration) {
+        Injector parent = createInjector();
+        return new GuiceStepsFactory(configuration, parent).createCandidateSteps();
+    }
+
+    private Injector createInjector() {
+        Injector parent = Guice.createInjector(new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(TradingService.class).in(Scopes.SINGLETON);
+              bind(GuiceTraderSteps.class).in(Scopes.SINGLETON);
+              bind(BeforeAfterSteps.class).in(Scopes.SINGLETON);
+            }
+          });
+        return parent;
+    }
+    
+}
+</pre>
+where the <b>GuiceTraderSteps</b> is appropriately Guice-annotated:
+<pre class="brush: java">
+public class GuiceTraderSteps extends TraderSteps {
+
+    @Inject
+    public GuiceTraderSteps(TradingService service) {
+        super(service);
+    }
+
+}
+</pre>
 <div class="clear">
 <hr />
 </div>

Modified: trunk/core/distribution/src/site/content/download.html (1570 => 1571)

--- trunk/core/distribution/src/site/content/download.html	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/distribution/src/site/content/download.html	2010-02-19 10:22:24 UTC (rev 1571)
@@ -49,7 +49,7 @@
 <script type="syntaxhighlighter" class="brush: xml"><![CDATA[
   <dependency> 
     <groupId>org.jbehave</groupId>
-    <artifactId>jbehave-[pico|spring]</artifactId>
+    <artifactId>jbehave-[pico|spring|guice]</artifactId>
     <version>[version]</version>
   </dependency>
 ]]></script>

Modified: trunk/core/distribution/src/site/content/javadoc.html (1570 => 1571)

--- trunk/core/distribution/src/site/content/javadoc.html	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/distribution/src/site/content/javadoc.html	2010-02-19 10:22:24 UTC (rev 1571)
@@ -17,6 +17,8 @@
 
 <p><a href="" Spring</a> adds support for dependency injection using <a href="" Framework</a></p>
 
+<p><a href="" Guice</a> adds support for dependency injection using <a href=""
+
 <h2>JBehave Plugins</h2>
 
 <p><a href="" Ant</a> contains the Ant task to run JBehave scenarios.</p>

Modified: trunk/core/examples/trader/pom.xml (1570 => 1571)

--- trunk/core/examples/trader/pom.xml	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/examples/trader/pom.xml	2010-02-19 10:22:24 UTC (rev 1571)
@@ -20,6 +20,11 @@
       <artifactId>jbehave-spring</artifactId>
       <version>${jbehave.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.jbehave</groupId>
+      <artifactId>jbehave-guice</artifactId>
+      <version>${jbehave.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <resources>

Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/GuiceTraderScenario.java (0 => 1571)

--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/GuiceTraderScenario.java	                        (rev 0)
+++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/GuiceTraderScenario.java	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,40 @@
+package org.jbehave.examples.trader.guice;
+
+import org.jbehave.examples.trader.BeforeAfterSteps;
+import org.jbehave.examples.trader.TraderScenario;
+import org.jbehave.examples.trader.service.TradingService;
+import org.jbehave.scenario.RunnableScenario;
+import org.jbehave.scenario.steps.CandidateSteps;
+import org.jbehave.scenario.steps.StepsConfiguration;
+import org.jbehave.scenario.steps.guice.GuiceStepsFactory;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Scopes;
+
+public class GuiceTraderScenario extends TraderScenario {
+
+    public GuiceTraderScenario(Class<? extends RunnableScenario> scenarioClass) {
+        super(scenarioClass);
+    }
+
+    @Override
+    protected CandidateSteps[] createSteps(StepsConfiguration configuration) {
+        Injector parent = createInjector();
+        return new GuiceStepsFactory(configuration, parent).createCandidateSteps();
+    }
+
+    private Injector createInjector() {
+        Injector parent = Guice.createInjector(new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(TradingService.class).in(Scopes.SINGLETON);
+              bind(GuiceTraderSteps.class).in(Scopes.SINGLETON);
+              bind(BeforeAfterSteps.class).in(Scopes.SINGLETON);
+            }
+          });
+        return parent;
+    }
+    
+}

Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/GuiceTraderSteps.java (0 => 1571)

--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/GuiceTraderSteps.java	                        (rev 0)
+++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/GuiceTraderSteps.java	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,18 @@
+package org.jbehave.examples.trader.guice;
+
+import org.jbehave.examples.trader.TraderSteps;
+import org.jbehave.examples.trader.service.TradingService;
+
+import com.google.inject.Inject;
+
+/**
+ * POJO annotated to allow Guice injection.
+ */
+public class GuiceTraderSteps extends TraderSteps {
+
+    @Inject
+    public GuiceTraderSteps(TradingService service) {
+        super(service);
+    }
+
+}

Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/scenarios/WildcardSearch.java (0 => 1571)

--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/scenarios/WildcardSearch.java	                        (rev 0)
+++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/scenarios/WildcardSearch.java	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,11 @@
+package org.jbehave.examples.trader.guice.scenarios;
+
+import org.jbehave.examples.trader.guice.GuiceTraderScenario;
+
+public class WildcardSearch extends GuiceTraderScenario {
+
+    public WildcardSearch() {
+        super(WildcardSearch.class);
+    }
+    
+}

Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/scenarios/wildcard_search.scenario (0 => 1571)

--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/scenarios/wildcard_search.scenario	                        (rev 0)
+++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/guice/scenarios/wildcard_search.scenario	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,19 @@
+Scenario: Traders can be searched by name.   This is the same scenario as
+org.jbehave.examples.trader.scenarios.wildcard_search, with the only difference that
+the candidate steps class (TraderSteps) is created, with it dependency, via a PicoContainer.
+
+Given the traders: 
+|name|rank|
+|Larry|Stooge 3|
+|Moe|Stooge 1|
+|Curly|Stooge 2|
+!-- This is a comment, which will be ignored in the execution
+When a wildcard search ".*y" is executed
+!-- This is another comment, also ignored, 
+but look Ma! I'm on a new line!
+Then the traders returned are:
+|name|rank|
+|Larry|Stooge 3|
+|Curly|Stooge 2|
+
+

Modified: trunk/core/examples/trader-test-scope/pom.xml (1570 => 1571)

--- trunk/core/examples/trader-test-scope/pom.xml	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/examples/trader-test-scope/pom.xml	2010-02-19 10:22:24 UTC (rev 1571)
@@ -20,6 +20,11 @@
       <artifactId>jbehave-spring</artifactId>
       <version>${jbehave.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.jbehave</groupId>
+      <artifactId>jbehave-guice</artifactId>
+      <version>${jbehave.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <!-- JBEHAVE-155: we can run scenarios in test scope -->

Property changes: trunk/core/jbehave-guice

Name: svn:ignore
   + target

Added: trunk/core/jbehave-guice/pom.xml (0 => 1571)

--- trunk/core/jbehave-guice/pom.xml	                        (rev 0)
+++ trunk/core/jbehave-guice/pom.xml	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,26 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.jbehave</groupId>
+    <artifactId>jbehave</artifactId>
+    <version>2.5-SNAPSHOT</version>
+  </parent>
+  <artifactId>jbehave-guice</artifactId>
+  <name>JBehave Guice</name>
+  <description>Extension of JBehave Core that allows CandidateSteps instances to be composed using Guice</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.jbehave</groupId>
+      <artifactId>jbehave-core</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.inject</groupId>
+      <artifactId>guice</artifactId>
+      <version>2.0</version>
+    </dependency>
+  </dependencies>
+
+</project>

Added: trunk/core/jbehave-guice/src/behaviour/java/org/jbehave/scenario/steps/guice/GuiceStepsFactoryBehaviour.java (0 => 1571)

--- trunk/core/jbehave-guice/src/behaviour/java/org/jbehave/scenario/steps/guice/GuiceStepsFactoryBehaviour.java	                        (rev 0)
+++ trunk/core/jbehave-guice/src/behaviour/java/org/jbehave/scenario/steps/guice/GuiceStepsFactoryBehaviour.java	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,107 @@
+package org.jbehave.scenario.steps.guice;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+
+import org.jbehave.scenario.annotations.Given;
+import org.jbehave.scenario.steps.CandidateSteps;
+import org.jbehave.scenario.steps.Steps;
+import org.jbehave.scenario.steps.StepsConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.CreationException;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Scopes;
+
+public class GuiceStepsFactoryBehaviour {
+
+    private static Field stepsInstance;
+
+    @Before
+    public void setUp() throws NoSuchFieldException {
+        stepsInstance = Steps.class.getDeclaredField("instance");
+        stepsInstance.setAccessible(true);
+    }
+
+    @Test
+    public void ensureThatStepsCanBeCreated() throws NoSuchFieldException, IllegalAccessException {
+        // Given
+        Injector parent = Guice.createInjector(new AbstractModule() {
+            @Override
+            protected void configure() {              
+                bind(FooSteps.class).in(Scopes.SINGLETON);
+            }
+          });
+
+        GuiceStepsFactory factory = new GuiceStepsFactory(new StepsConfiguration(), parent);
+        // When
+        CandidateSteps[] steps = factory.createCandidateSteps();
+        // Then 
+        assertFooStepsFound(steps);
+    }
+
+
+    @Test
+    public void ensureThatStepsWithStepsWithDependencyCanBeCreated() throws NoSuchFieldException, IllegalAccessException {
+        Injector parent = Guice.createInjector(new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(Integer.class).toInstance(42);
+              bind(FooStepsWithDependency.class).in(Scopes.SINGLETON);
+            }
+          });
+
+        // When
+        GuiceStepsFactory factory = new GuiceStepsFactory(new StepsConfiguration(), parent);
+        CandidateSteps[] steps = factory.createCandidateSteps();
+        // Then
+        assertFooStepsFound(steps);
+        assertEquals(42, (int) ((FooStepsWithDependency) stepsInstance.get(steps[0])).integer);
+    }
+
+    private void assertFooStepsFound(CandidateSteps[] steps) throws NoSuchFieldException, IllegalAccessException {
+        assertEquals(1, steps.length);
+        assertTrue(steps[0] instanceof CandidateSteps);
+        Object instance = stepsInstance.get(steps[0]);
+        assertTrue(instance instanceof FooSteps);
+    }
+
+
+    @Test(expected=CreationException.class)
+    public void ensureThatStepsWithMissingDependenciesCannotBeCreated() throws NoSuchFieldException, IllegalAccessException {
+        Injector parent = Guice.createInjector(new AbstractModule() {
+            @Override
+            protected void configure() {
+              bind(FooStepsWithDependency.class);
+            }
+          });
+        GuiceStepsFactory factory = new GuiceStepsFactory(new StepsConfiguration(), parent);
+        // When
+        factory.createCandidateSteps();
+        // Then ... expected exception is thrown        
+    }
+
+    public static class FooSteps {
+
+        @Given("a step with a $param")
+        public void aStepWithAParam(String param) {
+        }
+
+    }
+
+    public static class FooStepsWithDependency extends FooSteps {
+        private final Integer integer;
+
+        @Inject
+        public FooStepsWithDependency(Integer steps) {
+            this.integer = steps;
+        }
+
+    }
+}

Added: trunk/core/jbehave-guice/src/main/java/org/jbehave/scenario/steps/guice/GuiceStepsFactory.java (0 => 1571)

--- trunk/core/jbehave-guice/src/main/java/org/jbehave/scenario/steps/guice/GuiceStepsFactory.java	                        (rev 0)
+++ trunk/core/jbehave-guice/src/main/java/org/jbehave/scenario/steps/guice/GuiceStepsFactory.java	2010-02-19 10:22:24 UTC (rev 1571)
@@ -0,0 +1,59 @@
+package org.jbehave.scenario.steps.guice;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jbehave.scenario.steps.CandidateSteps;
+import org.jbehave.scenario.steps.Steps;
+import org.jbehave.scenario.steps.StepsConfiguration;
+
+import com.google.inject.Binding;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+
+/**
+ * A factory class for {...@link CandidateSteps} that uses an {...@link Injector}
+ * for the composition and instantiation of all components that contains
+ * scenario annotated methods.
+ * 
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class GuiceStepsFactory {
+
+    private final StepsConfiguration configuration;
+    private final Injector parent;
+
+    public GuiceStepsFactory(StepsConfiguration configuration, Injector parent) {
+        this.configuration = configuration;
+        this.parent = parent;
+    }
+
+    public CandidateSteps[] createCandidateSteps() {
+        List<Steps> steps = new ArrayList<Steps>();
+        for (Binding<?> binding : parent.getBindings().values()) {
+            Key<?> key = binding.getKey();
+            if (containsScenarioAnnotations(key.getTypeLiteral().getType())) {
+                steps.add(new Steps(configuration, parent.getInstance(key)));
+            }
+        }
+        return steps.toArray(new CandidateSteps[steps.size()]);
+    }
+
+    private boolean containsScenarioAnnotations(Type type) {
+        if ( type instanceof Class<?> ){
+            for (Method method : ((Class<?>)type).getMethods()) {
+                for (Annotation annotation : method.getAnnotations()) {
+                    if (annotation.annotationType().getName().startsWith("org.jbehave.scenario.annotations")) {
+                        return true;
+                    }
+                }
+            }            
+        }
+        return false;
+    }
+
+}

Modified: trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java (1570 => 1571)

--- trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java	2010-02-19 10:22:24 UTC (rev 1571)
@@ -15,6 +15,7 @@
  * {...@link ListableBeanFactory} for the composition and instantiation of all
  * components that contains scenario annotated methods.
  * 
+ * @author Paul Hammant
  * @author Mauro Talevi
  */
 public class SpringStepsFactory {

Modified: trunk/core/pom.xml (1570 => 1571)

--- trunk/core/pom.xml	2010-02-13 12:45:05 UTC (rev 1570)
+++ trunk/core/pom.xml	2010-02-19 10:22:24 UTC (rev 1571)
@@ -16,6 +16,7 @@
     <module>jbehave-maven-plugin</module>
     <module>jbehave-pico</module>
     <module>jbehave-spring</module>
+    <module>jbehave-guice</module>
   </modules>
 
   <dependencyManagement>


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to