• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wol-soft / php-json-schema-model-generator / 28856540538

07 Jul 2026 09:31AM UTC coverage: 98.076%. First build
28856540538

Pull #157

github

wol-soft
Warn and skip on unevaluatedProperties dead cells + edge-case tests

UnevaluatedPropertiesValidatorFactory now consolidates all four
sibling shapes that leave the unevaluatedProperties bucket
permanently empty into a single deadCodeReason() helper:

- additionalProperties: true — every extra flows to the model but
  the accumulator does not credit it, so the validator would still
  fire and defeat the intent of `additionalProperties: true`.
- additionalProperties: {schema} — every extra is claimed and
  validated by additionalProperties; the unevaluated set is empty.
- additionalProperties: false — every extra is rejected before the
  post-composition phase, so the unevaluated validator never runs.
- denyAdditionalProperties() generator flag with additionalProperties
  absent — synthesises the same false shape at configuration time.

Each cell emits a distinct warning via the existing echo channel
so build-output greps can identify the specific dead shape, and
skips validator emission entirely.

Tests added:

- Object-side dead-code data provider covering all four shapes plus
  the denyAdditionalProperties() variant. Rows pass the
  GeneratorConfiguration directly (setOutputEnabled(true) on the
  base, chained with setDenyAdditionalProperties(true) on the deny
  row) so the test signature drops the closure/fallback boilerplate.
- testAdditionalFalseRejectsExtrasEvenWhenUnevaluatedSchemaWouldAccept
  proves the factory suppressed the validator: an extra that would
  satisfy the unevaluated integer schema is still rejected because
  additionalProperties: false runs first.
- testContradictoryInnerSchemaThrowsSchemaExceptionPointingAtFile
  pins that an unevaluatedProperties schema with contradictory allOf
  types surfaces via the existing "conflicting types" SchemaException
  path, with the file identifier preserved.
- testPropertyNamesRejectionPrecedesUnevaluated data-provider variant
  covering both direct-exception and error-collection modes. The
  re... (continued)
Pull Request #157: Unevaluated properties

712 of 774 new or added lines in 38 files covered. (91.99%)

7237 of 7379 relevant lines covered (98.08%)

563.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/src/Model/Validator/UnevaluatedItemsValidator.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace PHPModelGenerator\Model\Validator;
6

7
use PHPModelGenerator\Exception\Arrays\InvalidUnevaluatedItemsException;
8
use PHPModelGenerator\Exception\SchemaException;
9
use PHPModelGenerator\Model\Property\PropertyInterface;
10
use PHPModelGenerator\Model\Schema;
11
use PHPModelGenerator\Model\SchemaDefinition\JsonSchema;
12
use PHPModelGenerator\PropertyProcessor\PropertyFactory;
13
use PHPModelGenerator\SchemaProcessor\SchemaProcessor;
14
use PHPModelGenerator\Utils\RenderHelper;
15

16
/**
17
 * Validator emitted for schemas declaring `unevaluatedItems: <schema>`.
18
 *
19
 * Mirrors UnevaluatedPropertiesValidator on the array side: each index of the array not
20
 * claimed by a sibling positive applicator must validate against the unevaluatedItems
21
 * subschema.
22
 */
23
class UnevaluatedItemsValidator extends AbstractUnevaluatedItemsValidator
24
{
25
    private const NESTED_PROPERTY_NAME = 'unevaluated item';
26

27
    private readonly PropertyInterface $validationProperty;
28

29
    /**
30
     * @throws SchemaException
31
     */
32
    public function __construct(
5✔
33
        SchemaProcessor $schemaProcessor,
34
        Schema $schema,
35
        PropertyInterface $property,
36
        JsonSchema $propertiesStructure,
37
    ) {
38
        $this->validationProperty = (new PropertyFactory())->create(
5✔
39
            $schemaProcessor,
5✔
40
            $schema,
5✔
41
            self::NESTED_PROPERTY_NAME,
5✔
42
            $propertiesStructure->navigate('unevaluatedItems'),
5✔
43
            true,
5✔
44
        );
5✔
45

46
        $this->validationProperty->onResolve(function (): void {
5✔
47
            $this->resolve();
5✔
48
        });
5✔
49

50
        parent::__construct(
5✔
51
            $property,
5✔
52
            DIRECTORY_SEPARATOR . 'Validator' . DIRECTORY_SEPARATOR . 'UnevaluatedItems.phptpl',
5✔
53
            InvalidUnevaluatedItemsException::class,
5✔
54
            ['&$invalidItems'],
5✔
55
            [
5✔
56
                'schema' => $schema,
5✔
57
                'validationProperty' => $this->validationProperty,
5✔
58
                'generatorConfiguration' => $schemaProcessor->getGeneratorConfiguration(),
5✔
59
                'viewHelper' => new RenderHelper($schemaProcessor->getGeneratorConfiguration()),
5✔
60
            ],
5✔
61
        );
5✔
62
    }
63

64
    /**
65
     * @inheritDoc
66
     */
67
    public function getCheck(): string
5✔
68
    {
69
        $this->removeRequiredPropertyValidator($this->validationProperty);
5✔
70

71
        return parent::getCheck();
5✔
72
    }
73

NEW
74
    public function getValidationProperty(): PropertyInterface
×
75
    {
NEW
76
        return $this->validationProperty;
×
77
    }
78

79
    /**
80
     * Initialize the per-call error map captured by reference into the IIFE so the
81
     * generated exception receives the populated list.
82
     */
83
    public function getValidatorSetUp(): string
5✔
84
    {
85
        return '$invalidItems = [];';
5✔
86
    }
87
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc