Skip to content

Commit

Permalink
[feat] add default for Mongo properties in (#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil authored Nov 15, 2022
1 parent 778607a commit b1d7ce3
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 31 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"matthiasnoback/symfony-dependency-injection-test": "^4.1",
"symfony/framework-bundle": "^4.4|^5.0|^6.0",
"symfony/maker-bundle": "^1.30",
"symfony/phpunit-bridge": "^6.0"
"symfony/phpunit-bridge": "^6.0",
"symfony/translation-contracts": "^3.0"
},
"config": {
"preferred-install": "dist",
Expand Down
16 changes: 11 additions & 5 deletions src/Bundle/Maker/MakeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Zenstruck\Foundry\Bundle\Maker;

use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as ODMClassMetadata;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadataInfo as ORMClassMetadata;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
use Symfony\Bundle\MakerBundle\ConsoleStyle;
use Symfony\Bundle\MakerBundle\DependencyBuilder;
use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException;
Expand All @@ -21,7 +24,7 @@
*/
final class MakeFactory extends AbstractMaker
{
private const ORM_DEFAULTS = [
private const DEFAULTS = [
'ARRAY' => '[],',
'ASCII_STRING' => 'self::faker()->text(),',
'BIGINT' => 'self::faker()->randomNumber(),',
Expand Down Expand Up @@ -211,24 +214,27 @@ private function defaultPropertiesFor(string $class, bool $allFields): iterable
{
$em = $this->managerRegistry->getManagerForClass($class);

if (!$em instanceof EntityManagerInterface) {
if (!$em instanceof ObjectManager) {
return [];
}

/** @var ORMClassMetadata|ODMClassMetadata $metadata */
$metadata = $em->getClassMetadata($class);
$ids = $metadata->getIdentifierFieldNames();

$dbType = $em instanceof EntityManagerInterface ? 'ORM' : 'ODM';

foreach ($metadata->fieldMappings as $property) {
// ignore identifiers and nullable fields
if ((!$allFields && ($property['nullable'] ?? false)) || \in_array($property['fieldName'], $ids, true)) {
continue;
}

$type = \mb_strtoupper($property['type']);
$value = "null, // TODO add {$type} ORM type manually";
$value = "null, // TODO add {$type} {$dbType} type manually";

if (\array_key_exists($type, self::ORM_DEFAULTS)) {
$value = self::ORM_DEFAULTS[$type];
if (\array_key_exists($type, self::DEFAULTS)) {
$value = self::DEFAULTS[$type];
}

yield $property['fieldName'] => $value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace App\Factory;

use Zenstruck\Foundry\Tests\Fixtures\Document\Post;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;

/**
* @extends ModelFactory<Post>
*
* @method Post|Proxy create(array|callable $attributes = [])
* @method static Post|Proxy createOne(array $attributes = [])
* @method static Post|Proxy find(object|array|mixed $criteria)
* @method static Post|Proxy findOrCreate(array $attributes)
* @method static Post|Proxy first(string $sortedField = 'id')
* @method static Post|Proxy last(string $sortedField = 'id')
* @method static Post|Proxy random(array $attributes = [])
* @method static Post|Proxy randomOrCreate(array $attributes = [])
* @method static list<Post>|list<Proxy> all()
* @method static list<Post>|list<Proxy> createMany(int $number, array|callable $attributes = [])
* @method static list<Post>|list<Proxy> createSequence(array|callable $sequence)
* @method static list<Post>|list<Proxy> findBy(array $attributes)
* @method static list<Post>|list<Proxy> randomRange(int $min, int $max, array $attributes = [])
* @method static list<Post>|list<Proxy> randomSet(int $number, array $attributes = [])
*/
final class PostFactory extends ModelFactory
{
public function __construct()
{
parent::__construct();

// TODO inject services if required (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services)
}

protected function getDefaults(): array
{
return [
// TODO add your default values here (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories)
'title' => self::faker()->text(),
'body' => self::faker()->text(),
'viewCount' => null, // TODO add INT ODM type manually
'createdAt' => self::faker()->dateTime(),
'comments' => null, // TODO add MANY ODM type manually
'user' => null, // TODO add ONE ODM type manually
];
}

protected function initialize(): self
{
// see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
return $this
// ->afterInstantiate(function(Post $post): void {})
;
}

protected static function getClass(): string
{
return Post::class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace App\Factory;

use Zenstruck\Foundry\Tests\Fixtures\Document\Comment;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;

/**
* @extends ModelFactory<Comment>
*
* @method Comment|Proxy create(array|callable $attributes = [])
* @method static Comment|Proxy createOne(array $attributes = [])
* @method static Comment|Proxy find(object|array|mixed $criteria)
* @method static Comment|Proxy findOrCreate(array $attributes)
* @method static Comment|Proxy first(string $sortedField = 'id')
* @method static Comment|Proxy last(string $sortedField = 'id')
* @method static Comment|Proxy random(array $attributes = [])
* @method static Comment|Proxy randomOrCreate(array $attributes = [])
* @method static list<Comment>|list<Proxy> all()
* @method static list<Comment>|list<Proxy> createMany(int $number, array|callable $attributes = [])
* @method static list<Comment>|list<Proxy> createSequence(array|callable $sequence)
* @method static list<Comment>|list<Proxy> findBy(array $attributes)
* @method static list<Comment>|list<Proxy> randomRange(int $min, int $max, array $attributes = [])
* @method static list<Comment>|list<Proxy> randomSet(int $number, array $attributes = [])
*/
final class CommentFactory extends ModelFactory
{
public function __construct()
{
parent::__construct();

// TODO inject services if required (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services)
}

protected function getDefaults(): array
{
return [
// TODO add your default values here (https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories)
'user' => null, // TODO add ONE ODM type manually
'body' => self::faker()->text(),
'createdAt' => self::faker()->dateTime(),
'approved' => self::faker()->boolean(),
];
}

protected function initialize(): self
{
// see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
return $this
// ->afterInstantiate(function(Comment $comment): void {})
;
}

protected static function getClass(): string
{
return Comment::class;
}
}
27 changes: 6 additions & 21 deletions tests/Functional/Bundle/Maker/MakeFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ public function can_create_factory(): void

$tester->execute(['entity' => Category::class]);

$this->assertFileFromMakerSameAsExpectedFile(
$this->expectedFile('CategoryFactory.php'),
self::tempFile('src/Factory/CategoryFactory.php')
);
$this->assertFileFromMakerSameAsExpectedFile(self::tempFile('src/Factory/CategoryFactory.php'));
}

/**
Expand All @@ -70,10 +67,7 @@ public function can_create_factory_interactively(): void
$this->assertStringNotContainsString(Category::class, $output);
$this->assertStringContainsString('Note: pass --test if you want to generate factories in your tests/ directory', $output);

$this->assertFileFromMakerSameAsExpectedFile(
$this->expectedFile('TagFactory.php'),
self::tempFile('src/Factory/TagFactory.php')
);
$this->assertFileFromMakerSameAsExpectedFile(self::tempFile('src/Factory/TagFactory.php'));
}

/**
Expand All @@ -91,10 +85,7 @@ public function can_create_factory_in_test_dir(): void

$tester->execute(['entity' => Category::class, '--test' => true]);

$this->assertFileFromMakerSameAsExpectedFile(
$this->expectedFile('CategoryFactory.php'),
self::tempFile('tests/Factory/CategoryFactory.php')
);
$this->assertFileFromMakerSameAsExpectedFile(self::tempFile('tests/Factory/CategoryFactory.php'));
}

/**
Expand All @@ -118,10 +109,7 @@ public function can_create_factory_in_test_dir_interactively(): void
$this->assertStringNotContainsString(Category::class, $output);
$this->assertStringNotContainsString('Note: pass --test if you want to generate factories in your tests/ directory', $output);

$this->assertFileFromMakerSameAsExpectedFile(
$this->expectedFile('TagFactory.php'),
self::tempFile('tests/Factory/TagFactory.php')
);
$this->assertFileFromMakerSameAsExpectedFile(self::tempFile('tests/Factory/TagFactory.php'));
}

/**
Expand All @@ -142,10 +130,7 @@ public function can_create_factory_with_phpstan_annotations(): void

$tester->execute(['entity' => Category::class]);

$this->assertFileFromMakerSameAsExpectedFile(
$this->expectedFile('CategoryFactory.php'),
self::tempFile('src/Factory/CategoryFactory.php')
);
$this->assertFileFromMakerSameAsExpectedFile(self::tempFile('src/Factory/CategoryFactory.php'));
}

/**
Expand Down Expand Up @@ -293,7 +278,7 @@ public function can_create_factory_for_odm(string $class, string $file): void
$tester->setInputs([$class]);
$tester->execute([]);

$this->assertFileExists(self::tempFile("src/Factory/{$file}.php"));
$this->assertFileFromMakerSameAsExpectedFile(self::tempFile("src/Factory/{$file}.php"));
}

public function documentProvider(): iterable
Expand Down
17 changes: 13 additions & 4 deletions tests/Functional/Bundle/Maker/MakerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\String\Slugger\AsciiSlugger;

/**
* @author Kevin Bond <kevinbond@gmail.com>
Expand Down Expand Up @@ -42,14 +43,22 @@ protected static function tempFile(string $path): string
return \sprintf('%s/%s', self::tempDir(), $path);
}

protected function expectedFile(string $file): string
protected function expectedFile(): string
{
return \sprintf('%s/../../../Fixtures/Maker/%s/%s', __DIR__, $this->getName(), $file);
$path = \sprintf(
'%s/../../../Fixtures/Maker/expected/%s.php',
__DIR__,
(new AsciiSlugger())->slug($this->getName())
);

$this->assertFileExists($path);

return \realpath($path);
}

protected function assertFileFromMakerSameAsExpectedFile(string $expectedFile, string $fileFromMaker): void
protected function assertFileFromMakerSameAsExpectedFile(string $fileFromMaker): void
{
$this->assertFileExists($fileFromMaker);
$this->assertFileEquals($expectedFile, $fileFromMaker);
$this->assertFileEquals($this->expectedFile(), $fileFromMaker);
}
}

0 comments on commit b1d7ce3

Please sign in to comment.