/**
  * 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);
 }
Пример #2
0
    /**
     * @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);
    }