Cucumber for Java: unify escaping moment for all cucumber versions
authorAndrey Vokin <andrey.vokin@jetbrains.com>
Tue, 22 Jan 2019 15:36:57 +0000 (16:36 +0100)
committerAndrey Vokin <andrey.vokin@jetbrains.com>
Tue, 22 Jan 2019 15:44:58 +0000 (16:44 +0100)
 * now definitely all command arguments are escaped
 * there is no need to escape brackets '[' and ']'

plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm2SMFormatter.java
plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvmSMFormatter.java
plugins/cucumber-jvm-formatter/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvmSMFormatterUtil.java
plugins/cucumber-jvm-formatter3/src/org/jetbrains/plugins/cucumber/java/run/CucumberJvm3SMFormatter.java

index f543df25d63712e3f1b7d739ff6157217f336f02..e605dde4cae6fe8bae8b8e53da1dbb66bc1d6a04 100644 (file)
@@ -36,8 +36,8 @@ public class CucumberJvm2SMFormatter implements Formatter {
   public CucumberJvm2SMFormatter(PrintStream out, String currentTimeValue) {
     myOut = out;
     myCurrentTimeValue = currentTimeValue;
-    outCommand(String.format(TEMPLATE_ENTER_THE_MATRIX, getCurrentTime()));
-    outCommand(String.format(TEMPLATE_SCENARIO_COUNTING_STARTED, 0, getCurrentTime()));
+    outCommand(TEMPLATE_ENTER_THE_MATRIX, getCurrentTime());
+    outCommand(TEMPLATE_SCENARIO_COUNTING_STARTED, "0", getCurrentTime());
   }
 
   private final EventHandler<TestCaseStarted> testCaseStartedHandler = new EventHandler<TestCaseStarted>() {
@@ -96,18 +96,15 @@ public class CucumberJvm2SMFormatter implements Formatter {
 
   private void handleTestCaseStarted(TestCaseStarted event) {
     if (currentFilePath == null) {
-      outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), escape(getEventUri(event)),
-                               escape(getFeatureFileDescription(getEventUri(event)))));
+      outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), getEventUri(event), getFeatureFileDescription(getEventUri(event)));
     }
     else if (!getEventUri(event).equals(currentFilePath)) {
       closeCurrentScenarioOutline();
-      outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(),
-                               escape(getFeatureFileDescription(currentFilePath))));
-      outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), escape(getEventUri(event)),
-                               escape(getFeatureFileDescription(getEventUri(event)))));
+      outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getFeatureFileDescription(currentFilePath));
+      outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), getEventUri(event), getFeatureFileDescription(getEventUri(event)));
     }
 
-    outCommand(String.format(TEMPLATE_SCENARIO_STARTED, getCurrentTime()));
+    outCommand(TEMPLATE_SCENARIO_STARTED, getCurrentTime());
 
     if (isScenarioOutline(event.testCase)) {
       int mainScenarioLine = getScenarioOutlineLine(event.testCase);
@@ -116,56 +113,51 @@ public class CucumberJvm2SMFormatter implements Formatter {
         closeCurrentScenarioOutline();
         currentScenarioOutlineLine = mainScenarioLine;
         currentScenarioOutlineName = getEventName(event);
-        outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(),
-                                 escape(getEventUri(event)) + ":" + currentScenarioOutlineLine, escape(currentScenarioOutlineName)));
-        outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), "", EXAMPLES_CAPTION));
+        outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), getEventUri(event) + ":" + currentScenarioOutlineLine,
+                   currentScenarioOutlineName);
+        outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), "", EXAMPLES_CAPTION);
       }
     } else {
       closeCurrentScenarioOutline();
     }
     currentFilePath = getEventUri(event);
 
