Skip to content

Commit

Permalink
Generate factories within domain layer. (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaspertey authored Mar 30, 2024
1 parent 6734315 commit 5221d15
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 43 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ All notable changes to `laravel-ddd` will be documented in this file.
- Support for autoloading and discovery of domain service providers, commands, policies, and factories.

### Changed
- Minimum supported Laravel version is now 10.25.
- (BREAKING) For applications that published the config prior to this release, config should be removed, re-published, and re-configured.
- (BREAKING) Generator commands no longer receive a domain argument. Instead of `ddd:action Invoicing CreateInvoice`, one of the following would be used:
- Using the --domain option: `ddd:action CreateInvoice --domain=Invoicing` (this takes precedence).
- Shorthand syntax: `ddd:action Invoicing:CreateInvoice`.
- Or simply `ddd:action CreateInvoice` to be prompted for the domain afterwards.
- Improved the reliability of generating base view models when `ddd.base_view_model` is something other than the default `Domain\Shared\ViewModels\ViewModel`.
- Domain factories are now generated inside the domain layer under the configured factory namespace `ddd.namespaces.factory` (default `Database\Factories`). Factories located in `/database/factories/<domain>/*` (v0.x) will continue to work as a fallback when attempting to resolve a domain model's factory.
- Minimum supported Laravel version is now 10.25.

### Chore
- Dropped Laravel 9 support.
Expand Down
27 changes: 1 addition & 26 deletions src/Commands/DomainFactoryMakeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Lunarstorm\LaravelDDD\Commands;

use Lunarstorm\LaravelDDD\Support\Path;
use Symfony\Component\Console\Input\InputOption;

class DomainFactoryMakeCommand extends DomainGeneratorCommand
Expand Down Expand Up @@ -31,37 +30,13 @@ protected function getStub()
return $this->resolveStubPath('factory.php.stub');
}

protected function rootNamespace()
{
return 'Database\\Factories\\';
}

protected function getDefaultNamespace($rootNamespace)
{
$domain = $this->domain?->domainWithSubdomain;

return $rootNamespace.'\\'.$domain;
}

protected function getRelativeDomainNamespace(): string
{
return '';
}

protected function getPath($name)
{
if (! str_ends_with($name, 'Factory')) {
$name .= 'Factory';
}

$name = str($name)
->replaceFirst($this->rootNamespace(), '')
->replace('\\', '/')
->ltrim('/')
->append('.php')
->toString();

return Path::normalize(base_path('database/factories/'.$name));
return parent::getPath($name);
}

protected function getFactoryName()
Expand Down
13 changes: 1 addition & 12 deletions src/Support/Domain.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,7 @@ public function model(string $name): DomainObject

public function factory(string $name): DomainObject
{
$name = str($name)->replace($this->namespace->root, '')->toString();

return new DomainObject(
name: $name,
domain: $this->domain,
namespace: $this->namespace->factories,
fullyQualifiedName: $this->namespace->factories.'\\'.$name,
path: str("database/factories/{$this->domainWithSubdomain}/{$name}.php")
->replace(['\\', '/'], DIRECTORY_SEPARATOR)
->toString(),
type: 'factory'
);
return $this->object('factory', $name);
}

public function dataTransferObject(string $name): DomainObject
Expand Down
16 changes: 14 additions & 2 deletions tests/Factory/DomainFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@
use Lunarstorm\LaravelDDD\Factories\DomainFactory;

it('can resolve the factory name of a domain model', function ($modelClass, $expectedFactoryClass) {
$this->setupTestApplication();

expect(DomainFactory::resolveFactoryName($modelClass))->toBe($expectedFactoryClass);
})->with([
["Domain\Customer\Models\Invoice", "Database\Factories\Customer\InvoiceFactory"],
["Domain\Reports\Accounting\Models\InvoiceReport", "Database\Factories\Reports\Accounting\InvoiceReportFactory"],
["Domain\Invoicing\Models\Invoice", "Domain\Invoicing\Database\Factories\InvoiceFactory"],
["Domain\Invoicing\Models\VanillaModel", "Domain\Invoicing\Database\Factories\VanillaModelFactory"],
["App\Models\Invoice", null],
]);

it('is backwards compatible with factories located in database/factories/**/*', function ($modelClass, $expectedFactoryClass) {
$this->setupTestApplication();

expect(DomainFactory::resolveFactoryName($modelClass))->toBe($expectedFactoryClass);
})->with([
["Domain\Customer\Models\Customer", "Database\Factories\Customer\CustomerFactory"],
["Domain\Reports\Accounting\Models\InvoiceReport", "Database\Factories\Reports\Accounting\InvoiceReportFactory"],
["Domain\Invoicing\Models\Payment", "Database\Factories\Invoicing\PaymentFactory"],
]);

it('can instantiate a domain model factory', function ($domainParameter, $modelName, $modelClass) {
Config::set('ddd.base_model', 'Lunarstorm\LaravelDDD\Models\DomainModel');
Artisan::call("ddd:model -f {$domainParameter}:{$modelName}");
Expand Down
4 changes: 2 additions & 2 deletions tests/Support/DomainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
->fullyQualifiedName->toBe($expectedFQN)
->path->toBe(Path::normalize($expectedPath));
})->with([
['Reporting', 'InvoiceReportFactory', 'Database\\Factories\\Reporting\\InvoiceReportFactory', 'database/factories/Reporting/InvoiceReportFactory.php'],
['Reporting.Internal', 'InvoiceReportFactory', 'Database\\Factories\\Reporting\\Internal\\InvoiceReportFactory', 'database/factories/Reporting/Internal/InvoiceReportFactory.php'],
['Reporting', 'InvoiceReportFactory', 'Domain\\Reporting\\Database\\Factories\\InvoiceReportFactory', 'src/Domain/Reporting/Database/Factories/InvoiceReportFactory.php'],
['Reporting.Internal', 'InvoiceReportFactory', 'Domain\\Reporting\\Internal\\Database\\Factories\\InvoiceReportFactory', 'src/Domain/Reporting/Internal/Database/Factories/InvoiceReportFactory.php'],
]);

it('can describe a data transfer object', function ($domainName, $name, $expectedFQN, $expectedPath) {
Expand Down

0 comments on commit 5221d15

Please sign in to comment.