/** * Adds definition to dispatcher. * * @param DefinitionInterface $definition * * @throws RedundantException */ public function addDefinition(DefinitionInterface $definition) { $regex = $definition->getRegex(); if (isset($this->definitions[$regex])) { throw new RedundantException($definition, $this->definitions[$regex]); } $this->definitions[$regex] = $definition; }
/** * Returns step text with colorized arguments. * * @param string $text * @param DefinitionInterface $definition * @param string $color * * @return string */ protected function colorizeDefinitionArguments($text, DefinitionInterface $definition, $color) { $regex = $definition->getRegex(); $paramColor = $color . '_param'; // If it's just a string - skip if ('/' !== substr($regex, 0, 1)) { return $text; } // Find arguments with offsets $matches = array(); preg_match($regex, $text, $matches, PREG_OFFSET_CAPTURE); array_shift($matches); // Replace arguments with colorized ones $shift = 0; $lastReplacementPosition = 0; foreach ($matches as $key => $match) { if (!is_numeric($key) || -1 === $match[1] || false !== strpos($match[0], '<')) { continue; } $offset = $match[1] + $shift; $value = $match[0]; // Skip inner matches if ($lastReplacementPosition > $offset) { continue; } $lastReplacementPosition = $offset + strlen($value); $begin = substr($text, 0, $offset); $end = substr($text, $lastReplacementPosition); $format = "{-{$color}}{+{$paramColor}}%s{-{$paramColor}}{+{$color}}"; $text = sprintf("%s{$format}%s", $begin, $value, $end); // Keep track of how many extra characters are added $shift += strlen($format) - 2; $lastReplacementPosition += strlen($format) - 2; } // Replace "<", ">" with colorized ones $text = preg_replace('/(<[^>]+>)/', "{-{$color}}{+{$paramColor}}\$1{-{$paramColor}}{+{$color}}", $text); return $text; }
/** * Prints path link, which links to the source containing the step definition. * * @param DefinitionInterface $definition */ protected function printPathLink(DefinitionInterface $definition) { $url = $this->getParameter('paths_base_url') . $this->relativizePathsInString($definition->getCallbackReflection()->getFileName()); $path = $this->relativizePathsInString($definition->getPath()); $this->writeln('<span class="path"><a href="' . $url . '">' . $path . '</a></span>'); }
/** * Initializes redundant exception. * * @param DefinitionInterface $step2 duplicate step definition * @param DefinitionInterface $step1 firstly matched step definition */ public function __construct(DefinitionInterface $step2, DefinitionInterface $step1) { $message = sprintf("Step \"%s\" is already defined in %s\n\n%s\n%s", $step2->getRegex(), $step1->getPath(), $step1->getPath(), $step2->getPath()); parent::__construct($message); }
/** * Executes provided step definition. * * @param StepNode $step step node * @param DefinitionInterface $definition step definition */ protected function executeStepDefinition(StepNode $step, DefinitionInterface $definition) { $this->executeStepsChain($step, $definition->run($this->context)); }
/** * Prints path to step. * * @param StepNode $step step node * @param DefinitionInterface $definition definition (if step defined) * @param \Exception $exception exception (if step failed) */ protected function printStepPath(StepNode $step, DefinitionInterface $definition = null, \Exception $exception = null) { $color = $exception instanceof PendingException ? '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); $feature = $node->getFeature(); $title = $feature->getTitle(); $title = $title ? "`{$title}'" : '***'; $featurePath = "Of feature {$title}."; $featurePathLn = mb_strlen($featurePath); $this->maxLineLength = max($this->maxLineLength, $stepPathLn); $this->maxLineLength = max($this->maxLineLength, $scenarioPathLn); $this->maxLineLength = max($this->maxLineLength, $featurePathLn); $this->write(" {+{$color}}{$stepPath}{-{$color}}"); if (null !== $definition) { $indentCount = $this->maxLineLength - $stepPathLn; $this->printPathComment($this->relativizePathsInString($definition->getPath()), $indentCount); } else { $this->writeln(); } $this->write(" {+{$color}}{$scenarioPath}{-{$color}}"); $indentCount = $this->maxLineLength - $scenarioPathLn; $this->printPathComment($this->relativizePathsInString($node->getFile()) . ':' . $node->getLine(), $indentCount); $this->write(" {+{$color}}{$featurePath}{-{$color}}"); $indentCount = $this->maxLineLength - $featurePathLn; $this->printPathComment($this->relativizePathsInString($feature->getFile()), $indentCount); $this->writeln(); }