Skip to content

Loading…

Add error check to scenario outline, add java snippet escaping for + and . #596

Merged
merged 3 commits into from

2 participants

@guyburton

There is an issue that a step such as Given < some data > with a table like
| some data |
| |

will throw an IndexOutOfBoundsException in the UnderscoreFunctionNameSanitizer. The token gets replaced with blank causing the issue. The test case below replicates the issue but I dont suggest adding this to the test suite.

I've added two checks- one in the sanitizer itself, and one in the calling code, which gives a more understandable error message for people who implement the step definition above.

I also added . and + to the list of escaped characters for the regex pattern generation since these were missing and added a test case for the UnderscoreFunctionNameSanitizer.

// throws IndexOutOfBoundsException
@Test
public void outlineReferenceWithNoOtherTextAndNoValueCausesException() {
    List<DataTableRow> rows = asList(new DataTableRow(NO_COMMENTS, asList("", ""), 1));
    Step outlineStep = new Step(NO_COMMENTS, "Given ", "<reference>", 0, rows, null);

    Step step = CucumberScenarioOutline.createExampleStep(
            outlineStep,
            new ExamplesTableRow(NO_COMMENTS, asList("reference"), 1, ""), // header
            new ExamplesTableRow(NO_COMMENTS, asList(""), 1, "")); // data

    new SnippetGenerator(new JavaSnippet()).getSnippet(step, new UnderscoreFunctionNameSanitizer());
}
@aslakhellesoy aslakhellesoy added a commit that referenced this pull request
@aslakhellesoy aslakhellesoy Attribution for #596 eadbc52
@aslakhellesoy aslakhellesoy merged commit a280f2f into cucumber:master

1 check passed

Details default The Travis CI build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
View
13 core/src/main/java/cucumber/runtime/model/CucumberScenarioOutline.java
@@ -1,5 +1,6 @@
package cucumber.runtime.model;
+import cucumber.runtime.CucumberException;
import cucumber.runtime.Runtime;
import gherkin.formatter.Formatter;
import gherkin.formatter.Reporter;
@@ -103,13 +104,17 @@ private static DocString docStringWithTokensReplaced(DocString docString, List<S
}
private static String replaceTokens(Set<Integer> matchedColumns, List<String> headerCells, List<String> exampleCells, String text) {
- for (int i = 0; i < headerCells.size(); i++) {
- String headerCell = headerCells.get(i);
- String value = exampleCells.get(i);
+ for (int col = 0; col < headerCells.size(); col++) {
+ String headerCell = headerCells.get(col);
+ String value = exampleCells.get(col);
String token = "<" + headerCell + ">";
+
if (text.contains(token)) {
text = text.replace(token, value);
- matchedColumns.add(i);
+ if (text.isEmpty()) {
+ throw new CucumberException("Step generated from scenario outline '" + token + "' is empty");
+ }
+ matchedColumns.add(col);
}
}
return text;
View
2 core/src/main/java/cucumber/runtime/snippets/SnippetGenerator.java
@@ -24,6 +24,8 @@
Pattern.compile("\\]"),
Pattern.compile("\\?"),
Pattern.compile("\\*"),
+ Pattern.compile("\\+"),
+ Pattern.compile("\\."),
Pattern.compile("\\^"),};
private static final String REGEXP_HINT = "Express the Regexp above with the code you wish you had";
View
3 core/src/main/java/cucumber/runtime/snippets/UnderscoreFunctionNameSanitizer.java
@@ -7,6 +7,9 @@ public String sanitizeFunctionName(String functionName) {
StringBuilder sanitized = new StringBuilder();
String trimmedFunctionName = functionName.trim();
+ if (trimmedFunctionName.isEmpty()) {
+ throw new IllegalArgumentException("Cannot have empty function name");
+ }
sanitized.append(Character.isJavaIdentifierStart(trimmedFunctionName.charAt(0)) ? trimmedFunctionName.charAt(0) : SUBST);
for (int i = 1; i < trimmedFunctionName.length(); i++) {
View
20 core/src/test/java/cucumber/runtime/snippets/UnderscoreFunctionNameSanitizerTest.java
@@ -0,0 +1,20 @@
+package cucumber.runtime.snippets;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class UnderscoreFunctionNameSanitizerTest {
+
+ private UnderscoreFunctionNameSanitizer sanitizer = new UnderscoreFunctionNameSanitizer();
+
+ @Test
+ public void testSanitizeFunctionName() {
+ assertEquals("_test_function_123", sanitizer.sanitizeFunctionName(".test function 123 "));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSanitizeEmptyFunctionName() {
+ sanitizer.sanitizeFunctionName("");
+ }
+
+}
View
4 java/src/test/java/cucumber/runtime/java/JavaSnippetTest.java
@@ -90,12 +90,12 @@ public void generatesSnippetWithEscapedQuestionMarks() {
@Test
public void generatesSnippetWithLotsOfEscapes() {
String expected = "" +
- "@Given(\"^\\\\^\\\\(\\\\[a-z\\\\]\\\\*\\\\)\\\\?\\\\$$\")\n" +
+ "@Given(\"^\\\\^\\\\(\\\\[a-z\\\\]\\\\*\\\\)\\\\?\\\\.\\\\+\\\\$$\")\n" +
"public void _a_z_$() throws Throwable {\n" +
" // Express the Regexp above with the code you wish you had\n" +
" throw new PendingException();\n" +
"}\n";
- assertEquals(expected, snippetFor("^([a-z]*)?$"));
+ assertEquals(expected, snippetFor("^([a-z]*)?.+$"));
}
@Test
Something went wrong with that request. Please try again.