Title: [975] trunk: [Liz] All the before/after scenario stuff now works.
Revision
975
Author
sirenian
Date
2008-10-16 05:10:08 -0500 (Thu, 16 Oct 2008)

Log Message

[Liz] All the before/after scenario stuff now works. NB: Ant build is broken and probably has been for some versions; SpringContainerBehaviour also not working due to library dependencies. Dan and I are about to Ivy this build so it should be fixed within a day or so.

Modified Paths

Added Paths

Property Changed

  • trunk/

Diff

Property changes: trunk

Name: svn:ignore
   - spike
bin
jbehave.iml
classes
delete_me
dist
workspace
jbehave.iws
build
target-eclipse
target
.classpath
.project
working
   + spike
bin
jbehave.iml
classes
delete_me
dist
workspace
jbehave.iws
build
target-eclipse
target
.classpath
.project
working
.hg

Added: trunk/.hgignore (0 => 975)

--- trunk/.hgignore	                        (rev 0)
+++ trunk/.hgignore	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,5 @@
+syntax: regexp
+^bin
+^working
+.DS_Store
+.svn

Modified: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/PlayersCanHazTurns.java (974 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/PlayersCanHazTurns.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/PlayersCanHazTurns.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -7,7 +7,9 @@
 import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
 import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;
 
+import com.lunivore.noughtsandcrosses.steps.BeforeAndAfterSteps;
 import com.lunivore.noughtsandcrosses.steps.LolCatzSteps;
+import com.lunivore.noughtsandcrosses.util.OAndXUniverse;
 
 /**
  * Checks that we can support scenarios written in other languages,
@@ -20,6 +22,10 @@
     }
 
     public PlayersCanHazTurns(final ClassLoader classLoader) {
+    	this(classLoader, new OAndXUniverse());
+    }
+    
+    public PlayersCanHazTurns(final ClassLoader classLoader, OAndXUniverse universe) {
         super(new MostUsefulConfiguration() {
             public KeyWords keywords() {
                 return new KeyWords("I can haz", "Gief", "Wen", "Den", "And");
@@ -28,7 +34,7 @@
                 return new ClasspathScenarioDefiner(new UnderscoredCamelCaseResolver(), new PatternScenarioParser(this),
                         classLoader);
             }
-        }, new LolCatzSteps());
+        }, new LolCatzSteps(universe), new BeforeAndAfterSteps(universe));
     }
     
 }

Modified: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/PlayersCanTakeTurns.java (974 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/PlayersCanTakeTurns.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/PlayersCanTakeTurns.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,25 +1,15 @@
 package com.lunivore.noughtsandcrosses;
 
-import org.jbehave.scenario.MostUsefulConfiguration;
-import org.jbehave.scenario.JUnitScenario;
-import org.jbehave.scenario.parser.PatternScenarioParser;
-import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
-import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;
+import com.lunivore.noughtsandcrosses.util.NoughtsAndCrossesScenario;
 
-import com.lunivore.noughtsandcrosses.steps.GridSteps;
+public class PlayersCanTakeTurns extends NoughtsAndCrossesScenario {
 
-public class PlayersCanTakeTurns extends JUnitScenario {
-
     public PlayersCanTakeTurns() {
-        this(Thread.currentThread().getContextClassLoader());
+        super(Thread.currentThread().getContextClassLoader());
     }
-
-    public PlayersCanTakeTurns(final ClassLoader classLoader) {
-        super(new MostUsefulConfiguration() {
-            public ClasspathScenarioDefiner forDefiningScenarios() {
-                return new ClasspathScenarioDefiner(new UnderscoredCamelCaseResolver(), new PatternScenarioParser(this),
-                        classLoader);
-            }
-        }, new GridSteps());
+    
+    public PlayersCanTakeTurns(ClassLoader classLoader) {
+        super(classLoader);
     }
+
 }

Modified: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/TheGridStartsEmpty.java (974 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/TheGridStartsEmpty.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/TheGridStartsEmpty.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,26 +1,15 @@
 package com.lunivore.noughtsandcrosses;
 
-import org.jbehave.scenario.PropertyBasedConfiguration;
-import org.jbehave.scenario.JUnitScenario;
-import org.jbehave.scenario.parser.PatternScenarioParser;
-import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
-import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;
+import com.lunivore.noughtsandcrosses.util.NoughtsAndCrossesScenario;
 
-import com.lunivore.noughtsandcrosses.steps.GridSteps;
-
-public class TheGridStartsEmpty extends JUnitScenario {
-
+public class TheGridStartsEmpty extends NoughtsAndCrossesScenario {
+    
     public TheGridStartsEmpty() {
         this(Thread.currentThread().getContextClassLoader());
     }
 
-    public TheGridStartsEmpty(final ClassLoader classLoader) {
-        super(new PropertyBasedConfiguration() {
-            @Override
-            public ClasspathScenarioDefiner forDefiningScenarios() {
-                return new ClasspathScenarioDefiner(new UnderscoredCamelCaseResolver(), new PatternScenarioParser(this),
-                        classLoader);
-            }
-        }, new GridSteps());
+    public TheGridStartsEmpty(ClassLoader classLoader) {
+        super(classLoader);
     }
+
 }

Modified: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/ThreeInARowWins.java (974 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/ThreeInARowWins.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/ThreeInARowWins.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,26 +1,15 @@
 package com.lunivore.noughtsandcrosses;
 
-import org.jbehave.scenario.PropertyBasedConfiguration;
-import org.jbehave.scenario.JUnitScenario;
-import org.jbehave.scenario.parser.PatternScenarioParser;
-import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
-import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;
+import com.lunivore.noughtsandcrosses.util.NoughtsAndCrossesScenario;
 
-import com.lunivore.noughtsandcrosses.steps.GridSteps;
+public class ThreeInARowWins extends NoughtsAndCrossesScenario {
 
-public class ThreeInARowWins extends JUnitScenario {
-
     public ThreeInARowWins() {
         this(Thread.currentThread().getContextClassLoader());
     }
-
-    public ThreeInARowWins(final ClassLoader classLoader) {
-        super(new PropertyBasedConfiguration() {
-            @Override
-            public ClasspathScenarioDefiner forDefiningScenarios() {
-                return new ClasspathScenarioDefiner(new UnderscoredCamelCaseResolver(), new PatternScenarioParser(this),
-                        classLoader);
-            }
-        }, new GridSteps());
+    
+    public ThreeInARowWins(ClassLoader classLoader) {
+        super(classLoader);
     }
+
 }

Added: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/BeforeAndAfterSteps.java (0 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/BeforeAndAfterSteps.java	                        (rev 0)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/BeforeAndAfterSteps.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,26 @@
+package com.lunivore.noughtsandcrosses.steps;
+
+import org.jbehave.scenario.annotations.AfterScenario;
+import org.jbehave.scenario.annotations.BeforeScenario;
+import org.jbehave.scenario.steps.Steps;
+
+import com.lunivore.noughtsandcrosses.util.OAndXUniverse;
+
+public class BeforeAndAfterSteps extends Steps {
+
+    private final OAndXUniverse universe;
+
+    public BeforeAndAfterSteps(OAndXUniverse universe) {
+        this.universe = universe;
+    }
+
+    @BeforeScenario
+    public void runThisBeforeScenarios() throws Exception {
+    	universe.reset();
+    }
+    
+    @AfterScenario
+    public void runThisAfterScenarios() throws Exception {
+    	universe.destroy();
+    }
+}

Modified: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/GridSteps.java (974 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/GridSteps.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/GridSteps.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -14,9 +14,9 @@
 import org.jbehave.scenario.annotations.Then;
 import org.jbehave.scenario.annotations.When;
 import org.jbehave.scenario.steps.Steps;
-import org.lunivore.tyburn.WindowControl;
 
 import com.lunivore.noughtsandcrosses.NoughtsAndCrosses;
+import com.lunivore.noughtsandcrosses.util.OAndXUniverse;
 import com.lunivore.noughtsandcrosses.view.ComponentNames;
 
 public class GridSteps extends Steps {
@@ -24,11 +24,18 @@
     public static String ROWS = "abc";
     public static String COLUMNS = "123";
     protected static final String NL = System.getProperty("line.separator");
-    protected WindowControl windowControl;
+	private final OAndXUniverse universe;
 
+    public GridSteps() {
+        this(new OAndXUniverse());
+    }
+    
+    public GridSteps(OAndXUniverse universe) {
+		this.universe = universe;
+    }
+
     @Given("the game is running")
     public void givenTheGameIsRunning() {
-        windowControl = new WindowControl(ComponentNames.NOUGHTSANDCROSSES);
         new NoughtsAndCrosses();
     }
     
@@ -44,19 +51,19 @@
     
     @Then("the message should read \"$message\"")
     public void thenTheMessageShouldRead(String message) throws Exception {
-        JLabel messageLabel = (JLabel) windowControl.findComponent(ComponentNames.MESSAGE);
+        JLabel messageLabel = (JLabel) universe.getControl().findComponent(ComponentNames.MESSAGE);
         ensureThat(messageLabel.getText(), equalTo(message));
     }
 
     @Then("the grid should look like $grid")
     public void thenTheGridShouldLookLike(String grid) throws Exception {
-        Component gridPanel = windowControl.findComponent(ComponentNames.GRID);
+        Component gridPanel = universe.getControl().findComponent(ComponentNames.GRID);
         ensureThat(gridPanel.toString(), equalTo(grid));
     }
 
     @When("the player clicks $space")
     public void whenPlayerClicksInSpace(String space) throws Exception {
-        windowControl.clickButton(space);
+    	universe.getControl().clickButton(space);
     }
     
     private void performMoves(List<String> oTurns, List<String> xTurns) throws Exception {

Modified: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/LolCatzSteps.java (974 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/LolCatzSteps.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/steps/LolCatzSteps.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -14,24 +14,28 @@
 import org.jbehave.scenario.annotations.Then;
 import org.jbehave.scenario.annotations.When;
 import org.jbehave.scenario.steps.Steps;
-import org.lunivore.tyburn.WindowControl;
 
 import com.lunivore.noughtsandcrosses.NoughtsAndCrosses;
+import com.lunivore.noughtsandcrosses.util.OAndXUniverse;
 import com.lunivore.noughtsandcrosses.view.ComponentNames;
 
 public class LolCatzSteps extends Steps {
     public static String ROWS = "abc";
     public static String COLUMNS = "123";
     protected static final String NL = System.getProperty("line.separator");
-    protected WindowControl windowControl;
+	private final OAndXUniverse universe;
 
     public LolCatzSteps() {
-        super("Gief", "Wen", "Den", "And");
+    	this(new OAndXUniverse());
     }
     
-    @Given("game")
+    public LolCatzSteps(OAndXUniverse universe) {
+    	super("Gief", "Wen", "Den", "And");
+		this.universe = universe;
+	}
+
+	@Given("game")
     public void givenTheGameIsRunning() {
-        windowControl = new WindowControl(ComponentNames.NOUGHTSANDCROSSES);
         new NoughtsAndCrosses();
     }
     
@@ -47,19 +51,19 @@
     
     @Then("message sez \"$message\"")
     public void thenTheMessageShouldRead(String message) throws Exception {
-        JLabel messageLabel = (JLabel) windowControl.findComponent(ComponentNames.MESSAGE);
+        JLabel messageLabel = (JLabel) universe.getControl().findComponent(ComponentNames.MESSAGE);
         ensureThat(messageLabel.getText(), equalTo(message));
     }
 
     @Then("I haz grid $grid")
     public void thenTheGridShouldLookLike(String grid) throws Exception {
-        Component gridPanel = windowControl.findComponent(ComponentNames.GRID);
+        Component gridPanel = universe.getControl().findComponent(ComponentNames.GRID);
         ensureThat(gridPanel.toString(), equalTo(grid));
     }
 
     @When("I clicks $space")
     public void whenPlayerClicksInSpace(String space) throws Exception {
-        windowControl.clickButton(space);
+    	universe.getControl().clickButton(space);
     }
     
     private void performMoves(List<String> oTurns, List<String> xTurns) throws Exception {

Added: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/util/NoughtsAndCrossesScenario.java (0 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/util/NoughtsAndCrossesScenario.java	                        (rev 0)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/util/NoughtsAndCrossesScenario.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,31 @@
+package com.lunivore.noughtsandcrosses.util;
+
+import org.jbehave.scenario.PropertyBasedConfiguration;
+import org.jbehave.scenario.Scenario;
+import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
+import org.jbehave.scenario.parser.PatternScenarioParser;
+import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;
+
+import com.lunivore.noughtsandcrosses.steps.BeforeAndAfterSteps;
+import com.lunivore.noughtsandcrosses.steps.GridSteps;
+
+public abstract class NoughtsAndCrossesScenario extends Scenario {
+
+	/**
+	 * The only reason this classLoader is here is to support Maven.
+	 */
+	public NoughtsAndCrossesScenario(final ClassLoader classLoader) {
+		this(classLoader, new OAndXUniverse());
+	}
+	
+	public NoughtsAndCrossesScenario(final ClassLoader classLoader, OAndXUniverse universe) {
+        super(new PropertyBasedConfiguration() {
+            @Override
+            public ClasspathScenarioDefiner forDefiningScenarios() {
+                return new ClasspathScenarioDefiner(new UnderscoredCamelCaseResolver(), new PatternScenarioParser(this),
+                        classLoader);
+            }
+        }, new GridSteps(universe), new BeforeAndAfterSteps(universe));
+     }
+
+}

