diff --git a/src/Command/ApiSuiteCommand.php b/src/Command/ApiSuiteCommand.php index 2b774e4..f59a18b 100644 --- a/src/Command/ApiSuiteCommand.php +++ b/src/Command/ApiSuiteCommand.php @@ -21,6 +21,7 @@ use SlayerBirden\DFCodeGeneration\Generator\Tests\Get as TestGet; use SlayerBirden\DFCodeGeneration\Generator\Tests\Gets as TestGets; use SlayerBirden\DFCodeGeneration\Generator\Tests\IdRegistry; +use SlayerBirden\DFCodeGeneration\Generator\Tests\NullValuesRandomizer; use SlayerBirden\DFCodeGeneration\Generator\Tests\ReflectionProviderFactory; use SlayerBirden\DFCodeGeneration\Generator\Tests\Update as TestUpdate; use SlayerBirden\DFCodeGeneration\Generator\Factory\SimpleProvider; @@ -116,13 +117,15 @@ protected function execute(InputInterface $input, OutputInterface $output) private function generateTests(): void { $entityProviderFactory = new ReflectionProviderFactory(new IdRegistry()); + // 50% null values written by default + $randomizer = new NullValuesRandomizer(.5); $files = []; - $files[] = (new TestAdd($this->entityClassName, $entityProviderFactory))->generate(); - $files[] = (new TestDelete($this->entityClassName, $entityProviderFactory))->generate(); - $files[] = (new TestGet($this->entityClassName, $entityProviderFactory))->generate(); - $files[] = (new TestGets($this->entityClassName, $entityProviderFactory))->generate(); - $files[] = (new TestUpdate($this->entityClassName, $entityProviderFactory))->generate(); + $files[] = (new TestAdd($this->entityClassName, $entityProviderFactory, $randomizer))->generate(); + $files[] = (new TestDelete($this->entityClassName, $entityProviderFactory, $randomizer))->generate(); + $files[] = (new TestGet($this->entityClassName, $entityProviderFactory, $randomizer))->generate(); + $files[] = (new TestGets($this->entityClassName, $entityProviderFactory, $randomizer))->generate(); + $files[] = (new TestUpdate($this->entityClassName, $entityProviderFactory, $randomizer))->generate(); array_walk($files, function ($contents) { $this->writer->write($contents); diff --git a/src/Generator/Tests/AbstractTest.php b/src/Generator/Tests/AbstractTest.php index d66b0f3..f9a72c2 100644 --- a/src/Generator/Tests/AbstractTest.php +++ b/src/Generator/Tests/AbstractTest.php @@ -22,19 +22,18 @@ abstract class AbstractTest implements GeneratorInterface private $innerProviders = []; private $appended = []; /** - * The default probability of Nulled values being filled with data - * @var float + * @var NullValuesRandomizer */ - private $probabilityOfFilledNullable; + private $nullValuesRandomizer; public function __construct( string $entityClassName, EntityProviderFactoryInterface $entityProviderFactory, - float $probabilityOfFilledNullable = .5 + NullValuesRandomizer $nullValuesRandomizer ) { $this->entityProviderFactory = $entityProviderFactory; $this->entityClassName = $entityClassName; - $this->probabilityOfFilledNullable = $probabilityOfFilledNullable; + $this->nullValuesRandomizer = $nullValuesRandomizer; } protected function getLatestProvider() @@ -87,8 +86,7 @@ private function getHaveInRepoPhrase(EntityProviderInterface $provider): string $type = $item['type']; $reference = $item['reference'] ?? []; $nullable = $item['nullable'] ?? false; - // Skip 50% of nullable values (by default) - if ($nullable && rand(0,100)/100 > $this->probabilityOfFilledNullable) { + if ($nullable && !$this->nullValuesRandomizer->ifShouldWrite()) { continue; } if ($reference) { diff --git a/src/Generator/Tests/NullValuesRandomizer.php b/src/Generator/Tests/NullValuesRandomizer.php new file mode 100644 index 0000000..707ad59 --- /dev/null +++ b/src/Generator/Tests/NullValuesRandomizer.php @@ -0,0 +1,25 @@ +probabilityOfFilledNull = $probabilityOfFilledNull; + } + + /** + * @return bool + */ + public function ifShouldWrite(): bool + { + return rand(0,100)/100 < $this->probabilityOfFilledNull; + } +} diff --git a/tests/unit/Generator/Tests/AddTest.php b/tests/unit/Generator/Tests/AddTest.php index ff53a43..1315ff2 100644 --- a/tests/unit/Generator/Tests/AddTest.php +++ b/tests/unit/Generator/Tests/AddTest.php @@ -57,7 +57,7 @@ public function testCreateClass() $this->provider->hasUnique()->willReturn(true); $this->provider->getIdName()->willReturn('id'); - $add = new Add('Dummy\\User', $this->factory->reveal()); + $add = new Add('Dummy\\User', $this->factory->reveal(), new NullValuesRandomizer(.5)); $code = $add->generate(); $this->assertNotEmpty($code); diff --git a/tests/unit/Generator/Tests/BeforeTest.php b/tests/unit/Generator/Tests/BeforeTest.php index 484081f..9a3b040 100644 --- a/tests/unit/Generator/Tests/BeforeTest.php +++ b/tests/unit/Generator/Tests/BeforeTest.php @@ -149,9 +149,8 @@ public function testManyToOne() BODY; - $actual = (new class('Dummy\\User', $this->getFactory()) extends AbstractTest + $actual = (new class('Dummy\\User', $this->getFactory(), new NullValuesRandomizer(.5)) extends AbstractTest { - public function generate(): string { return $this->generateHaveInRepo(); @@ -224,7 +223,7 @@ public function testManyToOneMultiple() BODY; - $actual = (new class('Dummy\\User', $this->getFactory(), 2) extends AbstractTest + $actual = (new class('Dummy\\User', $this->getFactory(), new NullValuesRandomizer(.5), 2) extends AbstractTest { /** * @var int @@ -234,9 +233,10 @@ public function testManyToOneMultiple() public function __construct( string $entityClassName, EntityProviderFactoryInterface $entityProviderFactory, + NullValuesRandomizer $randomizer, int $times ) { - parent::__construct($entityClassName, $entityProviderFactory); + parent::__construct($entityClassName, $entityProviderFactory, $randomizer); $this->times = $times; } @@ -319,7 +319,7 @@ public function testManyToManyMultiple() ]); $this->providers[] = $provider4; - $actual = (new class('Dummy\\User', $this->getFactory(), 2) extends AbstractTest + $actual = (new class('Dummy\\User', $this->getFactory(), new NullValuesRandomizer(.5), 2) extends AbstractTest { /** * @var int @@ -329,9 +329,10 @@ public function testManyToManyMultiple() public function __construct( string $entityClassName, EntityProviderFactoryInterface $entityProviderFactory, + NullValuesRandomizer $randomizer, int $times ) { - parent::__construct($entityClassName, $entityProviderFactory); + parent::__construct($entityClassName, $entityProviderFactory, $randomizer); $this->times = $times; } @@ -399,7 +400,7 @@ public function testRelationsNullable() $provider1 = $this->providers[0]; $provider1->getEntitySpec()->willReturn($spec); - $actual = (new class('Dummy\\User', $this->getFactory(), .0) extends AbstractTest + $actual = (new class('Dummy\\User', $this->getFactory(), new NullValuesRandomizer(.0)) extends AbstractTest { public function generate(): string @@ -454,7 +455,7 @@ public function testNullableColumn() $provider1 = $this->providers[0]; $provider1->getEntitySpec()->willReturn($spec); - $actual = (new class('Dummy\\User', $this->getFactory(), .0) extends AbstractTest + $actual = (new class('Dummy\\User', $this->getFactory(), new NullValuesRandomizer(.0)) extends AbstractTest { public function generate(): string diff --git a/tests/unit/Generator/Tests/DeleteTest.php b/tests/unit/Generator/Tests/DeleteTest.php index 69f84bd..7b63c06 100644 --- a/tests/unit/Generator/Tests/DeleteTest.php +++ b/tests/unit/Generator/Tests/DeleteTest.php @@ -57,7 +57,7 @@ public function testCreateClass() $this->provider->hasUnique()->willReturn(true); $this->provider->getIdName()->willReturn('id'); - $delete = new Delete('Dummy\\User', $this->factory->reveal()); + $delete = new Delete('Dummy\\User', $this->factory->reveal(), new NullValuesRandomizer(.5)); $code = $delete->generate(); $this->assertNotEmpty($code); diff --git a/tests/unit/Generator/Tests/GetTest.php b/tests/unit/Generator/Tests/GetTest.php index 30e0478..c723272 100644 --- a/tests/unit/Generator/Tests/GetTest.php +++ b/tests/unit/Generator/Tests/GetTest.php @@ -57,7 +57,7 @@ public function testCreateClass() $this->provider->hasUnique()->willReturn(true); $this->provider->getIdName()->willReturn('id'); - $get = new Get('Dummy\\User', $this->factory->reveal()); + $get = new Get('Dummy\\User', $this->factory->reveal(), new NullValuesRandomizer(.5)); $code = $get->generate(); $this->assertNotEmpty($code); diff --git a/tests/unit/Generator/Tests/GetsTest.php b/tests/unit/Generator/Tests/GetsTest.php index c79a2ce..ada8254 100644 --- a/tests/unit/Generator/Tests/GetsTest.php +++ b/tests/unit/Generator/Tests/GetsTest.php @@ -57,7 +57,7 @@ public function testCreateClass() $this->provider->hasUnique()->willReturn(true); $this->provider->getIdName()->willReturn('id'); - $gets = new Gets('Dummy\\User', $this->factory->reveal()); + $gets = new Gets('Dummy\\User', $this->factory->reveal(), new NullValuesRandomizer(.5)); $code = $gets->generate(); $this->assertNotEmpty($code); diff --git a/tests/unit/Generator/Tests/NullValuesRandomizerTest.php b/tests/unit/Generator/Tests/NullValuesRandomizerTest.php new file mode 100644 index 0000000..59ca053 --- /dev/null +++ b/tests/unit/Generator/Tests/NullValuesRandomizerTest.php @@ -0,0 +1,50 @@ +ifShouldWrite() ? ++$hits : null; + } + + $expected = (int)($percentage * 100); + $actual = round($hits / $total * 100); + + $this->assertThat($actual, new RangeConstraint($expected - 1, $expected + 1)); + } + + public function testThatZeroNeverCalled() + { + $randomizer = new NullValuesRandomizer(.0); + + $hits = 0; + for ($i = 0; $i < 1000000; ++$i) { + $randomizer->ifShouldWrite() ? ++$hits : null; + } + + $this->assertSame(0, $hits); + } + + public function percentageProvider(): array + { + return [ + [.1], + [.5], + [.0], + ]; + } +} diff --git a/tests/unit/Generator/Tests/RangeConstraint.php b/tests/unit/Generator/Tests/RangeConstraint.php new file mode 100644 index 0000000..f9fbfad --- /dev/null +++ b/tests/unit/Generator/Tests/RangeConstraint.php @@ -0,0 +1,54 @@ +from = $from; + $this->to = $to; + } + + /** + * @inheritdoc + */ + public function toString(): string + { + return 'in range'; + } + + /** + * @inheritdoc + */ + protected function matches($other): bool + { + return $other >= $this->from && $other <= $this->to; + } + + /** + * @inheritdoc + */ + protected function failureDescription($other): string + { + return \sprintf( + '%s is not in range between %s and %s', + $this->exporter->shortenedExport($other), + $this->from, + $this->to + ); + } +} diff --git a/tests/unit/Generator/Tests/UpdateTest.php b/tests/unit/Generator/Tests/UpdateTest.php index fe8c4d8..0f24258 100644 --- a/tests/unit/Generator/Tests/UpdateTest.php +++ b/tests/unit/Generator/Tests/UpdateTest.php @@ -60,7 +60,7 @@ public function testCreateClass() $this->provider->hasUnique()->willReturn(true); $this->provider->getIdName()->willReturn('id'); - $update = new Update('Dummy\\User', $this->factory->reveal()); + $update = new Update('Dummy\\User', $this->factory->reveal(), new NullValuesRandomizer(.5)); $code = $update->generate(); $this->assertNotEmpty($code);