From 01288b7e627210b44da1a4b7856b468aea95d5f9 Mon Sep 17 00:00:00 2001 From: lotyp Date: Thu, 25 May 2023 18:05:01 +0300 Subject: [PATCH] feat: add aggregatable traits --- Makefile | 12 +- composer.json | 57 ++-- composer.lock | 321 ++++++++++++++---- config/{package.php => event-sourcing.php} | 1 - database/factories/ModelFactory.php | 17 - .../migrations/create_package_table.php.stub | 19 -- phpunit.xml.dist | 16 +- .../EventSourcingServiceProvider.php | 26 ++ src/Commands/PackageCommand.php | 21 -- src/Events/Concerns/AggregatableRoot.php | 51 +++ src/Events/Concerns/AggregatableRootId.php | 46 +++ src/Facades/Package.php | 15 - src/Package.php | 25 -- src/PackageServiceProvider.php | 27 -- tests/Pest.php | 2 +- tests/TestCase.php | 26 +- 16 files changed, 430 insertions(+), 252 deletions(-) rename config/{package.php => event-sourcing.php} (51%) delete mode 100644 database/factories/ModelFactory.php delete mode 100644 database/migrations/create_package_table.php.stub create mode 100644 src/Bridge/Laravel/Providers/EventSourcingServiceProvider.php delete mode 100644 src/Commands/PackageCommand.php create mode 100644 src/Events/Concerns/AggregatableRoot.php create mode 100644 src/Events/Concerns/AggregatableRootId.php delete mode 100644 src/Facades/Package.php delete mode 100644 src/Package.php delete mode 100644 src/PackageServiceProvider.php diff --git a/Makefile b/Makefile index b39ed84..2355840 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ else WHITE := "" RST := "" endif -MAKE_LOGFILE = /tmp/wayofdev-laravel-package-tpl.log +MAKE_LOGFILE = /tmp/wayofdev-laravel-cycle-event-sourcing.log MAKE_CMD_COLOR := $(BLUE) # https://phpstan.org/user-guide/output-format @@ -43,7 +43,7 @@ help: @echo @echo ' 📑 Logs are stored in $(MAKE_LOGFILE)' @echo - @echo ' 📦 Package laravel-package-tpl (github.com/wayofdev/laravel-package-tpl)' + @echo ' 📦 Package laravel-cycle-event-sourcing (github.com/wayofdev/laravel-cycle-event-sourcing)' @echo ' 🤠 Author Andrij Orlenko (github.com/lotyp)' @echo ' 🏢 ${YELLOW}Org wayofdev (github.com/wayofdev)${RST}' .PHONY: help @@ -68,11 +68,11 @@ update: ## Updates composer dependencies by running composer update command # Testing # ------------------------------------------------------------------------------------ cs-diff: prepare ## Runs php-cs-fixer in dry-run mode and shows diff which will by applied - $(COMPOSER_RUN) cs-diff + $(COMPOSER_RUN) cs:diff .PHONY: cs-diff cs-fix: prepare ## Fixes code to follow coding standards using php-cs-fixer - $(COMPOSER_RUN) cs-fix + $(COMPOSER_RUN) cs:fix .PHONY: cs-fix stan: ## Runs phpstan – static analysis tool @@ -80,7 +80,7 @@ stan: ## Runs phpstan – static analysis tool .PHONY: stan stan-ci: - $(COMPOSER_RUN) stan-ci + $(COMPOSER_RUN) stan:ci .PHONY: stan-ci test: ## Run project php-unit and pest tests @@ -88,7 +88,7 @@ test: ## Run project php-unit and pest tests .PHONY: test test-cc: ## Run project php-unit and pest tests in coverage mode and build report - $(COMPOSER_RUN) test-cc + $(COMPOSER_RUN) test:cc .PHONY: test-cc # Yaml Actions diff --git a/composer.json b/composer.json index 5644fdb..d3e942d 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "wayofdev/laravel-package-tpl", - "description": "PHP package template with GitHub Actions", + "name": "wayofdev/cycle-event-sourcing", + "description": "Package that provides Cycle ORM integration with EventSauce in Laravel.", "type": "library", "license": "MIT", "homepage": "https://wayof.dev", @@ -16,43 +16,45 @@ ], "require": { "php": "^8.1", - "illuminate/contracts": "^10.7.1", - "spatie/laravel-package-tools": "^1.14.2", - "nunomaduro/collision": "^7.4.0" + "ext-decimal": "*", + "ext-json": "*", + "beberlei/assert": "^3.3", + "eventsauce/eventsauce": "^3.4", + "illuminate/contracts": "^10.12", + "nunomaduro/collision": "^7.4" }, "require-dev": { - "ergebnis/composer-normalize": "^2.30.2", - "nunomaduro/larastan": "^2.5.1", - "orchestra/testbench": "^8.3.1", - "pestphp/pest": "^2.4.0", - "pestphp/pest-plugin-laravel": "^2.0.0", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.10.11", - "phpstan/phpstan-deprecation-rules": "^1.1.3", - "phpstan/phpstan-phpunit": "^1.3.11", - "phpstan/phpstan-strict-rules": "^1.5.1", - "phpunit/phpunit": "^10.0.19", + "ergebnis/composer-normalize": "^2.31", + "nunomaduro/larastan": "^2.6", + "orchestra/testbench": "^8.3", + "pestphp/pest": "^2.4", + "pestphp/pest-plugin-laravel": "^2.0", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "^10.1", "roave/security-advisories": "dev-latest", - "wayofdev/cs-fixer-config": "^1.1.11" + "wayofdev/cs-fixer-config": "^1.2" }, "autoload": { "psr-4": { - "WayOfDev\\Laravel\\Package\\": "src/", - "WayOfDev\\Laravel\\Package\\Database\\Factories\\": "database/factories" + "WayOfDev\\EventSourcing\\": "src/" } }, "autoload-dev": { "psr-4": { - "WayOfDev\\Laravel\\Package\\Tests\\": "tests/" + "WayOfDev\\EventSourcing\\Tests\\": "tests/" } }, "scripts": { - "cs-fix": "php vendor/bin/php-cs-fixer fix -v", - "cs-diff": "php vendor/bin/php-cs-fixer fix --dry-run -v --diff", + "cs:fix": "php vendor/bin/php-cs-fixer fix -v", + "cs:diff": "php vendor/bin/php-cs-fixer fix --dry-run -v --diff", "test": "php vendor/bin/pest", - "test-cc": "php vendor/bin/pest --coverage", + "test:cc": "php vendor/bin/pest --coverage", "stan": "php vendor/bin/phpstan analyse", - "stan-ci": "php vendor/bin/phpstan analyse --error-format=github" + "stan:ci": "php vendor/bin/phpstan analyse --error-format=github" }, "config": { "sort-packages": true, @@ -65,11 +67,8 @@ "extra": { "laravel": { "providers": [ - "WayOfDev\\Laravel\\Package\\PackageServiceProvider" - ], - "aliases": { - "Package": "WayOfDev\\Laravel\\Package\\Facades\\Package" - } + "WayOfDev\\EventSourcing\\Bridge\\Laravel\\Providers\\EventSourcingServiceProvider" + ] }, "composer-normalize": { "indent-size": 4, diff --git a/composer.lock b/composer.lock index d302e70..8b48c49 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,75 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2749aec506107bef2680fb9e1aa96c1b", + "content-hash": "f1ce48e92c920eb11fab4990f9817d6e", "packages": [ + { + "name": "beberlei/assert", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/beberlei/assert.git", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": ">=6.0.0", + "yoast/phpunit-polyfills": "^0.1.0" + }, + "suggest": { + "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Assert/functions.php" + ], + "psr-4": { + "Assert\\": "lib/Assert" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "role": "Lead Developer" + }, + { + "name": "Richard Quadling", + "email": "rquadling@gmail.com", + "role": "Collaborator" + } + ], + "description": "Thin assertion library for input validation in business models.", + "keywords": [ + "assert", + "assertion", + "validation" + ], + "support": { + "issues": "https://github.com/beberlei/assert/issues", + "source": "https://github.com/beberlei/assert/tree/v3.3.2" + }, + "time": "2021-12-16T21:41:27+00:00" + }, { "name": "brick/math", "version": "0.11.0", @@ -432,6 +499,194 @@ ], "time": "2023-01-14T14:17:03+00:00" }, + { + "name": "eventsauce/clock", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/EventSaucePHP/Clock.git", + "reference": "0b740928a2bdbcbec836c912d9bee22b0c58ddb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/EventSaucePHP/Clock/zipball/0b740928a2bdbcbec836c912d9bee22b0c58ddb0", + "reference": "0b740928a2bdbcbec836c912d9bee22b0c58ddb0", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.18.4", + "phpstan/phpstan": "^0.12.82", + "phpunit/phpunit": "^9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "EventSauce\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Consume time from a Clock", + "keywords": [ + "EventSauce", + "clock", + "time" + ], + "support": { + "issues": "https://github.com/EventSaucePHP/Clock/issues", + "source": "https://github.com/EventSaucePHP/Clock/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2022-05-31T07:45:06+00:00" + }, + { + "name": "eventsauce/eventsauce", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/EventSaucePHP/EventSauce.git", + "reference": "a9231caa15f3bb129bb1502a2765d29a710fa696" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/EventSaucePHP/EventSauce/zipball/a9231caa15f3bb129bb1502a2765d29a710fa696", + "reference": "a9231caa15f3bb129bb1502a2765d29a710fa696", + "shasum": "" + }, + "require": { + "eventsauce/clock": "^1.0", + "eventsauce/object-hydrator": "^0.4.2 | ^0.5 | ^1.0.0", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "nikic/php-parser": "^v4.10.4", + "pestphp/pest": "^1.23", + "phpstan/phpstan": "^1.8.6", + "phpunit/phpunit": "^9.5.23|^10.0", + "ramsey/uuid": "^4.0", + "symfony/yaml": "^5.0 | ^6.0" + }, + "suggest": { + "eventsauce/code-generation": "Code generation for EventSauce", + "eventsauce/doctrine-message-repository": "Doctrine implementation of the message repository", + "eventsauce/test-utilities": "Base test tooling for testing aggregates" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-version/2.0": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "EventSauce\\EventSourcing\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "A pragmatic event sourcing library for PHP with a focus on developer experience.", + "homepage": "https://eventsauce.io/", + "support": { + "issues": "https://github.com/EventSaucePHP/EventSauce/issues", + "source": "https://github.com/EventSaucePHP/EventSauce/tree/3.4.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2023-05-14T09:41:34+00:00" + }, + { + "name": "eventsauce/object-hydrator", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/EventSaucePHP/ObjectHydrator.git", + "reference": "5187fba33e031b6c96c3b93bdfc21719e54108e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/EventSaucePHP/ObjectHydrator/zipball/5187fba33e031b6c96c3b93bdfc21719e54108e0", + "reference": "5187fba33e031b6c96c3b93bdfc21719e54108e0", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.4", + "league/construct-finder": "^1.1", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.7", + "phpunit/phpunit": "^9.5.11", + "ramsey/uuid": "^4.2" + }, + "suggest": { + "league/construct-finder": "Find all classes in a directory for the best dumped hydrators." + }, + "type": "library", + "autoload": { + "psr-4": { + "EventSauce\\ObjectHydrator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Converts structured data into strict objects.", + "keywords": [ + "construction", + "constructor", + "hydration", + "mapper" + ], + "support": { + "issues": "https://github.com/EventSaucePHP/ObjectHydrator/issues", + "source": "https://github.com/EventSaucePHP/ObjectHydrator/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2023-04-01T13:34:47+00:00" + }, { "name": "filp/whoops", "version": "2.15.2", @@ -2366,66 +2621,6 @@ ], "time": "2023-04-15T23:01:58+00:00" }, - { - "name": "spatie/laravel-package-tools", - "version": "1.15.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "efab1844b8826443135201c4443690f032c3d533" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/efab1844b8826443135201c4443690f032c3d533", - "reference": "efab1844b8826443135201c4443690f032c3d533", - "shasum": "" - }, - "require": { - "illuminate/contracts": "^9.28|^10.0", - "php": "^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.5", - "orchestra/testbench": "^7.7|^8.0", - "pestphp/pest": "^1.22", - "phpunit/phpunit": "^9.5.24", - "spatie/pest-plugin-test-time": "^1.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\LaravelPackageTools\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "role": "Developer" - } - ], - "description": "Tools for creating Laravel packages", - "homepage": "https://github.com/spatie/laravel-package-tools", - "keywords": [ - "laravel-package-tools", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.15.0" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2023-04-27T08:09:01+00:00" - }, { "name": "symfony/console", "version": "v6.2.10", @@ -10968,7 +11163,9 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.1" + "php": "^8.1", + "ext-decimal": "*", + "ext-json": "*" }, "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/config/package.php b/config/event-sourcing.php similarity index 51% rename from config/package.php rename to config/event-sourcing.php index 18786cc..1f6a841 100644 --- a/config/package.php +++ b/config/event-sourcing.php @@ -3,5 +3,4 @@ declare(strict_types=1); return [ - // config for WayOfDev\Laravel\Package ]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php deleted file mode 100644 index 911e488..0000000 --- a/database/factories/ModelFactory.php +++ /dev/null @@ -1,17 +0,0 @@ -id(); - - // add fields - - $table->timestamps(); - }); - } -}; diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 12da318..5f5ca6d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,12 +1,14 @@ + stopOnFailure="true" + stopOnError="true" + beStrictAboutOutputDuringTests="true" + cacheDirectory="./.build/phpunit.cache"> tests/Pest @@ -16,9 +18,6 @@ - - src - @@ -28,4 +27,9 @@ + + + src + + diff --git a/src/Bridge/Laravel/Providers/EventSourcingServiceProvider.php b/src/Bridge/Laravel/Providers/EventSourcingServiceProvider.php new file mode 100644 index 0000000..d1e1da8 --- /dev/null +++ b/src/Bridge/Laravel/Providers/EventSourcingServiceProvider.php @@ -0,0 +1,26 @@ +app->runningInConsole()) { + $this->publishes([ + __DIR__ . '/../../../../config/event-sourcing.php' => config_path('event-sourcing.php'), + ], 'config'); + + $this->registerConsoleCommands(); + } + } + + private function registerConsoleCommands(): void + { + $this->commands([]); + } +} diff --git a/src/Commands/PackageCommand.php b/src/Commands/PackageCommand.php deleted file mode 100644 index 69d13a5..0000000 --- a/src/Commands/PackageCommand.php +++ /dev/null @@ -1,21 +0,0 @@ -comment('All done'); - - return self::SUCCESS; - } -} diff --git a/src/Events/Concerns/AggregatableRoot.php b/src/Events/Concerns/AggregatableRoot.php new file mode 100644 index 0000000..af2670a --- /dev/null +++ b/src/Events/Concerns/AggregatableRoot.php @@ -0,0 +1,51 @@ +recordedEvents; + $this->recordedEvents = []; + + return $releasedEvents; + } + + protected function recordThat(object $event): void + { + $this->recordedEvents[] = $event; + } +} diff --git a/src/Events/Concerns/AggregatableRootId.php b/src/Events/Concerns/AggregatableRootId.php new file mode 100644 index 0000000..3288e26 --- /dev/null +++ b/src/Events/Concerns/AggregatableRootId.php @@ -0,0 +1,46 @@ +id === $entityId->id; + } + + public function toString(): string + { + return $this->id; + } + + public function __toString(): string + { + return $this->toString(); + } + + /** + * @throws AssertionFailedException + */ + protected function assertValidId(string $id): void + { + Assertion::uuid($id); + } + + /** + * @throws AssertionFailedException + */ + private function __construct(string $id) + { + $this->assertValidId($id); + + $this->id = $id; + } +} diff --git a/src/Facades/Package.php b/src/Facades/Package.php deleted file mode 100644 index 9eab5b2..0000000 --- a/src/Facades/Package.php +++ /dev/null @@ -1,15 +0,0 @@ -name; - } - - private function __construct(string $name) - { - $this->name = $name; - } -} diff --git a/src/PackageServiceProvider.php b/src/PackageServiceProvider.php deleted file mode 100644 index a383740..0000000 --- a/src/PackageServiceProvider.php +++ /dev/null @@ -1,27 +0,0 @@ -name('package') - ->hasConfigFile() - ->hasViews() - ->hasMigration('create_package_table') - ->hasCommand(PackageCommand::class); - } -} diff --git a/tests/Pest.php b/tests/Pest.php index 1d225b8..4ef1661 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -2,6 +2,6 @@ declare(strict_types=1); -namespace WayOfDev\Laravel\Package\Tests; +namespace WayOfDev\EventSourcing\Tests; uses(TestCase::class)->in(__DIR__); diff --git a/tests/TestCase.php b/tests/TestCase.php index 693e979..5fced74 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,37 +2,17 @@ declare(strict_types=1); -namespace WayOfDev\Laravel\Package\Tests; +namespace WayOfDev\EventSourcing\Tests; -use Illuminate\Database\Eloquent\Factories\Factory; use Orchestra\Testbench\TestCase as Orchestra; -use WayOfDev\Laravel\Package\PackageServiceProvider; +use WayOfDev\EventSourcing\Bridge\Laravel\Providers\EventSourcingServiceProvider; abstract class TestCase extends Orchestra { - protected function setUp(): void - { - parent::setUp(); - - Factory::guessFactoryNamesUsing( - static fn (string $modelName) => 'WayOfDev\\Laravel\\Package\\Database\\Factories\\' . class_basename($modelName) . 'Factory' - ); - } - - public function getEnvironmentSetUp($app): void - { - config()->set('database.default', 'testing'); - - /* - $migration = include __DIR__.'/../database/migrations/create_package_table.php.stub'; - $migration->up(); - */ - } - protected function getPackageProviders($app): array { return [ - PackageServiceProvider::class, + EventSourcingServiceProvider::class, ]; } }