Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Gherkin support #3643

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Expand Up @@ -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
Expand Down
71 changes: 50 additions & 21 deletions src/languages/gherkin.js
Expand Up @@ -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
]
};
}
16 changes: 8 additions & 8 deletions test/markup/gherkin/default.expect.txt
@@ -1,12 +1,12 @@
<span class="hljs-comment"># language: en</span>
<span class="hljs-keyword">Feature</span>: Addition
<span class="hljs-keyword">Feature</span><span class="hljs-punctuation">:</span> Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers

<span class="hljs-meta">@this_is_a_tag</span>
<span class="hljs-keyword">Scenario</span> <span class="hljs-keyword">Outline</span>: Add two numbers
<span class="hljs-symbol">*</span> I have a calculator
<span class="hljs-keyword">Scenario Outline</span><span class="hljs-punctuation">:</span> Add two numbers
<span class="hljs-keyword">*</span> I have a calculator
<span class="hljs-keyword">Given</span> I have entered <span class="hljs-variable">&lt;input_1&gt;</span> into the calculator
<span class="hljs-keyword">And</span> I have entered <span class="hljs-variable">&lt;input_2&gt;</span> into the calculator
<span class="hljs-keyword">When</span> I press <span class="hljs-variable">&lt;button&gt;</span>
Expand All @@ -18,8 +18,8 @@
multiline text
&quot;&quot;&quot;</span>

<span class="hljs-keyword">Examples</span>:
|<span class="hljs-string"> input_1 </span>|<span class="hljs-string"> input_2 </span>|<span class="hljs-string"> button </span>|<span class="hljs-string"> output </span>|
|<span class="hljs-string"> 20 </span>|<span class="hljs-string"> 30 </span>|<span class="hljs-string"> add </span>|<span class="hljs-string"> 50 </span>|
|<span class="hljs-string"> 2 </span>|<span class="hljs-string"> 5 </span>|<span class="hljs-string"> add </span>|<span class="hljs-string"> 7 </span>|
|<span class="hljs-string"> 0 </span>|<span class="hljs-string"> 40 </span>|<span class="hljs-string"> add </span>|<span class="hljs-string"> 40 </span>|
<span class="hljs-keyword">Examples</span><span class="hljs-punctuation">:</span>
<span class="hljs-string">| input_1 | input_2 | button | output |</span>
<span class="hljs-string">| 20 | 30 | add | 50 |</span>
<span class="hljs-string">| 2 | 5 | add | 7 |</span>
<span class="hljs-string">| 0 | 40 | add | 40 |</span>
21 changes: 21 additions & 0 deletions test/markup/gherkin/docstrings.expect.txt
@@ -0,0 +1,21 @@
<span class="hljs-keyword">Given</span> a blog post named &quot;Random&quot; with Markdown body
<span class="hljs-string">&quot;&quot;&quot;
Some Title, Eh?
===============
Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
&quot;&quot;&quot;</span>

<span class="hljs-keyword">Given</span> a blog post named &quot;Random&quot; with Markdown body
<span class="hljs-string">```
Some Title, Eh?
===============
Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
```</span>

<span class="hljs-keyword">Given</span> the following users exist:
<span class="hljs-string">| name | email | twitter |</span>
<span class="hljs-string">| Aslak | aslak@cucumber.io | @aslak_hellesoy |</span>
<span class="hljs-string">| Julien | julien@cucumber.io | @jbpros |</span>
<span class="hljs-string">| Matt | matt@cucumber.io | @mattwynne |</span>
21 changes: 21 additions & 0 deletions 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 |
34 changes: 34 additions & 0 deletions test/markup/gherkin/keywords.expect.txt
@@ -0,0 +1,34 @@
<span class="hljs-keyword">Feature</span><span class="hljs-punctuation">:</span> some feature

<span class="hljs-keyword">Rule</span><span class="hljs-punctuation">:</span> some rule

<span class="hljs-keyword">Background</span><span class="hljs-punctuation">:</span>
<span class="hljs-keyword">Given</span> some background

<span class="hljs-keyword">Example</span><span class="hljs-punctuation">:</span> an example
<span class="hljs-keyword">Given</span> the conditions
<span class="hljs-keyword">And</span> some other conditions
<span class="hljs-keyword">*</span> same as and
<span class="hljs-keyword">But</span> not these conditions
<span class="hljs-keyword">When</span> something happens
<span class="hljs-keyword">And</span> something else
<span class="hljs-keyword">Then</span> I do this

<span class="hljs-keyword">Scenario</span><span class="hljs-punctuation">:</span> same as example
<span class="hljs-keyword">Given</span> the conditions
<span class="hljs-keyword">And</span> some other conditions
<span class="hljs-keyword">*</span> same as and
<span class="hljs-keyword">But</span> not these conditions
<span class="hljs-keyword">When</span> something happens
<span class="hljs-keyword">And</span> something else
<span class="hljs-keyword">Then</span> I do this

<span class="hljs-keyword">Scenario Outline</span><span class="hljs-punctuation">:</span> some outline
<span class="hljs-keyword">Examples</span><span class="hljs-punctuation">:</span> part of outline
<span class="hljs-keyword">When</span> a
<span class="hljs-keyword">Then</span> b

<span class="hljs-keyword">Scenario Template</span><span class="hljs-punctuation">:</span> same as scenario outline
<span class="hljs-keyword">Scenarios</span><span class="hljs-punctuation">:</span> same as examples
<span class="hljs-keyword">When</span> a
<span class="hljs-keyword">Then</span> b
34 changes: 34 additions & 0 deletions 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
5 changes: 5 additions & 0 deletions test/markup/gherkin/variables.expect.txt
@@ -0,0 +1,5 @@
<span class="hljs-keyword">Scenario Outline</span><span class="hljs-punctuation">:</span> Add two numbers
<span class="hljs-keyword">Given</span> I have entered <span class="hljs-variable">&lt;input_1&gt;</span> into the calculator
<span class="hljs-keyword">And</span> I have entered <span class="hljs-variable">&lt;input_2&gt;</span> into the calculator
<span class="hljs-keyword">And</span> first &lt; second and second &gt; first
<span class="hljs-keyword">Then</span> second &lt;- first
5 changes: 5 additions & 0 deletions test/markup/gherkin/variables.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