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

Add descriptions support for the nodes: ExampleTable, Outline and Sce… #254

Open
wants to merge 2 commits into
base: master
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Behat/Gherkin/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,9 @@ protected function scanPyStringContent()
return null;
}

$token = $this->scanText();
$token = $this->takeToken('Text', $this->line);
$this->consumeLine();

// swallow trailing spaces
$token['value'] = preg_replace('/^\s{0,' . $this->pyStringSwallow . '}/u', '', $token['value'] ?? '');

Expand Down
6 changes: 4 additions & 2 deletions src/Behat/Gherkin/Loader/ArrayLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,14 @@ protected function loadScenarioHash(array $hash, $line = 0)
'keyword' => 'Scenario',
'line' => $line,
'steps' => array(),
'description' => null
),
$hash
);

$steps = $this->loadStepsHash($hash['steps']);

return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line']);
return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line'], $hash['description']);
}

/**
Expand All @@ -166,6 +167,7 @@ protected function loadOutlineHash(array $hash, $line = 0)
'line' => $line,
'steps' => array(),
'examples' => array(),
'description' => null
),
$hash
);
Expand All @@ -189,7 +191,7 @@ protected function loadOutlineHash(array $hash, $line = 0)
$examples[] = new ExampleTableNode($exHash, $examplesKeyword);;
}

return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']);
return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line'], $hash['description']);
}

/**
Expand Down
10 changes: 7 additions & 3 deletions src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ static function ($child) {
self::getSteps(isset($child['scenario']['steps']) ? $child['scenario']['steps'] : []),
self::getTables($child['scenario']['examples']),
$child['scenario']['keyword'],
$child['scenario']['location']['line']
$child['scenario']['location']['line'],
$child['scenario']['description'] ?? null
);
}
else {
Expand All @@ -94,7 +95,8 @@ static function ($child) {
self::getTags($child['scenario']),
self::getSteps(isset($child['scenario']['steps']) ? $child['scenario']['steps'] : []),
$child['scenario']['keyword'],
$child['scenario']['location']['line']
$child['scenario']['location']['line'],
$child['scenario']['description'] ?? null
);
}

Expand Down Expand Up @@ -184,7 +186,9 @@ static function($cell) {
return new ExampleTableNode(
$table,
$tableJson['keyword'],
self::getTags($tableJson)
self::getTags($tableJson),
$tableJson['name'] ?? null,
$tableJson['description'] ?? null
);
},
$json
Expand Down
36 changes: 35 additions & 1 deletion src/Behat/Gherkin/Node/ExampleTableNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,31 @@ class ExampleTableNode extends TableNode
*/
private $keyword;

/**
* @var null|string
*/
private $name;

/**
* @var null|string
*/
private $description;

/**
* Initializes example table.
*
* @param array $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
* @param string $keyword
* @param string[] $tags
* @param null|string $name
* @param null|string $description
*/
public function __construct(array $table, $keyword, array $tags = array())
public function __construct(array $table, $keyword, array $tags = [], ?string $name = null, ?string $description = null)
{
$this->keyword = $keyword;
$this->tags = $tags;
$this->name = $name;
$this->description = $description;

parent::__construct($table);
}
Expand Down Expand Up @@ -70,4 +84,24 @@ public function getKeyword()
{
return $this->keyword;
}

/**
* Returns the name.
*
* @return null|string
*/
public function getName()
{
return $this->name;
}

/**
* Returns the description.
*
* @return null|string
*/
public function getDescription()
{
return $this->description;
}
}
21 changes: 19 additions & 2 deletions src/Behat/Gherkin/Node/OutlineNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class OutlineNode implements ScenarioInterface
{
/**
* @var string
* @var null|string
*/
private $title;
/**
Expand All @@ -45,6 +45,10 @@ class OutlineNode implements ScenarioInterface
* @var null|ExampleNode[]
*/
private $examples;
/**
* @var null|string
*/
private $description;

/**
* Initializes outline.
Expand All @@ -55,14 +59,16 @@ class OutlineNode implements ScenarioInterface
* @param ExampleTableNode|ExampleTableNode[] $tables
* @param string $keyword
* @param integer $line
* @param null|string $description
*/
public function __construct(
$title,
array $tags,
array $steps,
$tables,
$keyword,
$line
$line,
?string $description = null
) {
$this->title = $title;
$this->tags = $tags;
Expand All @@ -74,6 +80,7 @@ public function __construct(
} else {
$this->tables = $tables;
}
$this->description = $description;
}

/**
Expand Down Expand Up @@ -219,6 +226,16 @@ public function getLine()
return $this->line;
}

/**
* Returns the description.
*
* @return null|string
*/
public function getDescription()
{
return $this->description;
}

/**
* Creates examples for this outline using examples table.
*
Expand Down
20 changes: 18 additions & 2 deletions src/Behat/Gherkin/Node/ScenarioNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class ScenarioNode implements ScenarioInterface
{
/**
* @var string
* @var null|string
*/
private $title;
/**
Expand All @@ -37,6 +37,10 @@ class ScenarioNode implements ScenarioInterface
* @var integer
*/
private $line;
/**
* @var null|string
*/
private $description;

/**
* Initializes scenario.
Expand All @@ -46,14 +50,16 @@ class ScenarioNode implements ScenarioInterface
* @param StepNode[] $steps
* @param string $keyword
* @param integer $line
* @param null|string $description
*/
public function __construct($title, array $tags, array $steps, $keyword, $line)
public function __construct($title, array $tags, array $steps, $keyword, $line, ?string $description = null)
{
$this->title = $title;
$this->tags = $tags;
$this->steps = $steps;
$this->keyword = $keyword;
$this->line = $line;
$this->description = $description;
}

/**
Expand Down Expand Up @@ -147,4 +153,14 @@ public function getLine()
{
return $this->line;
}

/**
* Returns the description.
*
* @return null|string
*/
public function getDescription()
{
return $this->description;
}
}
34 changes: 30 additions & 4 deletions src/Behat/Gherkin/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ protected function parseScenario()
$token = $this->expectTokenType('Scenario');

