diff --git a/CHANGES.md b/CHANGES.md index 4f892a69b8..62f3c85365 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,9 @@ Grammars: - enh(cmake) support bracket comments [Hirse][] - enh(java) add yield keyword to java [MBoegers][] - enh(java) add permits keyword to java [MBoegers][] +- fix(gherkin) update keyword list [Hirse][] +- fix(gherkin) variables can't contain whitespace [Hirse][] +- ehn(gherkin) docstrings can use backticks [Hirse][] [Josh Goebel]: https://github.com/joshgoebel [Josh Temple]: https://github.com/joshtemple diff --git a/src/languages/gherkin.js b/src/languages/gherkin.js index 8ec2fc9701..689c38b05e 100644 --- a/src/languages/gherkin.js +++ b/src/languages/gherkin.js @@ -5,43 +5,72 @@ Website: https://cucumber.io/docs/gherkin/ */ +const VARIABLE = { + scope: 'variable', + begin: /<[^>\s]+>/ +}; + export default function(hljs) { return { name: 'Gherkin', aliases: [ 'feature' ], - keywords: 'Feature Background Ability Business\ Need Scenario Scenarios Scenario\ Outline Scenario\ Template Examples Given And Then But When', + // No global keywords since they're all situational contains: [ { - className: 'symbol', - begin: '\\*', - relevance: 0 + // Eat whitespace at the start of the line + begin: /^[ \t]+/, + relevance: 0, }, { - className: 'meta', - begin: '@[^@\\s]+' + // "Business Need" and "Ability" are not part of the spec above, but are included in the English "translation" + // https://cucumber.io/docs/gherkin/languages/#gherkin-dialect-en-content + begin: [ + /(Feature|Business Need|Ability|Rule|Examples?|Scenario(?:s| Outline| Template)?|Background)/, + /:/ + ], + beginScope: { + 1: 'keyword', + 2: 'punctuation', + }, + end: /$/, + relevance: 10, + contains: [ VARIABLE ] }, { - begin: '\\|', - end: '\\|\\w*$', - contains: [ - { - className: 'string', - begin: '[^|]+' - } - ] + begin: /(?:Given|When|Then|And|But)\b/, + beginScope: 'keyword', + end: /$/, + contains: [ VARIABLE ] + }, + { + begin: /\*(?=[ \t])/, + relevance: 0, + beginScope: 'keyword', + end: /$/, + contains: [ VARIABLE ] }, { - className: 'variable', - begin: '<', - end: '>' + scope: 'meta', + begin: /@[^@\s]+/ }, hljs.HASH_COMMENT_MODE, { - className: 'string', - begin: '"""', - end: '"""' + scope: 'string', + variants: [ + { + begin: /"""/, + end: /"""/ + }, + { + begin: /```/, + end: /```/ + } + ] + }, + { + begin: /\|.*\|$/, + scope: 'string' }, - hljs.QUOTE_STRING_MODE ] }; } diff --git a/test/markup/gherkin/default.expect.txt b/test/markup/gherkin/default.expect.txt index 2da0e9ddad..371fff34a1 100644 --- a/test/markup/gherkin/default.expect.txt +++ b/test/markup/gherkin/default.expect.txt @@ -1,12 +1,12 @@ # language: en -Feature: Addition +Feature: Addition In order to avoid silly mistakes As a math idiot I want to be told the sum of two numbers @this_is_a_tag - Scenario Outline: Add two numbers - * I have a calculator + Scenario Outline: Add two numbers + * I have a calculator Given I have entered <input_1> into the calculator And I have entered <input_2> into the calculator When I press <button> @@ -18,8 +18,8 @@ multiline text """ - Examples: - | input_1 | input_2 | button | output | - | 20 | 30 | add | 50 | - | 2 | 5 | add | 7 | - | 0 | 40 | add | 40 | + Examples: + | input_1 | input_2 | button | output | + | 20 | 30 | add | 50 | + | 2 | 5 | add | 7 | + | 0 | 40 | add | 40 | diff --git a/test/markup/gherkin/docstrings.expect.txt b/test/markup/gherkin/docstrings.expect.txt new file mode 100644 index 0000000000..c275d21df2 --- /dev/null +++ b/test/markup/gherkin/docstrings.expect.txt @@ -0,0 +1,21 @@ +Given a blog post named "Random" with Markdown body + """ + Some Title, Eh? + =============== + Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. + """ + +Given a blog post named "Random" with Markdown body + ``` + Some Title, Eh? + =============== + Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. + ``` + +Given the following users exist: + | name | email | twitter | + | Aslak | aslak@cucumber.io | @aslak_hellesoy | + | Julien | julien@cucumber.io | @jbpros | + | Matt | matt@cucumber.io | @mattwynne | diff --git a/test/markup/gherkin/docstrings.txt b/test/markup/gherkin/docstrings.txt new file mode 100644 index 0000000000..90941a5c1c --- /dev/null +++ b/test/markup/gherkin/docstrings.txt @@ -0,0 +1,21 @@ +Given a blog post named "Random" with Markdown body + """ + Some Title, Eh? + =============== + Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. + """ + +Given a blog post named "Random" with Markdown body + ``` + Some Title, Eh? + =============== + Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, + consectetur adipiscing elit. + ``` + +Given the following users exist: + | name | email | twitter | + | Aslak | aslak@cucumber.io | @aslak_hellesoy | + | Julien | julien@cucumber.io | @jbpros | + | Matt | matt@cucumber.io | @mattwynne | diff --git a/test/markup/gherkin/keywords.expect.txt b/test/markup/gherkin/keywords.expect.txt new file mode 100644 index 0000000000..dc0255fbfd --- /dev/null +++ b/test/markup/gherkin/keywords.expect.txt @@ -0,0 +1,34 @@ +Feature: some feature + + Rule: some rule + + Background: + Given some background + + Example: an example + Given the conditions + And some other conditions + * same as and + But not these conditions + When something happens + And something else + Then I do this + + Scenario: same as example + Given the conditions + And some other conditions + * same as and + But not these conditions + When something happens + And something else + Then I do this + + Scenario Outline: some outline + Examples: part of outline + When a + Then b + + Scenario Template: same as scenario outline + Scenarios: same as examples + When a + Then b diff --git a/test/markup/gherkin/keywords.txt b/test/markup/gherkin/keywords.txt new file mode 100644 index 0000000000..e2cb983106 --- /dev/null +++ b/test/markup/gherkin/keywords.txt @@ -0,0 +1,34 @@ +Feature: some feature + + Rule: some rule + + Background: + Given some background + + Example: an example + Given the conditions + And some other conditions + * same as and + But not these conditions + When something happens + And something else + Then I do this + + Scenario: same as example + Given the conditions + And some other conditions + * same as and + But not these conditions + When something happens + And something else + Then I do this + + Scenario Outline: some outline + Examples: part of outline + When a + Then b + + Scenario Template: same as scenario outline + Scenarios: same as examples + When a + Then b diff --git a/test/markup/gherkin/variables.expect.txt b/test/markup/gherkin/variables.expect.txt new file mode 100644 index 0000000000..ad07389f68 --- /dev/null +++ b/test/markup/gherkin/variables.expect.txt @@ -0,0 +1,5 @@ +Scenario Outline: Add two numbers + Given I have entered <input_1> into the calculator + And I have entered <input_2> into the calculator + And first < second and second > first + Then second <- first diff --git a/test/markup/gherkin/variables.txt b/test/markup/gherkin/variables.txt new file mode 100644 index 0000000000..cd5e26ca7e --- /dev/null +++ b/test/markup/gherkin/variables.txt @@ -0,0 +1,5 @@ +Scenario Outline: Add two numbers + Given I have entered into the calculator + And I have entered into the calculator + And first < second and second > first + Then second <- first