Skip to content

Commit

Permalink
Merge pull request #142 from ergebnis/fix/reject
Browse files Browse the repository at this point in the history
Fix: Reject invalid field definition values
  • Loading branch information
ergebnis-bot authored Mar 31, 2020
2 parents 5a01c33 + 6895a5d commit 746b0a2
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 1 deletion.
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
parameters:
ignoreErrors:
-
message: "#^Instanceof between Ergebnis\\\\FactoryBot\\\\FieldDefinition and Ergebnis\\\\FactoryBot\\\\FieldDefinition will always evaluate to true\\.$#"
count: 1
path: src/EntityDefinition.php

-
message: "#^Method Ergebnis\\\\FactoryBot\\\\FieldDefinition\\:\\:resolve\\(\\) has no return typehint specified\\.$#"
count: 1
Expand Down
29 changes: 28 additions & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.10.1@eeed5ecccc10131397f0eb7ee6da810c0be3a7fc">
<file src="src/EntityDefinition.php">
<DocblockTypeContradiction occurrences="1">
<code>return !$fieldDefinition instanceof FieldDefinition;</code>
</DocblockTypeContradiction>
<MissingPropertyType occurrences="3">
<code>$classMetadata</code>
<code>$fieldDefinitions</code>
<code>$afterCreate</code>
</MissingPropertyType>
<MixedInferredReturnType occurrences="3">
<code>ORM\Mapping\ClassMetadata</code>
<code>array&lt;string, FieldDefinition&gt;</code>
<code>\Closure</code>
</MixedInferredReturnType>
<MixedReturnStatement occurrences="3">
<code>$this-&gt;classMetadata</code>
<code>$this-&gt;fieldDefinitions</code>
<code>$this-&gt;afterCreate</code>
</MixedReturnStatement>
</file>
<file src="src/FieldDefinition.php">
<MissingClosureReturnType occurrences="1">
<code>static function () use (&amp;$n, $funcOrString) {</code>
Expand Down Expand Up @@ -71,9 +91,16 @@
</InternalMethod>
</file>
<file src="test/Unit/EntityDefinitionTest.php">
<MissingClosureParamType occurrences="1">
<MissingClosureParamType occurrences="2">
<code>$entity</code>
<code>$entity</code>
</MissingClosureParamType>
<MixedArgumentTypeCoercion occurrences="1">
<code>$fieldDefinitions</code>
</MixedArgumentTypeCoercion>
<MixedInferredReturnType occurrences="1">
<code>\Generator</code>
</MixedInferredReturnType>
</file>
<file src="test/Unit/FixtureFactoryTest.php">
<ArgumentTypeCoercion occurrences="1">
Expand Down
10 changes: 10 additions & 0 deletions src/EntityDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,19 @@ final class EntityDefinition
* @param ORM\Mapping\ClassMetadata $classMetadata
* @param array<string, FieldDefinition> $fieldDefinitions
* @param \Closure $afterCreate
*
* @throws Exception\InvalidFieldDefinitions
*/
public function __construct(ORM\Mapping\ClassMetadata $classMetadata, array $fieldDefinitions, \Closure $afterCreate)
{
$invalidFieldDefinitions = \array_filter($fieldDefinitions, static function ($fieldDefinition): bool {
return !$fieldDefinition instanceof FieldDefinition;
});

if ([] !== $invalidFieldDefinitions) {
throw Exception\InvalidFieldDefinitions::values();
}

$this->classMetadata = $classMetadata;
$this->fieldDefinitions = $fieldDefinitions;
$this->afterCreate = $afterCreate;
Expand Down
27 changes: 27 additions & 0 deletions src/Exception/InvalidFieldDefinitions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2020 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/factory-bot
*/

namespace Ergebnis\FactoryBot\Exception;

use Ergebnis\FactoryBot\FieldDefinition;

final class InvalidFieldDefinitions extends \RuntimeException implements Exception
{
public static function values(): self
{
return new self(\sprintf(
'Field definitions need to be instances of "%s".',
FieldDefinition::class
));
}
}
49 changes: 49 additions & 0 deletions test/Unit/EntityDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Doctrine\ORM;
use Ergebnis\FactoryBot\EntityDefinition;
use Ergebnis\FactoryBot\Exception;
use Ergebnis\FactoryBot\FieldDefinition;
use Ergebnis\Test\Util\Helper;
use PHPUnit\Framework;
Expand All @@ -24,12 +25,60 @@
*
* @covers \Ergebnis\FactoryBot\EntityDefinition
*
* @uses \Ergebnis\FactoryBot\Exception\InvalidFieldDefinitions
* @uses \Ergebnis\FactoryBot\FieldDefinition
*/
final class EntityDefinitionTest extends Framework\TestCase
{
use Helper;

/**
* @dataProvider provideNotFieldDefinition
*
* @param mixed $fieldDefinition
*/
public function testConstructorRejectsFieldDefinitionsWhenValuesAreNotFieldDefinitions($fieldDefinition): void
{
$fieldDefinitions = [
'foo' => FieldDefinition::sequence(static function (): string {
return 'bar';
}),
'bar' => $fieldDefinition,
];

$this->expectException(Exception\InvalidFieldDefinitions::class);

new EntityDefinition(
$this->prophesize(ORM\Mapping\ClassMetadata::class)->reveal(),
$fieldDefinitions,
static function ($entity, array $fieldValues): void {
// intentionally left blank
}
);
}

public function provideNotFieldDefinition(): \Generator
{
$faker = self::faker();

$values = [
'array' => $faker->words,
'bool-false' => false,
'bool-true' => true,
'float' => $faker->randomFloat(),
'int' => $faker->numberBetween(),
'object' => new \stdClass(),
'resource' => \fopen(__FILE__, 'rb'),
'string' => $faker->sentence,
];

foreach ($values as $key => $value) {
yield $key => [
$value,
];
}
}

public function testConstructorSetsValues(): void
{
$classMetadata = $this->prophesize(ORM\Mapping\ClassMetadata::class);
Expand Down
41 changes: 41 additions & 0 deletions test/Unit/Exception/InvalidFieldDefinitionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2020 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/factory-bot
*/

namespace Ergebnis\FactoryBot\Test\Unit\Exception;

use Ergebnis\FactoryBot\Exception;
use Ergebnis\FactoryBot\FieldDefinition;
use Ergebnis\Test\Util\Helper;
use PHPUnit\Framework;

/**
* @internal
*
* @covers \Ergebnis\FactoryBot\Exception\InvalidFieldDefinitions
*/
final class InvalidFieldDefinitionsTest extends Framework\TestCase
{
use Helper;

public function testFromClassNameCreatesException(): void
{
$exception = Exception\InvalidFieldDefinitions::values();

$message = \sprintf(
'Field definitions need to be instances of "%s".',
FieldDefinition::class
);

self::assertSame($message, $exception->getMessage());
}
}

0 comments on commit 746b0a2

Please sign in to comment.