Skip to content
Merged
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
5 changes: 1 addition & 4 deletions src/Filter/LineFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

namespace Behat\Gherkin\Filter;

use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\ScenarioInterface;
Expand Down Expand Up @@ -95,9 +94,7 @@ public function filterFeature(FeatureNode $feature)
$filteredTable[$this->filterLine] = $table[$this->filterLine];
}

$scenario = $scenario->withTables(
[new ExampleTableNode($filteredTable, $exampleTable->getKeyword(), $exampleTable->getTags())],
);
$scenario = $scenario->withTables([$exampleTable->withTable($filteredTable)]);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/Filter/LineRangeFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

namespace Behat\Gherkin\Filter;

use Behat\Gherkin\Node\ExampleTableNode;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\OutlineNode;
use Behat\Gherkin\Node\ScenarioInterface;
Expand Down Expand Up @@ -111,7 +110,7 @@ public function filterFeature(FeatureNode $feature)
}

if (count($filteredTable) > 1) {
$exampleTableNodes[] = new ExampleTableNode($filteredTable, $exampleTable->getKeyword(), $exampleTable->getTags());
$exampleTableNodes[] = $exampleTable->withTable($filteredTable);
}
}

Expand Down
17 changes: 14 additions & 3 deletions src/Filter/NameFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Behat\Gherkin\Filter;

use Behat\Gherkin\Node\DescribableNodeInterface;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Gherkin\Node\ScenarioInterface;

