diff --git a/tests/Core/File/FindStartOfStatementTest.inc b/tests/Core/File/FindStartOfStatementTest.inc
index ce9dfad3f9..148d8103a5 100644
--- a/tests/Core/File/FindStartOfStatementTest.inc
+++ b/tests/Core/File/FindStartOfStatementTest.inc
@@ -121,3 +121,44 @@ return 0;
?>
Test
= '', foo(), '
';
+
+$value = [
+ /* testPrecededByArrowFunctionInArray - Expected */
+ Url::make('View Song', fn($song) => $song->url())
+ /* testPrecededByArrowFunctionInArray */
+ ->onlyOnDetail(),
+
+ new Panel('Information', [
+ Text::make('Title')
+ ]),
+];
+
+switch ($foo) {
+ /* testCaseStatement */
+ case 1:
+ /* testInsideCaseStatement */
+ $var = doSomething();
+ /* testInsideCaseBreakStatement */
+ break 2;
+
+ case 2:
+ /* testInsideCaseContinueStatement */
+ continue 2;
+
+ case 3:
+ /* testInsideCaseReturnStatement */
+ return false;
+
+ case 4:
+ /* testInsideCaseExitStatement */
+ exit(1);
+
+ case 5:
+ /* testInsideCaseThrowStatement */
+ throw new Exception();
+
+ /* testDefaultStatement */
+ default:
+ /* testInsideDefaultContinueStatement */
+ continue $var;
+}
diff --git a/tests/Core/File/FindStartOfStatementTest.php b/tests/Core/File/FindStartOfStatementTest.php
index 25b7f6aa73..334d05b2b3 100644
--- a/tests/Core/File/FindStartOfStatementTest.php
+++ b/tests/Core/File/FindStartOfStatementTest.php
@@ -3,7 +3,9 @@
* Tests for the \PHP_CodeSniffer\Files\File:findStartOfStatement method.
*
* @author Greg Sherwood
+ * @author Juliette Reinders Folmer
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @copyright 2019-2024 PHPCSStandards Contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
@@ -505,4 +507,134 @@ public function testOpenTagWithEcho()
}//end testOpenTagWithEcho()
+ /**
+ * Test object call on result of static function call with arrow function as parameter and wrapped within an array.
+ *
+ * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/2849
+ * @link https://github.com/squizlabs/PHP_CodeSniffer/commit/fbf67efc3fc0c2a355f5585d49f4f6fe160ff2f9
+ *
+ * @return void
+ */
+ public function testObjectCallPrecededByArrowFunctionAsFunctionCallParameterInArray()
+ {
+ $expected = $this->getTargetToken('/* testPrecededByArrowFunctionInArray - Expected */', T_STRING, 'Url');
+
+ $start = $this->getTargetToken('/* testPrecededByArrowFunctionInArray */', T_STRING, 'onlyOnDetail');
+ $found = self::$phpcsFile->findStartOfStatement($start);
+
+ $this->assertSame($expected, $found);
+
+ }//end testObjectCallPrecededByArrowFunctionAsFunctionCallParameterInArray()
+
+
+ /**
+ * Test finding the start of a statement inside a switch control structure case/default statement.
+ *
+ * @param string $testMarker The comment which prefaces the target token in the test file.
+ * @param int|string $targets The token to search for after the test marker.
+ * @param string|int $expectedTarget Token code of the expected start of statement stack pointer.
+ *
+ * @link https://github.com/squizlabs/php_codesniffer/issues/3192
+ * @link https://github.com/squizlabs/PHP_CodeSniffer/pull/3186/commits/18a0e54735bb9b3850fec266e5f4c50dacf618ea
+ *
+ * @dataProvider dataFindStartInsideSwitchCaseDefaultStatements
+ *
+ * @return void
+ */
+ public function testFindStartInsideSwitchCaseDefaultStatements($testMarker, $targets, $expectedTarget)
+ {
+ $testToken = $this->getTargetToken($testMarker, $targets);
+ $expected = $this->getTargetToken($testMarker, $expectedTarget);
+
+ $found = self::$phpcsFile->findStartOfStatement($testToken);
+
+ $this->assertSame($expected, $found);
+
+ }//end testFindStartInsideSwitchCaseDefaultStatements()
+
+
+ /**
+ * Data provider.
+ *
+ * @return array>
+ */
+ public static function dataFindStartInsideSwitchCaseDefaultStatements()
+ {
+ return [
+ 'Case keyword should be start of case statement - case itself' => [
+ 'testMarker' => '/* testCaseStatement */',
+ 'targets' => T_CASE,
+ 'expectedTarget' => T_CASE,
+ ],
+ 'Case keyword should be start of case statement - number (what\'s being compared)' => [
+ 'testMarker' => '/* testCaseStatement */',
+ 'targets' => T_LNUMBER,
+ 'expectedTarget' => T_CASE,
+ ],
+ 'Variable should be start of arbitrary assignment statement - variable itself' => [
+ 'testMarker' => '/* testInsideCaseStatement */',
+ 'targets' => T_VARIABLE,
+ 'expectedTarget' => T_VARIABLE,
+ ],
+ 'Variable should be start of arbitrary assignment statement - equal sign' => [
+ 'testMarker' => '/* testInsideCaseStatement */',
+ 'targets' => T_EQUAL,
+ 'expectedTarget' => T_VARIABLE,
+ ],
+ 'Variable should be start of arbitrary assignment statement - function call' => [
+ 'testMarker' => '/* testInsideCaseStatement */',
+ 'targets' => T_STRING,
+ 'expectedTarget' => T_VARIABLE,
+ ],
+ 'Break should be start for contents of the break statement - contents' => [
+ 'testMarker' => '/* testInsideCaseBreakStatement */',
+ 'targets' => T_LNUMBER,
+ 'expectedTarget' => T_BREAK,
+ ],
+ 'Continue should be start for contents of the continue statement - contents' => [
+ 'testMarker' => '/* testInsideCaseContinueStatement */',
+ 'targets' => T_LNUMBER,
+ 'expectedTarget' => T_CONTINUE,
+ ],
+ 'Return should be start for contents of the return statement - contents' => [
+ 'testMarker' => '/* testInsideCaseReturnStatement */',
+ 'targets' => T_FALSE,
+ 'expectedTarget' => T_RETURN,
+ ],
+ 'Exit should be start for contents of the exit statement - close parenthesis' => [
+ // Note: not sure if this is actually correct - should this be the open parenthesis ?
+ 'testMarker' => '/* testInsideCaseExitStatement */',
+ 'targets' => T_CLOSE_PARENTHESIS,
+ 'expectedTarget' => T_EXIT,
+ ],
+ 'Throw should be start for contents of the throw statement - new keyword' => [
+ 'testMarker' => '/* testInsideCaseThrowStatement */',
+ 'targets' => T_NEW,
+ 'expectedTarget' => T_THROW,
+ ],
+ 'Throw should be start for contents of the throw statement - exception name' => [
+ 'testMarker' => '/* testInsideCaseThrowStatement */',
+ 'targets' => T_STRING,
+ 'expectedTarget' => T_THROW,
+ ],
+ 'Throw should be start for contents of the throw statement - close parenthesis' => [
+ 'testMarker' => '/* testInsideCaseThrowStatement */',
+ 'targets' => T_CLOSE_PARENTHESIS,
+ 'expectedTarget' => T_THROW,
+ ],
+ 'Default keyword should be start of default statement - default itself' => [
+ 'testMarker' => '/* testDefaultStatement */',
+ 'targets' => T_DEFAULT,
+ 'expectedTarget' => T_DEFAULT,
+ ],
+ 'Return should be start for contents of the return statement (inside default) - variable' => [
+ 'testMarker' => '/* testInsideDefaultContinueStatement */',
+ 'targets' => T_VARIABLE,
+ 'expectedTarget' => T_CONTINUE,
+ ],
+ ];
+
+ }//end dataFindStartInsideSwitchCaseDefaultStatements()
+
+
}//end class