Skip to content

Commit 2a06fd5

Browse files
committed
ArrayValidator: data index validation
1 parent 874be2d commit 2a06fd5

5 files changed

+89
-0
lines changed

src/Validation/Result/ValidationResultBuilder.php

+5
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ public function addOneOfAmbiguousViolation(BreadCrumbPathInterface $breadCrumbPa
131131
return $this->addViolation($this->validityViolationFactory->createOneOfAmbiguousViolation($breadCrumbPath));
132132
}
133133

134+
public function addSequenceViolation(BreadCrumbPathInterface $breadCrumbPath): self
135+
{
136+
return $this->addViolation($this->validityViolationFactory->createSequenceViolation($breadCrumbPath));
137+
}
138+
134139
public function mergeResult(ValidationResultInterface $validationResult): self
135140
{
136141
return $this->mergeViolations($validationResult->getViolations());

src/Validation/Result/ValidityViolationFactory.php

+5
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,9 @@ public function createOneOfAmbiguousViolation(BreadCrumbPathInterface $breadCrum
135135
{
136136
return new ValidityViolation(1019, 'Value matches more then one schema.', [], $breadCrumbPath);
137137
}
138+
139+
public function createSequenceViolation(BreadCrumbPathInterface $breadCrumbPath): ValidityViolationInterface
140+
{
141+
return new ValidityViolation(1020, 'Sequence violation.', [], $breadCrumbPath);
142+
}
138143
}

src/Validation/Validator/ArrayValidator.php

+27
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ protected function doValidation(
5555
}
5656

5757
$itemsSchema = $this->schema->getItemsSchema();
58+
59+
if (! $this->validateDataIndex($data, $resultBuilder, $breadCrumbPath)) {
60+
return;
61+
}
62+
5863
foreach ($data as $itemIndex => $itemData) {
5964
$propertyValidationResult = $this->valueValidator->validate(
6065
$itemsSchema,
@@ -90,4 +95,26 @@ protected function collectPossibleViolationExamples(
9095
)
9196
);
9297
}
98+
99+
private function validateDataIndex(
100+
array $data,
101+
ValidationResultBuilder $resultBuilder,
102+
BreadCrumbPathInterface $breadCrumbPath
103+
): bool {
104+
$expectedIndex = 0;
105+
foreach ($data as $itemIndex => $itemData) {
106+
if (! is_int($itemIndex)) {
107+
$resultBuilder->addTypeViolation('array', $breadCrumbPath);
108+
return false;
109+
}
110+
if ($itemIndex !== $expectedIndex) {
111+
$resultBuilder->addSequenceViolation($breadCrumbPath);
112+
return false;
113+
}
114+
115+
$expectedIndex++;
116+
}
117+
118+
return true;
119+
}
93120
}

src/Validation/ValidityViolationFactoryInterface.php

+2
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,6 @@ public function createPatternViolation(
8585
public function createOneOfNoMatchViolation(BreadCrumbPathInterface $breadCrumbPath): ValidityViolationInterface;
8686

8787
public function createOneOfAmbiguousViolation(BreadCrumbPathInterface $breadCrumbPath): ValidityViolationInterface;
88+
89+
public function createSequenceViolation(BreadCrumbPathInterface $breadCrumbPath): ValidityViolationInterface;
8890
}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace ScrumWorks\OpenApiSchema\Tests\Validation;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use ScrumWorks\OpenApiSchema\Tests\DiTrait;
7+
use ScrumWorks\OpenApiSchema\Validation\Result\BreadCrumbPathFactory;
8+
use ScrumWorks\OpenApiSchema\Validation\Result\ValidationResultBuilderFactory;
9+
use ScrumWorks\OpenApiSchema\Validation\Validator\ArrayValidator;
10+
use ScrumWorks\OpenApiSchema\Validation\ValueSchemaValidatorInterface;
11+
use ScrumWorks\OpenApiSchema\ValueSchema\Data\ArraySchemaData;
12+
use ScrumWorks\OpenApiSchema\ValueSchema\Data\StringSchemaData;
13+
14+
final class ArrayValidatorTest extends TestCase
15+
{
16+
use DiTrait;
17+
18+
public function testArrayValidation(): void
19+
{
20+
$arraySchema = new ArraySchemaData(itemsSchema: new StringSchemaData());
21+
22+
$validator = new ArrayValidator(
23+
$this->getServiceFromContainerByType(BreadCrumbPathFactory::class),
24+
$this->getServiceFromContainerByType(ValidationResultBuilderFactory::class),
25+
$arraySchema,
26+
$this->getServiceFromContainerByType(ValueSchemaValidatorInterface::class)
27+
);
28+
29+
self::assertCount(0, $validator->validate(['asd', 'qwe'])->getViolations());
30+
self::assertCount(0, $validator->validate([
31+
0 => 'asd',
32+
1 => 'qwe',
33+
])->getViolations());
34+
35+
$violations = $validator->validate([
36+
'asd' => 'qwe',
37+
])->getViolations();
38+
self::assertEquals(1002, reset($violations)->getViolationCode());
39+
40+
self::assertCount(1, $validator->validate([
41+
'asd' => 'qwe',
42+
])->getViolations());
43+
$violations = $validator->validate([
44+
1 => 'asd',
45+
3 => 'qwe',
46+
])->getViolations();
47+
self::assertCount(1, $violations);
48+
self::assertEquals(1020, reset($violations)->getViolationCode());
49+
}
50+
}

0 commit comments

Comments
 (0)