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