public function addSnippet(StepNode $step) { $args = []; $pattern = $step->getText(); // match numbers (not in quotes) if (preg_match_all('~([\\d\\.])(?=([^"]*"[^"]*")*[^"]*$)~', $pattern, $matches)) { foreach ($matches[1] as $num => $param) { $num++; $args[] = '$num' . $num; $pattern = str_replace($param, ":num{$num}", $pattern); } } // match quoted string if (preg_match_all('~"(.*?)"~', $pattern, $matches)) { foreach ($matches[1] as $num => $param) { $num++; $args[] = '$arg' . $num; $pattern = str_replace('"' . $param . '"', ":arg{$num}", $pattern); } } if (in_array($pattern, $this->processed)) { return; } $methodName = preg_replace('~(\\s+?|\'|\\"|\\W)~', '', ucwords(preg_replace('~"(.*?)"|\\d+~', '', $step->getText()))); $this->snippets[] = (new Template($this->template))->place('type', $step->getKeywordType())->place('text', $pattern)->place('methodName', lcfirst($methodName))->place('params', implode(', ', $args))->produce(); $this->processed[] = $pattern; }
/** * Checks if Feature matches specified filter. * * @param StepNode $step * @param string $filterString * * @return Boolean */ private function isStepMatch(StepNode $step, $filterString) { if ('/' === $filterString[0]) { return 1 === preg_match($filterString, $step->getText()); } return false !== mb_strpos($step->getText(), $filterString, 0, 'utf8'); }
public function testTokens() { $step = new StepNode('When', 'Some "<text>" in <string>'); $step->setTokens(array('text' => 'change')); $this->assertEquals('Some "change" in <string>', $step->getText()); $this->assertEquals('Some "<text>" in <string>', $step->getCleanText()); $step->setTokens(array('text' => 'change', 'string' => 'browser')); $this->assertEquals('Some "change" in browser', $step->getText()); $this->assertEquals('Some "<text>" in <string>', $step->getCleanText()); }
/** * Loads definitions and translations from provided context. * * @param ContextInterface $context * @param StepNode $step * * @return DefinitionSnippet */ public function propose(ContextInterface $context, StepNode $step) { $contextRefl = new \ReflectionObject($context); $contextClass = $contextRefl->getName(); $replacePatterns = array("/(?<= |^)\\\\'(?:((?!\\').)*)\\\\'(?= |\$)/", '/(?<= |^)\\"(?:[^\\"]*)\\"(?= |$)/', '/(\\d+)/'); $text = $step->getText(); $text = preg_replace('/([\\/\\[\\]\\(\\)\\\\^\\$\\.\\|\\?\\*\\+\'])/', '\\\\$1', $text); $regex = preg_replace($replacePatterns, array("\\'([^\\']*)\\'", "\"([^\"]*)\"", "(\\d+)"), $text); preg_match('/' . $regex . '/', $step->getText(), $matches); $count = count($matches) - 1; $methodName = preg_replace($replacePatterns, '', $text); $methodName = Transliterator::transliterate($methodName, ' '); $methodName = preg_replace('/[^a-zA-Z\\_\\ ]/', '', $methodName); $methodName = str_replace(' ', '', ucwords($methodName)); if (0 !== strlen($methodName)) { $methodName[0] = strtolower($methodName[0]); } else { $methodName = 'stepDefinition1'; } // get method number from method name $methodNumber = 2; if (preg_match('/(\\d+)$/', $methodName, $matches)) { $methodNumber = intval($matches[1]); } // check that proposed method name isn't arelady defined in context while ($contextRefl->hasMethod($methodName)) { $methodName = preg_replace('/\\d+$/', '', $methodName); $methodName .= $methodNumber++; } // check that proposed method name haven't been proposed earlier if (isset(self::$proposedMethods[$contextClass])) { foreach (self::$proposedMethods[$contextClass] as $proposedRegex => $proposedMethod) { if ($proposedRegex !== $regex) { while ($proposedMethod === $methodName) { $methodName = preg_replace('/\\d+$/', '', $methodName); $methodName .= $methodNumber++; } } } } self::$proposedMethods[$contextClass][$regex] = $methodName; $args = array(); for ($i = 0; $i < $count; $i++) { $args[] = "\$arg" . ($i + 1); } foreach ($step->getArguments() as $argument) { if ($argument instanceof PyStringNode) { $args[] = "PyStringNode \$string"; } elseif ($argument instanceof TableNode) { $args[] = "TableNode \$table"; } } $description = $this->generateSnippet($regex, $methodName, $args); return new DefinitionSnippet($step, $description); }
public function testText() { $step = new StepNode('When'); $this->assertNull($step->getText()); $step->setText('Some definition'); $this->assertEquals('Some definition', $step->getText()); $step = new StepNode('When', 'Some action'); $this->assertEquals('Some action', $step->getText()); $step->setText('Some "<text>" in <string>'); $this->assertEquals('Some "<text>" in <string>', $step->getText()); }
public function addSnippet(StepNode $step) { $args = []; $pattern = $step->getText(); if (preg_match_all('~"(.*?)"~', $pattern, $matches)) { foreach ($matches[1] as $num => $param) { $num++; $args[] = '$arg' . $num; $pattern = str_replace('"' . $param . '"', ":arg{$num}", $pattern); } } $methodName = preg_replace('~(\\s+?|\'|\\")~', '', ucwords(preg_replace('~"(.*?)"~', '', $step->getText()))); $this->snippets[] = (new Template($this->template))->place('type', $step->getKeywordType())->place('text', $pattern)->place('methodName', lcfirst($methodName))->place('params', implode(', ', $args))->produce(); }
/** * Loads definitions and translations from provided context. * * @param ContextInterface $context * @param StepNode $step * * @return DefinitionSnippet */ public function propose(ContextInterface $context, StepNode $step) { $text = $step->getText(); $regex = preg_replace('/([\\/\\[\\]\\(\\)\\\\^\\$\\.\\|\\?\\*\\+\'])/', '\\\\$1', $text); $regex = preg_replace(array("/(?<= |^)\\\\'(?:((?!\\').)*)\\\\'(?= |\$)/", '/(?<= |^)\\"(?:[^\\"]*)\\"(?= |$)/', '/(\\d+)/'), array("\\'([^\\']*)\\'", "\"([^\"]*)\"", "(\\d+)"), $regex); preg_match('/' . $regex . '/', $text, $matches); $count = count($matches) - 1; $args = array("\$world"); for ($i = 0; $i < $count; $i++) { $args[] = "\$arg" . ($i + 1); } foreach ($step->getArguments() as $argument) { if ($argument instanceof PyStringNode) { $args[] = "\$string"; } elseif ($argument instanceof TableNode) { $args[] = "\$table"; } } $description = sprintf(<<<PHP \$steps->%s('/^%s\$/', function(%s) { throw new \\Behat\\Behat\\Exception\\PendingException(); }); PHP , '%s', $regex, implode(', ', $args)); return new DefinitionSnippet($step, $description); }
/** * {@inheritdoc} */ public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result) { $this->printText($formatter->getOutputPrinter(), $step->getKeyword(), $step->getText(), $result); $this->pathPrinter->printStepPath($formatter, $scenario, $step, $result, mb_strlen($this->indentText, 'utf8')); $this->printArguments($formatter, $step->getArguments(), $result); $this->printStdOut($formatter->getOutputPrinter(), $result); $this->printException($formatter->getOutputPrinter(), $result); }
/** * {@inheritdoc} */ public function generateSnippet(Environment $environment, StepNode $step) { if (!$environment instanceof ContextEnvironment) { throw new EnvironmentSnippetGenerationException(sprintf('ContextSnippetGenerator does not support `%s` environment.', get_class($environment)), $environment); } $contextClass = $this->getSnippetAcceptingContextClass($environment); $patternType = $this->getPatternType($contextClass); $stepText = $step->getText(); $pattern = $this->patternTransformer->generatePattern($patternType, $stepText); $methodName = $this->getMethodName($contextClass, $pattern->getCanonicalText(), $pattern->getPattern()); $methodArguments = $this->getMethodArguments($step, $pattern->getPlaceholderCount()); $snippetTemplate = $this->getSnippetTemplate($pattern->getPattern(), $methodName, $methodArguments); return new ContextSnippet($step, $snippetTemplate, $contextClass); }
/** * {@inheritdoc} * * @throws AmbiguousMatchException */ public function searchDefinition(Environment $environment, FeatureNode $feature, StepNode $step) { $suite = $environment->getSuite(); $language = $feature->getLanguage(); $stepText = $step->getText(); $multi = $step->getArguments(); $definitions = array(); $result = null; foreach ($this->repository->getEnvironmentDefinitions($environment) as $definition) { $definition = $this->translator->translateDefinition($suite, $definition, $language); if (!($newResult = $this->match($definition, $stepText, $multi))) { continue; } $result = $newResult; $definitions[] = $newResult->getMatchedDefinition(); } if (count($definitions) > 1) { throw new AmbiguousMatchException($result->getMatchedText(), $definitions); } return $result; }
/** * Prints step using provided printer. * * @param Formatter $formatter * @param Scenario $scenario * @param StepNode $step * @param StepResult $result */ public function printStep(Formatter $formatter, Scenario $scenario, StepNode $step, StepResult $result) { /** @var JUnitOutputPrinter $outputPrinter */ $outputPrinter = $formatter->getOutputPrinter(); $message = $step->getKeyword() . ' ' . $step->getText(); if ($result instanceof ExceptionResult && $result->hasException()) { $message .= ': ' . $this->exceptionPresenter->presentException($result->getException()); } $attributes = array('message' => $message); switch ($result->getResultCode()) { case TestResult::FAILED: $outputPrinter->addTestcaseChild('failure', $attributes); break; case TestResult::PENDING: $attributes['type'] = 'pending'; $outputPrinter->addTestcaseChild('error', $attributes); break; case StepResult::UNDEFINED: $attributes['type'] = 'undefined'; $outputPrinter->addTestcaseChild('error', $attributes); break; } }
protected function runStep(StepNode $stepNode) { $params = []; if ($stepNode->hasArguments()) { $args = $stepNode->getArguments(); $table = $args[0]; if ($table instanceof TableNode) { $params = [$table->getTableAsString()]; } } $meta = new Meta($stepNode->getText(), $params); $meta->setPrefix($stepNode->getKeyword()); $this->scenario->setMetaStep($meta); // enable metastep $stepText = $stepNode->getText(); $this->getScenario()->comment(null); // make metastep to be printed even if no steps foreach ($this->steps as $pattern => $context) { $matches = []; if (!preg_match($pattern, $stepText, $matches)) { continue; } array_shift($matches); if ($stepNode->hasArguments()) { $matches = array_merge($matches, $stepNode->getArguments()); } call_user_func_array($context, $matches); // execute the step break; } $this->scenario->setMetaStep(null); // disable metastep }
/** * 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; }
/** * @param FeatureNode $featureNode * @param StepNode $stepNode * @return ScenarioInterface|null */ private function detectScenario(FeatureNode $featureNode, StepNode $stepNode) { foreach ($featureNode->getScenarios() as $scenario) { foreach ($scenario->getSteps() as $step) { if ($step->getLine() === $stepNode->getLine() && $step->getText() === $stepNode->getText()) { return $scenario; } } } return null; }
/** * Prints path to step. * * @param Behat\Gherkin\Node\StepNode $step step node * @param Behat\Behat\Definition\Definition $definition definition (if step defined) * @param Exception $exception exception (if step failed) */ protected function printStepPath(StepNode $step, Definition $definition = null, \Exception $exception = null) { $color = $exception instanceof Pending ? 'pending' : 'failed'; $type = $step->getType(); $text = $step->getText(); $stepPath = "In step `{$type} {$text}'."; $stepPathLn = mb_strlen($stepPath); $node = $step->getParent(); if ($node instanceof BackgroundNode) { $scenarioPath = "From scenario background."; } else { $title = $node->getTitle(); $title = $title ? "`{$title}'" : '***'; $scenarioPath = "From scenario {$title}."; } $scenarioPathLn = mb_strlen($scenarioPath); $this->maxLineLength = max($this->maxLineLength, $stepPathLn); $this->maxLineLength = max($this->maxLineLength, $scenarioPathLn); $this->write(" {+{$color}}{$stepPath}{-{$color}}"); if (null !== $definition) { $indentCount = $this->maxLineLength - $stepPathLn; $this->printPathComment($definition->getFile(), $definition->getLine(), $indentCount); } else { $this->writeln(); } $this->write(" {+{$color}}{$scenarioPath}{-{$color}}"); $indentCount = $this->maxLineLength - $scenarioPathLn; $this->printPathComment($node->getFile(), $node->getLine(), $indentCount); $this->writeln(); }
/** * Calculates step width. * * @param StepNode $step * @param integer $indentation * * @return integer */ public function calculateStepWidth(StepNode $step, $indentation) { $indentText = str_repeat(' ', intval($indentation)); $text = sprintf('%s%s %s', $indentText, $step->getKeyword(), $step->getText()); return mb_strlen($text, 'utf8'); }
/** * Dumps a step. * * @param StepNode $step Step node instance * * @return string * * @throws Exception if invalid step type providen */ public function dumpStep(StepNode $step) { switch ($step->getType()) { case 'Given': $kw = $this->keywords->getGivenKeywords(); break; case 'When': $kw = $this->keywords->getWhenKeywords(); break; case 'Then': $kw = $this->keywords->getThenKeywords(); break; case 'But': $kw = $this->keywords->getButKeywords(); break; case 'And': $kw = $this->keywords->getAndKeywords(); break; default: throw new Exception("invalid type given : " . $step->getType()); } return $this->dumpText($kw . ' ' . $step->getText()); }
/** * @param StepNode $step * * @return string */ private function getStepText(StepNode $step) { $spacesQuantity = $this->computeIndentationSpaces($step->getKeyword()); return rtrim(sprintf('%s%s %s', $this->indent($spacesQuantity + self::INDENTATION), trim($step->getKeyword()), trim($step->getText()))) . "\n"; }
/** * Prints step definition path. * * @param Behat\Gherkin\Node\StepNode $step step node * @param Behat\Behat\Definition\Definition $definition definition (if found one) * * @uses printPathComment() */ protected function printStepDefinitionPath(StepNode $step, Definition $definition) { $type = $step->getType(); $text = $this->inOutlineSteps ? $step->getCleanText() : $step->getText(); $nameLength = mb_strlen(" {$type} {$text}"); $indentCount = $nameLength > $this->maxLineLength ? 0 : $this->maxLineLength - $nameLength; $this->printPathComment($definition->getFile(), $definition->getLine(), $indentCount); }
/** * add results for step tests * @param FeatureNode $feature object * @param ScenarioInterface $scenario object * @param StepNode $step object * @param TestResult $testResult object * @return null */ public function addStepResult(FeatureNode $feature, ScenarioInterface $scenario, StepNode $step, TestResult $testResult) { $featurePath = $feature->getFile(); $scenarioLine = $scenario->getLine(); $this->testResults[$featurePath]["scenarios"][$scenarioLine]["steps"][$step->getLine()] = ["name" => $step->getText(), "line" => $step->getLine(), "testResultCode" => $testResult->getResultCode(), "testResult" => self::RESULT_CODES_MAPPING[$testResult->getResultCode()]]; }
/** * Returns a valid filename without path * * @param StepNode $step * * @return string */ public function convertStepToFileName(StepNode $step) { return preg_replace('/[^A-Za-z0-9\\-]/', '_', mb_strtolower($step->getText())) . '.png'; }
/** * Prints step. * * @param [StepNode] $step step node * @param [integer] $result step result code * @param [DefinitionInterface] $definition def instance (if step defined) * @param [string] $snippet snippet (if step is undefined) * @param [\Exception] $exception exception (if step is failed) * @return [void] * * @uses StepEvent */ protected function printStep(StepNode $step, $result, DefinitionInterface $definition = null, $snippet = null, \Exception $exception = null) { $this->_feature_info = array('result' => $result, 'text' => $step->getText()); if ($exception != null) { $this->_feature_info['message'] = $exception->getMessage(); } }
/** * @see Behat\Behat\Definition\Proposal\DefinitionProposalInterface::propose() */ public function propose(ContextInterface $context, StepNode $step) { $contextRefl = new \ReflectionObject($context); $contextClass = $contextRefl->getName(); $text = $step->getText(); $replacePatterns = array('/\'([^\']*)\'/', '/\\"([^\\"]*)\\"/', '/(\\d+)/'); $regex = preg_replace('/([\\/\\[\\]\\(\\)\\\\^\\$\\.\\|\\?\\*\\+])/', '\\\\$1', $text); $regex = preg_replace($replacePatterns, array("\\'([^\\']*)\\'", "\"([^\"]*)\"", "(\\d+)"), $regex); // Single quotes without matching pair (escape in resulting regex): $regex = preg_replace('/\'.*(?<!\')/', '\\\\$0', $regex); preg_match('/' . $regex . '/', $text, $matches); $count = count($matches) - 1; $methodName = preg_replace($replacePatterns, '', $text); $methodName = Transliterator::transliterate($methodName, ' '); $methodName = preg_replace('/[^a-zA-Z\\_\\ ]/', '', $methodName); $methodName = str_replace(' ', '', ucwords($methodName)); if (0 !== strlen($methodName)) { $methodName[0] = strtolower($methodName[0]); } else { $methodName = 'stepDefinition1'; } // get method number from method name $methodNumber = 2; if (preg_match('/(\\d+)$/', $methodName, $matches)) { $methodNumber = intval($matches[1]); } // check that proposed method name isn't arelady defined in context while ($contextRefl->hasMethod($methodName)) { $methodName = preg_replace('/\\d+$/', '', $methodName); $methodName .= $methodNumber++; } // check that proposed method name haven't been proposed earlier if (isset(self::$proposedMethods[$contextClass])) { foreach (self::$proposedMethods[$contextClass] as $proposedRegex => $proposedMethod) { if ($proposedRegex !== $regex) { while ($proposedMethod === $methodName) { $methodName = preg_replace('/\\d+$/', '', $methodName); $methodName .= $methodNumber++; } } } } self::$proposedMethods[$contextClass][$regex] = $methodName; $args = array(); for ($i = 0; $i < $count; $i++) { $args[] = "\$argument" . ($i + 1); } foreach ($step->getArguments() as $argument) { if ($argument instanceof PyStringNode) { $args[] = "PyStringNode \$string"; } elseif ($argument instanceof TableNode) { $args[] = "TableNode \$table"; } } $description = sprintf(<<<PHP /** * @%s /^%s\$/ */ public function %s(%s) { throw new PendingException(); } PHP , '%s', $regex, $methodName, implode(', ', $args)); return new DefinitionSnippet($step, $description); }
/** * {@inheritdoc} */ protected function printStepName(StepNode $step, DefinitionInterface $definition = null, $color) { $type = $step->getType(); $text = $this->inOutlineSteps ? $step->getCleanText() : $step->getText(); if (null !== $definition) { $text = $this->colorizeDefinitionArguments($text, $definition, $color); } $this->writeln('<span class="keyword">' . $type . ' </span>'); $this->writeln('<span class="text">' . $text . '</span>'); }
/** * Finds step definition, that match specified step. * * @param Behat\Gherkin\Node\StepNode $step found step * * @return Behat\Behat\Definition\Definition * * @uses loadDefinitions() * * @throws Behat\Behat\Exception\Ambiguous if step description is ambiguous * @throws Behat\Behat\Exception\Undefined if step definition not found */ public function findDefinition(StepNode $step) { if (!count($this->definitions)) { $this->loadDefinitions(); } $text = $step->getText(); $multiline = $step->getArguments(); $matches = array(); // find step to match foreach ($this->definitions as $origRegex => $definition) { $transRegex = $this->translateDefinitionRegex($origRegex, $step->getLanguage()); if (preg_match($origRegex, $text, $arguments) || $origRegex !== $transRegex && preg_match($transRegex, $text, $arguments)) { // prepare callback arguments $arguments = $this->prepareCallbackArguments($definition->getCallbackReflection(), array_slice($arguments, 1), $multiline); // transform arguments foreach ($arguments as $num => $argument) { foreach ($this->transformations as $transformation) { if ($newArgument = $transformation->transform($argument)) { $arguments[$num] = $newArgument; } } } // set matched definition $definition->setMatchedText($text); $definition->setValues($arguments); $matches[] = $definition; } } if (count($matches) > 1) { throw new Ambiguous($text, $matches); } if (0 === count($matches)) { throw new Undefined($text); } return $matches[0]; }
function it_generates_a_sanitized_filename_for_a_scenario_step(StepNode $step) { $step->getText()->willReturn('When I 1st click the link wi-fi on "fsf.org".'); $this->convertStepToFileName($step)->shouldReturn('when_i_1st_click_the_link_wi-fi_on__fsf_org__.png'); }
/** * Prints step definition path. * * @param StepNode $step step node * @param DefinitionInterface $definition definition (if found one) * * @uses printPathComment() */ protected function printStepDefinitionPath(StepNode $step, DefinitionInterface $definition) { if ($this->getParameter('paths')) { $type = $step->getType(); $text = $this->inOutlineSteps ? $step->getCleanText() : $step->getText(); $indent = $this->stepIndent; $nameLength = mb_strlen("{$indent}{$type} {$text}"); $indentCount = $nameLength > $this->maxLineLength ? 0 : $this->maxLineLength - $nameLength; $this->printPathComment($this->relativizePathsInString($definition->getPath()), $indentCount); if ($this->getParameter('expand')) { $this->maxLineLength = max($this->maxLineLength, $nameLength); } } else { $this->writeln(); } }
/** * Executes steps chain (if there's one). * * Overwriten method to run behat hooks between chain steps. * * @param StepNode $step step node * @param mixed $chain chain * * @throws \Exception */ private function executeStepsChainWithHooks(StepNode $step, $chain = null) { if (null === $chain) { // If there are no more chained steps below we will dispatch the // after step event, skipping the step that looks for exceptions here. if (strstr($step->getText(), self::EXCEPTIONS_STEP_TEXT) === false) { $this->dispatchafterstep = true; } return; } $chain = is_array($chain) ? $chain : array($chain); foreach ($chain as $chainItem) { if ($chainItem instanceof SubstepInterface) { $substepNode = $chainItem->getStepNode(); $substepNode->setParent($step->getParent()); // Replace by tokens when needed. if ($substepNode->getParent() instanceof OutlineNode) { $substepNode = $substepNode->createExampleRowStep($this->tokens); } $this->dispatchafterstep = false; // Dispatch beforeStep event. $this->moodledispatcher->dispatch('beforeStep', new StepEvent($substepNode, $this->moodlelogicalParent, $this->moodlecontext)); $substepEvent = $this->executeStep($substepNode); // Dispatch afterStep event. if ($this->dispatchafterstep === true) { $this->moodledispatcher->dispatch('afterStep', $substepEvent); $this->dispatchafterstep = false; } // Here we mark the step as failed so parent steps in the chain // will not continue dispatching the afterStep event. if (StepEvent::PASSED !== $substepEvent->getResult()) { $this->failedstep = true; throw $substepEvent->getException(); } } elseif (is_callable($chainItem)) { $this->executeStepsChainWithHooks($step, call_user_func($chainItem)); } } }
/** * Finds step definition, that match specified step. * * @param ContextInterface $context * @param StepNode $step * @param bool $skip * * @return Definition * * @uses loadDefinitions() * * @throws AmbiguousException if step description is ambiguous * @throws UndefinedException if step definition not found */ public function findDefinition(ContextInterface $context, StepNode $step, $skip = false) { $text = $step->getText(); $multiline = $step->getArguments(); $matches = array(); // find step to match foreach ($this->getDefinitions() as $origRegex => $definition) { $transRegex = $this->translateDefinitionRegex($origRegex, $step->getLanguage()); // if not regex really (string) - transform into it if (0 !== strpos($origRegex, '/')) { $origRegex = '/^' . preg_quote($origRegex, '/') . '$/'; $transRegex = '/^' . preg_quote($transRegex, '/') . '$/'; } if (preg_match($origRegex, $text, $arguments) || $origRegex !== $transRegex && preg_match($transRegex, $text, $arguments)) { // prepare callback arguments $arguments = $this->prepareCallbackArguments($context, $definition->getCallbackReflection(), array_slice($arguments, 1), $multiline); if (!$skip) { // transform arguments foreach ($arguments as &$argument) { foreach ($this->getTransformations() as $trans) { $transRegex = $this->translateDefinitionRegex($trans->getRegex(), $step->getLanguage()); $newArgument = $trans->transform($transRegex, $context, $argument); if (null !== $newArgument) { $argument = $newArgument; } } } } // set matched definition $definition->setMatchedText($text); $definition->setValues($arguments); $matches[] = $definition; } } if (count($matches) > 1) { throw new AmbiguousException($text, $matches); } if (0 === count($matches)) { throw new UndefinedException($text); } return $matches[0]; }
/** * Returns the relative file path for the given step * * @param StepNode $step * @return string */ protected function getFilepath($step) { return sprintf('%s/%s/%d-%s.png', $this->formatString($this->currentScenario->getFeature()->getTitle()), $this->formatString($this->currentScenario->getTitle()), $this->stepNumber, $this->formatString($step->getText())); }