diff --git a/src/ToolBox/ParameterAnalyzer.php b/src/ToolBox/ParameterAnalyzer.php index 61aed1eb..21402191 100644 --- a/src/ToolBox/ParameterAnalyzer.php +++ b/src/ToolBox/ParameterAnalyzer.php @@ -95,7 +95,7 @@ private function getParameterDescription(\ReflectionMethod $method, string $para return ''; } - $pattern = '/@param\s+\S+\s+\$'.preg_quote($paramName, '/').'\s+(.*)/'; + $pattern = '/@param\s+\S+\s+\$'.preg_quote($paramName, '/').'\s+((.*)(?=\*)|.*)/'; if (preg_match($pattern, $docComment, $matches)) { return trim($matches[1]); } diff --git a/tests/ToolBox/ParameterAnalyzerTest.php b/tests/ToolBox/ParameterAnalyzerTest.php index 2a8c6362..a6a61f73 100644 --- a/tests/ToolBox/ParameterAnalyzerTest.php +++ b/tests/ToolBox/ParameterAnalyzerTest.php @@ -13,6 +13,7 @@ use PhpLlm\LlmChain\ToolBox\Metadata; use PhpLlm\LlmChain\ToolBox\ParameterAnalyzer; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; @@ -163,4 +164,83 @@ public function detectParameterDefinitionNone(): void self::assertNull($actual); } + + #[Test] + public function getParameterDescriptionWithoutDocBlock(): void + { + $targetMethod = self::createStub(\ReflectionMethod::class); + $targetMethod->method('getDocComment')->willReturn(false); + + $methodToTest = new \ReflectionMethod(ParameterAnalyzer::class, 'getParameterDescription'); + + self::assertSame( + '', + $methodToTest->invoke( + $this->analyzer, + $targetMethod, + 'myParam', + ) + ); + } + + #[Test] + #[DataProvider('provideGetParameterDescriptionCases')] + public function getParameterDescriptionWithDocs(string $docComment, string $expectedResult): void + { + $targetMethod = self::createStub(\ReflectionMethod::class); + $targetMethod->method('getDocComment')->willReturn($docComment); + + $methodToTest = new \ReflectionMethod(ParameterAnalyzer::class, 'getParameterDescription'); + + self::assertSame( + $expectedResult, + $methodToTest->invoke( + $this->analyzer, + $targetMethod, + 'myParam', + ) + ); + } + + public static function provideGetParameterDescriptionCases(): \Generator + { + yield 'empty doc block' => [ + 'docComment' => '', + 'expectedResult' => '', + ]; + + yield 'single line doc block with description' => [ + 'docComment' => '/** @param string $myParam The description */', + 'expectedResult' => 'The description', + ]; + + yield 'multi line doc block with description and other tags' => [ + 'docComment' => <<<'TEXT' + /** + * @param string $myParam The description + * @return void + */ + TEXT, + 'expectedResult' => 'The description', + ]; + + yield 'multi line doc block with multiple parameters' => [ + 'docComment' => <<<'TEXT' + /** + * @param string $myParam The description + * @param string $anotherParam The wrong description + */ + TEXT, + 'expectedResult' => 'The description', + ]; + + yield 'multi line doc block with parameter that is not searched for' => [ + 'docComment' => <<<'TEXT' + /** + * @param string $unknownParam The description + */ + TEXT, + 'expectedResult' => '', + ]; + } }