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\Definition\Search;
13 use Behat\Behat\Definition\Definition;
14 use Behat\Behat\Definition\DefinitionRepository;
15 use Behat\Behat\Definition\Exception\AmbiguousMatchException;
16 use Behat\Behat\Definition\Pattern\PatternTransformer;
17 use Behat\Behat\Definition\SearchResult;
18 use Behat\Behat\Definition\Translator\DefinitionTranslator;
19 use Behat\Gherkin\Node\ArgumentInterface;
20 use Behat\Gherkin\Node\FeatureNode;
21 use Behat\Gherkin\Node\StepNode;
22 use Behat\Testwork\Argument\ArgumentOrganiser;
23 use Behat\Testwork\Environment\Environment;
26 * Searches for a step definition using definition repository.
28 * @see DefinitionRepository
30 * @author Konstantin Kudryashov <ever.zet@gmail.com>
32 final class RepositorySearchEngine implements SearchEngine
35 * @var DefinitionRepository
39 * @var PatternTransformer
41 private $patternTransformer;
43 * @var DefinitionTranslator
47 * @var ArgumentOrganiser
49 private $argumentOrganiser;
52 * Initializes search engine.
54 * @param DefinitionRepository $repository
55 * @param PatternTransformer $patternTransformer
56 * @param DefinitionTranslator $translator
57 * @param ArgumentOrganiser $argumentOrganiser
59 public function __construct(
60 DefinitionRepository $repository,
61 PatternTransformer $patternTransformer,
62 DefinitionTranslator $translator,
63 ArgumentOrganiser $argumentOrganiser
65 $this->repository = $repository;
66 $this->patternTransformer = $patternTransformer;
67 $this->translator = $translator;
68 $this->argumentOrganiser = $argumentOrganiser;
74 * @throws AmbiguousMatchException
76 public function searchDefinition(
77 Environment $environment,
81 $suite = $environment->getSuite();
82 $language = $feature->getLanguage();
83 $stepText = $step->getText();
84 $multi = $step->getArguments();
86 $definitions = array();
89 foreach ($this->repository->getEnvironmentDefinitions($environment) as $definition) {
90 $definition = $this->translator->translateDefinition($suite, $definition, $language);
92 if (!$newResult = $this->match($definition, $stepText, $multi)) {
97 $definitions[] = $newResult->getMatchedDefinition();
100 if (count($definitions) > 1) {
101 throw new AmbiguousMatchException($result->getMatchedText(), $definitions);
108 * Attempts to match provided definition against a step text.
110 * @param Definition $definition
111 * @param string $stepText
112 * @param ArgumentInterface[] $multiline
114 * @return null|SearchResult
116 private function match(Definition $definition, $stepText, array $multiline)
118 $regex = $this->patternTransformer->transformPatternToRegex($definition->getPattern());
120 if (!preg_match($regex, $stepText, $match)) {
124 $function = $definition->getReflection();
125 $match = array_merge($match, array_values($multiline));
126 $arguments = $this->argumentOrganiser->organiseArguments($function, $match);
128 return new SearchResult($definition, $stepText, $arguments);