Ejemplo n.º 1
0
 public function pass(FuncCall $funcCall, Context $context)
 {
     $functionName = $this->resolveFunctionName($funcCall, $context);
     if (!$functionName || !isset($this->map[$functionName])) {
         return false;
     }
     if ($funcCall->getDocComment()) {
         $phpdoc = $this->docBlockFactory->create($funcCall->getDocComment()->getText());
         if ($phpdoc->hasTag('expected')) {
             return false;
         }
     }
     $context->notice('debug.code', sprintf('Function %s() is a debug function, please don`t use it in production.', $functionName), $funcCall);
     return true;
 }
Ejemplo n.º 2
0
 /**
  * @param ClassMethod $methodStmt
  * @param Context $context
  * @return bool
  */
 public function pass(ClassMethod $methodStmt, Context $context)
 {
     $functionName = $methodStmt->name;
     if (!$functionName) {
         return false;
     }
     if (substr($functionName, 0, 4) !== 'test') {
         return false;
     }
     if ($methodStmt->getDocComment()) {
         $phpdoc = $this->docBlockFactory->create($methodStmt->getDocComment()->getText());
         if ($phpdoc->hasTag('test')) {
             $context->notice('test.annotation', 'Annotation @test is not needed when the method is prefixed with test.', $methodStmt);
             return true;
         }
     }
     return false;
 }
