Skip to content

Commit

Permalink
Add support for Outline on background
Browse files Browse the repository at this point in the history
  • Loading branch information
dpakach committed Jan 15, 2020
1 parent 749be1f commit 8c78963
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 23 deletions.
18 changes: 17 additions & 1 deletion src/Behat/Gherkin/Loader/ArrayLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,23 @@ protected function loadBackgroundHash(array $hash)

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

return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line']);
if (isset($hash['examples']['keyword'])) {
$examplesKeyword = $hash['examples']['keyword'];
unset($hash['examples']['keyword']);
} else {
$examplesKeyword = 'Examples';
}
if (isset($hash['examples'])) {
$examplesTable = $hash['examples'];
} else {
$examplesTable = array();
}
if (\count($examplesTable) === 0) {
$examples = null;
} else {
$examples = new ExampleTableNode($examplesTable, $examplesKeyword);
}
return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line'], $examples);
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/Behat/Gherkin/Loader/YamlFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public function load($path)
$filename = $this->findRelativePath($path);

return array_map(function (FeatureNode $feature) use ($filename) {
if ($feature->getBackground() !== null && $feature->getBackground()->hasExamples()) {;
foreach ($feature->getScenarios() as $scenario) {
if (!$scenario->hasExamples()) {
$scenario->setExampleTable($feature->getBackground()->getExamples());
}
}
}
return new FeatureNode(
$feature->getTitle(),
$feature->getDescription(),
Expand Down
28 changes: 27 additions & 1 deletion src/Behat/Gherkin/Node/BackgroundNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class BackgroundNode implements ScenarioLikeInterface
* @var integer
*/
private $line;
/**
* @var ExampleTableNode
*/
private $exampleTable;

/**
* Initializes background.
Expand All @@ -41,13 +45,15 @@ class BackgroundNode implements ScenarioLikeInterface
* @param StepNode[] $steps
* @param string $keyword
* @param integer $line
* @param null|ExampleTableNode $exampleTable
*/
public function __construct($title, array $steps, $keyword, $line)
public function __construct($title, array $steps, $keyword, $line, $exampleTable=null)
{
$this->title = $title;
$this->steps = $steps;
$this->keyword = $keyword;
$this->line = $line;
$this->exampleTable = $exampleTable;
}

/**
Expand Down Expand Up @@ -109,4 +115,24 @@ public function getLine()
{
return $this->line;
}

/**
* Returns if background has ExampleTable
*
* @return boolean
*/
public function hasExamples()
{
return $this->exampleTable !== null;
}

/**
* Returns if background has ExampleTable
*
* @return null|ExampleTableNode
*/
public function getExamples()
{
return $this->exampleTable;
}
}
28 changes: 20 additions & 8 deletions src/Behat/Gherkin/Node/OutlineNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ class OutlineNode implements ScenarioInterface
/**
* Initializes outline.
*
* @param null|string $title
* @param string[] $tags
* @param StepNode[] $steps
* @param ExampleTableNode $table
* @param string $keyword
* @param integer $line
* @param null|string $title
* @param string[] $tags
* @param StepNode[] $steps
* @param null|ExampleTableNode $table
* @param string $keyword
* @param integer $line
*/
public function __construct(
$title,
array $tags,
array $steps,
ExampleTableNode $table,
$table,
$keyword,
$line
) {
Expand Down Expand Up @@ -151,7 +151,19 @@ public function getSteps()
*/
public function hasExamples()
{
return 0 < count($this->table->getColumnsHash());
return $this->table !== null && 0 < count($this->table->getRows());
}

/**
* Add Example to the outline.
*
* @param ExampleTableNode
*
* @return void
*/
public function setExampleTable($table)
{
$this->table = $table;
}

/**
Expand Down
39 changes: 28 additions & 11 deletions src/Behat/Gherkin/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,26 @@ protected function parseFeature()
}
}

if ($background === null || !$background->hasExamples()) {
foreach ($scenarios as $scenario) {
if ($scenario instanceof OutlineNode && !$scenario->hasExamples()) {
throw new ParserException(sprintf(
'Outline should have examples table, but got none for outline "%s" on line: %d%s',
rtrim($scenario->getTitle()),
$scenario->getLine(),
$this->file ? ' in file: ' . $this->file : ''
));
}
}
}
if ($background !== null && $background->hasExamples()) {;
foreach ($scenarios as $scenario) {
if ($scenario instanceof OutlineNode && !$scenario->hasExamples()) {
$scenario->setExampleTable($background->getExamples());
}
}
}

return new FeatureNode(
rtrim($title) ?: null,
rtrim($description) ?: null,
Expand Down Expand Up @@ -302,6 +322,7 @@ protected function parseBackground()
$title = trim($token['value']);
$keyword = $token['keyword'];
$line = $token['line'];
$example = null;

if (count($this->popTags())) {
throw new ParserException(sprintf(
Expand All @@ -313,10 +334,15 @@ protected function parseBackground()

// Parse description and steps
$steps = array();
$allowedTokenTypes = array('Step', 'Newline', 'Text', 'Comment');
$allowedTokenTypes = array('Step', 'Newline', 'Text', 'Comment', 'Examples');
while (in_array($this->predictTokenType(), $allowedTokenTypes)) {
$node = $this->parseExpression();

if ($node instanceof ExampleTableNode) {
$example = $node;
continue;
}

if ($node instanceof StepNode) {
$steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
continue;
Expand Down Expand Up @@ -350,7 +376,7 @@ protected function parseBackground()
}
}

return new BackgroundNode(rtrim($title) ?: null, $steps, $keyword, $line);
return new BackgroundNode(rtrim($title) ?: null, $steps, $keyword, $line, $example);
}

/**
Expand Down Expand Up @@ -470,15 +496,6 @@ protected function parseOutline()
}
}

if (null === $examples) {
throw new ParserException(sprintf(
'Outline should have examples table, but got none for outline "%s" on line: %d%s',
rtrim($title),
$line,
$this->file ? ' in file: ' . $this->file : ''
));
}

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

Expand Down
31 changes: 31 additions & 0 deletions tests/Behat/Gherkin/Fixtures/etalons/background_with_outline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
feature:
title: Feature with background and example
language: en
line: 1
description: ~

background:
line: 3
steps:
- { keyword_type: Given, type: Given, text: a passing step, line: 4 }
examples:
6: [login, password]
7: ['', '']
8: [unknown_user, '']

scenarios:
-
type: outline
title: ~
line: 10
steps:
- { keyword_type: 'Given', type: 'Given', text: 'a failing step', line: 11 }
- { keyword_type: 'When', type: 'When', text: 'I fill in "login" with "<login>"', line: 12 }
- { keyword_type: 'When', type: 'And', text: 'I fill in "password" with "<password>"', line: 13 }
arguments:
-
type: table
rows:
6: [ login, password ]
7: [ '' , '' ]
8: [ unknown_user , '' ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Feature: Feature with background and example

Background:
Given a passing step
Examples:
| login | password |
| | |
| unknown_user | |

Scenario Outline:
Given a failing step
When I fill in "login" with "<login>"
And I fill in "password" with "<password>"
6 changes: 4 additions & 2 deletions tests/Behat/Gherkin/Loader/ArrayLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ public function testLoadSteps()
'steps' => array(
array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'bg step 1', 'line' => 3),
array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'bg step 2')
)
),
'examples' => null
),
'scenarios' => array(
array(
Expand Down Expand Up @@ -326,7 +327,8 @@ public function testLoadStepArguments()
)
)
)
)
),
'examples' => null
)
)
)
Expand Down

0 comments on commit 8c78963

Please sign in to comment.