package tzatziki.analysis.exec; import gherkin.formatter.Formatter; import gherkin.formatter.Reporter; import gherkin.formatter.model.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import tzatziki.analysis.exec.model.BackgroundExec; import tzatziki.analysis.exec.model.FeatureExec; import tzatziki.analysis.exec.model.ScenarioExec; import tzatziki.analysis.exec.model.ScenarioOutlineExec; import tzatziki.analysis.exec.model.StepContainer; import tzatziki.analysis.exec.model.StepExec; import tzatziki.util.MemoizableIterator; import java.util.Iterator; import java.util.List; /** * @author <a href="http://twitter.com/aloyer">@aloyer</a> */ public abstract class ExecutionReport implements Formatter, Reporter { private final Logger log = LoggerFactory.getLogger(getClass()); private final ModelConverter converter; // private String currentUri; private FeatureExec currentFeature; private StepContainer currentStepContainer; private StepExec currentStep; // private MemoizableIterator<StepExec> stepIterator; public ExecutionReport() { this(new ModelConverter()); } public ExecutionReport(ModelConverter converter) { this.converter = converter; } @Override public void uri(String uri) { log.debug("uri: {}", uri); this.currentUri = uri; } @Override public void feature(Feature feature) { log.debug("feature: {}", feature.getName()); currentStep = null; currentStepContainer = null; stepIterator = null; flushCurrentFeature(); this.currentFeature = converter.convertFeature(currentUri, feature); } private void flushCurrentFeature() { if (currentFeature != null) { emit(currentFeature); } currentFeature = null; } protected abstract void emit(FeatureExec feature); @Override public void background(Background background) { log.debug("background: {}", background.getName()); currentStep = null; stepIterator = null; BackgroundExec backgroundExec = converter.convertBackground(background); currentFeature.background(backgroundExec); currentStepContainer = backgroundExec; } @Override public void startOfScenarioLifeCycle(Scenario scenario) { } @Override public void endOfScenarioLifeCycle(Scenario scenario) { } @Override public void scenario(Scenario scenario) { log.debug("scenario: {}", scenario.getName()); currentStep = null; stepIterator = null; ScenarioExec scenarioExec = converter.convertScenario(scenario); currentFeature.declareScenario(scenarioExec); currentStepContainer = scenarioExec; } @Override public void scenarioOutline(ScenarioOutline scenarioOutline) { log.debug("scenarioOutline: {}", scenarioOutline.getName()); currentStep = null; stepIterator = null; ScenarioOutlineExec scenarioOutlineExec = converter.convertScenarioOutline(scenarioOutline); currentFeature.declareScenarioOutline(scenarioOutlineExec); currentStepContainer = scenarioOutlineExec; } @Override public void examples(Examples examples) { log.debug("examples: {}", examples.getName()); currentStep = null; currentFeature .lastOutline() .get() .declareExamples(converter.convertExamples(examples)); } @Override public void step(Step step) { log.debug("step: {}", step.getName()); StepExec stepExec = converter.convertStep(step); currentStepContainer.declareStep(stepExec); currentStep = stepExec; } @Override public void result(Result result) { log.debug("result: {}", result); stepIterator.current().declareResult(converter.convertResult(result)); } @Override public void match(Match match) { log.debug("match: {}", match); // unfortunately match does not apply to the current step, // there are invoked once all scenario's steps are defined if(stepIterator == null) stepIterator = MemoizableIterator.wrap(currentStepContainer.steps().iterator()); StepExec stepExec = stepIterator.next(); stepExec.declareMatch(converter.convertMatch(match)); } @Override public void embedding(String mimeType, byte[] data) { log.debug("embedding: {}", mimeType); if (stepIterator != null) stepIterator.current().embedding(mimeType, data); else if (currentStepContainer != null) currentStepContainer.embedding(mimeType, data); } @Override public void write(String text) { log.debug("write: {}", text); if (currentStep != null) { currentStep.text(text); return; } if (currentStepContainer != null) { currentStepContainer.text(text); return; } log.warn("Unsupported text call"); } @Override public void eof() { log.debug("eof"); } @Override public void syntaxError(String state, String event, List<String> legalEvents, String uri, Integer line) { log.debug("syntaxError {} {}", state, event); } @Override public void done() { log.debug("done"); flushCurrentFeature(); } @Override public void close() { log.debug("close"); } @Override public void before(Match match, Result result) { log.debug("before"); } @Override public void after(Match match, Result result) { log.debug("after"); } }