Ejemplo n.º 3
0
 /**
  * Gets DocBlock from accessor or mutator method.
  *
  * @param string $class
  * @param string $ucFirstProperty
  * @param int    $type
  *
  * @return array
  */
 private function getDocBlockFromMethod($class, $ucFirstProperty, $type)
 {
     $prefixes = $type === self::ACCESSOR ? ReflectionExtractor::$accessorPrefixes : ReflectionExtractor::$mutatorPrefixes;
     $prefix = null;
     foreach ($prefixes as $prefix) {
         $methodName = $prefix . $ucFirstProperty;
         try {
             $reflectionMethod = new \ReflectionMethod($class, $methodName);
             if (self::ACCESSOR === $type && 0 === $reflectionMethod->getNumberOfRequiredParameters() || self::MUTATOR === $type && $reflectionMethod->getNumberOfParameters() >= 1) {
                 break;
             }
         } catch (\ReflectionException $reflectionException) {
             // Try the next prefix if the method doesn't exist
         }
     }
     if (!isset($reflectionMethod)) {
         return;
     }
     return array($this->docBlockFactory->create($reflectionMethod, $this->contextFactory->createFromReflector($reflectionMethod)), $prefix);
 }
 /**
  * @param \ReflectionClass $reflectionClass
  * @param \ReflectionProperty $reflectionProperty
  */
 protected function _assertCorrectSetterImplementation(\ReflectionClass $reflectionClass, \ReflectionProperty $reflectionProperty)
 {
     /** @var \phpDocumentor\Reflection\Type $propertyVarType */
     /** @var \phpDocumentor\Reflection\DocBlock\Tags\Param $methodParamTag */
     /** @var \phpDocumentor\Reflection\DocBlock\Tags\Return_ $methodReturnTag */
     $className = $reflectionClass->getName();
     $propertyName = $reflectionProperty->getName();
     $expectedSetterName = sprintf('set%s', ucfirst($propertyName));
     if ($this->requiresSetters) {
         $this->assertTrue(method_exists($className, $expectedSetterName), sprintf('Class "%s" must have a setter named "%s" for property "%s"', $className, $expectedSetterName, $propertyName));
     } else {
         if (!$reflectionClass->hasMethod($expectedSetterName)) {
             return;
         }
     }
     // Get method reflection
     $reflectionMethod = $reflectionClass->getMethod($expectedSetterName);
     // Validate we have one parameter
     $this->assertEquals(1, $reflectionMethod->getNumberOfParameters(), sprintf('Setter "%s" for property "%s" in class "%s" must have one parameter', $expectedSetterName, $propertyName, $className));
     $this->assertEquals(1, $reflectionMethod->getNumberOfRequiredParameters(), sprintf('Setter "%s" for property "%s" in class "%s" must have one required parameter', $expectedSetterName, $propertyName, $className));
     // Get first parameter
     $reflectionParameter = $reflectionMethod->getParameters()[0];
     // Validate name
     $parameterName = $reflectionParameter->getName();
     $this->assertEquals($propertyName, $parameterName, sprintf('Setter "%s" for property "%s" in class "%s" must have a parameter with the same name as the property', $expectedSetterName, $propertyName, $className));
     // Get method doc block
     $methodDockBlock = $this->docBlockFactory->create($reflectionMethod->getDocComment());
     // Try to locate param doc block tag
     $methodParamTags = $methodDockBlock->getTagsByName('param');
     $this->assertCount(1, $methodParamTags, sprintf('Parameter "%s" for setter "%s" for property "%s" in class "%s" must have a "@param" doc block attribute', $parameterName, $expectedSetterName, $propertyName, $className));
     // Grab doc block definition from class property declaration
     $propertyDocBlock = $this->docBlockFactory->create($reflectionProperty->getDocComment());
     $propertyVarType = $propertyDocBlock->getTagsByName('var')[0]->getType();
     // Pull out the @param attribute from the doc block comment
     $methodParamTag = $methodParamTags[0];
     $methodParamType = $methodParamTag->getType();
     $parameterClass = $reflectionParameter->getClass();
     // Finally, attempt to validate setter declaration sanity
     switch (true) {
         // If the setter is designed to expect more than 1 type of variable, ensure that
         // there is no type-hinting going on.
         case $methodParamType instanceof Compound:
             $this->assertNull($parameterClass, sprintf('The "@param" docblock for parameter "%s" in setter "%s" for property "%s" in class "%s" indicates that the value can be one of "%s", but the param TypeHint explicitly requires "%s".', $parameterName, $expectedSetterName, $propertyName, $className, (string) $methodParamType, null !== $parameterClass ? $parameterClass->getName() : ''));
             break;
             // If we're dealing with a scalar types, don't allow type-hinting as we need to work with php5
         // If we're dealing with a scalar types, don't allow type-hinting as we need to work with php5
         case $propertyVarType instanceof String_:
         case $propertyVarType instanceof Integer:
         case $propertyVarType instanceof Float_:
         case $propertyVarType instanceof Boolean:
             $this->assertNull($parameterClass, sprintf('Parameter "%s" in setter "%s" for property "%s" in class "%s" must not use type-hinting to maintain php 5 compatibility', $parameterName, $expectedSetterName, $propertyName, $className));
             break;
         case $propertyVarType instanceof Array_:
             $this->assertTrue($reflectionParameter->isArray(), sprintf('Parameter "%s" in setter "%s" for property "%s" in class "%s" must use type-hint of "array" or have it\'s doc block param tag value changed.', $parameterName, $expectedSetterName, $propertyName, $className));
             break;
         case $propertyVarType instanceof Object_:
             $fqsn = ltrim((string) $propertyVarType->getFqsen(), "\\");
             $this->assertEquals($fqsn, $parameterClass->getName(), sprintf('Parameter "%s" in setter "%s" for property "%s" in class "%s" must use type-hint equal to "%s".  Currently specifies "%s"', $parameterName, $expectedSetterName, $propertyName, $className, (string) $propertyVarType->getFqsen(), $parameterClass->getName()));
             break;
         default:
             $this->fail(sprintf('The parameter "%s" in setter "%s" for property "%s" in class "%s" is of type "%s", and there is no setter sanity check. Please add one to the test suite.', $parameterName, $expectedSetterName, $propertyName, $className, (string) $propertyVarType));
     }
 }
    /**
     * @covers ::__construct
     * @covers ::create
     * @uses phpDocumentor\Reflection\DocBlock\DescriptionFactory
     * @uses phpDocumentor\Reflection\DocBlock\Description
     */
    public function testTagsAreInterpretedUsingFactory()
    {
        $tagString = <<<TAG
@author Mike van Riel <*****@*****.**> This is with
  multiline description.
TAG;
        $tag = m::mock(Tag::class);
        $tagFactory = m::mock(TagFactory::class);
        $tagFactory->shouldReceive('create')->with($tagString)->andReturn($tag);
        $fixture = new DocBlockFactory(new DescriptionFactory($tagFactory), $tagFactory);
        $given = <<<DOCBLOCK
/**
 * This is a summary.
 *
 * @author Mike van Riel <*****@*****.**> This is with
 *   multiline description.
 */
DOCBLOCK;
        $docblock = $fixture->create($given, new Context(''));
        $this->assertEquals([$tag], $docblock->getTags());
    }
 /**
  * @covers ::__construct
  * @covers ::create
  * @uses   phpDocumentor\Reflection\DocBlock\DescriptionFactory
  * @uses   phpDocumentor\Reflection\DocBlock\Description
  * @uses   phpDocumentor\Reflection\Types\Context
  * @uses   phpDocumentor\Reflection\DocBlock\Tags\Param
  */
 public function testTagsWithContextNamespace()
 {
     $tagFactoryMock = m::mock(TagFactory::class);
     $fixture = new DocBlockFactory(m::mock(DescriptionFactory::class), $tagFactoryMock);
     $context = new Context('MyNamespace');
     $tagFactoryMock->shouldReceive('create')->with(m::any(), $context)->andReturn(new Param('param'));
     $docblock = $fixture->create('/** @param MyType $param */', $context);
 }