init
This commit is contained in:
48
vendor/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php
vendored
Normal file
48
vendor/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Cache;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Parser cache interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFresh($path, $timestamp);
|
||||
|
||||
/**
|
||||
* Reads feature cache from path.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function read($path);
|
||||
|
||||
/**
|
||||
* Caches feature node.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*/
|
||||
public function write($path, FeatureNode $feature);
|
||||
}
|
||||
109
vendor/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php
vendored
Normal file
109
vendor/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Cache;
|
||||
|
||||
use Behat\Gherkin\Exception\CacheException;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Gherkin;
|
||||
|
||||
/**
|
||||
* File cache.
|
||||
* Caches feature into a file.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class FileCache implements CacheInterface
|
||||
{
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* Initializes file cache.
|
||||
*
|
||||
* @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;
|
||||
|
||||
if (!is_dir($this->path)) {
|
||||
@mkdir($this->path, 0777, true);
|
||||
}
|
||||
|
||||
if (!is_writeable($this->path)) {
|
||||
throw new CacheException(sprintf('Cache path "%s" is not writeable. Check your filesystem permissions or disable Gherkin file cache.', $this->path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that cache for feature exists and is fresh.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
* @param integer $timestamp The last time feature was updated
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFresh($path, $timestamp)
|
||||
{
|
||||
$cachePath = $this->getCachePathFor($path);
|
||||
|
||||
if (!file_exists($cachePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return filemtime($cachePath) > $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads feature cache from path.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
*
|
||||
* @return FeatureNode
|
||||
*
|
||||
* @throws CacheException
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
$cachePath = $this->getCachePathFor($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 ));
|
||||
}
|
||||
|
||||
return $feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches feature node.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*/
|
||||
public function write($path, FeatureNode $feature)
|
||||
{
|
||||
file_put_contents($this->getCachePathFor($path), serialize($feature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature cache file path from features path.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCachePathFor($path)
|
||||
{
|
||||
return $this->path.'/'.md5($path).'.feature.cache';
|
||||
}
|
||||
}
|
||||
66
vendor/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php
vendored
Normal file
66
vendor/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Cache;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Memory cache.
|
||||
* Caches feature into a memory.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class MemoryCache implements CacheInterface
|
||||
{
|
||||
private $features = array();
|
||||
private $timestamps = array();
|
||||
|
||||
/**
|
||||
* Checks that cache for feature exists and is fresh.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
* @param integer $timestamp The last time feature was updated
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFresh($path, $timestamp)
|
||||
{
|
||||
if (!isset($this->features[$path])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->timestamps[$path] > $timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads feature cache from path.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function read($path)
|
||||
{
|
||||
return $this->features[$path];
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches feature node.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*/
|
||||
public function write($path, FeatureNode $feature)
|
||||
{
|
||||
$this->features[$path] = $feature;
|
||||
$this->timestamps[$path] = time();
|
||||
}
|
||||
}
|
||||
22
vendor/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php
vendored
Normal file
22
vendor/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Cache exception.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class CacheException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
15
vendor/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php
vendored
Normal file
15
vendor/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Exception;
|
||||
|
||||
interface Exception
|
||||
{
|
||||
}
|
||||
17
vendor/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php
vendored
Normal file
17
vendor/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class LexerException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
17
vendor/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php
vendored
Normal file
17
vendor/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class NodeException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
17
vendor/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php
vendored
Normal file
17
vendor/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ParserException extends RuntimeException implements Exception
|
||||
{
|
||||
}
|
||||
52
vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php
vendored
Normal file
52
vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Abstract filter class.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
abstract class ComplexFilter implements ComplexFilterInterface
|
||||
{
|
||||
/**
|
||||
* Filters feature according to the filter.
|
||||
*
|
||||
* @param FeatureNode $feature
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function filterFeature(FeatureNode $feature)
|
||||
{
|
||||
$scenarios = array();
|
||||
foreach ($feature->getScenarios() as $scenario) {
|
||||
if (!$this->isScenarioMatch($feature, $scenario)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$scenarios[] = $scenario;
|
||||
}
|
||||
|
||||
return new FeatureNode(
|
||||
$feature->getTitle(),
|
||||
$feature->getDescription(),
|
||||
$feature->getTags(),
|
||||
$feature->getBackground(),
|
||||
$scenarios,
|
||||
$feature->getKeyword(),
|
||||
$feature->getLanguage(),
|
||||
$feature->getFile(),
|
||||
$feature->getLine()
|
||||
);
|
||||
}
|
||||
}
|
||||
32
vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php
vendored
Normal file
32
vendor/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filter interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface ComplexFilterInterface extends FeatureFilterInterface
|
||||
{
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature node instance
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(FeatureNode $feature, ScenarioInterface $scenario);
|
||||
}
|
||||
39
vendor/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php
vendored
Normal file
39
vendor/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Feature filter interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface FeatureFilterInterface
|
||||
{
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
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);
|
||||
}
|
||||
30
vendor/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php
vendored
Normal file
30
vendor/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filter interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface FilterInterface extends FeatureFilterInterface
|
||||
{
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario);
|
||||
}
|
||||
122
vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php
vendored
Normal file
122
vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\ExampleTableNode;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\OutlineNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filters scenarios by definition line number.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class LineFilter implements FilterInterface
|
||||
{
|
||||
protected $filterLine;
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string $filterLine Line of the scenario to filter on
|
||||
*/
|
||||
public function __construct($filterLine)
|
||||
{
|
||||
$this->filterLine = intval($filterLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
return $this->filterLine === $feature->getLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario)
|
||||
{
|
||||
if ($this->filterLine === $scenario->getLine()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
|
||||
return $this->filterLine === $scenario->getLine()
|
||||
|| in_array($this->filterLine, $scenario->getExampleTable()->getLines());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters feature according to the filter and returns new one.
|
||||
*
|
||||
* @param FeatureNode $feature
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function filterFeature(FeatureNode $feature)
|
||||
{
|
||||
$scenarios = array();
|
||||
foreach ($feature->getScenarios() as $scenario) {
|
||||
if (!$this->isScenarioMatch($scenario)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
|
||||
$table = $scenario->getExampleTable()->getTable();
|
||||
$lines = array_keys($table);
|
||||
|
||||
if (in_array($this->filterLine, $lines)) {
|
||||
$filteredTable = array($lines[0] => $table[$lines[0]]);
|
||||
|
||||
if ($lines[0] !== $this->filterLine) {
|
||||
$filteredTable[$this->filterLine] = $table[$this->filterLine];
|
||||
}
|
||||
|
||||
$scenario = new OutlineNode(
|
||||
$scenario->getTitle(),
|
||||
$scenario->getTags(),
|
||||
$scenario->getSteps(),
|
||||
new ExampleTableNode($filteredTable, $scenario->getExampleTable()->getKeyword()),
|
||||
$scenario->getKeyword(),
|
||||
$scenario->getLine()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$scenarios[] = $scenario;
|
||||
}
|
||||
|
||||
return new FeatureNode(
|
||||
$feature->getTitle(),
|
||||
$feature->getDescription(),
|
||||
$feature->getTags(),
|
||||
$feature->getBackground(),
|
||||
$scenarios,
|
||||
$feature->getKeyword(),
|
||||
$feature->getLanguage(),
|
||||
$feature->getFile(),
|
||||
$feature->getLine()
|
||||
);
|
||||
}
|
||||
}
|
||||
134
vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php
vendored
Normal file
134
vendor/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\ExampleTableNode;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\OutlineNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filters scenarios by definition line number range.
|
||||
*
|
||||
* @author Fabian Kiss <headrevision@gmail.com>
|
||||
*/
|
||||
class LineRangeFilter implements FilterInterface
|
||||
{
|
||||
protected $filterMinLine;
|
||||
protected $filterMaxLine;
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string $filterMinLine Minimum line of a scenario to filter on
|
||||
* @param string $filterMaxLine Maximum line of a scenario to filter on
|
||||
*/
|
||||
public function __construct($filterMinLine, $filterMaxLine)
|
||||
{
|
||||
$this->filterMinLine = intval($filterMinLine);
|
||||
if ($filterMaxLine == '*') {
|
||||
$this->filterMaxLine = PHP_INT_MAX;
|
||||
} else {
|
||||
$this->filterMaxLine = intval($filterMaxLine);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
return $this->filterMinLine <= $feature->getLine()
|
||||
&& $this->filterMaxLine >= $feature->getLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario)
|
||||
{
|
||||
if ($this->filterMinLine <= $scenario->getLine() && $this->filterMaxLine >= $scenario->getLine()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
|
||||
foreach ($scenario->getExampleTable()->getLines() as $line) {
|
||||
if ($this->filterMinLine <= $line && $this->filterMaxLine >= $line) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters feature according to the filter.
|
||||
*
|
||||
* @param FeatureNode $feature
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function filterFeature(FeatureNode $feature)
|
||||
{
|
||||
$scenarios = array();
|
||||
foreach ($feature->getScenarios() as $scenario) {
|
||||
if (!$this->isScenarioMatch($scenario)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($scenario instanceof OutlineNode && $scenario->hasExamples()) {
|
||||
$table = $scenario->getExampleTable()->getTable();
|
||||
$lines = array_keys($table);
|
||||
|
||||
$filteredTable = array($lines[0] => $table[$lines[0]]);
|
||||
unset($table[$lines[0]]);
|
||||
|
||||
foreach ($table as $line => $row) {
|
||||
if ($this->filterMinLine <= $line && $this->filterMaxLine >= $line) {
|
||||
$filteredTable[$line] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$scenario = new OutlineNode(
|
||||
$scenario->getTitle(),
|
||||
$scenario->getTags(),
|
||||
$scenario->getSteps(),
|
||||
new ExampleTableNode($filteredTable, $scenario->getExampleTable()->getKeyword()),
|
||||
$scenario->getKeyword(),
|
||||
$scenario->getLine()
|
||||
);
|
||||
}
|
||||
|
||||
$scenarios[] = $scenario;
|
||||
}
|
||||
|
||||
return new FeatureNode(
|
||||
$feature->getTitle(),
|
||||
$feature->getDescription(),
|
||||
$feature->getTags(),
|
||||
$feature->getBackground(),
|
||||
$scenarios,
|
||||
$feature->getKeyword(),
|
||||
$feature->getLanguage(),
|
||||
$feature->getFile(),
|
||||
$feature->getLine()
|
||||
);
|
||||
}
|
||||
}
|
||||
68
vendor/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php
vendored
Normal file
68
vendor/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filters scenarios by feature/scenario name.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class NameFilter extends SimpleFilter
|
||||
{
|
||||
protected $filterString;
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string $filterString Name filter string
|
||||
*/
|
||||
public function __construct($filterString)
|
||||
{
|
||||
$this->filterString = trim($filterString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
if ('/' === $this->filterString[0]) {
|
||||
return 1 === preg_match($this->filterString, $feature->getTitle());
|
||||
}
|
||||
|
||||
return false !== mb_strpos($feature->getTitle(), $this->filterString, 0, 'utf8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario)
|
||||
{
|
||||
if ('/' === $this->filterString[0] && 1 === preg_match($this->filterString, $scenario->getTitle())) {
|
||||
return true;
|
||||
} elseif (false !== mb_strpos($scenario->getTitle(), $this->filterString, 0, 'utf8')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
61
vendor/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php
vendored
Normal file
61
vendor/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Filters features by their narrative using regular expression.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class NarrativeFilter extends SimpleFilter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $regex;
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string $regex
|
||||
*/
|
||||
public function __construct($regex)
|
||||
{
|
||||
$this->regex = $regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
return 1 === preg_match($this->regex, $feature->getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
72
vendor/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php
vendored
Normal file
72
vendor/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filters features by their paths.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class PathsFilter extends SimpleFilter
|
||||
{
|
||||
protected $filterPaths = array();
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string[] $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)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
foreach ($this->filterPaths as $path) {
|
||||
if (0 === strpos(realpath($feature->getFile()), $path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return false This filter is designed to work only with features
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
63
vendor/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php
vendored
Normal file
63
vendor/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filters features by their actors role.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class RoleFilter extends SimpleFilter
|
||||
{
|
||||
protected $pattern;
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string $role Approved role wildcard
|
||||
*/
|
||||
public function __construct($role)
|
||||
{
|
||||
$this->pattern = '/as an? ' . strtr(preg_quote($role, '/'), array(
|
||||
'\*' => '.*',
|
||||
'\?' => '.',
|
||||
'\[' => '[',
|
||||
'\]' => ']'
|
||||
)) . '[$\n]/i';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
return 1 === preg_match($this->pattern, $feature->getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return false This filter is designed to work only with features
|
||||
*/
|
||||
public function isScenarioMatch(ScenarioInterface $scenario)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
56
vendor/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php
vendored
Normal file
56
vendor/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Abstract filter class.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
abstract class SimpleFilter implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* Filters feature according to the filter.
|
||||
*
|
||||
* @param FeatureNode $feature
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function filterFeature(FeatureNode $feature)
|
||||
{
|
||||
if ($this->isFeatureMatch($feature)) {
|
||||
return $feature;
|
||||
}
|
||||
|
||||
$scenarios = array();
|
||||
foreach ($feature->getScenarios() as $scenario) {
|
||||
if (!$this->isScenarioMatch($scenario)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$scenarios[] = $scenario;
|
||||
}
|
||||
|
||||
return new FeatureNode(
|
||||
$feature->getTitle(),
|
||||
$feature->getDescription(),
|
||||
$feature->getTags(),
|
||||
$feature->getBackground(),
|
||||
$scenarios,
|
||||
$feature->getKeyword(),
|
||||
$feature->getLanguage(),
|
||||
$feature->getFile(),
|
||||
$feature->getLine()
|
||||
);
|
||||
}
|
||||
}
|
||||
90
vendor/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php
vendored
Normal file
90
vendor/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Filter;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
|
||||
/**
|
||||
* Filters scenarios by feature/scenario tag.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class TagFilter extends ComplexFilter
|
||||
{
|
||||
protected $filterString;
|
||||
|
||||
/**
|
||||
* Initializes filter.
|
||||
*
|
||||
* @param string $filterString Name filter string
|
||||
*/
|
||||
public function __construct($filterString)
|
||||
{
|
||||
$this->filterString = trim($filterString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Feature matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFeatureMatch(FeatureNode $feature)
|
||||
{
|
||||
return $this->isTagsMatchCondition($feature->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario or outline matches specified filter.
|
||||
*
|
||||
* @param FeatureNode $feature Feature node instance
|
||||
* @param ScenarioInterface $scenario Scenario or Outline node instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isScenarioMatch(FeatureNode $feature, ScenarioInterface $scenario)
|
||||
{
|
||||
return $this->isTagsMatchCondition(array_merge($feature->getTags(), $scenario->getTags()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that node matches condition.
|
||||
*
|
||||
* @param string[] $tags
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
protected function isTagsMatchCondition($tags)
|
||||
{
|
||||
$satisfies = true;
|
||||
|
||||
foreach (explode('&&', $this->filterString) as $andTags) {
|
||||
$satisfiesComma = false;
|
||||
|
||||
foreach (explode(',', $andTags) as $tag) {
|
||||
$tag = str_replace('@', '', trim($tag));
|
||||
|
||||
if ('~' === $tag[0]) {
|
||||
$tag = mb_substr($tag, 1, mb_strlen($tag, 'utf8') - 1, 'utf8');
|
||||
$satisfiesComma = !in_array($tag, $tags) || $satisfiesComma;
|
||||
} else {
|
||||
$satisfiesComma = in_array($tag, $tags) || $satisfiesComma;
|
||||
}
|
||||
}
|
||||
|
||||
$satisfies = (false !== $satisfiesComma && $satisfies && $satisfiesComma) || false;
|
||||
}
|
||||
|
||||
return $satisfies;
|
||||
}
|
||||
}
|
||||
142
vendor/behat/gherkin/src/Behat/Gherkin/Gherkin.php
vendored
Normal file
142
vendor/behat/gherkin/src/Behat/Gherkin/Gherkin.php
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin;
|
||||
|
||||
use Behat\Gherkin\Filter\FeatureFilterInterface;
|
||||
use Behat\Gherkin\Filter\LineFilter;
|
||||
use Behat\Gherkin\Filter\LineRangeFilter;
|
||||
use Behat\Gherkin\Loader\FileLoaderInterface;
|
||||
use Behat\Gherkin\Loader\LoaderInterface;
|
||||
|
||||
/**
|
||||
* Gherkin manager.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class Gherkin
|
||||
{
|
||||
const VERSION = '4.4-dev';
|
||||
|
||||
/**
|
||||
* @var LoaderInterface[]
|
||||
*/
|
||||
protected $loaders = array();
|
||||
/**
|
||||
* @var FeatureFilterInterface[]
|
||||
*/
|
||||
protected $filters = array();
|
||||
|
||||
/**
|
||||
* Adds loader to manager.
|
||||
*
|
||||
* @param LoaderInterface $loader Feature loader
|
||||
*/
|
||||
public function addLoader(LoaderInterface $loader)
|
||||
{
|
||||
$this->loaders[] = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds filter to manager.
|
||||
*
|
||||
* @param FeatureFilterInterface $filter Feature filter
|
||||
*/
|
||||
public function addFilter(FeatureFilterInterface $filter)
|
||||
{
|
||||
$this->filters[] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets filters to the parser.
|
||||
*
|
||||
* @param FeatureFilterInterface[] $filters
|
||||
*/
|
||||
public function setFilters(array $filters)
|
||||
{
|
||||
$this->filters = array();
|
||||
array_map(array($this, 'addFilter'), $filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets base features path.
|
||||
*
|
||||
* @param string $path Loaders base path
|
||||
*/
|
||||
public function setBasePath($path)
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
if ($loader instanceof FileLoaderInterface) {
|
||||
$loader->setBasePath($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads & filters resource with added loaders.
|
||||
*
|
||||
* @param mixed $resource Resource to load
|
||||
* @param FeatureFilterInterface[] $filters Additional filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function load($resource, array $filters = array())
|
||||
{
|
||||
$filters = array_merge($this->filters, $filters);
|
||||
|
||||
$matches = array();
|
||||
if (preg_match('/^(.*)\:(\d+)-(\d+|\*)$/', $resource, $matches)) {
|
||||
$resource = $matches[1];
|
||||
$filters[] = new LineRangeFilter($matches[2], $matches[3]);
|
||||
} elseif (preg_match('/^(.*)\:(\d+)$/', $resource, $matches)) {
|
||||
$resource = $matches[1];
|
||||
$filters[] = new LineFilter($matches[2]);
|
||||
}
|
||||
|
||||
$loader = $this->resolveLoader($resource);
|
||||
|
||||
if (null === $loader) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$features = array();
|
||||
foreach ($loader->load($resource) as $feature) {
|
||||
foreach ($filters as $filter) {
|
||||
$feature = $filter->filterFeature($feature);
|
||||
|
||||
if (!$feature->hasScenarios() && !$filter->isFeatureMatch($feature)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
$features[] = $feature;
|
||||
}
|
||||
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves loader by resource.
|
||||
*
|
||||
* @param mixed $resource Resource to load
|
||||
*
|
||||
* @return LoaderInterface
|
||||
*/
|
||||
public function resolveLoader($resource)
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
if ($loader->supports($resource)) {
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
200
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php
vendored
Normal file
200
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Keywords;
|
||||
|
||||
/**
|
||||
* Array initializable keywords holder.
|
||||
*
|
||||
* $keywords = new Behat\Gherkin\Keywords\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' => 'Но'
|
||||
* )
|
||||
* ));
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class ArrayKeywords implements KeywordsInterface
|
||||
{
|
||||
private $keywords = array();
|
||||
private $keywordString = array();
|
||||
private $language;
|
||||
|
||||
/**
|
||||
* Initializes holder with keywords.
|
||||
*
|
||||
* @param array $keywords Keywords array
|
||||
*/
|
||||
public function __construct(array $keywords)
|
||||
{
|
||||
$this->keywords = $keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets keywords holder language.
|
||||
*
|
||||
* @param string $language Language name
|
||||
*/
|
||||
public function setLanguage($language)
|
||||
{
|
||||
if (!isset($this->keywords[$language])) {
|
||||
$this->language = 'en';
|
||||
} else {
|
||||
$this->language = $language;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Feature keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFeatureKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['feature'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Background keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBackgroundKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['background'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Scenario keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScenarioKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['scenario'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Scenario Outline keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOutlineKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['scenario_outline'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Examples keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExamplesKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['examples'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Given keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGivenKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['given'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns When keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWhenKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['when'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Then keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getThenKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['then'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns And keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAndKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['and'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns But keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getButKeywords()
|
||||
{
|
||||
return $this->keywords[$this->language]['but'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all step keywords (Given, When, Then, And, But).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStepKeywords()
|
||||
{
|
||||
if (!isset($this->keywordString[$this->language])) {
|
||||
$keywords = array_merge(
|
||||
explode('|', $this->getGivenKeywords()),
|
||||
explode('|', $this->getWhenKeywords()),
|
||||
explode('|', $this->getThenKeywords()),
|
||||
explode('|', $this->getAndKeywords()),
|
||||
explode('|', $this->getButKeywords())
|
||||
);
|
||||
|
||||
usort($keywords, function ($keyword1, $keyword2) {
|
||||
return mb_strlen($keyword2, 'utf8') - mb_strlen($keyword1, 'utf8');
|
||||
});
|
||||
|
||||
$this->keywordString[$this->language] = implode('|', $keywords);
|
||||
}
|
||||
|
||||
return $this->keywordString[$this->language];
|
||||
}
|
||||
}
|
||||
31
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php
vendored
Normal file
31
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Keywords;
|
||||
|
||||
/**
|
||||
* File initializable keywords holder.
|
||||
*
|
||||
* $keywords = new Behat\Gherkin\Keywords\CachedArrayKeywords($file);
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class CachedArrayKeywords extends ArrayKeywords
|
||||
{
|
||||
/**
|
||||
* Initializes holder with file.
|
||||
*
|
||||
* @param string $file Cached array path
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
parent::__construct(include($file));
|
||||
}
|
||||
}
|
||||
121
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php
vendored
Normal file
121
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Keywords;
|
||||
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Cucumber-translations reader.
|
||||
*
|
||||
* $keywords = new Behat\Gherkin\Keywords\CucumberKeywords($i18nYmlPath);
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class CucumberKeywords extends ArrayKeywords
|
||||
{
|
||||
/**
|
||||
* Initializes holder with yaml string OR file.
|
||||
*
|
||||
* @param string $yaml Yaml string or file path
|
||||
*/
|
||||
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)) {
|
||||
throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $yaml));
|
||||
}
|
||||
|
||||
$file = $yaml;
|
||||
$yaml = file_get_contents($file);
|
||||
}
|
||||
|
||||
try {
|
||||
$content = Yaml::parse($yaml);
|
||||
} catch (ParseException $e) {
|
||||
if ($file) {
|
||||
$e->setParsedFile($file);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
parent::__construct($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Feature keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGivenKeywords()
|
||||
{
|
||||
return $this->prepareStepString(parent::getGivenKeywords());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns When keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWhenKeywords()
|
||||
{
|
||||
return $this->prepareStepString(parent::getWhenKeywords());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Then keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getThenKeywords()
|
||||
{
|
||||
return $this->prepareStepString(parent::getThenKeywords());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns And keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAndKeywords()
|
||||
{
|
||||
return $this->prepareStepString(parent::getAndKeywords());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns But keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getButKeywords()
|
||||
{
|
||||
return $this->prepareStepString(parent::getButKeywords());
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim *| from the begining of the list.
|
||||
*
|
||||
* @param string $keywordsString Keywords string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function prepareStepString($keywordsString)
|
||||
{
|
||||
if (0 === mb_strpos($keywordsString, '*|', 0, 'UTF-8')) {
|
||||
$keywordsString = mb_substr($keywordsString, 2, mb_strlen($keywordsString, 'utf8') - 2, 'utf8');
|
||||
}
|
||||
|
||||
return $keywordsString;
|
||||
}
|
||||
}
|
||||
365
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php
vendored
Normal file
365
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Keywords;
|
||||
|
||||
/**
|
||||
* Gherkin keywords dumper.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class KeywordsDumper
|
||||
{
|
||||
private $keywords;
|
||||
private $keywordsDumper;
|
||||
|
||||
/**
|
||||
* Initializes dumper.
|
||||
*
|
||||
* @param KeywordsInterface $keywords Keywords instance
|
||||
*/
|
||||
public function __construct(KeywordsInterface $keywords)
|
||||
{
|
||||
$this->keywords = $keywords;
|
||||
$this->keywordsDumper = array($this, 'dumpKeywords');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets keywords mapper function.
|
||||
*
|
||||
* Callable should accept 2 arguments (array $keywords and Boolean $isShort)
|
||||
*
|
||||
* @param callable $mapper Mapper function
|
||||
*/
|
||||
public function setKeywordsDumperFunction($mapper)
|
||||
{
|
||||
$this->keywordsDumper = $mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults keywords dumper.
|
||||
*
|
||||
* @param array $keywords Keywords list
|
||||
* @param Boolean $isShort Is short version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dumpKeywords(array $keywords, $isShort)
|
||||
{
|
||||
if ($isShort) {
|
||||
return 1 < count($keywords) ? '(' . implode('|', $keywords) . ')' : $keywords[0];
|
||||
}
|
||||
|
||||
return $keywords[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps keyworded feature into string.
|
||||
*
|
||||
* @param string $language Keywords language
|
||||
* @param Boolean $short Dump short version
|
||||
* @param bool $excludeAsterisk
|
||||
*
|
||||
* @return string|array String for short version and array of features for extended
|
||||
*/
|
||||
public function dump($language, $short = true, $excludeAsterisk = false)
|
||||
{
|
||||
$this->keywords->setLanguage($language);
|
||||
$languageComment = '';
|
||||
if ('en' !== $language) {
|
||||
$languageComment = "# language: $language\n";
|
||||
}
|
||||
|
||||
$keywords = explode('|', $this->keywords->getFeatureKeywords());
|
||||
|
||||
if ($short) {
|
||||
$keywords = call_user_func($this->keywordsDumper, $keywords, $short);
|
||||
|
||||
return trim($languageComment . $this->dumpFeature($keywords, $short, $excludeAsterisk));
|
||||
}
|
||||
|
||||
$features = array();
|
||||
foreach ($keywords as $keyword) {
|
||||
$keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
|
||||
$features[] = trim($languageComment . $this->dumpFeature($keyword, $short, $excludeAsterisk));
|
||||
}
|
||||
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps feature example.
|
||||
*
|
||||
* @param string $keyword Item keyword
|
||||
* @param Boolean $short Dump short version?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function dumpFeature($keyword, $short = true, $excludeAsterisk = false)
|
||||
{
|
||||
$dump = <<<GHERKIN
|
||||
{$keyword}: Internal operations
|
||||
In order to stay secret
|
||||
As a secret organization
|
||||
We need to be able to erase past agents' memory
|
||||
|
||||
|
||||
GHERKIN;
|
||||
|
||||
// Background
|
||||
$keywords = explode('|', $this->keywords->getBackgroundKeywords());
|
||||
if ($short) {
|
||||
$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);
|
||||
$dump .= $this->dumpBackground($keyword, $short, $excludeAsterisk);
|
||||
}
|
||||
|
||||
// Scenario
|
||||
$keywords = explode('|', $this->keywords->getScenarioKeywords());
|
||||
if ($short) {
|
||||
$keywords = call_user_func($this->keywordsDumper, $keywords, $short);
|
||||
$dump .= $this->dumpScenario($keywords, $short, $excludeAsterisk);
|
||||
} else {
|
||||
foreach ($keywords as $keyword) {
|
||||
$keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
|
||||
$dump .= $this->dumpScenario($keyword, $short, $excludeAsterisk);
|
||||
}
|
||||
}
|
||||
|
||||
// Outline
|
||||
$keywords = explode('|', $this->keywords->getOutlineKeywords());
|
||||
if ($short) {
|
||||
$keywords = call_user_func($this->keywordsDumper, $keywords, $short);
|
||||
$dump .= $this->dumpOutline($keywords, $short, $excludeAsterisk);
|
||||
} else {
|
||||
foreach ($keywords as $keyword) {
|
||||
$keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
|
||||
$dump .= $this->dumpOutline($keyword, $short, $excludeAsterisk);
|
||||
}
|
||||
}
|
||||
|
||||
return $dump;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps background example.
|
||||
*
|
||||
* @param string $keyword Item keyword
|
||||
* @param Boolean $short Dump short version?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function dumpBackground($keyword, $short = true, $excludeAsterisk = false)
|
||||
{
|
||||
$dump = <<<GHERKIN
|
||||
{$keyword}:
|
||||
|
||||
GHERKIN;
|
||||
|
||||
// Given
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getGivenKeywords(),
|
||||
'there is agent A',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// And
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getAndKeywords(),
|
||||
'there is agent B',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
return $dump . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps scenario example.
|
||||
*
|
||||
* @param string $keyword Item keyword
|
||||
* @param Boolean $short Dump short version?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function dumpScenario($keyword, $short = true, $excludeAsterisk = false)
|
||||
{
|
||||
$dump = <<<GHERKIN
|
||||
{$keyword}: Erasing agent memory
|
||||
|
||||
GHERKIN;
|
||||
|
||||
// Given
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getGivenKeywords(),
|
||||
'there is agent J',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// And
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getAndKeywords(),
|
||||
'there is agent K',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// When
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getWhenKeywords(),
|
||||
'I erase agent K\'s memory',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// Then
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getThenKeywords(),
|
||||
'there should be agent J',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// But
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getButKeywords(),
|
||||
'there should not be agent K',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
return $dump . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps outline example.
|
||||
*
|
||||
* @param string $keyword Item keyword
|
||||
* @param Boolean $short Dump short version?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function dumpOutline($keyword, $short = true, $excludeAsterisk = false)
|
||||
{
|
||||
$dump = <<<GHERKIN
|
||||
{$keyword}: Erasing other agents' memory
|
||||
|
||||
GHERKIN;
|
||||
|
||||
// Given
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getGivenKeywords(),
|
||||
'there is agent <agent1>',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// And
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getAndKeywords(),
|
||||
'there is agent <agent2>',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// When
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getWhenKeywords(),
|
||||
'I erase agent <agent2>\'s memory',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// Then
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getThenKeywords(),
|
||||
'there should be agent <agent1>',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
// But
|
||||
$dump .= $this->dumpStep(
|
||||
$this->keywords->getButKeywords(),
|
||||
'there should not be agent <agent2>',
|
||||
$short,
|
||||
$excludeAsterisk
|
||||
);
|
||||
|
||||
$keywords = explode('|', $this->keywords->getExamplesKeywords());
|
||||
if ($short) {
|
||||
$keyword = call_user_func($this->keywordsDumper, $keywords, $short);
|
||||
} else {
|
||||
$keyword = call_user_func($this->keywordsDumper, array($keywords[0]), $short);
|
||||
}
|
||||
|
||||
$dump .= <<<GHERKIN
|
||||
|
||||
{$keyword}:
|
||||
| agent1 | agent2 |
|
||||
| D | M |
|
||||
|
||||
GHERKIN;
|
||||
|
||||
return $dump . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps step example.
|
||||
*
|
||||
* @param string $keywords Item keyword
|
||||
* @param string $text Step text
|
||||
* @param Boolean $short Dump short version?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function dumpStep($keywords, $text, $short = true, $excludeAsterisk = false)
|
||||
{
|
||||
$dump = '';
|
||||
|
||||
$keywords = explode('|', $keywords);
|
||||
if ($short) {
|
||||
$keywords = array_map(
|
||||
function ($keyword) {
|
||||
return str_replace('<', '', $keyword);
|
||||
},
|
||||
$keywords
|
||||
);
|
||||
$keywords = call_user_func($this->keywordsDumper, $keywords, $short);
|
||||
$dump .= <<<GHERKIN
|
||||
{$keywords} {$text}
|
||||
|
||||
GHERKIN;
|
||||
} else {
|
||||
foreach ($keywords as $keyword) {
|
||||
if ($excludeAsterisk && '*' === $keyword) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$indent = ' ';
|
||||
if (false !== mb_strpos($keyword, '<', 0, 'utf8')) {
|
||||
$keyword = mb_substr($keyword, 0, -1, 'utf8');
|
||||
$indent = '';
|
||||
}
|
||||
$keyword = call_user_func($this->keywordsDumper, array($keyword), $short);
|
||||
$dump .= <<<GHERKIN
|
||||
{$keyword}{$indent}{$text}
|
||||
|
||||
GHERKIN;
|
||||
}
|
||||
}
|
||||
|
||||
return $dump;
|
||||
}
|
||||
}
|
||||
103
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php
vendored
Normal file
103
vendor/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Keywords;
|
||||
|
||||
/**
|
||||
* Keywords holder interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface KeywordsInterface
|
||||
{
|
||||
/**
|
||||
* Sets keywords holder language.
|
||||
*
|
||||
* @param string $language Language name
|
||||
*/
|
||||
public function setLanguage($language);
|
||||
|
||||
/**
|
||||
* Returns Feature keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFeatureKeywords();
|
||||
|
||||
/**
|
||||
* Returns Background keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBackgroundKeywords();
|
||||
|
||||
/**
|
||||
* Returns Scenario keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScenarioKeywords();
|
||||
|
||||
/**
|
||||
* Returns Scenario Outline keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOutlineKeywords();
|
||||
|
||||
/**
|
||||
* Returns Examples keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExamplesKeywords();
|
||||
|
||||
/**
|
||||
* Returns Given keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGivenKeywords();
|
||||
|
||||
/**
|
||||
* Returns When keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWhenKeywords();
|
||||
|
||||
/**
|
||||
* Returns Then keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getThenKeywords();
|
||||
|
||||
/**
|
||||
* Returns And keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAndKeywords();
|
||||
|
||||
/**
|
||||
* Returns But keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getButKeywords();
|
||||
|
||||
/**
|
||||
* Returns all step keywords (splitted by "|").
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStepKeywords();
|
||||
}
|
||||
614
vendor/behat/gherkin/src/Behat/Gherkin/Lexer.php
vendored
Normal file
614
vendor/behat/gherkin/src/Behat/Gherkin/Lexer.php
vendored
Normal file
@@ -0,0 +1,614 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin;
|
||||
|
||||
use Behat\Gherkin\Exception\LexerException;
|
||||
use Behat\Gherkin\Keywords\KeywordsInterface;
|
||||
|
||||
/**
|
||||
* Gherkin lexer.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class Lexer
|
||||
{
|
||||
private $language;
|
||||
private $lines;
|
||||
private $linesCount;
|
||||
private $line;
|
||||
private $trimmedLine;
|
||||
private $lineNumber;
|
||||
private $eos;
|
||||
private $keywords;
|
||||
private $keywordsCache = array();
|
||||
private $stepKeywordTypesCache = array();
|
||||
private $deferredObjects = array();
|
||||
private $deferredObjectsCount = 0;
|
||||
private $stashedToken;
|
||||
private $inPyString = false;
|
||||
private $pyStringSwallow = 0;
|
||||
private $featureStarted = false;
|
||||
private $allowMultilineArguments = false;
|
||||
private $allowSteps = false;
|
||||
|
||||
/**
|
||||
* 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 Exception\LexerException
|
||||
*/
|
||||
public function analyse($input, $language = 'en')
|
||||
{
|
||||
// try to detect unsupported encoding
|
||||
if ('UTF-8' !== mb_detect_encoding($input, 'UTF-8', true)) {
|
||||
throw new LexerException('Feature file is not in UTF8 encoding');
|
||||
}
|
||||
|
||||
$input = strtr($input, array("\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 = array();
|
||||
$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 = array();
|
||||
$this->stepKeywordTypesCache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 for number of tokens.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function predictToken()
|
||||
{
|
||||
if (null === $this->stashedToken) {
|
||||
$this->stashedToken = $this->getNextToken();
|
||||
}
|
||||
|
||||
return $this->stashedToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs token with specified parameters.
|
||||
*
|
||||
* @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
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns trimmed version of line.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getTrimmedLine()
|
||||
{
|
||||
return null !== $this->trimmedLine ? $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 null|array
|
||||
*/
|
||||
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 null|array
|
||||
*/
|
||||
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 ('Feature' === $type) {
|
||||
$this->featureStarted = true;
|
||||
}
|
||||
|
||||
// turn off PyString and Table searching
|
||||
if ('Feature' === $type || 'Scenario' === $type || 'Outline' === $type) {
|
||||
$this->allowMultilineArguments = false;
|
||||
} elseif ('Examples' === $type) {
|
||||
$this->allowMultilineArguments = true;
|
||||
}
|
||||
|
||||
// turn on steps searching
|
||||
if ('Scenario' === $type || 'Background' === $type || 'Outline' === $type) {
|
||||
$this->allowSteps = true;
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans EOS from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
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 ('Step' === $type) {
|
||||
$padded = array();
|
||||
foreach (explode('|', $keywords) as $keyword) {
|
||||
$padded[] = false !== mb_strpos($keyword, '<', 0, 'utf8')
|
||||
? 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 null|array
|
||||
*/
|
||||
protected function scanFeature()
|
||||
{
|
||||
return $this->scanInputForKeywords($this->getKeywords('Feature'), 'Feature');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Background from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanBackground()
|
||||
{
|
||||
return $this->scanInputForKeywords($this->getKeywords('Background'), 'Background');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Scenario from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanScenario()
|
||||
{
|
||||
return $this->scanInputForKeywords($this->getKeywords('Scenario'), 'Scenario');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Scenario Outline from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanOutline()
|
||||
{
|
||||
return $this->scanInputForKeywords($this->getKeywords('Outline'), 'Outline');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Scenario Outline Examples from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanExamples()
|
||||
{
|
||||
return $this->scanInputForKeywords($this->getKeywords('Examples'), 'Examples');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Step from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
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 null|array
|
||||
*/
|
||||
protected function scanPyStringOp()
|
||||
{
|
||||
if (!$this->allowMultilineArguments) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (false === ($pos = mb_strpos($this->line, '"""', 0, 'utf8'))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->inPyString = !$this->inPyString;
|
||||
$token = $this->takeToken('PyStringOp');
|
||||
$this->pyStringSwallow = $pos;
|
||||
|
||||
$this->consumeLine();
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans PyString content.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
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 null|array
|
||||
*/
|
||||
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('/(?<!\\\)\|/u', $line));
|
||||
$token['columns'] = $columns;
|
||||
|
||||
$this->consumeLine();
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Tags from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanTags()
|
||||
{
|
||||
$line = $this->getTrimmedLine();
|
||||
if (!isset($line[0]) || '@' !== $line[0]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$token = $this->takeToken('Tag');
|
||||
$tags = explode('@', mb_substr($line, 1, mb_strlen($line, 'utf8') - 1, 'utf8'));
|
||||
$tags = array_map('trim', $tags);
|
||||
$token['tags'] = $tags;
|
||||
|
||||
$this->consumeLine();
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Language specifier from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanLanguage()
|
||||
{
|
||||
if ($this->featureStarted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->inPyString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (0 !== mb_strpos(ltrim($this->line), '#', 0, 'utf8')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->scanInput('/^\s*\#\s*language:\s*([\w_\-]+)\s*$/', 'Language');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Comment from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function scanComment()
|
||||
{
|
||||
if ($this->inPyString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$line = $this->getTrimmedLine();
|
||||
if (0 !== mb_strpos($line, '#', 0, 'utf8')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$token = $this->takeToken('Comment', $line);
|
||||
$this->consumeLine();
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Newline from input & returns it if found.
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
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 null|array
|
||||
*/
|
||||
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 = array(
|
||||
'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';
|
||||
}
|
||||
}
|
||||
72
vendor/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php
vendored
Normal file
72
vendor/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
/**
|
||||
* Abstract filesystem loader.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
abstract class AbstractFileLoader implements FileLoaderInterface
|
||||
{
|
||||
protected $basePath;
|
||||
|
||||
/**
|
||||
* Sets base features path.
|
||||
*
|
||||
* @param string $path Base loader path
|
||||
*/
|
||||
public function setBasePath($path)
|
||||
{
|
||||
$this->basePath = realpath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds relative path for provided absolute (relative to base features path).
|
||||
*
|
||||
* @param string $path Absolute path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function findRelativePath($path)
|
||||
{
|
||||
if (null !== $this->basePath) {
|
||||
return strtr($path, array($this->basePath . DIRECTORY_SEPARATOR => ''));
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds absolute path for provided relative (relative to base features path).
|
||||
*
|
||||
* @param string $path Relative path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function findAbsolutePath($path)
|
||||
{
|
||||
if (is_file($path) || is_dir($path)) {
|
||||
return realpath($path);
|
||||
}
|
||||
|
||||
if (null === $this->basePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_file($this->basePath . DIRECTORY_SEPARATOR . $path)
|
||||
|| is_dir($this->basePath . DIRECTORY_SEPARATOR . $path)) {
|
||||
return realpath($this->basePath . DIRECTORY_SEPARATOR . $path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
269
vendor/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php
vendored
Normal file
269
vendor/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
use Behat\Gherkin\Node\BackgroundNode;
|
||||
use Behat\Gherkin\Node\ExampleTableNode;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\OutlineNode;
|
||||
use Behat\Gherkin\Node\PyStringNode;
|
||||
use Behat\Gherkin\Node\ScenarioNode;
|
||||
use Behat\Gherkin\Node\StepNode;
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
|
||||
/**
|
||||
* From-array loader.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class ArrayLoader implements LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Checks if current loader supports provided resource.
|
||||
*
|
||||
* @param mixed $resource Resource to load
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function supports($resource)
|
||||
{
|
||||
return is_array($resource) && (isset($resource['features']) || isset($resource['feature']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads features from provided resource.
|
||||
*
|
||||
* @param mixed $resource Resource to load
|
||||
*
|
||||
* @return FeatureNode[]
|
||||
*/
|
||||
public function load($resource)
|
||||
{
|
||||
$features = array();
|
||||
|
||||
if (isset($resource['features'])) {
|
||||
foreach ($resource['features'] as $iterator => $hash) {
|
||||
$feature = $this->loadFeatureHash($hash, $iterator);
|
||||
$features[] = $feature;
|
||||
}
|
||||
} elseif (isset($resource['feature'])) {
|
||||
$feature = $this->loadFeatureHash($resource['feature']);
|
||||
$features[] = $feature;
|
||||
}
|
||||
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads feature from provided feature hash.
|
||||
*
|
||||
* @param array $hash Feature hash
|
||||
* @param integer $line
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
protected function loadFeatureHash(array $hash, $line = 0)
|
||||
{
|
||||
$hash = array_merge(
|
||||
array(
|
||||
'title' => null,
|
||||
'description' => null,
|
||||
'tags' => array(),
|
||||
'keyword' => 'Feature',
|
||||
'language' => 'en',
|
||||
'line' => $line,
|
||||
'scenarios' => array(),
|
||||
),
|
||||
$hash
|
||||
);
|
||||
$background = isset($hash['background']) ? $this->loadBackgroundHash($hash['background']) : null;
|
||||
|
||||
$scenarios = array();
|
||||
foreach ((array) $hash['scenarios'] as $scenarioIterator => $scenarioHash) {
|
||||
if (isset($scenarioHash['type']) && 'outline' === $scenarioHash['type']) {
|
||||
$scenarios[] = $this->loadOutlineHash($scenarioHash, $scenarioIterator);
|
||||
} else {
|
||||
$scenarios[] = $this->loadScenarioHash($scenarioHash, $scenarioIterator);
|
||||
}
|
||||
}
|
||||
|
||||
return new FeatureNode($hash['title'], $hash['description'], $hash['tags'], $background, $scenarios, $hash['keyword'], $hash['language'], null, $hash['line']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads background from provided hash.
|
||||
*
|
||||
* @param array $hash Background hash
|
||||
*
|
||||
* @return BackgroundNode
|
||||
*/
|
||||
protected function loadBackgroundHash(array $hash)
|
||||
{
|
||||
$hash = array_merge(
|
||||
array(
|
||||
'title' => null,
|
||||
'keyword' => 'Background',
|
||||
'line' => 0,
|
||||
'steps' => array(),
|
||||
),
|
||||
$hash
|
||||
);
|
||||
|
||||
$steps = $this->loadStepsHash($hash['steps']);
|
||||
|
||||
return new BackgroundNode($hash['title'], $steps, $hash['keyword'], $hash['line']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads scenario from provided scenario hash.
|
||||
*
|
||||
* @param array $hash Scenario hash
|
||||
* @param integer $line Scenario definition line
|
||||
*
|
||||
* @return ScenarioNode
|
||||
*/
|
||||
protected function loadScenarioHash(array $hash, $line = 0)
|
||||
{
|
||||
$hash = array_merge(
|
||||
array(
|
||||
'title' => null,
|
||||
'tags' => array(),
|
||||
'keyword' => 'Scenario',
|
||||
'line' => $line,
|
||||
'steps' => array(),
|
||||
),
|
||||
$hash
|
||||
);
|
||||
|
||||
$steps = $this->loadStepsHash($hash['steps']);
|
||||
|
||||
return new ScenarioNode($hash['title'], $hash['tags'], $steps, $hash['keyword'], $hash['line']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads outline from provided outline hash.
|
||||
*
|
||||
* @param array $hash Outline hash
|
||||
* @param integer $line Outline definition line
|
||||
*
|
||||
* @return OutlineNode
|
||||
*/
|
||||
protected function loadOutlineHash(array $hash, $line = 0)
|
||||
{
|
||||
$hash = array_merge(
|
||||
array(
|
||||
'title' => null,
|
||||
'tags' => array(),
|
||||
'keyword' => 'Scenario Outline',
|
||||
'line' => $line,
|
||||
'steps' => array(),
|
||||
'examples' => array(),
|
||||
),
|
||||
$hash
|
||||
);
|
||||
|
||||
$steps = $this->loadStepsHash($hash['steps']);
|
||||
|
||||
if (isset($hash['examples']['keyword'])) {
|
||||
$examplesKeyword = $hash['examples']['keyword'];
|
||||
unset($hash['examples']['keyword']);
|
||||
} else {
|
||||
$examplesKeyword = 'Examples';
|
||||
}
|
||||
|
||||
$examples = new ExampleTableNode($hash['examples'], $examplesKeyword);
|
||||
|
||||
return new OutlineNode($hash['title'], $hash['tags'], $steps, $examples, $hash['keyword'], $hash['line']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads steps from provided hash.
|
||||
*
|
||||
* @param array $hash
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
private function loadStepsHash(array $hash)
|
||||
{
|
||||
$steps = array();
|
||||
foreach ($hash as $stepIterator => $stepHash) {
|
||||
$steps[] = $this->loadStepHash($stepHash, $stepIterator);
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads step from provided hash.
|
||||
*
|
||||
* @param array $hash Step hash
|
||||
* @param integer $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(),
|
||||
),
|
||||
$hash
|
||||
);
|
||||
|
||||
$arguments = array();
|
||||
foreach ($hash['arguments'] as $argumentHash) {
|
||||
if ('table' === $argumentHash['type']) {
|
||||
$arguments[] = $this->loadTableHash($argumentHash['rows']);
|
||||
} elseif ('pystring' === $argumentHash['type']) {
|
||||
$arguments[] = $this->loadPyStringHash($argumentHash, $hash['line'] + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return new StepNode($hash['type'], $hash['text'], $arguments, $hash['line'], $hash['keyword_type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads table from provided hash.
|
||||
*
|
||||
* @param array $hash Table hash
|
||||
*
|
||||
* @return TableNode
|
||||
*/
|
||||
protected function loadTableHash(array $hash)
|
||||
{
|
||||
return new TableNode($hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads PyString from provided hash.
|
||||
*
|
||||
* @param array $hash PyString hash
|
||||
* @param integer $line
|
||||
*
|
||||
* @return PyStringNode
|
||||
*/
|
||||
protected function loadPyStringHash(array $hash, $line = 0)
|
||||
{
|
||||
$line = isset($hash['line']) ? $hash['line'] : $line;
|
||||
|
||||
$strings = array();
|
||||
foreach (explode("\n", $hash['text']) as $string) {
|
||||
$strings[] = $string;
|
||||
}
|
||||
|
||||
return new PyStringNode($strings, $line);
|
||||
}
|
||||
}
|
||||
80
vendor/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php
vendored
Normal file
80
vendor/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
use Behat\Gherkin\Gherkin;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
|
||||
/**
|
||||
* Directory contents loader.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class DirectoryLoader extends AbstractFileLoader
|
||||
{
|
||||
protected $gherkin;
|
||||
|
||||
/**
|
||||
* Initializes loader.
|
||||
*
|
||||
* @param Gherkin $gherkin Gherkin manager
|
||||
*/
|
||||
public function __construct(Gherkin $gherkin)
|
||||
{
|
||||
$this->gherkin = $gherkin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current loader supports provided resource.
|
||||
*
|
||||
* @param mixed $path Resource to load
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function supports($path)
|
||||
{
|
||||
return is_string($path)
|
||||
&& is_dir($this->findAbsolutePath($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads features from provided resource.
|
||||
*
|
||||
* @param string $path Resource to load
|
||||
*
|
||||
* @return FeatureNode[]
|
||||
*/
|
||||
public function load($path)
|
||||
{
|
||||
$path = $this->findAbsolutePath($path);
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS)
|
||||
);
|
||||
$paths = array_map('strval', iterator_to_array($iterator));
|
||||
uasort($paths, 'strnatcasecmp');
|
||||
|
||||
$features = array();
|
||||
|
||||
foreach ($paths as $path) {
|
||||
$path = (string) $path;
|
||||
$loader = $this->gherkin->resolveLoader($path);
|
||||
|
||||
if (null !== $loader) {
|
||||
$features = array_merge($features, $loader->load($path));
|
||||
}
|
||||
}
|
||||
|
||||
return $features;
|
||||
}
|
||||
}
|
||||
26
vendor/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php
vendored
Normal file
26
vendor/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
/**
|
||||
* File Loader interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface FileLoaderInterface extends LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Sets base features path.
|
||||
*
|
||||
* @param string $path Base loader path
|
||||
*/
|
||||
public function setBasePath($path);
|
||||
}
|
||||
102
vendor/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php
vendored
Normal file
102
vendor/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
use Behat\Gherkin\Cache\CacheInterface;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Parser;
|
||||
|
||||
/**
|
||||
* Gherkin *.feature files loader.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class GherkinFileLoader extends AbstractFileLoader
|
||||
{
|
||||
protected $parser;
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Initializes loader.
|
||||
*
|
||||
* @param Parser $parser Parser
|
||||
* @param CacheInterface $cache Cache layer
|
||||
*/
|
||||
public function __construct(Parser $parser, CacheInterface $cache = null)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets cache layer.
|
||||
*
|
||||
* @param CacheInterface $cache Cache layer
|
||||
*/
|
||||
public function setCache(CacheInterface $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current loader supports provided resource.
|
||||
*
|
||||
* @param mixed $path Resource to load
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function supports($path)
|
||||
{
|
||||
return is_string($path)
|
||||
&& is_file($absolute = $this->findAbsolutePath($path))
|
||||
&& 'feature' === pathinfo($absolute, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads features from provided resource.
|
||||
*
|
||||
* @param string $path Resource to load
|
||||
*
|
||||
* @return FeatureNode[]
|
||||
*/
|
||||
public function load($path)
|
||||
{
|
||||
$path = $this->findAbsolutePath($path);
|
||||
|
||||
if ($this->cache) {
|
||||
if ($this->cache->isFresh($path, filemtime($path))) {
|
||||
$feature = $this->cache->read($path);
|
||||
} elseif (null !== $feature = $this->parseFeature($path)) {
|
||||
$this->cache->write($path, $feature);
|
||||
}
|
||||
} else {
|
||||
$feature = $this->parseFeature($path);
|
||||
}
|
||||
|
||||
return null !== $feature ? array($feature) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses feature at provided absolute path.
|
||||
*
|
||||
* @param string $path Feature path
|
||||
*
|
||||
* @return FeatureNode
|
||||
*/
|
||||
protected function parseFeature($path)
|
||||
{
|
||||
$filename = $this->findRelativePath($path);
|
||||
$content = file_get_contents($path);
|
||||
$feature = $this->parser->parse($content, $filename);
|
||||
|
||||
return $feature;
|
||||
}
|
||||
}
|
||||
39
vendor/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php
vendored
Normal file
39
vendor/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
|
||||
/**
|
||||
* Loader interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Checks if current loader supports provided resource.
|
||||
*
|
||||
* @param mixed $resource Resource to load
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function supports($resource);
|
||||
|
||||
/**
|
||||
* Loads features from provided resource.
|
||||
*
|
||||
* @param mixed $resource Resource to load
|
||||
*
|
||||
* @return FeatureNode[]
|
||||
*/
|
||||
public function load($resource);
|
||||
}
|
||||
73
vendor/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php
vendored
Normal file
73
vendor/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Loader;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Yaml files loader.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class YamlFileLoader extends AbstractFileLoader
|
||||
{
|
||||
private $loader;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->loader = new ArrayLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current loader supports provided resource.
|
||||
*
|
||||
* @param mixed $path Resource to load
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function supports($path)
|
||||
{
|
||||
return is_string($path)
|
||||
&& is_file($absolute = $this->findAbsolutePath($path))
|
||||
&& 'yml' === pathinfo($absolute, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads features from provided resource.
|
||||
*
|
||||
* @param string $path Resource to load
|
||||
*
|
||||
* @return FeatureNode[]
|
||||
*/
|
||||
public function load($path)
|
||||
{
|
||||
$path = $this->findAbsolutePath($path);
|
||||
$hash = Yaml::parse(file_get_contents($path));
|
||||
|
||||
$features = $this->loader->load($hash);
|
||||
$filename = $this->findRelativePath($path);
|
||||
|
||||
return array_map(function (FeatureNode $feature) use ($filename) {
|
||||
return new FeatureNode(
|
||||
$feature->getTitle(),
|
||||
$feature->getDescription(),
|
||||
$feature->getTags(),
|
||||
$feature->getBackground(),
|
||||
$feature->getScenarios(),
|
||||
$feature->getKeyword(),
|
||||
$feature->getLanguage(),
|
||||
$filename,
|
||||
$feature->getLine()
|
||||
);
|
||||
}, $features);
|
||||
}
|
||||
}
|
||||
20
vendor/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php
vendored
Normal file
20
vendor/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin arguments interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface ArgumentInterface extends NodeInterface
|
||||
{
|
||||
}
|
||||
112
vendor/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php
vendored
Normal file
112
vendor/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Background.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class BackgroundNode implements ScenarioLikeInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
/**
|
||||
* @var StepNode[]
|
||||
*/
|
||||
private $steps = array();
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keyword;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
|
||||
/**
|
||||
* Initializes background.
|
||||
*
|
||||
* @param null|string $title
|
||||
* @param StepNode[] $steps
|
||||
* @param string $keyword
|
||||
* @param integer $line
|
||||
*/
|
||||
public function __construct($title, array $steps, $keyword, $line)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->steps = $steps;
|
||||
$this->keyword = $keyword;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Background';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns background title.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if background has steps.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasSteps()
|
||||
{
|
||||
return 0 < count($this->steps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns background steps.
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
public function getSteps()
|
||||
{
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns background keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns background declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
}
|
||||
274
vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php
vendored
Normal file
274
vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Outline Example.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class ExampleNode implements ScenarioInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $tags;
|
||||
/**
|
||||
* @var StepNode[]
|
||||
*/
|
||||
private $outlineSteps;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $tokens;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
/**
|
||||
* @var null|StepNode[]
|
||||
*/
|
||||
private $steps;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $outlineTitle;
|
||||
|
||||
/**
|
||||
* Initializes outline.
|
||||
*
|
||||
* @param string $title
|
||||
* @param string[] $tags
|
||||
* @param StepNode[] $outlineSteps
|
||||
* @param string[] $tokens
|
||||
* @param integer $line
|
||||
* @param string|null $outlineTitle
|
||||
*/
|
||||
public function __construct($title, array $tags, $outlineSteps, array $tokens, $line, $outlineTitle = null)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->tags = $tags;
|
||||
$this->outlineSteps = $outlineSteps;
|
||||
$this->tokens = $tokens;
|
||||
$this->line = $line;
|
||||
$this->outlineTitle = $outlineTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Example';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->getNodeType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns example title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline is tagged with tag.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTag($tag)
|
||||
{
|
||||
return in_array($tag, $this->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline has tags (both inherited from feature and own).
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTags()
|
||||
{
|
||||
return 0 < count($this->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline tags (including inherited from feature).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline has steps.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasSteps()
|
||||
{
|
||||
return 0 < count($this->outlineSteps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline steps.
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
public function getSteps()
|
||||
{
|
||||
return $this->steps = $this->steps ? : $this->createExampleSteps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns example tokens.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTokens()
|
||||
{
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOutlineTitle()
|
||||
{
|
||||
return $this->outlineTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates steps for this example from abstract outline steps.
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
protected function createExampleSteps()
|
||||
{
|
||||
$steps = array();
|
||||
foreach ($this->outlineSteps as $outlineStep) {
|
||||
$keyword = $outlineStep->getKeyword();
|
||||
$keywordType = $outlineStep->getKeywordType();
|
||||
$text = $this->replaceTextTokens($outlineStep->getText());
|
||||
$args = $this->replaceArgumentsTokens($outlineStep->getArguments());
|
||||
$line = $outlineStep->getLine();
|
||||
|
||||
$steps[] = new StepNode($keyword, $text, $args, $line, $keywordType);
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces tokens in arguments with row values.
|
||||
*
|
||||
* @param ArgumentInterface[] $arguments
|
||||
*
|
||||
* @return ArgumentInterface[]
|
||||
*/
|
||||
protected function replaceArgumentsTokens(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $num => $argument) {
|
||||
if ($argument instanceof TableNode) {
|
||||
$arguments[$num] = $this->replaceTableArgumentTokens($argument);
|
||||
}
|
||||
if ($argument instanceof PyStringNode) {
|
||||
$arguments[$num] = $this->replacePyStringArgumentTokens($argument);
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces tokens in table with row values.
|
||||
*
|
||||
* @param TableNode $argument
|
||||
*
|
||||
* @return TableNode
|
||||
*/
|
||||
protected function replaceTableArgumentTokens(TableNode $argument)
|
||||
{
|
||||
$table = $argument->getTable();
|
||||
foreach ($table as $line => $row) {
|
||||
foreach (array_keys($row) as $col) {
|
||||
$table[$line][$col] = $this->replaceTextTokens($table[$line][$col]);
|
||||
}
|
||||
}
|
||||
|
||||
return new TableNode($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces tokens in PyString with row values.
|
||||
*
|
||||
* @param PyStringNode $argument
|
||||
*
|
||||
* @return PyStringNode
|
||||
*/
|
||||
protected function replacePyStringArgumentTokens(PyStringNode $argument)
|
||||
{
|
||||
$strings = $argument->getStrings();
|
||||
foreach ($strings as $line => $string) {
|
||||
$strings[$line] = $this->replaceTextTokens($strings[$line]);
|
||||
}
|
||||
|
||||
return new PyStringNode($strings, $argument->getLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces tokens in text with row values.
|
||||
*
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function replaceTextTokens($text)
|
||||
{
|
||||
foreach ($this->tokens as $key => $val) {
|
||||
$text = str_replace('<' . $key . '>', $val, $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
57
vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php
vendored
Normal file
57
vendor/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Outline Example Table.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class ExampleTableNode extends TableNode
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keyword;
|
||||
|
||||
/**
|
||||
* Initializes example table.
|
||||
*
|
||||
* @param array $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
|
||||
* @param string $keyword
|
||||
*/
|
||||
public function __construct(array $table, $keyword)
|
||||
{
|
||||
$this->keyword = $keyword;
|
||||
|
||||
parent::__construct($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'ExampleTable';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns example table keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->keyword;
|
||||
}
|
||||
}
|
||||
243
vendor/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php
vendored
Normal file
243
vendor/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Feature.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface
|
||||
{
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $title;
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $description;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $tags = array();
|
||||
/**
|
||||
* @var null|BackgroundNode
|
||||
*/
|
||||
private $background;
|
||||
/**
|
||||
* @var ScenarioInterface[]
|
||||
*/
|
||||
private $scenarios = array();
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keyword;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $language;
|
||||
/**
|
||||
* @var null|string
|
||||
*/
|
||||
private $file;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
|
||||
/**
|
||||
* Initializes feature.
|
||||
*
|
||||
* @param null|string $title
|
||||
* @param null|string $description
|
||||
* @param string[] $tags
|
||||
* @param null|BackgroundNode $background
|
||||
* @param ScenarioInterface[] $scenarios
|
||||
* @param string $keyword
|
||||
* @param string $language
|
||||
* @param null|string $file
|
||||
* @param integer $line
|
||||
*/
|
||||
public function __construct(
|
||||
$title,
|
||||
$description,
|
||||
array $tags,
|
||||
BackgroundNode $background = null,
|
||||
array $scenarios,
|
||||
$keyword,
|
||||
$language,
|
||||
$file,
|
||||
$line
|
||||
) {
|
||||
$this->title = $title;
|
||||
$this->description = $description;
|
||||
$this->tags = $tags;
|
||||
$this->background = $background;
|
||||
$this->scenarios = $scenarios;
|
||||
$this->keyword = $keyword;
|
||||
$this->language = $language;
|
||||
$this->file = $file;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Feature';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature title.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if feature has a description.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasDescription()
|
||||
{
|
||||
return !empty($this->description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature description.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if feature is tagged with tag.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTag($tag)
|
||||
{
|
||||
return in_array($tag, $this->tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if feature has tags.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTags()
|
||||
{
|
||||
return 0 < count($this->tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature tags.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if feature has background.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasBackground()
|
||||
{
|
||||
return null !== $this->background;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature background.
|
||||
*
|
||||
* @return null|BackgroundNode
|
||||
*/
|
||||
public function getBackground()
|
||||
{
|
||||
return $this->background;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if feature has scenarios.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasScenarios()
|
||||
{
|
||||
return 0 < count($this->scenarios);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature scenarios.
|
||||
*
|
||||
* @return ScenarioInterface[]
|
||||
*/
|
||||
public function getScenarios()
|
||||
{
|
||||
return $this->scenarios;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature language.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature file.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns feature declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
}
|
||||
33
vendor/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php
vendored
Normal file
33
vendor/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin keyword node interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface KeywordNodeInterface extends NodeInterface
|
||||
{
|
||||
/**
|
||||
* Returns node keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword();
|
||||
|
||||
/**
|
||||
* Returns node title.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitle();
|
||||
}
|
||||
33
vendor/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php
vendored
Normal file
33
vendor/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin node interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface NodeInterface
|
||||
{
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType();
|
||||
|
||||
/**
|
||||
* Returns feature declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine();
|
||||
}
|
||||
218
vendor/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php
vendored
Normal file
218
vendor/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Outline.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class OutlineNode implements ScenarioInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $tags;
|
||||
/**
|
||||
* @var StepNode[]
|
||||
*/
|
||||
private $steps;
|
||||
/**
|
||||
* @var ExampleTableNode
|
||||
*/
|
||||
private $table;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keyword;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
/**
|
||||
* @var null|ExampleNode[]
|
||||
*/
|
||||
private $examples;
|
||||
|
||||
/**
|
||||
* Initializes outline.
|
||||
*
|
||||
* @param null|string $title
|
||||
* @param string[] $tags
|
||||
* @param StepNode[] $steps
|
||||
* @param ExampleTableNode $table
|
||||
* @param string $keyword
|
||||
* @param integer $line
|
||||
*/
|
||||
public function __construct(
|
||||
$title,
|
||||
array $tags,
|
||||
array $steps,
|
||||
ExampleTableNode $table,
|
||||
$keyword,
|
||||
$line
|
||||
) {
|
||||
$this->title = $title;
|
||||
$this->tags = $tags;
|
||||
$this->steps = $steps;
|
||||
$this->table = $table;
|
||||
$this->keyword = $keyword;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Outline';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline title.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline is tagged with tag.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTag($tag)
|
||||
{
|
||||
return in_array($tag, $this->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline has tags (both inherited from feature and own).
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTags()
|
||||
{
|
||||
return 0 < count($this->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline tags (including inherited from feature).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline has steps.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasSteps()
|
||||
{
|
||||
return 0 < count($this->steps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline steps.
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
public function getSteps()
|
||||
{
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if outline has examples.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasExamples()
|
||||
{
|
||||
return 0 < count($this->table->getColumnsHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns examples table.
|
||||
*
|
||||
* @return ExampleTableNode
|
||||
*/
|
||||
public function getExampleTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of examples for the outline.
|
||||
*
|
||||
* @return ExampleNode[]
|
||||
*/
|
||||
public function getExamples()
|
||||
{
|
||||
return $this->examples = $this->examples ? : $this->createExamples();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns outline declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates examples for this outline using examples table.
|
||||
*
|
||||
* @return ExampleNode[]
|
||||
*/
|
||||
protected function createExamples()
|
||||
{
|
||||
$examples = array();
|
||||
foreach ($this->table->getColumnsHash() as $rowNum => $row) {
|
||||
$examples[] = new ExampleNode(
|
||||
$this->table->getRowAsString($rowNum + 1),
|
||||
$this->tags,
|
||||
$this->getSteps(),
|
||||
$row,
|
||||
$this->table->getRowLine($rowNum + 1),
|
||||
$this->getTitle()
|
||||
);
|
||||
}
|
||||
|
||||
return $examples;
|
||||
}
|
||||
}
|
||||
90
vendor/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php
vendored
Normal file
90
vendor/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin PyString argument.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class PyStringNode implements ArgumentInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $strings = array();
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
|
||||
/**
|
||||
* Initializes PyString.
|
||||
*
|
||||
* @param array $strings String in form of [$stringLine]
|
||||
* @param integer $line Line number where string been started
|
||||
*/
|
||||
public function __construct(array $strings, $line)
|
||||
{
|
||||
$this->strings = $strings;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'PyString';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns entire PyString lines set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStrings()
|
||||
{
|
||||
return $this->strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns raw string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRaw()
|
||||
{
|
||||
return implode("\n", $this->strings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts PyString into string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getRaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns line number at which PyString was started.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
}
|
||||
20
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php
vendored
Normal file
20
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin scenario interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface ScenarioInterface extends ScenarioLikeInterface, TaggedNodeInterface
|
||||
{
|
||||
}
|
||||
20
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php
vendored
Normal file
20
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin scenario-like interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface ScenarioLikeInterface extends KeywordNodeInterface, StepContainerInterface
|
||||
{
|
||||
}
|
||||
150
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php
vendored
Normal file
150
vendor/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Scenario.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class ScenarioNode implements ScenarioInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $tags = array();
|
||||
/**
|
||||
* @var StepNode[]
|
||||
*/
|
||||
private $steps = array();
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keyword;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
|
||||
/**
|
||||
* Initializes scenario.
|
||||
*
|
||||
* @param null|string $title
|
||||
* @param array $tags
|
||||
* @param StepNode[] $steps
|
||||
* @param string $keyword
|
||||
* @param integer $line
|
||||
*/
|
||||
public function __construct($title, array $tags, array $steps, $keyword, $line)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->tags = $tags;
|
||||
$this->steps = $steps;
|
||||
$this->keyword = $keyword;
|
||||
$this->line = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Scenario';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scenario title.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario is tagged with tag.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTag($tag)
|
||||
{
|
||||
return in_array($tag, $this->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario has tags (both inherited from feature and own).
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTags()
|
||||
{
|
||||
return 0 < count($this->getTags());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scenario tags (including inherited from feature).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if scenario has steps.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasSteps()
|
||||
{
|
||||
return 0 < count($this->steps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scenario steps.
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
public function getSteps()
|
||||
{
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scenario keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scenario declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
}
|
||||
33
vendor/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php
vendored
Normal file
33
vendor/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin step container interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface StepContainerInterface extends NodeInterface
|
||||
{
|
||||
/**
|
||||
* Checks if container has steps.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasSteps();
|
||||
|
||||
/**
|
||||
* Returns container steps.
|
||||
*
|
||||
* @return StepNode[]
|
||||
*/
|
||||
public function getSteps();
|
||||
}
|
||||
152
vendor/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php
vendored
Normal file
152
vendor/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
use Behat\Gherkin\Exception\NodeException;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Step.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class StepNode implements NodeInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keyword;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keywordType;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $text;
|
||||
/**
|
||||
* @var ArgumentInterface[]
|
||||
*/
|
||||
private $arguments = array();
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $line;
|
||||
|
||||
/**
|
||||
* Initializes step.
|
||||
*
|
||||
* @param string $keyword
|
||||
* @param string $text
|
||||
* @param ArgumentInterface[] $arguments
|
||||
* @param integer $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)
|
||||
));
|
||||
}
|
||||
|
||||
$this->keyword = $keyword;
|
||||
$this->text = $text;
|
||||
$this->arguments = $arguments;
|
||||
$this->line = $line;
|
||||
$this->keywordType = $keywordType ?: 'Given';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Step';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns step keyword in provided language (Given, When, Then, etc.).
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @deprecated use getKeyword() instead
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->getKeyword();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns step keyword in provided language (Given, When, Then, etc.).
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getKeyword()
|
||||
{
|
||||
return $this->keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns step type keyword (Given, When, Then, etc.).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKeywordType()
|
||||
{
|
||||
return $this->keywordType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns step text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getText()
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if step has arguments.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasArguments()
|
||||
{
|
||||
return 0 < count($this->arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns step arguments.
|
||||
*
|
||||
* @return ArgumentInterface[]
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns step declaration line number.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->line;
|
||||
}
|
||||
}
|
||||
342
vendor/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php
vendored
Normal file
342
vendor/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php
vendored
Normal file
@@ -0,0 +1,342 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
use ArrayIterator;
|
||||
use Behat\Gherkin\Exception\NodeException;
|
||||
use Iterator;
|
||||
use IteratorAggregate;
|
||||
|
||||
/**
|
||||
* Represents Gherkin Table argument.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class TableNode implements ArgumentInterface, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $table;
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $maxLineLength = array();
|
||||
|
||||
/**
|
||||
* Initializes table.
|
||||
*
|
||||
* @param array $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
|
||||
*
|
||||
* @throws NodeException If the given table is invalid
|
||||
*/
|
||||
public function __construct(array $table)
|
||||
{
|
||||
$this->table = $table;
|
||||
$columnCount = null;
|
||||
|
||||
foreach ($this->getRows() as $row) {
|
||||
if ($columnCount === null) {
|
||||
$columnCount = count($row);
|
||||
}
|
||||
|
||||
if (count($row) !== $columnCount) {
|
||||
throw new NodeException('Table does not have same number of columns in every row.');
|
||||
}
|
||||
|
||||
if (!is_array($row)) {
|
||||
throw new NodeException('Table is not two-dimensional.');
|
||||
}
|
||||
|
||||
foreach ($row as $column => $string) {
|
||||
if (!isset($this->maxLineLength[$column])) {
|
||||
$this->maxLineLength[$column] = 0;
|
||||
}
|
||||
|
||||
if (!is_scalar($string)) {
|
||||
throw new NodeException('Table is not two-dimensional.');
|
||||
}
|
||||
|
||||
$this->maxLineLength[$column] = max($this->maxLineLength[$column], mb_strlen($string, 'utf8'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table from a given list.
|
||||
*
|
||||
* @param array $list One-dimensional array
|
||||
*
|
||||
* @return TableNode
|
||||
*
|
||||
* @throws NodeException If the given list is not a one-dimensional array
|
||||
*/
|
||||
public static function fromList(array $list)
|
||||
{
|
||||
if (count($list) !== count($list, COUNT_RECURSIVE)) {
|
||||
throw new NodeException('List is not a one-dimensional array.');
|
||||
}
|
||||
|
||||
array_walk($list, function (&$item) {
|
||||
$item = array($item);
|
||||
});
|
||||
return new self($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNodeType()
|
||||
{
|
||||
return 'Table';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table hash, formed by columns (ColumnsHash).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHash()
|
||||
{
|
||||
return $this->getColumnsHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table hash, formed by columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnsHash()
|
||||
{
|
||||
$rows = $this->getRows();
|
||||
$keys = array_shift($rows);
|
||||
|
||||
$hash = array();
|
||||
foreach ($rows as $row) {
|
||||
$hash[] = array_combine($keys, $row);
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table hash, formed by rows.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRowsHash()
|
||||
{
|
||||
$hash = array();
|
||||
|
||||
foreach ($this->getRows() as $row) {
|
||||
$hash[array_shift($row)] = (1 == count($row)) ? $row[0] : $row;
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns numerated table lines.
|
||||
* Line numbers are keys, lines are values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table rows.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRows()
|
||||
{
|
||||
return array_values($this->table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table definition lines.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLines()
|
||||
{
|
||||
return array_keys($this->table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns specific row in a table.
|
||||
*
|
||||
* @param integer $index Row number
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws NodeException If row with specified index does not exist
|
||||
*/
|
||||
public function getRow($index)
|
||||
{
|
||||
$rows = $this->getRows();
|
||||
|
||||
if (!isset($rows[$index])) {
|
||||
throw new NodeException(sprintf('Rows #%d does not exist in table.', $index));
|
||||
}
|
||||
|
||||
return $rows[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns specific column in a table.
|
||||
*
|
||||
* @param integer $index Column number
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws NodeException If column with specified index does not exist
|
||||
*/
|
||||
public function getColumn($index)
|
||||
{
|
||||
if ($index >= count($this->getRow(0))) {
|
||||
throw new NodeException(sprintf('Column #%d does not exist in table.', $index));
|
||||
}
|
||||
|
||||
$rows = $this->getRows();
|
||||
$column = array();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$column[] = $row[$index];
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns line number at which specific row was defined.
|
||||
*
|
||||
* @param integer $index
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @throws NodeException If row with specified index does not exist
|
||||
*/
|
||||
public function getRowLine($index)
|
||||
{
|
||||
$lines = array_keys($this->table);
|
||||
|
||||
if (!isset($lines[$index])) {
|
||||
throw new NodeException(sprintf('Rows #%d does not exist in table.', $index));
|
||||
}
|
||||
|
||||
return $lines[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts row into delimited string.
|
||||
*
|
||||
* @param integer $rowNum Row number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRowAsString($rowNum)
|
||||
{
|
||||
$values = array();
|
||||
foreach ($this->getRow($rowNum) as $column => $value) {
|
||||
$values[] = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2);
|
||||
}
|
||||
|
||||
return sprintf('|%s|', implode('|', $values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts row into delimited string.
|
||||
*
|
||||
* @param integer $rowNum Row number
|
||||
* @param callable $wrapper Wrapper function
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRowAsStringWithWrappedValues($rowNum, $wrapper)
|
||||
{
|
||||
$values = array();
|
||||
foreach ($this->getRow($rowNum) as $column => $value) {
|
||||
$value = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2);
|
||||
|
||||
$values[] = call_user_func($wrapper, $value, $column);
|
||||
}
|
||||
|
||||
return sprintf('|%s|', implode('|', $values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts entire table into string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTableAsString()
|
||||
{
|
||||
$lines = array();
|
||||
for ($i = 0; $i < count($this->getRows()); $i++) {
|
||||
$lines[] = $this->getRowAsString($i);
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns line number at which table was started.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
return $this->getRowLine(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts table into string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getTableAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a hash iterator.
|
||||
*
|
||||
* @return Iterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->getHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads string right.
|
||||
*
|
||||
* @param string $text Text to pad
|
||||
* @param integer $length Length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function padRight($text, $length)
|
||||
{
|
||||
while ($length > mb_strlen($text, 'utf8')) {
|
||||
$text = $text . ' ';
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
42
vendor/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php
vendored
Normal file
42
vendor/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin\Node;
|
||||
|
||||
/**
|
||||
* Gherkin tagged node interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface TaggedNodeInterface extends NodeInterface
|
||||
{
|
||||
/**
|
||||
* Checks if node is tagged with tag.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTag($tag);
|
||||
|
||||
/**
|
||||
* Checks if node has tags (both inherited from feature and own).
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasTags();
|
||||
|
||||
/**
|
||||
* Returns node tags (including inherited from feature).
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTags();
|
||||
}
|
||||
699
vendor/behat/gherkin/src/Behat/Gherkin/Parser.php
vendored
Normal file
699
vendor/behat/gherkin/src/Behat/Gherkin/Parser.php
vendored
Normal file
@@ -0,0 +1,699 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat Gherkin.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Gherkin;
|
||||
|
||||
use Behat\Gherkin\Exception\LexerException;
|
||||
use Behat\Gherkin\Exception\ParserException;
|
||||
use Behat\Gherkin\Node\BackgroundNode;
|
||||
use Behat\Gherkin\Node\ExampleTableNode;
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\OutlineNode;
|
||||
use Behat\Gherkin\Node\PyStringNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
use Behat\Gherkin\Node\ScenarioNode;
|
||||
use Behat\Gherkin\Node\StepNode;
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
|
||||
/**
|
||||
* Gherkin parser.
|
||||
*
|
||||
* $lexer = new Behat\Gherkin\Lexer($keywords);
|
||||
* $parser = new Behat\Gherkin\Parser($lexer);
|
||||
* $featuresArray = $parser->parse('/path/to/feature.feature');
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
private $lexer;
|
||||
private $input;
|
||||
private $file;
|
||||
private $tags = array();
|
||||
private $languageSpecifierLine;
|
||||
|
||||
/**
|
||||
* Initializes parser.
|
||||
*
|
||||
* @param Lexer $lexer Lexer instance
|
||||
*/
|
||||
public function __construct(Lexer $lexer)
|
||||
{
|
||||
$this->lexer = $lexer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses input & returns features array.
|
||||
*
|
||||
* @param string $input Gherkin string document
|
||||
* @param string $file File name
|
||||
*
|
||||
* @return FeatureNode|null
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
public function parse($input, $file = null)
|
||||
{
|
||||
$this->languageSpecifierLine = null;
|
||||
$this->input = $input;
|
||||
$this->file = $file;
|
||||
$this->tags = array();
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
$feature = null;
|
||||
while ('EOS' !== ($predicted = $this->predictTokenType())) {
|
||||
$node = $this->parseExpression();
|
||||
|
||||
if (null === $node || "\n" === $node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$feature && $node instanceof FeatureNode) {
|
||||
$feature = $node;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($feature && $node instanceof FeatureNode) {
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next token if it's type equals to expected.
|
||||
*
|
||||
* @param string $type Token type
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception\ParserException
|
||||
*/
|
||||
protected function expectTokenType($type)
|
||||
{
|
||||
$types = (array) $type;
|
||||
if (in_array($this->predictTokenType(), $types)) {
|
||||
return $this->lexer->getAdvancedToken();
|
||||
}
|
||||
|
||||
$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 : ''
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next token if it's type equals to expected.
|
||||
*
|
||||
* @param string $type Token type
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
protected function acceptTokenType($type)
|
||||
{
|
||||
if ($type !== $this->predictTokenType()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->lexer->getAdvancedToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next token type without real input reading (prediction).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function predictTokenType()
|
||||
{
|
||||
$token = $this->lexer->predictToken();
|
||||
|
||||
return $token['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses current expression & returns Node.
|
||||
*
|
||||
* @return string|FeatureNode|BackgroundNode|ScenarioNode|OutlineNode|TableNode|StepNode
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
protected function parseExpression()
|
||||
{
|
||||
switch ($type = $this->predictTokenType()) {
|
||||
case 'Feature':
|
||||
return $this->parseFeature();
|
||||
case 'Background':
|
||||
return $this->parseBackground();
|
||||
case 'Scenario':
|
||||
return $this->parseScenario();
|
||||
case 'Outline':
|
||||
return $this->parseOutline();
|
||||
case 'Examples':
|
||||
return $this->parseExamples();
|
||||
case 'TableRow':
|
||||
return $this->parseTable();
|
||||
case 'PyStringOp':
|
||||
return $this->parsePyString();
|
||||
case 'Step':
|
||||
return $this->parseStep();
|
||||
case 'Text':
|
||||
return $this->parseText();
|
||||
case 'Newline':
|
||||
return $this->parseNewline();
|
||||
case 'Tag':
|
||||
return $this->parseTags();
|
||||
case 'Comment':
|
||||
return $this->parseComment();
|
||||
case 'Language':
|
||||
return $this->parseLanguage();
|
||||
case 'EOS':
|
||||
return '';
|
||||
}
|
||||
|
||||
throw new ParserException(sprintf('Unknown token type: %s', $type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses feature token & returns it's node.
|
||||
*
|
||||
* @return FeatureNode
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
protected function parseFeature()
|
||||
{
|
||||
$token = $this->expectTokenType('Feature');
|
||||
|
||||
$title = trim($token['value']) ?: null;
|
||||
$description = null;
|
||||
$tags = $this->popTags();
|
||||
$background = null;
|
||||
$scenarios = array();
|
||||
$keyword = $token['keyword'];
|
||||
$language = $this->lexer->getLanguage();
|
||||
$file = $this->file;
|
||||
$line = $token['line'];
|
||||
|
||||
// Parse description, background, scenarios & outlines
|
||||
while ('EOS' !== $this->predictTokenType()) {
|
||||
$node = $this->parseExpression();
|
||||
|
||||
if (is_string($node)) {
|
||||
$text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
|
||||
$description .= (null !== $description ? "\n" : '') . $text;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$background && $node instanceof BackgroundNode) {
|
||||
$background = $node;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof ScenarioInterface) {
|
||||
$scenarios[] = $node;
|
||||
continue;
|
||||
}
|
||||
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return new FeatureNode(
|
||||
rtrim($title) ?: null,
|
||||
rtrim($description) ?: null,
|
||||
$tags,
|
||||
$background,
|
||||
$scenarios,
|
||||
$keyword,
|
||||
$language,
|
||||
$file,
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses background token & returns it's node.
|
||||
*
|
||||
* @return BackgroundNode
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
protected function parseBackground()
|
||||
{
|
||||
$token = $this->expectTokenType('Background');
|
||||
|
||||
$title = trim($token['value']);
|
||||
$keyword = $token['keyword'];
|
||||
$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 : ''
|
||||
));
|
||||
}
|
||||
|
||||
// Parse description and steps
|
||||
$steps = array();
|
||||
$allowedTokenTypes = array('Step', 'Newline', 'Text', 'Comment');
|
||||
while (in_array($this->predictTokenType(), $allowedTokenTypes)) {
|
||||
$node = $this->parseExpression();
|
||||
|
||||
if ($node instanceof StepNode) {
|
||||
$steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!count($steps) && is_string($node)) {
|
||||
$text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
|
||||
$title .= "\n" . $text;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("\n" === $node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_string($node)) {
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return new BackgroundNode(rtrim($title) ?: null, $steps, $keyword, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses scenario token & returns it's node.
|
||||
*
|
||||
* @return ScenarioNode
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
protected function parseScenario()
|
||||
{
|
||||
$token = $this->expectTokenType('Scenario');
|
||||
|
||||
$title = trim($token['value']);
|
||||
$tags = $this->popTags();
|
||||
$keyword = $token['keyword'];
|
||||
$line = $token['line'];
|
||||
|
||||
// Parse description and steps
|
||||
$steps = array();
|
||||
while (in_array($this->predictTokenType(), array('Step', 'Newline', 'Text', 'Comment'))) {
|
||||
$node = $this->parseExpression();
|
||||
|
||||
if ($node instanceof StepNode) {
|
||||
$steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!count($steps) && is_string($node)) {
|
||||
$text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
|
||||
$title .= "\n" . $text;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("\n" === $node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_string($node)) {
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return new ScenarioNode(rtrim($title) ?: null, $tags, $steps, $keyword, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses scenario outline token & returns it's node.
|
||||
*
|
||||
* @return OutlineNode
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
protected function parseOutline()
|
||||
{
|
||||
$token = $this->expectTokenType('Outline');
|
||||
|
||||
$title = trim($token['value']);
|
||||
$tags = $this->popTags();
|
||||
$keyword = $token['keyword'];
|
||||
$examples = null;
|
||||
$line = $token['line'];
|
||||
|
||||
// Parse description, steps and examples
|
||||
$steps = array();
|
||||
while (in_array($this->predictTokenType(), array('Step', 'Examples', 'Newline', 'Text', 'Comment'))) {
|
||||
$node = $this->parseExpression();
|
||||
|
||||
if ($node instanceof StepNode) {
|
||||
$steps[] = $this->normalizeStepNodeKeywordType($node, $steps);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($node instanceof ExampleTableNode) {
|
||||
$examples = $node;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!count($steps) && is_string($node)) {
|
||||
$text = preg_replace('/^\s{0,' . ($token['indent'] + 2) . '}|\s*$/', '', $node);
|
||||
$title .= "\n" . $text;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("\n" === $node) {
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
|
||||
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 : ''
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $examples) {
|
||||
throw new ParserException(sprintf(
|
||||
'Outline should have examples table, but got none for outline "%s" on line: %d%s',
|
||||
rtrim($title),
|
||||
$line,
|
||||
$this->file ? ' in file: ' . $this->file : ''
|
||||
));
|
||||
}
|
||||
|
||||
return new OutlineNode(rtrim($title) ?: null, $tags, $steps, $examples, $keyword, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses step token & returns it's node.
|
||||
*
|
||||
* @return StepNode
|
||||
*/
|
||||
protected function parseStep()
|
||||
{
|
||||
$token = $this->expectTokenType('Step');
|
||||
|
||||
$keyword = $token['value'];
|
||||
$keywordType = $token['keyword_type'];
|
||||
$text = trim($token['text']);
|
||||
$line = $token['line'];
|
||||
|
||||
$arguments = array();
|
||||
while (in_array($predicted = $this->predictTokenType(), array('PyStringOp', 'TableRow', 'Newline', 'Comment'))) {
|
||||
if ('Comment' === $predicted || 'Newline' === $predicted) {
|
||||
$this->acceptTokenType($predicted);
|
||||
continue;
|
||||
}
|
||||
|
||||
$node = $this->parseExpression();
|
||||
|
||||
if ($node instanceof PyStringNode || $node instanceof TableNode) {
|
||||
$arguments[] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
return new StepNode($keyword, $text, $arguments, $line, $keywordType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses examples table node.
|
||||
*
|
||||
* @return ExampleTableNode
|
||||
*/
|
||||
protected function parseExamples()
|
||||
{
|
||||
$token = $this->expectTokenType('Examples');
|
||||
|
||||
$keyword = $token['keyword'];
|
||||
|
||||
return new ExampleTableNode($this->parseTableRows(), $keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses table token & returns it's node.
|
||||
*
|
||||
* @return TableNode
|
||||
*/
|
||||
protected function parseTable()
|
||||
{
|
||||
return new TableNode($this->parseTableRows());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses PyString token & returns it's node.
|
||||
*
|
||||
* @return PyStringNode
|
||||
*/
|
||||
protected function parsePyString()
|
||||
{
|
||||
$token = $this->expectTokenType('PyStringOp');
|
||||
|
||||
$line = $token['line'];
|
||||
|
||||
$strings = array();
|
||||
while ('PyStringOp' !== ($predicted = $this->predictTokenType()) && 'Text' === $predicted) {
|
||||
$token = $this->expectTokenType('Text');
|
||||
|
||||
$strings[] = $token['value'];
|
||||
}
|
||||
|
||||
$this->expectTokenType('PyStringOp');
|
||||
|
||||
return new PyStringNode($strings, $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses tags.
|
||||
*
|
||||
* @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string
|
||||
*/
|
||||
protected function parseTags()
|
||||
{
|
||||
$token = $this->expectTokenType('Tag');
|
||||
$this->tags = array_merge($this->tags, $token['tags']);
|
||||
|
||||
return $this->parseExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current set of tags and clears tag buffer.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function popTags()
|
||||
{
|
||||
$tags = $this->tags;
|
||||
$this->tags = array();
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses next text line & returns it.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parseText()
|
||||
{
|
||||
$token = $this->expectTokenType('Text');
|
||||
|
||||
return $token['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses next newline & returns \n.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parseNewline()
|
||||
{
|
||||
$this->expectTokenType('Newline');
|
||||
|
||||
return "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses next comment token & returns it's string content.
|
||||
*
|
||||
* @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string
|
||||
*/
|
||||
protected function parseComment()
|
||||
{
|
||||
$this->expectTokenType('Comment');
|
||||
|
||||
return $this->parseExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses language block and updates lexer configuration based on it.
|
||||
*
|
||||
* @return BackgroundNode|FeatureNode|OutlineNode|ScenarioNode|StepNode|TableNode|string
|
||||
*
|
||||
* @throws ParserException
|
||||
*/
|
||||
protected function parseLanguage()
|
||||
{
|
||||
$token = $this->expectTokenType('Language');
|
||||
|
||||
if (null === $this->languageSpecifierLine) {
|
||||
$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 : ''
|
||||
));
|
||||
}
|
||||
|
||||
return $this->parseExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
$this->acceptTokenType($predicted);
|
||||
continue;
|
||||
}
|
||||
|
||||
$token = $this->expectTokenType('TableRow');
|
||||
|
||||
$table[$token['line']] = $token['columns'];
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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())
|
||||
{
|
||||
if (in_array($node->getKeywordType(), array('And', 'But'))) {
|
||||
if (($prev = end($steps))) {
|
||||
$keywordType = $prev->getKeywordType();
|
||||
} else {
|
||||
$keywordType = 'Given';
|
||||
}
|
||||
|
||||
$node = new StepNode(
|
||||
$node->getKeyword(),
|
||||
$node->getText(),
|
||||
$node->getArguments(),
|
||||
$node->getLine(),
|
||||
$keywordType
|
||||
);
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user