Skip to content

Commit dfc94f9

Browse files
committed
Tests/GetMethodPropertiesTest: add extra tests
This adds some extra tests which were already in use in PHPCSUtils.
1 parent 18b9ccf commit dfc94f9

File tree

2 files changed

+213
-17
lines changed

2 files changed

+213
-17
lines changed

tests/Core/File/GetMethodPropertiesTest.inc

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ class MyClass {
3434
/* testMessyNullableReturnMethod */
3535
public function myFunction() /* comment
3636
*/ :
37-
/* comment */ ? //comment
37+
/* comment */ ? // phpcs:ignore Stnd.Cat.Sniff -- For reasons.
3838
array {}
3939

4040
/* testReturnNamespace */
4141
function myFunction(): \MyNamespace\MyClass {}
4242

4343
/* testReturnMultilineNamespace */
44+
// Parse error in PHP 8.0.
4445
function myFunction(): \MyNamespace /** comment *\/ comment */
4546
\MyClass /* comment */
4647
\Foo {}
@@ -163,3 +164,27 @@ function pseudoTypeTrue(): ?true {}
163164
/* testPHP82PseudoTypeFalseAndTrue */
164165
// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method.
165166
function pseudoTypeFalseAndTrue(): true|false {}
167+
168+
/* testNotAFunction */
169+
return true;
170+
171+
/* testPhpcsIssue1264 */
172+
function foo() : array {
173+
echo $foo;
174+
}
175+
176+
/* testArrowFunctionArrayReturnValue */
177+
$fn = fn(): array => [a($a, $b)];
178+
179+
/* testArrowFunctionReturnByRef */
180+
fn&(?string $a) : ?string => $b;
181+
182+
/* testFunctionCallFnPHPCS353-354 */
183+
$value = $obj->fn(true);
184+
185+
/* testFunctionDeclarationNestedInTernaryPHPCS2975 */
186+
return (!$a ? [ new class { public function b(): c {} } ] : []);
187+
188+
/* testArrowFunctionLiveCoding */
189+
// Intentional parse error. This has to be the last test in the file.
190+
$fn = fn

tests/Core/File/GetMethodPropertiesTest.php

Lines changed: 187 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace PHP_CodeSniffer\Tests\Core\File;
1111

12+
use PHP_CodeSniffer\Exceptions\RuntimeException;
1213
use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
1314

1415
/**
@@ -20,6 +21,60 @@ class GetMethodPropertiesTest extends AbstractMethodUnitTest
2021
{
2122

2223

24+
/**
25+
* Test receiving an expected exception when a non function token is passed.
26+
*
27+
* @param string $commentString The comment which preceeds the test.
28+
* @param string|int|array<int|string> $targetTokenType The token type to search for after $commentString.
29+
*
30+
* @dataProvider dataNotAFunctionException
31+
*
32+
* @return void
33+
*/
34+
public function testNotAFunctionException($commentString, $targetTokenType)
35+
{
36+
$this->expectException(RuntimeException::class);
37+
$this->expectExceptionMessage('$stackPtr must be of type T_FUNCTION or T_CLOSURE or T_FN');
38+
39+
$next = $this->getTargetToken($commentString, $targetTokenType);
40+
self::$phpcsFile->getMethodProperties($next);
41+
42+
}//end testNotAFunctionException()
43+
44+
45+
/**
46+
* Data Provider.
47+
*
48+
* @see testNotAFunctionException() For the array format.
49+
*
50+
* @return array<string, array<string, string|int|array<int|string>>>
51+
*/
52+
public static function dataNotAFunctionException()
53+
{
54+
return [
55+
'return' => [
56+
'commentString' => '/* testNotAFunction */',
57+
'targetTokenType' => T_RETURN,
58+
],
59+
'function-call-fn-phpcs-3.5.3-3.5.4' => [
60+
'commentString' => '/* testFunctionCallFnPHPCS353-354 */',
61+
'targetTokenType' => [
62+
T_FN,
63+
T_STRING,
64+
],
65+
],
66+
'fn-live-coding' => [
67+
'commentString' => '/* testArrowFunctionLiveCoding */',
68+
'targetTokenType' => [
69+
T_FN,
70+
T_STRING,
71+
],
72+
],
73+
];
74+
75+
}//end dataNotAFunctionException()
76+
77+
2378
/**
2479
* Test a basic function.
2580
*
@@ -335,15 +390,18 @@ public function testReturnMultilineNamespace()
335390
*/
336391
public function testReturnUnqualifiedName()
337392
{
393+
// Offsets are relative to the T_FUNCTION token.
338394
$expected = [
339-
'scope' => 'private',
340-
'scope_specified' => true,
341-
'return_type' => '?MyClass',
342-
'nullable_return_type' => true,
343-
'is_abstract' => false,
344-
'is_final' => false,
345-
'is_static' => false,
346-
'has_body' => true,
395+
'scope' => 'private',
396+
'scope_specified' => true,
397+
'return_type' => '?MyClass',
398+
'return_type_token' => 8,
399+
'return_type_end_token' => 8,
400+
'nullable_return_type' => true,
401+
'is_abstract' => false,
402+
'is_final' => false,
403+
'is_static' => false,
404+
'has_body' => true,
347405
];
348406

349407
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
@@ -358,15 +416,18 @@ public function testReturnUnqualifiedName()
358416
*/
359417
public function testReturnPartiallyQualifiedName()
360418
{
419+
// Offsets are relative to the T_FUNCTION token.
361420
$expected = [
362-
'scope' => 'public',
363-
'scope_specified' => false,
364-
'return_type' => 'Sub\Level\MyClass',
365-
'nullable_return_type' => false,
366-
'is_abstract' => false,
367-
'is_final' => false,
368-
'is_static' => false,
369-
'has_body' => true,
421+
'scope' => 'public',
422+
'scope_specified' => false,
423+
'return_type' => 'Sub\Level\MyClass',
424+
'return_type_token' => 7,
425+
'return_type_end_token' => 7,
426+
'nullable_return_type' => false,
427+
'is_abstract' => false,
428+
'is_final' => false,
429+
'is_static' => false,
430+
'has_body' => true,
370431
];
371432

372433
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
@@ -1102,6 +1163,116 @@ public function testPHP82PseudoTypeFalseAndTrue()
11021163
}//end testPHP82PseudoTypeFalseAndTrue()
11031164

11041165

1166+
/**
1167+
* Test for incorrect tokenization of array return type declarations in PHPCS < 2.8.0.
1168+
*
1169+
* @link https://github.com/squizlabs/PHP_CodeSniffer/pull/1264
1170+
*
1171+
* @return void
1172+
*/
1173+
public function testPhpcsIssue1264()
1174+
{
1175+
// Offsets are relative to the T_FUNCTION token.
1176+
$expected = [
1177+
'scope' => 'public',
1178+
'scope_specified' => false,
1179+
'return_type' => 'array',
1180+
'return_type_token' => 8,
1181+
'return_type_end_token' => 8,
1182+
'nullable_return_type' => false,
1183+
'is_abstract' => false,
1184+
'is_final' => false,
1185+
'is_static' => false,
1186+
'has_body' => true,
1187+
];
1188+
1189+
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
1190+
1191+
}//end testPhpcsIssue1264()
1192+
1193+
1194+
/**
1195+
* Test handling of incorrect tokenization of array return type declarations for arrow functions
1196+
* in a very specific code sample in PHPCS < 3.5.4.
1197+
*
1198+
* @link https://github.com/squizlabs/PHP_CodeSniffer/issues/2773
1199+
*
1200+
* @return void
1201+
*/
1202+
public function testArrowFunctionArrayReturnValue()
1203+
{
1204+
// Offsets are relative to the T_FN token.
1205+
$expected = [
1206+
'scope' => 'public',
1207+
'scope_specified' => false,
1208+
'return_type' => 'array',
1209+
'return_type_token' => 5,
1210+
'return_type_end_token' => 5,
1211+
'nullable_return_type' => false,
1212+
'is_abstract' => false,
1213+
'is_final' => false,
1214+
'is_static' => false,
1215+
'has_body' => true,
1216+
];
1217+
1218+
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
1219+
1220+
}//end testArrowFunctionArrayReturnValue()
1221+
1222+
1223+
/**
1224+
* Test handling of an arrow function returning by reference.
1225+
*
1226+
* @return void
1227+
*/
1228+
public function testArrowFunctionReturnByRef()
1229+
{
1230+
// Offsets are relative to the T_FN token.
1231+
$expected = [
1232+
'scope' => 'public',
1233+
'scope_specified' => false,
1234+
'return_type' => '?string',
1235+
'return_type_token' => 12,
1236+
'return_type_end_token' => 12,
1237+
'nullable_return_type' => true,
1238+
'is_abstract' => false,
1239+
'is_final' => false,
1240+
'is_static' => false,
1241+
'has_body' => true,
1242+
];
1243+
1244+
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
1245+
1246+
}//end testArrowFunctionReturnByRef()
1247+
1248+
1249+
/**
1250+
* Test handling of function declaration nested in a ternary, where the colon for the
1251+
* return type was incorrectly tokenized as T_INLINE_ELSE prior to PHPCS 3.5.7.
1252+
*
1253+
* @return void
1254+
*/
1255+
public function testFunctionDeclarationNestedInTernaryPHPCS2975()
1256+
{
1257+
// Offsets are relative to the T_FN token.
1258+
$expected = [
1259+
'scope' => 'public',
1260+
'scope_specified' => true,
1261+
'return_type' => 'c',
1262+
'return_type_token' => 7,
1263+
'return_type_end_token' => 7,
1264+
'nullable_return_type' => false,
1265+
'is_abstract' => false,
1266+
'is_final' => false,
1267+
'is_static' => false,
1268+
'has_body' => true,
1269+
];
1270+
1271+
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
1272+
1273+
}//end testFunctionDeclarationNestedInTernaryPHPCS2975()
1274+
1275+
11051276
/**
11061277
* Test helper.
11071278
*

0 commit comments

Comments
 (0)