Added: trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/util/OAndXUniverse.java (0 => 975)

--- trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/util/OAndXUniverse.java	                        (rev 0)
+++ trunk/examples/noughtsandcrosses/src/scenario/com/lunivore/noughtsandcrosses/util/OAndXUniverse.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,27 @@
+package com.lunivore.noughtsandcrosses.util;
+
+import org.lunivore.tyburn.WindowControl;
+
+import com.lunivore.noughtsandcrosses.view.ComponentNames;
+
+
+public class OAndXUniverse {
+
+	private WindowControl windowControl;
+
+	public OAndXUniverse() {
+		windowControl = new WindowControl(ComponentNames.NOUGHTSANDCROSSES);
+	}
+
+	public WindowControl getControl() {
+		return windowControl;
+	}
+
+	public void reset() throws Exception {
+		windowControl = new WindowControl(ComponentNames.NOUGHTSANDCROSSES);
+	}
+
+	public void destroy() throws Exception {
+		windowControl.closeWindow(); 
+	}
+}

Modified: trunk/jbehave-core/src/behaviour/org/jbehave/scenario/ScenarioRunnerBehaviour.java (974 => 975)

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/ScenarioRunnerBehaviour.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/ScenarioRunnerBehaviour.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -204,7 +204,6 @@
         
         verify(strategy).handleError(pendingResult.getThrowable());
     }
