diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100644 index c3bb259..0000000 --- a/.styleci.yml +++ /dev/null @@ -1 +0,0 @@ -preset: laravel \ No newline at end of file diff --git a/composer.json b/composer.json index 57e5181..9c73398 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,8 @@ "type": "library", "license": "MIT", "require": { - "php": "^7.2", - "laravel/framework": "5.5.*|5.6.*|5.7.*|5.8.*|^6.0|^7.0", + "php": "^7.3", + "laravel/framework": "^8.0", "doctrine/dbal": "^2.9" }, "autoload": { diff --git a/src/Commands/PopulatedFactoryMake.php b/src/Commands/PopulatedFactoryMake.php index 3ecb2af..efae8fe 100644 --- a/src/Commands/PopulatedFactoryMake.php +++ b/src/Commands/PopulatedFactoryMake.php @@ -25,34 +25,23 @@ class PopulatedFactoryMake extends Command protected $description = 'Make populated factory'; /** - * Factory generator instance. - * - * @var FactoryGenerator - */ - protected $factoryGenerator; - - /** - * Create a new command instance. + * Execute the console command. * * @param FactoryGenerator $factoryGenerator - */ - public function __construct(FactoryGenerator $factoryGenerator) - { - parent::__construct(); - - $this->factoryGenerator = $factoryGenerator; - } - - /** - * Execute the console command. * * @return mixed */ - public function handle() + public function handle(FactoryGenerator $factoryGenerator) { $modelClass = $this->argument('model'); - $modelClass = Str::startsWith($modelClass, '\\') ? $modelClass : 'App\\'.$modelClass; + $appNamespace = trim($this->getLaravel()->getNamespace(), '\\'); + + if (! Str::startsWith($modelClass, '\\')) { + $modelClass = class_exists($appNamespace.'\\Models\\'.$modelClass) + ? $appNamespace.'\\Models\\'.$modelClass + : $appNamespace.'\\'.$modelClass; + } if (! class_exists($modelClass)) { $this->error( @@ -72,7 +61,7 @@ public function handle() return; } - $modelName = last(explode('\\', $modelClass)); + $modelName = class_basename($model); $factoryName = $this->argument('name') ?? $modelName.'Factory'; @@ -88,7 +77,7 @@ public function handle() return; } - $factoryContent = $this->factoryGenerator->generate($model); + $factoryContent = $factoryGenerator->generate($model); File::put($factoryPath, $factoryContent); diff --git a/src/FactoryGenerator.php b/src/FactoryGenerator.php index 54ed542..d885f50 100644 --- a/src/FactoryGenerator.php +++ b/src/FactoryGenerator.php @@ -14,18 +14,14 @@ class FactoryGenerator const NL = PHP_EOL; - protected $connection; - protected $guesser; protected $columnShouldBeIgnored; protected $appendFactoryPhpDoc = true; - public function __construct(Connection $connection, FakeValueExpressionGuesser $guesser, ColumnShouldBeIgnored $columnShouldBeIgnored) + public function __construct(FakeValueExpressionGuesser $guesser, ColumnShouldBeIgnored $columnShouldBeIgnored) { - $this->connection = $connection; - $this->guesser = $guesser; $this->columnShouldBeIgnored = $columnShouldBeIgnored; @@ -37,39 +33,61 @@ public function generate(Model $model): string $columns = $this->columns($table); - return collect([ - 'when($this->appendFactoryPhpDoc, function (Collection $collection) { - return $collection->merge([ - self::NL, '/** @var \Illuminate\Database\Eloquent\Factory $factory */', self::NL, - ]); - })->merge([ - self::NL, '$factory->define(\\', get_class($model), '::class, function (Faker $faker) {', - self::NL, self::TAB, 'return [', self::NL - ])->pipe(function (Collection $collection) use ($columns) { - foreach ($columns as $column) { + $modelNamespace = get_class($model); + + $modelClassName = class_basename($model); + + $definition = collect($columns) + ->map(function (Column $column) { if (($this->columnShouldBeIgnored)($column)) { - continue; + return null; } if (is_null($value = $this->guessValue($column))) { - continue; + return null; } - $collection = $collection->merge([ - self::TAB, self::TAB, '\'', $column->getName(), '\' => ', $value, ',', self::NL, - ]); - } + return str_repeat(self::TAB, 3).'\''.$column->getName().'\' => '.$value.','; + }) + ->filter() + ->implode(self::NL); + + return <<merge([ - self::TAB, '];', self::NL, '});', self::NL, - ])->implode(''); +class {$modelClassName}Factory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected \$model = {$modelClassName}::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ +{$definition} + ]; + } +} +FACTORY; } protected function table(Model $model): Table { - $schemaManager = $this->connection + $schemaManager = $model->getConnection() ->getDoctrineSchemaManager(); $schemaManager->getDatabasePlatform() @@ -78,6 +96,10 @@ protected function table(Model $model): Table return $schemaManager->listTableDetails($model->getTable()); } + /** + * @param Table $table + * @return Column[]|array + */ protected function columns(Table $table): array { return $table->getColumns(); diff --git a/src/FakeValueExpressionGuesser.php b/src/FakeValueExpressionGuesser.php index aabee0e..bbb5fb9 100644 --- a/src/FakeValueExpressionGuesser.php +++ b/src/FakeValueExpressionGuesser.php @@ -62,69 +62,69 @@ protected function guessForString(Column $column) case $this->similar($name, ['password']): return '\'$2y$10$uTDnsRa0h7wLppc8/vB9C.YqsrAZwhjCgLWjcmpbndTmyo1k5tbRC\''; case $this->similar($name, ['email', 'emailaddress']): - return '$faker->unique()->safeEmail'; + return '$this->faker->unique()->safeEmail'; case $this->similar($name, ['name']): - return '$faker->name'; + return '$this->faker->name'; case $this->similar($name, ['firstname']): - return '$faker->firstName'; + return '$this->faker->firstName'; case $this->similar($name, ['lastname']): - return '$faker->lastName'; + return '$this->faker->lastName'; case $this->similar($name, ['address', 'streetaddress']): - return '$faker->streetAddress'; + return '$this->faker->streetAddress'; case $this->similar($name, ['city']): - return '$faker->city'; + return '$this->faker->city'; case $this->similar($name, ['postcode', 'postalcode']): - return '$faker->postcode'; + return '$this->faker->postcode'; case $this->similar($name, ['country']): - return '$faker->country'; + return '$this->faker->country'; case $this->similar($name, ['phone', 'number', 'phonenumber']): - return '$faker->phoneNumber'; + return '$this->faker->phoneNumber'; case $this->similar($name, ['company', 'company_name']): - return '$faker->company'; + return '$this->faker->company'; case $this->similar($name, ['job', 'jobtitle']): - return '$faker->jobTitle'; + return '$this->faker->jobTitle'; case $this->similar($name, ['credit_card', 'creditcardnumber']): - return '$faker->creditCardNumber'; + return '$this->faker->creditCardNumber'; case $this->similar($name, ['creditcardexpirationdate', 'expirationdate']): - return '$faker->creditCardExpirationDateString'; + return '$this->faker->creditCardExpirationDateString'; case $this->similar($name, ['username', 'nickname']): - return '$faker->userName'; + return '$this->faker->userName'; case $this->similar($name, ['domain', 'domainname']): - return '$faker->domainName'; + return '$this->faker->domainName'; case $this->similar($name, ['tld']): - return '$faker->tld'; + return '$this->faker->tld'; case $this->similar($name, ['url', 'link', 'uri', 'externallink', 'externalurl']): - return '$faker->url'; + return '$this->faker->url'; case $this->similar($name, ['slug']): - return '$faker->slug'; + return '$this->faker->slug'; case $this->similar($name, ['ip']): - return '$faker->ipv4'; + return '$this->faker->ipv4'; case $this->similar($name, ['mac', 'macaddress']): - return '$faker->macAddress'; + return '$this->faker->macAddress'; case $this->similar($name, ['timezone']): - return '$faker->timezone'; + return '$this->faker->timezone'; case $this->similar($name, ['countrycode']): - return '$faker->countryCode'; + return '$this->faker->countryCode'; case $this->similar($name, ['languagecode', 'language', 'locale']): - return '$faker->languageCode'; + return '$this->faker->languageCode'; case $this->similar($name, ['currencycode', 'currency']): - return '$faker->currencyCode'; + return '$this->faker->currencyCode'; case $this->similar($name, ['useragent']): - return '$faker->userAgent'; + return '$this->faker->userAgent'; case $this->similar($name, ['uuid']): - return '$faker->uuid'; + return '$this->faker->uuid'; case $this->similar($name, ['mime', 'mimetype']): - return '$faker->mimeType'; + return '$this->faker->mimeType'; case $this->similar($name, ['image', 'imagepath', 'img']): - return '$faker->image'; + return '$this->faker->image'; case $this->similar($name, ['html']): - return '$faker->randomHtml'; + return '$this->faker->randomHtml'; case $this->similar($name, ['hex', 'color']): - return '$faker->hexColor'; + return '$this->faker->hexColor'; case Str::contains($name, 'token'): - return '$faker->sha1'; + return '$this->faker->sha1'; default: - return '$faker->text('.((int) (($column->getLength() ?? 200) / 4)).')'; + return '$this->faker->text('.((int) (($column->getLength() ?? 200) / 4)).')'; } } @@ -135,7 +135,7 @@ protected function guessForText(Column $column) protected function guessForBoolean(Column $column) { - return '$faker->boolean(50)'; + return '$this->faker->boolean(50)'; } protected function guessForDatetime(Column $column) @@ -145,11 +145,11 @@ protected function guessForDatetime(Column $column) switch (true) { case $this->similar($name, ['expiration_date']): - return '$faker->dateTimeBetween(\'+1 year\', \'+5 years\')'; + return '$this->faker->dateTimeBetween(\'+1 year\', \'+5 years\')'; case $this->similar($name, ['birth', 'born_at', 'birthday', 'date_of_birth']): - return '$faker->dateTimeBetween(\'-60 years\', \'-1 year\')'; + return '$this->faker->dateTimeBetween(\'-60 years\', \'-1 year\')'; default: - return '$faker->dateTime'; + return '$this->faker->dateTime'; } } @@ -165,11 +165,11 @@ protected function guessForFloat(Column $column) switch (true) { case $this->similar($name, ['lat', 'latitude']): - return '$faker->latitude'; + return '$this->faker->latitude'; case $this->similar($name, ['lon', 'lng', 'longitude']): - return '$faker->longitude'; + return '$this->faker->longitude'; default: - return '$faker->randomFloat'; + return '$this->faker->randomFloat'; } } @@ -181,19 +181,19 @@ protected function guessForDecimal(Column $column) protected function guessForSmallint(Column $column) { if ($column->getUnsigned()) { - return '$faker->numberBetween(0, 65535)'; + return '$this->faker->numberBetween(0, 65535)'; } - return '$faker->numberBetween(-32768, 32767)'; + return '$this->faker->numberBetween(-32768, 32767)'; } protected function guessForInteger(Column $column) { if ($column->getUnsigned()) { - return '$faker->numberBetween(0, 4294967295)'; + return '$this->faker->numberBetween(0, 4294967295)'; } - return '$faker->numberBetween(-2147483648, 2147483647)'; + return '$this->faker->numberBetween(-2147483648, 2147483647)'; } protected function guessForBigint(Column $column)