Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Illia Sakovich committed Sep 9, 2020
1 parent f078a31 commit a0c112d
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 95 deletions.
1 change: 0 additions & 1 deletion .styleci.yml

This file was deleted.

4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
33 changes: 11 additions & 22 deletions src/Commands/PopulatedFactoryMake.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -72,7 +61,7 @@ public function handle()
return;
}

$modelName = last(explode('\\', $modelClass));
$modelName = class_basename($model);

$factoryName = $this->argument('name') ?? $modelName.'Factory';

Expand All @@ -88,7 +77,7 @@ public function handle()
return;
}

$factoryContent = $this->factoryGenerator->generate($model);
$factoryContent = $factoryGenerator->generate($model);

File::put($factoryPath, $factoryContent);

Expand Down
76 changes: 49 additions & 27 deletions src/FactoryGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -37,39 +33,61 @@ public function generate(Model $model): string

$columns = $this->columns($table);

return collect([
'<?php', self::NL, self::NL, 'use Faker\Generator as Faker;', self::NL,
])->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 <<<FACTORY
<?php
namespace Database\Factories;
use {$modelNamespace};
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
return $collection;
})->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()
Expand All @@ -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();
Expand Down
86 changes: 43 additions & 43 deletions src/FakeValueExpressionGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)).')';
}
}

Expand All @@ -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)
Expand All @@ -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';
}
}

Expand All @@ -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';
}
}

Expand All @@ -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)
Expand Down

0 comments on commit a0c112d

Please sign in to comment.