* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence */ namespace PHP_CodeSniffer\Tests\Core\File; use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest; class GetMethodPropertiesTest extends AbstractMethodUnitTest { /** * Test a basic function. * * @return void */ public function testBasicFunction() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testBasicFunction() /** * Test a function with a return type. * * @return void */ public function testReturnFunction() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'array', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testReturnFunction() /** * Test a closure used as a function argument. * * @return void */ public function testNestedClosure() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testNestedClosure() /** * Test a basic method. * * @return void */ public function testBasicMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testBasicMethod() /** * Test a private static method. * * @return void */ public function testPrivateStaticMethod() { $expected = [ 'scope' => 'private', 'scope_specified' => true, 'return_type' => '', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => true, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPrivateStaticMethod() /** * Test a basic final method. * * @return void */ public function testFinalMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => '', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => true, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testFinalMethod() /** * Test a protected method with a return type. * * @return void */ public function testProtectedReturnMethod() { $expected = [ 'scope' => 'protected', 'scope_specified' => true, 'return_type' => 'int', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testProtectedReturnMethod() /** * Test a public method with a return type. * * @return void */ public function testPublicReturnMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => 'array', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPublicReturnMethod() /** * Test a public method with a nullable return type. * * @return void */ public function testNullableReturnMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => '?array', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testNullableReturnMethod() /** * Test a public method with a nullable return type. * * @return void */ public function testMessyNullableReturnMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => '?array', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testMessyNullableReturnMethod() /** * Test a method with a namespaced return type. * * @return void */ public function testReturnNamespace() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '\MyNamespace\MyClass', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testReturnNamespace() /** * Test a method with a messy namespaces return type. * * @return void */ public function testReturnMultilineNamespace() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '\MyNamespace\MyClass\Foo', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testReturnMultilineNamespace() /** * Test a basic abstract method. * * @return void */ public function testAbstractMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '', 'nullable_return_type' => false, 'is_abstract' => true, 'is_final' => false, 'is_static' => false, 'has_body' => false, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testAbstractMethod() /** * Test an abstract method with a return type. * * @return void */ public function testAbstractReturnMethod() { $expected = [ 'scope' => 'protected', 'scope_specified' => true, 'return_type' => 'bool', 'nullable_return_type' => false, 'is_abstract' => true, 'is_final' => false, 'is_static' => false, 'has_body' => false, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testAbstractReturnMethod() /** * Test a basic interface method. * * @return void */ public function testInterfaceMethod() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => false, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testInterfaceMethod() /** * Test a static arrow function. * * @return void */ public function testArrowFunction() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => true, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testArrowFunction() /** * Test a function with return type "static". * * @return void */ public function testReturnTypeStatic() { $expected = [ 'scope' => 'private', 'scope_specified' => true, 'return_type' => 'static', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testReturnTypeStatic() /** * Test a function with return type "mixed". * * @return void */ public function testPHP8MixedTypeHint() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'mixed', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8MixedTypeHint() /** * Test a function with return type "mixed" and nullability. * * @return void */ public function testPHP8MixedTypeHintNullable() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?mixed', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8MixedTypeHintNullable() /** * Test a function with return type using the namespace operator. * * @return void */ public function testNamespaceOperatorTypeHint() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?namespace\Name', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testNamespaceOperatorTypeHint() /** * Verify recognition of PHP8 union type declaration. * * @return void */ public function testPHP8UnionTypesSimple() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int|float', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8UnionTypesSimple() /** * Verify recognition of PHP8 union type declaration with two classes. * * @return void */ public function testPHP8UnionTypesTwoClasses() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'MyClassA|\Package\MyClassB', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8UnionTypesTwoClasses() /** * Verify recognition of PHP8 union type declaration with all base types. * * @return void */ public function testPHP8UnionTypesAllBaseTypes() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'array|bool|callable|int|float|null|Object|string', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8UnionTypesAllBaseTypes() /** * Verify recognition of PHP8 union type declaration with all pseudo types. * * @return void */ public function testPHP8UnionTypesAllPseudoTypes() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'false|MIXED|self|parent|static|iterable|Resource|void', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8UnionTypesAllPseudoTypes() /** * Verify recognition of PHP8 union type declaration with (illegal) nullability. * * @return void */ public function testPHP8UnionTypesNullable() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?int|float', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8UnionTypesNullable() /** * Verify recognition of PHP8 type declaration with (illegal) single type null. * * @return void */ public function testPHP8PseudoTypeNull() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'null', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8PseudoTypeNull() /** * Verify recognition of PHP8 type declaration with (illegal) single type false. * * @return void */ public function testPHP8PseudoTypeFalse() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'false', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8PseudoTypeFalse() /** * Verify recognition of PHP8 type declaration with (illegal) type false combined with type bool. * * @return void */ public function testPHP8PseudoTypeFalseAndBool() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'bool|false', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8PseudoTypeFalseAndBool() /** * Verify recognition of PHP8 type declaration with (illegal) type object combined with a class name. * * @return void */ public function testPHP8ObjectAndClass() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'object|ClassName', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8ObjectAndClass() /** * Verify recognition of PHP8 type declaration with (illegal) type iterable combined with array/Traversable. * * @return void */ public function testPHP8PseudoTypeIterableAndArray() { $expected = [ 'scope' => 'public', 'scope_specified' => true, 'return_type' => 'iterable|array|Traversable', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => false, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8PseudoTypeIterableAndArray() /** * Verify recognition of PHP8 type declaration with (illegal) duplicate types. * * @return void */ public function testPHP8DuplicateTypeInUnionWhitespaceAndComment() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'int|string|INT', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8DuplicateTypeInUnionWhitespaceAndComment() /** * Verify recognition of PHP8.1 type "never". * * @return void */ public function testPHP81NeverType() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'never', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP81NeverType() /** * Verify recognition of PHP8.1 type "never" with (illegal) nullability. * * @return void */ public function testPHP81NullableNeverType() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?never', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP81NullableNeverType() /** /** * Verify recognition of PHP8.1 intersection type declaration. * * @return void */ public function testPHP8IntersectionTypes() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'Foo&Bar', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP8IntersectionTypes() /** * Verify recognition of PHP8.1 intersection type declaration with more types. * * @return void */ public function testPHP81MoreIntersectionTypes() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'MyClassA&\Package\MyClassB&\Package\MyClassC', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP81MoreIntersectionTypes() /** * Verify recognition of PHP8.1 intersection type declaration in arrow function. * * @return void */ public function testPHP81IntersectionArrowFunction() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'MyClassA&\Package\MyClassB', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP81IntersectionArrowFunction() /** * Verify recognition of PHP8.1 intersection type declaration with illegal simple types. * * @return void */ public function testPHP81IllegalIntersectionTypes() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => 'string&int', 'nullable_return_type' => false, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP81IllegalIntersectionTypes() /** * Verify recognition of PHP8.1 intersection type declaration with (illegal) nullability. * * @return void */ public function testPHP81NullableIntersectionTypes() { $expected = [ 'scope' => 'public', 'scope_specified' => false, 'return_type' => '?Foo&Bar', 'nullable_return_type' => true, 'is_abstract' => false, 'is_final' => false, 'is_static' => false, 'has_body' => true, ]; $this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected); }//end testPHP81NullableIntersectionTypes() /** * Test helper. * * @param string $commentString The comment which preceeds the test. * @param array $expected The expected function output. * * @return void */ private function getMethodPropertiesTestHelper($commentString, $expected) { $function = $this->getTargetToken($commentString, [T_FUNCTION, T_CLOSURE, T_FN]); $found = self::$phpcsFile->getMethodProperties($function); $this->assertArraySubset($expected, $found, true); }//end getMethodPropertiesTestHelper() }//end class