-
     
     private Configuration configurationWithPendingStrategy(StepCreator creator,
             ScenarioReporter reporter, PendingErrorStrategy strategy) {

Modified: trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/StepsBehaviour.java (974 => 975)

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/StepsBehaviour.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/StepsBehaviour.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -3,6 +3,8 @@
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.jbehave.util.JUnit4Ensure.ensureThat;
 
+import java.util.List;
+
 import org.junit.Test;
 
 public class StepsBehaviour {
@@ -20,15 +22,62 @@
         ensureThat(steps.given);
         ensureThat(steps.when);
         ensureThat(steps.then);
-        
     }
     
+    @Test
+    public void shouldProvideStepsToBePerformedBeforeScenarios() {
+    	MySteps steps = new MySteps();
+    	List<Step> executableSteps = steps.runBeforeScenario();
+		ensureThat(executableSteps.size(), equalTo(1));
+		
+    	executableSteps.get(0).perform();
+    	ensureThat(steps.before);
+    }
+    
+    @Test
+    public void shouldProvideStepsToBePerformedAfterScenarios() {
+    	MySteps steps = new MySteps();
+    	List<Step> executableSteps = steps.runAfterScenario();
+    	ensureThat(executableSteps.size(), equalTo(3));
+    	
+    	executableSteps.get(0).perform();
+    	ensureThat(steps.afterAll);
+    	
+    	executableSteps.get(1).perform();
+    	ensureThat(steps.afterSuccess);
+    	
+    	executableSteps.get(2).doNotPerform();
+    	ensureThat(steps.afterUnsuccess);
+    }
+    
+    @Test
+    public void shouldIgnoreSuccessfulStepsWhichArePerformedInUnsuccessfulScenarioOrViceVersa() {
+    	MySteps steps = new MySteps();
+    	List<Step> executableSteps = steps.runAfterScenario();
+    	
+    	executableSteps.get(0).doNotPerform();
+    	ensureThat(steps.afterAll); // @AfterScenario can be run after all scenarios
+    	
+		executableSteps.get(1).doNotPerform();
+		ensureThat(!steps.afterSuccess);
+		
+		
+		executableSteps.get(2).perform();
+		ensureThat(!steps.afterUnsuccess);
+	
+    }
+    
     public static class MySteps extends Steps {
         
         private boolean given;
         private boolean when;
         private boolean then;
-
+        
+        private boolean before;
+        private boolean afterAll;
+        private boolean afterSuccess;
+        private boolean afterUnsuccess;
+        
         @org.jbehave.scenario.annotations.Given("a given")
         public void given() {
             given = true;
@@ -43,5 +92,27 @@
         public void then() {
             then = true;
         }
+        
+        @org.jbehave.scenario.annotations.BeforeScenario
+        public void beforeScenarios() {
+        	before = true;
+        }
+        
+        @org.jbehave.scenario.annotations.AfterScenario
+        public void afterAllScenarios() {
+        	afterAll = true;
+        }
+        
+        @org.jbehave.scenario.annotations.AfterSuccessfulScenario
+        public void afterSuccessfulScenarios() {
+        	afterSuccess = true;
+        }
+        
+        @org.jbehave.scenario.annotations.AfterUnsuccessfulScenario
+        public void afterUnsuccessfulScenarios() {
+        	afterUnsuccess = true;
+        }
+        
+        
     }
 }

Modified: trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/UnmatchedToPendingStepCreatorBehaviour.java (974 => 975)

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/UnmatchedToPendingStepCreatorBehaviour.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/UnmatchedToPendingStepCreatorBehaviour.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,10 +1,13 @@
 package org.jbehave.scenario.steps;
 
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.collection.IsArray.array;
 import static org.jbehave.util.JUnit4Ensure.ensureThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.stub;
 
+import java.util.Arrays;
+
 import org.jbehave.scenario.definition.ScenarioDefinition;
 import org.junit.Test;
 
@@ -38,10 +41,8 @@
         
         CandidateStep candidate = mock(CandidateStep.class);
         CandidateSteps steps = mock(Steps.class);
-        Step executableStep = mock(Step.class);
         
         stub(candidate.matches("my step")).toReturn(false);
-        stub(candidate.createFrom("my step")).toReturn(executableStep);
         stub(steps.getSteps()).toReturn(new CandidateStep[] {candidate});
         
         // When
@@ -52,4 +53,38 @@
         StepResult result = executableSteps[0].perform();
         ensureThat(result.getThrowable().getMessage(), equalTo("Pending: my step"));
     }
