From 9b1c38b58d5f822a1d85003883419cf2c46d48e1 Mon Sep 17 00:00:00 2001 From: Amine Ben hammou Date: Wed, 21 Oct 2015 00:34:10 +0200 Subject: [PATCH] model factory generator added --- composer.json | 3 +- composer.lock | 76 ++++++++++++++++--- formats/factory-fields.json | 8 ++ .../tests/acceptance/FactoryCommandCept.php | 69 +++++++++++++++++ src/Commands/FactoryCommand.php | 63 +++++++++++++++ src/CommandsServiceProvider.php | 16 ++-- templates/factory.wnt | 9 +++ templates/factory/field.wnt | 1 + 8 files changed, 223 insertions(+), 22 deletions(-) create mode 100644 formats/factory-fields.json create mode 100644 lumen-test/tests/acceptance/FactoryCommandCept.php create mode 100644 src/Commands/FactoryCommand.php create mode 100644 templates/factory.wnt create mode 100644 templates/factory/field.wnt diff --git a/composer.json b/composer.json index a9a9345..cf0bca4 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "require": { "php": ">=5.5.0", "illuminate/console": "^5.1", - "illuminate/filesystem": "^5.1" + "illuminate/filesystem": "^5.1", + "fzaninotto/faker": "^1.5" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 84c846c..8f37cfb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "37849ba19e35018ecc2b5205e814b6ef", + "hash": "0e07f7bf375f2746df0a353573e4c832", "packages": [ { "name": "codeception/codeception", @@ -306,6 +306,58 @@ ], "time": "2015-08-12 20:21:31" }, + { + "name": "fzaninotto/faker", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "d0190b156bcca848d401fb80f31f504f37141c8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/d0190b156bcca848d401fb80f31f504f37141c8d", + "reference": "d0190b156bcca848d401fb80f31f504f37141c8d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" + }, + "suggest": { + "ext-intl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "time": "2015-05-29 06:29:14" + }, { "name": "guzzlehttp/guzzle", "version": "6.1.0", @@ -1733,12 +1785,12 @@ "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/symfony/BrowserKit.git", + "url": "https://github.com/symfony/browser-kit.git", "reference": "277a2457776d4cc25706fbdd9d1e4ab2dac884e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/277a2457776d4cc25706fbdd9d1e4ab2dac884e4", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/277a2457776d4cc25706fbdd9d1e4ab2dac884e4", "reference": "277a2457776d4cc25706fbdd9d1e4ab2dac884e4", "shasum": "" }, @@ -1788,12 +1840,12 @@ "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", + "url": "https://github.com/symfony/console.git", "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/9ff9032151186bd66ecee727d728f1319f52d1d8", + "url": "https://api.github.com/repos/symfony/console/zipball/9ff9032151186bd66ecee727d728f1319f52d1d8", "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8", "shasum": "" }, @@ -1845,12 +1897,12 @@ "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/symfony/CssSelector.git", + "url": "https://github.com/symfony/css-selector.git", "reference": "ffb5f3b8a75f8d1b9801e74dc6789a0751a670ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/ffb5f3b8a75f8d1b9801e74dc6789a0751a670ad", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ffb5f3b8a75f8d1b9801e74dc6789a0751a670ad", "reference": "ffb5f3b8a75f8d1b9801e74dc6789a0751a670ad", "shasum": "" }, @@ -1898,12 +1950,12 @@ "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/symfony/DomCrawler.git", + "url": "https://github.com/symfony/dom-crawler.git", "reference": "2a161e4ee2b2f33d4153be58df4f6f2a5506936e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/2a161e4ee2b2f33d4153be58df4f6f2a5506936e", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2a161e4ee2b2f33d4153be58df4f6f2a5506936e", "reference": "2a161e4ee2b2f33d4153be58df4f6f2a5506936e", "shasum": "" }, @@ -1951,12 +2003,12 @@ "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", + "url": "https://github.com/symfony/event-dispatcher.git", "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/b58c916f1db03a611b72dd702564f30ad8fe83fa", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b58c916f1db03a611b72dd702564f30ad8fe83fa", "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa", "shasum": "" }, @@ -2220,7 +2272,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.4.0" + "php": ">=5.5.0" }, "platform-dev": [] } diff --git a/formats/factory-fields.json b/formats/factory-fields.json new file mode 100644 index 0000000..6558f3c --- /dev/null +++ b/formats/factory-fields.json @@ -0,0 +1,8 @@ +{ + "type": "array", + "fields": { + "type": "object", + "separator": ":", + "fields": ["name","type"] + } +} \ No newline at end of file diff --git a/lumen-test/tests/acceptance/FactoryCommandCept.php b/lumen-test/tests/acceptance/FactoryCommandCept.php new file mode 100644 index 0000000..9d7cc59 --- /dev/null +++ b/lumen-test/tests/acceptance/FactoryCommandCept.php @@ -0,0 +1,69 @@ +wantTo('generate model factories without fields'); +$I->runShellCommand('php artisan wn:factory "App\Task"'); +$I->seeInShellOutput('App\Task factory generated'); +$I->openFile('./database/factories/ModelFactory.php'); +$I->seeInThisFile(' +$factory->define(App\Task::class, function ($faker) { + return [ + // Fields here + ]; +});'); +$I->writeToFile('./database/factories/ModelFactory.php', "define(App\User::class, function (\$faker) { + return [ + 'name' => \$faker->name, + 'email' => \$faker->email, + 'password' => str_random(10), + 'remember_token' => str_random(10), + ]; +}); +"); + +$I->wantTo('generate model factories with fields'); +$I->runShellCommand('php artisan wn:factory "App\Task" --fields="title:sentence(3),description:paragraph(3),due:date,hidden:boolean"'); +$I->seeInShellOutput('App\Task factory generated'); +$I->openFile('./database/factories/ModelFactory.php'); +$I->seeInThisFile(" + 'title' => \$faker->sentence(3), + 'description' => \$faker->paragraph(3), + 'due' => \$faker->date, + 'hidden' => \$faker->boolean, +"); +$I->writeToFile('./database/factories/ModelFactory.php', "define(App\User::class, function (\$faker) { + return [ + 'name' => \$faker->name, + 'email' => \$faker->email, + 'password' => str_random(10), + 'remember_token' => str_random(10), + ]; +}); +"); + diff --git a/src/Commands/FactoryCommand.php b/src/Commands/FactoryCommand.php new file mode 100644 index 0000000..5eab985 --- /dev/null +++ b/src/Commands/FactoryCommand.php @@ -0,0 +1,63 @@ +argument('model'); + + $file = $this->getFile(); + + $content = $this->fs->get($file); + + $content .= $this->getTemplate('factory') + ->with([ + 'model' => $model, + 'factory_fields' => $this->getFieldsContent() + ]) + ->get(); + + $this->save($content, $file); + + $this->info("{$model} factory generated !"); + } + + protected function getFile() + { + $file = $this->option('file'); + if(! $file){ + $file = './database/factories/ModelFactory.php'; + } + return $file; + } + + protected function getFieldsContent() + { + $content = []; + + $fields = $this->option('fields'); + + if($fields){ + $fields = $this->getArgumentParser('factory-fields')->parse($fields); + $template = $this->getTemplate('factory/field'); + foreach($fields as $field){ + $content[] = $template->with($field)->get(); + } + $content = implode(PHP_EOL, $content); + } else { + $content = "\t\t// Fields here"; + } + + return $content; + } + +} \ No newline at end of file diff --git a/src/CommandsServiceProvider.php b/src/CommandsServiceProvider.php index 8ab299b..e2835b9 100644 --- a/src/CommandsServiceProvider.php +++ b/src/CommandsServiceProvider.php @@ -15,6 +15,7 @@ class CommandsServiceProvider extends ServiceProvider $this->registerResourceCommand(); $this->registerResourcesCommand(); $this->registerPivotTableCommand(); + $this->registerFactoryCommand(); // $this->registerSeedCommand(); // $this->registerTestCommand(); } @@ -24,7 +25,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\ModelCommand']; }); $this->commands('command.wn.model'); - } protected function registerControllerRestActionsCommand(){ @@ -32,7 +32,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\ControllerRestActionsCommand']; }); $this->commands('command.wn.controller.rest-actions'); - } protected function registerControllerCommand(){ @@ -40,7 +39,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\ControllerCommand']; }); $this->commands('command.wn.controller'); - } protected function registerMigrationCommand(){ @@ -48,7 +46,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\MigrationCommand']; }); $this->commands('command.wn.migration'); - } protected function registerSeedCommand(){ @@ -56,7 +53,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\SeedCommand']; }); $this->commands('command.wn.seed'); - } protected function registerRouteCommand(){ @@ -64,7 +60,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\RouteCommand']; }); $this->commands('command.wn.route'); - } protected function registerTestCommand(){ @@ -72,7 +67,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\TestCommand']; }); $this->commands('command.wn.test'); - } protected function registerResourceCommand(){ @@ -80,7 +74,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\ResourceCommand']; }); $this->commands('command.wn.resource'); - } protected function registerResourcesCommand(){ @@ -88,7 +81,6 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\ResourcesCommand']; }); $this->commands('command.wn.resources'); - } protected function registerPivotTableCommand(){ @@ -96,7 +88,13 @@ class CommandsServiceProvider extends ServiceProvider return $app['Wn\Generators\Commands\PivotTableCommand']; }); $this->commands('command.wn.pivot-table'); + } + protected function registerFactoryCommand(){ + $this->app->singleton('command.wn.factory', function($app){ + return $app['Wn\Generators\Commands\FactoryCommand']; + }); + $this->commands('command.wn.factory'); } } diff --git a/templates/factory.wnt b/templates/factory.wnt new file mode 100644 index 0000000..e94a255 --- /dev/null +++ b/templates/factory.wnt @@ -0,0 +1,9 @@ + +/** + * Factory definition for model {{model}}. + */ +$factory->define({{model}}::class, function ($faker) { + return [ +{{factory_fields}} + ]; +}); diff --git a/templates/factory/field.wnt b/templates/factory/field.wnt new file mode 100644 index 0000000..46d13d1 --- /dev/null +++ b/templates/factory/field.wnt @@ -0,0 +1 @@ + '{{name}}' => $faker->{{type}}, \ No newline at end of file