diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cec296e3..4673214ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt ## [Unreleased] ### Fixed +- [.NET] Provide informative exception for trailing escapes in tables ([#245](https://github.com/cucumber/gherkin/pull/245)) +- [Perl] Provide informative exception for trailing escapes in tables ([#245](https://github.com/cucumber/gherkin/pull/245)) - [Ruby] Provide informative exception for trailing escapes in tables ([#244](https://github.com/cucumber/gherkin/pull/244)) - [Python] Provide informative exception for trailing escapes in tables ([#241](https://github.com/cucumber/gherkin/pull/241)) - (i18n) Provide trailing space in Irish step keywords ([#243](https://github.com/cucumber/gherkin/pull/243)) diff --git a/dotnet/Gherkin/GherkinLine.cs b/dotnet/Gherkin/GherkinLine.cs index 2c131b70b..60922ed32 100644 --- a/dotnet/Gherkin/GherkinLine.cs +++ b/dotnet/Gherkin/GherkinLine.cs @@ -125,16 +125,19 @@ private IEnumerable> SplitCells(string row) cell = ""; startPos = pos; } else if (c == GherkinLanguageConstants.TABLE_CELL_ESCAPE_CHAR) { - rowEnum.MoveNext(); - pos++; - c = rowEnum.Current; - if (c == GherkinLanguageConstants.TABLE_CELL_NEWLINE_ESCAPE) { - cell += "\n"; - } else { - if (c.ToString() != GherkinLanguageConstants.TABLE_CELL_SEPARATOR && c != GherkinLanguageConstants.TABLE_CELL_ESCAPE_CHAR) { - cell += GherkinLanguageConstants.TABLE_CELL_ESCAPE_CHAR; + if(rowEnum.MoveNext()) { + pos++; + c = rowEnum.Current; + if (c == GherkinLanguageConstants.TABLE_CELL_NEWLINE_ESCAPE) { + cell += "\n"; + } else { + if (c.ToString() != GherkinLanguageConstants.TABLE_CELL_SEPARATOR && c != GherkinLanguageConstants.TABLE_CELL_ESCAPE_CHAR) { + cell += GherkinLanguageConstants.TABLE_CELL_ESCAPE_CHAR; + } + cell += c; } - cell += c; + } else { + cell += GherkinLanguageConstants.TABLE_CELL_ESCAPE_CHAR; } } else { cell += c; diff --git a/perl/lib/Gherkin/Line.pm b/perl/lib/Gherkin/Line.pm index 2e879bd04..2c311513c 100644 --- a/perl/lib/Gherkin/Line.pm +++ b/perl/lib/Gherkin/Line.pm @@ -86,9 +86,12 @@ sub _split_table_cells_iterator { return ( $cell, $start_col ); } } elsif ( $char eq "\\" ) { - $row =~ s/^(.)// || die "Unpossible"; - $col += 1; - $cell .= '\\' . $1; + if ($row =~ s/^(.)//) { + $col += 1; + $cell .= '\\' . $1; + } else { + $cell .= '\\'; + } } elsif ( defined $char ) { $cell .= $char; } else { diff --git a/testdata/good/extra_table_content.feature b/testdata/good/extra_table_content.feature new file mode 100644 index 000000000..4c0e8b223 --- /dev/null +++ b/testdata/good/extra_table_content.feature @@ -0,0 +1,12 @@ +Feature: Extra table content + Tables are delimited by pipes on both sides. + Anything that isn't enclosed is not part of + the table. + + It is not recommended to use this feature, but + it is how the implementation currently works. + + Scenario: We're a bit extra + Given a pirate crew + | Luffy | Zorro | Doflamingo \ + | Nami | Brook | BlackBeard diff --git a/testdata/good/extra_table_content.feature.ast.ndjson b/testdata/good/extra_table_content.feature.ast.ndjson new file mode 100644 index 000000000..39ff30692 --- /dev/null +++ b/testdata/good/extra_table_content.feature.ast.ndjson @@ -0,0 +1 @@ +{"gherkinDocument": {"comments": [], "feature": {"children": [{"scenario": {"description": "", "examples": [], "id": "3", "keyword": "Scenario", "location": {"column": 3, "line": 9}, "name": "We're a bit extra", "steps": [{"dataTable": {"location": {"column": 7, "line": 11}, "rows": [{"cells": [{"location": {"column": 9, "line": 11}, "value": "Luffy"}, {"location": {"column": 17, "line": 11}, "value": "Zorro"}], "id": "0", "location": {"column": 7, "line": 11}}, {"cells": [{"location": {"column": 9, "line": 12}, "value": "Nami"}, {"location": {"column": 17, "line": 12}, "value": "Brook"}], "id": "1", "location": {"column": 7, "line": 12}}]}, "id": "2", "keyword": "Given ", "keywordType": "Context", "location": {"column": 5, "line": 10}, "text": "a pirate crew"}], "tags": []}}], "description": " Tables are delimited by pipes on both sides.\n Anything that isn't enclosed is not part of\n the table.\n\n It is not recommended to use this feature, but\n it is how the implementation currently works.", "keyword": "Feature", "language": "en", "location": {"column": 1, "line": 1}, "name": "Extra table content", "tags": []}, "uri": "../testdata/good/extra_table_content.feature"}} diff --git a/testdata/good/extra_table_content.feature.pickles.ndjson b/testdata/good/extra_table_content.feature.pickles.ndjson new file mode 100644 index 000000000..f2f26999b --- /dev/null +++ b/testdata/good/extra_table_content.feature.pickles.ndjson @@ -0,0 +1 @@ +{"pickle": {"astNodeIds": ["3"], "id": "5", "language": "en", "name": "We're a bit extra", "steps": [{"argument": {"dataTable": {"rows": [{"cells": [{"value": "Luffy"}, {"value": "Zorro"}]}, {"cells": [{"value": "Nami"}, {"value": "Brook"}]}]}}, "astNodeIds": ["2"], "id": "4", "text": "a pirate crew", "type": "Context"}], "tags": [], "uri": "../testdata/good/extra_table_content.feature"}} diff --git a/testdata/good/extra_table_content.feature.source.ndjson b/testdata/good/extra_table_content.feature.source.ndjson new file mode 100644 index 000000000..0e659de5c --- /dev/null +++ b/testdata/good/extra_table_content.feature.source.ndjson @@ -0,0 +1 @@ +{"source": {"data": "Feature: Extra table content\n Tables are delimited by pipes on both sides.\n Anything that isn't enclosed is not part of\n the table.\n\n It is not recommended to use this feature, but\n it is how the implementation currently works.\n\n Scenario: We're a bit extra\n Given a pirate crew\n | Luffy | Zorro | Doflamingo \\\n | Nami | Brook | BlackBeard\n", "mediaType": "text/x.cucumber.gherkin+plain", "uri": "../testdata/good/extra_table_content.feature"}} diff --git a/testdata/good/extra_table_content.feature.tokens b/testdata/good/extra_table_content.feature.tokens new file mode 100644 index 000000000..650c8db2d --- /dev/null +++ b/testdata/good/extra_table_content.feature.tokens @@ -0,0 +1,13 @@ +(1:1)FeatureLine:()Feature/Extra table content/ +(2:1)Other:/ Tables are delimited by pipes on both sides./ +(3:1)Other:/ Anything that isn't enclosed is not part of/ +(4:1)Other:/ the table./ +(5:1)Other:// +(6:1)Other:/ It is not recommended to use this feature, but/ +(7:1)Other:/ it is how the implementation currently works./ +(8:1)Other:// +(9:3)ScenarioLine:()Scenario/We're a bit extra/ +(10:5)StepLine:(Context)Given /a pirate crew/ +(11:7)TableRow://9:Luffy,17:Zorro +(12:7)TableRow://9:Nami,17:Brook +EOF