From 5830679a97b5d9093d570243bdc523b1d74e2502 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Fri, 3 Mar 2023 20:49:52 +0530 Subject: [PATCH 01/11] Add Implementation for https://github.com/cebe/yii2-app-api/issues/17 - WIP --- src/generator/default/faker.php | 2 +- src/lib/FakerStubResolver.php | 10 ++ .../relations_in_faker/relations_in_faker.php | 13 +++ .../relations_in_faker.yaml | 104 ++++++++++++++++++ tests/unit/RelationsInFakerTest.php | 25 +++++ 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 tests/specs/relations_in_faker/relations_in_faker.php create mode 100644 tests/specs/relations_in_faker/relations_in_faker.yaml create mode 100644 tests/unit/RelationsInFakerTest.php diff --git a/src/generator/default/faker.php b/src/generator/default/faker.php index 633d61c8..8babf30c 100644 --- a/src/generator/default/faker.php +++ b/src/generator/default/faker.php @@ -45,7 +45,7 @@ public function generateModel($attributes = []) $uniqueFaker = $this->uniqueFaker; $model = new getClassName() ?>(); attributes as $attribute): - if (!$attribute->fakerStub || $attribute->isReference()) { + if (!$attribute->fakerStub /*|| $attribute->isReference()*/) { continue; } ?> diff --git a/src/lib/FakerStubResolver.php b/src/lib/FakerStubResolver.php index 8686ac61..a52d61cc 100644 --- a/src/lib/FakerStubResolver.php +++ b/src/lib/FakerStubResolver.php @@ -46,6 +46,16 @@ public function resolve():?string if ($this->attribute->isReadOnly() && $this->attribute->isVirtual()) { return null; } + + VarDumper::dump('Property: '.$this->attribute->propertyName); + VarDumper::dump('Column: '.$this->attribute->columnName); + + // column name ends with `_id` + if (substr($this->attribute->columnName, -strlen('_id'))==='_id') { + VarDumper::dump('Yes'); + return '$faker->randomElement(\app\models\User::find()->select("id")->column())'; // TODO class and class namespace + } + $limits = $this->attribute->limits; switch ($this->attribute->phpType) { case 'bool': diff --git a/tests/specs/relations_in_faker/relations_in_faker.php b/tests/specs/relations_in_faker/relations_in_faker.php new file mode 100644 index 00000000..f53fc389 --- /dev/null +++ b/tests/specs/relations_in_faker/relations_in_faker.php @@ -0,0 +1,13 @@ + '@specs/relations_in_faker/relations_in_faker.yaml', + 'generateUrls' => false, + 'generateModels' => true, + 'excludeModels' => [ + 'Error', + ], + 'generateControllers' => false, + 'generateMigrations' => true, + 'generateModelFaker' => true, +]; diff --git a/tests/specs/relations_in_faker/relations_in_faker.yaml b/tests/specs/relations_in_faker/relations_in_faker.yaml new file mode 100644 index 00000000..09df928b --- /dev/null +++ b/tests/specs/relations_in_faker/relations_in_faker.yaml @@ -0,0 +1,104 @@ +openapi: 3.0.3 +info: + title: 'Proxy-Service' + description: "" + version: 1.0.0 + contact: + name: 'Carsten Brandt' + email: cb@cebe.cloud +servers: + - url: 'http://localhost:8937' + description: 'Local Dev API' +security: + - BasicAuth: [] +components: + securitySchemes: + BasicAuth: + type: http + scheme: basic + schemas: + Account: + description: user account + type: object + required: + - id + - name + properties: + id: + type: integer + name: + description: account name + type: string + maxLength: 40 + x-faker: 'substr($faker->userName(), 0, 40)' + + Domain: + description: domain + type: object + required: + - id + - name + - account + - created_at + properties: + id: + type: integer + name: + description: domain or sub-domain name, in DNS syntax, IDN are converted + type: string + maxLength: 128 + x-faker: '$faker->domainName' + account: + $ref: '#/components/schemas/Account' + + routings: + type: array + items: + $ref: '#/components/schemas/Routing' + + created_at: + readOnly: true + type: string + format: datetime + x-db-type: datetime + nullable: false + + Routing: + description: rounting specification + type: object + required: + - id + - domain + properties: + id: + type: integer + domain: + $ref: '#/components/schemas/Domain' + path: + type: string + maxLength: 255 + x-faker: '$faker->randomElement(["/", "/", "/", "/", "/api", "/tools", "/assets/web"])' + + ssl: + type: boolean + redirect_to_ssl: + type: boolean + + service: + type: string + maxLength: 255 + x-faker: '"http://tador.cebe.net/" . $faker->domainName' + + created_at: + readOnly: true + type: string + format: datetime + x-db-type: datetime + nullable: true + + +paths: + /: + get: + responses: [] + description: none diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php new file mode 100644 index 00000000..103e52e2 --- /dev/null +++ b/tests/unit/RelationsInFakerTest.php @@ -0,0 +1,25 @@ +runGenerator($testFile, 'mysql'); + } +} From ad2273eac4999b64dd5522217b3a3d3753a46708 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Thu, 16 Mar 2023 19:58:21 +0530 Subject: [PATCH 02/11] Sorting models as per relations dependencies WIP --- src/generator/default/faker.php | 20 ++++++ src/lib/FakerStubResolver.php | 6 +- src/lib/generators/ModelsGenerator.php | 1 + .../relations_in_faker.yaml | 61 +++++++++++++++++ tests/unit/RelationsInFakerTest.php | 68 ++++++++++++++++++- 5 files changed, 152 insertions(+), 4 deletions(-) diff --git a/src/generator/default/faker.php b/src/generator/default/faker.php index 8babf30c..01153e12 100644 --- a/src/generator/default/faker.php +++ b/src/generator/default/faker.php @@ -10,6 +10,13 @@ ?> +name) ?> +hasOneRelations['account'])) { +// \yii\helpers\VarDumper::dump($model->hasOneRelations['account']->getClassName()); +// } +?> + namespace ; use Faker\UniqueGenerator; @@ -62,4 +69,17 @@ public function generateModel($attributes = []) } return $model; } + +hasOneRelations):?> + public static function dependentOn() + { + return [ + // model class name +hasOneRelations as $key => $hasOneRelation): ?> + hasOneRelations[$key]->getClassName()).','.PHP_EOL ?> + + + ]; + } + } diff --git a/src/lib/FakerStubResolver.php b/src/lib/FakerStubResolver.php index a52d61cc..99274213 100644 --- a/src/lib/FakerStubResolver.php +++ b/src/lib/FakerStubResolver.php @@ -47,12 +47,12 @@ public function resolve():?string return null; } - VarDumper::dump('Property: '.$this->attribute->propertyName); - VarDumper::dump('Column: '.$this->attribute->columnName); + // VarDumper::dump('Property: '.$this->attribute->propertyName); + // VarDumper::dump('Column: '.$this->attribute->columnName); // column name ends with `_id` if (substr($this->attribute->columnName, -strlen('_id'))==='_id') { - VarDumper::dump('Yes'); + // VarDumper::dump('Yes'); return '$faker->randomElement(\app\models\User::find()->select("id")->column())'; // TODO class and class namespace } diff --git a/src/lib/generators/ModelsGenerator.php b/src/lib/generators/ModelsGenerator.php index 72cf61f4..65c71f04 100644 --- a/src/lib/generators/ModelsGenerator.php +++ b/src/lib/generators/ModelsGenerator.php @@ -77,6 +77,7 @@ public function generate():CodeFiles 'model' => $model, 'modelNamespace' => $this->config->modelNamespace, 'namespace' => $this->config->fakerNamespace, + 'abc' => 'the-abc' // TODO remove ] ) )); diff --git a/tests/specs/relations_in_faker/relations_in_faker.yaml b/tests/specs/relations_in_faker/relations_in_faker.yaml index 09df928b..2dcbd70f 100644 --- a/tests/specs/relations_in_faker/relations_in_faker.yaml +++ b/tests/specs/relations_in_faker/relations_in_faker.yaml @@ -95,6 +95,67 @@ components: format: datetime x-db-type: datetime nullable: true + d123: + $ref: '#/components/schemas/D123' + a123: + $ref: '#/components/schemas/A123' + + D123: + description: desc + type: object + required: + - id + properties: + id: + type: integer + name: + type: string + A123: + description: desc + type: object + required: + - id + properties: + id: + type: integer + name: + type: string + b123: + $ref: '#/components/schemas/B123' + B123: + description: desc + type: object + required: + - id + properties: + id: + type: integer + name: + type: string + c123: + $ref: '#/components/schemas/C123' + C123: + description: desc + type: object + required: + - id + properties: + id: + type: integer + name: + type: string + E123: + description: desc + type: object + required: + - id + properties: + id: + type: integer + name: + type: string + b123: + $ref: '#/components/schemas/B123' paths: diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index 103e52e2..e6c0f059 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -9,6 +9,7 @@ use yii\db\pgsql\Schema as PgSqlSchema; use yii\helpers\FileHelper; use yii\helpers\VarDumper; +use yii\helpers\StringHelper; use yii\validators\DateValidator; use function array_filter; use function getenv; @@ -18,8 +19,73 @@ class RelationsInFakerTest extends DbTestCase { public function testIndex() { - // return; $testFile = Yii::getAlias("@specs/relations_in_faker/relations_in_faker.php"); $this->runGenerator($testFile, 'mysql'); + + $fakers = FileHelper::findFiles(\Yii::getAlias('@app/models'), [ + 'only' => ['*Faker.php'], + 'except' => ['BaseModelFaker.php'], + ]); + $inbSortedFakers = []; + foreach($fakers as $fakerFile) { + $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); + $faker = new $className; + + $modelClassName = str_replace( + 'Faker', + '', + StringHelper::basename($fakerFile, '.php') + ); + + if (!method_exists($className, 'dependentOn')) { + // array_unshift($inbSortedFakers, $fakerFile); + $inbSortedFakers[$modelClassName] = null; + } else { + $inbSortedFakers[$modelClassName] = $className::dependentOn(); + // array_push($inbSortedFakers, $fakerFile); + } + } + VarDumper::dump($inbSortedFakers); + $newFakers = []; + foreach ($inbSortedFakers as $modelName => $dependency) { + if ($dependency === null) { + // if (!in_array($modelName, $newFakers)) { + // array_unshift($newFakers, $modelName); + // } + if ($key = array_search($modelName, $newFakers)) { + unset($newFakers[$key]); + } + array_unshift($newFakers, $modelName); + } else { + // resolve dependencies first + static::f123($dependency, $inbSortedFakers, $newFakers); + // if (!in_array($modelName, $newFakers)) { + // array_push($newFakers, $modelName); + // } + if ($key = array_search($modelName, $newFakers)) { + unset($newFakers[$key]); + } + array_push($newFakers, $modelName); + } + } + + $this->assertNull($newFakers); + } + + public static function f123($dependency, $inbSortedFakers, &$newFakers) + { + foreach ($dependency as $aDependency) { + if ($inbSortedFakers[$aDependency] === null) { + // if (!in_array($aDependency, $newFakers)) { + // array_unshift($newFakers, $aDependency); + // } + if ($key = array_search($aDependency, $newFakers)) { + unset($newFakers[$key]); + } + array_unshift($newFakers, $aDependency); + } else { + static::f123($inbSortedFakers[$aDependency], $inbSortedFakers, $newFakers); + } + } } } From 1c84ee8319f20c65ff34939ee04f5820fd9f201b Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Sun, 19 Mar 2023 19:39:11 +0530 Subject: [PATCH 03/11] Sort models by relation dependencies --- src/generator/default/faker.php | 9 +--- tests/unit/RelationsInFakerTest.php | 79 +++++++++++++++-------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/generator/default/faker.php b/src/generator/default/faker.php index 01153e12..12d43543 100644 --- a/src/generator/default/faker.php +++ b/src/generator/default/faker.php @@ -10,13 +10,6 @@ ?> -name) ?> -hasOneRelations['account'])) { -// \yii\helpers\VarDumper::dump($model->hasOneRelations['account']->getClassName()); -// } -?> - namespace ; use Faker\UniqueGenerator; @@ -69,8 +62,8 @@ public function generateModel($attributes = []) } return $model; } - hasOneRelations):?> + public static function dependentOn() { return [ diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index e6c0f059..2fafa507 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -26,7 +26,7 @@ public function testIndex() 'only' => ['*Faker.php'], 'except' => ['BaseModelFaker.php'], ]); - $inbSortedFakers = []; + $modelsDepends = $newFakers = []; foreach($fakers as $fakerFile) { $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); $faker = new $className; @@ -38,54 +38,55 @@ public function testIndex() ); if (!method_exists($className, 'dependentOn')) { - // array_unshift($inbSortedFakers, $fakerFile); - $inbSortedFakers[$modelClassName] = null; + $modelsDepends[$modelClassName] = null; } else { - $inbSortedFakers[$modelClassName] = $className::dependentOn(); - // array_push($inbSortedFakers, $fakerFile); + $modelsDepends[$modelClassName] = $className::dependentOn(); } } - VarDumper::dump($inbSortedFakers); - $newFakers = []; - foreach ($inbSortedFakers as $modelName => $dependency) { - if ($dependency === null) { - // if (!in_array($modelName, $newFakers)) { - // array_unshift($newFakers, $modelName); - // } - if ($key = array_search($modelName, $newFakers)) { - unset($newFakers[$key]); - } - array_unshift($newFakers, $modelName); - } else { - // resolve dependencies first - static::f123($dependency, $inbSortedFakers, $newFakers); - // if (!in_array($modelName, $newFakers)) { - // array_push($newFakers, $modelName); - // } - if ($key = array_search($modelName, $newFakers)) { - unset($newFakers[$key]); + + $noDependent = array_filter($modelsDepends, function ($elm) { + return $elm === null; + }); + + $dependent = array_filter($modelsDepends, function ($elm) { + return $elm !== null; + }); + + $justDepenentModels = array_keys($dependent); + $justDepenentModelsClone = $justDepenentModels; + + + foreach ($justDepenentModels as $model) { + if ($modelsDepends[$model] !== null) { + foreach ($modelsDepends[$model] as $dependentOn) { + if ($modelsDepends[$dependentOn] !== null) { + // move $dependentOn before $model in clone + + // d123 + // in that function if it is already before (sorted) then avoid it + static::d123($justDepenentModelsClone, $dependentOn, $model); + } } - array_push($newFakers, $modelName); } } - $this->assertNull($newFakers); + $this->assertNull($justDepenentModelsClone); } - public static function f123($dependency, $inbSortedFakers, &$newFakers) + public static function d123(&$justDepenentModelsClone, $dependentOn, $model) { - foreach ($dependency as $aDependency) { - if ($inbSortedFakers[$aDependency] === null) { - // if (!in_array($aDependency, $newFakers)) { - // array_unshift($newFakers, $aDependency); - // } - if ($key = array_search($aDependency, $newFakers)) { - unset($newFakers[$key]); - } - array_unshift($newFakers, $aDependency); - } else { - static::f123($inbSortedFakers[$aDependency], $inbSortedFakers, $newFakers); - } + $modelKey = array_search($model, $justDepenentModelsClone); + $depKey = array_search($dependentOn, $justDepenentModelsClone); + if ($depKey < $modelKey) { + return; } + + unset($justDepenentModelsClone[$depKey]); + + $restRight = array_slice($justDepenentModelsClone, $modelKey); + $theKey = (($modelKey) < 0) ? 0 : ($modelKey); + $restLeft = array_slice($justDepenentModelsClone, 0, $theKey); + + $justDepenentModelsClone = array_merge($restLeft, [$dependentOn], $restRight); } } From 493aeb43483bc63e72d6753f6b3e35fe4f3fd4b8 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Sun, 19 Mar 2023 20:00:31 +0530 Subject: [PATCH 04/11] Rename variable names --- tests/unit/RelationsInFakerTest.php | 39 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index 2fafa507..7e8368b4 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -26,7 +26,7 @@ public function testIndex() 'only' => ['*Faker.php'], 'except' => ['BaseModelFaker.php'], ]); - $modelsDepends = $newFakers = []; + $modelsDependencies = []; foreach($fakers as $fakerFile) { $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); $faker = new $className; @@ -38,55 +38,56 @@ public function testIndex() ); if (!method_exists($className, 'dependentOn')) { - $modelsDepends[$modelClassName] = null; + $modelsDependencies[$modelClassName] = null; } else { - $modelsDepends[$modelClassName] = $className::dependentOn(); + $modelsDependencies[$modelClassName] = $className::dependentOn(); } } - $noDependent = array_filter($modelsDepends, function ($elm) { + $standalone = array_filter($modelsDependencies, function ($elm) { return $elm === null; }); - $dependent = array_filter($modelsDepends, function ($elm) { + $dependent = array_filter($modelsDependencies, function ($elm) { return $elm !== null; }); $justDepenentModels = array_keys($dependent); - $justDepenentModelsClone = $justDepenentModels; + $sortedDependentModels = $justDepenentModels; foreach ($justDepenentModels as $model) { - if ($modelsDepends[$model] !== null) { - foreach ($modelsDepends[$model] as $dependentOn) { - if ($modelsDepends[$dependentOn] !== null) { + if ($modelsDependencies[$model] !== null) { + foreach ($modelsDependencies[$model] as $dependentOn) { + if ($modelsDependencies[$dependentOn] !== null) { // move $dependentOn before $model in clone - // d123 + // moveModel // in that function if it is already before (sorted) then avoid it - static::d123($justDepenentModelsClone, $dependentOn, $model); + static::moveModel($sortedDependentModels, $dependentOn, $model); } } } } - $this->assertNull($justDepenentModelsClone); + $finalSortedModels = array_merge(array_keys($standalone), $sortedDependentModels); + $this->assertNull($finalSortedModels); } - public static function d123(&$justDepenentModelsClone, $dependentOn, $model) + public static function moveModel(&$sortedDependentModels, $dependentOn, $model) { - $modelKey = array_search($model, $justDepenentModelsClone); - $depKey = array_search($dependentOn, $justDepenentModelsClone); + $modelKey = array_search($model, $sortedDependentModels); + $depKey = array_search($dependentOn, $sortedDependentModels); if ($depKey < $modelKey) { return; } - unset($justDepenentModelsClone[$depKey]); + unset($sortedDependentModels[$depKey]); - $restRight = array_slice($justDepenentModelsClone, $modelKey); + $restRight = array_slice($sortedDependentModels, $modelKey); $theKey = (($modelKey) < 0) ? 0 : ($modelKey); - $restLeft = array_slice($justDepenentModelsClone, 0, $theKey); + $restLeft = array_slice($sortedDependentModels, 0, $theKey); - $justDepenentModelsClone = array_merge($restLeft, [$dependentOn], $restRight); + $sortedDependentModels = array_merge($restLeft, [$dependentOn], $restRight); } } From 43d82e0661b704349cb3504505e85963fde9ccff Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Sun, 19 Mar 2023 21:20:52 +0530 Subject: [PATCH 05/11] Reflect model namespace in FakerStubResolver --- src/lib/AttributeResolver.php | 13 +++++++++---- src/lib/FakerStubResolver.php | 13 +++++++------ src/lib/SchemaToDatabase.php | 2 +- tests/unit/RelationsInFakerTest.php | 2 ++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/lib/AttributeResolver.php b/src/lib/AttributeResolver.php index 401b650f..8168f9ac 100644 --- a/src/lib/AttributeResolver.php +++ b/src/lib/AttributeResolver.php @@ -7,6 +7,7 @@ namespace cebe\yii2openapi\lib; +use cebe\yii2openapi\lib\Config; use cebe\yii2openapi\lib\CustomSpecAttr; use cebe\yii2openapi\lib\exceptions\InvalidDefinitionException; use cebe\yii2openapi\lib\items\Attribute; @@ -66,13 +67,16 @@ class AttributeResolver */ private $junctions; - /**@var bool */ + /** @var bool */ private $isJunctionSchema; - /**@var bool */ + /** @var bool */ private $hasMany2Many; - public function __construct(string $schemaName, ComponentSchema $schema, JunctionSchemas $junctions) + /** @var Config */ + private $config; + + public function __construct(string $schemaName, ComponentSchema $schema, JunctionSchemas $junctions, ?Config $config = null) { $this->schemaName = $schemaName; $this->schema = $schema; @@ -80,6 +84,7 @@ public function __construct(string $schemaName, ComponentSchema $schema, Junctio $this->junctions = $junctions; $this->isJunctionSchema = $junctions->isJunctionSchema($schemaName); $this->hasMany2Many = $junctions->hasMany2Many($schemaName); + $this->config = $config; } /** @@ -391,7 +396,7 @@ protected function catchManyToMany( */ protected function guessFakerStub(Attribute $attribute, PropertySchema $property):?string { - $resolver = Yii::createObject(['class' => FakerStubResolver::class], [$attribute, $property]); + $resolver = Yii::createObject(['class' => FakerStubResolver::class], [$attribute, $property, $this->config]); return $resolver->resolve(); } diff --git a/src/lib/FakerStubResolver.php b/src/lib/FakerStubResolver.php index 99274213..f04241a2 100644 --- a/src/lib/FakerStubResolver.php +++ b/src/lib/FakerStubResolver.php @@ -32,10 +32,14 @@ class FakerStubResolver */ private $property; - public function __construct(Attribute $attribute, PropertySchema $property) + /** @var Config */ + private $config; + + public function __construct(Attribute $attribute, PropertySchema $property, ?Config $config = null) { $this->attribute = $attribute; $this->property = $property; + $this->config = $config; } public function resolve():?string @@ -47,13 +51,10 @@ public function resolve():?string return null; } - // VarDumper::dump('Property: '.$this->attribute->propertyName); - // VarDumper::dump('Column: '.$this->attribute->columnName); - // column name ends with `_id` if (substr($this->attribute->columnName, -strlen('_id'))==='_id') { - // VarDumper::dump('Yes'); - return '$faker->randomElement(\app\models\User::find()->select("id")->column())'; // TODO class and class namespace + return '$faker->randomElement(\\'.$this->config->modelNamespace + .'\\'.ucfirst($this->attribute->propertyName).'::find()->select("id")->column())'; } $limits = $this->attribute->limits; diff --git a/src/lib/SchemaToDatabase.php b/src/lib/SchemaToDatabase.php index 47dbdb58..0e93ff29 100644 --- a/src/lib/SchemaToDatabase.php +++ b/src/lib/SchemaToDatabase.php @@ -89,7 +89,7 @@ public function prepareModels():array $schemaName = $junctions->trimPrefix($schemaName); } /**@var \cebe\yii2openapi\lib\AttributeResolver $resolver */ - $resolver = Yii::createObject(AttributeResolver::class, [$schemaName, $schema, $junctions]); + $resolver = Yii::createObject(AttributeResolver::class, [$schemaName, $schema, $junctions, $this->config]); $models[$schemaName] = $resolver->resolve(); } foreach ($models as $model) { diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index 7e8368b4..9f2c4fd0 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -26,6 +26,8 @@ public function testIndex() 'only' => ['*Faker.php'], 'except' => ['BaseModelFaker.php'], ]); + + // ---- $modelsDependencies = []; foreach($fakers as $fakerFile) { $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); From 0e2b3d76ca5e02f81c311a810f6c9e1e7a490850 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Sun, 19 Mar 2023 21:48:21 +0530 Subject: [PATCH 06/11] WIP --- tests/unit/RelationsInFakerTest.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index 9f2c4fd0..e338a5e8 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -27,10 +27,27 @@ public function testIndex() 'except' => ['BaseModelFaker.php'], ]); + $finalSortedModels = static::sortModels($fakers); + + $this->assertSame($finalSortedModels, [ + 'Account', + 'C123', + 'D123', + 'B123', + 'E123', + 'Domain', + 'A123', + 'Routing', + ]); + } + + // TODO faker namespace + public static function sortModels(array $fakers) + { // ---- $modelsDependencies = []; foreach($fakers as $fakerFile) { - $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); + $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); // TODO $faker = new $className; $modelClassName = str_replace( @@ -64,7 +81,7 @@ public function testIndex() if ($modelsDependencies[$dependentOn] !== null) { // move $dependentOn before $model in clone - // moveModel + // move model to sort/order // in that function if it is already before (sorted) then avoid it static::moveModel($sortedDependentModels, $dependentOn, $model); } @@ -73,7 +90,7 @@ public function testIndex() } $finalSortedModels = array_merge(array_keys($standalone), $sortedDependentModels); - $this->assertNull($finalSortedModels); + return $finalSortedModels; } public static function moveModel(&$sortedDependentModels, $dependentOn, $model) From 61f8fba7bf209e90148e9af7f1b2d170ee228f01 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 20 Mar 2023 18:02:44 +0530 Subject: [PATCH 07/11] Move sort order to yii2-app-api + make proper namespaces where needed + WIP --- src/generator/default/faker.php | 2 +- src/lib/generators/ModelsGenerator.php | 1 - .../relations_in_faker/relations_in_faker.php | 2 ++ .../relations_in_faker.yaml | 34 +++++++++++++++++++ tests/unit/RelationsInFakerTest.php | 11 +++--- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/generator/default/faker.php b/src/generator/default/faker.php index 12d43543..174d4c11 100644 --- a/src/generator/default/faker.php +++ b/src/generator/default/faker.php @@ -43,7 +43,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new getClassName() ?>(); + $model = new (); attributes as $attribute): if (!$attribute->fakerStub /*|| $attribute->isReference()*/) { continue; diff --git a/src/lib/generators/ModelsGenerator.php b/src/lib/generators/ModelsGenerator.php index 65c71f04..72cf61f4 100644 --- a/src/lib/generators/ModelsGenerator.php +++ b/src/lib/generators/ModelsGenerator.php @@ -77,7 +77,6 @@ public function generate():CodeFiles 'model' => $model, 'modelNamespace' => $this->config->modelNamespace, 'namespace' => $this->config->fakerNamespace, - 'abc' => 'the-abc' // TODO remove ] ) )); diff --git a/tests/specs/relations_in_faker/relations_in_faker.php b/tests/specs/relations_in_faker/relations_in_faker.php index f53fc389..260580c2 100644 --- a/tests/specs/relations_in_faker/relations_in_faker.php +++ b/tests/specs/relations_in_faker/relations_in_faker.php @@ -10,4 +10,6 @@ 'generateControllers' => false, 'generateMigrations' => true, 'generateModelFaker' => true, + 'modelNamespace' => 'app\\models', + 'fakerNamespace' => 'app\\models\\fakers', ]; diff --git a/tests/specs/relations_in_faker/relations_in_faker.yaml b/tests/specs/relations_in_faker/relations_in_faker.yaml index 2dcbd70f..2f88bdea 100644 --- a/tests/specs/relations_in_faker/relations_in_faker.yaml +++ b/tests/specs/relations_in_faker/relations_in_faker.yaml @@ -163,3 +163,37 @@ paths: get: responses: [] description: none + + + +# Dependencies: +# 'E123' => [ +# 0 => 'B123' +# ] +# 'Account' => null +# 'C123' => null +# 'Domain' => [ +# 0 => 'Account' +# ] +# 'B123' => [ +# 0 => 'C123' +# ] +# 'Routing' => [ +# 0 => 'Domain' +# 1 => 'D123' +# 2 => 'A123' +# ] +# 'D123' => null +# 'A123' => [ +# 0 => 'B123' +# ] + +# Sorted: +# 'Account', +# 'C123', +# 'D123', +# 'B123', +# 'E123', +# 'Domain', +# 'A123', +# 'Routing', diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index e338a5e8..0770a6a5 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -22,7 +22,7 @@ public function testIndex() $testFile = Yii::getAlias("@specs/relations_in_faker/relations_in_faker.php"); $this->runGenerator($testFile, 'mysql'); - $fakers = FileHelper::findFiles(\Yii::getAlias('@app/models'), [ + $fakers = FileHelper::findFiles(\Yii::getAlias('@app/models/fakers'), [ 'only' => ['*Faker.php'], 'except' => ['BaseModelFaker.php'], ]); @@ -41,13 +41,11 @@ public function testIndex() ]); } - // TODO faker namespace - public static function sortModels(array $fakers) + public static function sortModels(array $fakers, string $fakerNamespace = 'app\\models\\fakers\\') { - // ---- $modelsDependencies = []; foreach($fakers as $fakerFile) { - $className = 'app\\models\\' . StringHelper::basename($fakerFile, '.php'); // TODO + $className = $fakerNamespace . StringHelper::basename($fakerFile, '.php'); // TODO $faker = new $className; $modelClassName = str_replace( @@ -74,12 +72,11 @@ public static function sortModels(array $fakers) $justDepenentModels = array_keys($dependent); $sortedDependentModels = $justDepenentModels; - foreach ($justDepenentModels as $model) { if ($modelsDependencies[$model] !== null) { foreach ($modelsDependencies[$model] as $dependentOn) { if ($modelsDependencies[$dependentOn] !== null) { - // move $dependentOn before $model in clone + // move $dependentOn before $model // move model to sort/order // in that function if it is already before (sorted) then avoid it From a79e5f5a3ba0aeb3d7956f5a4d8d2adc51bedfc3 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 20 Mar 2023 20:48:07 +0530 Subject: [PATCH 08/11] Adjust existing tests as per new changes in Faker generation --- src/generator/default/faker.php | 2 +- src/lib/FakerStubResolver.php | 3 ++- tests/DbTestCase.php | 2 +- tests/fixtures/blog.php | 8 ++++---- tests/specs/blog/models/CommentFaker.php | 12 ++++++++++++ tests/specs/blog/models/PostFaker.php | 12 ++++++++++++ tests/specs/blog_v2/models/CommentFaker.php | 12 ++++++++++++ tests/specs/blog_v2/models/PostFaker.php | 12 ++++++++++++ tests/specs/many2many/models/Photos2PostsFaker.php | 12 ++++++++++++ tests/specs/many2many/models/PostsAttachesFaker.php | 12 ++++++++++++ tests/specs/many2many/models/PostsGalleryFaker.php | 12 ++++++++++++ tests/specs/menu/models/MenuFaker.php | 10 ++++++++++ tests/specs/petstore/models/PetFaker.php | 10 ++++++++++ .../petstore_namespace/mymodels/faker/PetFaker.php | 12 +++++++++++- .../petstore_namespace/mymodels/faker/StoreFaker.php | 2 +- .../app/models/mariafaker/AlldbdatatypeFaker.php | 2 +- .../maria/app/models/mariafaker/EditcolumnFaker.php | 2 +- .../maria/app/models/mariafaker/NewcolumnFaker.php | 2 +- .../maria/app/models/mariafaker/PristineFaker.php | 2 +- .../app/models/pgsqlfaker/AlldbdatatypeFaker.php | 2 +- .../pgsql/app/models/pgsqlfaker/EditcolumnFaker.php | 2 +- .../pgsql/app/models/pgsqlfaker/NewcolumnFaker.php | 2 +- .../pgsql/app/models/pgsqlfaker/PristineFaker.php | 2 +- tests/unit/GeneratorTest.php | 5 +++++ tests/unit/MultiDbFreshMigrationTest.php | 2 +- tests/unit/RelationsInFakerTest.php | 5 ++++- 26 files changed, 142 insertions(+), 19 deletions(-) diff --git a/src/generator/default/faker.php b/src/generator/default/faker.php index 174d4c11..a555d679 100644 --- a/src/generator/default/faker.php +++ b/src/generator/default/faker.php @@ -67,7 +67,7 @@ public function generateModel($attributes = []) public static function dependentOn() { return [ - // model class name + // just model class names hasOneRelations as $key => $hasOneRelation): ?> hasOneRelations[$key]->getClassName()).','.PHP_EOL ?> diff --git a/src/lib/FakerStubResolver.php b/src/lib/FakerStubResolver.php index f04241a2..fb71ad27 100644 --- a/src/lib/FakerStubResolver.php +++ b/src/lib/FakerStubResolver.php @@ -54,7 +54,8 @@ public function resolve():?string // column name ends with `_id` if (substr($this->attribute->columnName, -strlen('_id'))==='_id') { return '$faker->randomElement(\\'.$this->config->modelNamespace - .'\\'.ucfirst($this->attribute->propertyName).'::find()->select("id")->column())'; + . ($this->config->modelNamespace ? '\\' : '') + . ucfirst($this->attribute->reference).'::find()->select("id")->column())'; } $limits = $this->attribute->limits; diff --git a/tests/DbTestCase.php b/tests/DbTestCase.php index ed5be0e0..1c668240 100644 --- a/tests/DbTestCase.php +++ b/tests/DbTestCase.php @@ -101,7 +101,7 @@ protected function checkFiles(array $actual, array $expected) self::assertFileExists($file); self::assertFileExists($expectedFilePath); - $this->assertFileEquals($expectedFilePath, $file, "Failed asserting that file contents of\n$file\nare equal to file contents of\n$expectedFilePath"); + $this->assertFileEquals($expectedFilePath, $file, "Failed asserting that file contents of\n$file\nare equal to file contents of\n$expectedFilePath \n\n cp $file $expectedFilePath \n\n "); } } diff --git a/tests/fixtures/blog.php b/tests/fixtures/blog.php index ecdb3bf7..9fa874a5 100644 --- a/tests/fixtures/blog.php +++ b/tests/fixtures/blog.php @@ -73,13 +73,13 @@ ->asReference('Category') ->setRequired() ->setDescription('Category of posts') - ->setFakerStub('$uniqueFaker->numberBetween(0, 1000000)'), + ->setFakerStub('$faker->randomElement(\Category::find()->select("id")->column())'), 'created_at' => (new Attribute('created_at', ['phpType' => 'string', 'dbType' => 'date'])) ->setFakerStub('$faker->dateTimeThisCentury->format(\'Y-m-d\')'), 'created_by' => (new Attribute('created_by', ['phpType' => 'int', 'dbType' => 'integer'])) ->asReference('User') ->setDescription('The User') - ->setFakerStub('$uniqueFaker->numberBetween(0, 1000000)'), + ->setFakerStub('$faker->randomElement(\User::find()->select("id")->column())'), ], 'relations' => [ 'category' => new AttributeRelation('category', @@ -110,12 +110,12 @@ ->setSize(128) ->asReference('Post') ->setDescription('A blog post (uid used as pk for test purposes)') - ->setFakerStub('substr($uniqueFaker->sha256, 0, 128)'), + ->setFakerStub('$faker->randomElement(\Post::find()->select("id")->column())'), 'author' => (new Attribute('author', ['phpType' => 'int', 'dbType' => 'integer'])) ->setRequired() ->asReference('User') ->setDescription('The User') - ->setFakerStub('$uniqueFaker->numberBetween(0, 1000000)'), + ->setFakerStub('$faker->randomElement(\User::find()->select("id")->column())'), 'message' => (new Attribute('message', ['phpType' => 'array', 'dbType' => 'json', 'xDbType' => 'json'])) ->setRequired()->setDefault([])->setFakerStub('[]'), 'meta_data' => (new Attribute('meta_data', ['phpType' => 'array', 'dbType' => 'json', 'xDbType' => 'json'])) diff --git a/tests/specs/blog/models/CommentFaker.php b/tests/specs/blog/models/CommentFaker.php index c6a43f19..bf0f3fa6 100644 --- a/tests/specs/blog/models/CommentFaker.php +++ b/tests/specs/blog/models/CommentFaker.php @@ -30,6 +30,8 @@ public function generateModel($attributes = []) $uniqueFaker = $this->uniqueFaker; $model = new Comment(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->post_id = $faker->randomElement(\app\models\Post::find()->select("id")->column()); + $model->author_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); $model->message = []; $model->meta_data = []; $model->created_at = $faker->unixTime; @@ -40,4 +42,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Post', + 'User', + + ]; + } } diff --git a/tests/specs/blog/models/PostFaker.php b/tests/specs/blog/models/PostFaker.php index 32540642..946a284f 100644 --- a/tests/specs/blog/models/PostFaker.php +++ b/tests/specs/blog/models/PostFaker.php @@ -32,8 +32,10 @@ public function generateModel($attributes = []) $model->uid = substr($uniqueFaker->sha256, 0, 128); $model->title = substr($faker->sentence, 0, 255); $model->slug = substr($uniqueFaker->slug, 0, 200); + $model->category_id = $faker->randomElement(\app\models\Category::find()->select("id")->column()); $model->active = $faker->boolean; $model->created_at = $faker->dateTimeThisCentury->format('Y-m-d'); + $model->created_by_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { @@ -41,4 +43,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Category', + 'User', + + ]; + } } diff --git a/tests/specs/blog_v2/models/CommentFaker.php b/tests/specs/blog_v2/models/CommentFaker.php index 6c36cb24..968d1a10 100644 --- a/tests/specs/blog_v2/models/CommentFaker.php +++ b/tests/specs/blog_v2/models/CommentFaker.php @@ -30,6 +30,8 @@ public function generateModel($attributes = []) $uniqueFaker = $this->uniqueFaker; $model = new Comment(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->post_id = $faker->randomElement(\app\models\Post::find()->select("id")->column()); + $model->user_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); $model->message = $faker->sentence; $model->meta_data = substr($faker->text(300), 0, 300); $model->created_at = $faker->dateTimeThisYear('now', 'UTC')->format('Y-m-d H:i:s'); @@ -40,4 +42,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Post', + 'User', + + ]; + } } diff --git a/tests/specs/blog_v2/models/PostFaker.php b/tests/specs/blog_v2/models/PostFaker.php index a1e8eb81..8238bfb4 100644 --- a/tests/specs/blog_v2/models/PostFaker.php +++ b/tests/specs/blog_v2/models/PostFaker.php @@ -33,8 +33,10 @@ public function generateModel($attributes = []) $model->title = substr($faker->sentence, 0, 255); $model->slug = substr($uniqueFaker->slug, 0, 200); $model->lang = $faker->randomElement(['ru','eng']); + $model->category_id = $faker->randomElement(\app\models\Category::find()->select("id")->column()); $model->active = $faker->boolean; $model->created_at = $faker->dateTimeThisCentury->format('Y-m-d'); + $model->created_by_id = $faker->randomElement(\app\models\User::find()->select("id")->column()); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { @@ -42,4 +44,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Category', + 'User', + + ]; + } } diff --git a/tests/specs/many2many/models/Photos2PostsFaker.php b/tests/specs/many2many/models/Photos2PostsFaker.php index e4e125a2..b4e87ae3 100644 --- a/tests/specs/many2many/models/Photos2PostsFaker.php +++ b/tests/specs/many2many/models/Photos2PostsFaker.php @@ -30,6 +30,8 @@ public function generateModel($attributes = []) $uniqueFaker = $this->uniqueFaker; $model = new Photos2Posts(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->photo_id = $faker->randomElement(\app\models\Photo::find()->select("id")->column()); + $model->post_id = $faker->randomElement(\app\models\Post::find()->select("id")->column()); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { @@ -37,4 +39,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Photo', + 'Post', + + ]; + } } diff --git a/tests/specs/many2many/models/PostsAttachesFaker.php b/tests/specs/many2many/models/PostsAttachesFaker.php index 213c4911..18bc295a 100644 --- a/tests/specs/many2many/models/PostsAttachesFaker.php +++ b/tests/specs/many2many/models/PostsAttachesFaker.php @@ -30,6 +30,8 @@ public function generateModel($attributes = []) $uniqueFaker = $this->uniqueFaker; $model = new PostsAttaches(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->attach_id = $faker->randomElement(\app\models\Photo::find()->select("id")->column()); + $model->target_id = $faker->randomElement(\app\models\Post::find()->select("id")->column()); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); } else { @@ -37,4 +39,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Photo', + 'Post', + + ]; + } } diff --git a/tests/specs/many2many/models/PostsGalleryFaker.php b/tests/specs/many2many/models/PostsGalleryFaker.php index 7fc4fc61..972b8e0c 100644 --- a/tests/specs/many2many/models/PostsGalleryFaker.php +++ b/tests/specs/many2many/models/PostsGalleryFaker.php @@ -29,6 +29,8 @@ public function generateModel($attributes = []) $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; $model = new PostsGallery(); + $model->image_id = $faker->randomElement(\app\models\Photo::find()->select("id")->column()); + $model->article_id = $faker->randomElement(\app\models\Post::find()->select("id")->column()); $model->is_cover = $faker->boolean; if (!is_callable($attributes)) { $model->setAttributes($attributes, false); @@ -37,4 +39,14 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Photo', + 'Post', + + ]; + } } diff --git a/tests/specs/menu/models/MenuFaker.php b/tests/specs/menu/models/MenuFaker.php index 475d9f12..64e82b3b 100644 --- a/tests/specs/menu/models/MenuFaker.php +++ b/tests/specs/menu/models/MenuFaker.php @@ -31,6 +31,7 @@ public function generateModel($attributes = []) $model = new Menu(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = substr($faker->text(100), 0, 100); + $model->parent_id = $faker->randomElement(\app\models\Menu::find()->select("id")->column()); $model->args = []; $model->kwargs = []; if (!is_callable($attributes)) { @@ -40,4 +41,13 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Menu', + + ]; + } } diff --git a/tests/specs/petstore/models/PetFaker.php b/tests/specs/petstore/models/PetFaker.php index c8608e25..764d7817 100644 --- a/tests/specs/petstore/models/PetFaker.php +++ b/tests/specs/petstore/models/PetFaker.php @@ -31,6 +31,7 @@ public function generateModel($attributes = []) $model = new Pet(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = $faker->sentence; + $model->store_id = $faker->randomElement(\app\models\Store::find()->select("id")->column()); $model->tag = $faker->randomElement(['one', 'two', 'three', 'four']); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); @@ -39,4 +40,13 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Store', + + ]; + } } diff --git a/tests/specs/petstore_namespace/mymodels/faker/PetFaker.php b/tests/specs/petstore_namespace/mymodels/faker/PetFaker.php index 52991623..6080324f 100644 --- a/tests/specs/petstore_namespace/mymodels/faker/PetFaker.php +++ b/tests/specs/petstore_namespace/mymodels/faker/PetFaker.php @@ -29,9 +29,10 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Pet(); + $model = new \app\mymodels\Pet(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = $faker->sentence; + $model->store_id = $faker->randomElement(\app\mymodels\Store::find()->select("id")->column()); $model->tag = $faker->randomElement(['one', 'two', 'three', 'four']); if (!is_callable($attributes)) { $model->setAttributes($attributes, false); @@ -40,4 +41,13 @@ public function generateModel($attributes = []) } return $model; } + + public static function dependentOn() + { + return [ + // just model class names + 'Store', + + ]; + } } diff --git a/tests/specs/petstore_namespace/mymodels/faker/StoreFaker.php b/tests/specs/petstore_namespace/mymodels/faker/StoreFaker.php index ad199932..08febea3 100644 --- a/tests/specs/petstore_namespace/mymodels/faker/StoreFaker.php +++ b/tests/specs/petstore_namespace/mymodels/faker/StoreFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Store(); + $model = new \app\mymodels\Store(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = $faker->sentence; if (!is_callable($attributes)) { diff --git a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/AlldbdatatypeFaker.php b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/AlldbdatatypeFaker.php index 6072961b..32934ebe 100644 --- a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/AlldbdatatypeFaker.php +++ b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/AlldbdatatypeFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Alldbdatatype(); + $model = new \app\models\mariamodel\Alldbdatatype(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->string_col = substr($faker->text(255), 0, 255); $model->varchar_col = substr($faker->text(132), 0, 132); diff --git a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/EditcolumnFaker.php b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/EditcolumnFaker.php index 6b071f2d..c075dc25 100644 --- a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/EditcolumnFaker.php +++ b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/EditcolumnFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Editcolumn(); + $model = new \app\models\mariamodel\Editcolumn(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = substr($faker->text(254), 0, 254); $model->tag = $faker->sentence; diff --git a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/NewcolumnFaker.php b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/NewcolumnFaker.php index c4cbd228..a60800cd 100644 --- a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/NewcolumnFaker.php +++ b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/NewcolumnFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Newcolumn(); + $model = new \app\models\mariamodel\Newcolumn(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = substr($faker->text(255), 0, 255); $model->last_name = $faker->sentence; diff --git a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/PristineFaker.php b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/PristineFaker.php index 7f667702..2fdf01e5 100644 --- a/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/PristineFaker.php +++ b/tests/specs/x_db_type/rules_and_more/maria/app/models/mariafaker/PristineFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Pristine(); + $model = new \app\models\mariamodel\Pristine(); $model->custom_id_col = $faker->numberBetween(0, 1000000); $model->name = $faker->sentence; $model->tag = $faker->sentence; diff --git a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/AlldbdatatypeFaker.php b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/AlldbdatatypeFaker.php index abe5829e..e2af0af0 100644 --- a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/AlldbdatatypeFaker.php +++ b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/AlldbdatatypeFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Alldbdatatype(); + $model = new \app\models\pgsqlmodel\Alldbdatatype(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->string_col = $faker->sentence; $model->varchar_col = $faker->sentence; diff --git a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/EditcolumnFaker.php b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/EditcolumnFaker.php index f06a936a..b87d5f33 100644 --- a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/EditcolumnFaker.php +++ b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/EditcolumnFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Editcolumn(); + $model = new \app\models\pgsqlmodel\Editcolumn(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = substr($faker->text(254), 0, 254); $model->tag = $faker->sentence; diff --git a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/NewcolumnFaker.php b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/NewcolumnFaker.php index 2b945489..1b41dae7 100644 --- a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/NewcolumnFaker.php +++ b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/NewcolumnFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Newcolumn(); + $model = new \app\models\pgsqlmodel\Newcolumn(); //$model->id = $uniqueFaker->numberBetween(0, 1000000); $model->name = $faker->sentence; $model->first_name = $faker->sentence; diff --git a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/PristineFaker.php b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/PristineFaker.php index 71dfeb2c..aac33ab7 100644 --- a/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/PristineFaker.php +++ b/tests/specs/x_db_type/rules_and_more/pgsql/app/models/pgsqlfaker/PristineFaker.php @@ -29,7 +29,7 @@ public function generateModel($attributes = []) { $faker = $this->faker; $uniqueFaker = $this->uniqueFaker; - $model = new Pristine(); + $model = new \app\models\pgsqlmodel\Pristine(); $model->custom_id_col = $faker->numberBetween(0, 1000000); $model->name = $faker->sentence; $model->tag = $faker->sentence; diff --git a/tests/unit/GeneratorTest.php b/tests/unit/GeneratorTest.php index 1bede214..4937aa0f 100644 --- a/tests/unit/GeneratorTest.php +++ b/tests/unit/GeneratorTest.php @@ -38,6 +38,10 @@ public function testGenerate($testFile) $this->mockApplication(); // $this->mockApplication($this->mockDbSchemaAsEmpty()); + // if ($testFile !== '/app/tests/specs/petstore.php') { + // return; + // } + if ($testFile === '/app/tests/specs/postgres_custom.php' || $testFile === '/app/tests/specs/menu.php' ) { // TODO docs + add separate tests for this + refactor tests @@ -95,6 +99,7 @@ function($file) { $actualFile = str_replace('@app', Yii::getAlias('@app'), $file); $this->assertFileExists($expectedFile); $this->assertFileExists($actualFile); + // exec('cp '.$actualFile.' '.$expectedFile); $this->assertFileEquals($expectedFile, $actualFile, "Failed asserting that file contents of\n$actualFile\nare equal to file contents of\n$expectedFile"); } diff --git a/tests/unit/MultiDbFreshMigrationTest.php b/tests/unit/MultiDbFreshMigrationTest.php index c8901034..56eaaf91 100644 --- a/tests/unit/MultiDbFreshMigrationTest.php +++ b/tests/unit/MultiDbFreshMigrationTest.php @@ -96,7 +96,7 @@ protected function compareFiles(array $expected, string $testFile) $actualFile = str_replace('@app', Yii::getAlias('@app'), $file); self::assertFileExists($expectedFile); self::assertFileExists($actualFile); - $this->assertFileEquals($expectedFile, $actualFile, "Failed asserting that file contents of\n$actualFile\nare equal to file contents of\n$expectedFile"); + $this->assertFileEquals($expectedFile, $actualFile, "Failed asserting that file contents of\n$actualFile\nare equal to file contents of\n$expectedFile\n\n cp $actualFile $expectedFile \n\n "); } } diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index 0770a6a5..0b106768 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -27,6 +27,9 @@ public function testIndex() 'except' => ['BaseModelFaker.php'], ]); + // TODO check file contents are same, + // check migrations too + $finalSortedModels = static::sortModels($fakers); $this->assertSame($finalSortedModels, [ @@ -45,7 +48,7 @@ public static function sortModels(array $fakers, string $fakerNamespace = 'app\\ { $modelsDependencies = []; foreach($fakers as $fakerFile) { - $className = $fakerNamespace . StringHelper::basename($fakerFile, '.php'); // TODO + $className = $fakerNamespace . StringHelper::basename($fakerFile, '.php'); $faker = new $className; $modelClassName = str_replace( From fb347afd31a7292239969a6a82ab280b7a41f4f7 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 20 Mar 2023 21:43:07 +0530 Subject: [PATCH 09/11] Make tests stronger --- tests/DbTestCase.php | 19 ++- .../m200000_000000_create_table_c123s.php | 20 +++ .../m200000_000001_create_table_b123s.php | 23 +++ .../m200000_000002_create_table_a123s.php | 23 +++ .../m200000_000003_create_table_accounts.php | 20 +++ .../m200000_000004_create_table_d123s.php | 20 +++ .../m200000_000005_create_table_domains.php | 24 +++ .../m200000_000006_create_table_e123s.php | 23 +++ .../m200000_000007_create_table_routings.php | 33 ++++ .../relations_in_faker/app/models/A123.php | 10 ++ .../relations_in_faker/app/models/Account.php | 10 ++ .../relations_in_faker/app/models/B123.php | 10 ++ .../relations_in_faker/app/models/C123.php | 10 ++ .../relations_in_faker/app/models/D123.php | 10 ++ .../relations_in_faker/app/models/Domain.php | 10 ++ .../relations_in_faker/app/models/E123.php | 10 ++ .../relations_in_faker/app/models/Routing.php | 10 ++ .../app/models/base/A123.php | 35 +++++ .../app/models/base/Account.php | 27 ++++ .../app/models/base/B123.php | 35 +++++ .../app/models/base/C123.php | 26 ++++ .../app/models/base/D123.php | 26 ++++ .../app/models/base/Domain.php | 43 ++++++ .../app/models/base/E123.php | 35 +++++ .../app/models/base/Routing.php | 61 ++++++++ .../app/models/fakers/A123Faker.php | 52 +++++++ .../app/models/fakers/AccountFaker.php | 42 +++++ .../app/models/fakers/B123Faker.php | 52 +++++++ .../app/models/fakers/BaseModelFaker.php | 144 ++++++++++++++++++ .../app/models/fakers/C123Faker.php | 42 +++++ .../app/models/fakers/D123Faker.php | 42 +++++ .../app/models/fakers/DomainFaker.php | 53 +++++++ .../app/models/fakers/E123Faker.php | 52 +++++++ .../app/models/fakers/RoutingFaker.php | 60 ++++++++ tests/unit/RelationsInFakerTest.php | 16 +- 35 files changed, 1122 insertions(+), 6 deletions(-) create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000000_create_table_c123s.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000001_create_table_b123s.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000002_create_table_a123s.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000003_create_table_accounts.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000004_create_table_d123s.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000005_create_table_domains.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000006_create_table_e123s.php create mode 100644 tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000007_create_table_routings.php create mode 100644 tests/specs/relations_in_faker/app/models/A123.php create mode 100644 tests/specs/relations_in_faker/app/models/Account.php create mode 100644 tests/specs/relations_in_faker/app/models/B123.php create mode 100644 tests/specs/relations_in_faker/app/models/C123.php create mode 100644 tests/specs/relations_in_faker/app/models/D123.php create mode 100644 tests/specs/relations_in_faker/app/models/Domain.php create mode 100644 tests/specs/relations_in_faker/app/models/E123.php create mode 100644 tests/specs/relations_in_faker/app/models/Routing.php create mode 100644 tests/specs/relations_in_faker/app/models/base/A123.php create mode 100644 tests/specs/relations_in_faker/app/models/base/Account.php create mode 100644 tests/specs/relations_in_faker/app/models/base/B123.php create mode 100644 tests/specs/relations_in_faker/app/models/base/C123.php create mode 100644 tests/specs/relations_in_faker/app/models/base/D123.php create mode 100644 tests/specs/relations_in_faker/app/models/base/Domain.php create mode 100644 tests/specs/relations_in_faker/app/models/base/E123.php create mode 100644 tests/specs/relations_in_faker/app/models/base/Routing.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/A123Faker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/AccountFaker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/B123Faker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/BaseModelFaker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/C123Faker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/D123Faker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/DomainFaker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/E123Faker.php create mode 100644 tests/specs/relations_in_faker/app/models/fakers/RoutingFaker.php diff --git a/tests/DbTestCase.php b/tests/DbTestCase.php index 1c668240..3eacb29a 100644 --- a/tests/DbTestCase.php +++ b/tests/DbTestCase.php @@ -4,6 +4,7 @@ use cebe\yii2openapi\generator\ApiGenerator; use Yii; +use tests\unit\RelationsInFakerTest; use yii\di\Container; use yii\db\mysql\Schema as MySqlSchema; use yii\db\pgsql\Schema as PgSqlSchema; @@ -111,18 +112,30 @@ protected function runActualMigrations(string $db = 'mysql', int $number = 2): v $this->runDownMigrations($db, $number); } - protected function runFaker() + protected function runFaker(?string $fakerNamespace = null) { $fakers = FileHelper::findFiles(Yii::getAlias('@app'), [ 'recursive' => true, 'only' => ['*Faker.php'], 'except' => ['BaseModelFaker.php'], ]); - foreach($fakers as $fakerFile) { + + if ($fakerNamespace) { + $fakerNamespace .= '\\'; + } + + $sortedFakersModels = RelationsInFakerTest::sortModels($fakers, $fakerNamespace); + + foreach($sortedFakersModels as $justModelName) { $className = 'app\\models\\' . (ApiGenerator::isPostgres() ? "pgsqlfaker\\" : '') . (ApiGenerator::isMariaDb() ? "mariafaker\\" : '') . - StringHelper::basename($fakerFile, '.php'); + StringHelper::basename($justModelName, '.php'); + + if (!empty($fakerNamespace)) { + $className = $fakerNamespace .'\\'. StringHelper::basename($justModelName, '.php').'Faker'; + } + $faker = new $className; for($i = 0; $i < 10; $i++) { $model = $faker->generateModel(); diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000000_create_table_c123s.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000000_create_table_c123s.php new file mode 100644 index 00000000..0b91584c --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000000_create_table_c123s.php @@ -0,0 +1,20 @@ +createTable('{{%c123s}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->null(), + ]); + } + + public function down() + { + $this->dropTable('{{%c123s}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000001_create_table_b123s.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000001_create_table_b123s.php new file mode 100644 index 00000000..1f356f98 --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000001_create_table_b123s.php @@ -0,0 +1,23 @@ +createTable('{{%b123s}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->null(), + 'c123_id' => $this->integer()->null()->defaultValue(null), + ]); + $this->addForeignKey('fk_b123s_c123_id_c123s_id', '{{%b123s}}', 'c123_id', '{{%c123s}}', 'id'); + } + + public function down() + { + $this->dropForeignKey('fk_b123s_c123_id_c123s_id', '{{%b123s}}'); + $this->dropTable('{{%b123s}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000002_create_table_a123s.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000002_create_table_a123s.php new file mode 100644 index 00000000..5ebe6ee3 --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000002_create_table_a123s.php @@ -0,0 +1,23 @@ +createTable('{{%a123s}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->null(), + 'b123_id' => $this->integer()->null()->defaultValue(null), + ]); + $this->addForeignKey('fk_a123s_b123_id_b123s_id', '{{%a123s}}', 'b123_id', '{{%b123s}}', 'id'); + } + + public function down() + { + $this->dropForeignKey('fk_a123s_b123_id_b123s_id', '{{%a123s}}'); + $this->dropTable('{{%a123s}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000003_create_table_accounts.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000003_create_table_accounts.php new file mode 100644 index 00000000..989c801f --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000003_create_table_accounts.php @@ -0,0 +1,20 @@ +createTable('{{%accounts}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(40)->notNull(), + ]); + } + + public function down() + { + $this->dropTable('{{%accounts}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000004_create_table_d123s.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000004_create_table_d123s.php new file mode 100644 index 00000000..dfe49184 --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000004_create_table_d123s.php @@ -0,0 +1,20 @@ +createTable('{{%d123s}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->null(), + ]); + } + + public function down() + { + $this->dropTable('{{%d123s}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000005_create_table_domains.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000005_create_table_domains.php new file mode 100644 index 00000000..54701ead --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000005_create_table_domains.php @@ -0,0 +1,24 @@ +createTable('{{%domains}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->string(128)->notNull(), + 'account_id' => $this->integer()->notNull(), + 0 => 'created_at datetime NOT NULL', + ]); + $this->addForeignKey('fk_domains_account_id_accounts_id', '{{%domains}}', 'account_id', '{{%accounts}}', 'id'); + } + + public function down() + { + $this->dropForeignKey('fk_domains_account_id_accounts_id', '{{%domains}}'); + $this->dropTable('{{%domains}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000006_create_table_e123s.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000006_create_table_e123s.php new file mode 100644 index 00000000..7d17320f --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000006_create_table_e123s.php @@ -0,0 +1,23 @@ +createTable('{{%e123s}}', [ + 'id' => $this->primaryKey(), + 'name' => $this->text()->null(), + 'b123_id' => $this->integer()->null()->defaultValue(null), + ]); + $this->addForeignKey('fk_e123s_b123_id_b123s_id', '{{%e123s}}', 'b123_id', '{{%b123s}}', 'id'); + } + + public function down() + { + $this->dropForeignKey('fk_e123s_b123_id_b123s_id', '{{%e123s}}'); + $this->dropTable('{{%e123s}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000007_create_table_routings.php b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000007_create_table_routings.php new file mode 100644 index 00000000..0cf31efd --- /dev/null +++ b/tests/specs/relations_in_faker/app/migrations_mysql_db/m200000_000007_create_table_routings.php @@ -0,0 +1,33 @@ +createTable('{{%routings}}', [ + 'id' => $this->primaryKey(), + 'domain_id' => $this->integer()->notNull(), + 'path' => $this->string(255)->null()->defaultValue(null), + 'ssl' => $this->boolean()->null()->defaultValue(null), + 'redirect_to_ssl' => $this->boolean()->null()->defaultValue(null), + 'service' => $this->string(255)->null()->defaultValue(null), + 0 => 'created_at datetime NULL DEFAULT NULL', + 'd123_id' => $this->integer()->null()->defaultValue(null), + 'a123_id' => $this->integer()->null()->defaultValue(null), + ]); + $this->addForeignKey('fk_routings_domain_id_domains_id', '{{%routings}}', 'domain_id', '{{%domains}}', 'id'); + $this->addForeignKey('fk_routings_d123_id_d123s_id', '{{%routings}}', 'd123_id', '{{%d123s}}', 'id'); + $this->addForeignKey('fk_routings_a123_id_a123s_id', '{{%routings}}', 'a123_id', '{{%a123s}}', 'id'); + } + + public function down() + { + $this->dropForeignKey('fk_routings_a123_id_a123s_id', '{{%routings}}'); + $this->dropForeignKey('fk_routings_d123_id_d123s_id', '{{%routings}}'); + $this->dropForeignKey('fk_routings_domain_id_domains_id', '{{%routings}}'); + $this->dropTable('{{%routings}}'); + } +} diff --git a/tests/specs/relations_in_faker/app/models/A123.php b/tests/specs/relations_in_faker/app/models/A123.php new file mode 100644 index 00000000..f6874e5c --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/A123.php @@ -0,0 +1,10 @@ + [['name'], 'trim'], + 'b123_id_integer' => [['b123_id'], 'integer'], + 'b123_id_exist' => [['b123_id'], 'exist', 'targetRelation' => 'B123'], + 'name_string' => [['name'], 'string'], + ]; + } + + public function getB123() + { + return $this->hasOne(\app\models\B123::class, ['id' => 'b123_id']); + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/Account.php b/tests/specs/relations_in_faker/app/models/base/Account.php new file mode 100644 index 00000000..0ee4adc0 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/Account.php @@ -0,0 +1,27 @@ + [['name'], 'trim'], + 'required' => [['name'], 'required'], + 'name_string' => [['name'], 'string', 'max' => 40], + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/B123.php b/tests/specs/relations_in_faker/app/models/base/B123.php new file mode 100644 index 00000000..f05fe320 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/B123.php @@ -0,0 +1,35 @@ + [['name'], 'trim'], + 'c123_id_integer' => [['c123_id'], 'integer'], + 'c123_id_exist' => [['c123_id'], 'exist', 'targetRelation' => 'C123'], + 'name_string' => [['name'], 'string'], + ]; + } + + public function getC123() + { + return $this->hasOne(\app\models\C123::class, ['id' => 'c123_id']); + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/C123.php b/tests/specs/relations_in_faker/app/models/base/C123.php new file mode 100644 index 00000000..faa3f1e5 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/C123.php @@ -0,0 +1,26 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string'], + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/D123.php b/tests/specs/relations_in_faker/app/models/base/D123.php new file mode 100644 index 00000000..a6050a8a --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/D123.php @@ -0,0 +1,26 @@ + [['name'], 'trim'], + 'name_string' => [['name'], 'string'], + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/Domain.php b/tests/specs/relations_in_faker/app/models/base/Domain.php new file mode 100644 index 00000000..3f861f9e --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/Domain.php @@ -0,0 +1,43 @@ + [['name'], 'trim'], + 'required' => [['name', 'account_id'], 'required'], + 'account_id_integer' => [['account_id'], 'integer'], + 'account_id_exist' => [['account_id'], 'exist', 'targetRelation' => 'Account'], + 'name_string' => [['name'], 'string', 'max' => 128], + ]; + } + + public function getAccount() + { + return $this->hasOne(\app\models\Account::class, ['id' => 'account_id']); + } + + public function getRoutings() + { + return $this->hasMany(\app\models\Routing::class, ['domain_id' => 'id']); + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/E123.php b/tests/specs/relations_in_faker/app/models/base/E123.php new file mode 100644 index 00000000..6eb43814 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/E123.php @@ -0,0 +1,35 @@ + [['name'], 'trim'], + 'b123_id_integer' => [['b123_id'], 'integer'], + 'b123_id_exist' => [['b123_id'], 'exist', 'targetRelation' => 'B123'], + 'name_string' => [['name'], 'string'], + ]; + } + + public function getB123() + { + return $this->hasOne(\app\models\B123::class, ['id' => 'b123_id']); + } +} diff --git a/tests/specs/relations_in_faker/app/models/base/Routing.php b/tests/specs/relations_in_faker/app/models/base/Routing.php new file mode 100644 index 00000000..71a31b81 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/base/Routing.php @@ -0,0 +1,61 @@ + [['path', 'service'], 'trim'], + 'required' => [['domain_id'], 'required'], + 'domain_id_integer' => [['domain_id'], 'integer'], + 'domain_id_exist' => [['domain_id'], 'exist', 'targetRelation' => 'Domain'], + 'd123_id_integer' => [['d123_id'], 'integer'], + 'd123_id_exist' => [['d123_id'], 'exist', 'targetRelation' => 'D123'], + 'a123_id_integer' => [['a123_id'], 'integer'], + 'a123_id_exist' => [['a123_id'], 'exist', 'targetRelation' => 'A123'], + 'path_string' => [['path'], 'string', 'max' => 255], + 'ssl_boolean' => [['ssl'], 'boolean'], + 'redirect_to_ssl_boolean' => [['redirect_to_ssl'], 'boolean'], + 'service_string' => [['service'], 'string', 'max' => 255], + ]; + } + + public function getDomain() + { + return $this->hasOne(\app\models\Domain::class, ['id' => 'domain_id']); + } + + public function getD123() + { + return $this->hasOne(\app\models\D123::class, ['id' => 'd123_id']); + } + + public function getA123() + { + return $this->hasOne(\app\models\A123::class, ['id' => 'a123_id']); + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/A123Faker.php b/tests/specs/relations_in_faker/app/models/fakers/A123Faker.php new file mode 100644 index 00000000..dff3119d --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/A123Faker.php @@ -0,0 +1,52 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\A123(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + $model->b123_id = $faker->randomElement(\app\models\B123::find()->select("id")->column()); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } + + public static function dependentOn() + { + return [ + // just model class names + 'B123', + + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/AccountFaker.php b/tests/specs/relations_in_faker/app/models/fakers/AccountFaker.php new file mode 100644 index 00000000..2b247547 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/AccountFaker.php @@ -0,0 +1,42 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\Account(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = substr($faker->userName(), 0, 40); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/B123Faker.php b/tests/specs/relations_in_faker/app/models/fakers/B123Faker.php new file mode 100644 index 00000000..7065168e --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/B123Faker.php @@ -0,0 +1,52 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\B123(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + $model->c123_id = $faker->randomElement(\app\models\C123::find()->select("id")->column()); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } + + public static function dependentOn() + { + return [ + // just model class names + 'C123', + + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/BaseModelFaker.php b/tests/specs/relations_in_faker/app/models/fakers/BaseModelFaker.php new file mode 100644 index 00000000..9792cdd5 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/BaseModelFaker.php @@ -0,0 +1,144 @@ +faker = FakerFactory::create(str_replace('-', '_', \Yii::$app->language)); + $this->uniqueFaker = new UniqueGenerator($this->faker); + } + + abstract public function generateModel($attributes = []); + + public function getFaker():Generator + { + return $this->faker; + } + + public function getUniqueFaker():UniqueGenerator + { + return $this->uniqueFaker; + } + + public function setFaker(Generator $faker):void + { + $this->faker = $faker; + } + + public function setUniqueFaker(UniqueGenerator $faker):void + { + $this->uniqueFaker = $faker; + } + + /** + * Generate and return model + * @param array|callable $attributes + * @param UniqueGenerator|null $uniqueFaker + * @return \yii\db\ActiveRecord + * @example MyFaker::makeOne(['user_id' => 1, 'title' => 'foo']); + * @example MyFaker::makeOne( function($model, $faker) { + * $model->scenario = 'create'; + * $model->setAttributes(['user_id' => 1, 'title' => $faker->sentence]); + * return $model; + * }); + */ + public static function makeOne($attributes = [], ?UniqueGenerator $uniqueFaker = null) + { + $fakeBuilder = new static(); + if ($uniqueFaker !== null) { + $fakeBuilder->setUniqueFaker($uniqueFaker); + } + $model = $fakeBuilder->generateModel($attributes); + return $model; + } + + /** + * Generate, save and return model + * @param array|callable $attributes + * @param UniqueGenerator|null $uniqueFaker + * @return \yii\db\ActiveRecord + * @example MyFaker::saveOne(['user_id' => 1, 'title' => 'foo']); + * @example MyFaker::saveOne( function($model, $faker) { + * $model->scenario = 'create'; + * $model->setAttributes(['user_id' => 1, 'title' => $faker->sentence]); + * return $model; + * }); + */ + public static function saveOne($attributes = [], ?UniqueGenerator $uniqueFaker = null) + { + $model = static::makeOne($attributes, $uniqueFaker); + $model->save(); + return $model; + } + + /** + * Generate and return multiple models + * @param int $number + * @param array|callable $commonAttributes + * @return \yii\db\ActiveRecord[]|array + * @example TaskFaker::make(5, ['project_id'=>1, 'user_id' => 2]); + * @example TaskFaker::make(5, function($model, $faker, $uniqueFaker) { + * $model->setAttributes(['name' => $uniqueFaker->username, 'state'=>$faker->boolean(20)]); + * return $model; + * }); + */ + public static function make(int $number, $commonAttributes = [], ?UniqueGenerator $uniqueFaker = null):array + { + if ($number < 1) { + return []; + } + $fakeBuilder = new static(); + if ($uniqueFaker !== null) { + $fakeBuilder->setUniqueFaker($uniqueFaker); + } + return array_map(function () use ($commonAttributes, $fakeBuilder) { + $model = $fakeBuilder->generateModel($commonAttributes); + return $model; + }, range(0, $number -1)); + } + + /** + * Generate, save and return multiple models + * @param int $number + * @param array|callable $commonAttributes + * @return \yii\db\ActiveRecord[]|array + * @example TaskFaker::save(5, ['project_id'=>1, 'user_id' => 2]); + * @example TaskFaker::save(5, function($model, $faker, $uniqueFaker) { + * $model->setAttributes(['name' => $uniqueFaker->username, 'state'=>$faker->boolean(20)]); + * return $model; + * }); + */ + public static function save(int $number, $commonAttributes = [], ?UniqueGenerator $uniqueFaker = null):array + { + if ($number < 1) { + return []; + } + $fakeBuilder = new static(); + if ($uniqueFaker !== null) { + $fakeBuilder->setUniqueFaker($uniqueFaker); + } + return array_map(function () use ($commonAttributes, $fakeBuilder) { + $model = $fakeBuilder->generateModel($commonAttributes); + $model->save(); + return $model; + }, range(0, $number -1)); + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/C123Faker.php b/tests/specs/relations_in_faker/app/models/fakers/C123Faker.php new file mode 100644 index 00000000..0653a8ce --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/C123Faker.php @@ -0,0 +1,42 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\C123(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/D123Faker.php b/tests/specs/relations_in_faker/app/models/fakers/D123Faker.php new file mode 100644 index 00000000..23c56326 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/D123Faker.php @@ -0,0 +1,42 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\D123(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/DomainFaker.php b/tests/specs/relations_in_faker/app/models/fakers/DomainFaker.php new file mode 100644 index 00000000..8cd028cc --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/DomainFaker.php @@ -0,0 +1,53 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\Domain(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->domainName; + $model->account_id = $faker->randomElement(\app\models\Account::find()->select("id")->column()); + $model->created_at = $faker->dateTimeThisYear('now', 'UTC')->format('Y-m-d H:i:s'); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } + + public static function dependentOn() + { + return [ + // just model class names + 'Account', + + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/E123Faker.php b/tests/specs/relations_in_faker/app/models/fakers/E123Faker.php new file mode 100644 index 00000000..3e300586 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/E123Faker.php @@ -0,0 +1,52 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\E123(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->name = $faker->sentence; + $model->b123_id = $faker->randomElement(\app\models\B123::find()->select("id")->column()); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } + + public static function dependentOn() + { + return [ + // just model class names + 'B123', + + ]; + } +} diff --git a/tests/specs/relations_in_faker/app/models/fakers/RoutingFaker.php b/tests/specs/relations_in_faker/app/models/fakers/RoutingFaker.php new file mode 100644 index 00000000..06d7bff7 --- /dev/null +++ b/tests/specs/relations_in_faker/app/models/fakers/RoutingFaker.php @@ -0,0 +1,60 @@ +generateModels(['author_id' => 1]); + * $model = (new PostFaker())->generateModels(function($model, $faker, $uniqueFaker) { + * $model->scenario = 'create'; + * $model->author_id = 1; + * return $model; + * }); + **/ + public function generateModel($attributes = []) + { + $faker = $this->faker; + $uniqueFaker = $this->uniqueFaker; + $model = new \app\models\Routing(); + //$model->id = $uniqueFaker->numberBetween(0, 1000000); + $model->domain_id = $faker->randomElement(\app\models\Domain::find()->select("id")->column()); + $model->path = $faker->randomElement(["/", "/", "/", "/", "/api", "/tools", "/assets/web"]); + $model->ssl = $faker->boolean; + $model->redirect_to_ssl = $faker->boolean; + $model->service = "http://tador.cebe.net/" . $faker->domainName; + $model->created_at = $faker->dateTimeThisYear('now', 'UTC')->format('Y-m-d H:i:s'); + $model->d123_id = $faker->randomElement(\app\models\D123::find()->select("id")->column()); + $model->a123_id = $faker->randomElement(\app\models\A123::find()->select("id")->column()); + if (!is_callable($attributes)) { + $model->setAttributes($attributes, false); + } else { + $model = $attributes($model, $faker, $uniqueFaker); + } + return $model; + } + + public static function dependentOn() + { + return [ + // just model class names + 'Domain', + 'D123', + 'A123', + + ]; + } +} diff --git a/tests/unit/RelationsInFakerTest.php b/tests/unit/RelationsInFakerTest.php index 0b106768..d2be8989 100644 --- a/tests/unit/RelationsInFakerTest.php +++ b/tests/unit/RelationsInFakerTest.php @@ -20,6 +20,8 @@ class RelationsInFakerTest extends DbTestCase public function testIndex() { $testFile = Yii::getAlias("@specs/relations_in_faker/relations_in_faker.php"); + $testFileConfig = require $testFile; + $this->runGenerator($testFile, 'mysql'); $fakers = FileHelper::findFiles(\Yii::getAlias('@app/models/fakers'), [ @@ -27,9 +29,6 @@ public function testIndex() 'except' => ['BaseModelFaker.php'], ]); - // TODO check file contents are same, - // check migrations too - $finalSortedModels = static::sortModels($fakers); $this->assertSame($finalSortedModels, [ @@ -42,6 +41,17 @@ public function testIndex() 'A123', 'Routing', ]); + + $actualFiles = FileHelper::findFiles(Yii::getAlias('@app'), [ + 'recursive' => true, + ]); + $expectedFiles = FileHelper::findFiles(Yii::getAlias("@specs/relations_in_faker/app"), [ + 'recursive' => true, + ]); + $this->checkFiles($actualFiles, $expectedFiles); + $this->runUpMigrations('mysql', 8); + Yii::$app->db->schema->refresh(); + $this->runDownMigrations('mysql', 8); } public static function sortModels(array $fakers, string $fakerNamespace = 'app\\models\\fakers\\') From 91300dba25d172ba551c5eb6d8e8ccec10343040 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Mon, 20 Mar 2023 21:49:15 +0530 Subject: [PATCH 10/11] Revert a change that introduce bug --- tests/DbTestCase.php | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/DbTestCase.php b/tests/DbTestCase.php index 3eacb29a..1c668240 100644 --- a/tests/DbTestCase.php +++ b/tests/DbTestCase.php @@ -4,7 +4,6 @@ use cebe\yii2openapi\generator\ApiGenerator; use Yii; -use tests\unit\RelationsInFakerTest; use yii\di\Container; use yii\db\mysql\Schema as MySqlSchema; use yii\db\pgsql\Schema as PgSqlSchema; @@ -112,30 +111,18 @@ protected function runActualMigrations(string $db = 'mysql', int $number = 2): v $this->runDownMigrations($db, $number); } - protected function runFaker(?string $fakerNamespace = null) + protected function runFaker() { $fakers = FileHelper::findFiles(Yii::getAlias('@app'), [ 'recursive' => true, 'only' => ['*Faker.php'], 'except' => ['BaseModelFaker.php'], ]); - - if ($fakerNamespace) { - $fakerNamespace .= '\\'; - } - - $sortedFakersModels = RelationsInFakerTest::sortModels($fakers, $fakerNamespace); - - foreach($sortedFakersModels as $justModelName) { + foreach($fakers as $fakerFile) { $className = 'app\\models\\' . (ApiGenerator::isPostgres() ? "pgsqlfaker\\" : '') . (ApiGenerator::isMariaDb() ? "mariafaker\\" : '') . - StringHelper::basename($justModelName, '.php'); - - if (!empty($fakerNamespace)) { - $className = $fakerNamespace .'\\'. StringHelper::basename($justModelName, '.php').'Faker'; - } - + StringHelper::basename($fakerFile, '.php'); $faker = new $className; for($i = 0; $i < 10; $i++) { $model = $faker->generateModel(); From 21ec09caed9672ba28e0afe7ac5eab69f09970d4 Mon Sep 17 00:00:00 2001 From: Sohel Ahmed Mesaniya Date: Tue, 21 Mar 2023 18:44:57 +0530 Subject: [PATCH 11/11] Fix style --- src/generator/default/faker.php | 2 +- src/lib/CustomSpecAttr.php | 1 - src/lib/FakerStubResolver.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/generator/default/faker.php b/src/generator/default/faker.php index a555d679..7b93a12b 100644 --- a/src/generator/default/faker.php +++ b/src/generator/default/faker.php @@ -68,7 +68,7 @@ public static function dependentOn() { return [ // just model class names -hasOneRelations as $key => $hasOneRelation): ?> +hasOneRelations as $key => $hasOneRelation): ?> hasOneRelations[$key]->getClassName()).','.PHP_EOL ?> diff --git a/src/lib/CustomSpecAttr.php b/src/lib/CustomSpecAttr.php index 897df3a4..c4c1877c 100644 --- a/src/lib/CustomSpecAttr.php +++ b/src/lib/CustomSpecAttr.php @@ -35,5 +35,4 @@ class CustomSpecAttr */ public const FK_ON_DELETE = 'x-fk-on-delete'; public const FK_ON_UPDATE = 'x-fk-on-update'; - } diff --git a/src/lib/FakerStubResolver.php b/src/lib/FakerStubResolver.php index fb71ad27..a0e029b8 100644 --- a/src/lib/FakerStubResolver.php +++ b/src/lib/FakerStubResolver.php @@ -53,7 +53,7 @@ public function resolve():?string // column name ends with `_id` if (substr($this->attribute->columnName, -strlen('_id'))==='_id') { - return '$faker->randomElement(\\'.$this->config->modelNamespace + return '$faker->randomElement(\\'.$this->config->modelNamespace . ($this->config->modelNamespace ? '\\' : '') . ucfirst($this->attribute->reference).'::find()->select("id")->column())'; }