-    outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(),
-                             escape(getEventUri(event)) + ":" + getEventLine(event), escape(getScenarioName(event))));
+    outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), getEventUri(event) + ":" + getEventLine(event), getScenarioName(event));
   }
 
   private void handleTestCaseFinished(TestCaseFinished event) {
-    outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), escape(getScenarioName(event))));
-    outCommand(String.format(TEMPLATE_SCENARIO_FINISHED, getCurrentTime()));
+    outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getScenarioName(event));
+    outCommand(TEMPLATE_SCENARIO_FINISHED, getCurrentTime());
   }
 
   private void handleTestRunFinished(TestRunFinished event) {
     closeCurrentScenarioOutline();
-    outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(),
-                             escape(getFeatureFileDescription(currentFilePath))));
+    outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getFeatureFileDescription(currentFilePath));
   }
   private void handleTestStepStarted(TestStepStarted event) {
-    outCommand(String.format(TEMPLATE_TEST_STARTED, getCurrentTime(), escape(getStepLocation(event)),
-                             escape(getStepName(event))));
+    outCommand(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, escape(getStepName(event)), getCurrentTime()));
+      outCommand(TEMPLATE_TEST_PENDING, getStepName(event), getCurrentTime());
     } else {
       String[] messageAndDetails = getMessageAndDetails(event.result.getErrorMessage());
 
       ComparisonFailureData comparisonFailureData = ExpectedPatterns.createExceptionNotification(messageAndDetails[0]);
       if (comparisonFailureData != null) {
-        outCommand(String.format(TEMPLATE_COMPARISON_TEST_FAILED, getCurrentTime(), escape(messageAndDetails[1]),
-                                 escape(messageAndDetails[0]), escape(comparisonFailureData.getExpected()),
-                                 escape(comparisonFailureData.getActual()), escape(getStepName(event)), ""));
+        outCommand(TEMPLATE_COMPARISON_TEST_FAILED, getCurrentTime(), messageAndDetails[1], messageAndDetails[0],
+                   comparisonFailureData.getExpected(), comparisonFailureData.getActual(), getStepName(event), "");
       }
       else {
-        outCommand(String.format(TEMPLATE_TEST_FAILED, getCurrentTime(), "", escape(event.result.getErrorMessage()),
-                                 escape(getStepName(event)), ""));
+        outCommand(TEMPLATE_TEST_FAILED, getCurrentTime(), "", event.result.getErrorMessage(), getStepName(event), "");
       }
 
     }
     Long duration = event.result.getDuration() != null ? event.result.getDuration() / 1000000: 0;
-    outCommand(String.format(TEMPLATE_TEST_FINISHED, getCurrentTime(), duration, escape(getStepName(event))));
+    outCommand(TEMPLATE_TEST_FINISHED, getCurrentTime(), String.valueOf(duration), getStepName(event));
   }
 
   private String getFeatureFileDescription(String uri) {
@@ -182,8 +174,8 @@ public class CucumberJvm2SMFormatter implements Formatter {
 
   private void closeCurrentScenarioOutline() {
     if (currentScenarioOutlineLine > 0) {
-      outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), EXAMPLES_CAPTION));
-      outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), escape(currentScenarioOutlineName)));
+      outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), EXAMPLES_CAPTION);
+      outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), currentScenarioOutlineName);
       currentScenarioOutlineLine = 0;
       currentScenarioOutlineName = null;
     }
@@ -250,8 +242,8 @@ public class CucumberJvm2SMFormatter implements Formatter {
     return stepName;
   }
 
-  private void outCommand(String s) {
-    myOut.println(s);
+  private void outCommand(String command, String... parameters) {
+    myOut.println(escapeCommand(command, parameters));
   }
 
   private static PickleEvent getPickleEvent(TestCase testCase) {
index f523e164032264c76fbb59dd9e071c67f4da7e2c..6b080ac12a2a559b58b4a55ef91bf3df1feb59c0 100644 (file)
@@ -49,8 +49,8 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
     this.appendable = System.err;
     queue = new ArrayDeque<String>();
     currentSteps = new ArrayDeque<Step>();
-    outCommand(String.format(TEMPLATE_ENTER_THE_MATRIX, getCurrentTime()));
-    outCommand(String.format(TEMPLATE_SCENARIO_COUNTING_STARTED, 0, getCurrentTime()));
+    outCommand(TEMPLATE_ENTER_THE_MATRIX, getCurrentTime());
+    outCommand(TEMPLATE_SCENARIO_COUNTING_STARTED, "0", getCurrentTime());
   }
 
   @Override
@@ -59,7 +59,7 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
       done();
     }
     currentFeatureName = "Feature: " + getName(feature);
