Cucumber-JVM: formatter for version 3 implemented.

In Cucumber for Java v.3 class 'TestStep' was changed to interface. That's why IncompatibleClassChangeError appeared when project with attached library v.3 was executed with SMFormatter compiled with library v.2

IDEA-192612 IncompatibleClassChangeError running Cucumber 3+ tests
This commit is contained in:
Andrey Vokin
2018-07-19 14:28:15 +02:00
parent bfdab13dca
commit 69f4fbff63
4 changed files with 175 additions and 16 deletions
@@ -11,5 +11,6 @@
<orderEntry type="module" module-name="intellij.platform.testFramework" />
<orderEntry type="library" scope="PROVIDED" name="cucumber-core" level="project" />
<orderEntry type="module" module-name="intellij.cucumber.jvmFormatter" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.cucumber.jvmFormatter3" scope="RUNTIME" />
</component>
</module>
@@ -88,39 +88,39 @@ public class CucumberJvm2SMFormatter implements Formatter {
private void handleTestCaseStarted(TestCaseStarted event) {
if (currentFilePath == null) {
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), event.testCase.getUri(),
getFeatureFileDescription(event.testCase.getUri())));
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), getEventUri(event),
getFeatureFileDescription(getEventUri(event))));
}
else if (!event.testCase.getUri().equals(currentFilePath)) {
else if (!getEventUri(event).equals(currentFilePath)) {
closeCurrentScenarioOutline();
outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(),
getFeatureFileDescription(currentFilePath)));
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), event.testCase.getUri(),
getFeatureFileDescription(event.testCase.getUri())));
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), getEventUri(event),
getFeatureFileDescription(getEventUri(event))));
}
if (isScenarioOutline(event.testCase)) {
int mainScenarioLine = getScenarioOutlineLine(event.testCase);
if (currentScenarioOutlineLine != mainScenarioLine || currentFilePath == null ||
!currentFilePath.equals(event.testCase.getUri())) {
!currentFilePath.equals(getEventUri(event))) {
closeCurrentScenarioOutline();
currentScenarioOutlineLine = mainScenarioLine;
currentScenarioOutlineName = event.testCase.getName();
currentScenarioOutlineName = getEventName(event);
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(),
event.testCase.getUri() + ":" + currentScenarioOutlineLine, currentScenarioOutlineName));
getEventUri(event) + ":" + currentScenarioOutlineLine, currentScenarioOutlineName));
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), "", EXAMPLES_CAPTION));
}
} else {
closeCurrentScenarioOutline();
}
currentFilePath = event.testCase.getUri();
currentFilePath = getEventUri(event);
outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(),
event.testCase.getUri() + ":" + event.testCase.getLine(), getScenarioName(event.testCase)));
getEventUri(event) + ":" + getEventLine(event), getScenarioName(event)));
}
private void handleTestCaseFinished(TestCaseFinished event) {
outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getScenarioName(event.testCase)));
outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getScenarioName(event)));
}
private void handleTestRunFinished(TestRunFinished event) {
@@ -129,21 +129,21 @@ public class CucumberJvm2SMFormatter implements Formatter {
getFeatureFileDescription(currentFilePath)));
}
private void handleTestStepStarted(TestStepStarted event) {
outCommand(String.format(TEMPLATE_TEST_STARTED, getCurrentTime(), getStepLocation(event.testStep),
getStepName(event.testStep)));
outCommand(String.format(TEMPLATE_TEST_STARTED, getCurrentTime(), getStepLocation(event),
getStepName(event)));
}
private void handleTestStepFinished(TestStepFinished event) {
if (event.result.getStatus() == PASSED) {
// write nothing
} else if (event.result.getStatus() == SKIPPED || event.result.getStatus() == PENDING) {
outCommand(String.format(TEMPLATE_TEST_PENDING, getStepName(event.testStep), getCurrentTime()));
outCommand(String.format(TEMPLATE_TEST_PENDING, getStepName(event), getCurrentTime()));
} else {
outCommand(String.format(TEMPLATE_TEST_FAILED, getCurrentTime(), "",
escape(event.result.getErrorMessage()), getStepName(event.testStep), ""));
escape(event.result.getErrorMessage()), getStepName(event), ""));
}
Long duration = event.result.getDuration() != null ? event.result.getDuration() / 1000000: 0;
outCommand(String.format(TEMPLATE_TEST_FINISHED, getCurrentTime(), duration, getStepName(event.testStep)));
outCommand(String.format(TEMPLATE_TEST_FINISHED, getCurrentTime(), duration, getStepName(event)));
}
private String getFeatureFileDescription(String uri) {
@@ -238,6 +238,42 @@ public class CucumberJvm2SMFormatter implements Formatter {
return escape(testCase.getName());
}
protected String getScenarioName(TestCaseStarted testCaseStarted) {
return getScenarioName(testCaseStarted.testCase);
}
protected String getScenarioName(TestCaseFinished testCaseFinished) {
return getScenarioName(testCaseFinished.testCase);
}
protected String getEventUri(TestCaseStarted event) {
return event.testCase.getUri();
}
protected int getEventLine(TestCaseStarted event) {
return event.testCase.getLine();
}
protected String getEventName(TestCaseStarted event) {
return event.testCase.getName();
}
protected String getStepLocation(TestStepStarted testStepStarted) {
return getStepLocation(testStepStarted.testStep);
}
protected String getStepLocation(TestStepFinished testStepFinished) {
return getStepLocation(testStepFinished.testStep);
}
protected String getStepName(TestStepStarted testStepStarted) {
return getStepName(testStepStarted.testStep);
}
protected String getStepName(TestStepFinished testStepFinished) {
return getStepName(testStepFinished.testStep);
}
private String getCurrentTime() {
if (myCurrentTimeValue != null) {
return myCurrentTimeValue;
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="io.cucumber:cucumber-core:3.0.2" level="project" />
<orderEntry type="module" module-name="intellij.cucumber.jvmFormatter" />
</component>
</module>
@@ -0,0 +1,109 @@
package org.jetbrains.plugins.cucumber.java.run;
import cucumber.api.HookTestStep;
import cucumber.api.PickleStepTestStep;
import cucumber.api.TestCase;
import cucumber.api.TestStep;
import cucumber.api.event.TestCaseFinished;
import cucumber.api.event.TestCaseStarted;
import cucumber.api.event.TestStepFinished;
import cucumber.api.event.TestStepStarted;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static org.jetbrains.plugins.cucumber.java.run.CucumberJvmSMFormatterUtil.FILE_RESOURCE_PREFIX;
import static org.jetbrains.plugins.cucumber.java.run.CucumberJvmSMFormatterUtil.escape;
@SuppressWarnings("unused")
public class CucumberJvm3SMFormatter extends CucumberJvm2SMFormatter {
public CucumberJvm3SMFormatter() {
super();
}
@Override
protected String getEventUri(TestCaseStarted event) {
return event.testCase.getUri();
}
@Override
protected int getEventLine(TestCaseStarted event) {
return event.testCase.getLine();
}
@Override
protected String getEventName(TestCaseStarted event) {
return event.testCase.getName();
}
@Override
protected String getScenarioName(TestCaseStarted testCaseStarted) {
return getScenarioName(testCaseStarted.testCase);
}
@Override
protected String getScenarioName(TestCaseFinished testCaseFinished) {
return getScenarioName(testCaseFinished.testCase);
}
@Override
protected String getStepLocation(TestStepStarted testStepStarted) {
return getStepLocation(testStepStarted.testStep);
}
@Override
protected String getStepLocation(TestStepFinished testStepFinished) {
return getStepLocation(testStepFinished.testStep);
}
@Override
protected String getStepName(TestStepStarted testStepStarted) {
return getStepName(testStepStarted.testStep);
}
@Override
protected String getStepName(TestStepFinished testStepFinished) {
return getStepName(testStepFinished.testStep);
}
private static String getScenarioName(TestCase testCase) {
return escape("Scenario: " + testCase.getName());
}
private static String getStepLocation(TestStep step) {
if (step instanceof HookTestStep) {
try {
Field definitionMatchField = step.getClass().getSuperclass().getDeclaredField("stepDefinitionMatch");
definitionMatchField.setAccessible(true);
Object definitionMatchFieldValue = definitionMatchField.get(step);
Field hookDefinitionField = definitionMatchFieldValue.getClass().getDeclaredField("hookDefinition");
hookDefinitionField.setAccessible(true);
Object hookDefinitionFieldValue = hookDefinitionField.get(definitionMatchFieldValue);
Field methodField = hookDefinitionFieldValue.getClass().getDeclaredField("method");
methodField.setAccessible(true);
Object methodFieldValue = methodField.get(hookDefinitionFieldValue);
if (methodFieldValue instanceof Method) {
Method method = (Method)methodFieldValue;
return String.format("java:test://%s/%s", method.getDeclaringClass().getName(), method.getName());
}
}
catch (Exception ignored) {
}
return "";
}
PickleStepTestStep pickleStepTestStep = (PickleStepTestStep) step;
return FILE_RESOURCE_PREFIX + pickleStepTestStep.getStepLocation() + ":" + pickleStepTestStep.getStepLine();
}
private static String getStepName(TestStep step) {
String stepName;
if (step instanceof HookTestStep) {
stepName = "Hook: " + ((HookTestStep)step).getHookType().toString();
} else {
stepName = ((PickleStepTestStep) step).getPickleStep().getText();
}
return escape(stepName);
}
}