From 50fdacc4a8df5053314ea1f6460d398f7485a094 Mon Sep 17 00:00:00 2001 From: Christian Sciberras Date: Wed, 11 Dec 2024 23:50:31 +0100 Subject: [PATCH 1/5] Setup PHP-CS-Fixer config and pipeline --- .gitattributes | 17 +++++++++-------- .github/workflows/build.yml | 16 ++++++++++++++++ .gitignore | 2 ++ .php-cs-fixer.dist.php | 29 +++++++++++++++++++++++++++++ CONTRIBUTING.md | 8 ++++++++ composer.json | 15 +++++++++++++-- 6 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 .php-cs-fixer.dist.php diff --git a/.gitattributes b/.gitattributes index bac5d031..d706a454 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,9 @@ -/.github/ export-ignore -/bin/ export-ignore -/tests/ export-ignore -/.editorconfig export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore -/CONTRIBUTING.md export-ignore -/phpunit.dist.xml export-ignore +/.github/ export-ignore +/bin/ export-ignore +/tests/ export-ignore +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/CONTRIBUTING.md export-ignore +/phpunit.dist.xml export-ignore +/.php-cs-fixer.dist.php export-ignore diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd24a1a5..73745808 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,22 @@ on: types: [ created ] jobs: + check_code_style: + name: Check code style + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + coverage: none + php-version: '8.3' + + - name: Install dependencies + run: composer update + + - run: ./vendor/bin/php-cs-fixer fix --dry-run --diff --show-progress=dots + tests: runs-on: ubuntu-latest name: Build and test diff --git a/.gitignore b/.gitignore index d4f33b0f..7c409b70 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ composer.lock .phpunit.cache .phpunit.result.cache phpunit.xml +.php-cs-fixer.php +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..1d21c195 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,29 @@ +in(__DIR__) + ->notPath('i18n.php'); + +return (new PhpCsFixer\Config()) + ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect()) + ->setRules([ + '@PER-CS' => true, + '@Symfony' => true, + 'header_comment' => [ + 'header' => <<<'TEXT' + This file is part of the Behat Gherkin Parser. + (c) Konstantin Kudryashov + + For the full copyright and license information, please view the LICENSE + file that was distributed with this source code. + TEXT + ], + 'yoda_style' => [ + 'equal' => false, + 'identical' => false, + 'less_and_greater' => false, + ], + 'concat_space' => ['spacing' => 'one'], + 'phpdoc_align' => ['align' => 'left'], + ]) + ->setFinder($finder); diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 39dcc5fb..5baecdfa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,14 @@ We use automated tools to ensure that the code has a consistent style and is of composer lint ``` +## Automated Fixes + +Some problems detected by the linting tools can be fixed automatically. Simply run the following: + +```shell +composer fix +``` + ## Contributing to Gherkin Translations Gherkin supports →40 different languages and you could add more! You might notice `i18n.php` file in the root of diff --git a/composer.json b/composer.json index 9b84e94c..218f6e89 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,8 @@ "require-dev": { "symfony/yaml": "^5.4 || ^6.4 || ^7.0", "phpunit/phpunit": "^10.5", - "cucumber/cucumber": "dev-gherkin-24.1.0" + "cucumber/cucumber": "dev-gherkin-24.1.0", + "friendsofphp/php-cs-fixer": "^3.65" }, "suggest": { @@ -67,11 +68,21 @@ "scripts": { "lint": [ - "Composer\\Config::disableProcessTimeout" + "Composer\\Config::disableProcessTimeout", + "vendor/bin/php-cs-fixer fix --dry-run --diff --show-progress=dots" ], "test": [ "Composer\\Config::disableProcessTimeout", "vendor/bin/phpunit ./tests" + ], + "fix": [ + "Composer\\Config::disableProcessTimeout", + "vendor/bin/php-cs-fixer fix --diff --show-progress=dots" ] + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": false + } } } From 8ee3e6f9c428d03d8a0338cfba1665cf54e05be3 Mon Sep 17 00:00:00 2001 From: Christian Sciberras Date: Thu, 12 Dec 2024 00:04:59 +0100 Subject: [PATCH 2/5] Apply fixes --- src/Behat/Gherkin/Cache/CacheInterface.php | 8 +- src/Behat/Gherkin/Cache/FileCache.php | 28 +- src/Behat/Gherkin/Cache/MemoryCache.php | 24 +- .../Gherkin/Exception/CacheException.php | 6 +- src/Behat/Gherkin/Exception/Exception.php | 2 +- .../Gherkin/Exception/LexerException.php | 6 +- src/Behat/Gherkin/Exception/NodeException.php | 6 +- .../Gherkin/Exception/ParserException.php | 6 +- src/Behat/Gherkin/Filter/ComplexFilter.php | 6 +- .../Gherkin/Filter/ComplexFilterInterface.php | 4 +- .../Gherkin/Filter/FeatureFilterInterface.php | 4 +- src/Behat/Gherkin/Filter/FilterInterface.php | 2 +- src/Behat/Gherkin/Filter/LineFilter.php | 10 +- src/Behat/Gherkin/Filter/LineRangeFilter.php | 10 +- src/Behat/Gherkin/Filter/NameFilter.php | 16 +- src/Behat/Gherkin/Filter/NarrativeFilter.php | 6 +- src/Behat/Gherkin/Filter/PathsFilter.php | 6 +- src/Behat/Gherkin/Filter/RoleFilter.php | 10 +- src/Behat/Gherkin/Filter/SimpleFilter.php | 6 +- src/Behat/Gherkin/Filter/TagFilter.php | 17 +- src/Behat/Gherkin/Gherkin.php | 26 +- src/Behat/Gherkin/Keywords/ArrayKeywords.php | 26 +- .../Gherkin/Keywords/CachedArrayKeywords.php | 4 +- .../Gherkin/Keywords/CucumberKeywords.php | 18 +- src/Behat/Gherkin/Keywords/KeywordsDumper.php | 46 +- .../Gherkin/Keywords/KeywordsInterface.php | 24 +- src/Behat/Gherkin/Lexer.php | 125 ++-- src/Behat/Gherkin/Lexer.php~ | 652 ++++++++++++++++++ .../Gherkin/Loader/AbstractFileLoader.php | 8 +- src/Behat/Gherkin/Loader/ArrayLoader.php | 93 +-- .../Loader/CucumberNDJsonAstLoader.php | 28 +- src/Behat/Gherkin/Loader/DirectoryLoader.php | 12 +- .../Gherkin/Loader/FileLoaderInterface.php | 2 +- .../Gherkin/Loader/GherkinFileLoader.php | 12 +- src/Behat/Gherkin/Loader/LoaderInterface.php | 2 +- src/Behat/Gherkin/Loader/YamlFileLoader.php | 4 +- src/Behat/Gherkin/Node/ArgumentInterface.php | 2 +- src/Behat/Gherkin/Node/BackgroundNode.php | 22 +- src/Behat/Gherkin/Node/ExampleNode.php | 42 +- src/Behat/Gherkin/Node/ExampleTableNode.php | 11 +- src/Behat/Gherkin/Node/FeatureNode.php | 57 +- .../Gherkin/Node/KeywordNodeInterface.php | 4 +- .../Gherkin/Node/NamedScenarioInterface.php | 8 + src/Behat/Gherkin/Node/NodeInterface.php | 6 +- src/Behat/Gherkin/Node/OutlineNode.php | 44 +- src/Behat/Gherkin/Node/PyStringNode.php | 12 +- src/Behat/Gherkin/Node/ScenarioInterface.php | 2 +- .../Gherkin/Node/ScenarioLikeInterface.php | 2 +- src/Behat/Gherkin/Node/ScenarioNode.php | 31 +- .../Gherkin/Node/StepContainerInterface.php | 2 +- src/Behat/Gherkin/Node/StepNode.php | 28 +- src/Behat/Gherkin/Node/TableNode.php | 82 +-- .../Gherkin/Node/TaggedNodeInterface.php | 2 +- src/Behat/Gherkin/Parser.php | 206 ++---- tests/Behat/Gherkin/Cache/FileCacheTest.php | 16 +- tests/Behat/Gherkin/Cache/MemoryCacheTest.php | 16 +- .../Gherkin/Cucumber/CompatibilityTest.php | 36 +- tests/Behat/Gherkin/Filter/FilterTestCase.php | 34 +- tests/Behat/Gherkin/Filter/LineFilterTest.php | 38 +- .../Gherkin/Filter/LineRangeFilterTest.php | 96 +-- tests/Behat/Gherkin/Filter/NameFilterTest.php | 44 +- .../Gherkin/Filter/NarrativeFilterTest.php | 10 +- .../Behat/Gherkin/Filter/PathsFilterTest.php | 36 +- tests/Behat/Gherkin/Filter/RoleFilterTest.php | 16 +- tests/Behat/Gherkin/Filter/TagFilterTest.php | 171 ++--- tests/Behat/Gherkin/GherkinTest.php | 28 +- .../Gherkin/Keywords/ArrayKeywordsTest.php | 22 +- .../Keywords/CachedArrayKeywordsTest.php | 18 +- .../Gherkin/Keywords/CucumberKeywordsTest.php | 14 +- .../Gherkin/Keywords/KeywordsDumperTest.php | 68 +- .../Gherkin/Keywords/KeywordsTestCase.php | 60 +- .../Behat/Gherkin/Loader/ArrayLoaderTest.php | 348 +++++----- .../Gherkin/Loader/DirectoryLoaderTest.php | 28 +- .../Gherkin/Loader/GherkinFileLoaderTest.php | 8 + .../Gherkin/Loader/YamlFileLoaderTest.php | 8 + tests/Behat/Gherkin/Node/ExampleNodeTest.php | 72 +- tests/Behat/Gherkin/Node/OutlineNodeTest.php | 152 ++-- tests/Behat/Gherkin/Node/PyStringNodeTest.php | 14 +- tests/Behat/Gherkin/Node/StepNodeTest.php | 16 +- tests/Behat/Gherkin/Node/TableNodeTest.php | 392 +++++------ tests/Behat/Gherkin/ParserExceptionsTest.php | 58 +- tests/Behat/Gherkin/ParserTest.php | 104 +-- 82 files changed, 2256 insertions(+), 1495 deletions(-) create mode 100644 src/Behat/Gherkin/Lexer.php~ diff --git a/src/Behat/Gherkin/Cache/CacheInterface.php b/src/Behat/Gherkin/Cache/CacheInterface.php index d5439783..8505ee61 100644 --- a/src/Behat/Gherkin/Cache/CacheInterface.php +++ b/src/Behat/Gherkin/Cache/CacheInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -22,8 +22,8 @@ interface CacheInterface /** * Checks that cache for feature exists and is fresh. * - * @param string $path Feature path - * @param integer $timestamp The last time feature was updated + * @param string $path Feature path + * @param int $timestamp The last time feature was updated * * @return bool */ @@ -41,7 +41,7 @@ public function read($path); /** * Caches feature node. * - * @param string $path Feature path + * @param string $path Feature path * @param FeatureNode $feature Feature instance */ public function write($path, FeatureNode $feature); diff --git a/src/Behat/Gherkin/Cache/FileCache.php b/src/Behat/Gherkin/Cache/FileCache.php index 44707c2d..ea468569 100644 --- a/src/Behat/Gherkin/Cache/FileCache.php +++ b/src/Behat/Gherkin/Cache/FileCache.php @@ -1,18 +1,18 @@ -* -* For the full copyright and license information, please view the LICENSE -* file that was distributed with this source code. -*/ + * This file is part of the Behat Gherkin Parser. + * (c) Konstantin Kudryashov + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ namespace Behat\Gherkin\Cache; use Behat\Gherkin\Exception\CacheException; -use Behat\Gherkin\Node\FeatureNode; use Behat\Gherkin\Gherkin; +use Behat\Gherkin\Node\FeatureNode; /** * File cache. @@ -27,13 +27,13 @@ class FileCache implements CacheInterface /** * Initializes file cache. * - * @param string $path Path to the folder where to store caches. + * @param string $path path to the folder where to store caches * * @throws CacheException */ public function __construct($path) { - $this->path = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.'v'.Gherkin::VERSION; + $this->path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'v' . Gherkin::VERSION; if (!is_dir($this->path)) { @mkdir($this->path, 0777, true); @@ -47,8 +47,8 @@ public function __construct($path) /** * Checks that cache for feature exists and is fresh. * - * @param string $path Feature path - * @param integer $timestamp The last time feature was updated + * @param string $path Feature path + * @param int $timestamp The last time feature was updated * * @return bool */ @@ -78,7 +78,7 @@ public function read($path) $feature = unserialize(file_get_contents($cachePath)); if (!$feature instanceof FeatureNode) { - throw new CacheException(sprintf('Can not load cache for a feature "%s" from "%s".', $path, $cachePath )); + throw new CacheException(sprintf('Can not load cache for a feature "%s" from "%s".', $path, $cachePath)); } return $feature; @@ -87,7 +87,7 @@ public function read($path) /** * Caches feature node. * - * @param string $path Feature path + * @param string $path Feature path * @param FeatureNode $feature Feature instance */ public function write($path, FeatureNode $feature) @@ -104,6 +104,6 @@ public function write($path, FeatureNode $feature) */ protected function getCachePathFor($path) { - return $this->path.'/'.md5($path).'.feature.cache'; + return $this->path . '/' . md5($path) . '.feature.cache'; } } diff --git a/src/Behat/Gherkin/Cache/MemoryCache.php b/src/Behat/Gherkin/Cache/MemoryCache.php index 12d56ffa..6a5d942b 100644 --- a/src/Behat/Gherkin/Cache/MemoryCache.php +++ b/src/Behat/Gherkin/Cache/MemoryCache.php @@ -1,12 +1,12 @@ -* -* For the full copyright and license information, please view the LICENSE -* file that was distributed with this source code. -*/ + * This file is part of the Behat Gherkin Parser. + * (c) Konstantin Kudryashov + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ namespace Behat\Gherkin\Cache; @@ -20,14 +20,14 @@ */ class MemoryCache implements CacheInterface { - private $features = array(); - private $timestamps = array(); + private $features = []; + private $timestamps = []; /** * Checks that cache for feature exists and is fresh. * - * @param string $path Feature path - * @param integer $timestamp The last time feature was updated + * @param string $path Feature path + * @param int $timestamp The last time feature was updated * * @return bool */ @@ -55,12 +55,12 @@ public function read($path) /** * Caches feature node. * - * @param string $path Feature path + * @param string $path Feature path * @param FeatureNode $feature Feature instance */ public function write($path, FeatureNode $feature) { - $this->features[$path] = $feature; + $this->features[$path] = $feature; $this->timestamps[$path] = time(); } } diff --git a/src/Behat/Gherkin/Exception/CacheException.php b/src/Behat/Gherkin/Exception/CacheException.php index f8b9214c..4b9fb18a 100644 --- a/src/Behat/Gherkin/Exception/CacheException.php +++ b/src/Behat/Gherkin/Exception/CacheException.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -10,13 +10,11 @@ namespace Behat\Gherkin\Exception; -use RuntimeException; - /** * Cache exception. * * @author Konstantin Kudryashov */ -class CacheException extends RuntimeException implements Exception +class CacheException extends \RuntimeException implements Exception { } diff --git a/src/Behat/Gherkin/Exception/Exception.php b/src/Behat/Gherkin/Exception/Exception.php index f377e30f..6bc3570e 100644 --- a/src/Behat/Gherkin/Exception/Exception.php +++ b/src/Behat/Gherkin/Exception/Exception.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Exception/LexerException.php b/src/Behat/Gherkin/Exception/LexerException.php index 476d81f5..988bf781 100644 --- a/src/Behat/Gherkin/Exception/LexerException.php +++ b/src/Behat/Gherkin/Exception/LexerException.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -10,8 +10,6 @@ namespace Behat\Gherkin\Exception; -use RuntimeException; - -class LexerException extends RuntimeException implements Exception +class LexerException extends \RuntimeException implements Exception { } diff --git a/src/Behat/Gherkin/Exception/NodeException.php b/src/Behat/Gherkin/Exception/NodeException.php index b7d7a4c6..1acada1e 100644 --- a/src/Behat/Gherkin/Exception/NodeException.php +++ b/src/Behat/Gherkin/Exception/NodeException.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -10,8 +10,6 @@ namespace Behat\Gherkin\Exception; -use RuntimeException; - -class NodeException extends RuntimeException implements Exception +class NodeException extends \RuntimeException implements Exception { } diff --git a/src/Behat/Gherkin/Exception/ParserException.php b/src/Behat/Gherkin/Exception/ParserException.php index f835e726..634ebd62 100644 --- a/src/Behat/Gherkin/Exception/ParserException.php +++ b/src/Behat/Gherkin/Exception/ParserException.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -10,8 +10,6 @@ namespace Behat\Gherkin\Exception; -use RuntimeException; - -class ParserException extends RuntimeException implements Exception +class ParserException extends \RuntimeException implements Exception { } diff --git a/src/Behat/Gherkin/Filter/ComplexFilter.php b/src/Behat/Gherkin/Filter/ComplexFilter.php index a3a3b084..e0459b21 100644 --- a/src/Behat/Gherkin/Filter/ComplexFilter.php +++ b/src/Behat/Gherkin/Filter/ComplexFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -22,13 +22,11 @@ abstract class ComplexFilter implements ComplexFilterInterface /** * Filters feature according to the filter. * - * @param FeatureNode $feature - * * @return FeatureNode */ public function filterFeature(FeatureNode $feature) { - $scenarios = array(); + $scenarios = []; foreach ($feature->getScenarios() as $scenario) { if (!$this->isScenarioMatch($feature, $scenario)) { continue; diff --git a/src/Behat/Gherkin/Filter/ComplexFilterInterface.php b/src/Behat/Gherkin/Filter/ComplexFilterInterface.php index 82addd02..75683bf6 100644 --- a/src/Behat/Gherkin/Filter/ComplexFilterInterface.php +++ b/src/Behat/Gherkin/Filter/ComplexFilterInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -23,7 +23,7 @@ interface ComplexFilterInterface extends FeatureFilterInterface /** * Checks if scenario or outline matches specified filter. * - * @param FeatureNode $feature Feature node instance + * @param FeatureNode $feature Feature node instance * @param ScenarioInterface $scenario Scenario or Outline node instance * * @return bool diff --git a/src/Behat/Gherkin/Filter/FeatureFilterInterface.php b/src/Behat/Gherkin/Filter/FeatureFilterInterface.php index 6994b318..28fb396a 100644 --- a/src/Behat/Gherkin/Filter/FeatureFilterInterface.php +++ b/src/Behat/Gherkin/Filter/FeatureFilterInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -31,8 +31,6 @@ public function isFeatureMatch(FeatureNode $feature); /** * Filters feature according to the filter and returns new one. * - * @param FeatureNode $feature - * * @return FeatureNode */ public function filterFeature(FeatureNode $feature); diff --git a/src/Behat/Gherkin/Filter/FilterInterface.php b/src/Behat/Gherkin/Filter/FilterInterface.php index 469cb3cf..59238eda 100644 --- a/src/Behat/Gherkin/Filter/FilterInterface.php +++ b/src/Behat/Gherkin/Filter/FilterInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Filter/LineFilter.php b/src/Behat/Gherkin/Filter/LineFilter.php index 9cf6b304..a3d91821 100644 --- a/src/Behat/Gherkin/Filter/LineFilter.php +++ b/src/Behat/Gherkin/Filter/LineFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -70,13 +70,11 @@ public function isScenarioMatch(ScenarioInterface $scenario) /** * Filters feature according to the filter and returns new one. * - * @param FeatureNode $feature - * * @return FeatureNode */ public function filterFeature(FeatureNode $feature) { - $scenarios = array(); + $scenarios = []; foreach ($feature->getScenarios() as $scenario) { if (!$this->isScenarioMatch($scenario)) { continue; @@ -88,7 +86,7 @@ public function filterFeature(FeatureNode $feature) $lines = array_keys($table); if (in_array($this->filterLine, $lines)) { - $filteredTable = array($lines[0] => $table[$lines[0]]); + $filteredTable = [$lines[0] => $table[$lines[0]]]; if ($lines[0] !== $this->filterLine) { $filteredTable[$this->filterLine] = $table[$this->filterLine]; @@ -98,7 +96,7 @@ public function filterFeature(FeatureNode $feature) $scenario->getTitle(), $scenario->getTags(), $scenario->getSteps(), - array(new ExampleTableNode($filteredTable, $exampleTable->getKeyword(), $exampleTable->getTags())), + [new ExampleTableNode($filteredTable, $exampleTable->getKeyword(), $exampleTable->getTags())], $scenario->getKeyword(), $scenario->getLine() ); diff --git a/src/Behat/Gherkin/Filter/LineRangeFilter.php b/src/Behat/Gherkin/Filter/LineRangeFilter.php index e73d12d8..0fc8ae54 100644 --- a/src/Behat/Gherkin/Filter/LineRangeFilter.php +++ b/src/Behat/Gherkin/Filter/LineRangeFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -81,13 +81,11 @@ public function isScenarioMatch(ScenarioInterface $scenario) /** * Filters feature according to the filter. * - * @param FeatureNode $feature - * * @return FeatureNode */ public function filterFeature(FeatureNode $feature) { - $scenarios = array(); + $scenarios = []; foreach ($feature->getScenarios() as $scenario) { if (!$this->isScenarioMatch($scenario)) { continue; @@ -95,13 +93,13 @@ public function filterFeature(FeatureNode $feature) if ($scenario instanceof OutlineNode && $scenario->hasExamples()) { // first accumulate examples and then create scenario - $exampleTableNodes = array(); + $exampleTableNodes = []; foreach ($scenario->getExampleTables() as $exampleTable) { $table = $exampleTable->getTable(); $lines = array_keys($table); - $filteredTable = array($lines[0] => $table[$lines[0]]); + $filteredTable = [$lines[0] => $table[$lines[0]]]; unset($table[$lines[0]]); foreach ($table as $line => $row) { diff --git a/src/Behat/Gherkin/Filter/NameFilter.php b/src/Behat/Gherkin/Filter/NameFilter.php index 80974d1f..18aa5975 100644 --- a/src/Behat/Gherkin/Filter/NameFilter.php +++ b/src/Behat/Gherkin/Filter/NameFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -41,15 +41,15 @@ public function __construct($filterString) */ public function isFeatureMatch(FeatureNode $feature) { - if (null === $feature->getTitle()) { + if ($feature->getTitle() === null) { return false; } - if ('/' === $this->filterString[0]) { - return 1 === preg_match($this->filterString, $feature->getTitle()); + if ($this->filterString[0] === '/') { + return preg_match($this->filterString, $feature->getTitle()) === 1; } - return false !== mb_strpos($feature->getTitle(), $this->filterString, 0, 'utf8'); + return mb_strpos($feature->getTitle(), $this->filterString, 0, 'utf8') !== false; } /** @@ -61,13 +61,13 @@ public function isFeatureMatch(FeatureNode $feature) */ public function isScenarioMatch(ScenarioInterface $scenario) { - if (null === $scenario->getTitle()) { + if ($scenario->getTitle() === null) { return false; } - if ('/' === $this->filterString[0] && 1 === preg_match($this->filterString, $scenario->getTitle())) { + if ($this->filterString[0] === '/' && preg_match($this->filterString, $scenario->getTitle()) === 1) { return true; - } elseif (false !== mb_strpos($scenario->getTitle(), $this->filterString, 0, 'utf8')) { + } elseif (mb_strpos($scenario->getTitle(), $this->filterString, 0, 'utf8') !== false) { return true; } diff --git a/src/Behat/Gherkin/Filter/NarrativeFilter.php b/src/Behat/Gherkin/Filter/NarrativeFilter.php index eb5ae48d..51faa585 100644 --- a/src/Behat/Gherkin/Filter/NarrativeFilter.php +++ b/src/Behat/Gherkin/Filter/NarrativeFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -10,8 +10,8 @@ namespace Behat\Gherkin\Filter; -use Behat\Gherkin\Node\ScenarioInterface; use Behat\Gherkin\Node\FeatureNode; +use Behat\Gherkin\Node\ScenarioInterface; /** * Filters features by their narrative using regular expression. @@ -44,7 +44,7 @@ public function __construct($regex) */ public function isFeatureMatch(FeatureNode $feature) { - return 1 === preg_match($this->regex, $feature->getDescription() ?? ''); + return preg_match($this->regex, $feature->getDescription() ?? '') === 1; } /** diff --git a/src/Behat/Gherkin/Filter/PathsFilter.php b/src/Behat/Gherkin/Filter/PathsFilter.php index f9285977..22d65915 100644 --- a/src/Behat/Gherkin/Filter/PathsFilter.php +++ b/src/Behat/Gherkin/Filter/PathsFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -20,7 +20,7 @@ */ class PathsFilter extends SimpleFilter { - protected $filterPaths = array(); + protected $filterPaths = []; /** * Initializes filter. @@ -50,7 +50,7 @@ function ($realpath) { public function isFeatureMatch(FeatureNode $feature) { foreach ($this->filterPaths as $path) { - if (0 === strpos(realpath($feature->getFile()), $path)) { + if (str_starts_with(realpath($feature->getFile()), $path)) { return true; } } diff --git a/src/Behat/Gherkin/Filter/RoleFilter.php b/src/Behat/Gherkin/Filter/RoleFilter.php index 0ad3a29a..011a6068 100644 --- a/src/Behat/Gherkin/Filter/RoleFilter.php +++ b/src/Behat/Gherkin/Filter/RoleFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -29,12 +29,12 @@ class RoleFilter extends SimpleFilter */ public function __construct($role) { - $this->pattern = '/as an? ' . strtr(preg_quote($role, '/'), array( + $this->pattern = '/as an? ' . strtr(preg_quote($role, '/'), [ '\*' => '.*', '\?' => '.', '\[' => '[', - '\]' => ']' - )) . '[$\n]/i'; + '\]' => ']', + ]) . '[$\n]/i'; } /** @@ -46,7 +46,7 @@ public function __construct($role) */ public function isFeatureMatch(FeatureNode $feature) { - return 1 === preg_match($this->pattern, $feature->getDescription() ?? ''); + return preg_match($this->pattern, $feature->getDescription() ?? '') === 1; } /** diff --git a/src/Behat/Gherkin/Filter/SimpleFilter.php b/src/Behat/Gherkin/Filter/SimpleFilter.php index 10bee8fa..59516ba8 100644 --- a/src/Behat/Gherkin/Filter/SimpleFilter.php +++ b/src/Behat/Gherkin/Filter/SimpleFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -22,8 +22,6 @@ abstract class SimpleFilter implements FilterInterface /** * Filters feature according to the filter. * - * @param FeatureNode $feature - * * @return FeatureNode */ public function filterFeature(FeatureNode $feature) @@ -32,7 +30,7 @@ public function filterFeature(FeatureNode $feature) return $feature; } - $scenarios = array(); + $scenarios = []; foreach ($feature->getScenarios() as $scenario) { if (!$this->isScenarioMatch($scenario)) { continue; diff --git a/src/Behat/Gherkin/Filter/TagFilter.php b/src/Behat/Gherkin/Filter/TagFilter.php index 052ef398..2c155d2d 100644 --- a/src/Behat/Gherkin/Filter/TagFilter.php +++ b/src/Behat/Gherkin/Filter/TagFilter.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -32,32 +32,29 @@ public function __construct($filterString) { $this->filterString = trim($filterString); - if(preg_match('/\s/u', $this->filterString)) { + if (preg_match('/\s/u', $this->filterString)) { trigger_error( - "Tags with whitespace are deprecated and may be removed in a future version", + 'Tags with whitespace are deprecated and may be removed in a future version', E_USER_DEPRECATED ); - } + } } /** * Filters feature according to the filter. * - * @param FeatureNode $feature - * * @return FeatureNode */ public function filterFeature(FeatureNode $feature) { - $scenarios = array(); + $scenarios = []; foreach ($feature->getScenarios() as $scenario) { if (!$this->isScenarioMatch($feature, $scenario)) { continue; } if ($scenario instanceof OutlineNode && $scenario->hasExamples()) { - - $exampleTables = array(); + $exampleTables = []; foreach ($scenario->getExampleTables() as $exampleTable) { if ($this->isTagsMatchCondition(array_merge($feature->getTags(), $scenario->getTags(), $exampleTable->getTags()))) { @@ -147,7 +144,7 @@ protected function isTagsMatchCondition($tags) foreach (explode(',', $andTags) as $tag) { $tag = str_replace('@', '', trim($tag)); - if ('~' === $tag[0]) { + if ($tag[0] === '~') { $tag = mb_substr($tag, 1, mb_strlen($tag, 'utf8') - 1, 'utf8'); $satisfiesComma = !in_array($tag, $tags) || $satisfiesComma; } else { diff --git a/src/Behat/Gherkin/Gherkin.php b/src/Behat/Gherkin/Gherkin.php index c3cc5c0e..577d0a9a 100644 --- a/src/Behat/Gherkin/Gherkin.php +++ b/src/Behat/Gherkin/Gherkin.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -23,16 +23,16 @@ */ class Gherkin { - const VERSION = '4.8.0'; + public const VERSION = '4.8.0'; /** * @var LoaderInterface[] */ - protected $loaders = array(); + protected $loaders = []; /** * @var FeatureFilterInterface[] */ - protected $filters = array(); + protected $filters = []; /** * Adds loader to manager. @@ -61,8 +61,8 @@ public function addFilter(FeatureFilterInterface $filter) */ public function setFilters(array $filters) { - $this->filters = array(); - array_map(array($this, 'addFilter'), $filters); + $this->filters = []; + array_map([$this, 'addFilter'], $filters); } /** @@ -82,16 +82,16 @@ public function setBasePath($path) /** * Loads & filters resource with added loaders. * - * @param mixed $resource Resource to load - * @param FeatureFilterInterface[] $filters Additional filters + * @param mixed $resource Resource to load + * @param FeatureFilterInterface[] $filters Additional filters * * @return array */ - public function load($resource, array $filters = array()) + public function load($resource, array $filters = []) { $filters = array_merge($this->filters, $filters); - $matches = array(); + $matches = []; if (preg_match('/^(.*)\:(\d+)-(\d+|\*)$/', $resource, $matches)) { $resource = $matches[1]; $filters[] = new LineRangeFilter($matches[2], $matches[3]); @@ -102,11 +102,11 @@ public function load($resource, array $filters = array()) $loader = $this->resolveLoader($resource); - if (null === $loader) { - return array(); + if ($loader === null) { + return []; } - $features = array(); + $features = []; foreach ($loader->load($resource) as $feature) { foreach ($filters as $filter) { $feature = $filter->filterFeature($feature); diff --git a/src/Behat/Gherkin/Keywords/ArrayKeywords.php b/src/Behat/Gherkin/Keywords/ArrayKeywords.php index 2aa6b308..f1b95676 100644 --- a/src/Behat/Gherkin/Keywords/ArrayKeywords.php +++ b/src/Behat/Gherkin/Keywords/ArrayKeywords.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -44,8 +44,8 @@ */ class ArrayKeywords implements KeywordsInterface { - private $keywords = array(); - private $keywordString = array(); + private $keywords = []; + private $keywordString = []; private $language; /** @@ -73,7 +73,7 @@ public function setLanguage($language) } /** - * Returns Feature keywords (splitted by "|"). + * Returns Feature keywords (separated by "|"). * * @return string */ @@ -83,7 +83,7 @@ public function getFeatureKeywords() } /** - * Returns Background keywords (splitted by "|"). + * Returns Background keywords (separated by "|"). * * @return string */ @@ -93,7 +93,7 @@ public function getBackgroundKeywords() } /** - * Returns Scenario keywords (splitted by "|"). + * Returns Scenario keywords (separated by "|"). * * @return string */ @@ -103,7 +103,7 @@ public function getScenarioKeywords() } /** - * Returns Scenario Outline keywords (splitted by "|"). + * Returns Scenario Outline keywords (separated by "|"). * * @return string */ @@ -113,7 +113,7 @@ public function getOutlineKeywords() } /** - * Returns Examples keywords (splitted by "|"). + * Returns Examples keywords (separated by "|"). * * @return string */ @@ -123,7 +123,7 @@ public function getExamplesKeywords() } /** - * Returns Given keywords (splitted by "|"). + * Returns Given keywords (separated by "|"). * * @return string */ @@ -133,7 +133,7 @@ public function getGivenKeywords() } /** - * Returns When keywords (splitted by "|"). + * Returns When keywords (separated by "|"). * * @return string */ @@ -143,7 +143,7 @@ public function getWhenKeywords() } /** - * Returns Then keywords (splitted by "|"). + * Returns Then keywords (separated by "|"). * * @return string */ @@ -153,7 +153,7 @@ public function getThenKeywords() } /** - * Returns And keywords (splitted by "|"). + * Returns And keywords (separated by "|"). * * @return string */ @@ -163,7 +163,7 @@ public function getAndKeywords() } /** - * Returns But keywords (splitted by "|"). + * Returns But keywords (separated by "|"). * * @return string */ diff --git a/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php b/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php index 871f196f..71220132 100644 --- a/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php +++ b/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -26,6 +26,6 @@ class CachedArrayKeywords extends ArrayKeywords */ public function __construct($file) { - parent::__construct(include($file)); + parent::__construct(include $file); } } diff --git a/src/Behat/Gherkin/Keywords/CucumberKeywords.php b/src/Behat/Gherkin/Keywords/CucumberKeywords.php index 2a543967..49ae92e4 100644 --- a/src/Behat/Gherkin/Keywords/CucumberKeywords.php +++ b/src/Behat/Gherkin/Keywords/CucumberKeywords.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -31,8 +31,8 @@ public function __construct($yaml) { // Handle filename explicitly for BC reasons, as Symfony Yaml 3.0 does not do it anymore $file = null; - if (strpos($yaml, "\n") === false && is_file($yaml)) { - if (false === is_readable($yaml)) { + if (!str_contains($yaml, "\n") && is_file($yaml)) { + if (!is_readable($yaml)) { throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $yaml)); } @@ -54,7 +54,7 @@ public function __construct($yaml) } /** - * Returns Feature keywords (splitted by "|"). + * Returns Feature keywords (separated by "|"). * * @return string */ @@ -64,7 +64,7 @@ public function getGivenKeywords() } /** - * Returns When keywords (splitted by "|"). + * Returns When keywords (separated by "|"). * * @return string */ @@ -74,7 +74,7 @@ public function getWhenKeywords() } /** - * Returns Then keywords (splitted by "|"). + * Returns Then keywords (separated by "|"). * * @return string */ @@ -84,7 +84,7 @@ public function getThenKeywords() } /** - * Returns And keywords (splitted by "|"). + * Returns And keywords (separated by "|"). * * @return string */ @@ -94,7 +94,7 @@ public function getAndKeywords() } /** - * Returns But keywords (splitted by "|"). + * Returns But keywords (separated by "|"). * * @return string */ @@ -112,7 +112,7 @@ public function getButKeywords() */ private function prepareStepString($keywordsString) { - if (0 === mb_strpos($keywordsString, '*|', 0, 'UTF-8')) { + if (mb_strpos($keywordsString, '*|', 0, 'UTF-8') === 0) { $keywordsString = mb_substr($keywordsString, 2, mb_strlen($keywordsString, 'utf8') - 2, 'utf8'); } diff --git a/src/Behat/Gherkin/Keywords/KeywordsDumper.php b/src/Behat/Gherkin/Keywords/KeywordsDumper.php index 3254a3a3..d2bab344 100644 --- a/src/Behat/Gherkin/Keywords/KeywordsDumper.php +++ b/src/Behat/Gherkin/Keywords/KeywordsDumper.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -28,7 +28,7 @@ class KeywordsDumper public function __construct(KeywordsInterface $keywords) { $this->keywords = $keywords; - $this->keywordsDumper = array($this, 'dumpKeywords'); + $this->keywordsDumper = [$this, 'dumpKeywords']; } /** @@ -47,14 +47,14 @@ public function setKeywordsDumperFunction($mapper) * Defaults keywords dumper. * * @param array $keywords Keywords list - * @param bool $isShort Is short version + * @param bool $isShort Is short version * * @return string */ public function dumpKeywords(array $keywords, $isShort) { if ($isShort) { - return 1 < count($keywords) ? '(' . implode('|', $keywords) . ')' : $keywords[0]; + return count($keywords) > 1 ? '(' . implode('|', $keywords) . ')' : $keywords[0]; } return $keywords[0]; @@ -64,8 +64,8 @@ public function dumpKeywords(array $keywords, $isShort) * Dumps keyworded feature into string. * * @param string $language Keywords language - * @param bool $short Dump short version - * @param bool $excludeAsterisk + * @param bool $short Dump short version + * @param bool $excludeAsterisk * * @return string|array String for short version and array of features for extended */ @@ -73,7 +73,7 @@ public function dump($language, $short = true, $excludeAsterisk = false) { $this->keywords->setLanguage($language); $languageComment = ''; - if ('en' !== $language) { + if ($language !== 'en') { $languageComment = "# language: $language\n"; } @@ -85,9 +85,9 @@ public function dump($language, $short = true, $excludeAsterisk = false) return trim($languageComment . $this->dumpFeature($keywords, $short, $excludeAsterisk)); } - $features = array(); + $features = []; foreach ($keywords as $keyword) { - $keyword = call_user_func($this->keywordsDumper, array($keyword), $short); + $keyword = call_user_func($this->keywordsDumper, [$keyword], $short); $features[] = trim($languageComment . $this->dumpFeature($keyword, $short, $excludeAsterisk)); } @@ -97,8 +97,8 @@ public function dump($language, $short = true, $excludeAsterisk = false) /** * Dumps feature example. * - * @param string $keyword Item keyword - * @param bool $short Dump short version? + * @param string $keyword Item keyword + * @param bool $short Dump short version? * * @return string */ @@ -119,7 +119,7 @@ protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false $keywords = call_user_func($this->keywordsDumper, $keywords, $short); $dump .= $this->dumpBackground($keywords, $short, $excludeAsterisk); } else { - $keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short); + $keyword = call_user_func($this->keywordsDumper, [$keywords[0]], $short); $dump .= $this->dumpBackground($keyword, $short, $excludeAsterisk); } @@ -130,7 +130,7 @@ protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false $dump .= $this->dumpScenario($keywords, $short, $excludeAsterisk); } else { foreach ($keywords as $keyword) { - $keyword = call_user_func($this->keywordsDumper, array($keyword), $short); + $keyword = call_user_func($this->keywordsDumper, [$keyword], $short); $dump .= $this->dumpScenario($keyword, $short, $excludeAsterisk); } } @@ -142,7 +142,7 @@ protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false $dump .= $this->dumpOutline($keywords, $short, $excludeAsterisk); } else { foreach ($keywords as $keyword) { - $keyword = call_user_func($this->keywordsDumper, array($keyword), $short); + $keyword = call_user_func($this->keywordsDumper, [$keyword], $short); $dump .= $this->dumpOutline($keyword, $short, $excludeAsterisk); } } @@ -154,7 +154,7 @@ protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false * Dumps background example. * * @param string $keyword Item keyword - * @param bool $short Dump short version? + * @param bool $short Dump short version? * * @return string */ @@ -188,7 +188,7 @@ protected function dumpBackground($keyword, $short = true, $excludeAsterisk = fa * Dumps scenario example. * * @param string $keyword Item keyword - * @param bool $short Dump short version? + * @param bool $short Dump short version? * * @return string */ @@ -246,7 +246,7 @@ protected function dumpScenario($keyword, $short = true, $excludeAsterisk = fals * Dumps outline example. * * @param string $keyword Item keyword - * @param bool $short Dump short version? + * @param bool $short Dump short version? * * @return string */ @@ -301,7 +301,7 @@ protected function dumpOutline($keyword, $short = true, $excludeAsterisk = false if ($short) { $keyword = call_user_func($this->keywordsDumper, $keywords, $short); } else { - $keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short); + $keyword = call_user_func($this->keywordsDumper, [$keywords[0]], $short); } $dump .= <<keywordsDumper, array($keyword), $short); + $keyword = call_user_func($this->keywordsDumper, [$keyword], $short); $dump .= << * * For the full copyright and license information, please view the LICENSE @@ -25,77 +25,77 @@ interface KeywordsInterface public function setLanguage($language); /** - * Returns Feature keywords (splitted by "|"). + * Returns Feature keywords (separated by "|"). * * @return string */ public function getFeatureKeywords(); /** - * Returns Background keywords (splitted by "|"). + * Returns Background keywords (separated by "|"). * * @return string */ public function getBackgroundKeywords(); /** - * Returns Scenario keywords (splitted by "|"). + * Returns Scenario keywords (separated by "|"). * * @return string */ public function getScenarioKeywords(); /** - * Returns Scenario Outline keywords (splitted by "|"). + * Returns Scenario Outline keywords (separated by "|"). * * @return string */ public function getOutlineKeywords(); /** - * Returns Examples keywords (splitted by "|"). + * Returns Examples keywords (separated by "|"). * * @return string */ public function getExamplesKeywords(); /** - * Returns Given keywords (splitted by "|"). + * Returns Given keywords (separated by "|"). * * @return string */ public function getGivenKeywords(); /** - * Returns When keywords (splitted by "|"). + * Returns When keywords (separated by "|"). * * @return string */ public function getWhenKeywords(); /** - * Returns Then keywords (splitted by "|"). + * Returns Then keywords (separated by "|"). * * @return string */ public function getThenKeywords(); /** - * Returns And keywords (splitted by "|"). + * Returns And keywords (separated by "|"). * * @return string */ public function getAndKeywords(); /** - * Returns But keywords (splitted by "|"). + * Returns But keywords (separated by "|"). * * @return string */ public function getButKeywords(); /** - * Returns all step keywords (splitted by "|"). + * Returns all step keywords (separated by "|"). * * @return string */ diff --git a/src/Behat/Gherkin/Lexer.php b/src/Behat/Gherkin/Lexer.php index 761281ba..05453d16 100644 --- a/src/Behat/Gherkin/Lexer.php +++ b/src/Behat/Gherkin/Lexer.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -28,9 +28,9 @@ class Lexer private $lineNumber; private $eos; private $keywords; - private $keywordsCache = array(); - private $stepKeywordTypesCache = array(); - private $deferredObjects = array(); + private $keywordsCache = []; + private $stepKeywordTypesCache = []; + private $deferredObjects = []; private $deferredObjectsCount = 0; private $stashedToken; private $inPyString = false; @@ -38,7 +38,7 @@ class Lexer private $featureStarted = false; private $allowMultilineArguments = false; private $allowSteps = false; - private $pyStringDelimiter = null; + private $pyStringDelimiter; /** * Initializes lexer. @@ -53,19 +53,19 @@ public function __construct(KeywordsInterface $keywords) /** * Sets lexer input. * - * @param string $input Input string + * @param string $input Input string * @param string $language Language name * - * @throws Exception\LexerException + * @throws LexerException */ public function analyse($input, $language = 'en') { // try to detect unsupported encoding - if ('UTF-8' !== mb_detect_encoding($input, 'UTF-8', true)) { + if (mb_detect_encoding($input, 'UTF-8', true) !== 'UTF-8') { throw new LexerException('Feature file is not in UTF8 encoding'); } - $input = strtr($input, array("\r\n" => "\n", "\r" => "\n")); + $input = strtr($input, ["\r\n" => "\n", "\r" => "\n"]); $this->lines = explode("\n", $input); $this->linesCount = count($this->lines); @@ -74,7 +74,7 @@ public function analyse($input, $language = 'en') $this->trimmedLine = null; $this->eos = false; - $this->deferredObjects = array(); + $this->deferredObjects = []; $this->deferredObjectsCount = 0; $this->stashedToken = null; $this->inPyString = false; @@ -85,8 +85,8 @@ public function analyse($input, $language = 'en') $this->allowSteps = false; $this->keywords->setLanguage($this->language = $language); - $this->keywordsCache = array(); - $this->stepKeywordTypesCache = array(); + $this->keywordsCache = []; + $this->stepKeywordTypesCache = []; } /** @@ -128,7 +128,7 @@ public function deferToken(array $token) */ public function predictToken() { - if (null === $this->stashedToken) { + if ($this->stashedToken === null) { $this->stashedToken = $this->getNextToken(); } @@ -148,19 +148,19 @@ public function skipPredictedToken() /** * Constructs token with specified parameters. * - * @param string $type Token type + * @param string $type Token type * @param string $value Token value * * @return array */ public function takeToken($type, $value = null) { - return array( - 'type' => $type, - 'line' => $this->lineNumber, - 'value' => $value ?: null, - 'deferred' => false - ); + return [ + 'type' => $type, + 'line' => $this->lineNumber, + 'value' => $value ?: null, + 'deferred' => false, + ]; } /** @@ -181,7 +181,7 @@ protected function consumeLine() } /** - * Consumes first part of line from input without incrementing the line number + * Consumes first part of line from input without incrementing the line number. */ protected function consumeLineUntil(int $trimmedOffset) { @@ -196,7 +196,7 @@ protected function consumeLineUntil(int $trimmedOffset) */ protected function getTrimmedLine() { - return null !== $this->trimmedLine ? $this->trimmedLine : $this->trimmedLine = trim($this->line); + return $this->trimmedLine !== null ? $this->trimmedLine : $this->trimmedLine = trim($this->line); } /** @@ -257,9 +257,9 @@ protected function getNextToken() * Scans for token with specified regex. * * @param string $regex Regular expression - * @param string $type Expected token type + * @param string $type Expected token type * - * @return null|array + * @return array|null */ protected function scanInput($regex, $type) { @@ -277,9 +277,9 @@ protected function scanInput($regex, $type) * Scans for token with specified keywords. * * @param string $keywords Keywords (splitted with |) - * @param string $type Expected token type + * @param string $type Expected token type * - * @return null|array + * @return array|null */ protected function scanInputForKeywords($keywords, $type) { @@ -294,19 +294,19 @@ protected function scanInputForKeywords($keywords, $type) $this->consumeLine(); // turn off language searching - if ('Feature' === $type) { + if ($type === 'Feature') { $this->featureStarted = true; } // turn off PyString and Table searching - if ('Feature' === $type || 'Scenario' === $type || 'Outline' === $type) { + if ($type === 'Feature' || $type === 'Scenario' || $type === 'Outline') { $this->allowMultilineArguments = false; - } elseif ('Examples' === $type) { + } elseif ($type === 'Examples') { $this->allowMultilineArguments = true; } // turn on steps searching - if ('Scenario' === $type || 'Background' === $type || 'Outline' === $type) { + if ($type === 'Scenario' || $type === 'Background' || $type === 'Outline') { $this->allowSteps = true; } @@ -316,7 +316,7 @@ protected function scanInputForKeywords($keywords, $type) /** * Scans EOS from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanEOS() { @@ -340,10 +340,10 @@ protected function getKeywords($type) $getter = 'get' . $type . 'Keywords'; $keywords = $this->keywords->$getter(); - if ('Step' === $type) { - $padded = array(); + if ($type === 'Step') { + $padded = []; foreach (explode('|', $keywords) as $keyword) { - $padded[] = false !== mb_strpos($keyword, '<', 0, 'utf8') + $padded[] = mb_strpos($keyword, '<', 0, 'utf8') !== false ? preg_quote(mb_substr($keyword, 0, -1, 'utf8'), '/') . '\s*' : preg_quote($keyword, '/') . '\s+'; } @@ -360,7 +360,7 @@ protected function getKeywords($type) /** * Scans Feature from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanFeature() { @@ -370,7 +370,7 @@ protected function scanFeature() /** * Scans Background from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanBackground() { @@ -380,7 +380,7 @@ protected function scanBackground() /** * Scans Scenario from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanScenario() { @@ -390,7 +390,7 @@ protected function scanScenario() /** * Scans Scenario Outline from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanOutline() { @@ -400,7 +400,7 @@ protected function scanOutline() /** * Scans Scenario Outline Examples from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanExamples() { @@ -410,7 +410,7 @@ protected function scanExamples() /** * Scans Step from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanStep() { @@ -437,7 +437,7 @@ protected function scanStep() /** * Scans PyString from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanPyStringOp() { @@ -445,7 +445,7 @@ protected function scanPyStringOp() return null; } - if(!preg_match('/^\s*(?"""|```)/u', $this->line, $matches, PREG_OFFSET_CAPTURE)) { + if (!preg_match('/^\s*(?"""|```)/u', $this->line, $matches, PREG_OFFSET_CAPTURE)) { return null; } @@ -456,9 +456,8 @@ protected function scanPyStringOp() return null; } $this->pyStringDelimiter = null; - } - else { - $this->pyStringDelimiter= $delimiter; + } else { + $this->pyStringDelimiter = $delimiter; } $this->inPyString = !$this->inPyString; @@ -473,7 +472,7 @@ protected function scanPyStringOp() /** * Scans PyString content. * - * @return null|array + * @return array|null */ protected function scanPyStringContent() { @@ -491,7 +490,7 @@ protected function scanPyStringContent() /** * Scans Table Row from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanTableRow() { @@ -500,7 +499,7 @@ protected function scanTableRow() } $line = $this->getTrimmedLine(); - if (!isset($line[0]) || '|' !== $line[0] || '|' !== substr($line, -1)) { + if (!isset($line[0]) || $line[0] !== '|' || substr($line, -1) !== '|') { return null; } @@ -519,17 +518,17 @@ protected function scanTableRow() /** * Scans Tags from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanTags() { $line = $this->getTrimmedLine(); - if (!isset($line[0]) || '@' !== $line[0]) { + if (!isset($line[0]) || $line[0] !== '@') { return null; } - if(preg_match('/^(?.*)\s+#.*$/', $line, $matches)) { + if (preg_match('/^(?.*)\s+#.*$/', $line, $matches)) { ['line' => $line] = $matches; $this->consumeLineUntil(mb_strlen($line, 'utf-8')); } else { @@ -541,14 +540,13 @@ protected function scanTags() $tags = array_map('trim', $tags); $token['tags'] = $tags; - return $token; } /** * Scans Language specifier from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanLanguage() { @@ -560,7 +558,7 @@ protected function scanLanguage() return null; } - if (0 !== mb_strpos(ltrim($this->line), '#', 0, 'utf8')) { + if (mb_strpos(ltrim($this->line), '#', 0, 'utf8') !== 0) { return null; } @@ -570,7 +568,7 @@ protected function scanLanguage() /** * Scans Comment from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanComment() { @@ -579,7 +577,7 @@ protected function scanComment() } $line = $this->getTrimmedLine(); - if (0 !== mb_strpos($line, '#', 0, 'utf8')) { + if (mb_strpos($line, '#', 0, 'utf8') !== 0) { return null; } @@ -592,11 +590,11 @@ protected function scanComment() /** * Scans Newline from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanNewline() { - if ('' !== $this->getTrimmedLine()) { + if ($this->getTrimmedLine() !== '') { return null; } @@ -609,7 +607,7 @@ protected function scanNewline() /** * Scans text from input & returns it if found. * - * @return null|array + * @return array|null */ protected function scanText() { @@ -623,23 +621,24 @@ protected function scanText() * Returns step type keyword (Given, When, Then, etc.). * * @param string $native Step keyword in provided language + * * @return string */ private function getStepKeywordType($native) { // Consider "*" as a AND keyword so that it is normalized to the previous step type - if ('*' === $native) { + if ($native === '*') { return 'And'; } if (empty($this->stepKeywordTypesCache)) { - $this->stepKeywordTypesCache = array( + $this->stepKeywordTypesCache = [ 'Given' => explode('|', $this->keywords->getGivenKeywords()), 'When' => explode('|', $this->keywords->getWhenKeywords()), 'Then' => explode('|', $this->keywords->getThenKeywords()), 'And' => explode('|', $this->keywords->getAndKeywords()), - 'But' => explode('|', $this->keywords->getButKeywords()) - ); + 'But' => explode('|', $this->keywords->getButKeywords()), + ]; } foreach ($this->stepKeywordTypesCache as $type => $keywords) { diff --git a/src/Behat/Gherkin/Lexer.php~ b/src/Behat/Gherkin/Lexer.php~ new file mode 100644 index 00000000..05453d16 --- /dev/null +++ b/src/Behat/Gherkin/Lexer.php~ @@ -0,0 +1,652 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\Gherkin; + +use Behat\Gherkin\Exception\LexerException; +use Behat\Gherkin\Keywords\KeywordsInterface; + +/** + * Gherkin lexer. + * + * @author Konstantin Kudryashov + */ +class Lexer +{ + private $language; + private $lines; + private $linesCount; + private $line; + private $trimmedLine; + private $lineNumber; + private $eos; + private $keywords; + private $keywordsCache = []; + private $stepKeywordTypesCache = []; + private $deferredObjects = []; + private $deferredObjectsCount = 0; + private $stashedToken; + private $inPyString = false; + private $pyStringSwallow = 0; + private $featureStarted = false; + private $allowMultilineArguments = false; + private $allowSteps = false; + private $pyStringDelimiter; + + /** + * Initializes lexer. + * + * @param KeywordsInterface $keywords Keywords holder + */ + public function __construct(KeywordsInterface $keywords) + { + $this->keywords = $keywords; + } + + /** + * Sets lexer input. + * + * @param string $input Input string + * @param string $language Language name + * + * @throws LexerException + */ + public function analyse($input, $language = 'en') + { + // try to detect unsupported encoding + if (mb_detect_encoding($input, 'UTF-8', true) !== 'UTF-8') { + throw new LexerException('Feature file is not in UTF8 encoding'); + } + + $input = strtr($input, ["\r\n" => "\n", "\r" => "\n"]); + + $this->lines = explode("\n", $input); + $this->linesCount = count($this->lines); + $this->line = $this->lines[0]; + $this->lineNumber = 1; + $this->trimmedLine = null; + $this->eos = false; + + $this->deferredObjects = []; + $this->deferredObjectsCount = 0; + $this->stashedToken = null; + $this->inPyString = false; + $this->pyStringSwallow = 0; + + $this->featureStarted = false; + $this->allowMultilineArguments = false; + $this->allowSteps = false; + + $this->keywords->setLanguage($this->language = $language); + $this->keywordsCache = []; + $this->stepKeywordTypesCache = []; + } + + /** + * Returns current lexer language. + * + * @return string + */ + public function getLanguage() + { + return $this->language; + } + + /** + * Returns next token or previously stashed one. + * + * @return array + */ + public function getAdvancedToken() + { + return $this->getStashedToken() ?: $this->getNextToken(); + } + + /** + * Defers token. + * + * @param array $token Token to defer + */ + public function deferToken(array $token) + { + $token['deferred'] = true; + $this->deferredObjects[] = $token; + ++$this->deferredObjectsCount; + } + + /** + * Predicts the upcoming token without passing over it. + * + * @return array + */ + public function predictToken() + { + if ($this->stashedToken === null) { + $this->stashedToken = $this->getNextToken(); + } + + return $this->stashedToken; + } + + /** + * Skips over the currently-predicted token, if any. + * + * @return void + */ + public function skipPredictedToken() + { + $this->stashedToken = null; + } + + /** + * Constructs token with specified parameters. + * + * @param string $type Token type + * @param string $value Token value + * + * @return array + */ + public function takeToken($type, $value = null) + { + return [ + 'type' => $type, + 'line' => $this->lineNumber, + 'value' => $value ?: null, + 'deferred' => false, + ]; + } + + /** + * Consumes line from input & increments line counter. + */ + protected function consumeLine() + { + ++$this->lineNumber; + + if (($this->lineNumber - 1) === $this->linesCount) { + $this->eos = true; + + return; + } + + $this->line = $this->lines[$this->lineNumber - 1]; + $this->trimmedLine = null; + } + + /** + * Consumes first part of line from input without incrementing the line number. + */ + protected function consumeLineUntil(int $trimmedOffset) + { + $this->line = mb_substr(ltrim($this->line), $trimmedOffset, null, 'utf-8'); + $this->trimmedLine = null; + } + + /** + * Returns trimmed version of line. + * + * @return string + */ + protected function getTrimmedLine() + { + return $this->trimmedLine !== null ? $this->trimmedLine : $this->trimmedLine = trim($this->line); + } + + /** + * Returns stashed token or null if hasn't. + * + * @return array|null + */ + protected function getStashedToken() + { + $stashedToken = $this->stashedToken; + $this->stashedToken = null; + + return $stashedToken; + } + + /** + * Returns deferred token or null if hasn't. + * + * @return array|null + */ + protected function getDeferredToken() + { + if (!$this->deferredObjectsCount) { + return null; + } + + --$this->deferredObjectsCount; + + return array_shift($this->deferredObjects); + } + + /** + * Returns next token from input. + * + * @return array + */ + protected function getNextToken() + { + return $this->getDeferredToken() + ?: $this->scanEOS() + ?: $this->scanLanguage() + ?: $this->scanComment() + ?: $this->scanPyStringOp() + ?: $this->scanPyStringContent() + ?: $this->scanStep() + ?: $this->scanScenario() + ?: $this->scanBackground() + ?: $this->scanOutline() + ?: $this->scanExamples() + ?: $this->scanFeature() + ?: $this->scanTags() + ?: $this->scanTableRow() + ?: $this->scanNewline() + ?: $this->scanText(); + } + + /** + * Scans for token with specified regex. + * + * @param string $regex Regular expression + * @param string $type Expected token type + * + * @return array|null + */ + protected function scanInput($regex, $type) + { + if (!preg_match($regex, $this->line, $matches)) { + return null; + } + + $token = $this->takeToken($type, $matches[1]); + $this->consumeLine(); + + return $token; + } + + /** + * Scans for token with specified keywords. + * + * @param string $keywords Keywords (splitted with |) + * @param string $type Expected token type + * + * @return array|null + */ + protected function scanInputForKeywords($keywords, $type) + { + if (!preg_match('/^(\s*)(' . $keywords . '):\s*(.*)/u', $this->line, $matches)) { + return null; + } + + $token = $this->takeToken($type, $matches[3]); + $token['keyword'] = $matches[2]; + $token['indent'] = mb_strlen($matches[1], 'utf8'); + + $this->consumeLine(); + + // turn off language searching + if ($type === 'Feature') { + $this->featureStarted = true; + } + + // turn off PyString and Table searching + if ($type === 'Feature' || $type === 'Scenario' || $type === 'Outline') { + $this->allowMultilineArguments = false; + } elseif ($type === 'Examples') { + $this->allowMultilineArguments = true; + } + + // turn on steps searching + if ($type === 'Scenario' || $type === 'Background' || $type === 'Outline') { + $this->allowSteps = true; + } + + return $token; + } + + /** + * Scans EOS from input & returns it if found. + * + * @return array|null + */ + protected function scanEOS() + { + if (!$this->eos) { + return null; + } + + return $this->takeToken('EOS'); + } + + /** + * Returns keywords for provided type. + * + * @param string $type Keyword type + * + * @return string + */ + protected function getKeywords($type) + { + if (!isset($this->keywordsCache[$type])) { + $getter = 'get' . $type . 'Keywords'; + $keywords = $this->keywords->$getter(); + + if ($type === 'Step') { + $padded = []; + foreach (explode('|', $keywords) as $keyword) { + $padded[] = mb_strpos($keyword, '<', 0, 'utf8') !== false + ? preg_quote(mb_substr($keyword, 0, -1, 'utf8'), '/') . '\s*' + : preg_quote($keyword, '/') . '\s+'; + } + + $keywords = implode('|', $padded); + } + + $this->keywordsCache[$type] = $keywords; + } + + return $this->keywordsCache[$type]; + } + + /** + * Scans Feature from input & returns it if found. + * + * @return array|null + */ + protected function scanFeature() + { + return $this->scanInputForKeywords($this->getKeywords('Feature'), 'Feature'); + } + + /** + * Scans Background from input & returns it if found. + * + * @return array|null + */ + protected function scanBackground() + { + return $this->scanInputForKeywords($this->getKeywords('Background'), 'Background'); + } + + /** + * Scans Scenario from input & returns it if found. + * + * @return array|null + */ + protected function scanScenario() + { + return $this->scanInputForKeywords($this->getKeywords('Scenario'), 'Scenario'); + } + + /** + * Scans Scenario Outline from input & returns it if found. + * + * @return array|null + */ + protected function scanOutline() + { + return $this->scanInputForKeywords($this->getKeywords('Outline'), 'Outline'); + } + + /** + * Scans Scenario Outline Examples from input & returns it if found. + * + * @return array|null + */ + protected function scanExamples() + { + return $this->scanInputForKeywords($this->getKeywords('Examples'), 'Examples'); + } + + /** + * Scans Step from input & returns it if found. + * + * @return array|null + */ + protected function scanStep() + { + if (!$this->allowSteps) { + return null; + } + + $keywords = $this->getKeywords('Step'); + if (!preg_match('/^\s*(' . $keywords . ')([^\s].*)/u', $this->line, $matches)) { + return null; + } + + $keyword = trim($matches[1]); + $token = $this->takeToken('Step', $keyword); + $token['keyword_type'] = $this->getStepKeywordType($keyword); + $token['text'] = $matches[2]; + + $this->consumeLine(); + $this->allowMultilineArguments = true; + + return $token; + } + + /** + * Scans PyString from input & returns it if found. + * + * @return array|null + */ + protected function scanPyStringOp() + { + if (!$this->allowMultilineArguments) { + return null; + } + + if (!preg_match('/^\s*(?"""|```)/u', $this->line, $matches, PREG_OFFSET_CAPTURE)) { + return null; + } + + ['delimiter' => [0 => $delimiter, 1 => $indent]] = $matches; + + if ($this->inPyString) { + if ($this->pyStringDelimiter !== $delimiter) { + return null; + } + $this->pyStringDelimiter = null; + } else { + $this->pyStringDelimiter = $delimiter; + } + + $this->inPyString = !$this->inPyString; + $token = $this->takeToken('PyStringOp'); + $this->pyStringSwallow = $indent; + + $this->consumeLine(); + + return $token; + } + + /** + * Scans PyString content. + * + * @return array|null + */ + protected function scanPyStringContent() + { + if (!$this->inPyString) { + return null; + } + + $token = $this->scanText(); + // swallow trailing spaces + $token['value'] = preg_replace('/^\s{0,' . $this->pyStringSwallow . '}/u', '', $token['value'] ?? ''); + + return $token; + } + + /** + * Scans Table Row from input & returns it if found. + * + * @return array|null + */ + protected function scanTableRow() + { + if (!$this->allowMultilineArguments) { + return null; + } + + $line = $this->getTrimmedLine(); + if (!isset($line[0]) || $line[0] !== '|' || substr($line, -1) !== '|') { + return null; + } + + $token = $this->takeToken('TableRow'); + $line = mb_substr($line, 1, mb_strlen($line, 'utf8') - 2, 'utf8'); + $columns = array_map(function ($column) { + return trim(str_replace(['\\|', '\\\\'], ['|', '\\'], $column)); + }, preg_split('/(?consumeLine(); + + return $token; + } + + /** + * Scans Tags from input & returns it if found. + * + * @return array|null + */ + protected function scanTags() + { + $line = $this->getTrimmedLine(); + + if (!isset($line[0]) || $line[0] !== '@') { + return null; + } + + if (preg_match('/^(?.*)\s+#.*$/', $line, $matches)) { + ['line' => $line] = $matches; + $this->consumeLineUntil(mb_strlen($line, 'utf-8')); + } else { + $this->consumeLine(); + } + + $token = $this->takeToken('Tag'); + $tags = explode('@', mb_substr($line, 1, mb_strlen($line, 'utf8') - 1, 'utf8')); + $tags = array_map('trim', $tags); + $token['tags'] = $tags; + + return $token; + } + + /** + * Scans Language specifier from input & returns it if found. + * + * @return array|null + */ + protected function scanLanguage() + { + if ($this->featureStarted) { + return null; + } + + if ($this->inPyString) { + return null; + } + + if (mb_strpos(ltrim($this->line), '#', 0, 'utf8') !== 0) { + return null; + } + + return $this->scanInput('/^\s*\#\s*language:\s*([\w_\-]+)\s*$/', 'Language'); + } + + /** + * Scans Comment from input & returns it if found. + * + * @return array|null + */ + protected function scanComment() + { + if ($this->inPyString) { + return null; + } + + $line = $this->getTrimmedLine(); + if (mb_strpos($line, '#', 0, 'utf8') !== 0) { + return null; + } + + $token = $this->takeToken('Comment', $line); + $this->consumeLine(); + + return $token; + } + + /** + * Scans Newline from input & returns it if found. + * + * @return array|null + */ + protected function scanNewline() + { + if ($this->getTrimmedLine() !== '') { + return null; + } + + $token = $this->takeToken('Newline', mb_strlen($this->line, 'utf8')); + $this->consumeLine(); + + return $token; + } + + /** + * Scans text from input & returns it if found. + * + * @return array|null + */ + protected function scanText() + { + $token = $this->takeToken('Text', $this->line); + $this->consumeLine(); + + return $token; + } + + /** + * Returns step type keyword (Given, When, Then, etc.). + * + * @param string $native Step keyword in provided language + * + * @return string + */ + private function getStepKeywordType($native) + { + // Consider "*" as a AND keyword so that it is normalized to the previous step type + if ($native === '*') { + return 'And'; + } + + if (empty($this->stepKeywordTypesCache)) { + $this->stepKeywordTypesCache = [ + 'Given' => explode('|', $this->keywords->getGivenKeywords()), + 'When' => explode('|', $this->keywords->getWhenKeywords()), + 'Then' => explode('|', $this->keywords->getThenKeywords()), + 'And' => explode('|', $this->keywords->getAndKeywords()), + 'But' => explode('|', $this->keywords->getButKeywords()), + ]; + } + + foreach ($this->stepKeywordTypesCache as $type => $keywords) { + if (in_array($native, $keywords) || in_array($native . '<', $keywords)) { + return $type; + } + } + + return 'Given'; + } +} diff --git a/src/Behat/Gherkin/Loader/AbstractFileLoader.php b/src/Behat/Gherkin/Loader/AbstractFileLoader.php index 20932c12..fa0d2106 100644 --- a/src/Behat/Gherkin/Loader/AbstractFileLoader.php +++ b/src/Behat/Gherkin/Loader/AbstractFileLoader.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -38,8 +38,8 @@ public function setBasePath($path) */ protected function findRelativePath($path) { - if (null !== $this->basePath) { - return strtr($path, array($this->basePath . DIRECTORY_SEPARATOR => '')); + if ($this->basePath !== null) { + return strtr($path, [$this->basePath . DIRECTORY_SEPARATOR => '']); } return $path; @@ -58,7 +58,7 @@ protected function findAbsolutePath($path) return realpath($path); } - if (null === $this->basePath) { + if ($this->basePath === null) { return false; } diff --git a/src/Behat/Gherkin/Loader/ArrayLoader.php b/src/Behat/Gherkin/Loader/ArrayLoader.php index 145bed9d..0637478c 100644 --- a/src/Behat/Gherkin/Loader/ArrayLoader.php +++ b/src/Behat/Gherkin/Loader/ArrayLoader.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -47,7 +47,7 @@ public function supports($resource) */ public function load($resource) { - $features = array(); + $features = []; if (isset($resource['features'])) { foreach ($resource['features'] as $iterator => $hash) { @@ -65,30 +65,30 @@ public function load($resource) /** * Loads feature from provided feature hash. * - * @param array $hash Feature hash - * @param integer $line + * @param array $hash Feature hash + * @param int $line * * @return FeatureNode */ protected function loadFeatureHash(array $hash, $line = 0) { $hash = array_merge( - array( + [ 'title' => null, 'description' => null, - 'tags' => array(), + 'tags' => [], 'keyword' => 'Feature', 'language' => 'en', 'line' => $line, - 'scenarios' => array(), - ), + 'scenarios' => [], + ], $hash ); $background = isset($hash['background']) ? $this->loadBackgroundHash($hash['background']) : null; - $scenarios = array(); + $scenarios = []; foreach ((array) $hash['scenarios'] as $scenarioIterator => $scenarioHash) { - if (isset($scenarioHash['type']) && 'outline' === $scenarioHash['type']) { + if (isset($scenarioHash['type']) && $scenarioHash['type'] === 'outline') { $scenarios[] = $this->loadOutlineHash($scenarioHash, $scenarioIterator); } else { $scenarios[] = $this->loadScenarioHash($scenarioHash, $scenarioIterator); @@ -108,12 +108,12 @@ protected function loadFeatureHash(array $hash, $line = 0) protected function loadBackgroundHash(array $hash) { $hash = array_merge( - array( + [ 'title' => null, 'keyword' => 'Background', 'line' => 0, - 'steps' => array(), - ), + 'steps' => [], + ], $hash ); @@ -125,21 +125,21 @@ protected function loadBackgroundHash(array $hash) /** * Loads scenario from provided scenario hash. * - * @param array $hash Scenario hash - * @param integer $line Scenario definition line + * @param array $hash Scenario hash + * @param int $line Scenario definition line * * @return ScenarioNode */ protected function loadScenarioHash(array $hash, $line = 0) { $hash = array_merge( - array( + [ 'title' => null, - 'tags' => array(), + 'tags' => [], 'keyword' => 'Scenario', 'line' => $line, - 'steps' => array(), - ), + 'steps' => [], + ], $hash ); @@ -151,22 +151,22 @@ protected function loadScenarioHash(array $hash, $line = 0) /** * Loads outline from provided outline hash. * - * @param array $hash Outline hash - * @param integer $line Outline definition line + * @param array $hash Outline hash + * @param int $line Outline definition line * * @return OutlineNode */ protected function loadOutlineHash(array $hash, $line = 0) { $hash = array_merge( - array( + [ 'title' => null, - 'tags' => array(), + 'tags' => [], 'keyword' => 'Scenario Outline', 'line' => $line, - 'steps' => array(), - 'examples' => array(), - ), + 'steps' => [], + 'examples' => [], + ], $hash ); @@ -180,13 +180,13 @@ protected function loadOutlineHash(array $hash, $line = 0) } $exHash = $hash['examples']; - $examples = array(); + $examples = []; if ($this->examplesAreInArray($exHash)) { $examples = $this->processExamplesArray($exHash, $examplesKeyword, $examples); } else { // examples as a single table - we create an array with the only one element - $examples[] = new ExampleTableNode($exHash, $examplesKeyword);; + $examples[] = new ExampleTableNode($exHash, $examplesKeyword); } return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']); @@ -195,13 +195,11 @@ protected function loadOutlineHash(array $hash, $line = 0) /** * Loads steps from provided hash. * - * @param array $hash - * * @return StepNode[] */ private function loadStepsHash(array $hash) { - $steps = array(); + $steps = []; foreach ($hash as $stepIterator => $stepHash) { $steps[] = $this->loadStepHash($stepHash, $stepIterator); } @@ -212,30 +210,30 @@ private function loadStepsHash(array $hash) /** * Loads step from provided hash. * - * @param array $hash Step hash - * @param integer $line Step definition line + * @param array $hash Step hash + * @param int $line Step definition line * * @return StepNode */ protected function loadStepHash(array $hash, $line = 0) { $hash = array_merge( - array( + [ 'keyword_type' => 'Given', 'type' => 'Given', 'text' => null, 'keyword' => 'Scenario', 'line' => $line, - 'arguments' => array(), - ), + 'arguments' => [], + ], $hash ); - $arguments = array(); + $arguments = []; foreach ($hash['arguments'] as $argumentHash) { - if ('table' === $argumentHash['type']) { + if ($argumentHash['type'] === 'table') { $arguments[] = $this->loadTableHash($argumentHash['rows']); - } elseif ('pystring' === $argumentHash['type']) { + } elseif ($argumentHash['type'] === 'pystring') { $arguments[] = $this->loadPyStringHash($argumentHash, $hash['line'] + 1); } } @@ -258,8 +256,8 @@ protected function loadTableHash(array $hash) /** * Loads PyString from provided hash. * - * @param array $hash PyString hash - * @param integer $line + * @param array $hash PyString hash + * @param int $line * * @return PyStringNode */ @@ -267,7 +265,7 @@ protected function loadPyStringHash(array $hash, $line = 0) { $line = isset($hash['line']) ? $hash['line'] : $line; - $strings = array(); + $strings = []; foreach (explode("\n", $hash['text']) as $string) { $strings[] = $string; } @@ -276,8 +274,10 @@ protected function loadPyStringHash(array $hash, $line = 0) } /** - * Checks if examples node is an array + * Checks if examples node is an array. + * * @param $exHash object hash + * * @return bool */ private function examplesAreInArray($exHash) @@ -287,19 +287,20 @@ private function examplesAreInArray($exHash) /** * Processes cases when examples are in the form of array of arrays - * OR in the form of array of objects + * OR in the form of array of objects. * * @param $exHash array hash * @param $examplesKeyword string * @param $examples array + * * @return array */ private function processExamplesArray($exHash, $examplesKeyword, $examples) { - for ($i = 0; $i < count($exHash); $i++) { + for ($i = 0; $i < count($exHash); ++$i) { if (isset($exHash[$i]['table'])) { // we have examples as objects, hence there could be tags - $exHashTags = isset($exHash[$i]['tags']) ? $exHash[$i]['tags'] : array(); + $exHashTags = isset($exHash[$i]['tags']) ? $exHash[$i]['tags'] : []; $examples[] = new ExampleTableNode($exHash[$i]['table'], $examplesKeyword, $exHashTags); } else { // we have examples as arrays diff --git a/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php b/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php index 9fe763bc..e7748c6b 100644 --- a/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php +++ b/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Behat\Gherkin\Loader; use Behat\Gherkin\Node\BackgroundNode; @@ -11,11 +19,10 @@ use Behat\Gherkin\Node\StepNode; /** - * Loads a feature from cucumber's protobuf JSON format + * Loads a feature from cucumber's protobuf JSON format. */ class CucumberNDJsonAstLoader implements LoaderInterface { - public function supports($resource) { return is_string($resource); @@ -63,7 +70,7 @@ private static function getFeature(array $json, $filePath) private static function getTags(array $json) { return array_map( - static function(array $tag) { return preg_replace('/^@/', '', $tag['name']); }, + static function (array $tag) { return preg_replace('/^@/', '', $tag['name']); }, isset($json['tags']) ? $json['tags'] : [] ); } @@ -73,11 +80,9 @@ static function(array $tag) { return preg_replace('/^@/', '', $tag['name']); }, */ private static function getScenarios(array $json) { - return array_values( array_map( static function ($child) { - if ($child['scenario']['examples']) { return new OutlineNode( isset($child['scenario']['name']) ? $child['scenario']['name'] : null, @@ -87,8 +92,7 @@ static function ($child) { $child['scenario']['keyword'], $child['scenario']['location']['line'] ); - } - else { + } else { return new ScenarioNode( $child['scenario']['name'], self::getTags($child['scenario']), @@ -97,7 +101,6 @@ static function ($child) { $child['scenario']['location']['line'] ); } - }, array_filter( isset($json['children']) ? $json['children'] : [], @@ -142,7 +145,7 @@ static function ($child) { private static function getSteps(array $json) { return array_map( - static function(array $json) { + static function (array $json) { return new StepNode( trim($json['keyword']), $json['text'], @@ -161,12 +164,11 @@ static function(array $json) { private static function getTables(array $json) { return array_map( - static function($tableJson) { - + static function ($tableJson) { $table = []; $table[$tableJson['tableHeader']['location']['line']] = array_map( - static function($cell) { + static function ($cell) { return $cell['value']; }, $tableJson['tableHeader']['cells'] @@ -174,7 +176,7 @@ static function($cell) { foreach ($tableJson['tableBody'] as $bodyRow) { $table[$bodyRow['location']['line']] = array_map( - static function($cell) { + static function ($cell) { return $cell['value']; }, $bodyRow['cells'] diff --git a/src/Behat/Gherkin/Loader/DirectoryLoader.php b/src/Behat/Gherkin/Loader/DirectoryLoader.php index e0e65fcc..237b8a86 100644 --- a/src/Behat/Gherkin/Loader/DirectoryLoader.php +++ b/src/Behat/Gherkin/Loader/DirectoryLoader.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -12,8 +12,6 @@ use Behat\Gherkin\Gherkin; use Behat\Gherkin\Node\FeatureNode; -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; /** * Directory contents loader. @@ -58,19 +56,19 @@ public function load($path) { $path = $this->findAbsolutePath($path); - $iterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS) + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS) ); $paths = array_map('strval', iterator_to_array($iterator)); uasort($paths, 'strnatcasecmp'); - $features = array(); + $features = []; foreach ($paths as $path) { $path = (string) $path; $loader = $this->gherkin->resolveLoader($path); - if (null !== $loader) { + if ($loader !== null) { $features = array_merge($features, $loader->load($path)); } } diff --git a/src/Behat/Gherkin/Loader/FileLoaderInterface.php b/src/Behat/Gherkin/Loader/FileLoaderInterface.php index f18f19ae..ed696214 100644 --- a/src/Behat/Gherkin/Loader/FileLoaderInterface.php +++ b/src/Behat/Gherkin/Loader/FileLoaderInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Loader/GherkinFileLoader.php b/src/Behat/Gherkin/Loader/GherkinFileLoader.php index ac1e03fe..c7dfb007 100644 --- a/src/Behat/Gherkin/Loader/GherkinFileLoader.php +++ b/src/Behat/Gherkin/Loader/GherkinFileLoader.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -27,8 +27,8 @@ class GherkinFileLoader extends AbstractFileLoader /** * Initializes loader. * - * @param Parser $parser Parser - * @param CacheInterface $cache Cache layer + * @param Parser $parser Parser + * @param CacheInterface $cache Cache layer */ public function __construct(Parser $parser, ?CacheInterface $cache = null) { @@ -56,8 +56,8 @@ public function setCache(CacheInterface $cache) public function supports($path) { return is_string($path) - && is_file($absolute = $this->findAbsolutePath($path)) - && 'feature' === pathinfo($absolute, PATHINFO_EXTENSION); + && is_file($absolute = $this->findAbsolutePath($path)) + && pathinfo($absolute, PATHINFO_EXTENSION) === 'feature'; } /** @@ -81,7 +81,7 @@ public function load($path) $feature = $this->parseFeature($path); } - return null !== $feature ? array($feature) : array(); + return $feature !== null ? [$feature] : []; } /** diff --git a/src/Behat/Gherkin/Loader/LoaderInterface.php b/src/Behat/Gherkin/Loader/LoaderInterface.php index 322ce6c9..298dc5dd 100644 --- a/src/Behat/Gherkin/Loader/LoaderInterface.php +++ b/src/Behat/Gherkin/Loader/LoaderInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Loader/YamlFileLoader.php b/src/Behat/Gherkin/Loader/YamlFileLoader.php index 88193aa3..ee392647 100644 --- a/src/Behat/Gherkin/Loader/YamlFileLoader.php +++ b/src/Behat/Gherkin/Loader/YamlFileLoader.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -38,7 +38,7 @@ public function supports($path) { return is_string($path) && is_file($absolute = $this->findAbsolutePath($path)) - && 'yml' === pathinfo($absolute, PATHINFO_EXTENSION); + && pathinfo($absolute, PATHINFO_EXTENSION) === 'yml'; } /** diff --git a/src/Behat/Gherkin/Node/ArgumentInterface.php b/src/Behat/Gherkin/Node/ArgumentInterface.php index 4457f180..3e527019 100644 --- a/src/Behat/Gherkin/Node/ArgumentInterface.php +++ b/src/Behat/Gherkin/Node/ArgumentInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Node/BackgroundNode.php b/src/Behat/Gherkin/Node/BackgroundNode.php index 61044866..42969f4a 100644 --- a/src/Behat/Gherkin/Node/BackgroundNode.php +++ b/src/Behat/Gherkin/Node/BackgroundNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -24,23 +24,23 @@ class BackgroundNode implements ScenarioLikeInterface /** * @var StepNode[] */ - private $steps = array(); + private $steps = []; /** * @var string */ private $keyword; /** - * @var integer + * @var int */ private $line; /** * Initializes background. * - * @param null|string $title - * @param StepNode[] $steps - * @param string $keyword - * @param integer $line + * @param string|null $title + * @param StepNode[] $steps + * @param string $keyword + * @param int $line */ public function __construct($title, array $steps, $keyword, $line) { @@ -51,7 +51,7 @@ public function __construct($title, array $steps, $keyword, $line) } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -63,7 +63,7 @@ public function getNodeType() /** * Returns background title. * - * @return null|string + * @return string|null */ public function getTitle() { @@ -77,7 +77,7 @@ public function getTitle() */ public function hasSteps() { - return 0 < count($this->steps); + return count($this->steps) > 0; } /** @@ -103,7 +103,7 @@ public function getKeyword() /** * Returns background declaration line number. * - * @return integer + * @return int */ public function getLine() { diff --git a/src/Behat/Gherkin/Node/ExampleNode.php b/src/Behat/Gherkin/Node/ExampleNode.php index dfbab940..f11af793 100644 --- a/src/Behat/Gherkin/Node/ExampleNode.php +++ b/src/Behat/Gherkin/Node/ExampleNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -34,11 +34,11 @@ class ExampleNode implements ScenarioInterface, NamedScenarioInterface */ private $tokens; /** - * @var integer + * @var int */ private $line; /** - * @var null|StepNode[] + * @var StepNode[]|null */ private $steps; /** @@ -46,20 +46,20 @@ class ExampleNode implements ScenarioInterface, NamedScenarioInterface */ private $outlineTitle; /** - * @var null|int + * @var int|null */ private $index; /** * Initializes outline. * - * @param string $text The entire row as a string, e.g. "| 1 | 2 | 3 |" - * @param string[] $tags - * @param StepNode[] $outlineSteps - * @param string[] $tokens - * @param integer $line Line number within the feature file. - * @param string|null $outlineTitle Original title of the scenario outline. - * @param null|int $index The 1-based index of the row/example within the scenario outline. + * @param string $text The entire row as a string, e.g. "| 1 | 2 | 3 |" + * @param string[] $tags + * @param StepNode[] $outlineSteps + * @param string[] $tokens + * @param int $line line number within the feature file + * @param string|null $outlineTitle original title of the scenario outline + * @param int|null $index the 1-based index of the row/example within the scenario outline */ public function __construct($text, array $tags, $outlineSteps, array $tokens, $line, $outlineTitle = null, $index = null) { @@ -73,7 +73,7 @@ public function __construct($text, array $tags, $outlineSteps, array $tokens, $l } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -97,8 +97,8 @@ public function getKeyword() * * @return string * - * @deprecated You should normally not depend on the original row text, but if you really do, please switch - * to {@see self::getExampleText()} as this method will be removed in the next major version. + * @deprecated you should normally not depend on the original row text, but if you really do, please switch + * to {@see self::getExampleText()} as this method will be removed in the next major version */ public function getTitle() { @@ -124,7 +124,7 @@ public function hasTag($tag) */ public function hasTags() { - return 0 < count($this->getTags()); + return count($this->getTags()) > 0; } /** @@ -144,7 +144,7 @@ public function getTags() */ public function hasSteps() { - return 0 < count($this->outlineSteps); + return count($this->outlineSteps) > 0; } /** @@ -154,7 +154,7 @@ public function hasSteps() */ public function getSteps() { - return $this->steps = $this->steps ? : $this->createExampleSteps(); + return $this->steps = $this->steps ?: $this->createExampleSteps(); } /** @@ -170,7 +170,7 @@ public function getTokens() /** * Returns outline declaration line number. * - * @return integer + * @return int */ public function getLine() { @@ -211,7 +211,7 @@ public function getExampleText(): string */ protected function createExampleSteps() { - $steps = array(); + $steps = []; foreach ($this->outlineSteps as $outlineStep) { $keyword = $outlineStep->getKeyword(); $keywordType = $outlineStep->getKeywordType(); @@ -249,8 +249,6 @@ protected function replaceArgumentsTokens(array $arguments) /** * Replaces tokens in table with row values. * - * @param TableNode $argument - * * @return TableNode */ protected function replaceTableArgumentTokens(TableNode $argument) @@ -268,8 +266,6 @@ protected function replaceTableArgumentTokens(TableNode $argument) /** * Replaces tokens in PyString with row values. * - * @param PyStringNode $argument - * * @return PyStringNode */ protected function replacePyStringArgumentTokens(PyStringNode $argument) diff --git a/src/Behat/Gherkin/Node/ExampleTableNode.php b/src/Behat/Gherkin/Node/ExampleTableNode.php index 91753511..9b3dff4a 100644 --- a/src/Behat/Gherkin/Node/ExampleTableNode.php +++ b/src/Behat/Gherkin/Node/ExampleTableNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -34,7 +34,7 @@ class ExampleTableNode extends TableNode * @param string $keyword * @param string[] $tags */ - public function __construct(array $table, $keyword, array $tags = array()) + public function __construct(array $table, $keyword, array $tags = []) { $this->keyword = $keyword; $this->tags = $tags; @@ -43,7 +43,7 @@ public function __construct(array $table, $keyword, array $tags = array()) } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -53,8 +53,9 @@ public function getNodeType() } /** - * Returns attached tags - * @return \string[] + * Returns attached tags. + * + * @return string[] */ public function getTags() { diff --git a/src/Behat/Gherkin/Node/FeatureNode.php b/src/Behat/Gherkin/Node/FeatureNode.php index 833a5f16..21fb866c 100644 --- a/src/Behat/Gherkin/Node/FeatureNode.php +++ b/src/Behat/Gherkin/Node/FeatureNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -18,25 +18,25 @@ class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface { /** - * @var null|string + * @var string|null */ private $title; /** - * @var null|string + * @var string|null */ private $description; /** * @var string[] */ - private $tags = array(); + private $tags = []; /** - * @var null|BackgroundNode + * @var BackgroundNode|null */ private $background; /** * @var ScenarioInterface[] */ - private $scenarios = array(); + private $scenarios = []; /** * @var string */ @@ -46,26 +46,25 @@ class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface */ private $language; /** - * @var null|string + * @var string|null */ private $file; /** - * @var integer + * @var int */ private $line; /** * Initializes feature. * - * @param null|string $title - * @param null|string $description - * @param string[] $tags - * @param null|BackgroundNode $background + * @param string|null $title + * @param string|null $description + * @param string[] $tags * @param ScenarioInterface[] $scenarios - * @param string $keyword - * @param string $language - * @param null|string $file The absolute path to the feature file. - * @param integer $line + * @param string $keyword + * @param string $language + * @param string|null $file the absolute path to the feature file + * @param int $line */ public function __construct( $title, @@ -76,7 +75,7 @@ public function __construct( $keyword, $language, $file, - $line + $line, ) { // Verify that the feature file is an absolute path. if (!empty($file) && !$this->isAbsolutePath($file)) { @@ -94,7 +93,7 @@ public function __construct( } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -106,7 +105,7 @@ public function getNodeType() /** * Returns feature title. * - * @return null|string + * @return string|null */ public function getTitle() { @@ -126,7 +125,7 @@ public function hasDescription() /** * Returns feature description. * - * @return null|string + * @return string|null */ public function getDescription() { @@ -152,7 +151,7 @@ public function hasTag($tag) */ public function hasTags() { - return 0 < count($this->tags); + return count($this->tags) > 0; } /** @@ -172,13 +171,13 @@ public function getTags() */ public function hasBackground() { - return null !== $this->background; + return $this->background !== null; } /** * Returns feature background. * - * @return null|BackgroundNode + * @return BackgroundNode|null */ public function getBackground() { @@ -192,7 +191,7 @@ public function getBackground() */ public function hasScenarios() { - return 0 < count($this->scenarios); + return count($this->scenarios) > 0; } /** @@ -228,7 +227,7 @@ public function getLanguage() /** * Returns feature file as an absolute path. * - * @return null|string + * @return string|null */ public function getFile() { @@ -238,7 +237,7 @@ public function getFile() /** * Returns feature declaration line number. * - * @return integer + * @return int */ public function getLine() { @@ -256,16 +255,16 @@ public function getLine() */ protected function isAbsolutePath($file) { - if (null === $file) { + if ($file === null) { @trigger_error(sprintf('Calling "%s()" with a null in the $file argument is deprecated since Symfony 4.4.', __METHOD__), E_USER_DEPRECATED); } return strspn($file, '/\\', 0, 1) || (\strlen($file) > 3 && ctype_alpha($file[0]) - && ':' === $file[1] + && $file[1] === ':' && strspn($file, '/\\', 2, 1) ) - || null !== parse_url($file, PHP_URL_SCHEME) + || parse_url($file, PHP_URL_SCHEME) !== null ; } } diff --git a/src/Behat/Gherkin/Node/KeywordNodeInterface.php b/src/Behat/Gherkin/Node/KeywordNodeInterface.php index e6e412f3..9d76c80c 100644 --- a/src/Behat/Gherkin/Node/KeywordNodeInterface.php +++ b/src/Behat/Gherkin/Node/KeywordNodeInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -27,7 +27,7 @@ public function getKeyword(); /** * Returns node title. * - * @return null|string + * @return string|null */ public function getTitle(); } diff --git a/src/Behat/Gherkin/Node/NamedScenarioInterface.php b/src/Behat/Gherkin/Node/NamedScenarioInterface.php index 5188f664..e9475ff6 100644 --- a/src/Behat/Gherkin/Node/NamedScenarioInterface.php +++ b/src/Behat/Gherkin/Node/NamedScenarioInterface.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Behat\Gherkin\Node; interface NamedScenarioInterface diff --git a/src/Behat/Gherkin/Node/NodeInterface.php b/src/Behat/Gherkin/Node/NodeInterface.php index eabe61a0..12f02d33 100644 --- a/src/Behat/Gherkin/Node/NodeInterface.php +++ b/src/Behat/Gherkin/Node/NodeInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -18,7 +18,7 @@ interface NodeInterface { /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -27,7 +27,7 @@ public function getNodeType(); /** * Returns feature declaration line number. * - * @return integer + * @return int */ public function getLine(); } diff --git a/src/Behat/Gherkin/Node/OutlineNode.php b/src/Behat/Gherkin/Node/OutlineNode.php index 54cbd083..9ce174e2 100644 --- a/src/Behat/Gherkin/Node/OutlineNode.php +++ b/src/Behat/Gherkin/Node/OutlineNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -38,23 +38,23 @@ class OutlineNode implements ScenarioInterface */ private $keyword; /** - * @var integer + * @var int */ private $line; /** - * @var null|ExampleNode[] + * @var ExampleNode[]|null */ private $examples; /** * Initializes outline. * - * @param null|string $title - * @param string[] $tags - * @param StepNode[] $steps - * @param ExampleTableNode|ExampleTableNode[] $tables - * @param string $keyword - * @param integer $line + * @param string|null $title + * @param string[] $tags + * @param StepNode[] $steps + * @param ExampleTableNode|ExampleTableNode[] $tables + * @param string $keyword + * @param int $line */ public function __construct( $title, @@ -62,7 +62,7 @@ public function __construct( array $steps, $tables, $keyword, - $line + $line, ) { $this->title = $title; $this->tags = $tags; @@ -70,14 +70,14 @@ public function __construct( $this->keyword = $keyword; $this->line = $line; if (!is_array($tables)) { - $this->tables = array($tables); + $this->tables = [$tables]; } else { $this->tables = $tables; } } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -89,7 +89,7 @@ public function getNodeType() /** * Returns outline title. * - * @return null|string + * @return string|null */ public function getTitle() { @@ -115,7 +115,7 @@ public function hasTag($tag) */ public function hasTags() { - return 0 < count($this->getTags()); + return count($this->getTags()) > 0; } /** @@ -135,7 +135,7 @@ public function getTags() */ public function hasSteps() { - return 0 < count($this->steps); + return count($this->steps) > 0; } /** @@ -155,7 +155,7 @@ public function getSteps() */ public function hasExamples() { - return 0 < count($this->tables); + return count($this->tables) > 0; } /** @@ -164,25 +164,28 @@ public function hasExamples() * WARNING: it returns a merged table with tags lost. * * @deprecated use getExampleTables instead + * * @return ExampleTableNode */ public function getExampleTable() { - $table = array(); + $table = []; foreach ($this->tables[0]->getTable() as $k => $v) { $table[$k] = $v; } /** @var ExampleTableNode $exampleTableNode */ $exampleTableNode = new ExampleTableNode($table, $this->tables[0]->getKeyword()); - for ($i = 1; $i < count($this->tables); $i++) { + for ($i = 1; $i < count($this->tables); ++$i) { $exampleTableNode->mergeRowsFromTable($this->tables[$i]); } + return $exampleTableNode; } /** * Returns list of examples for the outline. + * * @return ExampleNode[] */ public function getExamples() @@ -192,6 +195,7 @@ public function getExamples() /** * Returns examples tables array for the outline. + * * @return ExampleTableNode[] */ public function getExampleTables() @@ -212,7 +216,7 @@ public function getKeyword() /** * Returns outline declaration line number. * - * @return integer + * @return int */ public function getLine() { @@ -226,7 +230,7 @@ public function getLine() */ protected function createExamples() { - $examples = array(); + $examples = []; foreach ($this->getExampleTables() as $exampleTable) { foreach ($exampleTable->getColumnsHash() as $rowNum => $row) { diff --git a/src/Behat/Gherkin/Node/PyStringNode.php b/src/Behat/Gherkin/Node/PyStringNode.php index f0e8948e..69589915 100644 --- a/src/Behat/Gherkin/Node/PyStringNode.php +++ b/src/Behat/Gherkin/Node/PyStringNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -20,17 +20,17 @@ class PyStringNode implements ArgumentInterface /** * @var array */ - private $strings = array(); + private $strings = []; /** - * @var integer + * @var int */ private $line; /** * Initializes PyString. * - * @param array $strings String in form of [$stringLine] - * @param integer $line Line number where string been started + * @param array $strings String in form of [$stringLine] + * @param int $line Line number where string been started */ public function __construct(array $strings, $line) { @@ -81,7 +81,7 @@ public function __toString() /** * Returns line number at which PyString was started. * - * @return integer + * @return int */ public function getLine() { diff --git a/src/Behat/Gherkin/Node/ScenarioInterface.php b/src/Behat/Gherkin/Node/ScenarioInterface.php index fb298435..96251aa7 100644 --- a/src/Behat/Gherkin/Node/ScenarioInterface.php +++ b/src/Behat/Gherkin/Node/ScenarioInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Node/ScenarioLikeInterface.php b/src/Behat/Gherkin/Node/ScenarioLikeInterface.php index 88f79347..4f6fd733 100644 --- a/src/Behat/Gherkin/Node/ScenarioLikeInterface.php +++ b/src/Behat/Gherkin/Node/ScenarioLikeInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Node/ScenarioNode.php b/src/Behat/Gherkin/Node/ScenarioNode.php index aa93a005..503413c6 100644 --- a/src/Behat/Gherkin/Node/ScenarioNode.php +++ b/src/Behat/Gherkin/Node/ScenarioNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -24,28 +24,27 @@ class ScenarioNode implements ScenarioInterface, NamedScenarioInterface /** * @var array */ - private $tags = array(); + private $tags = []; /** * @var StepNode[] */ - private $steps = array(); + private $steps = []; /** * @var string */ private $keyword; /** - * @var integer + * @var int */ private $line; /** * Initializes scenario. * - * @param null|string $title - * @param array $tags - * @param StepNode[] $steps - * @param string $keyword - * @param integer $line + * @param string|null $title + * @param StepNode[] $steps + * @param string $keyword + * @param int $line */ public function __construct($title, array $tags, array $steps, $keyword, $line) { @@ -57,7 +56,7 @@ public function __construct($title, array $tags, array $steps, $keyword, $line) } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -69,10 +68,10 @@ public function getNodeType() /** * Returns scenario title. * - * @return null|string + * @return string|null * - * @deprecated You should use {@see self::getName()} instead as this method will be removed in the next - * major version. + * @deprecated you should use {@see self::getName()} instead as this method will be removed in the next + * major version */ public function getTitle() { @@ -103,7 +102,7 @@ public function hasTag($tag) */ public function hasTags() { - return 0 < count($this->getTags()); + return count($this->getTags()) > 0; } /** @@ -123,7 +122,7 @@ public function getTags() */ public function hasSteps() { - return 0 < count($this->steps); + return count($this->steps) > 0; } /** @@ -149,7 +148,7 @@ public function getKeyword() /** * Returns scenario declaration line number. * - * @return integer + * @return int */ public function getLine() { diff --git a/src/Behat/Gherkin/Node/StepContainerInterface.php b/src/Behat/Gherkin/Node/StepContainerInterface.php index ebec3c4b..02d604eb 100644 --- a/src/Behat/Gherkin/Node/StepContainerInterface.php +++ b/src/Behat/Gherkin/Node/StepContainerInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Node/StepNode.php b/src/Behat/Gherkin/Node/StepNode.php index 77113bba..4c57200e 100644 --- a/src/Behat/Gherkin/Node/StepNode.php +++ b/src/Behat/Gherkin/Node/StepNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -34,30 +34,25 @@ class StepNode implements NodeInterface /** * @var ArgumentInterface[] */ - private $arguments = array(); + private $arguments = []; /** - * @var integer + * @var int */ private $line; /** * Initializes step. * - * @param string $keyword - * @param string $text + * @param string $keyword + * @param string $text * @param ArgumentInterface[] $arguments - * @param integer $line - * @param string $keywordType + * @param int $line + * @param string $keywordType */ public function __construct($keyword, $text, array $arguments, $line, $keywordType = null) { if (count($arguments) > 1) { - throw new NodeException(sprintf( - 'Steps could have only one argument, but `%s %s` have %d.', - $keyword, - $text, - count($arguments) - )); + throw new NodeException(sprintf('Steps could have only one argument, but `%s %s` have %d.', $keyword, $text, count($arguments))); } $this->keyword = $keyword; @@ -68,7 +63,7 @@ public function __construct($keyword, $text, array $arguments, $line, $keywordTy } /** - * Returns node type string + * Returns node type string. * * @return string */ @@ -93,7 +88,6 @@ public function getType() * Returns step keyword in provided language (Given, When, Then, etc.). * * @return string - * */ public function getKeyword() { @@ -127,7 +121,7 @@ public function getText() */ public function hasArguments() { - return 0 < count($this->arguments); + return count($this->arguments) > 0; } /** @@ -143,7 +137,7 @@ public function getArguments() /** * Returns step declaration line number. * - * @return integer + * @return int */ public function getLine() { diff --git a/src/Behat/Gherkin/Node/TableNode.php b/src/Behat/Gherkin/Node/TableNode.php index 4099f640..5552a193 100644 --- a/src/Behat/Gherkin/Node/TableNode.php +++ b/src/Behat/Gherkin/Node/TableNode.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -10,27 +10,24 @@ namespace Behat\Gherkin\Node; -use ArrayIterator; use Behat\Gherkin\Exception\NodeException; use Iterator; -use IteratorAggregate; -use ReturnTypeWillChange; /** * Represents Gherkin Table argument. * * @author Konstantin Kudryashov */ -class TableNode implements ArgumentInterface, IteratorAggregate +class TableNode implements ArgumentInterface, \IteratorAggregate { /** * @var array */ private $table; /** - * @var integer + * @var int */ - private $maxLineLength = array(); + private $maxLineLength = []; /** * Initializes table. @@ -45,13 +42,8 @@ public function __construct(array $table) $columnCount = null; foreach ($this->getRows() as $ridx => $row) { - if (!is_array($row)) { - throw new NodeException(sprintf( - "Table row '%s' is expected to be array, got %s", - $ridx, - gettype($row) - )); + throw new NodeException(sprintf("Table row '%s' is expected to be array, got %s", $ridx, gettype($row))); } if ($columnCount === null) { @@ -59,12 +51,7 @@ public function __construct(array $table) } if (count($row) !== $columnCount) { - throw new NodeException(sprintf( - "Table row '%s' is expected to have %s columns, got %s", - $ridx, - $columnCount, - count($row) - )); + throw new NodeException(sprintf("Table row '%s' is expected to have %s columns, got %s", $ridx, $columnCount, count($row))); } foreach ($row as $column => $string) { @@ -73,12 +60,7 @@ public function __construct(array $table) } if (!is_scalar($string)) { - throw new NodeException(sprintf( - "Table cell at row '%s', col '%s' is expected to be scalar, got %s", - $ridx, - $column, - gettype($string) - )); + throw new NodeException(sprintf("Table cell at row '%s', col '%s' is expected to be scalar, got %s", $ridx, $column, gettype($string))); } $this->maxLineLength[$column] = max($this->maxLineLength[$column], mb_strlen($string, 'utf8')); @@ -102,8 +84,9 @@ public static function fromList(array $list) } array_walk($list, function (&$item) { - $item = array($item); + $item = [$item]; }); + return new self($list); } @@ -137,7 +120,7 @@ public function getColumnsHash() $rows = $this->getRows(); $keys = array_shift($rows); - $hash = array(); + $hash = []; foreach ($rows as $row) { $hash[] = array_combine($keys, $row); } @@ -152,10 +135,10 @@ public function getColumnsHash() */ public function getRowsHash() { - $hash = array(); + $hash = []; foreach ($this->getRows() as $row) { - $hash[array_shift($row)] = (1 == count($row)) ? $row[0] : $row; + $hash[array_shift($row)] = (count($row) == 1) ? $row[0] : $row; } return $hash; @@ -195,7 +178,7 @@ public function getLines() /** * Returns specific row in a table. * - * @param integer $index Row number + * @param int $index Row number * * @return array * @@ -215,7 +198,7 @@ public function getRow($index) /** * Returns specific column in a table. * - * @param integer $index Column number + * @param int $index Column number * * @return array * @@ -228,7 +211,7 @@ public function getColumn($index) } $rows = $this->getRows(); - $column = array(); + $column = []; foreach ($rows as $row) { $column[] = $row[$index]; @@ -240,9 +223,9 @@ public function getColumn($index) /** * Returns line number at which specific row was defined. * - * @param integer $index + * @param int $index * - * @return integer + * @return int * * @throws NodeException If row with specified index does not exist */ @@ -260,13 +243,13 @@ public function getRowLine($index) /** * Converts row into delimited string. * - * @param integer $rowNum Row number + * @param int $rowNum Row number * * @return string */ public function getRowAsString($rowNum) { - $values = array(); + $values = []; foreach ($this->getRow($rowNum) as $column => $value) { $values[] = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2); } @@ -277,14 +260,14 @@ public function getRowAsString($rowNum) /** * Converts row into delimited string. * - * @param integer $rowNum Row number + * @param int $rowNum Row number * @param callable $wrapper Wrapper function * * @return string */ public function getRowAsStringWithWrappedValues($rowNum, $wrapper) { - $values = array(); + $values = []; foreach ($this->getRow($rowNum) as $column => $value) { $value = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2); @@ -295,14 +278,14 @@ public function getRowAsStringWithWrappedValues($rowNum, $wrapper) } /** - * Converts entire table into string + * Converts entire table into string. * * @return string */ public function getTableAsString() { - $lines = array(); - for ($i = 0; $i < count($this->getRows()); $i++) { + $lines = []; + for ($i = 0; $i < count($this->getRows()); ++$i) { $lines[] = $this->getRowAsString($i); } @@ -312,7 +295,7 @@ public function getTableAsString() /** * Returns line number at which table was started. * - * @return integer + * @return int */ public function getLine() { @@ -320,7 +303,7 @@ public function getLine() } /** - * Converts table into string + * Converts table into string. * * @return string */ @@ -332,18 +315,17 @@ public function __toString() /** * Retrieves a hash iterator. * - * @return Iterator + * @return \Iterator */ - #[ReturnTypeWillChange] + #[\ReturnTypeWillChange] public function getIterator() { - return new ArrayIterator($this->getHash()); + return new \ArrayIterator($this->getHash()); } /** * Obtains and adds rows from another table to the current table. * The second table should have the same structure as the current one. - * @param TableNode $node * * @deprecated remove together with OutlineNode::getExampleTable */ @@ -351,7 +333,7 @@ public function mergeRowsFromTable(TableNode $node) { // check structure if ($this->getRow(0) !== $node->getRow(0)) { - throw new NodeException("Tables have different structure. Cannot merge one into another"); + throw new NodeException('Tables have different structure. Cannot merge one into another'); } $firstLine = $node->getLine(); @@ -367,8 +349,8 @@ public function mergeRowsFromTable(TableNode $node) /** * Pads string right. * - * @param string $text Text to pad - * @param integer $length Length + * @param string $text Text to pad + * @param int $length Length * * @return string */ diff --git a/src/Behat/Gherkin/Node/TaggedNodeInterface.php b/src/Behat/Gherkin/Node/TaggedNodeInterface.php index 4afa6d1d..c313aadb 100644 --- a/src/Behat/Gherkin/Node/TaggedNodeInterface.php +++ b/src/Behat/Gherkin/Node/TaggedNodeInterface.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE diff --git a/src/Behat/Gherkin/Parser.php b/src/Behat/Gherkin/Parser.php index cc6ed005..35fcb089 100644 --- a/src/Behat/Gherkin/Parser.php +++ b/src/Behat/Gherkin/Parser.php @@ -1,7 +1,7 @@ * * For the full copyright and license information, please view the LICENSE @@ -37,10 +37,10 @@ class Parser private $lexer; private $input; private $file; - private $tags = array(); + private $tags = []; private $languageSpecifierLine; - private $passedNodesStack = array(); + private $passedNodesStack = []; /** * Initializes parser. @@ -56,7 +56,7 @@ public function __construct(Lexer $lexer) * Parses input & returns features array. * * @param string $input Gherkin string document - * @param string $file File name + * @param string $file File name * * @return FeatureNode|null * @@ -67,23 +67,19 @@ public function parse($input, $file = null) $this->languageSpecifierLine = null; $this->input = $input; $this->file = $file; - $this->tags = array(); + $this->tags = []; try { $this->lexer->analyse($this->input, 'en'); } catch (LexerException $e) { - throw new ParserException( - sprintf('Lexer exception "%s" thrown for file %s', $e->getMessage(), $file), - 0, - $e - ); + throw new ParserException(sprintf('Lexer exception "%s" thrown for file %s', $e->getMessage(), $file), 0, $e); } $feature = null; while ('EOS' !== ($predicted = $this->predictTokenType())) { $node = $this->parseExpression(); - if (null === $node || "\n" === $node) { + if ($node === null || $node === "\n") { continue; } @@ -93,27 +89,15 @@ public function parse($input, $file = null) } if ($feature && $node instanceof FeatureNode) { - throw new ParserException(sprintf( - 'Only one feature is allowed per feature file. But %s got multiple.', - $this->file - )); + throw new ParserException(sprintf('Only one feature is allowed per feature file. But %s got multiple.', $this->file)); } if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Feature, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Feature, but got text: "%s"%s', $node, $this->file ? ' in file: ' . $this->file : '')); } if (!$node instanceof FeatureNode) { - throw new ParserException(sprintf( - 'Expected Feature, but got %s on line: %d%s', - $node->getKeyword(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Feature, but got %s on line: %d%s', $node->getKeyword(), $node->getLine(), $this->file ? ' in file: ' . $this->file : '')); } } @@ -127,7 +111,7 @@ public function parse($input, $file = null) * * @return array * - * @throws Exception\ParserException + * @throws ParserException */ protected function expectTokenType($type) { @@ -138,13 +122,7 @@ protected function expectTokenType($type) $token = $this->lexer->predictToken(); - throw new ParserException(sprintf( - 'Expected %s token, but got %s on line: %d%s', - implode(' or ', $types), - $this->predictTokenType(), - $token['line'], - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected %s token, but got %s on line: %d%s', implode(' or ', $types), $this->predictTokenType(), $token['line'], $this->file ? ' in file: ' . $this->file : '')); } /** @@ -152,7 +130,7 @@ protected function expectTokenType($type) * * @param string $type Token type * - * @return null|array + * @return array|null */ protected function acceptTokenType($type) { @@ -239,7 +217,7 @@ protected function parseFeature() $description = null; $tags = $this->popTags(); $background = null; - $scenarios = array(); + $scenarios = []; $keyword = $token['keyword']; $language = $this->lexer->getLanguage(); $file = $this->file; @@ -248,12 +226,12 @@ protected function parseFeature() array_push($this->passedNodesStack, 'Feature'); // Parse description, background, scenarios & outlines - while ('EOS' !== $this->predictTokenType()) { + while ($this->predictTokenType() !== 'EOS') { $node = $this->parseExpression(); if (is_string($node)) { $text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node); - $description .= (null !== $description ? "\n" : '') . $text; + $description .= ($description !== null ? "\n" : '') . $text; continue; } @@ -268,21 +246,11 @@ protected function parseFeature() } if ($background instanceof BackgroundNode && $node instanceof BackgroundNode) { - throw new ParserException(sprintf( - 'Each Feature could have only one Background, but found multiple on lines %d and %d%s', - $background->getLine(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Each Feature could have only one Background, but found multiple on lines %d and %d%s', $background->getLine(), $node->getLine(), $this->file ? ' in file: ' . $this->file : '')); } if (!$node instanceof ScenarioNode) { - throw new ParserException(sprintf( - 'Expected Scenario, Outline or Background, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Scenario, Outline or Background, but got %s on line: %d%s', $node->getNodeType(), $node->getLine(), $this->file ? ' in file: ' . $this->file : '')); } } @@ -315,16 +283,12 @@ protected function parseBackground() $line = $token['line']; if (count($this->popTags())) { - throw new ParserException(sprintf( - 'Background can not be tagged, but it is on line: %d%s', - $line, - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Background can not be tagged, but it is on line: %d%s', $line, $this->file ? ' in file: ' . $this->file : '')); } // Parse description and steps - $steps = array(); - $allowedTokenTypes = array('Step', 'Newline', 'Text', 'Comment'); + $steps = []; + $allowedTokenTypes = ['Step', 'Newline', 'Text', 'Comment']; while (in_array($this->predictTokenType(), $allowedTokenTypes)) { $node = $this->parseExpression(); @@ -339,25 +303,16 @@ protected function parseBackground() continue; } - if ("\n" === $node) { + if ($node === "\n") { continue; } if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Step, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Step, but got text: "%s"%s', $node, $this->file ? ' in file: ' . $this->file : '')); } if (!$node instanceof StepNode) { - throw new ParserException(sprintf( - 'Expected Step, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Step, but got %s on line: %d%s', $node->getNodeType(), $node->getLine(), $this->file ? ' in file: ' . $this->file : '')); } } @@ -383,8 +338,8 @@ protected function parseScenario() array_push($this->passedNodesStack, 'Scenario'); // Parse description and steps - $steps = array(); - while (in_array($this->predictTokenType(), array('Step', 'Newline', 'Text', 'Comment'))) { + $steps = []; + while (in_array($this->predictTokenType(), ['Step', 'Newline', 'Text', 'Comment'])) { $node = $this->parseExpression(); if ($node instanceof StepNode) { @@ -398,25 +353,16 @@ protected function parseScenario() continue; } - if ("\n" === $node) { + if ($node === "\n") { continue; } if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Step, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Step, but got text: "%s"%s', $node, $this->file ? ' in file: ' . $this->file : '')); } if (!$node instanceof StepNode) { - throw new ParserException(sprintf( - 'Expected Step, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Step, but got %s on line: %d%s', $node->getNodeType(), $node->getLine(), $this->file ? ' in file: ' . $this->file : '')); } } @@ -441,15 +387,15 @@ protected function parseOutline() $keyword = $token['keyword']; /** @var ExampleTableNode $examples */ - $examples = array(); + $examples = []; $line = $token['line']; // Parse description, steps and examples - $steps = array(); + $steps = []; array_push($this->passedNodesStack, 'Outline'); - while (in_array($nextTokenType = $this->predictTokenType(), array('Step', 'Examples', 'Newline', 'Text', 'Comment', 'Tag'))) { + while (in_array($nextTokenType = $this->predictTokenType(), ['Step', 'Examples', 'Newline', 'Text', 'Comment', 'Tag'])) { if ($nextTokenType === 'Comment') { $this->lexer->skipPredictedToken(); continue; @@ -474,35 +420,21 @@ protected function parseOutline() continue; } - if ("\n" === $node) { + if ($node === "\n") { continue; } if (is_string($node)) { - throw new ParserException(sprintf( - 'Expected Step or Examples table, but got text: "%s"%s', - $node, - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Step or Examples table, but got text: "%s"%s', $node, $this->file ? ' in file: ' . $this->file : '')); } if (!$node instanceof StepNode) { - throw new ParserException(sprintf( - 'Expected Step or Examples table, but got %s on line: %d%s', - $node->getNodeType(), - $node->getLine(), - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Expected Step or Examples table, but got %s on line: %d%s', $node->getNodeType(), $node->getLine(), $this->file ? ' in file: ' . $this->file : '')); } } if (empty($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 : '' - )); + 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); @@ -524,9 +456,9 @@ protected function parseStep() array_push($this->passedNodesStack, 'Step'); - $arguments = array(); - while (in_array($predicted = $this->predictTokenType(), array('PyStringOp', 'TableRow', 'Newline', 'Comment'))) { - if ('Comment' === $predicted || 'Newline' === $predicted) { + $arguments = []; + while (in_array($predicted = $this->predictTokenType(), ['PyStringOp', 'TableRow', 'Newline', 'Comment'])) { + if ($predicted === 'Comment' || $predicted === 'Newline') { $this->acceptTokenType($predicted); continue; } @@ -550,13 +482,13 @@ protected function parseStep() */ protected function parseExamples() { - $keyword = ($this->expectTokenType('Examples'))['keyword']; - $tags = empty($this->tags) ? array() : $this->popTags(); + $keyword = $this->expectTokenType('Examples')['keyword']; + $tags = empty($this->tags) ? [] : $this->popTags(); $table = $this->parseTableRows(); try { return new ExampleTableNode($table, $keyword, $tags); - } catch(NodeException $e) { + } catch (NodeException $e) { $this->rethrowNodeException($e); } } @@ -572,7 +504,7 @@ protected function parseTable() try { return new TableNode($table); - } catch(NodeException $e) { + } catch (NodeException $e) { $this->rethrowNodeException($e); } } @@ -588,8 +520,8 @@ protected function parsePyString() $line = $token['line']; - $strings = array(); - while ('PyStringOp' !== ($predicted = $this->predictTokenType()) && 'Text' === $predicted) { + $strings = []; + while ('PyStringOp' !== ($predicted = $this->predictTokenType()) && $predicted === 'Text') { $token = $this->expectTokenType('Text'); $strings[] = $token['value']; @@ -613,12 +545,12 @@ protected function parseTags() $this->tags = array_merge($this->tags, $token['tags']); - $possibleTransitions = array( - 'Outline' => array( + $possibleTransitions = [ + 'Outline' => [ 'Examples', - 'Step' - ) - ); + 'Step', + ], + ]; $currentType = '-1'; // check if that is ok to go inside: @@ -642,13 +574,13 @@ protected function parseTags() protected function popTags() { $tags = $this->tags; - $this->tags = array(); + $this->tags = []; return $tags; } /** - * Checks the tags fit the required format + * Checks the tags fit the required format. * * @param string[] $tags */ @@ -696,31 +628,26 @@ protected function parseLanguage() { $token = $this->expectTokenType('Language'); - if (null === $this->languageSpecifierLine) { + if ($this->languageSpecifierLine === null) { $this->lexer->analyse($this->input, $token['value']); $this->languageSpecifierLine = $token['line']; } elseif ($token['line'] !== $this->languageSpecifierLine) { - throw new ParserException(sprintf( - 'Ambiguous language specifiers on lines: %d and %d%s', - $this->languageSpecifierLine, - $token['line'], - $this->file ? ' in file: ' . $this->file : '' - )); + throw new ParserException(sprintf('Ambiguous language specifiers on lines: %d and %d%s', $this->languageSpecifierLine, $token['line'], $this->file ? ' in file: ' . $this->file : '')); } return $this->parseExpression(); } /** - * Parses the rows of a table + * Parses the rows of a table. * * @return string[][] */ private function parseTableRows() { - $table = array(); - while (in_array($predicted = $this->predictTokenType(), array('TableRow', 'Newline', 'Comment'))) { - if ('Comment' === $predicted || 'Newline' === $predicted) { + $table = []; + while (in_array($predicted = $this->predictTokenType(), ['TableRow', 'Newline', 'Comment'])) { + if ($predicted === 'Comment' || $predicted === 'Newline') { $this->acceptTokenType($predicted); continue; } @@ -734,16 +661,16 @@ private function parseTableRows() } /** - * Changes step node type for types But, And to type of previous step if it exists else sets to Given + * Changes step node type for types But, And to type of previous step if it exists else sets to Given. * - * @param StepNode $node * @param StepNode[] $steps + * * @return StepNode */ - private function normalizeStepNodeKeywordType(StepNode $node, array $steps = array()) + private function normalizeStepNodeKeywordType(StepNode $node, array $steps = []) { - if (in_array($node->getKeywordType(), array('And', 'But'))) { - if (($prev = end($steps))) { + if (in_array($node->getKeywordType(), ['And', 'But'])) { + if ($prev = end($steps)) { $keywordType = $prev->getKeywordType(); } else { $keywordType = 'Given'; @@ -757,15 +684,12 @@ private function normalizeStepNodeKeywordType(StepNode $node, array $steps = arr $keywordType ); } + return $node; } private function rethrowNodeException(NodeException $e): void { - throw new ParserException( - $e->getMessage() . ($this->file ? ' in file ' . $this->file : ''), - 0, - $e - ); + throw new ParserException($e->getMessage() . ($this->file ? ' in file ' . $this->file : ''), 0, $e); } } diff --git a/tests/Behat/Gherkin/Cache/FileCacheTest.php b/tests/Behat/Gherkin/Cache/FileCacheTest.php index 24ec1e4d..a8f0f466 100644 --- a/tests/Behat/Gherkin/Cache/FileCacheTest.php +++ b/tests/Behat/Gherkin/Cache/FileCacheTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Cache; use Behat\Gherkin\Cache\FileCache; @@ -21,7 +29,7 @@ public function testIsFreshWhenThereIsNoFile(): void public function testIsFreshOnFreshFile(): void { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, null); $this->cache->write('some_path', $feature); @@ -30,7 +38,7 @@ public function testIsFreshOnFreshFile(): void public function testIsFreshOnOutdated(): void { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, null); $this->cache->write('some_path', $feature); @@ -39,8 +47,8 @@ public function testIsFreshOnOutdated(): void public function testCacheAndRead(): void { - $scenarios = array(new ScenarioNode('Some scenario', array(), array(), null, null)); - $feature = new FeatureNode('Some feature', 'some description', array(), null, $scenarios, null, null, null, null); + $scenarios = [new ScenarioNode('Some scenario', [], [], null, null)]; + $feature = new FeatureNode('Some feature', 'some description', [], null, $scenarios, null, null, null, null); $this->cache->write('some_feature', $feature); $featureRead = $this->cache->read('some_feature'); diff --git a/tests/Behat/Gherkin/Cache/MemoryCacheTest.php b/tests/Behat/Gherkin/Cache/MemoryCacheTest.php index 421bc0bc..326a5bb9 100644 --- a/tests/Behat/Gherkin/Cache/MemoryCacheTest.php +++ b/tests/Behat/Gherkin/Cache/MemoryCacheTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Cache; use Behat\Gherkin\Cache\MemoryCache; @@ -18,7 +26,7 @@ public function testIsFreshWhenThereIsNoFile() public function testIsFreshOnFreshFile() { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, null); $this->cache->write('some_path', $feature); @@ -27,7 +35,7 @@ public function testIsFreshOnFreshFile() public function testIsFreshOnOutdated() { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, null); $this->cache->write('some_path', $feature); @@ -36,8 +44,8 @@ public function testIsFreshOnOutdated() public function testCacheAndRead() { - $scenarios = array(new ScenarioNode('Some scenario', array(), array(), null, null)); - $feature = new FeatureNode('Some feature', 'some description', array(), null, $scenarios, null, null, null, null); + $scenarios = [new ScenarioNode('Some scenario', [], [], null, null)]; + $feature = new FeatureNode('Some feature', 'some description', [], null, $scenarios, null, null, null, null); $this->cache->write('some_feature', $feature); $featureRead = $this->cache->read('some_feature'); diff --git a/tests/Behat/Gherkin/Cucumber/CompatibilityTest.php b/tests/Behat/Gherkin/Cucumber/CompatibilityTest.php index 9d15041a..76ac0eae 100644 --- a/tests/Behat/Gherkin/Cucumber/CompatibilityTest.php +++ b/tests/Behat/Gherkin/Cucumber/CompatibilityTest.php @@ -1,29 +1,34 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + 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; /** - * Tests the parser against the upstream cucumber/gherkin test data + * Tests the parser against the upstream cucumber/gherkin test data. * * @group cucumber-compatibility */ class CompatibilityTest extends TestCase { - const TESTDATA_PATH = __DIR__ . '/../../../../vendor/cucumber/cucumber/gherkin/testdata'; + public const TESTDATA_PATH = __DIR__ . '/../../../../vendor/cucumber/cucumber/gherkin/testdata'; private $notParsingCorrectly = [ 'complex_background.feature' => 'Rule keyword not supported', @@ -63,7 +68,7 @@ class CompatibilityTest extends TestCase protected function setUp(): void { $arrKeywords = include __DIR__ . '/../../../../i18n.php'; - $lexer = new Lexer(new Keywords\ArrayKeywords($arrKeywords)); + $lexer = new Lexer(new Keywords\ArrayKeywords($arrKeywords)); $this->parser = new Parser($lexer); $this->loader = new CucumberNDJsonAstLoader(); } @@ -73,7 +78,7 @@ protected function setUp(): void */ public function testFeaturesParseTheSameAsCucumber(\SplFileInfo $file) { - if (isset($this->notParsingCorrectly[$file->getFilename()])){ + if (isset($this->notParsingCorrectly[$file->getFilename()])) { $this->markTestIncomplete($this->notParsingCorrectly[$file->getFilename()]); } @@ -95,7 +100,7 @@ public function testFeaturesParseTheSameAsCucumber(\SplFileInfo $file) */ public function testBadFeaturesDoNotParse(\SplFileInfo $file) { - if (isset($this->parsedButShouldNotBe[$file->getFilename()])){ + if (isset($this->parsedButShouldNotBe[$file->getFilename()])) { $this->markTestIncomplete($this->parsedButShouldNotBe[$file->getFilename()]); } @@ -122,27 +127,26 @@ private static function getCucumberFeatures($folder) { foreach (new \FilesystemIterator(self::TESTDATA_PATH . $folder) as $file) { if ($file->isFile() && $file->getExtension() == 'feature') { - yield $file->getFilename() => array($file); + yield $file->getFilename() => [$file]; } } } /** - * Renove features that aren't present in the cucumber source + * Renove features that aren't present in the cucumber source. */ private function normaliseFeature($featureNode) { - if (is_null($featureNode)) { return null; } $scenarios = array_map( - function(ScenarioInterface $scenarioNode) { + function (ScenarioInterface $scenarioNode) { $steps = array_map( - function(StepNode $step) { + function (StepNode $step) { $this->setPrivateProperty($step, 'keywordType', ''); - $this->setPrivateProperty($step, 'arguments', array()); + $this->setPrivateProperty($step, 'arguments', []); return $step; }, @@ -156,7 +160,6 @@ function(StepNode $step) { $featureNode->getScenarios() ); - return $featureNode; } @@ -168,7 +171,8 @@ private function setPrivateProperty($object, $propertyName, $value) $property->setValue($object, $value); } - private function expectDeprecationErrorMatches($message) { + private function expectDeprecationErrorMatches($message) + { set_error_handler( static function ($errno, $errstr) { restore_error_handler(); diff --git a/tests/Behat/Gherkin/Filter/FilterTestCase.php b/tests/Behat/Gherkin/Filter/FilterTestCase.php index fb056b48..ac98c964 100644 --- a/tests/Behat/Gherkin/Filter/FilterTestCase.php +++ b/tests/Behat/Gherkin/Filter/FilterTestCase.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Keywords\ArrayKeywords; @@ -13,20 +21,20 @@ protected function getParser() { return new Parser( new Lexer( - new ArrayKeywords(array( - 'en' => array( - 'feature' => 'Feature', - 'background' => 'Background', - 'scenario' => 'Scenario', + new ArrayKeywords([ + 'en' => [ + 'feature' => 'Feature', + 'background' => 'Background', + 'scenario' => 'Scenario', 'scenario_outline' => 'Scenario Outline|Scenario Template', - 'examples' => 'Examples|Scenarios', - 'given' => 'Given', - 'when' => 'When', - 'then' => 'Then', - 'and' => 'And', - 'but' => 'But' - ) - )) + 'examples' => 'Examples|Scenarios', + 'given' => 'Given', + 'when' => 'When', + 'then' => 'Then', + 'and' => 'And', + 'but' => 'But', + ], + ]) ) ); } diff --git a/tests/Behat/Gherkin/Filter/LineFilterTest.php b/tests/Behat/Gherkin/Filter/LineFilterTest.php index e621e8e5..1dae2537 100644 --- a/tests/Behat/Gherkin/Filter/LineFilterTest.php +++ b/tests/Behat/Gherkin/Filter/LineFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\LineFilter; @@ -12,7 +20,7 @@ class LineFilterTest extends FilterTestCase { public function testIsFeatureMatchFilter() { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, 1); $filter = new LineFilter(1); $this->assertTrue($filter->isFeatureMatch($feature)); @@ -26,7 +34,7 @@ public function testIsFeatureMatchFilter() public function testIsScenarioMatchFilter() { - $scenario = new ScenarioNode(null, array(), array(), null, 2); + $scenario = new ScenarioNode(null, [], [], null, 2); $filter = new LineFilter(2); $this->assertTrue($filter->isScenarioMatch($scenario)); @@ -37,7 +45,7 @@ public function testIsScenarioMatchFilter() $filter = new LineFilter(5); $this->assertFalse($filter->isScenarioMatch($scenario)); - $outline = new OutlineNode(null, array(), array(), new ExampleTableNode(array(), null), null, 20); + $outline = new OutlineNode(null, [], [], new ExampleTableNode([], null), null, 20); $filter = new LineFilter(5); $this->assertFalse($filter->isScenarioMatch($outline)); @@ -67,7 +75,7 @@ public function testFilterFeatureOutline() { $filter = new LineFilter(13); $feature = $filter->filterFeature($this->getParsedFeature()); - /** @var OutlineNode[] $scenarios */ + /* @var OutlineNode[] $scenarios */ $this->assertCount(1, $scenarios = $feature->getScenarios()); $this->assertSame('Scenario#3', $scenarios[0]->getTitle()); $this->assertCount(4, $scenarios[0]->getExampleTable()->getRows()); @@ -79,11 +87,11 @@ public function testFilterFeatureOutline() $exampleTableNodes = $scenarios[0]->getExampleTables(); $this->assertEquals(1, count($exampleTableNodes)); $this->assertCount(2, $exampleTableNodes[0]->getRows()); - $this->assertSame(array( - array('action', 'outcome'), - array('act#1', 'out#1'), - ), $exampleTableNodes[0]->getRows()); - $this->assertEquals(array('etag1'), $exampleTableNodes[0]->getTags()); + $this->assertSame([ + ['action', 'outcome'], + ['act#1', 'out#1'], + ], $exampleTableNodes[0]->getRows()); + $this->assertEquals(['etag1'], $exampleTableNodes[0]->getTags()); $filter = new LineFilter(26); $feature = $filter->filterFeature($this->getParsedFeature()); @@ -92,17 +100,17 @@ public function testFilterFeatureOutline() $exampleTableNodes = $scenarios[0]->getExampleTables(); $this->assertEquals(1, count($exampleTableNodes)); $this->assertCount(2, $exampleTableNodes[0]->getRows()); - $this->assertSame(array( - array('action', 'outcome'), - array('act#3', 'out#3'), - ), $exampleTableNodes[0]->getRows()); - $this->assertEquals(array('etag2'), $exampleTableNodes[0]->getTags()); + $this->assertSame([ + ['action', 'outcome'], + ['act#3', 'out#3'], + ], $exampleTableNodes[0]->getRows()); + $this->assertEquals(['etag2'], $exampleTableNodes[0]->getTags()); $filter = new LineFilter(19); $feature = $filter->filterFeature($this->getParsedFeature()); $this->assertCount(1, $scenarios = $feature->getScenarios()); $this->assertSame('Scenario#3', $scenarios[0]->getTitle()); $this->assertCount(1, $scenarios[0]->getExampleTable()->getRows()); - $this->assertSame(array(array('action', 'outcome')), $scenarios[0]->getExampleTable()->getRows()); + $this->assertSame([['action', 'outcome']], $scenarios[0]->getExampleTable()->getRows()); } } diff --git a/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php b/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php index 8609bee0..df060bd1 100644 --- a/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php +++ b/tests/Behat/Gherkin/Filter/LineRangeFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\LineRangeFilter; @@ -12,13 +20,13 @@ class LineRangeFilterTest extends FilterTestCase { public function featureLineRangeProvider() { - return array( - array('1', '1', true), - array('1', '2', true), - array('1', '*', true), - array('2', '2', false), - array('2', '*', false) - ); + return [ + ['1', '1', true], + ['1', '2', true], + ['1', '*', true], + ['2', '2', false], + ['2', '*', false], + ]; } /** @@ -26,7 +34,7 @@ public function featureLineRangeProvider() */ public function testIsFeatureMatchFilter($filterMinLine, $filterMaxLine, $expected) { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, 1); $filter = new LineRangeFilter($filterMinLine, $filterMaxLine); $this->assertSame($expected, $filter->isFeatureMatch($feature)); @@ -34,17 +42,17 @@ public function testIsFeatureMatchFilter($filterMinLine, $filterMaxLine, $expect public function scenarioLineRangeProvider() { - return array( - array('1', '2', 1), - array('1', '*', 2), - array('2', '2', 1), - array('2', '*', 2), - array('3', '3', 1), - array('3', '*', 1), - array('1', '1', 0), - array('4', '4', 0), - array('4', '*', 0) - ); + return [ + ['1', '2', 1], + ['1', '*', 2], + ['2', '2', 1], + ['2', '*', 2], + ['3', '3', 1], + ['3', '*', 1], + ['1', '1', 0], + ['4', '4', 0], + ['4', '*', 0], + ]; } /** @@ -52,8 +60,8 @@ public function scenarioLineRangeProvider() */ public function testIsScenarioMatchFilter($filterMinLine, $filterMaxLine, $expectedNumberOfMatches) { - $scenario = new ScenarioNode(null, array(), array(), null, 2); - $outline = new OutlineNode(null, array(), array(), array(new ExampleTableNode(array(), null)), null, 3); + $scenario = new ScenarioNode(null, [], [], null, 2); + $outline = new OutlineNode(null, [], [], [new ExampleTableNode([], null)], null, 3); $filter = new LineRangeFilter($filterMinLine, $filterMaxLine); $this->assertEquals( @@ -83,7 +91,7 @@ public function testFilterFeatureOutline() { $filter = new LineRangeFilter(12, 14); $feature = $filter->filterFeature($this->getParsedFeature()); - /** @var OutlineNode[] $scenarios */ + /* @var OutlineNode[] $scenarios */ $this->assertCount(1, $scenarios = $feature->getScenarios()); $this->assertSame('Scenario#3', $scenarios[0]->getTitle()); $this->assertFalse($scenarios[0]->hasExamples()); @@ -95,12 +103,12 @@ public function testFilterFeatureOutline() $exampleTableNodes = $scenarios[0]->getExampleTables(); $this->assertEquals(1, count($exampleTableNodes)); $this->assertCount(3, $exampleTableNodes[0]->getRows()); - $this->assertSame(array( - array('action', 'outcome'), - array('act#1', 'out#1'), - array('act#2', 'out#2'), - ), $exampleTableNodes[0]->getRows()); - $this->assertEquals(array('etag1'), $exampleTableNodes[0]->getTags()); + $this->assertSame([ + ['action', 'outcome'], + ['act#1', 'out#1'], + ['act#2', 'out#2'], + ], $exampleTableNodes[0]->getRows()); + $this->assertEquals(['etag1'], $exampleTableNodes[0]->getTags()); $filter = new LineRangeFilter(16, 26); $feature = $filter->filterFeature($this->getParsedFeature()); @@ -110,20 +118,20 @@ public function testFilterFeatureOutline() $this->assertEquals(2, count($exampleTableNodes)); $this->assertCount(3, $exampleTableNodes[0]->getRows()); - $this->assertSame(array( - array('action', 'outcome'), - array('act#1', 'out#1'), - array('act#2', 'out#2'), - ), $exampleTableNodes[0]->getRows()); - $this->assertEquals(array('etag1'), $exampleTableNodes[0]->getTags()); + $this->assertSame([ + ['action', 'outcome'], + ['act#1', 'out#1'], + ['act#2', 'out#2'], + ], $exampleTableNodes[0]->getRows()); + $this->assertEquals(['etag1'], $exampleTableNodes[0]->getTags()); $this->assertCount(2, $exampleTableNodes[1]->getRows()); - $this->assertSame(array( - array('action', 'outcome'), - array('act#3', 'out#3') - ), $exampleTableNodes[1]->getRows()); + $this->assertSame([ + ['action', 'outcome'], + ['act#3', 'out#3'], + ], $exampleTableNodes[1]->getRows()); - $this->assertEquals(array('etag2'), $exampleTableNodes[1]->getTags()); + $this->assertEquals(['etag2'], $exampleTableNodes[1]->getTags()); $filter = new LineRangeFilter(25, 26); $feature = $filter->filterFeature($this->getParsedFeature()); @@ -132,10 +140,10 @@ public function testFilterFeatureOutline() $exampleTableNodes = $scenarios[0]->getExampleTables(); $this->assertEquals(1, count($exampleTableNodes)); $this->assertCount(2, $exampleTableNodes[0]->getRows()); - $this->assertSame(array( - array('action', 'outcome'), - array('act#3', 'out#3'), - ), $exampleTableNodes[0]->getRows()); - $this->assertEquals(array('etag2'), $exampleTableNodes[0]->getTags()); + $this->assertSame([ + ['action', 'outcome'], + ['act#3', 'out#3'], + ], $exampleTableNodes[0]->getRows()); + $this->assertEquals(['etag2'], $exampleTableNodes[0]->getTags()); } } diff --git a/tests/Behat/Gherkin/Filter/NameFilterTest.php b/tests/Behat/Gherkin/Filter/NameFilterTest.php index 898462f0..ec44e669 100644 --- a/tests/Behat/Gherkin/Filter/NameFilterTest.php +++ b/tests/Behat/Gherkin/Filter/NameFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\NameFilter; @@ -11,47 +19,47 @@ class NameFilterTest extends TestCase { public function testFilterFeature() { - $feature = new FeatureNode('feature1', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('feature1', null, [], null, [], null, null, null, 1); $filter = new NameFilter('feature1'); $this->assertSame($feature, $filter->filterFeature($feature)); - $scenarios = array( - new ScenarioNode('scenario1', array(), array(), null, 2), - $matchedScenario = new ScenarioNode('scenario2', array(), array(), null, 4) - ); - $feature = new FeatureNode('feature1', null, array(), null, $scenarios, null, null, null, 1); + $scenarios = [ + new ScenarioNode('scenario1', [], [], null, 2), + $matchedScenario = new ScenarioNode('scenario2', [], [], null, 4), + ]; + $feature = new FeatureNode('feature1', null, [], null, $scenarios, null, null, null, 1); $filter = new NameFilter('scenario2'); $filteredFeature = $filter->filterFeature($feature); - $this->assertSame(array($matchedScenario), $filteredFeature->getScenarios()); + $this->assertSame([$matchedScenario], $filteredFeature->getScenarios()); } public function testIsFeatureMatchFilter() { - $feature = new FeatureNode('random feature title', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('random feature title', null, [], null, [], null, null, null, 1); $filter = new NameFilter('feature1'); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode('feature1', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('feature1', null, [], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode('feature1 title', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('feature1 title', null, [], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode('some feature1 title', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('some feature1 title', null, [], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode('some feature title', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('some feature title', null, [], null, [], null, null, null, 1); $this->assertFalse($filter->isFeatureMatch($feature)); $filter = new NameFilter('/fea.ure/'); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode('some feaSure title', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('some feaSure title', null, [], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode('some feture title', null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode('some feture title', null, [], null, [], null, null, null, 1); $this->assertFalse($filter->isFeatureMatch($feature)); } @@ -59,16 +67,16 @@ public function testIsScenarioMatchFilter() { $filter = new NameFilter('scenario1'); - $scenario = new ScenarioNode('UNKNOWN', array(), array(), null, 2); + $scenario = new ScenarioNode('UNKNOWN', [], [], null, 2); $this->assertFalse($filter->isScenarioMatch($scenario)); - $scenario = new ScenarioNode('scenario1', array(), array(), null, 2); + $scenario = new ScenarioNode('scenario1', [], [], null, 2); $this->assertTrue($filter->isScenarioMatch($scenario)); - $scenario = new ScenarioNode('scenario1 title', array(), array(), null, 2); + $scenario = new ScenarioNode('scenario1 title', [], [], null, 2); $this->assertTrue($filter->isScenarioMatch($scenario)); - $scenario = new ScenarioNode('some scenario title', array(), array(), null, 2); + $scenario = new ScenarioNode('some scenario title', [], [], null, 2); $this->assertFalse($filter->isScenarioMatch($scenario)); $filter = new NameFilter('/sce.ario/'); diff --git a/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php b/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php index dc2ebe8d..988b5b9d 100644 --- a/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php +++ b/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\NarrativeFilter; @@ -14,7 +22,7 @@ public function testIsFeatureMatchFilter() As a french user I need to be able to switch website language to french NAR; - $feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, $description, [], null, [], null, null, null, 1); $filter = new NarrativeFilter('/as (?:a|an) french user/'); $this->assertFalse($filter->isFeatureMatch($feature)); diff --git a/tests/Behat/Gherkin/Filter/PathsFilterTest.php b/tests/Behat/Gherkin/Filter/PathsFilterTest.php index 5d49ca0f..50d03330 100644 --- a/tests/Behat/Gherkin/Filter/PathsFilterTest.php +++ b/tests/Behat/Gherkin/Filter/PathsFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\PathsFilter; @@ -9,21 +17,21 @@ class PathsFilterTest extends FilterTestCase { public function testIsFeatureMatchFilter() { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, __FILE__, 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, __FILE__, 1); - $filter = new PathsFilter(array(__DIR__)); + $filter = new PathsFilter([__DIR__]); $this->assertTrue($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array('/abc', '/def', dirname(__DIR__))); + $filter = new PathsFilter(['/abc', '/def', dirname(__DIR__)]); $this->assertTrue($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array('/abc', '/def', __DIR__)); + $filter = new PathsFilter(['/abc', '/def', __DIR__]); $this->assertTrue($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array('/abc', __DIR__, '/def')); + $filter = new PathsFilter(['/abc', __DIR__, '/def']); $this->assertTrue($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array('/abc', '/def', '/wrong/path')); + $filter = new PathsFilter(['/abc', '/def', '/wrong/path']); $this->assertFalse($filter->isFeatureMatch($feature)); } @@ -31,21 +39,21 @@ public function testItDoesNotMatchPartialPaths() { $fixtures = __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR; - $feature = new FeatureNode(null, null, array(), null, array(), null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1); - $filter = new PathsFilter(array($fixtures . 'full')); + $filter = new PathsFilter([$fixtures . 'full']); $this->assertFalse($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array($fixtures . 'full' . DIRECTORY_SEPARATOR)); + $filter = new PathsFilter([$fixtures . 'full' . DIRECTORY_SEPARATOR]); $this->assertFalse($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array($fixtures . 'full_path' . DIRECTORY_SEPARATOR)); + $filter = new PathsFilter([$fixtures . 'full_path' . DIRECTORY_SEPARATOR]); $this->assertTrue($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array($fixtures . 'full_path')); + $filter = new PathsFilter([$fixtures . 'full_path']); $this->assertTrue($filter->isFeatureMatch($feature)); - $filter = new PathsFilter(array($fixtures . 'ful._path')); // Don't accept regexp + $filter = new PathsFilter([$fixtures . 'ful._path']); // Don't accept regexp $this->assertFalse($filter->isFeatureMatch($feature)); } @@ -53,9 +61,9 @@ public function testItDoesNotMatchIfFileWithSameNameButNotPathExistsInFolder() { $fixtures = __DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR; - $feature = new FeatureNode(null, null, array(), null, array(), null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, $fixtures . 'full_path' . DIRECTORY_SEPARATOR . 'file1', 1); - $filter = new PathsFilter(array($fixtures . 'full')); + $filter = new PathsFilter([$fixtures . 'full']); $this->assertFalse($filter->isFeatureMatch($feature)); } } diff --git a/tests/Behat/Gherkin/Filter/RoleFilterTest.php b/tests/Behat/Gherkin/Filter/RoleFilterTest.php index 72c3632b..f5386006 100644 --- a/tests/Behat/Gherkin/Filter/RoleFilterTest.php +++ b/tests/Behat/Gherkin/Filter/RoleFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\RoleFilter; @@ -14,7 +22,7 @@ public function testIsFeatureMatchFilter() As a french user I need to be able to switch website language to french NAR; - $feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, $description, [], null, [], null, null, null, 1); $filter = new RoleFilter('french user'); $this->assertTrue($filter->isFeatureMatch($feature)); @@ -34,7 +42,7 @@ public function testIsFeatureMatchFilter() $filter = new RoleFilter('French User'); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, 1); $filter = new RoleFilter('French User'); $this->assertFalse($filter->isFeatureMatch($feature)); } @@ -46,7 +54,7 @@ public function testFeatureRolePrefixedWithAn() As an american user I need to be able to switch website language to french NAR; - $feature = new FeatureNode(null, $description, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, $description, [], null, [], null, null, null, 1); $filter = new RoleFilter('american user'); $this->assertTrue($filter->isFeatureMatch($feature)); @@ -69,7 +77,7 @@ public function testFeatureRolePrefixedWithAn() $filter = new RoleFilter('American User'); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, 1); $filter = new RoleFilter('American User'); $this->assertFalse($filter->isFeatureMatch($feature)); } diff --git a/tests/Behat/Gherkin/Filter/TagFilterTest.php b/tests/Behat/Gherkin/Filter/TagFilterTest.php index f32ee397..de0596d5 100644 --- a/tests/Behat/Gherkin/Filter/TagFilterTest.php +++ b/tests/Behat/Gherkin/Filter/TagFilterTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Filter; use Behat\Gherkin\Filter\TagFilter; @@ -13,83 +21,83 @@ class TagFilterTest extends TestCase { public function testFilterFeature() { - $feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip'], null, [], null, null, null, 1); $filter = new TagFilter('@wip'); $this->assertEquals($feature, $filter->filterFeature($feature)); - $scenarios = array( - new ScenarioNode(null, array(), array(), null, 2), - $matchedScenario = new ScenarioNode(null, array('wip'), array(), null, 4) - ); - $feature = new FeatureNode(null, null, array(), null, $scenarios, null, null, null, 1); + $scenarios = [ + new ScenarioNode(null, [], [], null, 2), + $matchedScenario = new ScenarioNode(null, ['wip'], [], null, 4), + ]; + $feature = new FeatureNode(null, null, [], null, $scenarios, null, null, null, 1); $filteredFeature = $filter->filterFeature($feature); - $this->assertSame(array($matchedScenario), $filteredFeature->getScenarios()); + $this->assertSame([$matchedScenario], $filteredFeature->getScenarios()); $filter = new TagFilter('~@wip'); - $scenarios = array( - $matchedScenario = new ScenarioNode(null, array(), array(), null, 2), - new ScenarioNode(null, array('wip'), array(), null, 4) - ); - $feature = new FeatureNode(null, null, array(), null, $scenarios, null, null, null, 1); + $scenarios = [ + $matchedScenario = new ScenarioNode(null, [], [], null, 2), + new ScenarioNode(null, ['wip'], [], null, 4), + ]; + $feature = new FeatureNode(null, null, [], null, $scenarios, null, null, null, 1); $filteredFeature = $filter->filterFeature($feature); - $this->assertSame(array($matchedScenario), $filteredFeature->getScenarios()); + $this->assertSame([$matchedScenario], $filteredFeature->getScenarios()); } public function testIsFeatureMatchFilter() { - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, 1); $filter = new TagFilter('@wip'); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip'], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); $filter = new TagFilter('~@done'); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('wip', 'done'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip', 'done'], null, [], null, null, null, 1); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('tag1', 'tag2', 'tag3'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['tag1', 'tag2', 'tag3'], null, [], null, null, null, 1); $filter = new TagFilter('@tag5,@tag4,@tag6'); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array( + $feature = new FeatureNode(null, null, [ 'tag1', 'tag2', 'tag3', - 'tag5' - ), null, array(), null, null, null, 1); + 'tag5', + ], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); $filter = new TagFilter('@wip&&@vip'); - $feature = new FeatureNode(null, null, array('wip', 'done'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip', 'done'], null, [], null, null, null, 1); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('wip', 'done', 'vip'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip', 'done', 'vip'], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); $filter = new TagFilter('@wip,@vip&&@user'); - $feature = new FeatureNode(null, null, array('wip'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip'], null, [], null, null, null, 1); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('vip'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['vip'], null, [], null, null, null, 1); $this->assertFalse($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('wip', 'user'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['wip', 'user'], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); - $feature = new FeatureNode(null, null, array('vip', 'user'), null, array(), null, null, null, 1); + $feature = new FeatureNode(null, null, ['vip', 'user'], null, [], null, null, null, 1); $this->assertTrue($filter->isFeatureMatch($feature)); } public function testIsScenarioMatchFilter() { - $feature = new FeatureNode(null, null, array('feature-tag'), null, array(), null, null, null, 1); - $scenario = new ScenarioNode(null, array(), array(), null, 2); + $feature = new FeatureNode(null, null, ['feature-tag'], null, [], null, null, null, 1); + $scenario = new ScenarioNode(null, [], [], null, 2); $filter = new TagFilter('@wip'); $this->assertFalse($filter->isScenarioMatch($feature, $scenario)); @@ -97,57 +105,57 @@ public function testIsScenarioMatchFilter() $filter = new TagFilter('~@done'); $this->assertTrue($filter->isScenarioMatch($feature, $scenario)); - $scenario = new ScenarioNode(null, array( + $scenario = new ScenarioNode(null, [ 'tag1', 'tag2', - 'tag3' - ), array(), null, 2); + 'tag3', + ], [], null, 2); $filter = new TagFilter('@tag5,@tag4,@tag6'); $this->assertFalse($filter->isScenarioMatch($feature, $scenario)); - $scenario = new ScenarioNode(null, array( + $scenario = new ScenarioNode(null, [ 'tag1', 'tag2', 'tag3', - 'tag5' - ), array(), null, 2); + 'tag5', + ], [], null, 2); $this->assertTrue($filter->isScenarioMatch($feature, $scenario)); $filter = new TagFilter('@wip&&@vip'); - $scenario = new ScenarioNode(null, array('wip', 'not-done'), array(), null, 2); + $scenario = new ScenarioNode(null, ['wip', 'not-done'], [], null, 2); $this->assertFalse($filter->isScenarioMatch($feature, $scenario)); - $scenario = new ScenarioNode(null, array( + $scenario = new ScenarioNode(null, [ 'wip', 'not-done', - 'vip' - ), array(), null, 2); + 'vip', + ], [], null, 2); $this->assertTrue($filter->isScenarioMatch($feature, $scenario)); $filter = new TagFilter('@wip,@vip&&@user'); - $scenario = new ScenarioNode(null, array( - 'wip' - ), array(), null, 2); + $scenario = new ScenarioNode(null, [ + 'wip', + ], [], null, 2); $this->assertFalse($filter->isScenarioMatch($feature, $scenario)); - $scenario = new ScenarioNode(null, array('vip'), array(), null, 2); + $scenario = new ScenarioNode(null, ['vip'], [], null, 2); $this->assertFalse($filter->isScenarioMatch($feature, $scenario)); - $scenario = new ScenarioNode(null, array('wip', 'user'), array(), null, 2); + $scenario = new ScenarioNode(null, ['wip', 'user'], [], null, 2); $this->assertTrue($filter->isScenarioMatch($feature, $scenario)); $filter = new TagFilter('@feature-tag&&@user'); - $scenario = new ScenarioNode(null, array('wip', 'user'), array(), null, 2); + $scenario = new ScenarioNode(null, ['wip', 'user'], [], null, 2); $this->assertTrue($filter->isScenarioMatch($feature, $scenario)); $filter = new TagFilter('@feature-tag&&@user'); - $scenario = new ScenarioNode(null, array('wip'), array(), null, 2); + $scenario = new ScenarioNode(null, ['wip'], [], null, 2); $this->assertFalse($filter->isScenarioMatch($feature, $scenario)); - $scenario = new OutlineNode(null, array('wip'), array(), array( - new ExampleTableNode(array(), null, array('etag1', 'etag2')), - new ExampleTableNode(array(), null, array('etag2', 'etag3')), - ), null, 2); + $scenario = new OutlineNode(null, ['wip'], [], [ + new ExampleTableNode([], null, ['etag1', 'etag2']), + new ExampleTableNode([], null, ['etag2', 'etag3']), + ], null, 2); $tagFilter = new TagFilter('@etag3'); $this->assertTrue($tagFilter->isScenarioMatch($feature, $scenario)); @@ -177,18 +185,18 @@ public function testIsScenarioMatchFilter() $this->assertFalse($tagFilter->isScenarioMatch($feature, $scenario)); $tagFilter = new TagFilter('@etag1&&@etag3'); - $this->assertFalse($tagFilter->isScenarioMatch($feature, $scenario), "Tags from different examples tables"); + $this->assertFalse($tagFilter->isScenarioMatch($feature, $scenario), 'Tags from different examples tables'); } public function testFilterFeatureWithTaggedExamples() { - $exampleTableNode1 = new ExampleTableNode(array(), null, array('etag1', 'etag2')); - $exampleTableNode2 = new ExampleTableNode(array(), null, array('etag2', 'etag3')); - $scenario = new OutlineNode(null, array('wip'), array(), array( + $exampleTableNode1 = new ExampleTableNode([], null, ['etag1', 'etag2']); + $exampleTableNode2 = new ExampleTableNode([], null, ['etag2', 'etag3']); + $scenario = new OutlineNode(null, ['wip'], [], [ $exampleTableNode1, $exampleTableNode2, - ), null, 2); - $feature = new FeatureNode(null, null, array('feature-tag'), null, array($scenario), null, null, null, 1); + ], null, 2); + $feature = new FeatureNode(null, null, ['feature-tag'], null, [$scenario], null, null, null, 1); $tagFilter = new TagFilter('@etag2'); $matched = $tagFilter->filterFeature($feature); @@ -198,14 +206,14 @@ public function testFilterFeatureWithTaggedExamples() $tagFilter = new TagFilter('@etag1'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode1), $scenarioInterfaces[0]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode1], $scenarioInterfaces[0]->getExampleTables()); $tagFilter = new TagFilter('~@etag3'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode1), $scenarioInterfaces[0]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode1], $scenarioInterfaces[0]->getExampleTables()); $tagFilter = new TagFilter('@wip'); $matched = $tagFilter->filterFeature($feature); @@ -215,14 +223,14 @@ public function testFilterFeatureWithTaggedExamples() $tagFilter = new TagFilter('@wip&&@etag3'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode2), $scenarioInterfaces[0]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode2], $scenarioInterfaces[0]->getExampleTables()); $tagFilter = new TagFilter('@feature-tag&&@etag1&&@wip'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode1), $scenarioInterfaces[0]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode1], $scenarioInterfaces[0]->getExampleTables()); $tagFilter = new TagFilter('@feature-tag&&~@etag11111&&@wip'); $matched = $tagFilter->filterFeature($feature); @@ -232,41 +240,41 @@ public function testFilterFeatureWithTaggedExamples() $tagFilter = new TagFilter('@feature-tag&&~@etag1&&@wip'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode2), $scenarioInterfaces[0]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode2], $scenarioInterfaces[0]->getExampleTables()); $tagFilter = new TagFilter('@feature-tag&&@etag2'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); $this->assertEquals($scenario, $scenarioInterfaces[0]); - $exampleTableNode1 = new ExampleTableNode(array(), null, array('etag1', 'etag')); - $exampleTableNode2 = new ExampleTableNode(array(), null, array('etag2', 'etag22', 'etag')); - $exampleTableNode3 = new ExampleTableNode(array(), null, array('etag3', 'etag22', 'etag')); - $exampleTableNode4 = new ExampleTableNode(array(), null, array('etag4', 'etag')); - $scenario1 = new OutlineNode(null, array('wip'), array(), array( + $exampleTableNode1 = new ExampleTableNode([], null, ['etag1', 'etag']); + $exampleTableNode2 = new ExampleTableNode([], null, ['etag2', 'etag22', 'etag']); + $exampleTableNode3 = new ExampleTableNode([], null, ['etag3', 'etag22', 'etag']); + $exampleTableNode4 = new ExampleTableNode([], null, ['etag4', 'etag']); + $scenario1 = new OutlineNode(null, ['wip'], [], [ $exampleTableNode1, $exampleTableNode2, - ), null, 2); - $scenario2 = new OutlineNode(null, array('wip'), array(), array( + ], null, 2); + $scenario2 = new OutlineNode(null, ['wip'], [], [ $exampleTableNode3, $exampleTableNode4, - ), null, 2); - $feature = new FeatureNode(null, null, array('feature-tag'), null, array($scenario1, $scenario2), null, null, null, 1); + ], null, 2); + $feature = new FeatureNode(null, null, ['feature-tag'], null, [$scenario1, $scenario2], null, null, null, 1); $tagFilter = new TagFilter('@etag'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); - $this->assertEquals(array($scenario1, $scenario2), $scenarioInterfaces); + $this->assertEquals([$scenario1, $scenario2], $scenarioInterfaces); $tagFilter = new TagFilter('@etag22'); $matched = $tagFilter->filterFeature($feature); $scenarioInterfaces = $matched->getScenarios(); $this->assertEquals(2, count($scenarioInterfaces)); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode2), $scenarioInterfaces[0]->getExampleTables()); - /** @noinspection PhpUndefinedMethodInspection */ - $this->assertEquals(array($exampleTableNode3), $scenarioInterfaces[1]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode2], $scenarioInterfaces[0]->getExampleTables()); + /* @noinspection PhpUndefinedMethodInspection */ + $this->assertEquals([$exampleTableNode3], $scenarioInterfaces[1]->getExampleTables()); } public function testFilterWithWhitespaceIsDeprecated() @@ -274,7 +282,7 @@ public function testFilterWithWhitespaceIsDeprecated() $this->expectDeprecationError(); $tagFilter = new TagFilter('@tag with space'); - $scenario = new ScenarioNode(null, ['tag with space'], array(), null, 2); + $scenario = new ScenarioNode(null, ['tag with space'], [], null, 2); $feature = new FeatureNode(null, null, [], null, [$scenario], null, null, null, 1); $scenarios = $tagFilter->filterFeature($feature)->getScenarios(); @@ -291,7 +299,8 @@ public function testTagFilterThatIsAllWhitespaceIsIgnored() $this->assertTrue($result); } - private function expectDeprecationError() { + private function expectDeprecationError() + { set_error_handler( static function ($errno, $errstr) { restore_error_handler(); diff --git a/tests/Behat/Gherkin/GherkinTest.php b/tests/Behat/Gherkin/GherkinTest.php index 81f67160..30713786 100644 --- a/tests/Behat/Gherkin/GherkinTest.php +++ b/tests/Behat/Gherkin/GherkinTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin; use Behat\Gherkin\Gherkin; @@ -19,8 +27,8 @@ public function testLoader() $gherkin->addFilter($nameFilter = $this->getNameFilterMock()); $gherkin->addFilter($tagFilter = $this->getTagFilterMock()); - $scenario = new ScenarioNode(null, array(), array(), null, null); - $feature = new FeatureNode(null, null, array(), null, array($scenario), null, null, null, null); + $scenario = new ScenarioNode(null, [], [], null, null); + $feature = new FeatureNode(null, null, [], null, [$scenario], null, null, null, null); $loader ->expects($this->once()) @@ -31,7 +39,7 @@ public function testLoader() ->expects($this->once()) ->method('load') ->with($resource) - ->will($this->returnValue(array($feature))); + ->will($this->returnValue([$feature])); $nameFilter ->expects($this->once()) @@ -54,7 +62,7 @@ public function testLoader() ->with($this->identicalTo($feature)) ->will($this->returnValue($feature)); - $features = $gherkin->load($resource, array($customFilter1, $customFilter2)); + $features = $gherkin->load($resource, [$customFilter1, $customFilter2]); $this->assertEquals(1, count($features)); $scenarios = $features[0]->getScenarios(); @@ -66,7 +74,7 @@ public function testNotFoundLoader() { $gherkin = new Gherkin(); - $this->assertEquals(array(), $gherkin->load('some/feature/resource')); + $this->assertEquals([], $gherkin->load('some/feature/resource')); } public function testLoaderFiltersFeatures() @@ -75,7 +83,7 @@ public function testLoaderFiltersFeatures() $gherkin->addLoader($loader = $this->getLoaderMock()); $gherkin->addFilter($nameFilter = $this->getNameFilterMock()); - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, null); $loader ->expects($this->once()) @@ -86,7 +94,7 @@ public function testLoaderFiltersFeatures() ->expects($this->once()) ->method('load') ->with($resource) - ->will($this->returnValue(array($feature))); + ->will($this->returnValue([$feature])); $nameFilter ->expects($this->once()) @@ -108,9 +116,9 @@ public function testSetFiltersOverridesAllFilters() $gherkin = new Gherkin(); $gherkin->addLoader($loader = $this->getLoaderMock()); $gherkin->addFilter($nameFilter = $this->getNameFilterMock()); - $gherkin->setFilters(array()); + $gherkin->setFilters([]); - $feature = new FeatureNode(null, null, array(), null, array(), null, null, null, null); + $feature = new FeatureNode(null, null, [], null, [], null, null, null, null); $loader ->expects($this->once()) @@ -121,7 +129,7 @@ public function testSetFiltersOverridesAllFilters() ->expects($this->once()) ->method('load') ->with($resource) - ->will($this->returnValue(array($feature))); + ->will($this->returnValue([$feature])); $nameFilter ->expects($this->never()) diff --git a/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php b/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php index 7a48bbef..f39eae0d 100644 --- a/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php +++ b/tests/Behat/Gherkin/Keywords/ArrayKeywordsTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Keywords; use Behat\Gherkin\Keywords\ArrayKeywords; @@ -14,8 +22,8 @@ protected function getKeywords() protected function getKeywordsArray() { - return array( - 'with_special_chars' => array( + return [ + 'with_special_chars' => [ 'and' => 'And/foo', 'background' => 'Background.', 'but' => 'But[', @@ -28,19 +36,19 @@ protected function getKeywordsArray() 'scenario_outline' => 'Scenario Outline|Scenario Template', 'then' => 'Then', 'when' => 'When', - ), - ); + ], + ]; } protected function getSteps($keywords, $text, &$line, $keywordType) { - $steps = array(); + $steps = []; foreach (explode('|', $keywords) as $keyword) { - if (false !== mb_strpos($keyword, '<')) { + if (mb_strpos($keyword, '<') !== false) { $keyword = mb_substr($keyword, 0, -1); } - $steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType); + $steps[] = new StepNode($keyword, $text, [], $line++, $keywordType); } return $steps; diff --git a/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php b/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php index e64ed9f5..b2f7947b 100644 --- a/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php +++ b/tests/Behat/Gherkin/Keywords/CachedArrayKeywordsTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Keywords; use Behat\Gherkin\Keywords\CachedArrayKeywords; @@ -14,22 +22,22 @@ protected function getKeywords() protected function getKeywordsArray() { - return include(__DIR__ . '/../../../../i18n.php'); + return include __DIR__ . '/../../../../i18n.php'; } protected function getSteps($keywords, $text, &$line, $keywordType) { - $steps = array(); + $steps = []; foreach (explode('|', $keywords) as $keyword) { - if ('*' === $keyword) { + if ($keyword === '*') { continue; } - if (false !== mb_strpos($keyword, '<')) { + if (mb_strpos($keyword, '<') !== false) { $keyword = mb_substr($keyword, 0, -1); } - $steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType); + $steps[] = new StepNode($keyword, $text, [], $line++, $keywordType); } return $steps; diff --git a/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php b/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php index 810471e4..8674d00a 100644 --- a/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php +++ b/tests/Behat/Gherkin/Keywords/CucumberKeywordsTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Keywords; use Behat\Gherkin\Keywords\CucumberKeywords; @@ -20,13 +28,13 @@ protected function getKeywordsArray() protected function getSteps($keywords, $text, &$line, $keywordType) { - $steps = array(); + $steps = []; foreach (explode('|', mb_substr($keywords, 2)) as $keyword) { - if (false !== mb_strpos($keyword, '<')) { + if (mb_strpos($keyword, '<') !== false) { $keyword = mb_substr($keyword, 0, -1); } - $steps[] = new StepNode($keyword, $text, array(), $line++, $keywordType); + $steps[] = new StepNode($keyword, $text, [], $line++, $keywordType); } return $steps; diff --git a/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php b/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php index f3436413..3c725068 100644 --- a/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php +++ b/tests/Behat/Gherkin/Keywords/KeywordsDumperTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Keywords; use Behat\Gherkin\Keywords\ArrayKeywords; @@ -12,32 +20,32 @@ class KeywordsDumperTest extends TestCase protected function setUp(): void { - $this->keywords = new ArrayKeywords(array( - 'en' => array( - 'feature' => 'Feature', - 'background' => 'Background', - 'scenario' => 'Scenario', - 'scenario_outline' => 'Scenario Outline|Scenario Template', - 'examples' => 'Examples|Scenarios', - 'given' => 'Given', - 'when' => 'When', - 'then' => 'Then', - 'and' => 'And', - 'but' => 'But' - ), - 'ru' => array( - 'feature' => 'Функционал|Фича', - 'background' => 'Предыстория|Бэкграунд', - 'scenario' => 'Сценарий|История', - 'scenario_outline' => 'Структура сценария|Аутлайн', - 'examples' => 'Примеры', - 'given' => 'Допустим', - 'when' => 'Если|@', - 'then' => 'То', - 'and' => 'И', - 'but' => 'Но' - ) - )); + $this->keywords = new ArrayKeywords([ + 'en' => [ + 'feature' => 'Feature', + 'background' => 'Background', + 'scenario' => 'Scenario', + 'scenario_outline' => 'Scenario Outline|Scenario Template', + 'examples' => 'Examples|Scenarios', + 'given' => 'Given', + 'when' => 'When', + 'then' => 'Then', + 'and' => 'And', + 'but' => 'But', + ], + 'ru' => [ + 'feature' => 'Функционал|Фича', + 'background' => 'Предыстория|Бэкграунд', + 'scenario' => 'Сценарий|История', + 'scenario_outline' => 'Структура сценария|Аутлайн', + 'examples' => 'Примеры', + 'given' => 'Допустим', + 'when' => 'Если|@', + 'then' => 'То', + 'and' => 'И', + 'but' => 'Но', + ], + ]); } public function testEnKeywordsDumper() @@ -119,7 +127,7 @@ public function testRuKeywordsCustomKeywordsDumper() { $dumper = new KeywordsDumper($this->keywords); $dumper->setKeywordsDumperFunction(function ($keywords) { - return ''.implode(', ', $keywords).''; + return '' . implode(', ', $keywords) . ''; }); $dumped = $dumper->dump('ru'); @@ -161,7 +169,7 @@ public function testExtendedVersionDumper() $dumper = new KeywordsDumper($this->keywords); $dumped = $dumper->dump('ru', false); - $etalon = array( + $etalon = [ <<assertEquals($etalon, $dumped); } diff --git a/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php b/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php index b26fe2ec..452ee096 100644 --- a/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php +++ b/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Keywords; use Behat\Gherkin\Keywords\KeywordsDumper; @@ -15,7 +23,9 @@ abstract class KeywordsTestCase extends TestCase { abstract protected function getKeywords(); + abstract protected function getKeywordsArray(); + abstract protected function getSteps($keywords, $text, &$line, $keywordType); public function translationTestDataProvider() @@ -27,12 +37,12 @@ public function translationTestDataProvider() // Remove languages with repeated keywords unset($keywordsArray['en-old'], $keywordsArray['uz'], $keywordsArray['ne']); - $data = array(); + $data = []; foreach ($keywordsArray as $lang => $i18nKeywords) { - $features = array(); + $features = []; foreach (explode('|', $i18nKeywords['feature']) as $transNum => $featureKeyword) { $line = 1; - if ('en' !== $lang) { + if ($lang !== 'en') { $line = 2; } @@ -41,19 +51,19 @@ public function translationTestDataProvider() $keywords = explode('|', $i18nKeywords['background']); $backgroundLine = $line; - $line += 1; + ++$line; $background = new BackgroundNode(null, array_merge( $this->getSteps($i18nKeywords['given'], 'there is agent A', $line, 'Given'), $this->getSteps($i18nKeywords['and'], 'there is agent B', $line, 'Given') ), $keywords[0], $backgroundLine); - $line += 1; + ++$line; - $scenarios = array(); + $scenarios = []; foreach (explode('|', $i18nKeywords['scenario']) as $scenarioKeyword) { $scenarioLine = $line; - $line += 1; + ++$line; $steps = array_merge( $this->getSteps($i18nKeywords['given'], 'there is agent J', $line, 'Given'), @@ -63,12 +73,12 @@ public function translationTestDataProvider() $this->getSteps($i18nKeywords['but'], 'there should not be agent K', $line, 'Then') ); - $scenarios[] = new ScenarioNode('Erasing agent memory', array(), $steps, $scenarioKeyword, $scenarioLine); - $line += 1; + $scenarios[] = new ScenarioNode('Erasing agent memory', [], $steps, $scenarioKeyword, $scenarioLine); + ++$line; } foreach (explode('|', $i18nKeywords['scenario_outline']) as $outlineKeyword) { $outlineLine = $line; - $line += 1; + ++$line; $steps = array_merge( $this->getSteps($i18nKeywords['given'], 'there is agent ', $line, 'Given'), @@ -77,17 +87,17 @@ public function translationTestDataProvider() $this->getSteps($i18nKeywords['then'], 'there should be agent ', $line, 'Then'), $this->getSteps($i18nKeywords['but'], 'there should not be agent ', $line, 'Then') ); - $line += 1; + ++$line; $keywords = explode('|', $i18nKeywords['examples']); - $table = new ExampleTableNode(array( - ++$line => array('agent1', 'agent2'), - ++$line => array('D', 'M') - ), $keywords[0]); - $line += 1; - - $scenarios[] = new OutlineNode('Erasing other agents\' memory', array(), $steps, $table, $outlineKeyword, $outlineLine); - $line += 1; + $table = new ExampleTableNode([ + ++$line => ['agent1', 'agent2'], + ++$line => ['D', 'M'], + ], $keywords[0]); + ++$line; + + $scenarios[] = new OutlineNode('Erasing other agents\' memory', [], $steps, $table, $outlineKeyword, $outlineLine); + ++$line; } $features[] = new FeatureNode( @@ -98,7 +108,7 @@ public function translationTestDataProvider() We need to be able to erase past agents' memory DESC , - array(), + [], $background, $scenarios, $featureKeyword, @@ -111,7 +121,7 @@ public function translationTestDataProvider() $dumped = $dumper->dump($lang, false, true); foreach ($dumped as $num => $dumpedFeature) { - $data[$lang . "_" . $num] = array($lang, $num, $features[$num], $dumpedFeature); + $data[$lang . '_' . $num] = [$lang, $num, $features[$num], $dumpedFeature]; } } @@ -121,10 +131,10 @@ public function translationTestDataProvider() /** * @dataProvider translationTestDataProvider * - * @param string $language language name - * @param int $num Fixture index for that language - * @param FeatureNode $etalon etalon features (to test against) - * @param string $source gherkin source + * @param string $language language name + * @param int $num Fixture index for that language + * @param FeatureNode $etalon etalon features (to test against) + * @param string $source gherkin source */ public function testTranslation($language, $num, FeatureNode $etalon, $source) { diff --git a/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php b/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php index d373a9b9..01471981 100644 --- a/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php +++ b/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Loader; use Behat\Gherkin\Loader\ArrayLoader; @@ -8,7 +16,7 @@ class ArrayLoaderTest extends TestCase { - /** @var ArrayLoader */ + /** @var ArrayLoader */ private $loader; protected function setUp(): void @@ -21,32 +29,32 @@ public function testSupports() $this->assertFalse($this->loader->supports(__DIR__)); $this->assertFalse($this->loader->supports(__FILE__)); $this->assertFalse($this->loader->supports('string')); - $this->assertFalse($this->loader->supports(array('wrong_root'))); - $this->assertFalse($this->loader->supports(array('features'))); - $this->assertTrue($this->loader->supports(array('features' => array()))); - $this->assertTrue($this->loader->supports(array('feature' => array()))); + $this->assertFalse($this->loader->supports(['wrong_root'])); + $this->assertFalse($this->loader->supports(['features'])); + $this->assertTrue($this->loader->supports(['features' => []])); + $this->assertTrue($this->loader->supports(['feature' => []])); } public function testLoadEmpty() { - $this->assertEquals(array(), $this->loader->load(array('features' => array()))); + $this->assertEquals([], $this->loader->load(['features' => []])); } public function testLoadFeatures() { - $features = $this->loader->load(array( - 'features' => array( - array( - 'title' => 'First feature', - 'line' => 3, - ), - array( - 'description' => 'Second feature description', - 'language' => 'ru', - 'tags' => array('some', 'tags') - ) - ), - )); + $features = $this->loader->load([ + 'features' => [ + [ + 'title' => 'First feature', + 'line' => 3, + ], + [ + 'description' => 'Second feature description', + 'language' => 'ru', + 'tags' => ['some', 'tags'], + ], + ], + ]); $this->assertEquals(2, count($features)); @@ -62,31 +70,31 @@ public function testLoadFeatures() $this->assertEquals('Second feature description', $features[1]->getDescription()); $this->assertNull($features[1]->getFile()); $this->assertEquals('ru', $features[1]->getLanguage()); - $this->assertEquals(array('some', 'tags'), $features[1]->getTags()); + $this->assertEquals(['some', 'tags'], $features[1]->getTags()); } public function testLoadScenarios() { - $features = $this->loader->load(array( - 'features' => array( - array( - 'title' => 'Feature', - 'scenarios' => array( - array( + $features = $this->loader->load([ + 'features' => [ + [ + 'title' => 'Feature', + 'scenarios' => [ + [ 'title' => 'First scenario', - 'line' => 2 - ), - array( - 'tags' => array('second', 'scenario', 'tags') - ), - array( - 'tags' => array('third', 'scenario'), - 'line' => 3 - ) - ) - ) - ), - )); + 'line' => 2, + ], + [ + 'tags' => ['second', 'scenario', 'tags'], + ], + [ + 'tags' => ['third', 'scenario'], + 'line' => 3, + ], + ], + ], + ], + ]); $this->assertEquals(1, count($features)); @@ -101,35 +109,35 @@ public function testLoadScenarios() $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[1]); $this->assertNull($scenarios[1]->getTitle()); - $this->assertEquals(array('second', 'scenario', 'tags'), $scenarios[1]->getTags()); + $this->assertEquals(['second', 'scenario', 'tags'], $scenarios[1]->getTags()); $this->assertEquals(1, $scenarios[1]->getLine()); $this->assertInstanceOf('Behat\Gherkin\Node\ScenarioNode', $scenarios[2]); $this->assertNull($scenarios[2]->getTitle()); - $this->assertEquals(array('third', 'scenario'), $scenarios[2]->getTags()); + $this->assertEquals(['third', 'scenario'], $scenarios[2]->getTags()); $this->assertEquals(3, $scenarios[2]->getLine()); } public function testLoadOutline() { - $features = $this->loader->load(array( - 'features' => array( - array( - 'title' => 'Feature', - 'scenarios' => array( - array( - 'type' => 'outline', + $features = $this->loader->load([ + 'features' => [ + [ + 'title' => 'Feature', + 'scenarios' => [ + [ + 'type' => 'outline', 'title' => 'First outline', - 'line' => 2 - ), - array( - 'type' => 'outline', - 'tags' => array('second', 'outline', 'tags') - ) - ) - ) - ), - )); + 'line' => 2, + ], + [ + 'type' => 'outline', + 'tags' => ['second', 'outline', 'tags'], + ], + ], + ], + ], + ]); $this->assertEquals(1, count($features)); @@ -144,64 +152,64 @@ public function testLoadOutline() $this->assertInstanceOf('Behat\Gherkin\Node\OutlineNode', $outlines[1]); $this->assertNull($outlines[1]->getTitle()); - $this->assertEquals(array('second', 'outline', 'tags'), $outlines[1]->getTags()); + $this->assertEquals(['second', 'outline', 'tags'], $outlines[1]->getTags()); $this->assertEquals(1, $outlines[1]->getLine()); } public function testOutlineExamples() { - $features = $this->loader->load(array( - 'features' => array( - array( - 'title' => 'Feature', - 'scenarios' => array( - array( - 'type' => 'outline', - 'title' => 'First outline', - 'line' => 2, - 'examples' => array( - 11 => array('user', 'pass'), - 12 => array('ever', 'sdsd'), - 13 => array('anto', 'fdfd') - ) - ), - array( - 'type' => 'outline', - 'tags' => array('second', 'outline', 'tags') - ) - ) - ) - ), - )); + $features = $this->loader->load([ + 'features' => [ + [ + 'title' => 'Feature', + 'scenarios' => [ + [ + 'type' => 'outline', + 'title' => 'First outline', + 'line' => 2, + 'examples' => [ + 11 => ['user', 'pass'], + 12 => ['ever', 'sdsd'], + 13 => ['anto', 'fdfd'], + ], + ], + [ + 'type' => 'outline', + 'tags' => ['second', 'outline', 'tags'], + ], + ], + ], + ], + ]); $this->assertEquals(1, count($features)); /** @var OutlineNode[] $scenarios */ $scenarios = $features[0]->getScenarios(); - $scenario = $scenarios[0]; + $scenario = $scenarios[0]; $this->assertEquals( - array(array('user' => 'ever', 'pass' => 'sdsd'), array('user' => 'anto', 'pass' => 'fdfd')), + [['user' => 'ever', 'pass' => 'sdsd'], ['user' => 'anto', 'pass' => 'fdfd']], $scenario->getExampleTable()->getHash() ); } public function testLoadBackground() { - $features = $this->loader->load(array( - 'features' => array( - array( - ), - array( - 'background' => array() - ), - array( - 'background' => array( - 'line' => 2 - ) - ), - ) - )); + $features = $this->loader->load([ + 'features' => [ + [ + ], + [ + 'background' => [], + ], + [ + 'background' => [ + 'line' => 2, + ], + ], + ], + ]); $this->assertEquals(3, count($features)); @@ -214,35 +222,35 @@ public function testLoadBackground() public function testLoadSteps() { - $features = $this->loader->load(array( - 'features' => array( - array( - 'background' => array( - 'steps' => array( - array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'bg step 1', 'line' => 3), - array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'bg step 2') - ) - ), - 'scenarios' => array( - array( + $features = $this->loader->load([ + 'features' => [ + [ + 'background' => [ + 'steps' => [ + ['type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'bg step 1', 'line' => 3], + ['type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'bg step 2'], + ], + ], + 'scenarios' => [ + [ 'title' => 'Scenario', - 'steps' => array( - array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'sc step 1'), - array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'sc step 2') - ) - ), - array( + 'steps' => [ + ['type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'sc step 1'], + ['type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'sc step 2'], + ], + ], + [ 'title' => 'Outline', - 'type' => 'outline', - 'steps' => array( - array('type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'out step 1'), - array('type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'out step 2') - ) - ) - ) - ) - ) - )); + 'type' => 'outline', + 'steps' => [ + ['type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'out step 1'], + ['type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'out step 2'], + ], + ], + ], + ], + ], + ]); $background = $features[0]->getBackground(); $this->assertTrue($background->hasSteps()); @@ -259,7 +267,7 @@ public function testLoadSteps() $this->assertEquals('bg step 2', $steps[1]->getText()); $this->assertEquals(1, $steps[1]->getLine()); - $scenarios = $features[0]->getScenarios(); + $scenarios = $features[0]->getScenarios(); $scenario = $scenarios[0]; $this->assertTrue($scenario->hasSteps()); @@ -294,47 +302,47 @@ public function testLoadSteps() public function testLoadStepArguments() { - $features = $this->loader->load(array( - 'features' => array( - array( - 'background' => array( - 'steps' => array( - array( + $features = $this->loader->load([ + 'features' => [ + [ + 'background' => [ + 'steps' => [ + [ 'type' => 'Gangway!', 'keyword_type' => 'Given', 'text' => 'step with table argument', - 'arguments' => array( - array( - 'type' => 'table', - 'rows' => array( - array('key', 'val'), - array(1, 2), - array(3, 4) - ) - ) - ) - ), - array( + 'arguments' => [ + [ + 'type' => 'table', + 'rows' => [ + ['key', 'val'], + [1, 2], + [3, 4], + ], + ], + ], + ], + [ 'type' => 'Blimey!', 'keyword_type' => 'When', 'text' => 'step with pystring argument', - 'arguments' => array( - array( - 'type' => 'pystring', - 'text' => ' some text', - ) - ) - ), - array( + 'arguments' => [ + [ + 'type' => 'pystring', + 'text' => ' some text', + ], + ], + ], + [ 'type' => 'Let go and haul', 'keyword_type' => 'Then', 'text' => '2nd step with pystring argument', - 'arguments' => array( - array( - 'type' => 'pystring', - 'text' => 'some text', - ) - ) - ) - ) - ) - ) - ) - )); + 'arguments' => [ + [ + 'type' => 'pystring', + 'text' => 'some text', + ], + ], + ], + ], + ], + ], + ], + ]); $background = $features[0]->getBackground(); @@ -350,7 +358,7 @@ public function testLoadStepArguments() $this->assertEquals('Given', $steps[0]->getKeywordType()); $this->assertEquals('step with table argument', $steps[0]->getText()); $this->assertInstanceOf('Behat\Gherkin\Node\TableNode', $arguments[0]); - $this->assertEquals(array(array('key'=>1, 'val'=>2), array('key'=>3,'val'=>4)), $arguments[0]->getHash()); + $this->assertEquals([['key' => 1, 'val' => 2], ['key' => 3, 'val' => 4]], $arguments[0]->getHash()); $arguments = $steps[1]->getArguments(); $this->assertEquals('Blimey!', $steps[1]->getType()); @@ -371,11 +379,11 @@ public function testLoadStepArguments() public function testSingleFeatureArray() { - $features = $this->loader->load(array( - 'feature' => array( - 'title' => 'Some feature' - ) - )); + $features = $this->loader->load([ + 'feature' => [ + 'title' => 'Some feature', + ], + ]); $this->assertEquals(1, count($features)); $this->assertEquals('Some feature', $features[0]->getTitle()); diff --git a/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php b/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php index d8378d94..e6c9bd6e 100644 --- a/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php +++ b/tests/Behat/Gherkin/Loader/DirectoryLoaderTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Loader; use Behat\Gherkin\Loader\DirectoryLoader; @@ -13,8 +21,8 @@ class DirectoryLoaderTest extends TestCase protected function setUp(): void { - $this->gherkin = $this->createGherkinMock(); - $this->loader = new DirectoryLoader($this->gherkin); + $this->gherkin = $this->createGherkinMock(); + $this->loader = new DirectoryLoader($this->gherkin); $this->featuresPath = realpath(__DIR__ . '/../Fixtures/directories'); } @@ -53,10 +61,10 @@ public function testUndefinedFileLoad() $this->gherkin ->expects($this->once()) ->method('resolveLoader') - ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php') + ->with($this->featuresPath . DIRECTORY_SEPARATOR . 'phps' . DIRECTORY_SEPARATOR . 'some_file.php') ->will($this->returnValue(null)); - $this->assertEquals(array(), $this->loader->load($this->featuresPath . '/phps')); + $this->assertEquals([], $this->loader->load($this->featuresPath . '/phps')); } public function testBasePath() @@ -64,12 +72,12 @@ public function testBasePath() $this->gherkin ->expects($this->once()) ->method('resolveLoader') - ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php') + ->with($this->featuresPath . DIRECTORY_SEPARATOR . 'phps' . DIRECTORY_SEPARATOR . 'some_file.php') ->will($this->returnValue(null)); $this->loader->setBasePath($this->featuresPath); - $this->assertEquals(array(), $this->loader->load('phps')); + $this->assertEquals([], $this->loader->load('phps')); } public function testDefinedFileLoad() @@ -79,15 +87,15 @@ public function testDefinedFileLoad() $this->gherkin ->expects($this->once()) ->method('resolveLoader') - ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php') + ->with($this->featuresPath . DIRECTORY_SEPARATOR . 'phps' . DIRECTORY_SEPARATOR . 'some_file.php') ->will($this->returnValue($loaderMock)); $loaderMock ->expects($this->once()) ->method('load') - ->with($this->featuresPath.DIRECTORY_SEPARATOR.'phps'.DIRECTORY_SEPARATOR.'some_file.php') - ->will($this->returnValue(array('feature1', 'feature2'))); + ->with($this->featuresPath . DIRECTORY_SEPARATOR . 'phps' . DIRECTORY_SEPARATOR . 'some_file.php') + ->will($this->returnValue(['feature1', 'feature2'])); - $this->assertEquals(array('feature1', 'feature2'), $this->loader->load($this->featuresPath . '/phps')); + $this->assertEquals(['feature1', 'feature2'], $this->loader->load($this->featuresPath . '/phps')); } } diff --git a/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php b/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php index 8b870890..48755d0d 100644 --- a/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php +++ b/tests/Behat/Gherkin/Loader/GherkinFileLoaderTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Loader; use Behat\Gherkin\Keywords\CucumberKeywords; diff --git a/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php b/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php index cd5d9d89..60b53929 100644 --- a/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php +++ b/tests/Behat/Gherkin/Loader/YamlFileLoaderTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Loader; use Behat\Gherkin\Loader\YamlFileLoader; diff --git a/tests/Behat/Gherkin/Node/ExampleNodeTest.php b/tests/Behat/Gherkin/Node/ExampleNodeTest.php index 0b03f49f..d57168ce 100644 --- a/tests/Behat/Gherkin/Node/ExampleNodeTest.php +++ b/tests/Behat/Gherkin/Node/ExampleNodeTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Node; use Behat\Gherkin\Node\ExampleTableNode; @@ -13,20 +21,20 @@ class ExampleNodeTest extends TestCase { public function testCreateExampleSteps() { - $steps = array( - $step1 = new StepNode('Gangway!', 'I am ', array(), null, 'Given'), - $step2 = new StepNode('Aye!', 'my email is ', array(), null, 'And'), - $step3 = new StepNode('Blimey!', 'I open homepage', array(), null, 'When'), - $step4 = new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'), - ); - - $table = new ExampleTableNode(array( - array('name', 'email'), - array('everzet', 'ever.zet@gmail.com'), - array('example', 'example@example.com') - ), 'Examples'); - - $outline = new OutlineNode(null, array(), $steps, $table, null, null); + $steps = [ + $step1 = new StepNode('Gangway!', 'I am ', [], null, 'Given'), + $step2 = new StepNode('Aye!', 'my email is ', [], null, 'And'), + $step3 = new StepNode('Blimey!', 'I open homepage', [], null, 'When'), + $step4 = new StepNode('Let go and haul', 'website should recognise me', [], null, 'Then'), + ]; + + $table = new ExampleTableNode([ + ['name', 'email'], + ['everzet', 'ever.zet@gmail.com'], + ['example', 'example@example.com'], + ], 'Examples'); + + $outline = new OutlineNode(null, [], $steps, $table, null, null); $examples = $outline->getExamples(); $this->assertCount(4, $steps = $examples[0]->getSteps()); @@ -62,24 +70,24 @@ public function testCreateExampleSteps() public function testCreateExampleStepsWithArguments() { - $steps = array( - $step1 = new StepNode('Gangway!', 'I am ', array(), null, 'Given'), - $step2 = new StepNode('Aye!', 'my email is ', array(), null, 'And'), - $step3 = new StepNode('Blimey!', 'I open:', array( - new PyStringNode(array('page: '), null) - ), null, 'When'), - $step4 = new StepNode('Let go and haul', 'website should recognise me', array( - new TableNode(array(array('page', ''))) - ), null, 'Then'), - ); - - $table = new ExampleTableNode(array( - array('name', 'email', 'url'), - array('everzet', 'ever.zet@gmail.com', 'homepage'), - array('example', 'example@example.com', 'other page') - ), 'Examples'); - - $outline = new OutlineNode(null, array(), $steps, $table, null, null); + $steps = [ + $step1 = new StepNode('Gangway!', 'I am ', [], null, 'Given'), + $step2 = new StepNode('Aye!', 'my email is ', [], null, 'And'), + $step3 = new StepNode('Blimey!', 'I open:', [ + new PyStringNode(['page: '], null), + ], null, 'When'), + $step4 = new StepNode('Let go and haul', 'website should recognise me', [ + new TableNode([['page', '']]), + ], null, 'Then'), + ]; + + $table = new ExampleTableNode([ + ['name', 'email', 'url'], + ['everzet', 'ever.zet@gmail.com', 'homepage'], + ['example', 'example@example.com', 'other page'], + ], 'Examples'); + + $outline = new OutlineNode(null, [], $steps, $table, null, null); $examples = $outline->getExamples(); $steps = $examples[0]->getSteps(); diff --git a/tests/Behat/Gherkin/Node/OutlineNodeTest.php b/tests/Behat/Gherkin/Node/OutlineNodeTest.php index 426e41dc..78a32c5c 100644 --- a/tests/Behat/Gherkin/Node/OutlineNodeTest.php +++ b/tests/Behat/Gherkin/Node/OutlineNodeTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Node; use Behat\Gherkin\Node\ExampleNode; @@ -12,121 +20,121 @@ class OutlineNodeTest extends TestCase { public function testCreatesExamplesForExampleTable(): void { - $steps = array( - new StepNode('Gangway!', 'I am ', array(), null, 'Given'), - new StepNode('Aye!', 'my email is ', array(), null, 'And'), - new StepNode('Blimey!', 'I open homepage', array(), null, 'When'), - new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'), - ); + $steps = [ + new StepNode('Gangway!', 'I am ', [], null, 'Given'), + new StepNode('Aye!', 'my email is ', [], null, 'And'), + new StepNode('Blimey!', 'I open homepage', [], null, 'When'), + new StepNode('Let go and haul', 'website should recognise me', [], null, 'Then'), + ]; - $table = new ExampleTableNode(array( - 2 => array('name', 'email'), - 22 => array('everzet', 'ever.zet@gmail.com'), - 23 => array('example', 'example@example.com') - ), 'Examples'); + $table = new ExampleTableNode([ + 2 => ['name', 'email'], + 22 => ['everzet', 'ever.zet@gmail.com'], + 23 => ['example', 'example@example.com'], + ], 'Examples'); - $outline = new OutlineNode(null, array(), $steps, $table, null, null); + $outline = new OutlineNode(null, [], $steps, $table, null, null); $this->assertCount(2, $examples = $outline->getExamples()); $this->assertEquals(22, $examples[0]->getLine()); $this->assertEquals(23, $examples[1]->getLine()); - $this->assertEquals(array('name' => 'everzet', 'email' => 'ever.zet@gmail.com'), $examples[0]->getTokens()); - $this->assertEquals(array('name' => 'example', 'email' => 'example@example.com'), $examples[1]->getTokens()); + $this->assertEquals(['name' => 'everzet', 'email' => 'ever.zet@gmail.com'], $examples[0]->getTokens()); + $this->assertEquals(['name' => 'example', 'email' => 'example@example.com'], $examples[1]->getTokens()); } public function testCreatesExamplesForExampleTableWithSeveralExamplesAndTags(): void { - $steps = array( - new StepNode('Gangway!', 'I am ', array(), null, 'Given'), - new StepNode('Aye!', 'my email is ', array(), null, 'And'), - new StepNode('Blimey!', 'I open homepage', array(), null, 'When'), - new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'), - ); - - $table = new ExampleTableNode(array( - 2 => array('name', 'email'), - 22 => array('everzet', 'ever.zet@gmail.com'), - 23 => array('example', 'example@example.com') - ), 'Examples', array()); - - $table2 = new ExampleTableNode(array( - 3 => array('name', 'email'), - 32 => array('everzet2', 'ever.zet2@gmail.com'), - 33 => array('example2', 'example2@example.com') - ), 'Examples', array('etag1', 'etag2')); - - $outline = new OutlineNode(null, array('otag1', 'otag2'), $steps, array($table, $table2), null, null); + $steps = [ + new StepNode('Gangway!', 'I am ', [], null, 'Given'), + new StepNode('Aye!', 'my email is ', [], null, 'And'), + new StepNode('Blimey!', 'I open homepage', [], null, 'When'), + new StepNode('Let go and haul', 'website should recognise me', [], null, 'Then'), + ]; + + $table = new ExampleTableNode([ + 2 => ['name', 'email'], + 22 => ['everzet', 'ever.zet@gmail.com'], + 23 => ['example', 'example@example.com'], + ], 'Examples', []); + + $table2 = new ExampleTableNode([ + 3 => ['name', 'email'], + 32 => ['everzet2', 'ever.zet2@gmail.com'], + 33 => ['example2', 'example2@example.com'], + ], 'Examples', ['etag1', 'etag2']); + + $outline = new OutlineNode(null, ['otag1', 'otag2'], $steps, [$table, $table2], null, null); $this->assertCount(4, $examples = $outline->getExamples()); $this->assertEquals(22, $examples[0]->getLine()); $this->assertEquals(23, $examples[1]->getLine()); $this->assertEquals(32, $examples[2]->getLine()); $this->assertEquals(33, $examples[3]->getLine()); - $this->assertEquals(array('name' => 'everzet', 'email' => 'ever.zet@gmail.com'), $examples[0]->getTokens()); - $this->assertEquals(array('name' => 'example', 'email' => 'example@example.com'), $examples[1]->getTokens()); - $this->assertEquals(array('name' => 'everzet2', 'email' => 'ever.zet2@gmail.com'), $examples[2]->getTokens()); - $this->assertEquals(array('name' => 'example2', 'email' => 'example2@example.com'), $examples[3]->getTokens()); - - for ($i = 0; $i < 2; $i++) { - foreach (array('otag1', 'otag2') as $tag) { - $this->assertTrue($examples[$i]->hasTag($tag), "there is no tag " . $tag . " in example #" . $i); + $this->assertEquals(['name' => 'everzet', 'email' => 'ever.zet@gmail.com'], $examples[0]->getTokens()); + $this->assertEquals(['name' => 'example', 'email' => 'example@example.com'], $examples[1]->getTokens()); + $this->assertEquals(['name' => 'everzet2', 'email' => 'ever.zet2@gmail.com'], $examples[2]->getTokens()); + $this->assertEquals(['name' => 'example2', 'email' => 'example2@example.com'], $examples[3]->getTokens()); + + for ($i = 0; $i < 2; ++$i) { + foreach (['otag1', 'otag2'] as $tag) { + $this->assertTrue($examples[$i]->hasTag($tag), 'there is no tag ' . $tag . ' in example #' . $i); } } - for ($i = 2; $i < 4; $i++) { - foreach (array('otag1', 'otag2', 'etag1', 'etag2') as $tag) { - $this->assertTrue($examples[$i]->hasTag($tag), "there is no tag " . $tag . " in example #" . $i); + for ($i = 2; $i < 4; ++$i) { + foreach (['otag1', 'otag2', 'etag1', 'etag2'] as $tag) { + $this->assertTrue($examples[$i]->hasTag($tag), 'there is no tag ' . $tag . ' in example #' . $i); } } } public function testCreatesEmptyExamplesForEmptyExampleTable(): void { - $steps = array( - new StepNode('Gangway!', 'I am ', array(), null, 'Given'), - new StepNode('Aye!', 'my email is ', array(), null, 'And'), - new StepNode('Blimey!', 'I open homepage', array(), null, 'When'), - new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'), - ); + $steps = [ + new StepNode('Gangway!', 'I am ', [], null, 'Given'), + new StepNode('Aye!', 'my email is ', [], null, 'And'), + new StepNode('Blimey!', 'I open homepage', [], null, 'When'), + new StepNode('Let go and haul', 'website should recognise me', [], null, 'Then'), + ]; - $table = new ExampleTableNode(array( - array('name', 'email') - ), 'Examples'); + $table = new ExampleTableNode([ + ['name', 'email'], + ], 'Examples'); - $outline = new OutlineNode(null, array(), $steps, $table, null, null); + $outline = new OutlineNode(null, [], $steps, $table, null, null); $this->assertCount(0, $outline->getExamples()); } public function testCreatesEmptyExamplesForNoExampleTable(): void { - $steps = array( - new StepNode('Gangway!', 'I am ', array(), null, 'Given'), - new StepNode('Aye!', 'my email is ', array(), null, 'And'), - new StepNode('Blimey!', 'I open homepage', array(), null, 'When'), - new StepNode('Let go and haul', 'website should recognise me', array(), null, 'Then'), - ); + $steps = [ + new StepNode('Gangway!', 'I am ', [], null, 'Given'), + new StepNode('Aye!', 'my email is ', [], null, 'And'), + new StepNode('Blimey!', 'I open homepage', [], null, 'When'), + new StepNode('Let go and haul', 'website should recognise me', [], null, 'Then'), + ]; - $table = new ExampleTableNode(array(), 'Examples'); + $table = new ExampleTableNode([], 'Examples'); - $outline = new OutlineNode(null, array(), $steps, array($table), null, null); + $outline = new OutlineNode(null, [], $steps, [$table], null, null); $this->assertCount(0, $outline->getExamples()); } public function testPopulatesExampleWithOutlineTitle(): void { - $steps = array( - new StepNode('', 'I am ', array(), null, 'Given'), - ); + $steps = [ + new StepNode('', 'I am ', [], null, 'Given'), + ]; - $table = new ExampleTableNode(array( - 10 => array('name', 'email'), - 11 => array('Ciaran', 'ciaran@example.com'), - 12 => array('John', 'john@example.com'), - ), 'Examples'); + $table = new ExampleTableNode([ + 10 => ['name', 'email'], + 11 => ['Ciaran', 'ciaran@example.com'], + 12 => ['John', 'john@example.com'], + ], 'Examples'); - $outline = new OutlineNode('An outline title for ', array(), $steps, $table, null, null); + $outline = new OutlineNode('An outline title for ', [], $steps, $table, null, null); $this->assertSame( [ diff --git a/tests/Behat/Gherkin/Node/PyStringNodeTest.php b/tests/Behat/Gherkin/Node/PyStringNodeTest.php index ca6d1aae..40997d62 100644 --- a/tests/Behat/Gherkin/Node/PyStringNodeTest.php +++ b/tests/Behat/Gherkin/Node/PyStringNodeTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Node; use Behat\Gherkin\Node\PyStringNode; @@ -9,14 +17,14 @@ class PyStringNodeTest extends TestCase { public function testGetStrings() { - $str = new PyStringNode(array('line1', 'line2', 'line3'), 0); + $str = new PyStringNode(['line1', 'line2', 'line3'], 0); - $this->assertEquals(array('line1', 'line2', 'line3'), $str->getStrings()); + $this->assertEquals(['line1', 'line2', 'line3'], $str->getStrings()); } public function testGetRaw() { - $str = new PyStringNode(array('line1', 'line2', 'line3'), 0); + $str = new PyStringNode(['line1', 'line2', 'line3'], 0); $expected = << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Node; use Behat\Gherkin\Node\PyStringNode; @@ -13,9 +21,9 @@ public function testThatStepCanHaveOnlyOneArgument() { $this->expectException('Behat\Gherkin\Exception\NodeException'); - new StepNode('Gangway!', 'I am on the page:', array( - new PyStringNode(array('one', 'two'), 11), - new TableNode(array(array('one', 'two'))), - ), 10, 'Given'); + new StepNode('Gangway!', 'I am on the page:', [ + new PyStringNode(['one', 'two'], 11), + new TableNode([['one', 'two']]), + ], 10, 'Given'); } } diff --git a/tests/Behat/Gherkin/Node/TableNodeTest.php b/tests/Behat/Gherkin/Node/TableNodeTest.php index ac344318..a510808e 100644 --- a/tests/Behat/Gherkin/Node/TableNodeTest.php +++ b/tests/Behat/Gherkin/Node/TableNodeTest.php @@ -1,5 +1,13 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin\Node; use Behat\Gherkin\Exception\NodeException; @@ -11,210 +19,209 @@ class TableNodeTest extends TestCase public function testConstructorExpectsSameNumberOfColumnsInEachRow() { $this->expectException(NodeException::class); - new TableNode(array( - array('username', 'password'), - array('everzet'), - array('antono', 'pa$sword') - )); + new TableNode([ + ['username', 'password'], + ['everzet'], + ['antono', 'pa$sword'], + ]); } public function testConstructorExpectsTwoDimensionalArray() { $this->expectException(NodeException::class); $this->expectExceptionMessage("Table row '0' is expected to be array, got string"); - new TableNode(array( - 'everzet', 'antono' - )); + new TableNode([ + 'everzet', 'antono', + ]); } public function testConstructorExpectsScalarCellValue() { $this->expectException(NodeException::class); $this->expectExceptionMessage("Table cell at row '0', col '0' is expected to be scalar, got array"); - new TableNode(array( - array(array('everzet', 'antono')) - )); + new TableNode([ + [['everzet', 'antono']], + ]); } public function testConstructorExpectsEqualRowLengths() { $this->expectException(NodeException::class); $this->expectExceptionMessage("Table row '1' is expected to have 2 columns, got 1"); - new TableNode(array( - array('everzet', 'antono'), - array('everzet'), - )); + new TableNode([ + ['everzet', 'antono'], + ['everzet'], + ]); } public function testHashTable() { - $table = new TableNode(array( - array('username', 'password'), - array('everzet', 'qwerty'), - array('antono', 'pa$sword') - )); + $table = new TableNode([ + ['username', 'password'], + ['everzet', 'qwerty'], + ['antono', 'pa$sword'], + ]); $this->assertEquals( - array( - array('username' => 'everzet', 'password' => 'qwerty') - , array('username' => 'antono', 'password' => 'pa$sword') - ), + [ + ['username' => 'everzet', 'password' => 'qwerty'], ['username' => 'antono', 'password' => 'pa$sword'], + ], $table->getHash() ); - $table = new TableNode(array( - array('username', 'password'), - array('', 'qwerty'), - array('antono', ''), - array('', '') - )); + $table = new TableNode([ + ['username', 'password'], + ['', 'qwerty'], + ['antono', ''], + ['', ''], + ]); $this->assertEquals( - array( - array('username' => '', 'password' => 'qwerty'), - array('username' => 'antono', 'password' => ''), - array('username' => '', 'password' => ''), - ), + [ + ['username' => '', 'password' => 'qwerty'], + ['username' => 'antono', 'password' => ''], + ['username' => '', 'password' => ''], + ], $table->getHash() ); } public function testIterator() { - $table = new TableNode(array( - array('username', 'password'), - array('', 'qwerty'), - array('antono', ''), - array('', ''), - )); + $table = new TableNode([ + ['username', 'password'], + ['', 'qwerty'], + ['antono', ''], + ['', ''], + ]); $this->assertEquals( - array( - array('username' => '', 'password' => 'qwerty'), - array('username' => 'antono', 'password' => ''), - array('username' => '', 'password' => ''), - ), + [ + ['username' => '', 'password' => 'qwerty'], + ['username' => 'antono', 'password' => ''], + ['username' => '', 'password' => ''], + ], iterator_to_array($table) ); } public function testRowsHashTable() { - $table = new TableNode(array( - array('username', 'everzet'), - array('password', 'qwerty'), - array('uid', '35'), - )); + $table = new TableNode([ + ['username', 'everzet'], + ['password', 'qwerty'], + ['uid', '35'], + ]); $this->assertEquals( - array('username' => 'everzet', 'password' => 'qwerty', 'uid' => '35'), + ['username' => 'everzet', 'password' => 'qwerty', 'uid' => '35'], $table->getRowsHash() ); } public function testLongRowsHashTable() { - $table = new TableNode(array( - array('username', 'everzet', 'marcello'), - array('password', 'qwerty', '12345'), - array('uid', '35', '22') - )); - - $this->assertEquals(array( - 'username' => array('everzet', 'marcello'), - 'password' => array('qwerty', '12345'), - 'uid' => array('35', '22') - ), $table->getRowsHash()); + $table = new TableNode([ + ['username', 'everzet', 'marcello'], + ['password', 'qwerty', '12345'], + ['uid', '35', '22'], + ]); + + $this->assertEquals([ + 'username' => ['everzet', 'marcello'], + 'password' => ['qwerty', '12345'], + 'uid' => ['35', '22'], + ], $table->getRowsHash()); } public function testGetRows() { - $table = new TableNode(array( - array('username', 'password'), - array('everzet', 'qwerty'), - array('antono', 'pa$sword') - )); - - $this->assertEquals(array( - array('username', 'password'), - array('everzet', 'qwerty'), - array('antono', 'pa$sword') - ), $table->getRows()); + $table = new TableNode([ + ['username', 'password'], + ['everzet', 'qwerty'], + ['antono', 'pa$sword'], + ]); + + $this->assertEquals([ + ['username', 'password'], + ['everzet', 'qwerty'], + ['antono', 'pa$sword'], + ], $table->getRows()); } public function testGetLines() { - $table = new TableNode(array( - 5 => array('username', 'password'), - 10 => array('everzet', 'qwerty'), - 13 => array('antono', 'pa$sword') - )); + $table = new TableNode([ + 5 => ['username', 'password'], + 10 => ['everzet', 'qwerty'], + 13 => ['antono', 'pa$sword'], + ]); - $this->assertEquals(array(5, 10, 13), $table->getLines()); + $this->assertEquals([5, 10, 13], $table->getLines()); } public function testGetRow() { - $table = new TableNode(array( - array('username', 'password'), - array('everzet', 'qwerty'), - array('antono', 'pa$sword') - )); - - $this->assertEquals(array('username', 'password'), $table->getRow(0)); - $this->assertEquals(array('antono', 'pa$sword'), $table->getRow(2)); + $table = new TableNode([ + ['username', 'password'], + ['everzet', 'qwerty'], + ['antono', 'pa$sword'], + ]); + + $this->assertEquals(['username', 'password'], $table->getRow(0)); + $this->assertEquals(['antono', 'pa$sword'], $table->getRow(2)); } public function testGetColumn() { - $table = new TableNode(array( - array('username', 'password'), - array('everzet', 'qwerty'), - array('antono', 'pa$sword') - )); - - $this->assertEquals(array('username', 'everzet', 'antono'), $table->getColumn(0)); - $this->assertEquals(array('password', 'qwerty', 'pa$sword'), $table->getColumn(1)); - - $table = new TableNode(array( - array('username'), - array('everzet'), - array('antono') - )); - - $this->assertEquals(array('username', 'everzet', 'antono'), $table->getColumn(0)); + $table = new TableNode([ + ['username', 'password'], + ['everzet', 'qwerty'], + ['antono', 'pa$sword'], + ]); + + $this->assertEquals(['username', 'everzet', 'antono'], $table->getColumn(0)); + $this->assertEquals(['password', 'qwerty', 'pa$sword'], $table->getColumn(1)); + + $table = new TableNode([ + ['username'], + ['everzet'], + ['antono'], + ]); + + $this->assertEquals(['username', 'everzet', 'antono'], $table->getColumn(0)); } public function testGetRowWithLineNumbers() { - $table = new TableNode(array( - 5 => array('username', 'password'), - 10 => array('everzet', 'qwerty'), - 13 => array('antono', 'pa$sword') - )); - - $this->assertEquals(array('username', 'password'), $table->getRow(0)); - $this->assertEquals(array('antono', 'pa$sword'), $table->getRow(2)); + $table = new TableNode([ + 5 => ['username', 'password'], + 10 => ['everzet', 'qwerty'], + 13 => ['antono', 'pa$sword'], + ]); + + $this->assertEquals(['username', 'password'], $table->getRow(0)); + $this->assertEquals(['antono', 'pa$sword'], $table->getRow(2)); } public function testGetTable() { - $table = new TableNode($a = array( - 5 => array('username', 'password'), - 10 => array('everzet', 'qwerty'), - 13 => array('antono', 'pa$sword') - )); + $table = new TableNode($a = [ + 5 => ['username', 'password'], + 10 => ['everzet', 'qwerty'], + 13 => ['antono', 'pa$sword'], + ]); $this->assertEquals($a, $table->getTable()); } public function testGetRowLine() { - $table = new TableNode(array( - 5 => array('username', 'password'), - 10 => array('everzet', 'qwerty'), - 13 => array('antono', 'pa$sword') - )); + $table = new TableNode([ + 5 => ['username', 'password'], + 10 => ['everzet', 'qwerty'], + 13 => ['antono', 'pa$sword'], + ]); $this->assertEquals(5, $table->getRowLine(0)); $this->assertEquals(13, $table->getRowLine(2)); @@ -222,11 +229,11 @@ public function testGetRowLine() public function testGetRowAsString() { - $table = new TableNode(array( - 5 => array('username', 'password'), - 10 => array('everzet', 'qwerty'), - 13 => array('antono', 'pa$sword') - )); + $table = new TableNode([ + 5 => ['username', 'password'], + 10 => ['everzet', 'qwerty'], + 13 => ['antono', 'pa$sword'], + ]); $this->assertEquals('| username | password |', $table->getRowAsString(0)); $this->assertEquals('| antono | pa$sword |', $table->getRowAsString(2)); @@ -234,11 +241,11 @@ public function testGetRowAsString() public function testGetTableAsString() { - $table = new TableNode(array( - 5 => array('id', 'username', 'password'), - 10 => array('42', 'everzet', 'qwerty'), - 13 => array('2', 'antono', 'pa$sword') - )); + $table = new TableNode([ + 5 => ['id', 'username', 'password'], + 10 => ['42', 'everzet', 'qwerty'], + 13 => ['2', 'antono', 'pa$sword'], + ]); $expected = <<assertEquals($expected, $table); } + public function testMergeRowsFromTablePassSeveralTablesShouldBeMerged() { - $table = new TableNode(array( - 5 => array('id', 'username', 'password'), - 10 => array('42', 'everzet', 'qwerty'), - 13 => array('2', 'antono', 'pa$sword') - )); - - $new = new TableNode(array( - 25 => array('id', 'username', 'password'), - 210 => array('242', '2everzet', '2qwerty'), - 213 => array('22', '2antono', '2pa$sword') - )); - - $new2 = new TableNode(array( - 35 => array('id', 'username', 'password'), - 310 => array('342', '3everzet', '3qwerty'), - 313 => array('32', '3antono', '3pa$sword') - )); + $table = new TableNode([ + 5 => ['id', 'username', 'password'], + 10 => ['42', 'everzet', 'qwerty'], + 13 => ['2', 'antono', 'pa$sword'], + ]); + + $new = new TableNode([ + 25 => ['id', 'username', 'password'], + 210 => ['242', '2everzet', '2qwerty'], + 213 => ['22', '2antono', '2pa$sword'], + ]); + + $new2 = new TableNode([ + 35 => ['id', 'username', 'password'], + 310 => ['342', '3everzet', '3qwerty'], + 313 => ['32', '3antono', '3pa$sword'], + ]); $table->mergeRowsFromTable($new); $table->mergeRowsFromTable($new2); - $this->assertEquals(array('id', 'username', 'password'), $table->getRow(0)); - $this->assertEquals(array('2', 'antono', 'pa$sword'), $table->getRow(2)); - $this->assertEquals(array('242', '2everzet', '2qwerty'), $table->getRow(3)); - $this->assertEquals(array('32', '3antono', '3pa$sword'), $table->getRow(6)); + $this->assertEquals(['id', 'username', 'password'], $table->getRow(0)); + $this->assertEquals(['2', 'antono', 'pa$sword'], $table->getRow(2)); + $this->assertEquals(['242', '2everzet', '2qwerty'], $table->getRow(3)); + $this->assertEquals(['32', '3antono', '3pa$sword'], $table->getRow(6)); } public function testMergeRowsFromTableWrongHeaderNameExceptionThrown() { $this->expectException(NodeException::class); - $table = new TableNode(array( - 5 => array('id', 'username', 'password'), - 10 => array('42', 'everzet', 'qwerty'), - 13 => array('2', 'antono', 'pa$sword') - )); + $table = new TableNode([ + 5 => ['id', 'username', 'password'], + 10 => ['42', 'everzet', 'qwerty'], + 13 => ['2', 'antono', 'pa$sword'], + ]); - $new = new TableNode(array( - 25 => array('id', 'QWE', 'password'), - 210 => array('242', '2everzet', '2qwerty') - )); + $new = new TableNode([ + 25 => ['id', 'QWE', 'password'], + 210 => ['242', '2everzet', '2qwerty'], + ]); $table->mergeRowsFromTable($new); } @@ -310,25 +318,25 @@ public function testMergeRowsFromTableWrongHeaderNameExceptionThrown() public function testGetTableFromListWithMultidimensionalArrayArgument() { $this->expectException(NodeException::class); - TableNode::fromList(array( - array(1, 2, 3), - array(4, 5, 6) - )); + TableNode::fromList([ + [1, 2, 3], + [4, 5, 6], + ]); } public function testMergeRowsFromTableWrongHeaderOrderExceptionThrown() { $this->expectException(NodeException::class); - $table = new TableNode(array( - 5 => array('id', 'username', 'password'), - 10 => array('42', 'everzet', 'qwerty'), - 13 => array('2', 'antono', 'pa$sword') - )); + $table = new TableNode([ + 5 => ['id', 'username', 'password'], + 10 => ['42', 'everzet', 'qwerty'], + 13 => ['2', 'antono', 'pa$sword'], + ]); - $new = new TableNode(array( - 25 => array('id', 'password', 'username'), - 210 => array('242', '2everzet', '2qwerty') - )); + $new = new TableNode([ + 25 => ['id', 'password', 'username'], + 210 => ['242', '2everzet', '2qwerty'], + ]); $table->mergeRowsFromTable($new); } @@ -336,16 +344,16 @@ public function testMergeRowsFromTableWrongHeaderOrderExceptionThrown() public function testMergeRowsFromTableWrongHeaderSizeExceptionThrown() { $this->expectException(NodeException::class); - $table = new TableNode(array( - 5 => array('id', 'username', 'password'), - 10 => array('42', 'everzet', 'qwerty'), - 13 => array('2', 'antono', 'pa$sword') - )); - - $new = new TableNode(array( - 25 => array('id', 'username'), - 210 => array('242', '2everzet') - )); + $table = new TableNode([ + 5 => ['id', 'username', 'password'], + 10 => ['42', 'everzet', 'qwerty'], + 13 => ['2', 'antono', 'pa$sword'], + ]); + + $new = new TableNode([ + 25 => ['id', 'username'], + 210 => ['242', '2everzet'], + ]); $table->mergeRowsFromTable($new); } diff --git a/tests/Behat/Gherkin/ParserExceptionsTest.php b/tests/Behat/Gherkin/ParserExceptionsTest.php index ec315c1e..5a5af2df 100644 --- a/tests/Behat/Gherkin/ParserExceptionsTest.php +++ b/tests/Behat/Gherkin/ParserExceptionsTest.php @@ -1,10 +1,18 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin; +use Behat\Gherkin\Keywords\ArrayKeywords; use Behat\Gherkin\Lexer; use Behat\Gherkin\Parser; -use Behat\Gherkin\Keywords\ArrayKeywords; use PHPUnit\Framework\TestCase; class ParserExceptionsTest extends TestCase @@ -16,32 +24,32 @@ class ParserExceptionsTest extends TestCase protected function setUp(): void { - $keywords = new ArrayKeywords(array( - 'en' => array( - 'feature' => 'Feature', - 'background' => 'Background', - 'scenario' => 'Scenario', + $keywords = new ArrayKeywords([ + 'en' => [ + 'feature' => 'Feature', + 'background' => 'Background', + 'scenario' => 'Scenario', 'scenario_outline' => 'Scenario Outline', - 'examples' => 'Examples', - 'given' => 'Given', - 'when' => 'When', - 'then' => 'Then', - 'and' => 'And', - 'but' => 'But' - ), - 'ru' => array( - 'feature' => 'Функционал', - 'background' => 'Предыстория', - 'scenario' => 'Сценарий', + 'examples' => 'Examples', + 'given' => 'Given', + 'when' => 'When', + 'then' => 'Then', + 'and' => 'And', + 'but' => 'But', + ], + 'ru' => [ + 'feature' => 'Функционал', + 'background' => 'Предыстория', + 'scenario' => 'Сценарий', 'scenario_outline' => 'Структура сценария', - 'examples' => 'Примеры', - 'given' => 'Допустим', - 'when' => 'То', - 'then' => 'Если', - 'and' => 'И', - 'but' => 'Но' - ) - )); + 'examples' => 'Примеры', + 'given' => 'Допустим', + 'when' => 'То', + 'then' => 'Если', + 'and' => 'И', + 'but' => 'Но', + ], + ]); $this->gherkin = new Parser(new Lexer($keywords)); } diff --git a/tests/Behat/Gherkin/ParserTest.php b/tests/Behat/Gherkin/ParserTest.php index 5102b2c4..2a6f1a0e 100644 --- a/tests/Behat/Gherkin/ParserTest.php +++ b/tests/Behat/Gherkin/ParserTest.php @@ -1,13 +1,21 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Tests\Behat\Gherkin; -use Behat\Gherkin\Node\FeatureNode; +use Behat\Gherkin\Keywords\ArrayKeywords; use Behat\Gherkin\Lexer; +use Behat\Gherkin\Loader\YamlFileLoader; +use Behat\Gherkin\Node\FeatureNode; use Behat\Gherkin\Node\ScenarioNode; use Behat\Gherkin\Parser; -use Behat\Gherkin\Keywords\ArrayKeywords; -use Behat\Gherkin\Loader\YamlFileLoader; use PHPUnit\Framework\TestCase; class ParserTest extends TestCase @@ -17,12 +25,12 @@ class ParserTest extends TestCase public function parserTestDataProvider() { - $data = array(); + $data = []; foreach (glob(__DIR__ . '/Fixtures/etalons/*.yml') as $file) { $testname = basename($file, '.yml'); - $data[$testname] = array($testname); + $data[$testname] = [$testname]; } return $data; @@ -73,7 +81,7 @@ public function testSingleCharacterStepSupport() Scenario: When x FEATURE -); + ); $scenarios = $feature->getScenarios(); /** @var ScenarioNode $scenario */ @@ -84,46 +92,46 @@ public function testSingleCharacterStepSupport() protected function getGherkinParser() { - if (null === $this->gherkin) { - $keywords = new ArrayKeywords(array( - 'en' => array( - 'feature' => 'Feature', - 'background' => 'Background', - 'scenario' => 'Scenario', + if ($this->gherkin === null) { + $keywords = new ArrayKeywords([ + 'en' => [ + 'feature' => 'Feature', + 'background' => 'Background', + 'scenario' => 'Scenario', 'scenario_outline' => 'Scenario Outline', - 'examples' => 'Examples', - 'given' => 'Given', - 'when' => 'When', - 'then' => 'Then', - 'and' => 'And', - 'but' => 'But' - ), - 'ru' => array( - 'feature' => 'Функционал', - 'background' => 'Предыстория', - 'scenario' => 'Сценарий', + 'examples' => 'Examples', + 'given' => 'Given', + 'when' => 'When', + 'then' => 'Then', + 'and' => 'And', + 'but' => 'But', + ], + 'ru' => [ + 'feature' => 'Функционал', + 'background' => 'Предыстория', + 'scenario' => 'Сценарий', 'scenario_outline' => 'Структура сценария', - 'examples' => 'Примеры', - 'given' => 'Допустим', - 'when' => 'То', - 'then' => 'Если', - 'and' => 'И', - 'but' => 'Но' - ), - 'ja' => array ( - 'feature' => 'フィーチャ', - 'background' => '背景', - 'scenario' => 'シナリオ', - 'scenario_outline' => 'シナリオアウトライン', - 'examples' => '例|サンプル', - 'given' => '前提<', - 'when' => 'もし<', - 'then' => 'ならば<', - 'and' => 'かつ<', - 'but' => 'しかし<' - ) - )); - $this->gherkin = new Parser(new Lexer($keywords)); + 'examples' => 'Примеры', + 'given' => 'Допустим', + 'when' => 'То', + 'then' => 'Если', + 'and' => 'И', + 'but' => 'Но', + ], + 'ja' => [ + 'feature' => 'フィーチャ', + 'background' => '背景', + 'scenario' => 'シナリオ', + 'scenario_outline' => 'シナリオアウトライン', + 'examples' => '例|サンプル', + 'given' => '前提<', + 'when' => 'もし<', + 'then' => 'ならば<', + 'and' => 'かつ<', + 'but' => 'しかし<', + ], + ]); + $this->gherkin = new Parser(new Lexer($keywords)); } return $this->gherkin; @@ -131,7 +139,7 @@ protected function getGherkinParser() protected function getYamlParser() { - if (null === $this->yaml) { + if ($this->yaml === null) { $this->yaml = new YamlFileLoader(); } @@ -142,13 +150,13 @@ protected function parseFixture($fixture) { $file = __DIR__ . '/Fixtures/features/' . $fixture; - return array($this->getGherkinParser()->parse(file_get_contents($file), $file)); + return [$this->getGherkinParser()->parse(file_get_contents($file), $file)]; } protected function parseEtalon($etalon) { $features = $this->getYamlParser()->load(__DIR__ . '/Fixtures/etalons/' . $etalon); - $feature = $features[0]; + $feature = $features[0]; return new FeatureNode( $feature->getTitle(), @@ -165,7 +173,7 @@ protected function parseEtalon($etalon) public function testParsingManyCommentsShouldPass() { - if (! extension_loaded('xdebug')) { + if (!extension_loaded('xdebug')) { $this->markTestSkipped('xdebug extension must be enabled.'); } $defaultPHPSetting = 256; From 20abc5739d4fb32038817797e070f866860333d2 Mon Sep 17 00:00:00 2001 From: Christian Sciberras Date: Thu, 12 Dec 2024 20:29:49 +0100 Subject: [PATCH 3/5] Fix/normalise here/nowdocs --- .php-cs-fixer.dist.php | 2 + src/Behat/Gherkin/Keywords/KeywordsDumper.php | 38 +- tests/Behat/Gherkin/Filter/FilterTestCase.php | 50 +-- .../Gherkin/Filter/NarrativeFilterTest.php | 10 +- tests/Behat/Gherkin/Filter/RoleFilterTest.php | 20 +- .../Gherkin/Keywords/KeywordsDumperTest.php | 376 +++++++++--------- .../Gherkin/Keywords/KeywordsTestCase.php | 10 +- .../Gherkin/Loader/YamlFileLoaderTest.php | 10 +- tests/Behat/Gherkin/Node/PyStringNodeTest.php | 10 +- tests/Behat/Gherkin/Node/TableNodeTest.php | 10 +- tests/Behat/Gherkin/ParserExceptionsTest.php | 254 ++++++------ tests/Behat/Gherkin/ParserTest.php | 32 +- 12 files changed, 412 insertions(+), 410 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 1d21c195..e98fc23c 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -25,5 +25,7 @@ ], 'concat_space' => ['spacing' => 'one'], 'phpdoc_align' => ['align' => 'left'], + 'heredoc_to_nowdoc' => true, + 'heredoc_indentation' => ['indentation' => 'same_as_start'], ]) ->setFinder($finder); diff --git a/src/Behat/Gherkin/Keywords/KeywordsDumper.php b/src/Behat/Gherkin/Keywords/KeywordsDumper.php index d2bab344..4eca2425 100644 --- a/src/Behat/Gherkin/Keywords/KeywordsDumper.php +++ b/src/Behat/Gherkin/Keywords/KeywordsDumper.php @@ -105,13 +105,13 @@ public function dump($language, $short = true, $excludeAsterisk = false) protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false) { $dump = <<keywords->getBackgroundKeywords()); @@ -161,9 +161,9 @@ protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false protected function dumpBackground($keyword, $short = true, $excludeAsterisk = false) { $dump = <<dumpStep( @@ -195,9 +195,9 @@ protected function dumpBackground($keyword, $short = true, $excludeAsterisk = fa protected function dumpScenario($keyword, $short = true, $excludeAsterisk = false) { $dump = <<dumpStep( @@ -253,9 +253,9 @@ protected function dumpScenario($keyword, $short = true, $excludeAsterisk = fals protected function dumpOutline($keyword, $short = true, $excludeAsterisk = false) { $dump = <<dumpStep( @@ -306,11 +306,11 @@ protected function dumpOutline($keyword, $short = true, $excludeAsterisk = false $dump .= <<keywordsDumper, $keywords, $short); $dump .= <<keywordsDumper, [$keyword], $short); $dump .= << occurs - Then should be visible + Scenario Outline: Scenario#3 + When occurs + Then should be visible - @etag1 - Examples: - | action | outcome | - | act#1 | out#1 | - | act#2 | out#2 | - - @etag2 - Examples: - | action | outcome | - | act#3 | out#3 | + @etag1 + Examples: + | action | outcome | + | act#1 | out#1 | + | act#2 | out#2 | + + @etag2 + Examples: + | action | outcome | + | act#3 | out#3 | -GHERKIN; + GHERKIN; } protected function getParsedFeature() diff --git a/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php b/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php index 988b5b9d..b5f914f1 100644 --- a/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php +++ b/tests/Behat/Gherkin/Filter/NarrativeFilterTest.php @@ -17,11 +17,11 @@ class NarrativeFilterTest extends FilterTestCase { public function testIsFeatureMatchFilter() { - $description = <<keywords); $dumped = $dumper->dump('en'); - $etalon = << - And there is agent - When I erase agent 's memory - Then there should be agent - But there should not be agent - - (Examples|Scenarios): - | agent1 | agent2 | - | D | M | -GHERKIN; + $etalon = <<<'GHERKIN' + Feature: Internal operations + In order to stay secret + As a secret organization + We need to be able to erase past agents' memory + + Background: + Given there is agent A + And there is agent B + + Scenario: Erasing agent memory + Given there is agent J + And there is agent K + When I erase agent K's memory + Then there should be agent J + But there should not be agent K + + (Scenario Outline|Scenario Template): Erasing other agents' memory + Given there is agent + And there is agent + When I erase agent 's memory + Then there should be agent + But there should not be agent + + (Examples|Scenarios): + | agent1 | agent2 | + | D | M | + GHERKIN; $this->assertEquals($etalon, $dumped); } @@ -90,35 +90,35 @@ public function testRuKeywordsDumper() $dumper = new KeywordsDumper($this->keywords); $dumped = $dumper->dump('ru'); - $etalon = << - И there is agent - (Если|@) I erase agent 's memory - То there should be agent - Но there should not be agent - - Примеры: - | agent1 | agent2 | - | D | M | -GHERKIN; + $etalon = <<<'GHERKIN' + # language: ru + (Функционал|Фича): Internal operations + In order to stay secret + As a secret organization + We need to be able to erase past agents' memory + + (Предыстория|Бэкграунд): + Допустим there is agent A + И there is agent B + + (Сценарий|История): Erasing agent memory + Допустим there is agent J + И there is agent K + (Если|@) I erase agent K's memory + То there should be agent J + Но there should not be agent K + + (Структура сценария|Аутлайн): Erasing other agents' memory + Допустим there is agent + И there is agent + (Если|@) I erase agent 's memory + То there should be agent + Но there should not be agent + + Примеры: + | agent1 | agent2 | + | D | M | + GHERKIN; $this->assertEquals($etalon, $dumped); } @@ -131,35 +131,35 @@ public function testRuKeywordsCustomKeywordsDumper() }); $dumped = $dumper->dump('ru'); - $etalon = <<Функционал, Фича: Internal operations - In order to stay secret - As a secret organization - We need to be able to erase past agents' memory - - Предыстория, Бэкграунд: - Допустим there is agent A - И there is agent B - - Сценарий, История: Erasing agent memory - Допустим there is agent J - И there is agent K - Если, @ I erase agent K's memory - То there should be agent J - Но there should not be agent K - - Структура сценария, Аутлайн: Erasing other agents' memory - Допустим there is agent - И there is agent - Если, @ I erase agent 's memory - То there should be agent - Но there should not be agent - - Примеры: - | agent1 | agent2 | - | D | M | -GHERKIN; + $etalon = <<<'GHERKIN' + # language: ru + Функционал, Фича: Internal operations + In order to stay secret + As a secret organization + We need to be able to erase past agents' memory + + Предыстория, Бэкграунд: + Допустим there is agent A + И there is agent B + + Сценарий, История: Erasing agent memory + Допустим there is agent J + И there is agent K + Если, @ I erase agent K's memory + То there should be agent J + Но there should not be agent K + + Структура сценария, Аутлайн: Erasing other agents' memory + Допустим there is agent + И there is agent + Если, @ I erase agent 's memory + То there should be agent + Но there should not be agent + + Примеры: + | agent1 | agent2 | + | D | M | + GHERKIN; $this->assertEquals($etalon, $dumped); } @@ -170,108 +170,108 @@ public function testExtendedVersionDumper() $dumped = $dumper->dump('ru', false); $etalon = [ - << - И there is agent - Если I erase agent 's memory - @ I erase agent 's memory - То there should be agent - Но there should not be agent - - Примеры: - | agent1 | agent2 | - | D | M | - - Аутлайн: Erasing other agents' memory - Допустим there is agent - И there is agent - Если I erase agent 's memory - @ I erase agent 's memory - То there should be agent - Но there should not be agent - - Примеры: - | agent1 | agent2 | - | D | M | -GHERKIN - , << - И there is agent - Если I erase agent 's memory - @ I erase agent 's memory - То there should be agent - Но there should not be agent - - Примеры: - | agent1 | agent2 | - | D | M | - - Аутлайн: Erasing other agents' memory - Допустим there is agent - И there is agent - Если I erase agent 's memory - @ I erase agent 's memory - То there should be agent - Но there should not be agent - - Примеры: - | agent1 | agent2 | - | D | M | -GHERKIN, + <<<'GHERKIN' + # language: ru + Функционал: Internal operations + In order to stay secret + As a secret organization + We need to be able to erase past agents' memory + + Предыстория: + Допустим there is agent A + И there is agent B + + Сценарий: Erasing agent memory + Допустим there is agent J + И there is agent K + Если I erase agent K's memory + @ I erase agent K's memory + То there should be agent J + Но there should not be agent K + + История: Erasing agent memory + Допустим there is agent J + И there is agent K + Если I erase agent K's memory + @ I erase agent K's memory + То there should be agent J + Но there should not be agent K + + Структура сценария: Erasing other agents' memory + Допустим there is agent + И there is agent + Если I erase agent 's memory + @ I erase agent 's memory + То there should be agent + Но there should not be agent + + Примеры: + | agent1 | agent2 | + | D | M | + + Аутлайн: Erasing other agents' memory + Допустим there is agent + И there is agent + Если I erase agent 's memory + @ I erase agent 's memory + То there should be agent + Но there should not be agent + + Примеры: + | agent1 | agent2 | + | D | M | + GHERKIN + , <<<'GHERKIN' + # language: ru + Фича: Internal operations + In order to stay secret + As a secret organization + We need to be able to erase past agents' memory + + Предыстория: + Допустим there is agent A + И there is agent B + + Сценарий: Erasing agent memory + Допустим there is agent J + И there is agent K + Если I erase agent K's memory + @ I erase agent K's memory + То there should be agent J + Но there should not be agent K + + История: Erasing agent memory + Допустим there is agent J + И there is agent K + Если I erase agent K's memory + @ I erase agent K's memory + То there should be agent J + Но there should not be agent K + + Структура сценария: Erasing other agents' memory + Допустим there is agent + И there is agent + Если I erase agent 's memory + @ I erase agent 's memory + То there should be agent + Но there should not be agent + + Примеры: + | agent1 | agent2 | + | D | M | + + Аутлайн: Erasing other agents' memory + Допустим there is agent + И there is agent + Если I erase agent 's memory + @ I erase agent 's memory + То there should be agent + Но there should not be agent + + Примеры: + | agent1 | agent2 | + | D | M | + GHERKIN, ]; $this->assertEquals($etalon, $dumped); diff --git a/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php b/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php index 452ee096..eb823244 100644 --- a/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php +++ b/tests/Behat/Gherkin/Keywords/KeywordsTestCase.php @@ -102,11 +102,11 @@ public function translationTestDataProvider() $features[] = new FeatureNode( 'Internal operations', - <<assertEquals('Addition', $features[0]->getTitle()); $this->assertEquals(2, $features[0]->getLine()); $this->assertEquals('en', $features[0]->getLanguage()); - $expectedDescription = <<assertEquals($expectedDescription, $features[0]->getDescription()); $scenarios = $features[0]->getScenarios(); diff --git a/tests/Behat/Gherkin/Node/PyStringNodeTest.php b/tests/Behat/Gherkin/Node/PyStringNodeTest.php index 40997d62..44365e4c 100644 --- a/tests/Behat/Gherkin/Node/PyStringNodeTest.php +++ b/tests/Behat/Gherkin/Node/PyStringNodeTest.php @@ -26,11 +26,11 @@ public function testGetRaw() { $str = new PyStringNode(['line1', 'line2', 'line3'], 0); - $expected = <<assertEquals($expected, $str->getRaw()); } } diff --git a/tests/Behat/Gherkin/Node/TableNodeTest.php b/tests/Behat/Gherkin/Node/TableNodeTest.php index a510808e..3a7432bb 100644 --- a/tests/Behat/Gherkin/Node/TableNodeTest.php +++ b/tests/Behat/Gherkin/Node/TableNodeTest.php @@ -247,11 +247,11 @@ public function testGetTableAsString() 13 => ['2', 'antono', 'pa$sword'], ]); - $expected = <<
assertEquals($expected, $table->getTableAsString()); } diff --git a/tests/Behat/Gherkin/ParserExceptionsTest.php b/tests/Behat/Gherkin/ParserExceptionsTest.php index 5a5af2df..6c904b24 100644 --- a/tests/Behat/Gherkin/ParserExceptionsTest.php +++ b/tests/Behat/Gherkin/ParserExceptionsTest.php @@ -55,11 +55,11 @@ protected function setUp(): void public function testStepRightAfterFeature() { - $feature = <<gherkin->parse($feature); @@ -68,22 +68,22 @@ public function testStepRightAfterFeature() public function testTextInBackground() { - $feature = <<gherkin->parse($feature); $background = $feature->getBackground(); @@ -95,77 +95,77 @@ public function testTextInBackground() public function testTextInScenario() { - $feature = <<gherkin->parse($feature); $this->assertCount(2, $scenarios = $feature->getScenarios()); - $firstTitle = <<assertEquals($firstTitle, $scenarios[0]->getTitle()); - $secondTitle = <<assertEquals($secondTitle, $scenarios[1]->getTitle()); } public function testAmbigiousLanguage() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -173,11 +173,11 @@ public function testAmbigiousLanguage() public function testEmptyOutline() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -185,14 +185,14 @@ public function testEmptyOutline() public function testWrongTagPlacement() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -200,13 +200,13 @@ public function testWrongTagPlacement() public function testBackgroundWithTag() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -214,14 +214,14 @@ public function testBackgroundWithTag() public function testEndlessPyString() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -229,14 +229,14 @@ public function testEndlessPyString() public function testWrongStepType() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -244,15 +244,15 @@ public function testWrongStepType() public function testMultipleBackgrounds() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -260,11 +260,11 @@ public function testMultipleBackgrounds() public function testMultipleFeatures() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); @@ -272,14 +272,14 @@ public function testMultipleFeatures() public function testTableWithoutRightBorder() { - $feature = <<expectException("\Behat\Gherkin\Exception\ParserException"); $this->gherkin->parse($feature); diff --git a/tests/Behat/Gherkin/ParserTest.php b/tests/Behat/Gherkin/ParserTest.php index 2a6f1a0e..7c711cdd 100644 --- a/tests/Behat/Gherkin/ParserTest.php +++ b/tests/Behat/Gherkin/ParserTest.php @@ -57,18 +57,18 @@ public function testParserResetsTagsBetweenFeatures() { $parser = $this->getGherkinParser(); - $parser->parse(<<parse(<<<'FEATURE' + Feature: + Scenario: + Given step + @skipped + FEATURE ); - $feature2 = $parser->parse(<<parse(<<<'FEATURE' + Feature: + Scenario: + Given step + FEATURE ); $this->assertFalse($feature2->hasTags()); @@ -76,11 +76,11 @@ public function testParserResetsTagsBetweenFeatures() public function testSingleCharacterStepSupport() { - $feature = $this->getGherkinParser()->parse(<<getGherkinParser()->parse(<<<'FEATURE' + Feature: + Scenario: + When x + FEATURE ); $scenarios = $feature->getScenarios(); From 2900966485c83213b8d0b0976f78cd9c4cb9291f Mon Sep 17 00:00:00 2001 From: Christian Sciberras Date: Thu, 12 Dec 2024 20:20:41 +0100 Subject: [PATCH 4/5] Enable rules and fix array/list types (risky) --- .php-cs-fixer.dist.php | 3 + src/Behat/Gherkin/Filter/PathsFilter.php | 18 ++-- src/Behat/Gherkin/Filter/TagFilter.php | 2 +- src/Behat/Gherkin/Gherkin.php | 14 +-- src/Behat/Gherkin/Loader/ArrayLoader.php | 4 +- .../Loader/CucumberNDJsonAstLoader.php | 99 ++++++++----------- src/Behat/Gherkin/Loader/DirectoryLoader.php | 22 ++--- .../Gherkin/Loader/GherkinFileLoader.php | 19 ++-- src/Behat/Gherkin/Loader/LoaderInterface.php | 2 +- src/Behat/Gherkin/Loader/YamlFileLoader.php | 25 ++--- src/Behat/Gherkin/Node/BackgroundNode.php | 8 +- src/Behat/Gherkin/Node/ExampleNode.php | 30 +++--- src/Behat/Gherkin/Node/ExampleTableNode.php | 6 +- src/Behat/Gherkin/Node/FeatureNode.php | 16 +-- src/Behat/Gherkin/Node/OutlineNode.php | 30 +++--- src/Behat/Gherkin/Node/ScenarioNode.php | 10 +- .../Gherkin/Node/StepContainerInterface.php | 2 +- src/Behat/Gherkin/Node/StepNode.php | 6 +- .../Gherkin/Node/TaggedNodeInterface.php | 2 +- src/Behat/Gherkin/Parser.php | 14 +-- .../Behat/Gherkin/Loader/ArrayLoaderTest.php | 2 - 21 files changed, 157 insertions(+), 177 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index e98fc23c..0b309a98 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -6,6 +6,7 @@ return (new PhpCsFixer\Config()) ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect()) + ->setRiskyAllowed(true) ->setRules([ '@PER-CS' => true, '@Symfony' => true, @@ -27,5 +28,7 @@ 'phpdoc_align' => ['align' => 'left'], 'heredoc_to_nowdoc' => true, 'heredoc_indentation' => ['indentation' => 'same_as_start'], + 'phpdoc_array_type' => true, + 'phpdoc_list_type' => true, ]) ->setFinder($finder); diff --git a/src/Behat/Gherkin/Filter/PathsFilter.php b/src/Behat/Gherkin/Filter/PathsFilter.php index 22d65915..10918595 100644 --- a/src/Behat/Gherkin/Filter/PathsFilter.php +++ b/src/Behat/Gherkin/Filter/PathsFilter.php @@ -25,19 +25,17 @@ class PathsFilter extends SimpleFilter /** * Initializes filter. * - * @param string[] $paths List of approved paths + * @param array $paths List of approved paths */ public function __construct(array $paths) { - $this->filterPaths = array_map( - function ($realpath) { - return rtrim($realpath, DIRECTORY_SEPARATOR) . - (is_dir($realpath) ? DIRECTORY_SEPARATOR : ''); - }, - array_filter( - array_map('realpath', $paths) - ) - ); + foreach ($paths as $path) { + if (($realpath = realpath($path)) === false) { + continue; + } + $this->filterPaths[] = rtrim($realpath, DIRECTORY_SEPARATOR) + . (is_dir($realpath) ? DIRECTORY_SEPARATOR : ''); + } } /** diff --git a/src/Behat/Gherkin/Filter/TagFilter.php b/src/Behat/Gherkin/Filter/TagFilter.php index 2c155d2d..73dc9459 100644 --- a/src/Behat/Gherkin/Filter/TagFilter.php +++ b/src/Behat/Gherkin/Filter/TagFilter.php @@ -126,7 +126,7 @@ public function isScenarioMatch(FeatureNode $feature, ScenarioInterface $scenari /** * Checks that node matches condition. * - * @param string[] $tags + * @param array $tags * * @return bool */ diff --git a/src/Behat/Gherkin/Gherkin.php b/src/Behat/Gherkin/Gherkin.php index 577d0a9a..4c8332d6 100644 --- a/src/Behat/Gherkin/Gherkin.php +++ b/src/Behat/Gherkin/Gherkin.php @@ -26,11 +26,11 @@ class Gherkin public const VERSION = '4.8.0'; /** - * @var LoaderInterface[] + * @var list */ protected $loaders = []; /** - * @var FeatureFilterInterface[] + * @var list */ protected $filters = []; @@ -57,12 +57,12 @@ public function addFilter(FeatureFilterInterface $filter) /** * Sets filters to the parser. * - * @param FeatureFilterInterface[] $filters + * @param array $filters */ public function setFilters(array $filters) { $this->filters = []; - array_map([$this, 'addFilter'], $filters); + array_map($this->addFilter(...), $filters); } /** @@ -83,7 +83,7 @@ public function setBasePath($path) * Loads & filters resource with added loaders. * * @param mixed $resource Resource to load - * @param FeatureFilterInterface[] $filters Additional filters + * @param array $filters Additional filters * * @return array */ @@ -92,10 +92,10 @@ public function load($resource, array $filters = []) $filters = array_merge($this->filters, $filters); $matches = []; - if (preg_match('/^(.*)\:(\d+)-(\d+|\*)$/', $resource, $matches)) { + if (preg_match('/^(.*):(\d+)-(\d+|\*)$/', $resource, $matches)) { $resource = $matches[1]; $filters[] = new LineRangeFilter($matches[2], $matches[3]); - } elseif (preg_match('/^(.*)\:(\d+)$/', $resource, $matches)) { + } elseif (preg_match('/^(.*):(\d+)$/', $resource, $matches)) { $resource = $matches[1]; $filters[] = new LineFilter($matches[2]); } diff --git a/src/Behat/Gherkin/Loader/ArrayLoader.php b/src/Behat/Gherkin/Loader/ArrayLoader.php index 0637478c..eb39264b 100644 --- a/src/Behat/Gherkin/Loader/ArrayLoader.php +++ b/src/Behat/Gherkin/Loader/ArrayLoader.php @@ -43,7 +43,7 @@ public function supports($resource) * * @param mixed $resource Resource to load * - * @return FeatureNode[] + * @return list */ public function load($resource) { @@ -195,7 +195,7 @@ protected function loadOutlineHash(array $hash, $line = 0) /** * Loads steps from provided hash. * - * @return StepNode[] + * @return list */ private function loadStepsHash(array $hash) { diff --git a/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php b/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php index e7748c6b..68781274 100644 --- a/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php +++ b/src/Behat/Gherkin/Loader/CucumberNDJsonAstLoader.php @@ -65,18 +65,18 @@ private static function getFeature(array $json, $filePath) } /** - * @return string[] + * @return list */ private static function getTags(array $json) { return array_map( - static function (array $tag) { return preg_replace('/^@/', '', $tag['name']); }, - isset($json['tags']) ? $json['tags'] : [] + static fn (array $tag) => preg_replace('/^@/', '', $tag['name']), + array_values($json['tags'] ?? []) ); } /** - * @return ScenarioInterface[] + * @return list */ private static function getScenarios(array $json) { @@ -85,25 +85,25 @@ private static function getScenarios(array $json) static function ($child) { if ($child['scenario']['examples']) { return new OutlineNode( - isset($child['scenario']['name']) ? $child['scenario']['name'] : null, + $child['scenario']['name'] ?? null, self::getTags($child['scenario']), - self::getSteps(isset($child['scenario']['steps']) ? $child['scenario']['steps'] : []), + self::getSteps($child['scenario']['steps'] ?? []), self::getTables($child['scenario']['examples']), $child['scenario']['keyword'], $child['scenario']['location']['line'] ); - } else { - return new ScenarioNode( - $child['scenario']['name'], - self::getTags($child['scenario']), - self::getSteps(isset($child['scenario']['steps']) ? $child['scenario']['steps'] : []), - $child['scenario']['keyword'], - $child['scenario']['location']['line'] - ); } + + return new ScenarioNode( + $child['scenario']['name'], + self::getTags($child['scenario']), + self::getSteps($child['scenario']['steps'] ?? []), + $child['scenario']['keyword'], + $child['scenario']['location']['line'] + ); }, array_filter( - isset($json['children']) ? $json['children'] : [], + $json['children'] ?? [], static function ($child) { return isset($child['scenario']); } @@ -112,75 +112,56 @@ static function ($child) { ); } - /** - * @return BackgroundNode|null - */ - private static function getBackground(array $json) + private static function getBackground(array $json): ?BackgroundNode { $backgrounds = array_values( array_map( - static function ($child) { - return new BackgroundNode( - $child['background']['name'], - self::getSteps(isset($child['background']['steps']) ? $child['background']['steps'] : []), - $child['background']['keyword'], - $child['background']['location']['line'] - ); - }, + static fn ($child) => new BackgroundNode( + $child['background']['name'], + self::getSteps($child['background']['steps'] ?? []), + $child['background']['keyword'], + $child['background']['location']['line'] + ), array_filter( - isset($json['children']) ? $json['children'] : [], - static function ($child) { - return isset($child['background']); - } + $json['children'] ?? [], + static fn ($child) => isset($child['background']), ) ) ); - return count($backgrounds) == 1 ? $backgrounds[0] : null; + return count($backgrounds) === 1 ? $backgrounds[0] : null; } /** - * @return StepNode[] + * @return list */ - private static function getSteps(array $json) + private static function getSteps(array $items): array { return array_map( - static function (array $json) { - return new StepNode( - trim($json['keyword']), - $json['text'], - [], - $json['location']['line'], - trim($json['keyword']) - ); - }, - $json + static fn (array $item) => new StepNode( + trim($item['keyword']), + $item['text'], + [], + $item['location']['line'], + trim($item['keyword']) + ), + array_values($items) ); } /** - * @return ExampleTableNode[] + * @return list */ - private static function getTables(array $json) + private static function getTables(array $items): array { return array_map( static function ($tableJson) { $table = []; - $table[$tableJson['tableHeader']['location']['line']] = array_map( - static function ($cell) { - return $cell['value']; - }, - $tableJson['tableHeader']['cells'] - ); + $table[$tableJson['tableHeader']['location']['line']] = array_column($tableJson['tableHeader']['cells'], 'value'); foreach ($tableJson['tableBody'] as $bodyRow) { - $table[$bodyRow['location']['line']] = array_map( - static function ($cell) { - return $cell['value']; - }, - $bodyRow['cells'] - ); + $table[$bodyRow['location']['line']] = array_column($bodyRow['cells'], 'value'); } return new ExampleTableNode( @@ -189,7 +170,7 @@ static function ($cell) { self::getTags($tableJson) ); }, - $json + array_values($items) ); } } diff --git a/src/Behat/Gherkin/Loader/DirectoryLoader.php b/src/Behat/Gherkin/Loader/DirectoryLoader.php index 237b8a86..84778c2a 100644 --- a/src/Behat/Gherkin/Loader/DirectoryLoader.php +++ b/src/Behat/Gherkin/Loader/DirectoryLoader.php @@ -35,32 +35,32 @@ public function __construct(Gherkin $gherkin) /** * Checks if current loader supports provided resource. * - * @param mixed $path Resource to load + * @param mixed $resource Resource to load * * @return bool */ - public function supports($path) + public function supports($resource) { - return is_string($path) - && is_dir($this->findAbsolutePath($path)); + return is_string($resource) + && is_dir($this->findAbsolutePath($resource)); } /** * Loads features from provided resource. * - * @param string $path Resource to load + * @param string $resource Resource to load * - * @return FeatureNode[] + * @return list */ - public function load($path) + public function load($resource) { - $path = $this->findAbsolutePath($path); + $path = $this->findAbsolutePath($resource); $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS) ); - $paths = array_map('strval', iterator_to_array($iterator)); - uasort($paths, 'strnatcasecmp'); + $paths = array_map(strval(...), iterator_to_array($iterator)); + uasort($paths, strnatcasecmp(...)); $features = []; @@ -69,7 +69,7 @@ public function load($path) $loader = $this->gherkin->resolveLoader($path); if ($loader !== null) { - $features = array_merge($features, $loader->load($path)); + array_push($features, ...$loader->load($path)); } } diff --git a/src/Behat/Gherkin/Loader/GherkinFileLoader.php b/src/Behat/Gherkin/Loader/GherkinFileLoader.php index c7dfb007..11e0870b 100644 --- a/src/Behat/Gherkin/Loader/GherkinFileLoader.php +++ b/src/Behat/Gherkin/Loader/GherkinFileLoader.php @@ -49,27 +49,27 @@ public function setCache(CacheInterface $cache) /** * Checks if current loader supports provided resource. * - * @param mixed $path Resource to load + * @param mixed $resource Resource to load * * @return bool */ - public function supports($path) + public function supports($resource) { - return is_string($path) - && is_file($absolute = $this->findAbsolutePath($path)) + return is_string($resource) + && is_file($absolute = $this->findAbsolutePath($resource)) && pathinfo($absolute, PATHINFO_EXTENSION) === 'feature'; } /** * Loads features from provided resource. * - * @param string $path Resource to load + * @param string $resource Resource to load * - * @return FeatureNode[] + * @return list */ - public function load($path) + public function load($resource) { - $path = $this->findAbsolutePath($path); + $path = $this->findAbsolutePath($resource); if ($this->cache) { if ($this->cache->isFresh($path, filemtime($path))) { @@ -94,8 +94,7 @@ public function load($path) protected function parseFeature($path) { $content = file_get_contents($path); - $feature = $this->parser->parse($content, $path); - return $feature; + return $this->parser->parse($content, $path); } } diff --git a/src/Behat/Gherkin/Loader/LoaderInterface.php b/src/Behat/Gherkin/Loader/LoaderInterface.php index 298dc5dd..eae74a50 100644 --- a/src/Behat/Gherkin/Loader/LoaderInterface.php +++ b/src/Behat/Gherkin/Loader/LoaderInterface.php @@ -33,7 +33,7 @@ public function supports($resource); * * @param mixed $resource Resource to load * - * @return FeatureNode[] + * @return list */ public function load($resource); } diff --git a/src/Behat/Gherkin/Loader/YamlFileLoader.php b/src/Behat/Gherkin/Loader/YamlFileLoader.php index ee392647..5dd4d42c 100644 --- a/src/Behat/Gherkin/Loader/YamlFileLoader.php +++ b/src/Behat/Gherkin/Loader/YamlFileLoader.php @@ -30,33 +30,33 @@ public function __construct() /** * Checks if current loader supports provided resource. * - * @param mixed $path Resource to load + * @param mixed $resource Resource to load * * @return bool */ - public function supports($path) + public function supports($resource) { - return is_string($path) - && is_file($absolute = $this->findAbsolutePath($path)) + return is_string($resource) + && is_file($absolute = $this->findAbsolutePath($resource)) && pathinfo($absolute, PATHINFO_EXTENSION) === 'yml'; } /** * Loads features from provided resource. * - * @param string $path Resource to load + * @param string $resource Resource to load * - * @return FeatureNode[] + * @return list */ - public function load($path) + public function load($resource) { - $path = $this->findAbsolutePath($path); + $path = $this->findAbsolutePath($resource); $hash = Yaml::parse(file_get_contents($path)); $features = $this->loader->load($hash); - return array_map(function (FeatureNode $feature) use ($path) { - return new FeatureNode( + return array_map( + static fn (FeatureNode $feature) => new FeatureNode( $feature->getTitle(), $feature->getDescription(), $feature->getTags(), @@ -66,7 +66,8 @@ public function load($path) $feature->getLanguage(), $path, $feature->getLine() - ); - }, $features); + ), + $features + ); } } diff --git a/src/Behat/Gherkin/Node/BackgroundNode.php b/src/Behat/Gherkin/Node/BackgroundNode.php index 42969f4a..cd5b2e0f 100644 --- a/src/Behat/Gherkin/Node/BackgroundNode.php +++ b/src/Behat/Gherkin/Node/BackgroundNode.php @@ -22,7 +22,7 @@ class BackgroundNode implements ScenarioLikeInterface */ private $title; /** - * @var StepNode[] + * @var list */ private $steps = []; /** @@ -38,14 +38,14 @@ class BackgroundNode implements ScenarioLikeInterface * Initializes background. * * @param string|null $title - * @param StepNode[] $steps + * @param array $steps * @param string $keyword * @param int $line */ public function __construct($title, array $steps, $keyword, $line) { $this->title = $title; - $this->steps = $steps; + $this->steps = array_values($steps); $this->keyword = $keyword; $this->line = $line; } @@ -83,7 +83,7 @@ public function hasSteps() /** * Returns background steps. * - * @return StepNode[] + * @return list */ public function getSteps() { diff --git a/src/Behat/Gherkin/Node/ExampleNode.php b/src/Behat/Gherkin/Node/ExampleNode.php index f11af793..ad8798e3 100644 --- a/src/Behat/Gherkin/Node/ExampleNode.php +++ b/src/Behat/Gherkin/Node/ExampleNode.php @@ -22,15 +22,15 @@ class ExampleNode implements ScenarioInterface, NamedScenarioInterface */ private $text; /** - * @var string[] + * @var list */ private $tags; /** - * @var StepNode[] + * @var list */ private $outlineSteps; /** - * @var string[] + * @var array */ private $tokens; /** @@ -38,7 +38,7 @@ class ExampleNode implements ScenarioInterface, NamedScenarioInterface */ private $line; /** - * @var StepNode[]|null + * @var list|null */ private $steps; /** @@ -54,9 +54,9 @@ class ExampleNode implements ScenarioInterface, NamedScenarioInterface * Initializes outline. * * @param string $text The entire row as a string, e.g. "| 1 | 2 | 3 |" - * @param string[] $tags - * @param StepNode[] $outlineSteps - * @param string[] $tokens + * @param array $tags + * @param array $outlineSteps + * @param array $tokens * @param int $line line number within the feature file * @param string|null $outlineTitle original title of the scenario outline * @param int|null $index the 1-based index of the row/example within the scenario outline @@ -64,8 +64,8 @@ class ExampleNode implements ScenarioInterface, NamedScenarioInterface public function __construct($text, array $tags, $outlineSteps, array $tokens, $line, $outlineTitle = null, $index = null) { $this->text = $text; - $this->tags = $tags; - $this->outlineSteps = $outlineSteps; + $this->tags = array_values($tags); + $this->outlineSteps = array_values($outlineSteps); $this->tokens = $tokens; $this->line = $line; $this->outlineTitle = $outlineTitle; @@ -130,7 +130,7 @@ public function hasTags() /** * Returns outline tags (including inherited from feature). * - * @return string[] + * @return list */ public function getTags() { @@ -150,7 +150,7 @@ public function hasSteps() /** * Returns outline steps. * - * @return StepNode[] + * @return list */ public function getSteps() { @@ -160,7 +160,7 @@ public function getSteps() /** * Returns example tokens. * - * @return string[] + * @return list */ public function getTokens() { @@ -207,7 +207,7 @@ public function getExampleText(): string /** * Creates steps for this example from abstract outline steps. * - * @return StepNode[] + * @return list */ protected function createExampleSteps() { @@ -228,9 +228,9 @@ protected function createExampleSteps() /** * Replaces tokens in arguments with row values. * - * @param ArgumentInterface[] $arguments + * @param array $arguments * - * @return ArgumentInterface[] + * @return array */ protected function replaceArgumentsTokens(array $arguments) { diff --git a/src/Behat/Gherkin/Node/ExampleTableNode.php b/src/Behat/Gherkin/Node/ExampleTableNode.php index 9b3dff4a..fe2ee52f 100644 --- a/src/Behat/Gherkin/Node/ExampleTableNode.php +++ b/src/Behat/Gherkin/Node/ExampleTableNode.php @@ -18,7 +18,7 @@ class ExampleTableNode extends TableNode { /** - * @var string[] + * @var list */ private $tags; @@ -32,7 +32,7 @@ class ExampleTableNode extends TableNode * * @param array $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]] * @param string $keyword - * @param string[] $tags + * @param list $tags */ public function __construct(array $table, $keyword, array $tags = []) { @@ -55,7 +55,7 @@ public function getNodeType() /** * Returns attached tags. * - * @return string[] + * @return list */ public function getTags() { diff --git a/src/Behat/Gherkin/Node/FeatureNode.php b/src/Behat/Gherkin/Node/FeatureNode.php index 21fb866c..165222f1 100644 --- a/src/Behat/Gherkin/Node/FeatureNode.php +++ b/src/Behat/Gherkin/Node/FeatureNode.php @@ -26,7 +26,7 @@ class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface */ private $description; /** - * @var string[] + * @var list */ private $tags = []; /** @@ -34,7 +34,7 @@ class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface */ private $background; /** - * @var ScenarioInterface[] + * @var list */ private $scenarios = []; /** @@ -59,8 +59,8 @@ class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface * * @param string|null $title * @param string|null $description - * @param string[] $tags - * @param ScenarioInterface[] $scenarios + * @param list $tags + * @param list $scenarios * @param string $keyword * @param string $language * @param string|null $file the absolute path to the feature file @@ -83,9 +83,9 @@ public function __construct( } $this->title = $title; $this->description = $description; - $this->tags = $tags; + $this->tags = array_values($tags); $this->background = $background; - $this->scenarios = $scenarios; + $this->scenarios = array_values($scenarios); $this->keyword = $keyword; $this->language = $language; $this->file = $file; @@ -157,7 +157,7 @@ public function hasTags() /** * Returns feature tags. * - * @return string[] + * @return list */ public function getTags() { @@ -197,7 +197,7 @@ public function hasScenarios() /** * Returns feature scenarios. * - * @return ScenarioInterface[] + * @return list */ public function getScenarios() { diff --git a/src/Behat/Gherkin/Node/OutlineNode.php b/src/Behat/Gherkin/Node/OutlineNode.php index 9ce174e2..1fff4796 100644 --- a/src/Behat/Gherkin/Node/OutlineNode.php +++ b/src/Behat/Gherkin/Node/OutlineNode.php @@ -22,15 +22,15 @@ class OutlineNode implements ScenarioInterface */ private $title; /** - * @var string[] + * @var list */ private $tags; /** - * @var StepNode[] + * @var list */ private $steps; /** - * @var ExampleTableNode|ExampleTableNode[] + * @var ExampleTableNode|list */ private $tables; /** @@ -42,7 +42,7 @@ class OutlineNode implements ScenarioInterface */ private $line; /** - * @var ExampleNode[]|null + * @var list|null */ private $examples; @@ -50,9 +50,9 @@ class OutlineNode implements ScenarioInterface * Initializes outline. * * @param string|null $title - * @param string[] $tags - * @param StepNode[] $steps - * @param ExampleTableNode|ExampleTableNode[] $tables + * @param list $tags + * @param list $steps + * @param ExampleTableNode|list $tables * @param string $keyword * @param int $line */ @@ -65,14 +65,14 @@ public function __construct( $line, ) { $this->title = $title; - $this->tags = $tags; - $this->steps = $steps; + $this->tags = array_values($tags); + $this->steps = array_values($steps); $this->keyword = $keyword; $this->line = $line; if (!is_array($tables)) { $this->tables = [$tables]; } else { - $this->tables = $tables; + $this->tables = array_values($tables); } } @@ -121,7 +121,7 @@ public function hasTags() /** * Returns outline tags (including inherited from feature). * - * @return string[] + * @return list */ public function getTags() { @@ -141,7 +141,7 @@ public function hasSteps() /** * Returns outline steps. * - * @return StepNode[] + * @return list */ public function getSteps() { @@ -186,7 +186,7 @@ public function getExampleTable() /** * Returns list of examples for the outline. * - * @return ExampleNode[] + * @return list */ public function getExamples() { @@ -196,7 +196,7 @@ public function getExamples() /** * Returns examples tables array for the outline. * - * @return ExampleTableNode[] + * @return list */ public function getExampleTables() { @@ -226,7 +226,7 @@ public function getLine() /** * Creates examples for this outline using examples table. * - * @return ExampleNode[] + * @return list */ protected function createExamples() { diff --git a/src/Behat/Gherkin/Node/ScenarioNode.php b/src/Behat/Gherkin/Node/ScenarioNode.php index 503413c6..0a67cb71 100644 --- a/src/Behat/Gherkin/Node/ScenarioNode.php +++ b/src/Behat/Gherkin/Node/ScenarioNode.php @@ -26,7 +26,7 @@ class ScenarioNode implements ScenarioInterface, NamedScenarioInterface */ private $tags = []; /** - * @var StepNode[] + * @var list */ private $steps = []; /** @@ -42,15 +42,15 @@ class ScenarioNode implements ScenarioInterface, NamedScenarioInterface * Initializes scenario. * * @param string|null $title - * @param StepNode[] $steps + * @param list $steps * @param string $keyword * @param int $line */ public function __construct($title, array $tags, array $steps, $keyword, $line) { $this->title = $title; - $this->tags = $tags; - $this->steps = $steps; + $this->tags = array_values($tags); + $this->steps = array_values($steps); $this->keyword = $keyword; $this->line = $line; } @@ -128,7 +128,7 @@ public function hasSteps() /** * Returns scenario steps. * - * @return StepNode[] + * @return list */ public function getSteps() { diff --git a/src/Behat/Gherkin/Node/StepContainerInterface.php b/src/Behat/Gherkin/Node/StepContainerInterface.php index 02d604eb..33e40367 100644 --- a/src/Behat/Gherkin/Node/StepContainerInterface.php +++ b/src/Behat/Gherkin/Node/StepContainerInterface.php @@ -27,7 +27,7 @@ public function hasSteps(); /** * Returns container steps. * - * @return StepNode[] + * @return list */ public function getSteps(); } diff --git a/src/Behat/Gherkin/Node/StepNode.php b/src/Behat/Gherkin/Node/StepNode.php index 4c57200e..c785e376 100644 --- a/src/Behat/Gherkin/Node/StepNode.php +++ b/src/Behat/Gherkin/Node/StepNode.php @@ -32,7 +32,7 @@ class StepNode implements NodeInterface */ private $text; /** - * @var ArgumentInterface[] + * @var list */ private $arguments = []; /** @@ -45,7 +45,7 @@ class StepNode implements NodeInterface * * @param string $keyword * @param string $text - * @param ArgumentInterface[] $arguments + * @param list $arguments * @param int $line * @param string $keywordType */ @@ -127,7 +127,7 @@ public function hasArguments() /** * Returns step arguments. * - * @return ArgumentInterface[] + * @return list */ public function getArguments() { diff --git a/src/Behat/Gherkin/Node/TaggedNodeInterface.php b/src/Behat/Gherkin/Node/TaggedNodeInterface.php index c313aadb..717af1c6 100644 --- a/src/Behat/Gherkin/Node/TaggedNodeInterface.php +++ b/src/Behat/Gherkin/Node/TaggedNodeInterface.php @@ -36,7 +36,7 @@ public function hasTags(); /** * Returns node tags (including inherited from feature). * - * @return string[] + * @return list */ public function getTags(); } diff --git a/src/Behat/Gherkin/Parser.php b/src/Behat/Gherkin/Parser.php index 35fcb089..314c60fb 100644 --- a/src/Behat/Gherkin/Parser.php +++ b/src/Behat/Gherkin/Parser.php @@ -223,7 +223,7 @@ protected function parseFeature() $file = $this->file; $line = $token['line']; - array_push($this->passedNodesStack, 'Feature'); + $this->passedNodesStack[] = 'Feature'; // Parse description, background, scenarios & outlines while ($this->predictTokenType() !== 'EOS') { @@ -335,7 +335,7 @@ protected function parseScenario() $keyword = $token['keyword']; $line = $token['line']; - array_push($this->passedNodesStack, 'Scenario'); + $this->passedNodesStack[] = 'Scenario'; // Parse description and steps $steps = []; @@ -393,7 +393,7 @@ protected function parseOutline() // Parse description, steps and examples $steps = []; - array_push($this->passedNodesStack, 'Outline'); + $this->passedNodesStack[] = 'Outline'; while (in_array($nextTokenType = $this->predictTokenType(), ['Step', 'Examples', 'Newline', 'Text', 'Comment', 'Tag'])) { if ($nextTokenType === 'Comment') { @@ -454,7 +454,7 @@ protected function parseStep() $text = trim($token['text']); $line = $token['line']; - array_push($this->passedNodesStack, 'Step'); + $this->passedNodesStack[] = 'Step'; $arguments = []; while (in_array($predicted = $this->predictTokenType(), ['PyStringOp', 'TableRow', 'Newline', 'Comment'])) { @@ -582,7 +582,7 @@ protected function popTags() /** * Checks the tags fit the required format. * - * @param string[] $tags + * @param array $tags */ protected function guardTags(array $tags) { @@ -641,7 +641,7 @@ protected function parseLanguage() /** * Parses the rows of a table. * - * @return string[][] + * @return array> */ private function parseTableRows() { @@ -663,7 +663,7 @@ private function parseTableRows() /** * Changes step node type for types But, And to type of previous step if it exists else sets to Given. * - * @param StepNode[] $steps + * @param list $steps * * @return StepNode */ diff --git a/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php b/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php index 01471981..5e795ada 100644 --- a/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php +++ b/tests/Behat/Gherkin/Loader/ArrayLoaderTest.php @@ -11,7 +11,6 @@ namespace Tests\Behat\Gherkin\Loader; use Behat\Gherkin\Loader\ArrayLoader; -use Behat\Gherkin\Node\OutlineNode; use PHPUnit\Framework\TestCase; class ArrayLoaderTest extends TestCase @@ -184,7 +183,6 @@ public function testOutlineExamples() $this->assertEquals(1, count($features)); - /** @var OutlineNode[] $scenarios */ $scenarios = $features[0]->getScenarios(); $scenario = $scenarios[0]; From 402b7517b8e4c6f57fac802ea06a1fb66ed64fdf Mon Sep 17 00:00:00 2001 From: Christian Sciberras Date: Sat, 7 Dec 2024 18:02:29 +0100 Subject: [PATCH 5/5] Initial PHPStan setup --- .gitattributes | 2 ++ .github/workflows/build.yml | 24 ++++++++++++++++++++++++ .gitignore | 1 + composer.json | 9 +++++++-- phpstan.dist.neon | 6 ++++++ src/Behat/Gherkin/Parser.php | 3 +++ 6 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 phpstan.dist.neon diff --git a/.gitattributes b/.gitattributes index d706a454..86707809 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,3 +7,5 @@ /CONTRIBUTING.md export-ignore /phpunit.dist.xml export-ignore /.php-cs-fixer.dist.php export-ignore +/phpstan.dist.neon export-ignore +/phpstan-baseline.neon export-ignore diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 73745808..f107692e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,17 @@ on: types: [ created ] jobs: + check_composer: + name: Check composer.json + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + coverage: none + php-version: '8.3' + - run: composer validate --strict --no-check-lock + check_code_style: name: Check code style runs-on: ubuntu-latest @@ -24,6 +35,19 @@ jobs: - run: ./vendor/bin/php-cs-fixer fix --dry-run --diff --show-progress=dots + static_analysis: + name: Static analysis + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + coverage: none + php-version: '8.3' + - name: Install dependencies + run: composer update + - run: ./vendor/bin/phpstan analyze + tests: runs-on: ubuntu-latest name: Build and test diff --git a/.gitignore b/.gitignore index 7c409b70..7f5eea4d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ composer.lock phpunit.xml .php-cs-fixer.php .php-cs-fixer.cache +phpstan.neon diff --git a/composer.json b/composer.json index 218f6e89..12752e05 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,10 @@ "symfony/yaml": "^5.4 || ^6.4 || ^7.0", "phpunit/phpunit": "^10.5", "cucumber/cucumber": "dev-gherkin-24.1.0", - "friendsofphp/php-cs-fixer": "^3.65" + "friendsofphp/php-cs-fixer": "^3.65", + "phpstan/phpstan": "^2", + "phpstan/extension-installer": "^1", + "phpstan/phpstan-phpunit": "^2" }, "suggest": { @@ -69,6 +72,7 @@ "scripts": { "lint": [ "Composer\\Config::disableProcessTimeout", + "vendor/bin/phpstan analyse --no-progress --memory-limit 512M", "vendor/bin/php-cs-fixer fix --dry-run --diff --show-progress=dots" ], "test": [ @@ -80,9 +84,10 @@ "vendor/bin/php-cs-fixer fix --diff --show-progress=dots" ] }, + "config": { "allow-plugins": { - "phpstan/extension-installer": false + "phpstan/extension-installer": true } } } diff --git a/phpstan.dist.neon b/phpstan.dist.neon new file mode 100644 index 00000000..c7a33b2d --- /dev/null +++ b/phpstan.dist.neon @@ -0,0 +1,6 @@ +parameters: + level: 0 + paths: + - bin + - src + - tests diff --git a/src/Behat/Gherkin/Parser.php b/src/Behat/Gherkin/Parser.php index 314c60fb..d6c6c300 100644 --- a/src/Behat/Gherkin/Parser.php +++ b/src/Behat/Gherkin/Parser.php @@ -688,6 +688,9 @@ private function normalizeStepNodeKeywordType(StepNode $node, array $steps = []) return $node; } + /** + * @return no-return + */ private function rethrowNodeException(NodeException $e): void { throw new ParserException($e->getMessage() . ($this->file ? ' in file ' . $this->file : ''), 0, $e);