Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
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
8 changes: 8 additions & 0 deletions src/Behat/Gherkin/Loader/YamlFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Behat\Gherkin\Loader;

use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\OutlineNode;
use Symfony\Component\Yaml\Yaml;

/**
Expand Down Expand Up @@ -57,6 +58,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 instanceof OutlineNode && !$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()) {;
Comment thread
phil-davis marked this conversation as resolved.
Outdated
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,48 @@
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: scenario1
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 }
examples:
6: [ login, password ]
7: [ '' , '' ]
8: [ unknown_user , '' ]

- type: scenario
title: scenario2
line: 15
steps:
- { keyword_type: 'Given', type: 'Given', text: 'a failing step', line: 16 }
- { keyword_type: 'When', type: 'When', text: 'I fill in "login" with "user"', line: 17 }
- { keyword_type: 'When', type: 'And', text: 'I fill in "password" with "password"', line: 18 }

- type: outline
title: scenario3
line: 20
steps:
- { keyword_type: 'Given', type: 'Given', text: 'a failing step', line: 21 }
- { keyword_type: 'When', type: 'When', text: 'I fill in "login" with "<login>"', line: 22 }
- { keyword_type: 'When', type: 'And', text: 'I fill in "password" with "<password>"', line: 23 }
examples:
25: [ login, password ]
26: [ hello, world ]
27: [ user , pass ]
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>"
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Feature: Feature with background and example

Background:
Given a passing step
Examples:
| login | password |
Comment thread
phil-davis marked this conversation as resolved.
Outdated
| | |
| unknown_user | |

Scenario Outline: scenario1
Given a failing step
When I fill in "login" with "<login>"
And I fill in "password" with "<password>"

Scenario: scenario2
Given a failing step
When I fill in "login" with "user"
And I fill in "password" with "password"

Scenario Outline: scenario3
Given a failing step
When I fill in "login" with "<login>"
And I fill in "password" with "<password>"
Examples:
| login | password |
| hello | world |
| user | pass |
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