+    
+    @SuppressWarnings("unchecked")
+	@Test
+    public void shouldPrependBeforeScenarioAndAppendAfterScenarioAnnotatedSteps() {
+    	//Given some steps classes which run different steps before and after scenarios
+    	Steps steps1 = mock(Steps.class);
+    	Steps steps2 = mock(Steps.class);
+    	Step stepBefore1 = mock(Step.class);
+    	Step stepBefore2 = mock(Step.class);
+    	Step stepAfter1 = mock(Step.class);
+    	Step stepAfter2 = mock(Step.class);
+
+    	stub(steps1.runBeforeScenario()).toReturn(Arrays.asList(stepBefore1));
+    	stub(steps2.runBeforeScenario()).toReturn(Arrays.asList(stepBefore2));
+    	stub(steps1.runAfterScenario()).toReturn(Arrays.asList(stepAfter1));
+    	stub(steps2.runAfterScenario()).toReturn(Arrays.asList(stepAfter2));
+
+    	// And which have a 'normal' step that matches our scenario
+        CandidateStep candidate = mock(CandidateStep.class);
+        Step normalStep = mock(Step.class);
+        
+        stub(candidate.matches("my step")).toReturn(true);
+        stub(candidate.createFrom("my step")).toReturn(normalStep);
+        stub(steps1.getSteps()).toReturn(new CandidateStep[] {candidate});
+        stub(steps2.getSteps()).toReturn(new CandidateStep[] {});
+    	
+        // When we create the series of steps for the scenario
+    	UnmatchedToPendingStepCreator creator = new UnmatchedToPendingStepCreator();
+    	Step[] executableSteps = creator.createStepsFrom(new ScenarioDefinition("", "my step"), steps1, steps2);
+    	
+    	// Then all before and after steps should be added
+    	ensureThat(executableSteps, array(equalTo(stepBefore2), equalTo(stepBefore1), equalTo(normalStep), equalTo(stepAfter1), equalTo(stepAfter2)));
+    }
+
 }

