/** * Apply Prophecy functionality to class node. * * @param ClassNode $node */ public function apply(ClassNode $node) { $node->addInterface('Prophecy\\Prophecy\\ProphecySubjectInterface'); $node->addProperty('objectProphecy', 'private'); foreach ($node->getMethods() as $name => $method) { if ('__construct' === strtolower($name)) { continue; } $method->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());'); } $prophecySetter = new MethodNode('setProphecy'); $prophecyArgument = new ArgumentNode('prophecy'); $prophecyArgument->setTypeHint('Prophecy\\Prophecy\\ProphecyInterface'); $prophecySetter->addArgument($prophecyArgument); $prophecySetter->setCode('$this->objectProphecy = $prophecy;'); $prophecyGetter = new MethodNode('getProphecy'); $prophecyGetter->setCode('return $this->objectProphecy;'); if ($node->hasMethod('__call')) { $__call = $node->getMethod('__call'); } else { $__call = new MethodNode('__call'); $__call->addArgument(new ArgumentNode('name')); $__call->addArgument(new ArgumentNode('arguments')); $node->addMethod($__call); } $__call->setCode(<<<PHP throw new \\Prophecy\\Exception\\Doubler\\MethodNotFoundException( sprintf('Method `%s::%s()` not found.', get_class(\$this), func_get_arg(0)), \$this->getProphecy(), func_get_arg(0) ); PHP ); $node->addMethod($prophecySetter); $node->addMethod($prophecyGetter); }
function it_will_remove_echo_and_eval_methods(ClassNode $node, MethodNode $method1, MethodNode $method2, MethodNode $method3) { $node->removeMethod('eval')->shouldBeCalled(); $node->removeMethod('echo')->shouldBeCalled(); $method1->getName()->willReturn('echo'); $method2->getName()->willReturn('eval'); $method3->getName()->willReturn('notKeyword'); $node->getMethods()->willReturn(array('echo' => $method1, 'eval' => $method2, 'notKeyword' => $method3)); $this->apply($node); }
/** * Discover Magical API * * @param ClassNode $node */ public function apply(ClassNode $node) { $parentClass = $node->getParentClass(); $reflectionClass = new \ReflectionClass($parentClass); $phpdoc = new DocBlock($reflectionClass->getDocComment()); $tagList = $phpdoc->getTagsByName('method'); foreach ($tagList as $tag) { $methodNode = new MethodNode($tag->getMethodName()); $methodNode->setStatic($tag->isStatic()); $node->addMethod($methodNode); } }
/** * Discover Magical API * * @param ClassNode $node */ public function apply(ClassNode $node) { $parentClass = $node->getParentClass(); $reflectionClass = new \ReflectionClass($parentClass); $tagList = $this->tagRetriever->getTagList($reflectionClass); foreach ($tagList as $tag) { $methodName = $tag->getMethodName(); if (empty($methodName)) { continue; } if (!$reflectionClass->hasMethod($methodName)) { $methodNode = new MethodNode($methodName); $methodNode->setStatic($tag->isStatic()); $node->addMethod($methodNode); } } }
public function addMethod(MethodNode $method) { if (!$this->isExtendable($method->getName())) { $message = sprintf('Method `%s` is not extendable, so can not be added.', $method->getName()); throw new MethodNotExtendableException($message, $this->getParentClass(), $method->getName()); } $this->methods[$method->getName()] = $method; }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $node * @param \Prophecy\Doubler\Generator\Node\MethodNode $constructor * @param \Prophecy\Doubler\Generator\Node\MethodNode $method1 * @param \Prophecy\Doubler\Generator\Node\MethodNode $method2 * @param \Prophecy\Doubler\Generator\Node\MethodNode $method3 */ function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prophecy_makeCall($node, $constructor, $method1, $method2, $method3) { $node->addInterface('Prophecy\\Prophecy\\ProphecySubjectInterface')->willReturn(NULL); $node->addProperty('objectProphecy', 'private')->willReturn(NULL); $node->hasMethod(Argument::any())->willReturn(FALSE); $node->addMethod(Argument::type('Prophecy\\Doubler\\Generator\\Node\\MethodNode'))->willReturn(NULL); $node->addMethod(Argument::type('Prophecy\\Doubler\\Generator\\Node\\MethodNode'))->willReturn(NULL); $constructor->getName()->willReturn('__construct'); $method1->getName()->willReturn('method1'); $method2->getName()->willReturn('method2'); $method3->getName()->willReturn('method3'); $node->getMethods()->willReturn(array('method1' => $method1, 'method2' => $method2, 'method3' => $method3)); $constructor->setCode(Argument::any())->shouldNotBeCalled(); $method1->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());')->shouldBeCalled(); $method2->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());')->shouldBeCalled(); $method3->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());')->shouldBeCalled(); $this->apply($node); }
/** * Discover Magical API * * @param ClassNode $node */ public function apply(ClassNode $node) { $parentClass = $node->getParentClass(); $reflectionClass = new \ReflectionClass($parentClass); $phpdoc = new DocBlock($reflectionClass->getDocComment()); $tagList = $phpdoc->getTagsByName('method'); $interfaces = $reflectionClass->getInterfaces(); foreach ($interfaces as $interface) { $phpdoc = new DocBlock($interface); $tagList = array_merge($tagList, $phpdoc->getTagsByName('method')); } foreach ($tagList as $tag) { $methodName = $tag->getMethodName(); if (!$reflectionClass->hasMethod($methodName)) { $methodNode = new MethodNode($tag->getMethodName()); $methodNode->setStatic($tag->isStatic()); $node->addMethod($methodNode); } } }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $class * @param \Prophecy\Doubler\Generator\Node\MethodNode $method * @param \Prophecy\Doubler\Generator\Node\ArgumentNode $argument */ function it_overrides_properly_methods_with_args_passed_by_reference($class, $method, $argument) { $class->getParentClass()->willReturn('RuntimeException'); $class->getInterfaces()->willReturn(array('Prophecy\\Doubler\\Generator\\MirroredInterface')); $class->getProperties()->willReturn(array()); $class->getMethods()->willReturn(array($method)); $method->getName()->willReturn('getName'); $method->getVisibility()->willReturn('public'); $method->isStatic()->willReturn(false); $method->getArguments()->willReturn(array($argument)); $method->getCode()->willReturn('return $this->name;'); $argument->getName()->willReturn('fullname'); $argument->getTypeHint()->willReturn('array'); $argument->isOptional()->willReturn(true); $argument->getDefault()->willReturn(null); $argument->isPassedByReference()->willReturn(true); $code = $this->generate('CustomClass', $class); $expected = <<<'PHP' namespace { class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface { public function getName(array &$fullname = NULL) { return $this->name; } } } PHP; $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); $code->shouldBe($expected); }
/** * Discover Magical API * * @param ClassNode $node */ public function apply(ClassNode $node) { $types = array_filter($node->getInterfaces(), function ($interface) { return 0 !== strpos($interface, 'Prophecy\\'); }); $types[] = $node->getParentClass(); foreach ($types as $type) { $reflectionClass = new \ReflectionClass($type); $tagList = $this->tagRetriever->getTagList($reflectionClass); foreach ($tagList as $tag) { $methodName = $tag->getMethodName(); if (empty($methodName)) { continue; } if (!$reflectionClass->hasMethod($methodName)) { $methodNode = new MethodNode($methodName); $methodNode->setStatic($tag->isStatic()); $node->addMethod($methodNode); } } } }
public function addMethod(MethodNode $method) { $this->methods[$method->getName()] = $method; }
private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode) { $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName(); $node = new Node\ArgumentNode($name); $node->setTypeHint($this->getTypeHint($parameter)); if (true === $parameter->isDefaultValueAvailable()) { $node->setDefault($parameter->getDefaultValue()); } elseif (true === $parameter->isOptional() || true === $parameter->allowsNull()) { $node->setDefault(null); } if (true === $parameter->isPassedByReference()) { $node->setAsPassedByReference(); } $methodNode->addArgument($node); }
/** * * @param \Prophecy\Doubler\Generator\Node\MethodNode $method */ function its_hasMethod_returns_false_if_method_has_been_removed($method) { $method->getName()->willReturn('getName'); $this->addMethod($method); $this->removeMethod('getName'); $this->hasMethod('getName')->shouldReturn(false); }
private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode) { $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName(); $node = new Node\ArgumentNode($name); $node->setTypeHint($this->getTypeHint($parameter)); if ($this->isVariadic($parameter)) { $node->setAsVariadic(); } if ($this->hasDefaultValue($parameter)) { $node->setDefault($this->getDefaultValue($parameter)); } if ($parameter->isPassedByReference()) { $node->setAsPassedByReference(); } $methodNode->addArgument($node); }
function it_throws_an_exception_when_adding_a_method_that_isnt_extendable(MethodNode $method) { $this->addUnextendableMethod('testMethod'); $method->getName()->willReturn('testMethod'); $expectedException = new MethodNotExtendableException("Method `testMethod` is not extendable, so can not be added.", "stdClass", "testMethod"); $this->shouldThrow($expectedException)->duringAddMethod($method); }