Coverage Report - org.jbehave.core.reporters.PostStoryStatisticsCollector
 
Classes in this File Line Coverage Branch Coverage Complexity
PostStoryStatisticsCollector
90%
105/116
90%
36/40
1.645
 
 1  
 package org.jbehave.core.reporters;
 2  
 
 3  
 import java.io.IOException;
 4  
 import java.io.OutputStream;
 5  
 import java.util.HashMap;
 6  
 import java.util.List;
 7  
 import java.util.Map;
 8  
 import java.util.Properties;
 9  
 
 10  
 import org.apache.commons.lang.builder.ToStringBuilder;
 11  
 import org.apache.commons.lang.builder.ToStringStyle;
 12  
 import org.jbehave.core.model.ExamplesTable;
 13  
 import org.jbehave.core.model.GivenStories;
 14  
 import org.jbehave.core.model.Meta;
 15  
 import org.jbehave.core.model.Narrative;
 16  
 import org.jbehave.core.model.OutcomesTable;
 17  
 import org.jbehave.core.model.Scenario;
 18  
 import org.jbehave.core.model.Story;
 19  
 import org.jbehave.core.model.StoryDuration;
 20  
 
 21  
 import static java.util.Arrays.asList;
 22  
 
 23  
 /**
 24  
  * <p>
 25  
  * Reporter that collects statistics and writes them as properties to output
 26  
  * stream after each story
 27  
  * </p>
 28  
  */
 29  
 public class PostStoryStatisticsCollector implements StoryReporter {
 30  
 
 31  
     private final OutputStream output;
 32  13
     private final Map<String, Integer> data = new HashMap<String, Integer>();
 33  13
     private final List<String> events = asList("notAllowed", "pending", "scenariosNotAllowed",
 34  
             "givenStoryScenariosNotAllowed", "steps", "stepsSuccessful", "stepsIgnorable", "stepsPending",
 35  
             "stepsNotPerformed", "stepsFailed", "currentScenarioSteps", "currentScenarioStepsPending", "scenarios",
 36  
             "scenariosSuccessful", "scenariosPending", "scenariosFailed", "givenStories", "givenStoryScenarios",
 37  
             "givenStoryScenariosSuccessful", "givenStoryScenariosPending", "givenStoryScenariosFailed", "examples");
 38  
 
 39  
     private Throwable cause;
 40  
     private OutcomesTable outcomesFailed;
 41  
     private int givenStories;
 42  
     private long storyStartTime;
 43  
     private boolean currentScenarioNotAllowed;
 44  
 
 45  13
     public PostStoryStatisticsCollector(OutputStream output) {
 46  13
         this.output = output;
 47  13
     }
 48  
 
 49  
     public void successful(String step) {
 50  4
         add("steps");
 51  4
         add("stepsSuccessful");
 52  4
         add("currentScenarioSteps");
 53  4
     }
 54  
 
 55  
     public void ignorable(String step) {
 56  1
         add("steps");
 57  1
         add("stepsIgnorable");
 58  1
         add("currentScenarioSteps");
 59  1
     }
 60  
 
 61  
     public void pending(String step) {
 62  1
         add("steps");
 63  1
         add("stepsPending");
 64  1
         add("currentScenarioSteps");
 65  1
         add("currentScenarioStepsPending");
 66  1
     }
 67  
 
 68  
     public void notPerformed(String step) {
 69  2
         add("steps");
 70  2
         add("stepsNotPerformed");
 71  2
         add("currentScenarioSteps");
 72  2
     }
 73  
 
 74  
     public void failed(String step, Throwable cause) {
 75  2
         this.cause = cause;
 76  2
         add("steps");
 77  2
         add("stepsFailed");
 78  2
         add("currentScenarioSteps");
 79  2
     }
 80  
 
 81  
     public void failedOutcomes(String step, OutcomesTable table) {
 82  2
         this.outcomesFailed = table;
 83  2
         add("steps");
 84  2
         add("stepsFailed");
 85  2
         add("currentScenarioSteps");
 86  2
     }
 87  
 
 88  
     public void beforeStory(Story story, boolean givenStory) {
 89  5
         if (givenStory) {
 90  3
             this.givenStories++;
 91  
         }
 92  
 
 93  5
         if (!givenStory) {
 94  2
             resetData();
 95  2
             storyStartTime = System.currentTimeMillis();
 96  
         }
 97  5
     }
 98  
 
 99  
     public void narrative(final Narrative narrative) {
 100  0
     }
 101  
 
 102  
     public void storyNotAllowed(Story story, String filter) {
 103  1
         resetData();
 104  1
         add("notAllowed");
 105  1
         writeData();
 106  1
     }
 107  
 
 108  
     public void storyCancelled(Story story, StoryDuration storyDuration) {
 109  0
         add("cancelled");
 110  0
     }
 111  
 
 112  
     public void afterStory(boolean givenStory) {
 113  5
         if (givenStory) {
 114  3
             this.givenStories--;
 115  
         } else {
 116  2
             if (has("scenariosPending") || has("givenStoryScenariosPending")) {
 117  1
                 add("pending");
 118  
             }
 119  2
             int duration = (int)(System.currentTimeMillis() - storyStartTime);
 120  2
             data.put("duration", duration);
 121  2
             writeData();
 122  
         }
 123  5
     }
 124  
 
 125  
     public void givenStories(GivenStories givenStories) {
 126  0
         add("givenStories");
 127  0
     }
 128  
 
 129  
     public void givenStories(List<String> storyPaths) {
 130  2
         add("givenStories");
 131  2
     }
 132  
 
 133  
     public void beforeScenario(String title) {
 134  7
         cause = null;
 135  7
         outcomesFailed = null;
 136  7
         currentScenarioNotAllowed = false;
 137  7
         reset("currentScenarioSteps");
 138  7
         reset("currentScenarioStepsPending");
 139  7
     }
 140  
 
 141  
     public void scenarioNotAllowed(Scenario scenario, String filter) {
 142  1
         if (givenStories > 0) {
 143  0
             add("givenStoryScenariosNotAllowed");
 144  
         } else {
 145  1
             add("scenariosNotAllowed");
 146  1
             currentScenarioNotAllowed = true;
 147  
         }
 148  1
     }
 149  
 
 150  
     public void scenarioMeta(Meta meta) {
 151  1
     }
 152  
 
 153  
     public void afterScenario() {
 154  7
         if (givenStories > 0) {
 155  3
             countScenarios("givenStoryScenarios");
 156  
         } else {
 157  4
             countScenarios("scenarios");
 158  
         }
 159  7
         if (has("currentScenarioStepsPending") || (!has("currentScenarioSteps") && !currentScenarioNotAllowed)) {
 160  2
             if (givenStories > 0) {
 161  1
                 add("givenStoryScenariosPending");
 162  
             } else {
 163  1
                 add("scenariosPending");
 164  
             }
 165  
         }
 166  7
     }
 167  
 
 168  
     private void countScenarios(String namespace) {
 169  7
         add(namespace);
 170  7
         if (!currentScenarioNotAllowed){
 171  6
                 if (cause != null || outcomesFailed != null) {
 172  1
                     add(namespace + "Failed");
 173  
                 } else {
 174  5
                     add(namespace + "Successful");
 175  
                 }
 176  
         }
 177  7
     }
 178  
 
 179  
     public void beforeExamples(List<String> steps, ExamplesTable table) {
 180  1
     }
 181  
 
 182  
     public void example(Map<String, String> tableRow) {
 183  2
         add("examples");
 184  2
     }
 185  
 
 186  
     public void afterExamples() {
 187  1
     }
 188  
 
 189  
     public void dryRun() {
 190  1
     }
 191  
 
 192  
     public void pendingMethods(List<String> methods) {
 193  0
     }
 194  
 
 195  
     public void restarted(String step, Throwable cause) {
 196  0
     }
 197  
 
 198  
     private void add(String event) {
 199  59
         Integer count = data.get(event);
 200  59
         if (count == null) {
 201  6
             count = 0;
 202  
         }
 203  59
         count++;
 204  59
         data.put(event, count);
 205  59
     }
 206  
 
 207  
     private boolean has(String event) {
 208  16
         Integer count = data.get(event);
 209  16
         if (count == null) {
 210  0
             count = 0;
 211  
         }
 212  16
         return count > 0;
 213  
     }
 214  
 
 215  
     private void writeData() {
 216  3
         Properties p = new Properties();
 217  3
         for (String event : data.keySet()) {
 218  68
             if (!event.startsWith("current")) {
 219  62
                 p.setProperty(event, data.get(event).toString());
 220  
             }
 221  
         }
 222  
         try {
 223  3
             p.store(output, this.getClass().getName());
 224  0
         } catch (IOException e) {
 225  0
             e.printStackTrace();
 226  3
         }
 227  3
     }
 228  
 
 229  
     private void resetData() {
 230  3
         data.clear();
 231  3
         for (String event : events) {
 232  66
             reset(event);
 233  
         }
 234  3
     }
 235  
 
 236  
     private void reset(String event) {
 237  80
         data.put(event, 0);
 238  80
     }
 239  
 
 240  
     @Override
 241  
     public String toString() {
 242  1
         return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(output).append(data).toString();
 243  
     }
 244  
 
 245  
 }