Skip to content

Fix regression introduced by #68 #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2023
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
8 changes: 8 additions & 0 deletions src/Model/Validator/PropertyTemplateValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPMicroTemplate\Render;
use PHPModelGenerator\Exception\RenderException;
use PHPModelGenerator\Model\Property\PropertyInterface;
use PHPModelGenerator\Model\Schema;

/**
* Class PropertyTemplateValidator
Expand Down Expand Up @@ -45,6 +46,13 @@ public function __construct(
parent::__construct($property, $exceptionClass, $exceptionParams);
}

public function setScope(Schema $schema): void
{
if (isset($this->templateValues['schema'])) {
$this->templateValues['schema'] = $schema;
}
}

/**
* Get the source code for the check to perform
*
Expand Down
2 changes: 1 addition & 1 deletion src/PropertyProcessor/Property/BaseProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ protected function transferComposedPropertiesToSchema(PropertyInterface $propert

// If the transferred validator of the composed property is also a composed property strip the nested
// composition validations from the added validator. The nested composition will be validated in the object
// generated for the nested composition which will be executed via an instanciation. Consequently the
// generated for the nested composition which will be executed via an instantiation. Consequently, the
// validation must not be executed in the outer composition.
$this->schema->addBaseValidator(
($validator instanceof ComposedPropertyValidator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace PHPModelGenerator\SchemaProcessor\PostProcessor\Internal;

use Exception;
use PHPModelGenerator\Exception\Object\InvalidAdditionalPropertiesException;
use PHPModelGenerator\Exception\SchemaException;
use PHPModelGenerator\Model\GeneratorConfiguration;
use PHPModelGenerator\Model\Property\Property;
Expand Down Expand Up @@ -114,7 +114,7 @@ public function __construct(Schema $schema)
array_keys($schema->getJsonSchema()->getJson()['properties'] ?? [])
),
],
Exception::class
InvalidAdditionalPropertiesException::class
);
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/Utils/RenderHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPModelGenerator\Model\Property\PropertyInterface;
use PHPModelGenerator\Model\Schema;
use PHPModelGenerator\Model\Validator\ExtractedMethodValidator;
use PHPModelGenerator\Model\Validator\PropertyTemplateValidator;
use PHPModelGenerator\Model\Validator\PropertyValidatorInterface;

/**
Expand Down Expand Up @@ -162,6 +163,12 @@ public function getTypeHintAnnotation(PropertyInterface $property, bool $outputT

public function renderValidator(PropertyValidatorInterface $validator, Schema $schema): string
{
// scoping of the validator might be required as validators from a composition might be transferred to a
// different schema
if ($validator instanceof PropertyTemplateValidator) {
$validator->setScope($schema);
}

if (!$validator instanceof ExtractedMethodValidator) {
return "
{$validator->getValidatorSetUp()}
Expand All @@ -184,7 +191,7 @@ public function renderMethods(Schema $schema): string

// don't change to a foreach loop as the render process of a method might add additional methods
for ($i = 0; $i < count($schema->getMethods()); $i++) {
$renderedMethods .= $schema->getMethods()[array_keys($schema->getMethods())[$i]]->getCode();
$renderedMethods .= $schema->getMethods()[array_keys($schema->getMethods())[$i]]->getCode() . "\n\n";
}

return $renderedMethods;
Expand Down
26 changes: 14 additions & 12 deletions tests/AbstractPHPModelGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ protected function generateClassFromFile(
string $schemaProviderClass = RecursiveDirectoryProvider::class
): string {
return $this->generateClass(
file_get_contents(__DIR__ . '/Schema/' . $this->getStaticClassName() . '/' . $file),
file_get_contents($this->getSchemaFilePath($file)),
$generatorConfiguration,
$originalClassNames,
$implicitNull,
Expand Down Expand Up @@ -171,16 +171,13 @@ protected function generateClassFromFileTemplate(
string $schemaProviderClass = RecursiveDirectoryProvider::class
): string {
return $this->generateClass(
call_user_func_array(
'sprintf',
array_merge(
[file_get_contents(__DIR__ . '/Schema/' . $this->getStaticClassName() . '/' . $file)],
array_map(
static function (string $item) use ($escape): string {
return $escape ? str_replace("'", '"', addcslashes($item, '"\\')) : $item;
},
$values
)
sprintf(
file_get_contents($this->getSchemaFilePath($file)),
...array_map(
static function (string $item) use ($escape): string {
return $escape ? str_replace("'", '"', addcslashes($item, '"\\')) : $item;
},
$values
)
),
$generatorConfiguration,
Expand Down Expand Up @@ -517,6 +514,11 @@ protected function getGeneratedFiles(): array
return $this->generatedFiles;
}

protected function getSchemaFilePath(string $file): string
{
return __DIR__ . '/Schema/' . $this->getStaticClassName() . '/' . $file;
}

/**
* Generate a unique name for a class
*
Expand All @@ -536,7 +538,7 @@ private function getClassName(): string
return $name;
}

private function getStaticClassName(): string
protected function getStaticClassName(): string
{
$parts = explode('\\', static::class);

Expand Down
17 changes: 17 additions & 0 deletions tests/Issues/AbstractIssueTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace PHPModelGenerator\Tests\Issues;

use PHPModelGenerator\Tests\AbstractPHPModelGeneratorTest;

abstract class AbstractIssueTest extends AbstractPHPModelGeneratorTest
{
protected function getSchemaFilePath(string $file): string
{
preg_match('/(?P<issue>\d+)/', $this->getStaticClassName(), $matches);

return __DIR__ . '/../Schema/Issues/' . $matches['issue'] . '/' . $file;
}
}
45 changes: 45 additions & 0 deletions tests/Issues/Regression/RegressionIssue65Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace PHPModelGenerator\Tests\Issues\Regression;

use PHPModelGenerator\Exception\ComposedValue\AllOfException;
use PHPModelGenerator\Tests\Issues\AbstractIssueTest;

class RegressionIssue65Test extends AbstractIssueTest
{
public function testValidInput(): void
{
$className = $this->generateClassFromFile('regression.json');

$object = new $className(['list' => [['id' => 10, 'name' => 'Hans']], 'label' => 'visitors']);

$this->assertSame('visitors', $object->getLabel());
$this->assertCount(1, $object->getList());
$this->assertSame(10, $object->getList()[0]->getId());
$this->assertSame('Hans', $object->getList()[0]->getName());
}

/**
* @dataProvider invalidInputDataProvider
*/
public function testInvalidInput(array $input): void
{
$this->expectException(AllOfException::class);

$className = $this->generateClassFromFile('regression.json');

new $className($input);
}

public function invalidInputDataProvider(): array
{
return [
'invalid label' => [['label' => 10]],
'invalid list element' => [['list' => [['id' => 10, 'name' => 'Hans'], 10]]],
'invalid id in list element' => [['list' => [['id' => '10', 'name' => 'Hans']]]],
'invalid name in list element' => [['list' => [['id' => 10, 'name' => false]]]],
];
}
}
40 changes: 40 additions & 0 deletions tests/Schema/Issues/65/regression.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"allOf": [
{
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"allOf": [
{
"type": "object",
"properties": {
"id": {
"type": "integer"
}
}
},
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
]
}
}
}
},
{
"type": "object",
"properties": {
"label": {
"type": "string"
}
}
}
]
}