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

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

23 Oct 2026 03:12PM UTC coverage: 99.318% (+0.1%) from 99.21%
39976243810

Pull #157

github

claude
Activate evaluation tracking only for keywords of the schema's own class

needsActivation() searched the nested schemas (object properties, object-typed
branches) as well, so a keyword deep inside a nested class activated the
tracking of every enclosing class although no unevaluated keyword of those
classes reads it. Every nested class is processed on its own and activates its
own tracking. unevaluatedProperties on a property always lives in the
property's nested class, only unevaluatedItems of a property is evaluated by
the schema's class.

Cover the fallback of resolvePrimaryJsonPointer() for properties without a
JsonPointer attribute, throw on the unreachable missing nested class of an
untyped object property instead of generating it without one, update the
docblock of UnevaluatedPropertiesPostProcessor to the update validation of the
merged master and drop an issue reference from a comment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016TbSpXPq3pUmw9Hrh9CfRG
Pull Request #157: Unevaluated properties

10050 of 10119 relevant lines covered (99.32%)

588.72 hits per line

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

96.55
/src/Model/Validator/ExtractedMethodValidator.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace PHPModelGenerator\Model\Validator;
6

7
use PHPMicroTemplate\Exception\PHPMicroTemplateException;
8
use PHPModelGenerator\Exception\RenderException;
9
use PHPModelGenerator\Model\GeneratorConfiguration;
10
use PHPModelGenerator\Model\MethodInterface;
11
use PHPModelGenerator\Model\Property\PropertyInterface;
12
use PHPModelGenerator\Model\Schema;
13
use PHPModelGenerator\Utils\RenderHelper;
14

15
/**
16
 * Renders the validator in a separate method. Might be required for recursive validations which would otherwise cause
17
 * infinite loops during validator rendering
18
 */
19
abstract class ExtractedMethodValidator extends PropertyTemplateValidator
20
{
21
    protected string $extractedMethodName;
22

23
    public function __construct(
1,547 ✔
24
        protected readonly GeneratorConfiguration $generatorConfiguration,
25
        PropertyInterface $property,
26
        string $template,
27
        array $templateValues,
28
        string $exceptionClass,
29
        array $exceptionParams = [],
30
        ?Schema $schema = null,
31
    ) {
32
        $methodName = sprintf(
1,547 ✔
33
            '_validate%s_%s_%s',
1,547 ✔
34
            str_replace(' ', '', ucfirst($property->getAttribute())),
1,547 ✔
35
            str_replace('Validator', '', substr(strrchr(static::class, '\\'), 1)),
1,547 ✔
36
            md5(json_encode($property->getJsonSchema()->getJson())),
1,547 ✔
37
        );
1,547 ✔
38

39
        // Two validators of the same kind on the same attribute with identical schema JSON (two
40
        // compositions on one property, identical anyOf branches, ...) hash to the same name, and
41
        // a class registers each name once - the second validator would silently reuse the first
42
        // one's method body. The class-scoped reservation separates them deterministically.
43
        // Rejected: mixing spl_object_id() into the hash - it separates them too, but the id shifts
44
        // whenever an unrelated schema was processed earlier in the run, renaming the extracted
45
        // methods of classes that did not change.
46
        $this->extractedMethodName = $schema?->reserveMethodName($methodName) ?? $methodName;
1,547 ✔
47

48
        parent::__construct($property, $template, $templateValues, $exceptionClass, $exceptionParams);
1,547 ✔
49
    }
50

51
    public function getMethod(): MethodInterface
932 ✔
52
    {
53
        return new class ($this, $this->generatorConfiguration) implements MethodInterface {
932 ✔
54
            public function __construct(
55
                private readonly ExtractedMethodValidator $validator,
56
                private readonly GeneratorConfiguration $generatorConfiguration,
57
            ) {}
932 ✔
58

59
            public function getCode(): string
60
            {
61
                return $this->validator->renderExtractedMethod($this->generatorConfiguration);
932 ✔
62
            }
63
        };
932 ✔
64
    }
65

66
    /**
67
     * @throws RenderException
68
     */
69
    public function renderExtractedMethod(GeneratorConfiguration $generatorConfiguration): string
932 ✔
70
    {
71
        $renderHelper = new RenderHelper($generatorConfiguration);
932 ✔
72

73
        try {
74
            return $this->getRenderer()->renderTemplate(
932 ✔
75
                DIRECTORY_SEPARATOR . 'Validator' . DIRECTORY_SEPARATOR . 'ExtractedMethod.phptpl',
932 ✔
76
                [
932 ✔
77
                    'methodName' => $this->getExtractedMethodName(),
932 ✔
78
                    'setUp' => $this->getValidatorSetUp(),
932 ✔
79
                    'check' => $this->getCheck(),
932 ✔
80
                    'errorHandling' => $renderHelper->validationError($this),
932 ✔
81
                    'viewHelper' => $renderHelper,
932 ✔
82
                ],
932 ✔
83
            );
932 ✔
84
        } catch (PHPMicroTemplateException $exception) {
×
85
            // @codeCoverageIgnoreStart
86
            throw new RenderException(
87
                "Can't render extracted method {$this->getExtractedMethodName()}",
88
                0,
89
                $exception,
90
            );
91
            // @codeCoverageIgnoreEnd
92
        }
93
    }
94

95
    public function getExtractedMethodName(): string
932 ✔
96
    {
97
        return $this->extractedMethodName;
932 ✔
98
    }
99
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc