commit 14d9c2749ef2b64c05d92591716dd191d65e2f64
Author:     Mauro Talevi <mauro.tal...@aquilonia.org>
AuthorDate: Sun, 9 Nov 2014 10:37:57 +0100
Commit:     Mauro Talevi <mauro.tal...@aquilonia.org>
CommitDate: Sun, 9 Nov 2014 10:37:57 +0100

    JBEHAVE-1053:  Support restarting scenario and story in PerformableTree.

diff --git 
a/jbehave-core/src/main/java/org/jbehave/core/embedder/PerformableTree.java 
b/jbehave-core/src/main/java/org/jbehave/core/embedder/PerformableTree.java
index a8c87f1..23e4b6f 100644
--- a/jbehave-core/src/main/java/org/jbehave/core/embedder/PerformableTree.java
+++ b/jbehave-core/src/main/java/org/jbehave/core/embedder/PerformableTree.java
@@ -17,6 +17,8 @@ import org.jbehave.core.failures.BatchFailures;
 import org.jbehave.core.failures.FailingUponPendingStep;
 import org.jbehave.core.failures.PendingStepFound;
 import org.jbehave.core.failures.PendingStepsFound;
+import org.jbehave.core.failures.RestartingScenarioFailure;
+import org.jbehave.core.failures.RestartingStoryFailure;
 import org.jbehave.core.failures.UUIDExceptionWrapper;
 import org.jbehave.core.model.ExamplesTable;
 import org.jbehave.core.model.GivenStories;
@@ -356,16 +358,23 @@ public class PerformableTree {
     }
 
     public void perform(RunContext context, Story story) {
+       boolean restartingStory = false;
+
         try {
             performCancellable(context, story);
-        } catch (Throwable e) {
+            if (context.restartStory()){
+                               context.reporter().restartedStory(story, 
context.failure(context.state()));
+                               restartingStory = true;
+               perform(context, story);
+            }
+        } catch (InterruptedException e) {
             if (context.isCancelled(story)) {
                 context.reporter().storyCancelled(story, 
context.storyDuration(story));
                 context.reporter().afterStory(context.givenStory);
             }
                throw new UUIDExceptionWrapper(e);
         } finally {
-            if (!context.givenStory() && context.reporter() instanceof 
ConcurrentStoryReporter) {
+            if (!context.givenStory() && context.reporter() instanceof 
ConcurrentStoryReporter && !restartingStory ) {
                 ((ConcurrentStoryReporter) context.reporter()).invokeDelayed();
             }
         }
@@ -374,6 +383,7 @@ public class PerformableTree {
     private void performCancellable(RunContext context, Story story) throws 
InterruptedException {
         if (context.configuration().storyControls().resetStateBeforeStory()) {
             context.resetState();
+            context.resetFailures();
         }
         context.currentPath(story.getPath());
 
@@ -432,6 +442,28 @@ public class PerformableTree {
             resetState();
         }
 
+       public boolean restartScenario() {
+               Throwable cause = failure(state);
+               while (cause != null) {
+                       if (cause instanceof RestartingScenarioFailure) {
+                               return true;
+                       }
+                       cause = cause.getCause();
+               }
+               return false;
+       }
+
+       public boolean restartStory() {
+               Throwable cause = failure(state);
+               while (cause != null) {
+                       if (cause instanceof RestartingStoryFailure) {
+                               return true;
+                       }
+                       cause = cause.getCause();
+               }
+               return false;
+       }
+
                public void currentPath(String path) {
             this.path = path;
             this.reporter = configuration.storyReporter(path);
@@ -761,7 +793,8 @@ public class PerformableTree {
         private boolean allowed;
                private NormalPerformableScenario normalPerformableScenario;
         private List<ExamplePerformableScenario> examplePerformableScenarios = 
new ArrayList<ExamplePerformableScenario>();
-        Status status;
+        @SuppressWarnings("unused")
+               private Status status;
 
         public PerformableScenario(Scenario scenario, String storyPath) {
             this.scenario = scenario;
@@ -858,6 +891,18 @@ public class PerformableTree {
         public Map<String, String> getParameters() {
             return parameters;
         }
+
+               protected void performRestartableSteps(RunContext context)
+                               throws InterruptedException {
+                       boolean restart = true;
+                       while (restart) {
+                               restart = false;
+                               steps.perform(context);
+                               if (context.restartScenario()){
+                                       restart = true;
+                               }
+                       }
+               }
     }
 
     public static class NormalPerformableScenario extends 
AbstractPerformableScenario {
@@ -880,7 +925,7 @@ public class PerformableTree {
                                        story.perform(context);
                                }
                        }
-            steps.perform(context);
+                       performRestartableSteps(context);               
             afterSteps.perform(context);
         }
 
@@ -906,7 +951,7 @@ public class PerformableTree {
                                context.givenStory = story.givenStory();
                 story.perform(context);
             }
-            steps.perform(context);
+                       performRestartableSteps(context);               
             afterSteps.perform(context);
         }
 
@@ -960,8 +1005,12 @@ public class PerformableTree {
             StoryReporter reporter = context.reporter();
             results = new ArrayList<StepResult>();
             for (Step step : steps) {
+                try {
                                        context.interruptIfCancelled();
                                        state = state.run(step, results, 
reporter, state.getFailure());
+                               } catch (RestartingScenarioFailure e) {
+                       reporter.restarted(step.toString(), e);
+                               }
             }
             context.stateIs(state);
             context.pendingSteps(pendingSteps);



Reply via email to