Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 6 additions & 16 deletions src/Factory/V30/FromCebe.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ private static function createSchema(

return new Schema(
type: $schema->type,
enum: $schema->enum ?? null,
const: $schema->const ?? null,
enum: isset($schema->enum) ?
array_map(fn($e) => new Value($e), $schema->enum) :
null,
default: isset($schema->default) ? new Value($schema->default) : null,
nullable: $schema->nullable ?? false,
multipleOf: $schema->multipleOf ?? null,
Expand All @@ -160,31 +161,20 @@ enum: $schema->enum ?? null,
maxItems: $schema->maxItems ?? null,
minItems: $schema->minItems ?? 0,
uniqueItems: $schema->uniqueItems ?? false,
maxContains: $schema->maxContains ?? null,
minContains: $schema->minContains ?? null,
maxProperties: $schema->maxProperties ?? null,
minProperties: $schema->minProperties ?? 0,
required: $schema->required ?? null,
dependentRequired: $schema->dependentRequired ?? null,
allOf: isset($schema->allOf) ? $createSchemas($schema->allOf) : null,
anyOf: isset($schema->anyOf) ? $createSchemas($schema->anyOf) : null,
oneOf: isset($schema->oneOf) ? $createSchemas($schema->oneOf) : null,
not: isset($schema->not) ? self::createSchema($schema->not) : null,
if: isset($schema->if) ? self::createSchema($schema->if) : null,
then: isset($schema->then) ? self::createSchema($schema->then) : null,
else: isset($schema->else) ? self::createSchema($schema->else) : null,
dependentSchemas: isset($schema->dependentSchemas) ?
$createSchemas($schema->dependentSchemas) :
null,
items: isset($schema->items) ? (is_array($schema->items) ?
$createSchemas($schema->items) :
self::createSchema($schema->items)) :
null,
properties: isset($schema->properties) ? $createSchemas($schema->properties) : null,
items: isset($schema->items) ? self::createSchema($schema->items) : null,
properties: isset($schema->properties) ? $createSchemas($schema->properties) : [],
additionalProperties: isset($schema->additionalProperties) ? (is_bool($schema->additionalProperties) ?
$schema->additionalProperties :
self::createSchema($schema->additionalProperties) ?? true) :
true,
format: $schema->format ?? null,
);
}

Expand Down
14 changes: 9 additions & 5 deletions src/ValueObject/Partial/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,16 @@ public function __construct(
* 3.1 https://json-schema.org/draft/2020-12/json-schema-core#name-keywords-for-applying-subschema
*/
/** @var array<Schema> */
public array|null $prefixItems = null,
/** @var array<Schema>|Schema|null */
public array|Schema|null $items = null,
public array $prefixItems = [],
public Schema|null $items = null,
public Schema|null $contains = null,
/**
* Keywords for applying subschemas to arrays
* 3.0 https://datatracker.ietf.org/doc/html/draft-wright-json-schema-validation-00#section-5.22
* 3.1 https://json-schema.org/draft/2020-12/json-schema-core#name-keywords-for-applying-subschemas
*/
/** @var array<string, Schema>|null */
public array|null $properties = [],
/** @var array<string, Schema> */
public array $properties = [],
/** @var array<string, Schema> */
public array $patternProperties = [],
public bool|Schema $additionalProperties = true,
Expand All @@ -120,6 +119,11 @@ public function __construct(
*/
public bool|Schema $unevaluatedItems = true,
public bool|Schema $unevaluatedProperties = true,
/**
* Keywords that MAY provide additional validation, depending on tool
* https://datatracker.ietf.org/doc/html/draft-wright-json-schema-validation-00#section-7
*/
public string|null $format = null,
) {
}
}
21 changes: 7 additions & 14 deletions src/ValueObject/Valid/V30/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ final class Schema extends Validated implements Valid\Schema
public readonly int $minLength;
public readonly string|null $pattern;

/** @var array<Schema>|Schema|null */
public readonly array|Schema|null $items;
/** @var Schema|null */
public readonly Schema|null $items;
public readonly int|null $maxItems;
public readonly int $minItems;
public readonly bool $uniqueItems;
Expand All @@ -55,6 +55,7 @@ final class Schema extends Validated implements Valid\Schema
public readonly array|null $oneOf;
public readonly Schema|null $not;

public readonly string|null $format;