Added: trunk/jbehave-core/src/java/org/jbehave/Ensure.java (0 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/Ensure.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/Ensure.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,7 @@
+package org.jbehave;
+
+import org.jbehave.util.JUnit4Ensure;
+
+public class Ensure extends JUnit4Ensure {
+
+}

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/ScenarioRunner.java (974 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/ScenarioRunner.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/ScenarioRunner.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -37,19 +37,23 @@
         
         reporter.beforeStory(story.getBlurb());
         for (ScenarioDefinition scenario : story.getScenarios()) {
-            Step[] steps = configuration.forCreatingSteps().createStepsFrom(scenario, candidateSteps);
-            reporter.beforeScenario(scenario.getTitle());
-            state = new FineSoFar();
-            for (Step step : steps) {
-                state.run(step);
-            }
-            reporter.afterScenario();
-            
+            runScenario(configuration, scenario, candidateSteps);
         }
         reporter.afterStory();
         currentStrategy.handleError(throwable);
-    };
+    }
 
+	private void runScenario(Configuration configuration,
+			ScenarioDefinition scenario, CandidateSteps... candidateSteps) {
+		Step[] steps = configuration.forCreatingSteps().createStepsFrom(scenario, candidateSteps);
+		reporter.beforeScenario(scenario.getTitle());
+		state = new FineSoFar();
+		for (Step step : steps) {
+		    state.run(step);
+		}
+		reporter.afterScenario();
+	};
+
     private class SomethingHappened implements State {
         public void run(Step step) {
             StepResult result = step.doNotPerform();

Added: trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterScenario.java (0 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterScenario.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterScenario.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,12 @@
+package org.jbehave.scenario.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.METHOD)
+public @interface AfterScenario {
+
+}

Added: trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterSuccessfulScenario.java (0 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterSuccessfulScenario.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterSuccessfulScenario.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,12 @@
+package org.jbehave.scenario.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.METHOD)
+public @interface AfterSuccessfulScenario {
+
+}

Added: trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterUnsuccessfulScenario.java (0 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterUnsuccessfulScenario.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/AfterUnsuccessfulScenario.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,12 @@
+package org.jbehave.scenario.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.METHOD)
+public @interface AfterUnsuccessfulScenario {
+
+}

Added: trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/BeforeScenario.java (0 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/BeforeScenario.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/annotations/BeforeScenario.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,12 @@
+package org.jbehave.scenario.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
[EMAIL PROTECTED](ElementType.METHOD)
+public @interface BeforeScenario {
+
+}

Added: trunk/jbehave-core/src/java/org/jbehave/scenario/errors/BeforeOrAfterScenarioException.java (0 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/errors/BeforeOrAfterScenarioException.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/errors/BeforeOrAfterScenarioException.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -0,0 +1,19 @@
+package org.jbehave.scenario.errors;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import org.jbehave.scenario.steps.Steps;
+
+public class BeforeOrAfterScenarioException extends RuntimeException {
+
+	private static final long serialVersionUID = 8025578549612669575L;
+
+	public BeforeOrAfterScenarioException(Class<? extends Annotation> annotation, Method method, Throwable t) {
+		super("Method " + method.getClass().getSimpleName() + "." + method.getName() + 
+				", annotated with " + annotation.getSimpleName() + " failed. Please note that " +
+				Steps.class.getSimpleName() + " methods annotated with " +
+				"this type of annotation should not take parameters, and any exceptions generated by them " +
+				"cannot be handled by JBehave.", t);
+	}
+}

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateSteps.java (974 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateSteps.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateSteps.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,5 +1,7 @@
 package org.jbehave.scenario.steps;
 
+import java.util.Collection;
+
 /**
  * Represents the list of candidate steps that can be performed
  */
@@ -19,4 +21,8 @@
      */
     CandidateStep[] getSteps(Class<?> stepsClass);
 
+    Collection<? extends Step> runBeforeScenario();
+
+    Collection<? extends Step> runAfterScenario();
+
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PendingStep.java (974 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PendingStep.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PendingStep.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -23,4 +23,8 @@
         return StepResult.pending(getDescription());
     }
 
+    @Override
+    public String toString() {
+    	return getClass().getSimpleName() + "[" + step + "]";
+    }
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/Steps.java (974 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/Steps.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/Steps.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,12 +1,20 @@
 package org.jbehave.scenario.steps;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.jbehave.scenario.annotations.AfterScenario;
+import org.jbehave.scenario.annotations.AfterSuccessfulScenario;
+import org.jbehave.scenario.annotations.AfterUnsuccessfulScenario;
+import org.jbehave.scenario.annotations.BeforeScenario;
 import org.jbehave.scenario.annotations.Given;
 import org.jbehave.scenario.annotations.Then;
 import org.jbehave.scenario.annotations.When;
+import org.jbehave.scenario.errors.BeforeOrAfterScenarioException;
+import org.jbehave.scenario.reporters.ScenarioReporter;
 
 /**
  * <p>
@@ -51,7 +59,7 @@
  * </p>
  */
 public class Steps implements CandidateSteps {
-
+	
     private final StepsConfiguration configuration;
 
     /**
@@ -71,6 +79,15 @@
     public Steps(String... startingWords) {
         this(new StepsConfiguration(startingWords));
     }
+    
+    /**
+     * Creates Steps with all default dependencies except for custom parameter converters.
+     * 
+     * @param converters a set of converters which can change strings into other objects to pass into executable steps
+     */
+    public Steps(ParameterConverters converters) {
+    	this(new StepsConfiguration(converters));
+    }
 
     /**
      * Creates Steps with all custom dependencies
@@ -105,4 +122,68 @@
         steps.add(new CandidateStep(stepAsString, method, this, configuration.getPatternBuilder(), configuration
                 .getMonitor(), configuration.getParameterConverters(), configuration.getStartingWords()));
     }
+
+	public List<Step> runBeforeScenario() {
+		return stepsHaving(BeforeScenario.class, new OkayToRun(), new OkayToRun());
+	}
+	
+	public List<Step> runAfterScenario() {
+		List<Step> steps = new ArrayList<Step>();
+		steps.addAll(stepsHaving(AfterScenario.class, new OkayToRun(), new OkayToRun()));
+		steps.addAll(stepsHaving(AfterSuccessfulScenario.class, new OkayToRun(), new DoNotRun()));
+		steps.addAll(stepsHaving(AfterUnsuccessfulScenario.class, new DoNotRun(), new OkayToRun()));
+		return steps;
+	}
+
+	private List<Step> stepsHaving(final Class<? extends Annotation> annotation, final StepPart forSuccessfulScenarios, final StepPart forUnsuccessfulScenarios) {
+		ArrayList<Step> steps = new ArrayList<Step>();
+        for (final Method method : this.getClass().getMethods()) {
+			if (method.isAnnotationPresent(annotation)) {
+				steps.add(new Step() {
+
+					public StepResult doNotPerform() {
+						return forUnsuccessfulScenarios.run(annotation, method);
+					}
+
+					public StepResult perform() {
+								return forSuccessfulScenarios.run(annotation, method);
+					}
+					
+				});
+			}
+        }
+        return steps;
+	}
+	
+	private class OkayToRun implements StepPart {
+		public StepResult run(final Class<? extends Annotation> annotation, Method method) {
+			try {
+				method.invoke(Steps.this);
+			} catch (InvocationTargetException e) {
+				if (e.getCause() != null) { throw new BeforeOrAfterScenarioException(annotation, method, e.getCause()); }
+			} catch (Throwable t) {
+				throw new RuntimeException(t);
+			}
+			return new SilentStepResult();
+		}
+	}
+	
+	private class DoNotRun implements StepPart {
+		public StepResult run(Class<? extends Annotation> annotation, Method method) {
+			return new SilentStepResult();
+		}
+	}
+	
+	private interface StepPart {
+		StepResult run(Class<? extends Annotation> annotation, Method method);
+	}
+	
+    public class SilentStepResult extends StepResult {
+    	public SilentStepResult() {
+			super("");
+		}
+    	
+		@Override
+		public void describeTo(ScenarioReporter reporter) {}
+	}
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepsConfiguration.java (974 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepsConfiguration.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepsConfiguration.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -10,13 +10,18 @@
  * </p>
  */
 public class StepsConfiguration {
+
+    public static final String[] DEFAULT_STARTING_WORDS = new String[] {
+        "Given", "When", "Then", "And"
+    };
+    
     private StepPatternBuilder patternBuilder;
     private StepMonitor monitor;
     private ParameterConverters parameterConverters;
     private String[] startingWords;
 
     public StepsConfiguration() {
-        this("Given", "When", "Then", "And");
+        this(DEFAULT_STARTING_WORDS);
     }
 
     public StepsConfiguration(String... startingWords) {
@@ -31,6 +36,10 @@
         this.startingWords = startingWords;
     }
 
+    public StepsConfiguration(ParameterConverters converters) {
+        this(new PrefixCapturingPatternBuilder(), new SilentStepMonitor(), converters, DEFAULT_STARTING_WORDS);
+    }
+
     public StepPatternBuilder getPatternBuilder() {
         return patternBuilder;
     }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java (974 => 975)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java	2008-10-07 20:51:37 UTC (rev 974)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java	2008-10-16 10:10:08 UTC (rev 975)
@@ -1,25 +1,45 @@
 package org.jbehave.scenario.steps;
 
+import java.util.ArrayList;
+
 import org.jbehave.scenario.definition.ScenarioDefinition;
 
 public class UnmatchedToPendingStepCreator implements StepCreator {
 
     public Step[] createStepsFrom(ScenarioDefinition scenario,
             CandidateSteps... candidateSteps) {
-        Step[] steps = new Step[scenario.getSteps().size()];
-        for (int i = 0; i < steps.length; i++) {
-            String stringStep = scenario.getSteps().get(i);
+        ArrayList<Step> steps = new ArrayList<Step>();
+        
+        addAllNormalSteps(scenario, steps, candidateSteps);
+        addBeforeAndAfterSteps(steps, candidateSteps);
+        
+        return steps.toArray(new Step[steps.size()]);
+    }
+
+	private void addBeforeAndAfterSteps(ArrayList<Step> steps,
+			CandidateSteps[] candidateSteps) {
+		for (CandidateSteps candidates : candidateSteps) {
+			steps.addAll(0, candidates.runBeforeScenario());
+		}
+		
+		for (CandidateSteps candidates : candidateSteps) {
+			steps.addAll(candidates.runAfterScenario());
+		}
+	}
+
+	private void addAllNormalSteps(ScenarioDefinition scenario,
+			ArrayList<Step> steps, CandidateSteps... candidateSteps) {
+		for (String stringStep : scenario.getSteps()) {
+			Step step = new PendingStep(stringStep);
             for (CandidateSteps candidates : candidateSteps) {
                 for (CandidateStep candidate : candidates.getSteps()) {
                     if (candidate.matches(stringStep)) {
-                        steps[i] = candidate.createFrom(stringStep);
+                        step = candidate.createFrom(stringStep);
+                        break;
                     }
                 }
             }
-            if (steps[i] == null) {
-                steps[i] = new PendingStep(stringStep);
-            }
+            steps.add(step);
         }
-        return steps;
-    }
+	}
 }

Added: trunk/lib/build/hamcrest-all-1.1.jar

(Binary files differ)
Property changes on: trunk/lib/build/hamcrest-all-1.1.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream

Added: trunk/lib/production/picocontainer-2.6.jar

(Binary files differ)
Property changes on: trunk/lib/production/picocontainer-2.6.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream

Added: trunk/lib/production/picocontainer-script-core-2.0.jar

(Binary files differ)
Property changes on: trunk/lib/production/picocontainer-script-core-2.0.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream

Added: trunk/lib/production/spring-2.5.5.jar

(Binary files differ)
Property changes on: trunk/lib/production/spring-2.5.5.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream

To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to