diff --git a/src/Types/ArraySchema.php b/src/Types/ArraySchema.php index 54de85e..2c4cc58 100644 --- a/src/Types/ArraySchema.php +++ b/src/Types/ArraySchema.php @@ -43,7 +43,7 @@ public function contains(Schema $schema): static public function minContains(int $min): static { if ($min < 0) { - throw new SchemaException('minContains must be non-negative'); + throw new SchemaException('minContains must be greater than or equal to 0'); } if ($this->maxContains !== null && $min > $this->maxContains) { @@ -63,7 +63,7 @@ public function minContains(int $min): static public function maxContains(int $max): static { if ($max < 0) { - throw new SchemaException('maxContains must be non-negative'); + throw new SchemaException('maxContains must be greater than or equal to 0'); } if ($this->minContains !== null && $max < $this->minContains) { diff --git a/tests/ArchitectureTest.php b/tests/ArchitectureTest.php index c0fb154..0bcddd9 100644 --- a/tests/ArchitectureTest.php +++ b/tests/ArchitectureTest.php @@ -4,5 +4,11 @@ namespace Cortex\JsonSchema\Tests; +use Throwable; + arch()->preset()->php(); arch()->preset()->security(); + +arch()->expect('Cortex\JsonSchema\Contracts')->toBeInterfaces(); +arch()->expect('Cortex\JsonSchema\Enums')->toBeEnums(); +arch()->expect('Cortex\JsonSchema\Exceptions')->toExtend(Throwable::class); diff --git a/tests/Unit/SchemaFactoryTest.php b/tests/Unit/SchemaFactoryTest.php index 727b215..ba49980 100644 --- a/tests/Unit/SchemaFactoryTest.php +++ b/tests/Unit/SchemaFactoryTest.php @@ -87,4 +87,6 @@ 'fooArray', ], ]); + + expect($schema->toJson())->toBe(json_encode($schema->toArray())); }); diff --git a/tests/Unit/Targets/ArraySchemaTest.php b/tests/Unit/Targets/ArraySchemaTest.php index 90476ce..1e470c7 100644 --- a/tests/Unit/Targets/ArraySchemaTest.php +++ b/tests/Unit/Targets/ArraySchemaTest.php @@ -123,3 +123,15 @@ 'At least one array item must match schema', ); }); + +it('throws an exception if the minContains is less than 0', function (): void { + Schema::array('numbers') + ->description('List of numbers') + ->minContains(-1); +})->throws(SchemaException::class, 'minContains must be greater than or equal to 0'); + +it('throws an exception if the maxContains is less than 0', function (): void { + Schema::array('numbers') + ->description('List of numbers') + ->maxContains(-1); +})->throws(SchemaException::class, 'maxContains must be greater than or equal to 0'); diff --git a/tests/Unit/Targets/IntegerSchemaTest.php b/tests/Unit/Targets/IntegerSchemaTest.php index 8893800..f6d308e 100644 --- a/tests/Unit/Targets/IntegerSchemaTest.php +++ b/tests/Unit/Targets/IntegerSchemaTest.php @@ -156,3 +156,9 @@ 'The data (string) must match the type: integer, null', ); }); + +it('throws an exception if the multipleOf is less than 0', function (): void { + Schema::integer('age') + ->description('User age') + ->multipleOf(-1); +})->throws(SchemaException::class, 'multipleOf must be greater than 0'); diff --git a/tests/Unit/Targets/ObjectSchemaTest.php b/tests/Unit/Targets/ObjectSchemaTest.php index e68882d..51f9451 100644 --- a/tests/Unit/Targets/ObjectSchemaTest.php +++ b/tests/Unit/Targets/ObjectSchemaTest.php @@ -173,3 +173,25 @@ 'key2' => 'value2', ]))->not->toThrow(SchemaException::class); }); + +it('can specify a propertyNames schema', function (): void { + $schema = Schema::object('user') + ->properties( + Schema::string('name')->required(), + ) + // ->additionalProperties(true) + ->propertyNames(Schema::string()->pattern('^[a-zA-Z]+$')); + + $schemaArray = $schema->toArray(); + + expect($schemaArray)->toHaveKey('propertyNames.pattern', '^[a-zA-Z]+$'); + + // Validation tests + expect(fn() => $schema->validate([ + 'name' => 'John Doe', + ]))->not->toThrow(SchemaException::class); + + expect(fn() => $schema->validate([ + 'name' => 123, // invalid property name pattern + ]))->toThrow(SchemaException::class, 'The properties must match schema: name'); +}); diff --git a/tests/Unit/Targets/StringSchemaTest.php b/tests/Unit/Targets/StringSchemaTest.php index 5026a2b..273dfff 100644 --- a/tests/Unit/Targets/StringSchemaTest.php +++ b/tests/Unit/Targets/StringSchemaTest.php @@ -105,6 +105,12 @@ ); expect(fn() => $schema->validate('test@example.com'))->not->toThrow(SchemaException::class); + + $schema = Schema::string('email') + ->description('User email address') + ->format('custom'); + + expect($schema->toArray())->toHaveKey('format', 'custom'); }); it('can create a nullable string schema', function (): void { @@ -122,10 +128,14 @@ expect(fn() => $schema->validate(null))->not->toThrow(SchemaException::class); expect(fn() => $schema->validate('John'))->not->toThrow(SchemaException::class); + expect($schema->isValid(null))->toBeTrue(); + expect($schema->isValid('John'))->toBeTrue(); + expect(fn() => $schema->validate(123))->toThrow( SchemaException::class, 'The data (integer) must match the type: string, null', ); + expect($schema->isValid(123))->toBeFalse(); }); it('can create a read-only string schema', function (): void {