/** * 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); }
/** * * @param \Prophecy\Doubler\Generator\Node\ClassNode $node */ function it_ignores_existing_methods($node) { $node->getParentClass()->willReturn('spec\\Prophecy\\Doubler\\ClassPatch\\MagicalApiExtended'); $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); $node->addMethod(new MethodNode('definedMethod'))->shouldNotBeCalled(); $this->apply($node); }
/** * Forces class to implement Iterator interface. * * @param ClassNode $node */ public function apply(ClassNode $node) { $node->addInterface('Iterator'); $node->addMethod(new MethodNode('current')); $node->addMethod(new MethodNode('key')); $node->addMethod(new MethodNode('next')); $node->addMethod(new MethodNode('rewind')); $node->addMethod(new MethodNode('valid')); }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $node */ function it_adds_a_method_to_node_if_not_exists($node) { $node->hasMethod('__construct')->willReturn(false); $node->addMethod(Argument::any())->shouldBeCalled(); $node->getParentClass()->shouldBeCalled(); $this->apply($node); }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $node */ function it_discovers_api_using_phpdoc_from_extended_parent_interfaces($node) { $node->getParentClass()->willReturn('spec\\Prophecy\\Doubler\\ClassPatch\\MagicalApiImplementedExtended'); $node->getInterfaces()->willReturn(array()); $node->addMethod(new MethodNode('implementedMethod'))->shouldBeCalled(); $this->apply($node); }
/** * @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); }
/** * Updated constructor code to call parent one with dummy file argument. * * @param ClassNode $node */ public function apply(ClassNode $node) { if ($node->hasMethod('__construct')) { $constructor = $node->getMethod('__construct'); } else { $constructor = new MethodNode('__construct'); $node->addMethod($constructor); } $constructor->setCode('return parent::__construct("' . __FILE__ . '");'); }
/** * 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); } }
/** * Updated constructor code to call parent one with dummy file argument. * * @param ClassNode $node */ public function apply(ClassNode $node) { if ($node->hasMethod('__construct')) { $constructor = $node->getMethod('__construct'); } else { $constructor = new MethodNode('__construct'); $node->addMethod($constructor); } if ($this->nodeIsDirectoryIterator($node)) { $constructor->setCode('return parent::__construct("' . __DIR__ . '");'); return; } $constructor->useParentCode(); }
/** * 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); } } }
/** * Makes all class constructor arguments optional. * * @param ClassNode $node */ public function apply(ClassNode $node) { if (!$node->hasMethod('__construct')) { $node->addMethod(new MethodNode('__construct', '')); return; } $constructor = $node->getMethod('__construct'); foreach ($constructor->getArguments() as $argument) { $argument->setDefault(null); } $constructor->setCode(<<<PHP if (0 < func_num_args()) { call_user_func_array(array('parent', '__construct'), func_get_args()); } PHP ); }
/** * 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); } } }
/** * 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); } } } }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $node */ function it_forces_node_to_implement_IteratorAggregate($node) { $node->addInterface('Iterator')->shouldBeCalled(); $node->addMethod(Argument::type('Prophecy\\Doubler\\Generator\\Node\\MethodNode'))->willReturn(null); $this->apply($node); }
private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode) { $node = new Node\MethodNode($method->getName()); if (true === $method->isProtected()) { $node->setVisibility('protected'); } if (true === $method->isStatic()) { $node->setStatic(); } if (is_array($params = $method->getParameters()) && count($params)) { foreach ($params as $param) { $this->reflectArgumentToNode($param, $node); } } $classNode->addMethod($node); }
private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode) { $node = new Node\MethodNode($method->getName()); if (true === $method->isProtected()) { $node->setVisibility('protected'); } if (true === $method->isStatic()) { $node->setStatic(); } if (true === $method->returnsReference()) { $node->setReturnsReference(); } if (version_compare(PHP_VERSION, '7.0', '>=') && true === $method->hasReturnType()) { $node->setReturnType((string) $method->getReturnType()); } if (is_array($params = $method->getParameters()) && count($params)) { foreach ($params as $param) { $this->reflectArgumentToNode($param, $node); } } $classNode->addMethod($node); }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $class */ function it_creates_new_constructor_if_object_has_none($class) { $class->hasMethod('__construct')->willReturn(false); $class->addMethod(Argument::type('Prophecy\\Doubler\\Generator\\Node\\MethodNode'))->shouldBeCalled(); $this->apply($class); }
/** * @param \Prophecy\Doubler\Generator\Node\ClassNode $node */ function it_discovers_api_using_phpdoc($node) { $node->getParentClass()->willReturn('spec\\Prophecy\\Doubler\\ClassPatch\\MagicalApi'); $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); $this->apply($node); }