$title = trim($token['value'] ?? '');
$description = $this->parseDescription();
$tags = $this->popTags();
$keyword = $token['keyword'];
$line = $token['line'];
Expand Down Expand Up @@ -422,7 +423,7 @@ protected function parseScenario()

array_pop($this->passedNodesStack);

return new ScenarioNode(rtrim($title) ?: null, $tags, $steps, $keyword, $line);
return new ScenarioNode(rtrim($title) ?: null, $tags, $steps, $keyword, $line, $description);
}

/**
Expand All @@ -437,6 +438,7 @@ protected function parseOutline()
$token = $this->expectTokenType('Outline');

$title = trim($token['value'] ?? '');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why removing the trimming for scenario but not for outline ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought to make it compatible with the CompatibilityTest for the descriptions.feature.
I now see this is NOT the case. I will fix this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted the trim scenario title functionality.

$description = $this->parseDescription();
$tags = $this->popTags();
$keyword = $token['keyword'];

Expand Down Expand Up @@ -505,7 +507,7 @@ protected function parseOutline()
));
}

return new OutlineNode(rtrim($title) ?: null, $tags, $steps, $examples, $keyword, $line);
return new OutlineNode(rtrim($title) ?: null, $tags, $steps, $examples, $keyword, $line, $description);
}

/**
Expand Down Expand Up @@ -550,12 +552,15 @@ protected function parseStep()
*/
protected function parseExamples()
{
$keyword = ($this->expectTokenType('Examples'))['keyword'];
$token = $this->expectTokenType('Examples');
$keyword = $token['keyword'];
$name = $token['value'] ?? null;
$tags = empty($this->tags) ? array() : $this->popTags();
$description = $this->parseDescription();
$table = $this->parseTableRows();

try {
return new ExampleTableNode($table, $keyword, $tags);
return new ExampleTableNode($table, $keyword, $tags, $name, $description);
} catch(NodeException $e) {
$this->rethrowNodeException($e);
}
Expand Down Expand Up @@ -733,6 +738,27 @@ private function parseTableRows()
return $table;
}

/**
* @return string|null
*/
private function parseDescription()
{
$result = null;
while (null !== ($node = $this->acceptTokenType('Newline') ?? $this->acceptTokenType('Text'))) {
if ($node['type'] === 'Newline') {
$result .= "\n";
} else {
if ($result === null) {
$result = $node['value'] ?? "\n";
} else {
$result .= "\n" . $node['value'] ?? "\n";
}
}
}

return null !== $result ? trim($result, "\n") : null;
}

/**
* Changes step node type for types But, And to type of previous step if it exists else sets to Given
*
Expand Down
5 changes: 0 additions & 5 deletions tests/Behat/Gherkin/Cucumber/CompatibilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@
namespace Behat\Gherkin\Cucumber;

use Behat\Gherkin\Exception\ParserException;
use Behat\Gherkin\Gherkin;
use Behat\Gherkin\Keywords;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Loader\ArrayLoader;
use Behat\Gherkin\Loader\CucumberNDJsonAstLoader;
use Behat\Gherkin\Loader\LoaderInterface;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioInterface;
use Behat\Gherkin\Node\ScenarioNode;
use Behat\Gherkin\Node\StepNode;
use Behat\Gherkin\Parser;
use PHPUnit\Framework\TestCase;
Expand All @@ -30,7 +26,6 @@ class CompatibilityTest extends TestCase
'rule.feature' => 'Rule keyword not supported',
'rule_with_tag.feature' => 'Rule keyword not supported',
'tags.feature' => 'Rule keyword not supported',
'descriptions.feature' => 'Examples table descriptions not supported',
'incomplete_scenario_outline.feature' => 'Scenario and Scenario outline not yet synonyms',
'padded_example.feature' => 'Scenario and Scenario outline not yet synonyms',
'scenario_outline.feature' => 'Scenario and Scenario outline not yet synonyms',
Expand Down
13 changes: 4 additions & 9 deletions tests/Behat/Gherkin/Fixtures/etalons/complex_descriptions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,9 @@ feature:

scenarios:
-
type: scenario
title: |-
Some
| complex | description |

"""
hell yeah
"""
line: 16
type: scenario
title: Some
description: " | complex | description |\n\n\"\"\"\nhell yeah\n\"\"\""
line: 16
steps:
- { keyword_type: 'Given', type: 'Given', text: 'one two three', line: 22 }
Loading