diff --git a/src/DocBlock/Tags/Factory/MethodFactory.php b/src/DocBlock/Tags/Factory/MethodFactory.php index 17c768f8..845a2da6 100644 --- a/src/DocBlock/Tags/Factory/MethodFactory.php +++ b/src/DocBlock/Tags/Factory/MethodFactory.php @@ -42,11 +42,6 @@ public function create(PhpDocTagNode $node, Context $context): Tag return new Method( $tagValue->methodName, - [], - $this->createReturnType($tagValue, $context), - $tagValue->isStatic, - $this->descriptionFactory->create($tagValue->description, $context), - false, array_map( function (MethodTagValueParameterNode $param) use ($context) { return new MethodParameter( @@ -64,6 +59,10 @@ function (MethodTagValueParameterNode $param) use ($context) { }, $tagValue->parameters ), + $this->createReturnType($tagValue, $context), + $tagValue->isStatic, + $this->descriptionFactory->create($tagValue->description, $context), + false, ); } diff --git a/src/DocBlock/Tags/Method.php b/src/DocBlock/Tags/Method.php index d2c0c82c..66d11675 100644 --- a/src/DocBlock/Tags/Method.php +++ b/src/DocBlock/Tags/Method.php @@ -13,34 +13,17 @@ namespace phpDocumentor\Reflection\DocBlock\Tags; -use InvalidArgumentException; use phpDocumentor\Reflection\DocBlock\Description; -use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\Exception\CannotCreateTag; use phpDocumentor\Reflection\Type; -use phpDocumentor\Reflection\TypeResolver; -use phpDocumentor\Reflection\Types\Context as TypeContext; -use phpDocumentor\Reflection\Types\Mixed_; use phpDocumentor\Reflection\Types\Void_; use Webmozart\Assert\Assert; -use function array_keys; -use function array_map; -use function explode; use function implode; -use function is_string; -use function preg_match; -use function sort; -use function strpos; -use function substr; -use function trigger_error; -use function trim; -use function var_export; - -use const E_USER_DEPRECATED; - /** * Reflection class for an {@}method in a Docblock. */ + final class Method extends BaseTag { protected string $name = 'method'; @@ -57,18 +40,15 @@ final class Method extends BaseTag private array $parameters; /** - * @param array> $arguments * @param MethodParameter[] $parameters - * @phpstan-param array $arguments */ public function __construct( string $methodName, - array $arguments = [], + array $parameters = [], ?Type $returnType = null, bool $static = false, ?Description $description = null, - bool $returnsReference = false, - ?array $parameters = null + bool $returnsReference = false ) { Assert::stringNotEmpty($methodName); @@ -76,133 +56,12 @@ public function __construct( $returnType = new Void_(); } - $arguments = $this->filterArguments($arguments); - $this->methodName = $methodName; $this->returnType = $returnType; $this->isStatic = $static; $this->description = $description; $this->returnsReference = $returnsReference; - $this->parameters = $parameters ?? $this->fromLegacyArguments($arguments); - } - - /** - * @deprecated Create using static factory is deprecated, - * this method should not be called directly by library consumers - */ - public static function create( - string $body, - ?TypeResolver $typeResolver = null, - ?DescriptionFactory $descriptionFactory = null, - ?TypeContext $context = null - ): ?self { - trigger_error( - 'Create using static factory is deprecated, this method should not be called directly - by library consumers', - E_USER_DEPRECATED - ); - Assert::stringNotEmpty($body); - Assert::notNull($typeResolver); - Assert::notNull($descriptionFactory); - - // 1. none or more whitespace - // 2. optionally the keyword "static" followed by whitespace - // 3. optionally a word with underscores followed by whitespace : as - // type for the return value - // 4. optionally an ampersand followed or not by whitespace : as - // a reference - // 5. then optionally a word with underscores followed by () and - // whitespace : as method name as used by phpDocumentor - // 6. then a word with underscores, followed by ( and any character - // until a ) and whitespace : as method name with signature - // 7. any remaining text : as description - if ( - !preg_match( - '/^ - # Static keyword - # Declares a static method ONLY if type is also present - (?: - (static) - \s+ - )? - # Return type - (?: - ( - (?:[\w\|_\\\\]*\$this[\w\|_\\\\]*) - | - (?: - (?:[\w\|_\\\\]+) - # array notation - (?:\[\])* - )*+ - ) - \s+ - )? - # Returns reference - (?: - (&) - \s* - )? - # Method name - ([\w_]+) - # Arguments - (?: - \(([^\)]*)\) - )? - \s* - # Description - (.*) - $/sux', - $body, - $matches - ) - ) { - return null; - } - - [, $static, $returnType, $returnsReference, $methodName, $argumentLines, $description] = $matches; - - $static = $static === 'static'; - - if ($returnType === '') { - $returnType = 'void'; - } - - $returnsReference = $returnsReference === '&'; - - $returnType = $typeResolver->resolve($returnType, $context); - $description = $descriptionFactory->create($description, $context); - - /** @phpstan-var array $arguments */ - $arguments = []; - if ($argumentLines !== '') { - $argumentsExploded = explode(',', $argumentLines); - foreach ($argumentsExploded as $argument) { - $argument = explode(' ', self::stripRestArg(trim($argument)), 2); - if (strpos($argument[0], '$') === 0) { - $argumentName = substr($argument[0], 1); - $argumentType = new Mixed_(); - } else { - $argumentType = $typeResolver->resolve($argument[0], $context); - $argumentName = ''; - if (isset($argument[1])) { - $argument[1] = self::stripRestArg($argument[1]); - $argumentName = substr($argument[1], 1); - } - } - - $arguments[] = ['name' => $argumentName, 'type' => $argumentType]; - } - } - - return new static( - $methodName, - $arguments, - $returnType, - $static, - $description, - $returnsReference - ); + $this->parameters = $parameters; } /** @@ -213,24 +72,6 @@ public function getMethodName(): string return $this->methodName; } - /** - * @deprecated Method deprecated, use {@see self::getParameters()} - * - * @return array> - * @phpstan-return array - */ - public function getArguments(): array - { - trigger_error('Method deprecated, use ::getParameters()', E_USER_DEPRECATED); - - return array_map( - static function (MethodParameter $methodParameter) { - return ['name' => $methodParameter->getName(), 'type' => $methodParameter->getType()]; - }, - $this->parameters - ); - } - /** @return MethodParameter[] */ public function getParameters(): array { @@ -287,69 +128,8 @@ public function __toString(): string . ($description !== '' ? ' ' . $description : ''); } - /** - * @param mixed[][]|string[] $arguments - * @phpstan-param array $arguments - * - * @return mixed[][] - * @phpstan-return array - */ - private function filterArguments(array $arguments = []): array - { - $result = []; - foreach ($arguments as $argument) { - if (is_string($argument)) { - $argument = ['name' => $argument]; - } - - if (!isset($argument['type'])) { - $argument['type'] = new Mixed_(); - } - - $keys = array_keys($argument); - sort($keys); - if ($keys !== ['name', 'type']) { - throw new InvalidArgumentException( - 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true) - ); - } - - $result[] = $argument; - } - - return $result; - } - - private static function stripRestArg(string $argument): string - { - if (strpos($argument, '...') === 0) { - $argument = trim(substr($argument, 3)); - } - - return $argument; - } - - /** - * @param array{name: string, type: Type} $arguments - * @phpstan-param array $arguments - * - * @return MethodParameter[] - */ - private function fromLegacyArguments(array $arguments): array + public static function create(string $body): void { - trigger_error( - 'Create method parameters via legacy format is deprecated add parameters via the constructor', - E_USER_DEPRECATED - ); - - return array_map( - static function ($arg) { - return new MethodParameter( - $arg['name'], - $arg['type'] - ); - }, - $arguments - ); + throw new CannotCreateTag('Method tag cannot be created'); } } diff --git a/tests/integration/InterpretingDocBlocksTest.php b/tests/integration/InterpretingDocBlocksTest.php index c8bfe1f6..698aac96 100644 --- a/tests/integration/InterpretingDocBlocksTest.php +++ b/tests/integration/InterpretingDocBlocksTest.php @@ -217,14 +217,13 @@ public function testMethodRegression(): void [ new Method( 'setInteger', - [], + [ + new MethodParameter('integer', new Integer()) + ], new Void_(), false, new Description(''), false, - [ - new MethodParameter('integer', new Integer()) - ] ), ], $docblock->getTags() diff --git a/tests/integration/TypedTagsTest.php b/tests/integration/TypedTagsTest.php index 5f8da6cf..2151712b 100644 --- a/tests/integration/TypedTagsTest.php +++ b/tests/integration/TypedTagsTest.php @@ -75,7 +75,7 @@ public function testMethodFormats(string $type, Type $expectedType): void $this->assertInstanceOf(Method::class, $phpdoc->getTags()[0]); $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getReturnType()); - $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getParameters()[0]->getType()); + $this->assertEquals($expectedType, current($phpdoc->getTags()[0]->getParameters())->getType()); } /** @dataProvider invalidFormatsProvider */ diff --git a/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php index 59f148db..5756acf2 100644 --- a/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php @@ -56,7 +56,6 @@ public function tagProvider(): array true, new Description(''), false, - [] ), ], [ @@ -68,7 +67,6 @@ public function tagProvider(): array false, new Description(''), false, - [] ), ], [ @@ -80,82 +78,75 @@ public function tagProvider(): array false, new Description(''), false, - [] ), ], [ '@method myMethod($a)', new Method( 'myMethod', - [], + [new MethodParameter('a', new Mixed_())], new Void_(), false, new Description(''), false, - [new MethodParameter('a', new Mixed_())] ), ], [ '@method void setInteger(integer $integer)', new Method( 'setInteger', - [], + [new MethodParameter('integer', new Integer())], new Void_(), false, new Description(''), false, - [new MethodParameter('integer', new Integer())] ), ], [ '@method myMethod($a = 1)', new Method( 'myMethod', - [], + [new MethodParameter('a', new Mixed_(), false, false, '1')], new Void_(), false, new Description(''), false, - [new MethodParameter('a', new Mixed_(), false, false, '1')] ), ], [ '@method myMethod(int $a = 1)', new Method( 'myMethod', - [], + [new MethodParameter('a', new Integer(), false, false, '1')], new Void_(), false, new Description(''), false, - [new MethodParameter('a', new Integer(), false, false, '1')] ), ], [ '@method myMethod(int ...$a)', new Method( 'myMethod', - [], + [new MethodParameter('a', new Integer(), false, true)], new Void_(), false, new Description(''), false, - [new MethodParameter('a', new Integer(), false, true)] ), ], [ '@method myMethod(int &$a, string $b)', new Method( 'myMethod', - [], + [ + new MethodParameter('a', new Integer(), true, false), + new MethodParameter('b', new String_(), false, false), + ], new Void_(), false, new Description(''), false, - [ - new MethodParameter('a', new Integer(), true, false), - new MethodParameter('b', new String_(), false, false), - ] ), ], ]; diff --git a/tests/unit/DocBlock/Tags/MethodTest.php b/tests/unit/DocBlock/Tags/MethodTest.php index dfc0032b..c80b8178 100644 --- a/tests/unit/DocBlock/Tags/MethodTest.php +++ b/tests/unit/DocBlock/Tags/MethodTest.php @@ -15,17 +15,9 @@ use Mockery as m; use phpDocumentor\Reflection\DocBlock\Description; -use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -use phpDocumentor\Reflection\Fqsen; -use phpDocumentor\Reflection\TypeResolver; -use phpDocumentor\Reflection\Types\Array_; -use phpDocumentor\Reflection\Types\Compound; -use phpDocumentor\Reflection\Types\Context; -use phpDocumentor\Reflection\Types\Integer; -use phpDocumentor\Reflection\Types\Mixed_; +use phpDocumentor\Reflection\Exception\CannotCreateTag; use phpDocumentor\Reflection\Types\Object_; use phpDocumentor\Reflection\Types\String_; -use phpDocumentor\Reflection\Types\This; use phpDocumentor\Reflection\Types\Void_; use PHPUnit\Framework\TestCase; @@ -68,8 +60,8 @@ public function testIfCorrectTagNameIsReturned(): void public function testIfTagCanBeRenderedUsingDefaultFormatter(): void { $arguments = [ - ['name' => 'argument1', 'type' => new String_()], - ['name' => 'argument2', 'type' => new Object_()], + new MethodParameter('argument1', new String_()), + new MethodParameter('argument2', new Object_()), ]; $fixture = new Method( @@ -97,7 +89,7 @@ public function testIfTagCanBeRenderedUsingSpecificFormatter(): void $fixture = new Method('myMethod'); $formatter = m::mock(Formatter::class); - $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); + $formatter->allows('format')->with($fixture)->andReturns('Rendered output'); $this->assertSame('Rendered output', $fixture->render($formatter)); } @@ -122,75 +114,12 @@ public function testHasMethodName(): void public function testHasArguments(): void { $arguments = [ - ['name' => 'argument1', 'type' => new String_()], + new MethodParameter('argument1', new String_()), ]; $fixture = new Method('myMethod', $arguments); - $this->assertSame($arguments, $fixture->getArguments()); - } - - /** - * @covers ::__construct - * @covers ::getArguments - */ - public function testArgumentsMayBePassedAsString(): void - { - $arguments = ['argument1']; - $expected = [ - ['name' => $arguments[0], 'type' => new Mixed_()], - ]; - - $fixture = new Method('myMethod', $arguments); - - $this->assertEquals($expected, $fixture->getArguments()); - } - - /** - * @covers ::__construct - * @covers ::getArguments - */ - public function testArgumentTypeCanBeInferredAsMixed(): void - { - $arguments = [['name' => 'argument1']]; - $expected = [ - ['name' => $arguments[0]['name'], 'type' => new Mixed_()], - ]; - - $fixture = new Method('myMethod', $arguments); - - $this->assertEquals($expected, $fixture->getArguments()); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::__construct - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::getArguments - * @uses \phpDocumentor\Reflection\DocBlock\Description - * - * @covers ::create - */ - public function testRestArgumentIsParsedAsRegularArg(): void - { - $expected = [ - ['name' => 'arg1', 'type' => new Mixed_()], - ['name' => 'rest', 'type' => new Mixed_()], - ['name' => 'rest2', 'type' => new Array_()], - ]; - - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - $description = new Description(''); - $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description); - - $fixture = Method::create( - 'void myMethod($arg1, ...$rest, array ... $rest2)', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertEquals($expected, $fixture->getArguments()); + $this->assertSame($arguments, $fixture->getParameters()); } /** @@ -257,8 +186,8 @@ public function testHasDescription(): void public function testStringRepresentationIsReturned(): void { $arguments = [ - ['name' => 'argument1', 'type' => new String_()], - ['name' => 'argument2', 'type' => new Object_()], + new MethodParameter('argument1', new String_()), + new MethodParameter('argument2', new Object_()), ]; $fixture = new Method('myMethod', $arguments, new Void_(), true, new Description('My Description')); @@ -284,11 +213,9 @@ public function testStringRepresentationIsReturnedWithoutDescription(): void (string) $fixture ); - // --- - $arguments = [ - ['name' => 'argument1', 'type' => new String_()], - ['name' => 'argument2', 'type' => new Object_()], + new MethodParameter('argument1', new String_()), + new MethodParameter('argument2', new Object_()), ]; $fixture = new Method('myMethod', $arguments, new Void_(), true); @@ -299,403 +226,11 @@ public function testStringRepresentationIsReturnedWithoutDescription(): void } /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Fqsen - * @uses \phpDocumentor\Reflection\Types\Context - * - * @covers ::create - */ - public function testFactoryMethod(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description('My Description'); - $expectedArguments = [ - ['name' => 'argument1', 'type' => new String_()], - ['name' => 'argument2', 'type' => new Mixed_()], - ]; - - $descriptionFactory->shouldReceive('create') - ->with('My Description', $context) - ->andReturn($description); - - $fixture = Method::create( - 'static void myMethod(string $argument1, $argument2) My Description', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertSame( - 'static void myMethod(string $argument1, mixed $argument2) My Description', - (string) $fixture - ); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertEquals($expectedArguments, $fixture->getArguments()); - $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); - $this->assertSame($description, $fixture->getDescription()); - $this->assertFalse($fixture->returnsReference()); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Types\Context - * - * @covers ::create - */ - public function testReturnTypeThis(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description(''); - - $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description); - - $fixture = Method::create( - 'static $this myMethod()', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertTrue($fixture->isStatic()); - $this->assertSame('static $this myMethod()', (string) $fixture); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertInstanceOf(This::class, $fixture->getReturnType()); - $this->assertFalse($fixture->returnsReference()); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Types\Context - * - * @covers ::create - */ - public function testReturnTypeNoneWithLongMethodName(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description(''); - - $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description); - - $fixture = Method::create( - 'myVeryLongMethodName($node)', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertFalse($fixture->isStatic()); - $this->assertSame('void myVeryLongMethodName(mixed $node)', (string) $fixture); - $this->assertSame('myVeryLongMethodName', $fixture->getMethodName()); - $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); - $this->assertFalse($fixture->returnsReference()); - } - - /** - * @return string[][] - */ - public function collectionReturnTypesProvider(): array - { - return [ - ['int[]', Array_::class, Integer::class, Compound::class], - ['int[][]', Array_::class, Array_::class, Compound::class], - ['Object[]', Array_::class, Object_::class, Compound::class], - ['array[]', Array_::class, Array_::class, Compound::class], - ]; - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\Types\Array_ - * @uses \phpDocumentor\Reflection\Types\Compound - * @uses \phpDocumentor\Reflection\Types\Integer - * @uses \phpDocumentor\Reflection\Types\Object_ - * - * @dataProvider collectionReturnTypesProvider * @covers ::create */ - public function testCollectionReturnTypes( - string $returnType, - string $expectedType, - ?string $expectedValueType = null, - ?string $expectedKeyType = null - ): void { - $resolver = new TypeResolver(); - $descriptionFactory = m::mock(DescriptionFactory::class); - $descriptionFactory->shouldReceive('create') - ->with('', null) - ->andReturn(new Description('')); - - $fixture = Method::create("${returnType} myMethod(\$arg)", $resolver, $descriptionFactory); - $returnType = $fixture->getReturnType(); - $this->assertInstanceOf($expectedType, $returnType); - - if (!($returnType instanceof Array_)) { - return; - } - - $this->assertInstanceOf($expectedValueType, $returnType->getValueType()); - $this->assertInstanceOf($expectedKeyType, $returnType->getKeyType()); - } - - /** - * @covers ::create - */ - public function testFactoryMethodFailsIfBodyIsEmpty(): void + public function testFactoryMethodThrows(): void { - $this->expectException('InvalidArgumentException'); + $this->expectException(CannotCreateTag::class); Method::create(''); } - - /** - * @covers ::create - */ - public function testFactoryMethodReturnsNullIfBodyIsIncorrect(): void - { - $this->expectException('InvalidArgumentException'); - $this->assertNull(Method::create('body(')); - } - - /** - * @covers ::create - */ - public function testFactoryMethodFailsIfResolverIsNull(): void - { - $this->expectException('InvalidArgumentException'); - Method::create('body'); - } - - /** - * @covers ::create - */ - public function testFactoryMethodFailsIfDescriptionFactoryIsNull(): void - { - $this->expectException('InvalidArgumentException'); - Method::create('body', new TypeResolver()); - } - - /** - * @covers ::__construct - */ - public function testCreationFailsIfBodyIsEmpty(): void - { - $this->expectException('InvalidArgumentException'); - new Method(''); - } - - /** - * @covers ::__construct - */ - public function testCreationFailsIfArgumentRecordContainsInvalidEntry(): void - { - $this->expectException('InvalidArgumentException'); - new Method('body', [['name' => 'myName', 'unknown' => 'nah']]); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Fqsen - * @uses \phpDocumentor\Reflection\Types\Context - * - * @covers ::create - */ - public function testCreateMethodParenthesisMissing(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description('My Description'); - - $descriptionFactory->shouldReceive('create')->with( - 'My Description', - $context - )->andReturn($description); - - $fixture = Method::create( - 'static void myMethod My Description', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertSame('static void myMethod() My Description', (string) $fixture); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertEquals([], $fixture->getArguments()); - $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); - $this->assertSame($description, $fixture->getDescription()); - $this->assertFalse($fixture->returnsReference()); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Fqsen - * @uses \phpDocumentor\Reflection\Types\Context - * - * @covers ::create - */ - public function testCreateMethodEmptyArguments(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description('My Description'); - - $descriptionFactory->shouldReceive('create') - ->with('My Description', $context) - ->andReturn($description); - - $fixture = Method::create( - 'static void myMethod() My Description', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertSame('static void myMethod() My Description', (string) $fixture); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertEquals([], $fixture->getArguments()); - $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); - $this->assertSame($description, $fixture->getDescription()); - $this->assertFalse($fixture->returnsReference()); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Fqsen - * @uses \phpDocumentor\Reflection\Types\Context - * @uses \phpDocumentor\Reflection\Types\Void_ - * - * @covers ::create - */ - public function testCreateWithoutReturnType(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description(''); - - $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description); - - $fixture = Method::create( - 'myMethod()', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertSame('void myMethod()', (string) $fixture); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertEquals([], $fixture->getArguments()); - $this->assertInstanceOf(Void_::class, $fixture->getReturnType()); - $this->assertSame($description, $fixture->getDescription()); - $this->assertFalse($fixture->returnsReference()); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Fqsen - * @uses \phpDocumentor\Reflection\Types\Context - * @uses \phpDocumentor\Reflection\Types\Array_ - * @uses \phpDocumentor\Reflection\Types\Compound - * @uses \phpDocumentor\Reflection\Types\Integer - * @uses \phpDocumentor\Reflection\Types\Object_ - * - * @covers ::create - */ - public function testCreateWithMixedReturnTypes(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $descriptionFactory->shouldReceive('create')->andReturn(new Description('')); - - $fixture = Method::create( - 'MyClass[]|int[] myMethod()', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertSame('\MyClass[]|int[] myMethod()', (string) $fixture); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertEquals([], $fixture->getArguments()); - - $this->assertEquals( - new Compound([ - new Array_(new Object_(new Fqsen('\MyClass'))), - new Array_(new Integer()), - ]), - $fixture->getReturnType() - ); - } - - /** - * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method:: - * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory - * @uses \phpDocumentor\Reflection\TypeResolver - * @uses \phpDocumentor\Reflection\DocBlock\Description - * @uses \phpDocumentor\Reflection\Fqsen - * @uses \phpDocumentor\Reflection\Types\Context - * @uses \phpDocumentor\Reflection\Types\String_ - * - * @covers ::create - */ - public function testCreateWithReference(): void - { - $descriptionFactory = m::mock(DescriptionFactory::class); - $resolver = new TypeResolver(); - $context = new Context(''); - - $description = new Description(''); - - $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description); - - $fixture = Method::create( - 'string &myMethod()', - $resolver, - $descriptionFactory, - $context - ); - - $this->assertSame('string &myMethod()', (string) $fixture); - $this->assertSame('myMethod', $fixture->getMethodName()); - $this->assertEquals([], $fixture->getArguments()); - $this->assertInstanceOf(String_::class, $fixture->getReturnType()); - $this->assertSame($description, $fixture->getDescription()); - $this->assertTrue($fixture->returnsReference()); - } }