-    outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + feature.getLine(), currentFeatureName));
+    outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + feature.getLine(), currentFeatureName);
   }
 
   private static boolean isRealScenario(final Scenario scenario) {
@@ -69,7 +69,7 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
   @Override
   public void scenario(Scenario scenario) {
     closeScenario();
-    outCommand(String.format(TEMPLATE_SCENARIO_STARTED, getCurrentTime()));
+    outCommand(TEMPLATE_SCENARIO_STARTED, getCurrentTime());
     if (isRealScenario(scenario)) {
       scenarioCount++;
       closeScenarioOutline();
@@ -77,7 +77,7 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
     }
     currentScenario = scenario;
     beforeExampleSection = false;
-    outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + scenario.getLine(), getName(currentScenario)));
+    outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + scenario.getLine(), getName(currentScenario));
 
     while (queue.size() > 0) {
       String smMessage = queue.poll();
@@ -95,14 +95,13 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
     currentScenarioOutline = outline;
     currentScenario = null;
     beforeExampleSection = true;
-    outCommand(
-      String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + outline.getLine(), getName(currentScenarioOutline)));
+    outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + outline.getLine(), getName(currentScenarioOutline));
   }
 
   @Override
   public void examples(Examples examples) {
     beforeExampleSection = false;
-    outCommand(String.format(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + examples.getLine(), "Examples:"));
+    outCommand(TEMPLATE_TEST_SUITE_STARTED, getCurrentTime(), uri + ":" + examples.getLine(), "Examples:");
   }
 
   @Override
@@ -126,7 +125,7 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
   public void result(Result result) {
     stepCount++;
     Step currentStep = currentSteps.poll();
-    outCommand(String.format(TEMPLATE_TEST_STARTED, getCurrentTime(), uri + ":" + currentStep.getLine(), getName(currentStep)), true);
+    outCommand(TEMPLATE_TEST_STARTED, true, getCurrentTime(), uri + ":" + currentStep.getLine(), getName(currentStep));
     String stepFullName = getName(currentStep);
     if (result.getStatus().equals(Result.FAILED)) {
       failedStepCount++;
@@ -144,24 +143,24 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
         details = "";
       }
 
-      outCommand(String.format(TEMPLATE_TEST_FAILED, getCurrentTime(), escape(details), escape(message), stepFullName, ""), true);
+      outCommand(TEMPLATE_TEST_FAILED, true, getCurrentTime(), details, message, stepFullName, "");
     }
     else if (result.getStatus().equals(RESULT_STATUS_PENDING)) {
       pendingStepCount++;
       scenarioPassed = false;
-      outCommand(String.format(TEMPLATE_TEST_PENDING, stepFullName, getCurrentTime()), true);
+      outCommand(TEMPLATE_TEST_PENDING, true, stepFullName, getCurrentTime());
     }
     else if (result.equals(Result.UNDEFINED)) {
       undefinedStepCount++;
       scenarioPassed = false;
       String message = "Undefined step: " + getName(currentStep);
       String details = "";
-      outCommand(String.format(TEMPLATE_TEST_FAILED, getCurrentTime(), escape(details), escape(message), stepFullName, "error = 'true'"), true);
+      outCommand(TEMPLATE_TEST_FAILED, true, getCurrentTime(), details, message, stepFullName, "error = 'true'");
     }
     else if (result.equals(Result.SKIPPED)) {
       skippedStepCount++;
       scenarioPassed = false;
-      outCommand(String.format(TEMPLATE_TEST_PENDING, stepFullName, getCurrentTime()), true);
+      outCommand(TEMPLATE_TEST_PENDING, true, stepFullName, getCurrentTime());
     }
     else {
       passedStepCount++;
@@ -169,7 +168,8 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
 
     final String currentTime = getCurrentTime();
     final Long duration = result.getDuration();
-    outCommand(String.format(TEMPLATE_TEST_FINISHED, currentTime, (duration == null ? 0 : duration.longValue()) / MILLION, stepFullName), true);
+    double durationInSeconds = 1.0 * (duration == null ? 0 : duration.longValue()) / MILLION;
+    outCommand(TEMPLATE_TEST_FINISHED, true, currentTime, String.valueOf(durationInSeconds), stepFullName);
   }
 
   private void closeScenario() {
@@ -181,10 +181,10 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
       }
 
       if (!scenarioPassed) {
-        outCommand(String.format(TEMPLATE_SCENARIO_FAILED, getCurrentTime()), true);
+        outCommand(TEMPLATE_SCENARIO_FAILED, true, getCurrentTime());
       }
-      outCommand(String.format(TEMPLATE_SCENARIO_FINISHED, getCurrentTime()), true);
-      outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getName(currentScenario)));
+      outCommand(TEMPLATE_SCENARIO_FINISHED, true, getCurrentTime());
+      outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getName(currentScenario));
     }
     scenarioPassed = true;
     currentScenario = null;
