style: apply php-cs-fixer and PHPStan fixes (#289)
* style: apply php-cs-fixer to test files Addresses drift flagged by the default PHP-CS-Fixer config — mostly adds missing `: void` return types on pre-existing test methods. No behavioural changes. * fix: resolve phpstan errors surfaced by qa - Drop the obsolete `Method ::test*() has no return type specified` ignore rule — every test method now declares a return type, so the pattern never matches and phpstan reports it as unmatched. - Remove `?? []` from two reads of `CallToolRequest::$arguments`; the property is typed `array` (non-nullable), so the coalesce is a no-op that phpstan flags. --------- Co-authored-by: DDEV User <nobody@example.com>
This commit is contained in:
parent
7af5a345c1
commit
73e4cc2456
16 changed files with 98 additions and 100 deletions
|
|
@ -44,7 +44,7 @@ class CallToolRequestHandler implements RequestHandlerInterface
|
||||||
\assert($request instanceof CallToolRequest);
|
\assert($request instanceof CallToolRequest);
|
||||||
|
|
||||||
$name = $request->name;
|
$name = $request->name;
|
||||||
$args = $request->arguments ?? [];
|
$args = $request->arguments;
|
||||||
|
|
||||||
if (!isset($this->toolDefinitions[$name])) {
|
if (!isset($this->toolDefinitions[$name])) {
|
||||||
return new Error($request->getId(), Error::METHOD_NOT_FOUND, \sprintf('Tool not found: %s', $name));
|
return new Error($request->getId(), Error::METHOD_NOT_FOUND, \sprintf('Tool not found: %s', $name));
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ parameters:
|
||||||
- tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php
|
- tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php
|
||||||
treatPhpDocTypesAsCertain: false
|
treatPhpDocTypesAsCertain: false
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
-
|
|
||||||
message: "#^Method .*::test.*\\(\\) has no return type specified\\.$#"
|
|
||||||
-
|
-
|
||||||
identifier: missingType.iterableValue
|
identifier: missingType.iterableValue
|
||||||
path: tests/
|
path: tests/
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ final class CallToolHandler implements RequestHandlerInterface
|
||||||
\assert($request instanceof CallToolRequest);
|
\assert($request instanceof CallToolRequest);
|
||||||
|
|
||||||
$toolName = $request->name;
|
$toolName = $request->name;
|
||||||
$arguments = $request->arguments ?? [];
|
$arguments = $request->arguments;
|
||||||
|
|
||||||
$this->logger->debug('Executing tool', ['name' => $toolName, 'arguments' => $arguments]);
|
$this->logger->debug('Executing tool', ['name' => $toolName, 'arguments' => $arguments]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class DiscoveryTest extends TestCase
|
||||||
$this->discoverer = new Discoverer();
|
$this->discoverer = new Discoverer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDiscoversAllElementTypesCorrectlyFromFixtureFiles()
|
public function testDiscoversAllElementTypesCorrectlyFromFixtureFiles(): void
|
||||||
{
|
{
|
||||||
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ class DiscoveryTest extends TestCase
|
||||||
$this->assertEquals([InvocableResourceTemplateFixture::class, '__invoke'], $templates['invokable://user-profile/{userId}']->handler);
|
$this->assertEquals([InvocableResourceTemplateFixture::class, '__invoke'], $templates['invokable://user-profile/{userId}']->handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDoesNotDiscoverElementsFromExcludedDirectories()
|
public function testDoesNotDiscoverElementsFromExcludedDirectories(): void
|
||||||
{
|
{
|
||||||
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
||||||
$this->assertArrayHasKey('hidden_subdir_tool', $discovery->getTools());
|
$this->assertArrayHasKey('hidden_subdir_tool', $discovery->getTools());
|
||||||
|
|
@ -114,14 +114,14 @@ class DiscoveryTest extends TestCase
|
||||||
$this->assertArrayNotHasKey('hidden_subdir_tool', $discovery->getTools());
|
$this->assertArrayNotHasKey('hidden_subdir_tool', $discovery->getTools());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandlesEmptyDirectoriesOrDirectoriesWithNoPhpFiles()
|
public function testHandlesEmptyDirectoriesOrDirectoriesWithNoPhpFiles(): void
|
||||||
{
|
{
|
||||||
$discovery = $this->discoverer->discover(__DIR__, ['EmptyDir']);
|
$discovery = $this->discoverer->discover(__DIR__, ['EmptyDir']);
|
||||||
|
|
||||||
$this->assertTrue($discovery->isEmpty());
|
$this->assertTrue($discovery->isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCorrectlyInfersNamesAndDescriptionsFromMethodsOrClassesIfNotSetInAttribute()
|
public function testCorrectlyInfersNamesAndDescriptionsFromMethodsOrClassesIfNotSetInAttribute(): void
|
||||||
{
|
{
|
||||||
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ class DiscoveryTest extends TestCase
|
||||||
$this->assertEquals('An invokable calculator tool.', $tools['InvokableCalculator']->tool->description);
|
$this->assertEquals('An invokable calculator tool.', $tools['InvokableCalculator']->tool->description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDiscoversEnhancedCompletionProvidersWithValuesAndEnumAttributes()
|
public function testDiscoversEnhancedCompletionProvidersWithValuesAndEnumAttributes(): void
|
||||||
{
|
{
|
||||||
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
$discovery = $this->discoverer->discover(__DIR__, ['Fixtures']);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ class DocBlockParserTest extends TestCase
|
||||||
$this->parser = new DocBlockParser();
|
$this->parser = new DocBlockParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetDescriptionReturnsCorrectDescription()
|
public function testGetDescriptionReturnsCorrectDescription(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithSummaryAndDescription');
|
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithSummaryAndDescription');
|
||||||
$docComment = $method->getDocComment() ?: null;
|
$docComment = $method->getDocComment() ?: null;
|
||||||
|
|
@ -43,7 +43,7 @@ class DocBlockParserTest extends TestCase
|
||||||
$this->assertEquals('Simple summary line.', $this->parser->getDescription($docBlock2));
|
$this->assertEquals('Simple summary line.', $this->parser->getDescription($docBlock2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetParamTagsReturnsStructuredParamInfo()
|
public function testGetParamTagsReturnsStructuredParamInfo(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithParams');
|
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithParams');
|
||||||
$docComment = $method->getDocComment() ?: null;
|
$docComment = $method->getDocComment() ?: null;
|
||||||
|
|
@ -94,7 +94,7 @@ class DocBlockParserTest extends TestCase
|
||||||
$this->assertEquals('object param', $this->parser->getParamDescription($params['$param6']));
|
$this->assertEquals('object param', $this->parser->getParamDescription($params['$param6']));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetTagsByNameReturnsSpecificTags()
|
public function testGetTagsByNameReturnsSpecificTags(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithMultipleTags');
|
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithMultipleTags');
|
||||||
$docComment = $method->getDocComment() ?: null;
|
$docComment = $method->getDocComment() ?: null;
|
||||||
|
|
@ -116,7 +116,7 @@ class DocBlockParserTest extends TestCase
|
||||||
$this->assertEmpty($nonExistentTags);
|
$this->assertEmpty($nonExistentTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandlesMethodWithNoDocblockGracefully()
|
public function testHandlesMethodWithNoDocblockGracefully(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithNoDocBlock');
|
$method = new \ReflectionMethod(DocBlockTestFixture::class, 'methodWithNoDocBlock');
|
||||||
$docComment = $method->getDocComment() ?: null;
|
$docComment = $method->getDocComment() ?: null;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ interface MyDiscoverableInterface
|
||||||
|
|
||||||
trait MyDiscoverableTrait
|
trait MyDiscoverableTrait
|
||||||
{
|
{
|
||||||
public function traitMethod()
|
public function traitMethod(): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use Mcp\Capability\Attribute\McpTool;
|
||||||
class HiddenTool
|
class HiddenTool
|
||||||
{
|
{
|
||||||
#[McpTool(name: 'hidden_subdir_tool')]
|
#[McpTool(name: 'hidden_subdir_tool')]
|
||||||
public function run()
|
public function run(): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class HandlerResolverTest extends TestCase
|
class HandlerResolverTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testResolvesClosuresToReflectionFunction()
|
public function testResolvesClosuresToReflectionFunction(): void
|
||||||
{
|
{
|
||||||
$closure = static function (string $input): string {
|
$closure = static function (string $input): string {
|
||||||
return "processed: $input";
|
return "processed: $input";
|
||||||
|
|
@ -29,7 +29,7 @@ class HandlerResolverTest extends TestCase
|
||||||
$this->assertEquals('string', $returnType->getName());
|
$this->assertEquals('string', $returnType->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testResolvesValidArrayHandler()
|
public function testResolvesValidArrayHandler(): void
|
||||||
{
|
{
|
||||||
$handler = [ValidHandlerClass::class, 'publicMethod'];
|
$handler = [ValidHandlerClass::class, 'publicMethod'];
|
||||||
$resolved = HandlerResolver::resolve($handler);
|
$resolved = HandlerResolver::resolve($handler);
|
||||||
|
|
@ -38,7 +38,7 @@ class HandlerResolverTest extends TestCase
|
||||||
$this->assertEquals(ValidHandlerClass::class, $resolved->getDeclaringClass()->getName());
|
$this->assertEquals(ValidHandlerClass::class, $resolved->getDeclaringClass()->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testResolvesValidInvokableClassStringHandler()
|
public function testResolvesValidInvokableClassStringHandler(): void
|
||||||
{
|
{
|
||||||
$handler = ValidInvokableClass::class;
|
$handler = ValidInvokableClass::class;
|
||||||
$resolved = HandlerResolver::resolve($handler);
|
$resolved = HandlerResolver::resolve($handler);
|
||||||
|
|
@ -47,7 +47,7 @@ class HandlerResolverTest extends TestCase
|
||||||
$this->assertEquals(ValidInvokableClass::class, $resolved->getDeclaringClass()->getName());
|
$this->assertEquals(ValidInvokableClass::class, $resolved->getDeclaringClass()->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testResolvesStaticMethodsForManualRegistration()
|
public function testResolvesStaticMethodsForManualRegistration(): void
|
||||||
{
|
{
|
||||||
$handler = [ValidHandlerClass::class, 'staticMethod'];
|
$handler = [ValidHandlerClass::class, 'staticMethod'];
|
||||||
$resolved = HandlerResolver::resolve($handler);
|
$resolved = HandlerResolver::resolve($handler);
|
||||||
|
|
@ -56,84 +56,84 @@ class HandlerResolverTest extends TestCase
|
||||||
$this->assertTrue($resolved->isStatic());
|
$this->assertTrue($resolved->isStatic());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForInvalidArrayHandlerFormatCount()
|
public function testThrowsForInvalidArrayHandlerFormatCount(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage("Invalid array handler format. Expected [ClassName::class, 'methodName'].");
|
$this->expectExceptionMessage("Invalid array handler format. Expected [ClassName::class, 'methodName'].");
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class]); /* @phpstan-ignore argument.type */
|
HandlerResolver::resolve([ValidHandlerClass::class]); /* @phpstan-ignore argument.type */
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForInvalidArrayHandlerFormatTypes()
|
public function testThrowsForInvalidArrayHandlerFormatTypes(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage("Invalid array handler format. Expected [ClassName::class, 'methodName'].");
|
$this->expectExceptionMessage("Invalid array handler format. Expected [ClassName::class, 'methodName'].");
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class, 123]); /* @phpstan-ignore argument.type */
|
HandlerResolver::resolve([ValidHandlerClass::class, 123]); /* @phpstan-ignore argument.type */
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForNonExistentClassInArrayHandler()
|
public function testThrowsForNonExistentClassInArrayHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Handler class "NonExistentClass" not found');
|
$this->expectExceptionMessage('Handler class "NonExistentClass" not found');
|
||||||
HandlerResolver::resolve(['NonExistentClass', 'method']);
|
HandlerResolver::resolve(['NonExistentClass', 'method']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForNonExistentMethodInArrayHandler()
|
public function testThrowsForNonExistentMethodInArrayHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Handler method "nonExistentMethod" not found in class');
|
$this->expectExceptionMessage('Handler method "nonExistentMethod" not found in class');
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class, 'nonExistentMethod']);
|
HandlerResolver::resolve([ValidHandlerClass::class, 'nonExistentMethod']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForNonExistentClassInStringHandler()
|
public function testThrowsForNonExistentClassInStringHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Invalid handler format. Expected Closure, [ClassName::class, \'methodName\'] or InvokableClassName::class string.');
|
$this->expectExceptionMessage('Invalid handler format. Expected Closure, [ClassName::class, \'methodName\'] or InvokableClassName::class string.');
|
||||||
HandlerResolver::resolve('NonExistentInvokableClass');
|
HandlerResolver::resolve('NonExistentInvokableClass');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForNonInvokableClassStringHandler()
|
public function testThrowsForNonInvokableClassStringHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Invokable handler class "Mcp\Tests\Unit\Capability\Discovery\NonInvokableClass" must have a public "__invoke" method.');
|
$this->expectExceptionMessage('Invokable handler class "Mcp\Tests\Unit\Capability\Discovery\NonInvokableClass" must have a public "__invoke" method.');
|
||||||
HandlerResolver::resolve(NonInvokableClass::class);
|
HandlerResolver::resolve(NonInvokableClass::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForProtectedMethodHandler()
|
public function testThrowsForProtectedMethodHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('must be public');
|
$this->expectExceptionMessage('must be public');
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class, 'protectedMethod']);
|
HandlerResolver::resolve([ValidHandlerClass::class, 'protectedMethod']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForPrivateMethodHandler()
|
public function testThrowsForPrivateMethodHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('must be public');
|
$this->expectExceptionMessage('must be public');
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class, 'privateMethod']);
|
HandlerResolver::resolve([ValidHandlerClass::class, 'privateMethod']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForConstructorAsHandler()
|
public function testThrowsForConstructorAsHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('cannot be a constructor or destructor');
|
$this->expectExceptionMessage('cannot be a constructor or destructor');
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class, '__construct']);
|
HandlerResolver::resolve([ValidHandlerClass::class, '__construct']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForDestructorAsHandler()
|
public function testThrowsForDestructorAsHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('cannot be a constructor or destructor');
|
$this->expectExceptionMessage('cannot be a constructor or destructor');
|
||||||
HandlerResolver::resolve([ValidHandlerClass::class, '__destruct']);
|
HandlerResolver::resolve([ValidHandlerClass::class, '__destruct']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowsForAbstractMethodHandler()
|
public function testThrowsForAbstractMethodHandler(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Handler method "Mcp\Tests\Unit\Capability\Discovery\AbstractHandlerClass::abstractMethod" must be abstract.');
|
$this->expectExceptionMessage('Handler method "Mcp\Tests\Unit\Capability\Discovery\AbstractHandlerClass::abstractMethod" must be abstract.');
|
||||||
HandlerResolver::resolve([AbstractHandlerClass::class, 'abstractMethod']);
|
HandlerResolver::resolve([AbstractHandlerClass::class, 'abstractMethod']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testResolvesClosuresWithDifferentSignatures()
|
public function testResolvesClosuresWithDifferentSignatures(): void
|
||||||
{
|
{
|
||||||
$noParams = static function () {
|
$noParams = static function () {
|
||||||
return 'test';
|
return 'test';
|
||||||
|
|
@ -152,7 +152,7 @@ class HandlerResolverTest extends TestCase
|
||||||
$this->assertTrue(HandlerResolver::resolve($variadic)->isVariadic());
|
$this->assertTrue(HandlerResolver::resolve($variadic)->isVariadic());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDistinguishesBetweenClosuresAndCallableArrays()
|
public function testDistinguishesBetweenClosuresAndCallableArrays(): void
|
||||||
{
|
{
|
||||||
$closure = static function () {
|
$closure = static function () {
|
||||||
return 'closure';
|
return 'closure';
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->schemaGenerator = new SchemaGenerator(new DocBlockParser());
|
$this->schemaGenerator = new SchemaGenerator(new DocBlockParser());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesEmptyPropertiesObjectForMethodWithNoParameters()
|
public function testGeneratesEmptyPropertiesObjectForMethodWithNoParameters(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'noParams');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'noParams');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -37,7 +37,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertArrayNotHasKey('required', $schema);
|
$this->assertArrayNotHasKey('required', $schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInfersBasicTypesFromPhpTypeHints()
|
public function testInfersBasicTypesFromPhpTypeHints(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typeHintsOnly');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typeHintsOnly');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -49,7 +49,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['name', 'age', 'active', 'tags'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['name', 'age', 'active', 'tags'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInfersTypesAndDescriptionsFromDocBlockTags()
|
public function testInfersTypesAndDescriptionsFromDocBlockTags(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'docBlockOnly');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'docBlockOnly');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -60,7 +60,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['username', 'count', 'enabled', 'data'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['username', 'count', 'enabled', 'data'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUsesPhpTypeHintsForTypeAndDocBlockForDescriptions()
|
public function testUsesPhpTypeHintsForTypeAndDocBlockForDescriptions(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typeHintsWithDocBlock');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typeHintsWithDocBlock');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -70,7 +70,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['email', 'score', 'verified'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['email', 'score', 'verified'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUsesCompleteSchemaDefinitionFromMethodLevelSchemaAttribute()
|
public function testUsesCompleteSchemaDefinitionFromMethodLevelSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodLevelCompleteDefinition');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodLevelCompleteDefinition');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -92,7 +92,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
], $schema);
|
], $schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesSchemaFromMethodLevelSchemaAttributeWithProperties()
|
public function testGeneratesSchemaFromMethodLevelSchemaAttributeWithProperties(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodLevelWithProperties');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodLevelWithProperties');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -104,7 +104,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['age', 'username', 'email'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['age', 'username', 'email'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesSchemaForSingleArrayArgumentFromMethodLevelSchemaAttribute()
|
public function testGeneratesSchemaForSingleArrayArgumentFromMethodLevelSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodLevelArrayArgument');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodLevelArrayArgument');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -124,7 +124,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEquals(['profiles'], $schema['required']);
|
$this->assertEquals(['profiles'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesSchemaFromIndividualParameterLevelSchemaAttributes()
|
public function testGeneratesSchemaFromIndividualParameterLevelSchemaAttributes(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterLevelOnly');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterLevelOnly');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -143,7 +143,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['recipientId', 'messageBody'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['recipientId', 'messageBody'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAppliesStringConstraintsFromParameterLevelSchemaAttributes()
|
public function testAppliesStringConstraintsFromParameterLevelSchemaAttributes(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterStringConstraints');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterStringConstraints');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -153,7 +153,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['email', 'password', 'regularString'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['email', 'password', 'regularString'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAppliesNumericConstraintsFromParameterLevelSchemaAttributes()
|
public function testAppliesNumericConstraintsFromParameterLevelSchemaAttributes(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterNumericConstraints');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterNumericConstraints');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -163,7 +163,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['age', 'rating', 'count'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['age', 'rating', 'count'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAppliesArrayConstraintsFromParameterLevelSchemaAttributes()
|
public function testAppliesArrayConstraintsFromParameterLevelSchemaAttributes(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterArrayConstraints');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterArrayConstraints');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -172,7 +172,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['tags', 'scores'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['tags', 'scores'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMergesMethodLevelAndParameterLevelSchemaAttributes()
|
public function testMergesMethodLevelAndParameterLevelSchemaAttributes(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodAndParameterLevel');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'methodAndParameterLevel');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -181,7 +181,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['settingKey', 'newValue'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['settingKey', 'newValue'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCombinesPhpTypeHintsDocBlockDescriptionsAndParameterLevelSchemaConstraints()
|
public function testCombinesPhpTypeHintsDocBlockDescriptionsAndParameterLevelSchemaConstraints(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typeHintDocBlockAndParameterSchema');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typeHintDocBlockAndParameterSchema');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -190,7 +190,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['username', 'priority'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['username', 'priority'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesCorrectSchemaForEnumParameters()
|
public function testGeneratesCorrectSchemaForEnumParameters(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'enumParameters');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'enumParameters');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -202,7 +202,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['stringEnum', 'intEnum', 'unitEnum'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['stringEnum', 'intEnum', 'unitEnum'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesCorrectSchemaForArrayTypeDeclarations()
|
public function testGeneratesCorrectSchemaForArrayTypeDeclarations(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'arrayTypeScenarios');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'arrayTypeScenarios');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -218,7 +218,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['genericArray', 'stringArray', 'intArray', 'mixedMap', 'objectLikeArray', 'nestedObjectArray'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['genericArray', 'stringArray', 'intArray', 'mixedMap', 'objectLikeArray', 'nestedObjectArray'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandlesNullableTypeHintsAndOptionalParameters()
|
public function testHandlesNullableTypeHintsAndOptionalParameters(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'nullableAndOptional');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'nullableAndOptional');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -230,7 +230,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['nullableString'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['nullableString'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesSchemaForPhpUnionTypes()
|
public function testGeneratesSchemaForPhpUnionTypes(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'unionTypes');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'unionTypes');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -239,7 +239,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['stringOrInt', 'multiUnion'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['stringOrInt', 'multiUnion'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRepresentsVariadicStringParametersAsArrayOfStrings()
|
public function testRepresentsVariadicStringParametersAsArrayOfStrings(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'variadicStrings');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'variadicStrings');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -247,7 +247,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertArrayNotHasKey('required', $schema);
|
$this->assertArrayNotHasKey('required', $schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAppliesItemConstraintsToVariadicParameters()
|
public function testAppliesItemConstraintsToVariadicParameters(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'variadicWithConstraints');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'variadicWithConstraints');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -255,7 +255,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertArrayNotHasKey('required', $schema);
|
$this->assertArrayNotHasKey('required', $schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandlesMixedTypeHintsOmittingExplicitType()
|
public function testHandlesMixedTypeHintsOmittingExplicitType(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'mixedTypes');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'mixedTypes');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -264,7 +264,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['anyValue'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['anyValue'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesSchemaForComplexNestedObjectAndArrayStructures()
|
public function testGeneratesSchemaForComplexNestedObjectAndArrayStructures(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'complexNestedSchema');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'complexNestedSchema');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -303,7 +303,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEquals(['order'], $schema['required']);
|
$this->assertEquals(['order'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTypePrecedenceParameterSchemaOverridesDocBlockOverridesPhpTypeHint()
|
public function testTypePrecedenceParameterSchemaOverridesDocBlockOverridesPhpTypeHint(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typePrecedenceTest');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'typePrecedenceTest');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -313,7 +313,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertEqualsCanonicalizing(['numericString', 'stringWithConstraints', 'arrayWithItems'], $schema['required']);
|
$this->assertEqualsCanonicalizing(['numericString', 'stringWithConstraints', 'arrayWithItems'], $schema['required']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGeneratesEmptyPropertiesObjectForMethodWithNoParametersEvenWithMethodLevelSchema()
|
public function testGeneratesEmptyPropertiesObjectForMethodWithNoParametersEvenWithMethodLevelSchema(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'noParamsWithSchema');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'noParamsWithSchema');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -322,7 +322,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
$this->assertArrayNotHasKey('required', $schema);
|
$this->assertArrayNotHasKey('required', $schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInfersParameterTypeAsAnyIfOnlyConstraintsAreGiven()
|
public function testInfersParameterTypeAsAnyIfOnlyConstraintsAreGiven(): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterSchemaInferredType');
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, 'parameterSchemaInferredType');
|
||||||
$schema = $this->schemaGenerator->generate($method);
|
$schema = $this->schemaGenerator->generate($method);
|
||||||
|
|
@ -340,7 +340,7 @@ final class SchemaGeneratorTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
#[DataProvider('methodsWithForbiddenParameter')]
|
#[DataProvider('methodsWithForbiddenParameter')]
|
||||||
public function testGenerateWithForbiddenParameterNames(string $methodName)
|
public function testGenerateWithForbiddenParameterNames(string $methodName): void
|
||||||
{
|
{
|
||||||
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, $methodName);
|
$method = new \ReflectionMethod(SchemaGeneratorFixture::class, $methodName);
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
|
|
||||||
// --- Basic Validation Tests ---
|
// --- Basic Validation Tests ---
|
||||||
|
|
||||||
public function testValidDataPassesValidation()
|
public function testValidDataPassesValidation(): void
|
||||||
{
|
{
|
||||||
$schema = $this->getSimpleSchema();
|
$schema = $this->getSimpleSchema();
|
||||||
$data = $this->getValidData();
|
$data = $this->getValidData();
|
||||||
|
|
@ -36,7 +36,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEmpty($errors);
|
$this->assertEmpty($errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidTypeGeneratesTypeError()
|
public function testInvalidTypeGeneratesTypeError(): void
|
||||||
{
|
{
|
||||||
$schema = $this->getSimpleSchema();
|
$schema = $this->getSimpleSchema();
|
||||||
$data = $this->getValidData();
|
$data = $this->getValidData();
|
||||||
|
|
@ -50,7 +50,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('Expected `integer`', $errors[0]['message']);
|
$this->assertStringContainsString('Expected `integer`', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMissingRequiredPropertyGeneratesRequiredError()
|
public function testMissingRequiredPropertyGeneratesRequiredError(): void
|
||||||
{
|
{
|
||||||
$schema = $this->getSimpleSchema();
|
$schema = $this->getSimpleSchema();
|
||||||
$data = $this->getValidData();
|
$data = $this->getValidData();
|
||||||
|
|
@ -62,7 +62,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('Missing required properties: `name`', $errors[0]['message']);
|
$this->assertStringContainsString('Missing required properties: `name`', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAdditionalPropertyGeneratesAdditionalPropertiesError()
|
public function testAdditionalPropertyGeneratesAdditionalPropertiesError(): void
|
||||||
{
|
{
|
||||||
$schema = $this->getSimpleSchema();
|
$schema = $this->getSimpleSchema();
|
||||||
$data = $this->getValidData();
|
$data = $this->getValidData();
|
||||||
|
|
@ -77,7 +77,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
|
|
||||||
// --- Keyword Constraint Tests ---
|
// --- Keyword Constraint Tests ---
|
||||||
|
|
||||||
public function testEnumConstraintViolation()
|
public function testEnumConstraintViolation(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'string', 'enum' => ['A', 'B']];
|
$schema = ['type' => 'string', 'enum' => ['A', 'B']];
|
||||||
$data = 'C';
|
$data = 'C';
|
||||||
|
|
@ -88,7 +88,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('must be one of the allowed values: "A", "B"', $errors[0]['message']);
|
$this->assertStringContainsString('must be one of the allowed values: "A", "B"', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMinimumConstraintViolation()
|
public function testMinimumConstraintViolation(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'integer', 'minimum' => 10];
|
$schema = ['type' => 'integer', 'minimum' => 10];
|
||||||
$data = 5;
|
$data = 5;
|
||||||
|
|
@ -99,7 +99,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('must be greater than or equal to 10', $errors[0]['message']);
|
$this->assertStringContainsString('must be greater than or equal to 10', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMaxLengthConstraintViolation()
|
public function testMaxLengthConstraintViolation(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'string', 'maxLength' => 5];
|
$schema = ['type' => 'string', 'maxLength' => 5];
|
||||||
$data = 'toolong';
|
$data = 'toolong';
|
||||||
|
|
@ -110,7 +110,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('Maximum string length is 5, found 7', $errors[0]['message']);
|
$this->assertStringContainsString('Maximum string length is 5, found 7', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPatternConstraintViolation()
|
public function testPatternConstraintViolation(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'string', 'pattern' => '^[a-z]+$'];
|
$schema = ['type' => 'string', 'pattern' => '^[a-z]+$'];
|
||||||
$data = '123';
|
$data = '123';
|
||||||
|
|
@ -121,7 +121,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('does not match the required pattern: `^[a-z]+$`', $errors[0]['message']);
|
$this->assertStringContainsString('does not match the required pattern: `^[a-z]+$`', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMinItemsConstraintViolation()
|
public function testMinItemsConstraintViolation(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'array', 'minItems' => 2];
|
$schema = ['type' => 'array', 'minItems' => 2];
|
||||||
$data = ['one'];
|
$data = ['one'];
|
||||||
|
|
@ -132,7 +132,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('Array should have at least 2 items, 1 found', $errors[0]['message']);
|
$this->assertStringContainsString('Array should have at least 2 items, 1 found', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUniqueItemsConstraintViolation()
|
public function testUniqueItemsConstraintViolation(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'array', 'uniqueItems' => true];
|
$schema = ['type' => 'array', 'uniqueItems' => true];
|
||||||
$data = ['a', 'b', 'a'];
|
$data = ['a', 'b', 'a'];
|
||||||
|
|
@ -144,7 +144,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Nested Structures and Pointers ---
|
// --- Nested Structures and Pointers ---
|
||||||
public function testNestedObjectValidationErrorPointer()
|
public function testNestedObjectValidationErrorPointer(): void
|
||||||
{
|
{
|
||||||
$schema = [
|
$schema = [
|
||||||
'type' => 'object',
|
'type' => 'object',
|
||||||
|
|
@ -164,7 +164,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEquals('/user/id', $errors[0]['pointer']);
|
$this->assertEquals('/user/id', $errors[0]['pointer']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testArrayItemValidationErrorPointer()
|
public function testArrayItemValidationErrorPointer(): void
|
||||||
{
|
{
|
||||||
$schema = [
|
$schema = [
|
||||||
'type' => 'array',
|
'type' => 'array',
|
||||||
|
|
@ -178,7 +178,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Data Conversion Tests ---
|
// --- Data Conversion Tests ---
|
||||||
public function testValidatesDataPassedAsStdClassObject()
|
public function testValidatesDataPassedAsStdClassObject(): void
|
||||||
{
|
{
|
||||||
$schema = $this->getSimpleSchema();
|
$schema = $this->getSimpleSchema();
|
||||||
$dataObj = json_decode(json_encode($this->getValidData())); // Convert to stdClass
|
$dataObj = json_decode(json_encode($this->getValidData())); // Convert to stdClass
|
||||||
|
|
@ -187,7 +187,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEmpty($errors);
|
$this->assertEmpty($errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesDataWithNestedAssociativeArraysCorrectly()
|
public function testValidatesDataWithNestedAssociativeArraysCorrectly(): void
|
||||||
{
|
{
|
||||||
$schema = [
|
$schema = [
|
||||||
'type' => 'object',
|
'type' => 'object',
|
||||||
|
|
@ -207,7 +207,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Edge Cases ---
|
// --- Edge Cases ---
|
||||||
public function testHandlesInvalidSchemaStructureGracefully()
|
public function testHandlesInvalidSchemaStructureGracefully(): void
|
||||||
{
|
{
|
||||||
$schema = ['type' => 'object', 'properties' => ['name' => ['type' => 123]]]; // Invalid type value
|
$schema = ['type' => 'object', 'properties' => ['name' => ['type' => 123]]]; // Invalid type value
|
||||||
$data = ['name' => 'test'];
|
$data = ['name' => 'test'];
|
||||||
|
|
@ -218,7 +218,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('Schema validation process failed', $errors[0]['message']);
|
$this->assertStringContainsString('Schema validation process failed', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandlesEmptyDataObjectAgainstSchemaRequiringProperties()
|
public function testHandlesEmptyDataObjectAgainstSchemaRequiringProperties(): void
|
||||||
{
|
{
|
||||||
$schema = $this->getSimpleSchema(); // Requires name, age etc.
|
$schema = $this->getSimpleSchema(); // Requires name, age etc.
|
||||||
$data = []; // Empty data
|
$data = []; // Empty data
|
||||||
|
|
@ -229,7 +229,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEquals('required', $errors[0]['keyword']);
|
$this->assertEquals('required', $errors[0]['keyword']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHandlesEmptySchemaAllowsAnything()
|
public function testHandlesEmptySchemaAllowsAnything(): void
|
||||||
{
|
{
|
||||||
$schema = []; // Empty schema object/array implies no constraints
|
$schema = []; // Empty schema object/array implies no constraints
|
||||||
$data = ['anything' => [1, 2], 'goes' => true];
|
$data = ['anything' => [1, 2], 'goes' => true];
|
||||||
|
|
@ -241,7 +241,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('Invalid schema', $errors[0]['message']);
|
$this->assertStringContainsString('Invalid schema', $errors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesSchemaWithStringFormatConstraintsFromSchemaAttribute()
|
public function testValidatesSchemaWithStringFormatConstraintsFromSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$emailSchema = (new Schema(format: 'email'))->toArray();
|
$emailSchema = (new Schema(format: 'email'))->toArray();
|
||||||
|
|
||||||
|
|
@ -256,7 +256,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertStringContainsString('email', $invalidErrors[0]['message']);
|
$this->assertStringContainsString('email', $invalidErrors[0]['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesSchemaWithStringLengthConstraintsFromSchemaAttribute()
|
public function testValidatesSchemaWithStringLengthConstraintsFromSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$passwordSchema = (new Schema(minLength: 8, pattern: '^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$'))->toArray();
|
$passwordSchema = (new Schema(minLength: 8, pattern: '^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$'))->toArray();
|
||||||
|
|
||||||
|
|
@ -275,7 +275,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEquals('pattern', $noDigitErrors[0]['keyword']);
|
$this->assertEquals('pattern', $noDigitErrors[0]['keyword']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesSchemaWithNumericConstraintsFromSchemaAttribute()
|
public function testValidatesSchemaWithNumericConstraintsFromSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$ageSchema = (new Schema(minimum: 18, maximum: 120))->toArray();
|
$ageSchema = (new Schema(minimum: 18, maximum: 120))->toArray();
|
||||||
|
|
||||||
|
|
@ -294,7 +294,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEquals('maximum', $tooHighErrors[0]['keyword']);
|
$this->assertEquals('maximum', $tooHighErrors[0]['keyword']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesSchemaWithArrayConstraintsFromSchemaAttribute()
|
public function testValidatesSchemaWithArrayConstraintsFromSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$tagsSchema = (new Schema(uniqueItems: true, minItems: 2))->toArray();
|
$tagsSchema = (new Schema(uniqueItems: true, minItems: 2))->toArray();
|
||||||
|
|
||||||
|
|
@ -313,7 +313,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEquals('minItems', $tooFewErrors[0]['keyword']);
|
$this->assertEquals('minItems', $tooFewErrors[0]['keyword']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesSchemaWithObjectConstraintsFromSchemaAttribute()
|
public function testValidatesSchemaWithObjectConstraintsFromSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$userSchema = (new Schema(
|
$userSchema = (new Schema(
|
||||||
properties: [
|
properties: [
|
||||||
|
|
@ -363,7 +363,7 @@ class SchemaValidatorTest extends TestCase
|
||||||
$this->assertEquals('minimum', $ageErrors[0]['keyword']);
|
$this->assertEquals('minimum', $ageErrors[0]['keyword']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidatesSchemaWithNestedConstraintsFromSchemaAttribute()
|
public function testValidatesSchemaWithNestedConstraintsFromSchemaAttribute(): void
|
||||||
{
|
{
|
||||||
$orderSchema = (new Schema(
|
$orderSchema = (new Schema(
|
||||||
properties: [
|
properties: [
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ use PHPUnit\Framework\TestCase;
|
||||||
*/
|
*/
|
||||||
final class ClientLoggerTest extends TestCase
|
final class ClientLoggerTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testLog()
|
public function testLog(): void
|
||||||
{
|
{
|
||||||
$session = $this->getMockBuilder(Session::class)
|
$session = $this->getMockBuilder(Session::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
@ -39,7 +39,7 @@ final class ClientLoggerTest extends TestCase
|
||||||
$logger->notice('test');
|
$logger->notice('test');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLogFilter()
|
public function testLogFilter(): void
|
||||||
{
|
{
|
||||||
$session = $this->getMockBuilder(Session::class)
|
$session = $this->getMockBuilder(Session::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
@ -56,7 +56,7 @@ final class ClientLoggerTest extends TestCase
|
||||||
$logger->debug('test');
|
$logger->debug('test');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLogFilterSameLevel()
|
public function testLogFilterSameLevel(): void
|
||||||
{
|
{
|
||||||
$session = $this->getMockBuilder(Session::class)
|
$session = $this->getMockBuilder(Session::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
@ -73,7 +73,7 @@ final class ClientLoggerTest extends TestCase
|
||||||
$logger->info('test');
|
$logger->info('test');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLogWithInvalidLevel()
|
public function testLogWithInvalidLevel(): void
|
||||||
{
|
{
|
||||||
$session = $this->getMockBuilder(Session::class)
|
$session = $this->getMockBuilder(Session::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class IconTest extends TestCase
|
class IconTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testValidConstructor()
|
public function testValidConstructor(): void
|
||||||
{
|
{
|
||||||
$icon = new Icon('https://www.php.net/images/logos/php-logo-white.svg', 'image/svg+xml', ['any']);
|
$icon = new Icon('https://www.php.net/images/logos/php-logo-white.svg', 'image/svg+xml', ['any']);
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ class IconTest extends TestCase
|
||||||
$this->assertSame('any', $icon->sizes[0]);
|
$this->assertSame('any', $icon->sizes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstructorWithMultipleSizes()
|
public function testConstructorWithMultipleSizes(): void
|
||||||
{
|
{
|
||||||
$icon = new Icon('https://example.com/icon.png', 'image/png', ['48x48', '96x96']);
|
$icon = new Icon('https://example.com/icon.png', 'image/png', ['48x48', '96x96']);
|
||||||
|
|
||||||
|
|
@ -34,14 +34,14 @@ class IconTest extends TestCase
|
||||||
$this->assertSame(['48x48', '96x96'], $icon->sizes);
|
$this->assertSame(['48x48', '96x96'], $icon->sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstructorWithAnySizes()
|
public function testConstructorWithAnySizes(): void
|
||||||
{
|
{
|
||||||
$icon = new Icon('https://example.com/icon.svg', 'image/png', ['any']);
|
$icon = new Icon('https://example.com/icon.svg', 'image/png', ['any']);
|
||||||
|
|
||||||
$this->assertSame(['any'], $icon->sizes);
|
$this->assertSame(['any'], $icon->sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstructorWithNullOptionalFields()
|
public function testConstructorWithNullOptionalFields(): void
|
||||||
{
|
{
|
||||||
$icon = new Icon('https://example.com/icon.png');
|
$icon = new Icon('https://example.com/icon.png');
|
||||||
|
|
||||||
|
|
@ -50,35 +50,35 @@ class IconTest extends TestCase
|
||||||
$this->assertNull($icon->sizes);
|
$this->assertNull($icon->sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidSizesFormatThrowsException()
|
public function testInvalidSizesFormatThrowsException(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
|
||||||
new Icon('https://example.com/icon.png', 'image/png', ['invalid-size']);
|
new Icon('https://example.com/icon.png', 'image/png', ['invalid-size']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidPixelSizesFormatThrowsException()
|
public function testInvalidPixelSizesFormatThrowsException(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
|
||||||
new Icon('https://example.com/icon.png', 'image/png', ['180x48x48']);
|
new Icon('https://example.com/icon.png', 'image/png', ['180x48x48']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEmptySrcThrowsException()
|
public function testEmptySrcThrowsException(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
|
||||||
new Icon('', 'image/png', ['48x48']);
|
new Icon('', 'image/png', ['48x48']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvalidSrcThrowsException()
|
public function testInvalidSrcThrowsException(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
|
||||||
new Icon('not-a-url', 'image/png', ['48x48']);
|
new Icon('not-a-url', 'image/png', ['48x48']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testValidDataUriSrc()
|
public function testValidDataUriSrc(): void
|
||||||
{
|
{
|
||||||
$dataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA';
|
$dataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA';
|
||||||
$icon = new Icon($dataUri, 'image/png', ['48x48']);
|
$icon = new Icon($dataUri, 'image/png', ['48x48']);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
final class NotificationTest extends TestCase
|
final class NotificationTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testMetaIsLoopedThrough()
|
public function testMetaIsLoopedThrough(): void
|
||||||
{
|
{
|
||||||
$notificationImplementation = new class extends Notification {
|
$notificationImplementation = new class extends Notification {
|
||||||
public static function getMethod(): string
|
public static function getMethod(): string
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
final class RequestTest extends TestCase
|
final class RequestTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testMetaAndIdAreLoopedThrough()
|
public function testMetaAndIdAreLoopedThrough(): void
|
||||||
{
|
{
|
||||||
$requestImplementation = new class extends Request {
|
$requestImplementation = new class extends Request {
|
||||||
public static function getMethod(): string
|
public static function getMethod(): string
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
final class CreateSamplingMessageRequestTest extends TestCase
|
final class CreateSamplingMessageRequestTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testConstructorWithValidSetOfMessages()
|
public function testConstructorWithValidSetOfMessages(): void
|
||||||
{
|
{
|
||||||
$messages = [
|
$messages = [
|
||||||
new SamplingMessage(Role::User, new TextContent('My name is George.')),
|
new SamplingMessage(Role::User, new TextContent('My name is George.')),
|
||||||
|
|
@ -34,7 +34,7 @@ final class CreateSamplingMessageRequestTest extends TestCase
|
||||||
$this->assertSame(150, $request->maxTokens);
|
$this->assertSame(150, $request->maxTokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstructorWithInvalidSetOfMessages()
|
public function testConstructorWithInvalidSetOfMessages(): void
|
||||||
{
|
{
|
||||||
$this->expectException(InvalidArgumentException::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Messages must be instance of SamplingMessage.');
|
$this->expectExceptionMessage('Messages must be instance of SamplingMessage.');
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ class SessionTest extends TestCase
|
||||||
$this->assertNotEquals($session1->getId()->toRfc4122(), $session2->getId()->toRfc4122());
|
$this->assertNotEquals($session1->getId()->toRfc4122(), $session2->getId()->toRfc4122());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAll()
|
public function testAll(): void
|
||||||
{
|
{
|
||||||
$store = $this->getMockBuilder(InMemorySessionStore::class)
|
$store = $this->getMockBuilder(InMemorySessionStore::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
@ -289,7 +289,7 @@ class SessionTest extends TestCase
|
||||||
$this->assertEquals(['foo' => 'bar'], $result);
|
$this->assertEquals(['foo' => 'bar'], $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveBeforeReadInitializesData()
|
public function testSaveBeforeReadInitializesData(): void
|
||||||
{
|
{
|
||||||
$store = new InMemorySessionStore();
|
$store = new InMemorySessionStore();
|
||||||
$session = new Session($store);
|
$session = new Session($store);
|
||||||
|
|
@ -298,7 +298,7 @@ class SessionTest extends TestCase
|
||||||
$this->assertTrue($session->save());
|
$this->assertTrue($session->save());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAllReturnsEmptyArrayForNullPayload()
|
public function testAllReturnsEmptyArrayForNullPayload(): void
|
||||||
{
|
{
|
||||||
$store = $this->getMockBuilder(InMemorySessionStore::class)
|
$store = $this->getMockBuilder(InMemorySessionStore::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue