Coverage Report - org.jbehave.core.reporters.PostStoryStatisticsCollector
 
Classes in this File Line Coverage Branch Coverage Complexity
PostStoryStatisticsCollector
88%
109/123
88%
39/44
1.688
 
 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 beforeStep(String step) {
 50  0
     }
 51  
 
 52  
     public void successful(String step) {
 53  4
         add("steps");
 54  4
         add("stepsSuccessful");
 55  4
         add("currentScenarioSteps");
 56  4
     }
 57  
 
 58  
     public void ignorable(String step) {
 59  1
         add("steps");
 60  1
         add("stepsIgnorable");
 61  1
         add("currentScenarioSteps");
 62  1
     }
 63  
 
 64  
     public void pending(String step) {
 65  1
         add("steps");
 66  1
         add("stepsPending");
 67  1
         add("currentScenarioSteps");
 68  1
         add("currentScenarioStepsPending");
 69  1
     }
 70  
 
 71  
     public void notPerformed(String step) {
 72  2
         add("steps");
 73  2
         add("stepsNotPerformed");
 74  2
         add("currentScenarioSteps");
 75  2
     }
 76  
 
 77  
     public void failed(String step, Throwable cause) {
 78  2
         this.cause = cause;
 79  2
         add("steps");
 80  2
         add("stepsFailed");
 81  2
         add("currentScenarioSteps");
 82  2
     }
 83  
 
 84  
     public void failedOutcomes(String step, OutcomesTable table) {
 85  2
         this.outcomesFailed = table;
 86  2
         add("steps");
 87  2
         add("stepsFailed");
 88  2
         add("currentScenarioSteps");
 89  2
     }
 90  
 
 91  
     public void beforeStory(Story story, boolean givenStory) {
 92  6
         if (givenStory) {
 93  3
             this.givenStories++;
 94  
         }
 95  
 
 96  6
         if (!givenStory) {
 97  3
             resetData();
 98  3
             storyStartTime = System.currentTimeMillis();
 99  
         }
 100  6
     }
 101  
 
 102  
     public void narrative(final Narrative narrative) {
 103  0
     }
 104  
 
 105  
     public void storyNotAllowed(Story story, String filter) {
 106  1
         resetData();
 107  1
         add("notAllowed");
 108  1
         writeData();
 109  1
     }
 110  
 
 111  
     public void storyCancelled(Story story, StoryDuration storyDuration) {
 112  0
         add("cancelled");
 113  0
     }
 114  
 
 115  
     public void afterStory(boolean givenStory) {
 116  6
             boolean write = false;
 117  6
         if (givenStory) {
 118  3
             this.givenStories--;
 119  3
             if ( has("stepsFailed") ){
 120  0
                     add("scenariosFailed");
 121  0
                     write = true;
 122  
             }
 123  
         } else {
 124  3
             if (has("scenariosPending") || has("givenStoryScenariosPending")) {
 125  1
                 add("pending");
 126  
             }
 127  3
             write = true;
 128  
         }
 129  6
         if ( write ) {
 130  3
             int duration = (int)(System.currentTimeMillis() - storyStartTime);
 131  3
             data.put("duration", duration);
 132  3
             writeData();
 133  
         }
 134  6
     }
 135  
 
 136  
     public void givenStories(GivenStories givenStories) {
 137  0
         add("givenStories");
 138  0
     }
 139  
 
 140  
     public void givenStories(List<String> storyPaths) {
 141  2
         add("givenStories");
 142  2
     }
 143  
 
 144  
     public void beforeScenario(String title) {
 145  7
         cause = null;
 146  7
         outcomesFailed = null;
 147  7
         currentScenarioNotAllowed = false;
 148  7
         reset("currentScenarioSteps");
 149  7
         reset("currentScenarioStepsPending");
 150  7
     }
 151  
 
 152  
     public void scenarioNotAllowed(Scenario scenario, String filter) {
 153  1
         if (givenStories > 0) {
 154  0
             add("givenStoryScenariosNotAllowed");
 155  
         } else {
 156  1
             add("scenariosNotAllowed");
 157  1
             currentScenarioNotAllowed = true;
 158  
         }
 159  1
     }
 160  
 
 161  
     public void scenarioMeta(Meta meta) {
 162  1
     }
 163  
 
 164  
     public void afterScenario() {
 165  7
         if (givenStories > 0) {
 166  3
             countScenarios("givenStoryScenarios");
 167  
         } else {
 168  4
             countScenarios("scenarios");
 169  
         }
 170  7
         if (has("currentScenarioStepsPending") || (!has("currentScenarioSteps") && !currentScenarioNotAllowed)) {
 171  2
             if (givenStories > 0) {
 172  1
                 add("givenStoryScenariosPending");
 173  
             } else {
 174  1
                 add("scenariosPending");
 175  
             }
 176  
         }
 177  7
     }
 178  
 
 179  
     private void countScenarios(String namespace) {
 180  7
         add(namespace);
 181  7
         if (!currentScenarioNotAllowed){
 182  6
                 if (cause != null || outcomesFailed != null) {
 183  1
                     add(namespace + "Failed");
 184  
                 } else {
 185  5
                     add(namespace + "Successful");
 186  
                 }
 187  
         }
 188  7
     }
 189  
 
 190  
     public void beforeExamples(List<String> steps, ExamplesTable table) {
 191  1
     }
 192  
 
 193  
     public void example(Map<String, String> tableRow) {
 194  2
         add("examples");
 195  2
     }
 196  
 
 197  
     public void afterExamples() {
 198  1
     }
 199  
 
 200  
     public void dryRun() {
 201  1
     }
 202  
 
 203  
     public void pendingMethods(List<String> methods) {
 204  0
     }
 205  
 
 206  
     public void restarted(String step, Throwable cause) {
 207  0
     }
 208  
 
 209  
     private void add(String event) {
 210  59
         Integer count = data.get(event);
 211  59
         if (count == null) {
 212  6
             count = 0;
 213  
         }
 214  59
         count++;
 215  59
         data.put(event, count);
 216  59
     }
 217  
 
 218  
     private boolean has(String event) {
 219  21
         Integer count = data.get(event);
 220  21
         if (count == null) {
 221  0
             count = 0;
 222  
         }
 223  21
         return count > 0;
 224  
     }
 225  
 
 226  
     private void writeData() {
 227  4
         Properties p = new Properties();
 228  4
         for (String event : data.keySet()) {
 229  91
             if (!event.startsWith("current")) {
 230  83
                 p.setProperty(event, data.get(event).toString());
 231  
             }
 232  
         }
 233  
         try {
 234  4
             p.store(output, this.getClass().getName());
 235  0
         } catch (IOException e) {
 236  0
             e.printStackTrace();
 237  4
         }
 238  4
     }
 239  
 
 240  
     private void resetData() {
 241  4
         data.clear();
 242  4
         for (String event : events) {
 243  88
             reset(event);
 244  
         }
 245  4
     }
 246  
 
 247  
     private void reset(String event) {
 248  102
         data.put(event, 0);
 249  102
     }
 250  
 
 251  
     @Override
 252  
     public String toString() {
 253  1
         return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(output).append(data).toString();
 254  
     }
 255  
 
 256  
 
 257  
 }