@@ -196,9 +196,9 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
         passedScenarioCount++;
       }
       if (!beforeExampleSection) {
-        outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), "Examples:"));
+        outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), "Examples:");
       }
-      outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getName(currentScenarioOutline)));
+      outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), getName(currentScenarioOutline));
     }
     currentScenarioOutline = null;
   }
@@ -217,7 +217,7 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
   @Override
   public void done() {
     closePreviousScenarios();
-    outCommand(String.format(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), currentFeatureName));
+    outCommand(TEMPLATE_TEST_SUITE_FINISHED, getCurrentTime(), currentFeatureName);
   }
 
   @Override
@@ -266,27 +266,28 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
 
   @Override
   public void close() {
-    outCommand(String.format(TEMPLATE_SCENARIO_COUNTING_FINISHED, getCurrentTime()));
+    outCommand(TEMPLATE_SCENARIO_COUNTING_FINISHED, getCurrentTime());
   }
 
   @Override
   public void before(Match match, Result result) {
   }
 
-  private void outCommand(String s) {
-    outCommand(s, false);
+  private void outCommand(String command, String... parameters) {
+    outCommand(command, false, parameters);
   }
 
-  private void outCommand(String s, boolean waitForScenario) {
+  private void outCommand(String command, boolean waitForScenario, String... parameters) {
+    String line = escapeCommand(command, parameters);
     if (currentScenario == null && waitForScenario) {
-      queue.add(s);
+      queue.add(line);
     }
     else {
       try {
         if (!endedByNewLine) {
           appendable.append("\n");
         }
-        appendable.append(s);
+        appendable.append(line);
         appendable.append("\n");
         endedByNewLine = true;
       }
@@ -306,22 +307,22 @@ public class CucumberJvmSMFormatter implements Formatter, Reporter {
 
   private static String getName(Scenario scenario) {
     if (scenario.getKeyword().equals("Scenario Outline")) {
-      return escape("Scenario: Line: " + scenario.getLine());
+      return "Scenario: Line: " + scenario.getLine();
     }
     else {
-      return escape("Scenario: " + scenario.getName());
+      return "Scenario: " + scenario.getName();
     }
   }
 
   private static String getName(ScenarioOutline outline) {
-    return escape("Scenario Outline: " + outline.getName());
+    return "Scenario Outline: " + outline.getName();
   }
 
   private static String getName(Step step) {
-    return escape(step.getKeyword() + " " + step.getName());
+    return step.getKeyword() + " " + step.getName();
   }
 
   private static String getName(Feature feature) {
-    return escape(feature.getName());
+    return feature.getName();
   }
 }
index 4f06605490559aa799044ac72218bc3e97b083b2..63c66fc1b9fa0395ecd35287045ecbe11b416e76 100644 (file)
@@ -41,11 +41,23 @@ public class CucumberJvmSMFormatterUtil {
     return DATE_FORMAT.format(new Date());
   }
 
-  public static String escape(String source) {
+  private static String escape(String source) {
     if (source == null) {
       return "";
     }
-    return source.replace("|", "||").replace("\n", "|n").replace("\r", "|r").replace("'", "|'").replace("[", "|[").replace("]", "|]");
+    return source.replace("|", "||").replace("\n", "|n").replace("\r", "|r").replace("'", "|'");
+  }
+
+  /**
+   * escapes symbols: "|", "'" and new line so that not to tear SM messages
+   */
+  public static String escapeCommand(String command, String... parameters) {
+    String[] escapedParameters = new String[parameters.length];
+    for (int i = 0; i < escapedParameters.length; i++) {
+      escapedParameters[i] = escape(parameters[i]);
+    }
+
+    return String.format(command, (Object[])escapedParameters);
   }
 
   /**
index 90b3822daca09e695e144404d791032753e58dc5..de5a5830ecac2772993f110f6b44222ee6a9c08c 100644 (file)
@@ -13,7 +13,6 @@ 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 {
@@ -67,7 +66,7 @@ public class CucumberJvm3SMFormatter extends CucumberJvm2SMFormatter {
   }
 
   private static String getScenarioName(TestCase testCase) {
-    return escape("Scenario: " + testCase.getName());
+    return "Scenario: " + testCase.getName();
   }
 
   private static String getStepLocation(TestStep step) {
@@ -104,6 +103,6 @@ public class CucumberJvm3SMFormatter extends CucumberJvm2SMFormatter {
     } else {
       stepName = ((PickleStepTestStep) step).getPickleStep().getText();
     }
-    return escape(stepName);
+    return stepName;
   }
 }