From 93196f212e2a21dd6c4d2a75b239340bacaa8810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Fri, 24 Apr 2020 08:25:44 +0200 Subject: [PATCH] Enhancement: Introduce named constructor and mark primary constructor private --- CHANGELOG.md | 2 + phpstan-baseline.neon | 5 -- psalm-baseline.xml | 63 +++++++++++++++++++- src/FieldDefinition.php | 10 ++-- src/FieldDefinition/Closure.php | 7 ++- src/FieldDefinition/Reference.php | 18 +++++- src/FieldDefinition/References.php | 26 +++++++- src/FieldDefinition/Sequence.php | 17 +++++- src/FieldDefinition/Value.php | 18 +++++- test/Unit/FieldDefinition/ClosureTest.php | 2 +- test/Unit/FieldDefinition/ReferenceTest.php | 2 +- test/Unit/FieldDefinition/ReferencesTest.php | 4 +- test/Unit/FieldDefinition/SequenceTest.php | 4 +- test/Unit/FieldDefinition/ValueTest.php | 2 +- test/Unit/FieldDefinitionTest.php | 18 +++--- 15 files changed, 160 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a34ab65..479d96ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ For a full diff see [`fa9c564...master`][fa9c564...master]. * Extracted `FieldDefinition\Value` ([#160]), by [@localheinz] * Extracted `FieldDefinition\Closure` ([#161]), by [@localheinz] * Extracted `FieldDefinition\Sequence` ([#164]), by [@localheinz] +* Introduced named constructors for field definitions and marked primary constructor as `private` ([#188]), by [@localheinz] ### Fixed @@ -93,5 +94,6 @@ For a full diff see [`fa9c564...master`][fa9c564...master]. [#161]: https://github.com/ergebnis/factory-bot/pull/161 [#164]: https://github.com/ergebnis/factory-bot/pull/164 [#185]: https://github.com/ergebnis/factory-bot/pull/185 +[#188]: https://github.com/ergebnis/factory-bot/pull/188 [@localheinz]: https://github.com/localheinz diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b571748a..f582d2c7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -65,11 +65,6 @@ parameters: count: 1 path: test/Fixture/FixtureFactory/Entity/User.php - - - message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertInstanceOf\\(\\) with 'Ergebnis\\\\\\\\FactoryBot\\\\\\\\Test\\\\\\\\Fixture\\\\\\\\FixtureFactory\\\\\\\\Entity\\\\\\\\User' and Ergebnis\\\\FactoryBot\\\\Test\\\\Fixture\\\\FixtureFactory\\\\Entity\\\\User will always evaluate to true\\.$#" - count: 1 - path: test/Unit/FieldDefinition/ReferenceTest.php - - message: "#^Parameter \\#1 \\$className of method Ergebnis\\\\FactoryBot\\\\FixtureFactory\\:\\:defineEntity\\(\\) expects class\\-string\\, string given\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index d0a0e984..a2813751 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5,6 +5,44 @@ return !$fieldDefinition instanceof FieldDefinition\Resolvable; + + + $className + $className + + + $value + + + FieldDefinition\Reference::required($className) + FieldDefinition\Reference<T> + FieldDefinition\References<T> + + + + + self<T> + + + class-string<T> + + + + + self<T> + + + class-string<T> + + + + + self<T> + + + T + + $fieldValues[$fieldName] @@ -58,15 +96,34 @@ - - assertInstanceOf - + + $className + + + + + Fixture\FixtureFactory\Entity\User::class + $className + + + $value + $resolved + + + $className + $className + $className + + + $value + + $className diff --git a/src/FieldDefinition.php b/src/FieldDefinition.php index a6f9854d..0d4dcfea 100644 --- a/src/FieldDefinition.php +++ b/src/FieldDefinition.php @@ -17,7 +17,7 @@ final class FieldDefinition { public static function closure(\Closure $closure): FieldDefinition\Closure { - return new FieldDefinition\Closure($closure); + return FieldDefinition\Closure::required($closure); } /** @@ -32,7 +32,7 @@ public static function sequence($value, int $initialNumber = 1): FieldDefinition $value .= '%d'; } - return new FieldDefinition\Sequence( + return FieldDefinition\Sequence::required( $value, $initialNumber ); @@ -53,7 +53,7 @@ public static function sequence($value, int $initialNumber = 1): FieldDefinition */ public static function reference(string $className): FieldDefinition\Reference { - return new FieldDefinition\Reference($className); + return FieldDefinition\Reference::required($className); } /** @@ -74,7 +74,7 @@ public static function reference(string $className): FieldDefinition\Reference */ public static function references(string $className, int $count = 1): FieldDefinition\References { - return new FieldDefinition\References( + return FieldDefinition\References::required( $className, $count ); @@ -95,6 +95,6 @@ public static function references(string $className, int $count = 1): FieldDefin */ public static function value($value): FieldDefinition\Value { - return new FieldDefinition\Value($value); + return FieldDefinition\Value::required($value); } } diff --git a/src/FieldDefinition/Closure.php b/src/FieldDefinition/Closure.php index 1b9f88d3..3c491a6e 100644 --- a/src/FieldDefinition/Closure.php +++ b/src/FieldDefinition/Closure.php @@ -25,11 +25,16 @@ final class Closure implements Resolvable */ private $closure; - public function __construct(\Closure $closure) + private function __construct(\Closure $closure) { $this->closure = $closure; } + public static function required(\Closure $closure): self + { + return new self($closure); + } + public function resolve(FixtureFactory $fixtureFactory) { $closure = $this->closure; diff --git a/src/FieldDefinition/Reference.php b/src/FieldDefinition/Reference.php index 9cb02a8d..bbf47c6a 100644 --- a/src/FieldDefinition/Reference.php +++ b/src/FieldDefinition/Reference.php @@ -40,11 +40,27 @@ final class Reference implements Resolvable * * @param string $className */ - public function __construct(string $className) + private function __construct(string $className) { $this->className = $className; } + /** + * @phpstan-param class-string $className + * @phpstan-return self + * + * @psalm-param class-string $className + * @psalm-return self + * + * @param string $className + * + * @return self + */ + public static function required(string $className): self + { + return new self($className); + } + /** * @phpstan-return T * diff --git a/src/FieldDefinition/References.php b/src/FieldDefinition/References.php index 95fe4caa..c9c7bf38 100644 --- a/src/FieldDefinition/References.php +++ b/src/FieldDefinition/References.php @@ -46,10 +46,28 @@ final class References implements Resolvable * * @param string $className * @param int $count + */ + private function __construct(string $className, int $count) + { + $this->className = $className; + $this->count = $count; + } + + /** + * @phpstan-param class-string $className + * @phpstan-return self + * + * @psalm-param class-string $className + * @psalm-return self + * + * @param string $className + * @param int $count * * @throws Exception\InvalidCount + * + * @return self */ - public function __construct(string $className, int $count) + public static function required(string $className, int $count): self { if (1 > $count) { throw Exception\InvalidCount::notGreaterThanOrEqualTo( @@ -58,8 +76,10 @@ public function __construct(string $className, int $count) ); } - $this->className = $className; - $this->count = $count; + return new self( + $className, + $count + ); } /** diff --git a/src/FieldDefinition/Sequence.php b/src/FieldDefinition/Sequence.php index badb87ed..e899165d 100644 --- a/src/FieldDefinition/Sequence.php +++ b/src/FieldDefinition/Sequence.php @@ -31,19 +31,30 @@ final class Sequence implements Resolvable */ private $sequentialNumber; + private function __construct(string $value, int $initialNumber) + { + $this->value = $value; + $this->sequentialNumber = $initialNumber; + } + /** * @param string $value * @param int $initialNumber * * @throws Exception\InvalidSequence + * + * @return self */ - public function __construct(string $value, int $initialNumber) + public static function required(string $value, int $initialNumber): self { if (false === \strpos($value, '%d')) { throw Exception\InvalidSequence::value($value); } - $this->value = $value; - $this->sequentialNumber = $initialNumber; + + return new self( + $value, + $initialNumber + ); } public function resolve(FixtureFactory $fixtureFactory): string diff --git a/src/FieldDefinition/Value.php b/src/FieldDefinition/Value.php index d905c77d..f6fc4d32 100644 --- a/src/FieldDefinition/Value.php +++ b/src/FieldDefinition/Value.php @@ -40,11 +40,27 @@ final class Value implements Resolvable * * @param mixed $value */ - public function __construct($value) + private function __construct($value) { $this->value = $value; } + /** + * @phpstan-param T $value + * @phpstan-return self + * + * @psalm-param T $value + * @psalm-return self + * + * @param mixed $value + * + * @return self + */ + public static function required($value): self + { + return new self($value); + } + /** * @phpstan-return T * diff --git a/test/Unit/FieldDefinition/ClosureTest.php b/test/Unit/FieldDefinition/ClosureTest.php index 82bdbfce..e21e2536 100644 --- a/test/Unit/FieldDefinition/ClosureTest.php +++ b/test/Unit/FieldDefinition/ClosureTest.php @@ -40,7 +40,7 @@ public function testResolveReturnsResultOfInvokingClosureWithFixtureFactory(): v return $fixtureFactory->get(Fixture\FixtureFactory\Entity\User::class); }; - $fieldDefinition = new Closure($closure); + $fieldDefinition = Closure::required($closure); $resolved = $fieldDefinition->resolve($fixtureFactory); diff --git a/test/Unit/FieldDefinition/ReferenceTest.php b/test/Unit/FieldDefinition/ReferenceTest.php index 597c133b..6fe5a07b 100644 --- a/test/Unit/FieldDefinition/ReferenceTest.php +++ b/test/Unit/FieldDefinition/ReferenceTest.php @@ -38,7 +38,7 @@ public function testResolveReturnsObjectFromFixtureFactory(): void $fixtureFactory->defineEntity($className); - $fieldDefinition = new Reference($className); + $fieldDefinition = Reference::required($className); $resolved = $fieldDefinition->resolve($fixtureFactory); diff --git a/test/Unit/FieldDefinition/ReferencesTest.php b/test/Unit/FieldDefinition/ReferencesTest.php index 207fea8a..aaa8b649 100644 --- a/test/Unit/FieldDefinition/ReferencesTest.php +++ b/test/Unit/FieldDefinition/ReferencesTest.php @@ -45,7 +45,7 @@ public function testConstructorRejectsInvalidCount(int $count): void $count )); - new References( + References::required( Fixture\FixtureFactory\Entity\User::class, $count ); @@ -64,7 +64,7 @@ public function testResolveReturnsObjectsFromFixtureFactory(int $count): void $fixtureFactory->defineEntity($className); - $fieldDefinition = new References( + $fieldDefinition = References::required( $className, $count ); diff --git a/test/Unit/FieldDefinition/SequenceTest.php b/test/Unit/FieldDefinition/SequenceTest.php index 28ac2364..222a74ea 100644 --- a/test/Unit/FieldDefinition/SequenceTest.php +++ b/test/Unit/FieldDefinition/SequenceTest.php @@ -41,7 +41,7 @@ public function testConstructorRejectsValueWhenItIsMissingPercentDPlaceholder(): $value )); - new Sequence( + Sequence::required( $value, $initialNumber ); @@ -57,7 +57,7 @@ public function testResolveReturnsValueWithPercentDReplacedWithSequentialNumber( $fixtureFactory = new FixtureFactory(self::entityManager()); - $fieldDefinition = new Sequence( + $fieldDefinition = Sequence::required( $value, $initialNumber ); diff --git a/test/Unit/FieldDefinition/ValueTest.php b/test/Unit/FieldDefinition/ValueTest.php index 86c048e7..7b492147 100644 --- a/test/Unit/FieldDefinition/ValueTest.php +++ b/test/Unit/FieldDefinition/ValueTest.php @@ -37,7 +37,7 @@ public function testResolveReturnsValue($value): void { $fixtureFactory = new FixtureFactory(self::entityManager()); - $fieldDefinition = new Value($value); + $fieldDefinition = Value::required($value); $resolved = $fieldDefinition->resolve($fixtureFactory); diff --git a/test/Unit/FieldDefinitionTest.php b/test/Unit/FieldDefinitionTest.php index e96ee4ec..20777dc0 100644 --- a/test/Unit/FieldDefinitionTest.php +++ b/test/Unit/FieldDefinitionTest.php @@ -45,7 +45,7 @@ public function testClosureReturnsClosure(): void $fieldDefinition = FieldDefinition::closure($closure); - $expected = new FieldDefinition\Closure($closure); + $expected = FieldDefinition\Closure::required($closure); self::assertEquals($expected, $fieldDefinition); } @@ -56,7 +56,7 @@ public function testReferenceReturnsReference(): void $fieldDefinition = FieldDefinition::reference($className); - $expected = new FieldDefinition\Reference($className); + $expected = FieldDefinition\Reference::required($className); self::assertEquals($expected, $fieldDefinition); } @@ -84,7 +84,7 @@ public function testReferencesReturnsReferencesWhenCountIsNotSpecified(): void $fieldDefinition = FieldDefinition::references($className); - $expected = new FieldDefinition\References( + $expected = FieldDefinition\References::required( $className, 1 ); @@ -106,7 +106,7 @@ public function testReferencesReturnsReferencesWhenCountIsSpecified(int $count): $count ); - $expected = new FieldDefinition\References( + $expected = FieldDefinition\References::required( $className, $count ); @@ -120,7 +120,7 @@ public function testSequenceReturnsSequenceWhenValueContainsPlaceholderAndInitia $fieldDefinition = FieldDefinition::sequence($value); - $expected = new FieldDefinition\Sequence( + $expected = FieldDefinition\Sequence::required( $value, 1 ); @@ -142,7 +142,7 @@ public function testSequenceReturnsSequenceWhenValueContainsPlaceholderAndInitia $initialNumber ); - $expected = new FieldDefinition\Sequence( + $expected = FieldDefinition\Sequence::required( $value, $initialNumber ); @@ -156,7 +156,7 @@ public function testSequenceReturnsSequenceWhenValueDoesNotContainPlaceholderAnd $fieldDefinition = FieldDefinition::sequence($value); - $expected = new FieldDefinition\Sequence( + $expected = FieldDefinition\Sequence::required( $value . '%d', 1 ); @@ -178,7 +178,7 @@ public function testSequenceReturnsSequenceWhenValueDoesNotContainPlaceholderAnd $initialNumber ); - $expected = new FieldDefinition\Sequence( + $expected = FieldDefinition\Sequence::required( $value . '%d', $initialNumber ); @@ -195,7 +195,7 @@ public function testValueReturnsValue($value): void { $fieldDefinition = FieldDefinition::value($value); - $expected = new FieldDefinition\Value($value); + $expected = FieldDefinition\Value::required($value); self::assertEquals($expected, $fieldDefinition); }