From 26a777b064f910fbcb4af477eefd6a6dccdab4d7 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Tue, 25 May 2021 10:59:57 +0200 Subject: [PATCH 1/6] Issue #84 add a test to document the issue --- tests/Factory/ArticlesAuthorFactory.php | 45 +++++++++++++++++++ .../src/Model/Table/ArticlesAuthorsTable.php | 30 +++++++++++++ .../TestApp/src/Model/Table/ArticlesTable.php | 1 + .../Factory/BaseFactoryAssociationsTest.php | 25 +++++++++++ .../Shell/Task/FixtureFactoryTaskTest.php | 4 +- 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 tests/Factory/ArticlesAuthorFactory.php create mode 100644 tests/TestApp/src/Model/Table/ArticlesAuthorsTable.php diff --git a/tests/Factory/ArticlesAuthorFactory.php b/tests/Factory/ArticlesAuthorFactory.php new file mode 100644 index 00000000..4db36a07 --- /dev/null +++ b/tests/Factory/ArticlesAuthorFactory.php @@ -0,0 +1,45 @@ +setDefaultData(function (Generator $faker) { + return []; + }); + } +} diff --git a/tests/TestApp/src/Model/Table/ArticlesAuthorsTable.php b/tests/TestApp/src/Model/Table/ArticlesAuthorsTable.php new file mode 100644 index 00000000..82da270d --- /dev/null +++ b/tests/TestApp/src/Model/Table/ArticlesAuthorsTable.php @@ -0,0 +1,30 @@ +addAssociations([ + 'belongsTo' => [ + 'Articles', + 'Authors', + ], + ]); + parent::initialize($config); + } +} diff --git a/tests/TestApp/src/Model/Table/ArticlesTable.php b/tests/TestApp/src/Model/Table/ArticlesTable.php index 3621ff71..d599735b 100644 --- a/tests/TestApp/src/Model/Table/ArticlesTable.php +++ b/tests/TestApp/src/Model/Table/ArticlesTable.php @@ -25,6 +25,7 @@ public function initialize(array $config) $this->addAssociations([ 'hasMany' => [ 'TestPlugin.Bills', + 'ArticlesAuthors', ], 'belongsToMany' => [ 'Authors', diff --git a/tests/TestCase/Factory/BaseFactoryAssociationsTest.php b/tests/TestCase/Factory/BaseFactoryAssociationsTest.php index 5375559a..6b87c4f9 100644 --- a/tests/TestCase/Factory/BaseFactoryAssociationsTest.php +++ b/tests/TestCase/Factory/BaseFactoryAssociationsTest.php @@ -706,4 +706,29 @@ public function testReproduceIssue84() $this->assertSame(10, $this->AuthorsTable->find()->count()); $this->assertSame(2, $this->BillsTable->find()->count()); } + + /** + * Reproduce the issue reported here: https://github.com/vierge-noire/cakephp-fixture-factories/issues/84 + */ + public function testReproduceIssue84WithArticlesAuthors() + { + $articles = ArticleFactory::make(2) + ->with('ArticlesAuthors[5].Authors', ['biography' => 'Foo']) + ->with('Bills') + ->without('Authors') // do not create the default authors + ->persist(); + + $this->assertSame(2, count($articles)); + foreach ($articles as $article) { + $this->assertSame(5, count($article->articles_authors)); + foreach ($article->articles_authors as $aa) { + $this->assertSame('Foo', $aa->author->biography); + } + $this->assertSame(1, count($article->bills)); + } + + $this->assertSame(2, $this->ArticlesTable->find()->count()); + $this->assertSame(10, $this->AuthorsTable->find()->count()); + $this->assertSame(2, $this->BillsTable->find()->count()); + } } diff --git a/tests/TestCase/Shell/Task/FixtureFactoryTaskTest.php b/tests/TestCase/Shell/Task/FixtureFactoryTaskTest.php index dde5722e..316873ab 100644 --- a/tests/TestCase/Shell/Task/FixtureFactoryTaskTest.php +++ b/tests/TestCase/Shell/Task/FixtureFactoryTaskTest.php @@ -31,6 +31,7 @@ class FixtureFactoryTaskTest extends TestCase public $appTables = [ 'Addresses', + 'ArticlesAuthors', 'Articles', 'Authors', 'Cities', @@ -101,7 +102,8 @@ public function testHandleAssociationsWithArticles() $expected = [ 'toOne' => [], 'oneToMany' => [ - 'Bills' => 'TestPlugin\Test\Factory\BillFactory' + 'Bills' => 'TestPlugin\Test\Factory\BillFactory', + 'ArticlesAuthors' => 'TestApp\Test\Factory\ArticlesAuthorFactory', ], 'manyToMany' => [ 'Authors' => 'TestApp\Test\Factory\AuthorFactory', From a563c0d51ecd1142d2791ad2b442d940eb5280c3 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 28 May 2021 21:43:49 +0200 Subject: [PATCH 2/6] Issue #87 Create find and cout static methods --- README.md | 29 ++++++++- src/Factory/BaseFactory.php | 21 +++++++ tests/Factory/ArticleFactory.php | 10 ++++ .../Factory/BaseFactoryStaticFinderTest.php | 59 +++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 tests/TestCase/Factory/BaseFactoryStaticFinderTest.php diff --git a/README.md b/README.md index af81d179..a6b33ec9 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,36 @@ Here is a quick example, detailed in this section: $article = ArticleFactory::make(5)->with('Authors[3].Address.City.Country', ['name' => 'Kenya'])->persist(); ``` +#### On the command line: +Factories can also conveniently populate your database in order to test your application on the browser. +The following command will persist 5 articles, each with 3 irish authors, considering that the `ArticleFactory` class features +a `withThreeIrishAuthors()` method: +```$xslt +bin/cake fixture_factories_persist Authors -n 5 -m withThreeIrishAuthors +``` +The option `--dry-run` or `-d` will display the output without persisting. +The option `-c` will persist in the connection provided (default is `test`). +The option `-w` will create associated fixtures. + +The `fixture_factories_persist` command is featured on CakePHP 4 only (open to contribution for CakePHP 3). + +## Querying the database + +Because the fixture factories are closely related to the database, the package provide two methods to conveniently +query the database. Note that both methods will by-pass the `beforeFind` event, facilitating the inspection of your +test database. + +#### ArticleFactory::find() +This method will return a query on the table related to the given factory. + +#### ArticleFactory::count() +This method will return the number of entries in the table of the given factory. + ## [Test Lifecycle](docs/lifecycle.md) -The only step performed by the package's test suite is to truncate *dirty* tables before each test. +The only step performed by the package's test suite is to truncate *dirty* tables before each test. More documentation +on the management of the test database may be found +[in the cakephp test suite light documentation](https://github.com/vierge-noire/cakephp-test-suite-light). ## License diff --git a/src/Factory/BaseFactory.php b/src/Factory/BaseFactory.php index c47c4870..702653b9 100644 --- a/src/Factory/BaseFactory.php +++ b/src/Factory/BaseFactory.php @@ -15,6 +15,7 @@ use Cake\Datasource\EntityInterface; use Cake\I18n\I18n; +use Cake\ORM\Query; use Cake\ORM\Table; use Cake\ORM\TableRegistry; use CakephpFixtureFactories\Error\PersistenceException; @@ -557,4 +558,24 @@ public function mergeAssociated(array $data): self return $this; } + + /** + * Query the factory's related table without before find. + * + * @return \Cake\ORM\Query + */ + public static function find(): Query + { + return self::make()->getTable()->find(); + } + + /** + * Count the factory's related table entries without before find. + * + * @return int + */ + public static function count(): int + { + return self::find()->count(); + } } diff --git a/tests/Factory/ArticleFactory.php b/tests/Factory/ArticleFactory.php index 577ae791..15b26d2b 100644 --- a/tests/Factory/ArticleFactory.php +++ b/tests/Factory/ArticleFactory.php @@ -109,4 +109,14 @@ public function withHiddenBiography(string $text) Article::HIDDEN_PARAGRAPH_PROPERTY_NAME => $text ]); } + + public function published() + { + return $this->patchData(['published' => true]); + } + + public function unpublished() + { + return $this->patchData(['published' => false]); + } } diff --git a/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php b/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php new file mode 100644 index 00000000..76f634c0 --- /dev/null +++ b/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php @@ -0,0 +1,59 @@ +Articles = TableRegistry::getTableLocator()->get('Articles'); + $this->Articles->getEventManager()->on( + 'Model.beforeFind', + function(EventInterface $event, Query $query) { + return $query->where(['title' => 'Cannot be found.']); + } + ); + } + + public function tearDown(): void + { + unset($this->Articles); + TableRegistry::getTableLocator()->clear(); + } + + /** + * @Given there are $n articles + * @When I query on the base table, considering the before find in the setup + * @Then no articles are found + * @When I query on the factory tables + * @Then $n articles are found + */ + public function testBaseFactoryStaticFind() + { + $n = 2; + ArticleFactory::make(2)->unpublished()->persist(); + $this->assertSame([], $this->Articles->find()->toArray()); + $this->assertSame($n, ArticleFactory::find()->count()); + $this->assertSame(0, ArticleFactory::find()->find('published')->count()); + $this->assertSame($n, ArticleFactory::count()); + } +} From d9d49cd90756215a4f5670f8a7182bc1183d1800 Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Fri, 21 May 2021 13:41:54 +0200 Subject: [PATCH 3/6] Issue #75 Scenario --- src/Error/FixtureScenarioException.php | 20 ++++ src/Factory/FactoryAwareTrait.php | 100 ++++++++++++++++++ src/Scenario/FixtureScenarioInterface.php | 25 +++++ src/Scenario/ScenarioAwareTrait.php | 49 +++++++++ tests/Factory/AuthorFactory.php | 5 + .../FiveAustralianAuthorsScenario.php | 20 ++++ .../TestCase/Scenario/FixtureScenarioTest.php | 85 +++++++++++++++ 7 files changed, 304 insertions(+) create mode 100644 src/Error/FixtureScenarioException.php create mode 100644 src/Factory/FactoryAwareTrait.php create mode 100644 src/Scenario/FixtureScenarioInterface.php create mode 100644 src/Scenario/ScenarioAwareTrait.php create mode 100644 tests/Scenario/FiveAustralianAuthorsScenario.php create mode 100644 tests/TestCase/Scenario/FixtureScenarioTest.php diff --git a/src/Error/FixtureScenarioException.php b/src/Error/FixtureScenarioException.php new file mode 100644 index 00000000..81683a4a --- /dev/null +++ b/src/Error/FixtureScenarioException.php @@ -0,0 +1,20 @@ +getFactoryClassName($name); + + if (class_exists($factoryClassName)) { + return $factoryClassName::make(...$arguments); + } + + throw new FactoryNotFoundException("Unable to locate factory class $factoryClassName"); + } + + /** + * Converts factory or model name to a fully qualified factory class name + * + * @param string $name Factory or model name + * @return string Fully qualified class name + */ + public function getFactoryClassName(string $name): string + { + // phpcs:disable + @[$modelName, $plugin] = array_reverse(explode('.', $name)); + // phpcs:enable + + return $this->getFactoryNamespace($plugin) . '\\' . $this->getFactoryNameFromModelName($modelName); + } + + /** + * Returns the factory file name + * + * @param string $name [description] + * @return string [description] + */ + public function getFactoryFileName(string $name): string + { + return $this->getFactoryNameFromModelName($name) . '.php'; + } + + /** + * Return the name of the factory from a model name + * + * @param string $modelName Name of the model + * @return string + */ + public static function getFactoryNameFromModelName(string $modelName): string + { + return Inflector::singularize(ucfirst($modelName)) . 'Factory'; + } + + /** + * Namespace where the factory belongs + * + * @param string|null $plugin name of the plugin, or null if no plugin + * @return string + */ + public function getFactoryNamespace(?string $plugin = null): string + { + if (Configure::read('TestFixtureNamespace')) { + return Configure::read('TestFixtureNamespace'); + } else { + return ( + $plugin ? + str_replace('/', '\\', $plugin) : + Configure::read('App.namespace', 'App') + ) . '\Test\Factory'; + } + } +} diff --git a/src/Scenario/FixtureScenarioInterface.php b/src/Scenario/FixtureScenarioInterface.php new file mode 100644 index 00000000..8faeda62 --- /dev/null +++ b/src/Scenario/FixtureScenarioInterface.php @@ -0,0 +1,25 @@ +getFactoryNamespace($plugin), 'Factory') . 'Scenario'; + $scenario = $scenarioNamespace . '\\' . $scenarioName . 'Scenario'; + } + + if (!is_subclass_of($scenario, FixtureScenarioInterface::class)) { + $msg = "The class {$scenario} must implement " . FixtureScenarioInterface::class; + throw new FixtureScenarioException($msg); + } + + /** @var \CakephpFixtureFactories\Scenario\FixtureScenarioInterface $scenario */ + $scenario = new $scenario(); + $scenario->load(); + } +} diff --git a/tests/Factory/AuthorFactory.php b/tests/Factory/AuthorFactory.php index 04867750..490a9b83 100644 --- a/tests/Factory/AuthorFactory.php +++ b/tests/Factory/AuthorFactory.php @@ -43,4 +43,9 @@ public function withAddress($parameter = null) { return $this->with('Address', AddressFactory::make($parameter)); } + + public function fromCountry(string $name) + { + return $this->with('Address.City.Country', CountryFactory::make(compact('name'))); + } } diff --git a/tests/Scenario/FiveAustralianAuthorsScenario.php b/tests/Scenario/FiveAustralianAuthorsScenario.php new file mode 100644 index 00000000..065b846b --- /dev/null +++ b/tests/Scenario/FiveAustralianAuthorsScenario.php @@ -0,0 +1,20 @@ +fromCountry(self::COUNTRY_NAME)->persist(); + } +} diff --git a/tests/TestCase/Scenario/FixtureScenarioTest.php b/tests/TestCase/Scenario/FixtureScenarioTest.php new file mode 100644 index 00000000..84fc3059 --- /dev/null +++ b/tests/TestCase/Scenario/FixtureScenarioTest.php @@ -0,0 +1,85 @@ +AuthorsTable = TableRegistry::getTableLocator()->get('Authors'); + parent::setUp(); + } + + public function tearDown(): void + { + unset($this->AuthorsTable); + parent::tearDown(); + } + + public function scenarioNames(): array + { + return [ + ['FiveAustralianAuthors'], + [FiveAustralianAuthorsScenario::class], + ]; + } + + /** + * @dataProvider scenarioNames + */ + public function testLoadScenario($scenario) + { + $this->loadFixtureScenario($scenario); + + $australianAuthors = $this->AuthorsTable->find() + ->innerJoinWith('Address.City.Country', function (Query $q) { + return $q->where(['Country.name' => FiveAustralianAuthorsScenario::COUNTRY_NAME]); + }) + ->count(); + $this->assertSame(FiveAustralianAuthorsScenario::N, $australianAuthors); + } + + public function testLoadScenarioException() + { + $this->expectException(FixtureScenarioException::class); + $this->loadFixtureScenario(self::class); + } +} From fce543adf52d08400323c8020a0c49c3885443ff Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Wed, 9 Jun 2021 00:10:10 +0200 Subject: [PATCH 4/6] Issue #92 Removes the (re)inflect in the association names --- src/Factory/DataCompiler.php | 5 +- src/Factory/FactoryAwareTrait.php | 89 +++++++++++++++++++ .../Factory/BaseFactoryAssociationsTest.php | 25 +++++- 3 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 src/Factory/FactoryAwareTrait.php diff --git a/src/Factory/DataCompiler.php b/src/Factory/DataCompiler.php index a48db9ea..31452b05 100644 --- a/src/Factory/DataCompiler.php +++ b/src/Factory/DataCompiler.php @@ -146,7 +146,7 @@ public function getCompiledTemplateData() * @param bool $setPrimaryKey Set the primary key if this entity is alone or the first of an array. * @return \Cake\Datasource\EntityInterface */ - public function compileEntity($injectedData, $setPrimaryKey = false): EntityInterface + public function compileEntity($injectedData = [], bool $setPrimaryKey = false): EntityInterface { if ($injectedData instanceof EntityInterface) { $entity = $injectedData; @@ -280,7 +280,6 @@ private function mergeWithAssociatedData(EntityInterface $entity): self private function mergeWithToOne(EntityInterface $entity, string $associationName, array $data) { $count = count($data); - $associationName = Inflector::singularize($associationName); /** @var BaseFactory $factory */ $factory = $data[$count - 1]; @@ -348,7 +347,7 @@ public function getMarshallerAssociationName(string $associationName): string $result = []; $cast = explode('.', $associationName); $table = $this->getFactory()->getRootTableRegistry(); - foreach ($cast as $i => $ass) { + foreach ($cast as $ass) { $association = $table->getAssociation($ass); $result[] = $association->getProperty(); $table = $association->getTarget(); diff --git a/src/Factory/FactoryAwareTrait.php b/src/Factory/FactoryAwareTrait.php new file mode 100644 index 00000000..ab723ca8 --- /dev/null +++ b/src/Factory/FactoryAwareTrait.php @@ -0,0 +1,89 @@ +getFactoryClassName($name); + + if (class_exists($factoryClassName)) { + return $factoryClassName::make(...$arguments); + } + + throw new FactoryNotFoundException("Unable to locate factory class $factoryClassName"); + } + + /** + * Converts factory or model name to a fully qualified factory class name + * + * @param string $name Factory or model name + * @return string Fully qualified class name + */ + public function getFactoryClassName(string $name): string + { + // phpcs:disable + @[$modelName, $plugin] = array_reverse(explode('.', $name)); + // phpcs:enable + + return $this->getFactoryNamespace($plugin) . '\\' . $this->getFactoryNameFromModelName($modelName); + } + + /** + * Returns the factory file name + * + * @param string $name [description] + * @return string [description] + */ + public function getFactoryFileName(string $name): string + { + return $this->getFactoryNameFromModelName($name) . '.php'; + } + + /** + * Return the name of the factory from a model name + * + * @param string $modelName Name of the model + * @return string + */ + public static function getFactoryNameFromModelName(string $modelName): string + { + return Inflector::singularize(ucfirst($modelName)) . 'Factory'; + } + + /** + * Namespace where the factory belongs + * + * @param string|null $plugin name of the plugin, or null if no plugin + * @return string + */ + public function getFactoryNamespace(?string $plugin = null): string + { + if (Configure::check('TestFixtureNamespace')) { + return Configure::read('TestFixtureNamespace'); + } else { + return ( + $plugin ? + str_replace('/', '\\', $plugin) : + Configure::read('App.namespace', 'App') + ) . '\Test\Factory'; + } + } +} diff --git a/tests/TestCase/Factory/BaseFactoryAssociationsTest.php b/tests/TestCase/Factory/BaseFactoryAssociationsTest.php index 6b87c4f9..27c1dc34 100644 --- a/tests/TestCase/Factory/BaseFactoryAssociationsTest.php +++ b/tests/TestCase/Factory/BaseFactoryAssociationsTest.php @@ -27,7 +27,6 @@ use CakephpFixtureFactories\Test\Factory\CityFactory; use CakephpFixtureFactories\Test\Factory\CountryFactory; use CakephpFixtureFactories\Test\Factory\CustomerFactory; -use CakephpFixtureFactories\Util; use Exception; use TestApp\Model\Entity\Address; use TestApp\Model\Entity\City; @@ -731,4 +730,28 @@ public function testReproduceIssue84WithArticlesAuthors() $this->assertSame(10, $this->AuthorsTable->find()->count()); $this->assertSame(2, $this->BillsTable->find()->count()); } + + public function testCompileEntityForToOneAssociation() + { + $this->CitiesTable->addAssociations([ + 'belongsTo' => [ + 'Countries' + ], + ]); + $name = 'FooCountry'; + $factories = [ + CityFactory::makeWithModelEvents()->with('Country', compact('name')), + CityFactory::makeWithModelEvents()->with('Countries', compact('name')), + CityFactory::makeWithModelEvents()->with('Country')->with('Countries', compact('name')), + CityFactory::makeWithModelEvents()->with('Country', ['name' => 'Foo'])->with('Countries', compact('name')), + ]; + + foreach ($factories as $factory) { + $entity = $factory->getEntity(); + $this->assertSame($name, $entity->country->name); + $this->assertSame(null, $entity->countries); + } + + TableRegistry::getTableLocator()->clear(); + } } From 2f943cc85f850a9d38f2cc0485cb93bee03715ab Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Wed, 9 Jun 2021 18:40:07 +0200 Subject: [PATCH 5/6] Issue #87 Add arguments to ::find() --- src/Factory/BaseFactory.php | 8 +++++--- tests/TestCase/Factory/BaseFactoryStaticFinderTest.php | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Factory/BaseFactory.php b/src/Factory/BaseFactory.php index 702653b9..09b3c3f8 100644 --- a/src/Factory/BaseFactory.php +++ b/src/Factory/BaseFactory.php @@ -562,11 +562,13 @@ public function mergeAssociated(array $data): self /** * Query the factory's related table without before find. * - * @return \Cake\ORM\Query + * @param string $type the type of query to perform + * @param array $options An array that will be passed to Query::applyOptions() + * @return \Cake\ORM\Query The query builder */ - public static function find(): Query + public static function find(string $type = 'all', array $options = []): Query { - return self::make()->getTable()->find(); + return self::make()->getTable()->find($type, $options); } /** diff --git a/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php b/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php index 76f634c0..afb24e94 100644 --- a/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php +++ b/tests/TestCase/Factory/BaseFactoryStaticFinderTest.php @@ -53,7 +53,7 @@ public function testBaseFactoryStaticFind() ArticleFactory::make(2)->unpublished()->persist(); $this->assertSame([], $this->Articles->find()->toArray()); $this->assertSame($n, ArticleFactory::find()->count()); - $this->assertSame(0, ArticleFactory::find()->find('published')->count()); + $this->assertSame(0, ArticleFactory::find('published')->count()); $this->assertSame($n, ArticleFactory::count()); } } From 1c75db633055d30e162cc9a94085797012c97fbe Mon Sep 17 00:00:00 2001 From: Juan Pablo Ramirez Date: Wed, 9 Jun 2021 18:33:47 +0200 Subject: [PATCH 6/6] Issue #75 add a test for nested scenarii --- README.md | 22 +++++++++++++++ .../FiveAustralianAuthorsScenario.php | 12 +++++++- .../Scenario/TenAustralianAuthorsScenario.php | 28 +++++++++++++++++++ .../TestCase/Scenario/FixtureScenarioTest.php | 26 ++++++++++------- 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 tests/Scenario/TenAustralianAuthorsScenario.php diff --git a/README.md b/README.md index af81d179..a21abdb6 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,28 @@ Here is a quick example, detailed in this section: $article = ArticleFactory::make(5)->with('Authors[3].Address.City.Country', ['name' => 'Kenya'])->persist(); ``` +#### On the command line: +Factories can also conveniently populate your database in order to test your application on the browser. +The following command will persist 5 articles, each with 3 irish authors, considering that the `ArticleFactory` class features +a `withThreeIrishAuthors()` method: +```$xslt +bin/cake fixture_factories_persist Authors -n 5 -m withThreeIrishAuthors +``` +The option `--dry-run` or `-d` will display the output without persisting. +The option `-c` will persist in the connection provided (default is `test`). +The option `-w` will create associated fixtures. + +The `fixture_factories_persist` command is featured on CakePHP 4 only (open to contribution for CakePHP 3). + +#### Scenarios: + +You can create scenarios that will persist a multitude of test fixtures. Use the `CakephpFixtureFactories\Scenario\ScenarioAwareTrait` +in your test and load your scenario with the `loadFixtureScenario()` method. You can either provide the +fully qualified name of the scenario class, or place your scenarios under the `App\Test\Scenario` namespace. + +Scenarios should implement the `CakephpFixtureFactories\Scenario\FixtureScenarioInterface` class. +[This test](tests/TestCase/Scenario/FixtureScenarioTest.php) provides an example on how to use scenarios. + ## [Test Lifecycle](docs/lifecycle.md) The only step performed by the package's test suite is to truncate *dirty* tables before each test. diff --git a/tests/Scenario/FiveAustralianAuthorsScenario.php b/tests/Scenario/FiveAustralianAuthorsScenario.php index 065b846b..24d2d76f 100644 --- a/tests/Scenario/FiveAustralianAuthorsScenario.php +++ b/tests/Scenario/FiveAustralianAuthorsScenario.php @@ -1,6 +1,16 @@ loadFixtureScenario(FiveAustralianAuthorsScenario::class); + $this->loadFixtureScenario(FiveAustralianAuthorsScenario::class); + } +} diff --git a/tests/TestCase/Scenario/FixtureScenarioTest.php b/tests/TestCase/Scenario/FixtureScenarioTest.php index 84fc3059..ff39efa4 100644 --- a/tests/TestCase/Scenario/FixtureScenarioTest.php +++ b/tests/TestCase/Scenario/FixtureScenarioTest.php @@ -22,6 +22,7 @@ use CakephpFixtureFactories\Error\FixtureScenarioException; use CakephpFixtureFactories\Scenario\ScenarioAwareTrait; use CakephpFixtureFactories\Test\Scenario\FiveAustralianAuthorsScenario; +use CakephpFixtureFactories\Test\Scenario\TenAustralianAuthorsScenario; class FixtureScenarioTest extends TestCase { @@ -57,24 +58,20 @@ public function tearDown(): void public function scenarioNames(): array { return [ - ['FiveAustralianAuthors'], - [FiveAustralianAuthorsScenario::class], + ['FiveAustralianAuthors', FiveAustralianAuthorsScenario::N], + [FiveAustralianAuthorsScenario::class, FiveAustralianAuthorsScenario::N], + ['TenAustralianAuthors', 2*FiveAustralianAuthorsScenario::N], + [TenAustralianAuthorsScenario::class, 2*FiveAustralianAuthorsScenario::N], ]; } /** * @dataProvider scenarioNames */ - public function testLoadScenario($scenario) + public function testLoadScenario($scenario, int $expectedAuthors) { $this->loadFixtureScenario($scenario); - - $australianAuthors = $this->AuthorsTable->find() - ->innerJoinWith('Address.City.Country', function (Query $q) { - return $q->where(['Country.name' => FiveAustralianAuthorsScenario::COUNTRY_NAME]); - }) - ->count(); - $this->assertSame(FiveAustralianAuthorsScenario::N, $australianAuthors); + $this->assertSame($expectedAuthors, $this->countAustralianAuthors()); } public function testLoadScenarioException() @@ -82,4 +79,13 @@ public function testLoadScenarioException() $this->expectException(FixtureScenarioException::class); $this->loadFixtureScenario(self::class); } + + private function countAustralianAuthors(): int + { + return $this->AuthorsTable->find() + ->innerJoinWith('Address.City.Country', function (Query $q) { + return $q->where(['Country.name' => FiveAustralianAuthorsScenario::COUNTRY_NAME]); + }) + ->count(); + } }