From 69f4fbff6317b2d5cd920e9b89a048f118525d7b Mon Sep 17 00:00:00 2001 From: Andrey Vokin Date: Wed, 18 Jul 2018 16:26:38 +0200 Subject: [PATCH] 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 --- .../intellij.cucumber.testRunner.iml | 1 + .../java/run/CucumberJvm2SMFormatter.java | 68 ++++++++--- .../intellij.cucumber.jvmFormatter3.iml | 13 +++ .../java/run/CucumberJvm3SMFormatter.java | 109 ++++++++++++++++++ 4 files changed, 175 insertions(+), 16 deletions(-) create mode 100644 plugins/cucumber-jvm-formatter3/intellij.cucumber.jvmFormatter3.iml create mode 100644 plugins/cucumber-jvm-formatter3/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm3SMFormatter.java diff --git a/build/cucumber-test-runner/intellij.cucumber.testRunner.iml b/build/cucumber-test-runner/intellij.cucumber.testRunner.iml index e6a27d2b64e7..6fce6df85775 100644 --- a/build/cucumber-test-runner/intellij.cucumber.testRunner.iml +++ b/build/cucumber-test-runner/intellij.cucumber.testRunner.iml @@ -11,5 +11,6 @@ + \ No newline at end of file diff --git a/plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm2SMFormatter.java b/plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm2SMFormatter.java index 3d14eda81029..b6d61dd01f12 100644 --- a/plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm2SMFormatter.java +++ b/plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm2SMFormatter.java @@ -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; diff --git a/plugins/cucumber-jvm-formatter3/intellij.cucumber.jvmFormatter3.iml b/plugins/cucumber-jvm-formatter3/intellij.cucumber.jvmFormatter3.iml new file mode 100644 index 000000000000..2d430f86614f --- /dev/null +++ b/plugins/cucumber-jvm-formatter3/intellij.cucumber.jvmFormatter3.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/cucumber-jvm-formatter3/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm3SMFormatter.java b/plugins/cucumber-jvm-formatter3/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm3SMFormatter.java new file mode 100644 index 000000000000..90b3822daca0 --- /dev/null +++ b/plugins/cucumber-jvm-formatter3/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm3SMFormatter.java @@ -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); + } +}