4 * This file is part of the Behat.
5 * (c) Konstantin Kudryashov <ever.zet@gmail.com>
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
11 namespace Behat\Behat\Gherkin\Specification;
13 use Behat\Gherkin\Filter\FilterInterface;
14 use Behat\Gherkin\Filter\NameFilter;
15 use Behat\Gherkin\Filter\NarrativeFilter;
16 use Behat\Gherkin\Filter\RoleFilter;
17 use Behat\Gherkin\Filter\TagFilter;
18 use Behat\Gherkin\Gherkin;
19 use Behat\Gherkin\Node\FeatureNode;
20 use Behat\Testwork\Specification\SpecificationIterator;
21 use Behat\Testwork\Suite\Exception\SuiteConfigurationException;
22 use Behat\Testwork\Suite\Suite;
25 * Lazily iterates (parses one-by-one) over features.
27 * @author Konstantin Kudryashov <ever.zet@gmail.com>
29 final class LazyFeatureIterator implements SpecificationIterator
42 private $paths = array();
44 * @var FilterInterface[]
46 private $filters = array();
50 private $position = 0;
54 private $features = array();
58 private $currentFeature;
61 * Initializes specifications.
64 * @param Gherkin $gherkin
65 * @param string[] $paths
66 * @param FilterInterface[] $filters
68 public function __construct(Suite $suite, Gherkin $gherkin, array $paths, array $filters = array())
70 $this->suite = $suite;
71 $this->gherkin = $gherkin;
72 $this->paths = array_values($paths);
73 $this->filters = array_merge($this->getSuiteFilters($suite), $filters);
79 public function getSuite()
87 public function rewind()
90 $this->moveToNextAvailableFeature();
96 public function next()
98 $this->moveToNextAvailableFeature();
104 public function valid()
106 return null !== $this->currentFeature;
112 public function key()
114 return $this->position;
120 public function current()
122 return $this->currentFeature;
126 * Returns list of filters from suite settings.
128 * @param Suite $suite
130 * @return FilterInterface[]
132 private function getSuiteFilters(Suite $suite)
134 if (!$suite->hasSetting('filters') || !is_array($suite->getSetting('filters'))) {
139 foreach ($suite->getSetting('filters') as $type => $filterString) {
140 $filters[] = $this->createFilter($type, $filterString, $suite);
147 * Creates filter of provided type.
149 * @param string $type
150 * @param string $filterString
151 * @param Suite $suite
153 * @return FilterInterface
155 * @throws SuiteConfigurationException If filter type is not recognised
157 private function createFilter($type, $filterString, Suite $suite)
159 if ('role' === $type) {
160 return new RoleFilter($filterString);
163 if ('name' === $type) {
164 return new NameFilter($filterString);
167 if ('tags' === $type) {
168 return new TagFilter($filterString);
171 if ('narrative' === $type) {
172 return new NarrativeFilter($filterString);
175 throw new SuiteConfigurationException(sprintf(
176 '`%s` filter is not supported by the `%s` suite. Supported types are `%s`.',
179 implode('`, `', array('role', 'name', 'tags'))
180 ), $suite->getName());
184 * Parses paths consequently.
186 private function moveToNextAvailableFeature()
188 while (!count($this->features) && $this->position < count($this->paths)) {
189 $this->features = $this->parseFeature($this->paths[$this->position]);
193 $this->currentFeature = array_shift($this->features);
197 * Parses feature at path.
199 * @param string $path
201 * @return FeatureNode[]
203 private function parseFeature($path)
205 return $this->gherkin->load($path, $this->filters);