Skip to content

Commit

Permalink
Merge pull request #22 from spiral-packages/hotfix/seed-specific-seeder
Browse files Browse the repository at this point in the history
Fixes problem with seeding seeder by given class name
  • Loading branch information
butschster authored Jul 12, 2023
2 parents 86545c0 + efe0334 commit 0c999a0
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 18 deletions.
15 changes: 15 additions & 0 deletions src/Bootloader/DatabaseSeederBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
namespace Spiral\DatabaseSeeder\Bootloader;

use Spiral\Boot\Bootloader\Bootloader;
use Spiral\DatabaseSeeder\Seeder\AttributeLocator;
use Spiral\DatabaseSeeder\Seeder\DirectoryLocator;
use Spiral\DatabaseSeeder\Seeder\Locator;

/**
* Contains all package bootloaders
Expand All @@ -16,4 +19,16 @@ class DatabaseSeederBootloader extends Bootloader
CommandBootloader::class,
ScaffolderBootloader::class,
];

protected const SINGLETONS = [
Locator::class => [self::class, 'initLocator'],
];

private function initLocator(AttributeLocator $attributeLocator, DirectoryLocator $directoryLocator): Locator
{
return new Locator(
$directoryLocator,
$attributeLocator,
);
}
}
9 changes: 3 additions & 6 deletions src/Seeder/AttributeLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
use Spiral\Core\FactoryInterface;
use Spiral\Tokenizer\ClassesInterface;

class AttributeLocator
final class AttributeLocator implements LocatorInterface
{
public function __construct(
private readonly ClassesInterface $classesLocator,
private readonly ReaderInterface $reader,
private readonly FactoryInterface $factory
private readonly FactoryInterface $factory,
) {
}

/**
* @return SeederInterface[]
*/
public function find(): array
{
$seeders = [];
Expand All @@ -33,7 +30,7 @@ public function find(): array
$seeder = $this->factory->make($class->getName(), ['priority' => $attr->priority]);

\assert($seeder instanceof SeederInterface);
$seeders[] = $seeder;
$seeders[$seeder::class] = $seeder;
}
}

Expand Down
9 changes: 3 additions & 6 deletions src/Seeder/DirectoryLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
use Spiral\Files\FilesInterface;
use Spiral\Tokenizer\Reflection\ReflectionFile;

class DirectoryLocator
final class DirectoryLocator implements LocatorInterface
{
public function __construct(
private readonly FilesInterface $files,
private readonly DatabaseSeederConfig $config,
private readonly FactoryInterface $factory
private readonly FactoryInterface $factory,
) {
}

/**
* @return SeederInterface[]
*/
public function find(): array
{
if (!$this->files->isDirectory($this->config->getSeedersDirectory())) {
Expand All @@ -36,7 +33,7 @@ public function find(): array
continue;
}

$seeders[] = $this->factory->make($classes[0]);
$seeders[$classes[0]] = $this->factory->make($classes[0]);
}

return $seeders;
Expand Down
19 changes: 13 additions & 6 deletions src/Seeder/Locator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,30 @@

class Locator
{
/**@var LocatorInterface[] */
private array $locator;

public function __construct(
private AttributeLocator $attributeLocator,
private DirectoryLocator $directoryLocator
LocatorInterface ...$locator,
) {
$this->locator = $locator;
}

/**
* @return SeederInterface[]
*/
public function findSeeders(?string $seeder = null): array
{
$seeders = \array_replace($this->directoryLocator->find(), $this->attributeLocator->find());
$seeders = [];

foreach ($this->locator as $locator) {
$seeders = \array_merge($seeders, $locator->find());
}

if ($seeder) {
if ($seeder !== null) {
$seeders = \array_filter(
$seeders,
fn(SeederInterface $seeder) => (new \ReflectionClass($seeder))->getShortName() === $seeder
static fn(SeederInterface $s): bool => (new \ReflectionClass($s))->getShortName() === $seeder,
);
}

Expand All @@ -34,7 +41,7 @@ public function findSeeders(?string $seeder = null): array
return ($a->getPriority() < $b->getPriority()) ? -1 : 1;
});

return $seeders;
return \array_values($seeders);
}

public static function isSeederClass(\ReflectionClass $class): bool
Expand Down
14 changes: 14 additions & 0 deletions src/Seeder/LocatorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Spiral\DatabaseSeeder\Seeder;

interface LocatorInterface
{
/**
* @template T of SeederInterface
* @return array<class-string<T>, T>
*/
public function find(): array;
}
63 changes: 63 additions & 0 deletions tests/src/Unit/Seeder/LocatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace Tests\Unit\Seeder;

use PHPUnit\Framework\TestCase;
use Spiral\DatabaseSeeder\Seeder\Locator;
use Spiral\DatabaseSeeder\Seeder\LocatorInterface;
use Tests\Database\Seeder\CommentSeeder;
use Tests\Database\Seeder\PostSeeder;
use Tests\Database\Seeder\UserSeeder;

final class LocatorTest extends TestCase
{
public function testFindSeederByName(): void
{
$locator = new Locator(
$seedersLocator = \Mockery::mock(LocatorInterface::class),
);

$seedersLocator->shouldReceive('find')->once()->andReturn([
$seeder = new CommentSeeder(),
new PostSeeder(),
new UserSeeder(),
]);

$seeders = $locator->findSeeders('CommentSeeder');

$this->assertEquals([$seeder], $seeders);
}


public function testFindAllSeeders(): void
{
$locator = new Locator(
$seedersLocator = \Mockery::mock(LocatorInterface::class),
$directoriesSeedersLocator = \Mockery::mock(LocatorInterface::class),
);

$seedersLocator->shouldReceive('find')
->once()
->andReturn([
PostSeeder::class => new PostSeeder(),
UserSeeder::class => $userSeeder = new UserSeeder(),
]);

$directoriesSeedersLocator->shouldReceive('find')
->once()
->andReturn([
PostSeeder::class => $postSeeder = new PostSeeder(),
CommentSeeder::class => $commentSeeder = new CommentSeeder()
]);

$seeders = $locator->findSeeders();

$this->assertEquals([
$postSeeder,
$commentSeeder,
$userSeeder,
], $seeders);
}
}

0 comments on commit 0c999a0

Please sign in to comment.