示例#1
0
 public function getMock()
 {
     $mock = $this->testCase->getMock('stdClass', $this->functions, array(), 'PHPUnit_Extension_FunctionMocker_' . uniqid());
     foreach ($this->functions as $function) {
         $fqFunction = $this->namespace . '\\' . $function;
         if (in_array($fqFunction, static::$mockedFunctions, true)) {
             continue;
         }
         if (!extension_loaded('runkit') || !ini_get('runkit.internal_override')) {
             PHPUnit_Extension_FunctionMocker_CodeGenerator::defineFunction($function, $this->namespace);
         } elseif (!function_exists('__phpunit_function_mocker_' . $function)) {
             runkit_function_rename($function, '__phpunit_function_mocker_' . $function);
             error_log($function);
             runkit_method_redefine($function, function () use($function) {
                 if (!isset($GLOBALS['__PHPUNIT_EXTENSION_FUNCTIONMOCKER'][$this->namespace])) {
                     return call_user_func_array('__phpunit_function_mocker_' . $function, func_get_args());
                 }
                 return call_user_func_array(array($GLOBALS['__PHPUNIT_EXTENSION_FUNCTIONMOCKER'][$this->namespace], $function), func_get_args());
             });
             var_dump(strlen("foo"));
         }
         static::$mockedFunctions[] = $fqFunction;
     }
     if (!isset($GLOBALS['__PHPUNIT_EXTENSION_FUNCTIONMOCKER'])) {
         $GLOBALS['__PHPUNIT_EXTENSION_FUNCTIONMOCKER'] = array();
     }
     $GLOBALS['__PHPUNIT_EXTENSION_FUNCTIONMOCKER'][$this->namespace] = $mock;
     return $mock;
 }
 /**
  * Creates runkit method to be used for mocking, taking care of callback to this object.
  *
  * Also temporary renames the original method if there is.
  */
 protected function createFunction()
 {
     list($class, $method) = $this->getClassAndMethod();
     $this->restore_name = 'restore_' . $class . '_' . $method . '_' . $this->id . '_' . uniqid();
     // We save the original method in the class for restoring.
     runkit_method_copy($class, $this->restore_name, $class, $method);
     runkit_method_redefine($class, $method, '', $this->getCallback(), RUNKIT_ACC_STATIC);
     $this->active = true;
 }
示例#3
0
 public static function reload_method($classname, $methodname)
 {
     $method = new ReflectionMethod($classname, $methodname);
     $visibility = RUNKIT_ACC_PUBLIC;
     if ($method->isProtected()) {
         $visibility = RUNKIT_ACC_PROTECTED;
     } else {
         if ($method->isPrivate()) {
             $visibility = RUNKIT_ACC_PRIVATE;
         }
     }
     if ($method->isStatic()) {
         $visibility = $visibility | RUNKIT_ACC_STATIC;
     }
     return runkit_method_redefine($classname, $methodname, self::getMethodArguments($classname, $methodname), self::getMethodCode($classname, $methodname), $visibility);
 }
示例#4
0
 /**
  * Constructs a new callable object, abstracting
  * differences between the different constructs
  * PHP supports.
  *
  * \param mixed $callable
  *      A callable item. It must be compatible
  *      with the PHP callback pseudo-type.
  *
  * \throw InvalidArgumentException
  *      The given item is not compatible
  *      with the PHP callback pseudo-type.
  *
  * \see
  *      More information on the callback pseudo-type can be found here:
  *      http://php.net/language.pseudo-types.php#language.types.callback
  */
 public function __construct($callable)
 {
     if (!is_callable($callable, false, $representation)) {
         throw new \InvalidArgumentException('Not a valid callable');
     }
     if (!self::$patched) {
         self::$patched = true;
         // @codeCoverageIgnoreStart
         // Adds support for references to invoke() on PHP 5.6.0+.
         if (version_compare(PHP_VERSION, '5.6.0', '>=') && function_exists('runkit_method_redefine')) {
             runkit_method_redefine(__CLASS__, '__invoke', '&...$args', 'return call_user_func_array($this->callableObj, $args);');
         }
         // @codeCoverageIgnoreEnd
     }
     // This happens for anonymous functions
     // created with create_function().
     if (is_string($callable) && $representation == "") {
         $representation = $callable;
     }
     $this->callableObj = $callable;
     $this->representation = $representation;
 }
示例#5
0
 /**
  * @param \Runkit\RunkitMethod $method
  *
  * @return boolean
  */
 public function redefineMethod(\Runkit\RunkitMethod $method)
 {
     if (!function_exists('runkit_method_redefine')) {
         return false;
     }
     return runkit_method_redefine($method->getClass(), $method->getName(), (string) $method->getArguments(), $method->getCode()->get(), $method->getAccess());
 }
示例#6
0
 protected function _reverseMethodCallRedirection()
 {
     $newOrigFuncName = $this->_functionName . $this->_origFuncSuffix;
     $spyFuncName = $this->_functionName . $this->_spyFuncSuffix;
     $isStatic = (new \ReflectionMethod($this->_context, $this->_functionName))->isStatic();
     if ($isStatic) {
         $origCallback = 'array("' . $this->_context . '", "' . $newOrigFuncName . '")';
     } else {
         $origCallback = 'array($this, "' . $newOrigFuncName . '")';
     }
     runkit_method_remove($this->_context, $spyFuncName);
     //keep memory address of function to prevent seg fault
     runkit_method_redefine($this->_context, $this->_functionName, '', '$args = func_get_args();
         return call_user_func_array(' . $origCallback . ', $args);', RUNKIT_ACC_PUBLIC | ($isStatic ? RUNKIT_ACC_STATIC : 0));
 }
示例#7
0
 /**
  * Mock a method.
  *
  * Replace the code of a function of a specific class
  *
  * @param Callable $method     Method defined in an array form
  * @param String   $mock       Replacement code for the method
  * @param String   $visibility Visibility of the redefined method
  * @param String   $args       Comma-delimited list of arguments for the redefined method
  *
  * @return void
  */
 protected function mock_method($method, $mock, $visibility = 'public', $args = '')
 {
     $class_name = is_object($method[0]) ? get_class($method[0]) : $method[0];
     $method_name = $method[1];
     if (method_exists($class_name, $method_name . self::FUNCTION_ID) === FALSE) {
         runkit_method_copy($class_name, $method_name . self::FUNCTION_ID, $class_name, $method_name);
     }
     switch ($visibility) {
         case 'public':
             $visibility_flag = RUNKIT_ACC_PUBLIC;
             break;
         case 'protected':
             $visibility_flag = RUNKIT_ACC_PROTECTED;
             break;
         case 'private':
             $visibility_flag = RUNKIT_ACC_PRIVATE;
             break;
     }
     runkit_method_redefine($class_name, $method_name, $args, $mock, $visibility_flag);
 }
 /**
  * @Given class :fqcn has method :method with arguments :args and code
  */
 public function classHasMethodWithArgumentsAndCode($fqcn, $method, $args, PyStringNode $code)
 {
     $this->checkRunkit();
     $class = new \ReflectionClass($fqcn);
     if (!$class->hasMethod($method)) {
         throw new \RuntimeException(sprintf('Class %s does not have method %s', $fqcn, $method));
     }
     runkit_method_redefine($fqcn, $method, $args, $code->__toString(), RUNKIT_ACC_PUBLIC);
 }