Skip to content

Commit 5971a5f

Browse files
committed
Tests/GetMethodPropertiesTest: add extra tests
This adds some extra tests which were already in use in PHPCSUtils.
1 parent 4a759e3 commit 5971a5f

File tree

2 files changed

+247
-1
lines changed

2 files changed

+247
-1
lines changed

tests/Core/File/GetMethodPropertiesTest.inc

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,23 @@ 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 {}
48+
49+
/* testReturnUnqualifiedName */
50+
private function myFunction(): ?MyClass {}
51+
52+
/* testReturnPartiallyQualifiedName */
53+
function myFunction(): Sub\Level\MyClass {}
4754
}
4855

4956
abstract class MyClass
@@ -157,3 +164,27 @@ function pseudoTypeTrue(): ?true {}
157164
/* testPHP82PseudoTypeFalseAndTrue */
158165
// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method.
159166
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: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,59 @@ class GetMethodPropertiesTest extends AbstractMethodUnitTest
2020
{
2121

2222

23+
/**
24+
* Test receiving an expected exception when a non function token is passed.
25+
*
26+
* @param string $commentString The comment which preceeds the test.
27+
* @param string|int|array<int|string> $targetTokenType The token type to search for after $commentString.
28+
*
29+
* @dataProvider dataNotAFunctionException
30+
*
31+
* @return void
32+
*/
33+
public function testNotAFunctionException($commentString, $targetTokenType)
34+
{
35+
$this->expectRunTimeException('$stackPtr must be of type T_FUNCTION or T_CLOSURE or T_FN');
36+
37+
$next = $this->getTargetToken($commentString, $targetTokenType);
38+
self::$phpcsFile->getMethodProperties($next);
39+
40+
}//end testNotAFunctionException()
41+
42+
43+
/**
44+
* Data Provider.
45+
*
46+
* @see testNotAFunctionException() For the array format.
47+
*
48+
* @return array<string, array<string, string|int|array<int|string>>>
49+
*/
50+
public static function dataNotAFunctionException()
51+
{
52+
return [
53+
'return' => [
54+
'commentString' => '/* testNotAFunction */',
55+
'targetTokenType' => T_RETURN,
56+
],
57+
'function-call-fn-phpcs-3.5.3-3.5.4' => [
58+
'commentString' => '/* testFunctionCallFnPHPCS353-354 */',
59+
'targetTokenType' => [
60+
T_FN,
61+
T_STRING,
62+
],
63+
],
64+
'fn-live-coding' => [
65+
'commentString' => '/* testArrowFunctionLiveCoding */',
66+
'targetTokenType' => [
67+
T_FN,
68+
T_STRING,
69+
],
70+
],
71+
];
72+
73+
}//end dataNotAFunctionException()
74+
75+
2376
/**
2477
* Test a basic function.
2578
*
@@ -328,6 +381,58 @@ public function testReturnMultilineNamespace()
328381
}//end testReturnMultilineNamespace()
329382

330383

384+
/**
385+
* Test a method with an unqualified named return type.
386+
*
387+
* @return void
388+
*/
389+
public function testReturnUnqualifiedName()
390+
{
391+
// Offsets are relative to the T_FUNCTION token.
392+
$expected = [
393+
'scope' => 'private',
394+
'scope_specified' => true,
395+
'return_type' => '?MyClass',
396+
'return_type_token' => 8,
397+
'return_type_end_token' => 8,
398+
'nullable_return_type' => true,
399+
'is_abstract' => false,
400+
'is_final' => false,
401+
'is_static' => false,
402+
'has_body' => true,
403+
];
404+
405+
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
406+
407+
}//end testReturnUnqualifiedName()
408+
409+
410+
/**
411+
* Test a method with a partially qualified namespaced return type.
412+
*
413+
* @return void
414+
*/
415+
public function testReturnPartiallyQualifiedName()
416+
{
417+
// Offsets are relative to the T_FUNCTION token.
418+
$expected = [
419+
'scope' => 'public',
420+
'scope_specified' => false,
421+
'return_type' => 'Sub\Level\MyClass',
422+
'return_type_token' => 7,
423+
'return_type_end_token' => 11,
424+
'nullable_return_type' => false,
425+
'is_abstract' => false,
426+
'is_final' => false,
427+
'is_static' => false,
428+
'has_body' => true,
429+
];
430+
431+
$this->getMethodPropertiesTestHelper('/* '.__FUNCTION__.' */', $expected);
432+
433+
}//end testReturnPartiallyQualifiedName()
434+
435+
331436
/**
332437
* Test a basic abstract method.
333438
*
@@ -1056,6 +1161,116 @@ public function testPHP82PseudoTypeFalseAndTrue()
10561161
}//end testPHP82PseudoTypeFalseAndTrue()
10571162

10581163

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

0 commit comments

Comments
 (0)