Expand Down Expand Up @@ -59,15 +60,25 @@ public function isFeatureMatch(FeatureNode $feature)
*/
public function isScenarioMatch(ScenarioInterface $scenario)
{
if ($scenario->getTitle() === null) {
// Historically (and in legacy GherkinCompatibilityMode), multiline scenario text was all part of the title.
// In new GherkinCompatibilityMode the text will be split into a single-line title & multiline description.
// For BC, this filter should continue to match on the complete multiline text value.
$textParts = array_filter([
$scenario->getTitle(),
$scenario instanceof DescribableNodeInterface ? $scenario->getDescription() : null,
]);

if ($textParts === []) {
return false;
}

if ($this->filterString[0] === '/' && preg_match($this->filterString, $scenario->getTitle())) {
$textToMatch = implode("\n", $textParts);

if ($this->filterString[0] === '/' && preg_match($this->filterString, $textToMatch)) {
return true;
}

if (str_contains($scenario->getTitle(), $this->filterString)) {
if (str_contains($textToMatch, $this->filterString)) {
return true;
}

Expand Down
13 changes: 12 additions & 1 deletion src/GherkinCompatibilityMode.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,25 @@ public function shouldRemoveStepKeywordSpace(): bool
/**
* @internal
*/
public function shouldRemoveFeatureDescriptionPadding(): bool
public function shouldRemoveDescriptionPadding(): bool
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed because in legacy mode, padding is also removed from descriptions that get combined into title on elements that did not previously support a description.

{
return match ($this) {
self::LEGACY => true,
default => false,
};
}

/**
* @internal
*/
public function allowAllNodeDescriptions(): bool
{
return match ($this) {
self::LEGACY => false,
default => true,
};
}

/**
* @internal
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class Lexer
private bool $allowLanguageTag = true;
private bool $allowFeature = true;
private bool $allowMultilineArguments = false;
private bool $allowExamples = false;
private bool $allowSteps = false;
/**
* @phpstan-var TDocStringSeparator|null
Expand Down Expand Up @@ -141,6 +142,7 @@ public function analyse(string $input, string $language = 'en')
$this->allowFeature = true;
$this->allowMultilineArguments = false;
$this->allowSteps = false;
$this->allowExamples = false;

if (\func_num_args() > 1) {
// @codeCoverageIgnoreStart
Expand Down Expand Up @@ -584,6 +586,7 @@ protected function scanScenario()

$this->allowMultilineArguments = false;
$this->allowSteps = true;
$this->allowExamples = true;

return $token;
}
Expand All @@ -605,6 +608,7 @@ protected function scanOutline()

$this->allowMultilineArguments = false;
$this->allowSteps = true;
$this->allowExamples = true;

return $token;
}
Expand All @@ -618,6 +622,9 @@ protected function scanOutline()
*/
protected function scanExamples()
{
if (!$this->allowExamples) {
return null;
}
$token = $this->scanTitleLine($this->currentDialect->getExamplesKeywords(), 'Examples');

if ($token === null) {
Expand Down
8 changes: 7 additions & 1 deletion src/Node/BackgroundNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* @final since 4.15.0
*/
class BackgroundNode implements ScenarioLikeInterface
class BackgroundNode implements ScenarioLikeInterface, DescribableNodeInterface
{
/**
* @param StepNode[] $steps
Expand All @@ -27,6 +27,7 @@ public function __construct(
private readonly array $steps,
private readonly string $keyword,
private readonly int $line,
private readonly ?string $description = null,
) {
}

Expand All @@ -50,6 +51,11 @@ public function getTitle()
return $this->title;
}

public function getDescription(): ?string
{
return $this->description;
}

/**
* Checks if background has steps.
*
Expand Down
19 changes: 19 additions & 0 deletions src/Node/DescribableNodeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of the Behat Gherkin Parser.
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Behat\Gherkin\Node;

interface DescribableNodeInterface
{
/**
* @return ?string
*/
public function getDescription();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately this interface method can only have a soft typehint to avoid a BC break when applying it to the existing FeatureNode::getDescription().

I have, however, given all the new implementations of the method a hard typehint.

}
28 changes: 27 additions & 1 deletion src/Node/ExampleTableNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* @final since 4.15.0
*/
class ExampleTableNode extends TableNode implements TaggedNodeInterface
class ExampleTableNode extends TableNode implements TaggedNodeInterface, DescribableNodeInterface
{
use TaggedNodeTrait;

Expand All @@ -29,6 +29,8 @@ public function __construct(
array $table,
private readonly string $keyword,
private readonly array $tags = [],
private readonly ?string $name = null,
private readonly ?string $description = null,
) {
parent::__construct($table);
}
Expand All @@ -43,6 +45,16 @@ public function getNodeType()
return 'ExampleTable';
}

public function getName(): ?string
{
return $this->name;
}

public function getDescription(): ?string
{
return $this->description;
}

public function getTags()
{
return $this->tags;
Expand All @@ -57,4 +69,18 @@ public function getKeyword()
{
return $this->keyword;
}

/**
* @param array<int, list<string>> $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
*/
public function withTable(array $table): self
{
return new self(
$table,
$this->keyword,
$this->tags,
$this->name,
$this->description,
);
}
}
2 changes: 1 addition & 1 deletion src/Node/FeatureNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*
* @final since 4.15.0
*/
class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface
class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface, DescribableNodeInterface
{
use TaggedNodeTrait;

Expand Down
11 changes: 9 additions & 2 deletions src/Node/OutlineNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* @final since 4.15.0
*/
class OutlineNode implements ScenarioInterface
class OutlineNode implements ScenarioInterface, DescribableNodeInterface
{
use TaggedNodeTrait;

Expand All @@ -42,6 +42,7 @@ public function __construct(
array|ExampleTableNode $tables,
private readonly string $keyword,
private readonly int $line,
private readonly ?string $description = null,
) {
$this->tables = is_array($tables) ? $tables : [$tables];
}
Expand All @@ -66,6 +67,11 @@ public function getTitle()
return $this->title;
}

public function getDescription(): ?string
{
return $this->description;
}

public function getTags()
{
return $this->tags;
Expand Down Expand Up @@ -104,7 +110,7 @@ public function hasExamples()
/**
* Builds and returns examples table for the outline.
*
* WARNING: it returns a merged table with tags lost.
* WARNING: it returns a merged table with tags, names & descriptions lost.
*
* @return ExampleTableNode
*
Expand Down Expand Up @@ -181,6 +187,7 @@ public function withTables(array $exampleTables): self
$exampleTables,
$this->keyword,
$this->line,
$this->description,
);
}

Expand Down
8 changes: 7 additions & 1 deletion src/Node/ScenarioNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* @final since 4.15.0
*/
class ScenarioNode implements ScenarioInterface, NamedScenarioInterface
class ScenarioNode implements ScenarioInterface, NamedScenarioInterface, DescribableNodeInterface
{
use TaggedNodeTrait;

Expand All @@ -31,6 +31,7 @@ public function __construct(
private readonly array $steps,
private readonly string $keyword,
private readonly int $line,
private readonly ?string $description = null,
) {
}

Expand Down Expand Up @@ -62,6 +63,11 @@ public function getName(): ?string
return $this->title;
}

public function getDescription(): ?string
{
return $this->description;
}

public function getTags()
{
return $this->tags;
Expand Down
Loading