/** @var Type[] */
private readonly array $typesItCanBe;
Expand Down Expand Up @@ -101,6 +102,8 @@ public function __construct(
new Schema($this->getIdentifier()->append('not'), $schema->not) :
null;

$this->format = $schema->format;

$this->typesItCanBe = array_map(
fn($t) => Type::from($t),
$this->typesItCanBe()
Expand Down Expand Up @@ -297,14 +300,8 @@ private function validateProperties(?array $subSchemas): array
return $result;
}

/**
* @param array<Partial\Schema>|Partial\Schema|null $items
* @return array<Schema>|Schema|null
*/
private function validateItems(
Type|null $type,
array|Partial\Schema|null $items,
): array|Schema|null {
private function validateItems(Type|null $type, Partial\Schema|null $items): Schema|null
{
if (is_null($items)) {
//@todo update tests to support this validation
//if ($type == Type::Array) {
Expand All @@ -314,10 +311,6 @@ private function validateItems(
return $items;
}

if (is_array($items)) {
return $this->validateSubSchemas('items', $items);
}

return new Schema($this->getIdentifier()->append('items'), $items);
}
}
160 changes: 160 additions & 0 deletions tests/ValueObject/Valid/V30/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Membrane\OpenAPIReader\Exception\InvalidOpenAPI;
use Membrane\OpenAPIReader\OpenAPIVersion;
use Membrane\OpenAPIReader\Tests\Fixtures\Helper\PartialHelper;
use Membrane\OpenAPIReader\ValueObject\Limit;
use Membrane\OpenAPIReader\ValueObject\Partial;
use Membrane\OpenAPIReader\ValueObject\Valid\Enum\Type;
use Membrane\OpenAPIReader\ValueObject\Valid\Identifier;
Expand All @@ -18,6 +19,7 @@
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -117,6 +119,26 @@ public function itWarnsAgainstImpossibleSchemas(
);
}

#[Test]
#[TestDox('It determines the relevant numeric inclusive|exclusive maximum, if there is one')]
#[DataProvider('provideSchemasWithMax')]
public function itGetsRelevantMaximum(?Limit $expected, Partial\Schema $schema): void
{
$sut = new Schema(new Identifier(''), $schema);

self::assertEquals($expected, $sut->getRelevantMaximum());
}

#[Test]
#[TestDox('It determines the relevant numeric inclusive|exclusive minimum, if there is one')]
#[DataProvider('provideSchemasWithMin')]
public function itGetsRelevantMinimum(?Limit $expected, Partial\Schema $schema): void
{
$sut = new Schema(new Identifier(''), $schema);

self::assertEquals($expected, $sut->getRelevantMinimum());
}

public static function provideInvalidComplexSchemas(): Generator
{
$xOfs = [
Expand Down Expand Up @@ -291,4 +313,142 @@ public static function provideSchemasAcceptNoTypes(): Generator
];
}
}

/**
* @return Generator<array{
* 0: ?Limit,
* 1: Partial\Schema
* }>
*/
public static function provideSchemasWithMax(): Generator
{
yield 'no min or max' => [
null,
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: false,
maximum: null,
minimum: null,
),
];

yield 'inclusive min' => [
null,
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: false,
maximum: null,
minimum: 1,
),
];

yield 'exclusive min' => [
null,
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: true,
maximum: null,
minimum: 1,
),
];

yield 'inclusive max' => [
new Limit(1, false),
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: false,
maximum: 1,
minimum: null,
),
];

yield 'exclusive max' => [
new Limit(1, true),
PartialHelper::createSchema(
exclusiveMaximum: true,
exclusiveMinimum: false,
maximum: 1,
minimum: null,
),
];

yield 'inclusive max and exclusive min' => [
new Limit(5, false),
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: true,
maximum: 5,
minimum: 1,
),
];
}

/**
* @return Generator<array{
* 0: ?Limit,
* 1: Partial\Schema
* }>
*/
public static function provideSchemasWithMin(): Generator
{
yield 'no min or max' => [
null,
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: false,
maximum: null,
minimum: null,
),
];

yield 'inclusive min' => [
new Limit(1, false),
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: false,
maximum: null,
minimum: 1,
),
];

yield 'exclusive min' => [
new Limit(1, true),
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: true,
maximum: null,
minimum: 1,
),
];

yield 'inclusive max' => [
null,
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: false,
maximum: 1,
minimum: null,
),
];

yield 'exclusive max' => [
null,
PartialHelper::createSchema(
exclusiveMaximum: true,
exclusiveMinimum: false,
maximum: 1,
minimum: null,
),
];

yield 'inclusive max and exclusive min' => [
new Limit(1, true),
PartialHelper::createSchema(
exclusiveMaximum: false,
exclusiveMinimum: true,
maximum: 5,
minimum: 1,
),
];
}
}
Loading