PostStoryStatisticsCollector.java
- package org.jbehave.core.reporters;
- import static java.util.Arrays.asList;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import org.apache.commons.lang3.builder.ToStringBuilder;
- import org.apache.commons.lang3.builder.ToStringStyle;
- import org.jbehave.core.failures.RestartingStoryFailure;
- import org.jbehave.core.model.GivenStories;
- import org.jbehave.core.model.OutcomesTable;
- import org.jbehave.core.model.Scenario;
- import org.jbehave.core.model.Story;
- import org.jbehave.core.model.StoryDuration;
- import org.jbehave.core.steps.StepCreator.PendingStep;
- import org.jbehave.core.steps.Timing;
- /**
- * <p>
- * Reporter that collects statistics and writes them as properties to output
- * stream after each story
- * </p>
- */
- public class PostStoryStatisticsCollector extends NullStoryReporter {
- private final OutputStream output;
- private final Map<String, Integer> data = new HashMap<>();
- private final List<String> events = asList("excluded", "pending", "scenariosExcluded",
- "givenStoryScenariosExcluded", "steps", "stepsSuccessful", "stepsIgnorable", "comments", "stepsPending",
- "stepsNotPerformed", "stepsFailed", "currentScenarioSteps", "currentScenarioStepsPending", "scenarios",
- "scenariosSuccessful", "scenariosPending", "scenariosFailed", "givenStories", "givenStoryScenarios",
- "givenStoryScenariosSuccessful", "givenStoryScenariosPending", "givenStoryScenariosFailed", "examples");
- private Throwable cause;
- private OutcomesTable outcomesFailed;
- private int givenStories;
- private boolean currentScenarioExcluded;
- public PostStoryStatisticsCollector(OutputStream output) {
- this.output = output;
- }
- @Override
- public void successful(String step) {
- add("steps");
- add("stepsSuccessful");
- add("currentScenarioSteps");
- }
- @Override
- public void ignorable(String step) {
- add("steps");
- add("stepsIgnorable");
- add("currentScenarioSteps");
- }
- @Override
- public void comment(String step) {
- add("steps");
- add("comments");
- add("currentScenarioSteps");
- }
- @Override
- public void pending(PendingStep step) {
- add("steps");
- add("stepsPending");
- add("currentScenarioSteps");
- add("currentScenarioStepsPending");
- }
- @Override
- public void notPerformed(String step) {
- add("steps");
- add("stepsNotPerformed");
- add("currentScenarioSteps");
- }
- @Override
- public void failed(String step, Throwable cause) {
- this.cause = cause;
- if (cause != null && !(cause.getCause() instanceof RestartingStoryFailure)) {
- add("steps");
- add("stepsFailed");
- add("currentScenarioSteps");
- }
- }
- @Override
- public void failedOutcomes(String step, OutcomesTable table) {
- this.outcomesFailed = table;
- add("steps");
- add("stepsFailed");
- add("currentScenarioSteps");
- }
- @Override
- public void beforeStory(Story story, boolean givenStory) {
- if (givenStory) {
- this.givenStories++;
- }
- if (!givenStory) {
- resetData();
- }
- }
- @Override
- public void storyExcluded(Story story, String filter) {
- resetData();
- add("excluded");
- writeData();
- }
- @Override
- public void storyCancelled(Story story, StoryDuration storyDuration) {
- add("cancelled");
- }
- @Override
- public void afterStory(boolean givenStory) {
- boolean write = false;
- if (givenStory) {
- this.givenStories--;
- if (has("stepsFailed")) {
- add("scenariosFailed");
- write = true;
- }
- } else {
- if (has("scenariosPending") || has("givenStoryScenariosPending")) {
- add("pending");
- }
- write = true;
- }
- if (write) {
- writeData();
- }
- }
- @Override
- public void givenStories(GivenStories givenStories) {
- add("givenStories");
- }
- @Override
- public void givenStories(List<String> storyPaths) {
- add("givenStories");
- }
- @Override
- public void beforeScenario(Scenario scenario) {
- cause = null;
- outcomesFailed = null;
- currentScenarioExcluded = false;
- reset("currentScenarioSteps");
- reset("currentScenarioStepsPending");
- }
- @Override
- public void scenarioExcluded(Scenario scenario, String filter) {
- if (givenStories > 0) {
- add("givenStoryScenariosExcluded");
- } else {
- add("scenariosExcluded");
- currentScenarioExcluded = true;
- }
- }
- @Override
- public void afterScenario(Timing timing) {
- if (givenStories > 0) {
- countScenarios("givenStoryScenarios");
- } else {
- countScenarios("scenarios");
- }
- if (has("currentScenarioStepsPending") || (!has("currentScenarioSteps") && !currentScenarioExcluded)) {
- if (givenStories > 0) {
- add("givenStoryScenariosPending");
- } else {
- add("scenariosPending");
- }
- }
- }
- private void countScenarios(String namespace) {
- add(namespace);
- if (!currentScenarioExcluded) {
- if (cause != null || outcomesFailed != null) {
- add(namespace + "Failed");
- } else {
- add(namespace + "Successful");
- }
- }
- }
- @Override
- public void example(Map<String, String> tableRow, int exampleIndex) {
- add("examples");
- }
- @Override
- public void restartedStory(Story story, Throwable cause) {
- resetData();
- }
- private void add(String event) {
- Integer count = data.get(event);
- if (count == null) {
- count = 0;
- }
- count++;
- data.put(event, count);
- }
- private boolean has(String event) {
- Integer count = data.get(event);
- if (count == null) {
- count = 0;
- }
- return count > 0;
- }
- private void writeData() {
- Properties p = new Properties();
- for (String event : data.keySet()) {
- if (!event.startsWith("current")) {
- p.setProperty(event, data.get(event).toString());
- }
- }
- try {
- p.store(output, this.getClass().getName());
- output.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- private void resetData() {
- data.clear();
- for (String event : events) {
- reset(event);
- }
- }
- private void reset(String event) {
- data.put(event, 0);
- }
- @Override
- public String toString() {
- return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(output).append(data).toString();
- }
- }