diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..bc3ab5c1
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "composer"
+ directory: "/"
+ schedule:
+ interval: "daily"
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index ba672677..3e034c57 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -9,8 +9,13 @@ jobs:
uses: actions/checkout@v2
- name: Docker pull
run: docker-compose pull php
+ - name: Docker caching
+ uses: satackey/action-docker-layer-caching@v0.0.11
+ continue-on-error: true
+ - name: Start PHP container
+ run: docker-compose up --detach --build --no-deps php
- name: Run composer validate
- run: docker-compose run --rm --no-deps php composer validate --strict --no-interaction --ansi
+ run: docker-compose exec -T php composer validate --strict --no-interaction --ansi
run-php-cs-fixer:
name: php-cs-fixer
runs-on: ubuntu-latest
@@ -19,16 +24,21 @@ jobs:
uses: actions/checkout@v2
- name: Docker pull
run: docker-compose pull php
+ - name: Docker caching
+ uses: satackey/action-docker-layer-caching@v0.0.11
+ continue-on-error: true
- name: Composer caching
uses: actions/cache@v2
with:
path: ./build/.composer
key: ${{ runner.os }}-composer-v1-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-v1-
+ - name: Start PHP container
+ run: docker-compose up --detach --build --no-deps php
- name: Install dependencies
- run: docker-compose run --rm --no-deps php composer --no-scripts install --no-interaction --ansi
+ run: docker-compose exec -T php composer --no-scripts install --no-interaction --ansi
- name: Run php-cs-fixer
- run: docker-compose run --rm --no-deps php bin/php-cs-fixer fix --diff --dry-run --ansi --config=.php-cs-fixer.dist.php
+ run: docker-compose exec -T php bin/php-cs-fixer fix --diff --dry-run --ansi --config=.php-cs-fixer.dist.php
run-phpunit:
name: phpunit
runs-on: ubuntu-latest
@@ -37,22 +47,32 @@ jobs:
uses: actions/checkout@v2
- name: Docker pull
run: docker-compose pull
+ - name: Docker caching
+ uses: satackey/action-docker-layer-caching@v0.0.11
+ continue-on-error: true
- name: Composer caching
uses: actions/cache@v2
with:
path: ./build/.composer
key: ${{ runner.os }}-composer-v1-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-v1-
+ - name: Start containers
+ run: docker-compose up --detach --build
- name: Install dependencies
- run: docker-compose run --rm php composer install --no-scripts --no-interaction --ansi
+ run: docker-compose exec -T php composer install --no-scripts --no-interaction --ansi
- name: Run phpunit
- run: docker-compose run --rm php xphp bin/phpunit --color=always --configuration=phpunit.xml.dist
- - name: Upload coverage report to codecov.io
- uses: codecov/codecov-action@v1
+ run: docker-compose exec -T php xphp -dxdebug.mode=coverage bin/phpunit --color=always --configuration=phpunit.xml.dist
+ - name: Upload coverage report to Codecov.io
+ uses: codecov/codecov-action@v2
with:
files: ./build/.phpunit/clover.xml
fail_ci_if_error: true
verbose: true
+# - name: Upload coverage report to GitHub.com
+# uses: actions/upload-artifact@v2
+# with:
+# name: Code Coverage Report
+# path: build/.phpunit/code-coverage/*
run-rector:
name: rector
runs-on: ubuntu-latest
@@ -61,16 +81,21 @@ jobs:
uses: actions/checkout@v2
- name: Docker pull
run: docker-compose pull php
+ - name: Docker caching
+ uses: satackey/action-docker-layer-caching@v0.0.11
+ continue-on-error: true
- name: Composer caching
uses: actions/cache@v2
with:
path: ./build/.composer
key: ${{ runner.os }}-composer-v1-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-v1-
+ - name: Start PHP container
+ run: docker-compose up --detach --build --no-deps php
- name: Install dependencies
- run: docker-compose run --rm --no-deps php composer install --no-interaction --ansi
+ run: docker-compose exec -T php composer install --no-interaction --ansi
- name: Run rector
- run: docker-compose run --rm --no-deps php bin/rector --no-progress-bar --dry-run --ansi
+ run: docker-compose exec -T php bin/rector --no-progress-bar --dry-run --ansi
run-deptrac:
name: deptrac
runs-on: ubuntu-latest
@@ -79,13 +104,18 @@ jobs:
uses: actions/checkout@v2
- name: Docker pull
run: docker-compose pull php
+ - name: Docker caching
+ uses: satackey/action-docker-layer-caching@v0.0.11
+ continue-on-error: true
- name: Composer caching
uses: actions/cache@v2
with:
path: ./build/.composer
key: ${{ runner.os }}-composer-v1-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-v1-
+ - name: Start PHP container
+ run: docker-compose up --detach --build --no-deps php
- name: Install dependencies
- run: docker-compose run --rm --no-deps php composer install --no-scripts --no-interaction --ansi
+ run: docker-compose exec -T php composer install --no-scripts --no-interaction --ansi
- name: Run deptrac
- run: docker-compose run --rm --no-deps php bin/deptrac --no-progress --no-interaction --cache-file=./build/.deptrac/.deptrac.cache --ansi
+ run: docker-compose exec -T php bin/deptrac --no-progress --no-interaction --cache-file=./build/.deptrac/.deptrac.cache --ansi
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 3d0204ec..eb5f9850 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -3,6 +3,7 @@
$config = new PhpCsFixer\Config();
$finder = PhpCsFixer\Finder::create();
$finder
+ // The vendor directory is excluded by default.
->exclude('.github')
->exclude('bin')
->exclude('build')
@@ -30,6 +31,7 @@
'php_unit_dedicate_assert_internal_type' => true,
'php_unit_mock' => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
+ 'no_extra_blank_lines' => true,
'header_comment' => [
'comment_type' => 'PHPDoc',
'location' => 'after_open',
@@ -46,7 +48,6 @@
],
]
)
- //The vendor directory is excluded by default.
->setFinder($finder)
;
diff --git a/README.md b/README.md
index 5157ed08..293d6387 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,25 @@
-Streak
-------
+![Streak](docs/images/logo.png)
+-------------------------------
+
+[![CI](https://github.com/streakphp/streak/actions/workflows/ci.yaml/badge.svg)](https://github.com/streakphp/streak/actions/workflows/ci.yaml)
[![codecov](https://codecov.io/gh/streakphp/streak/branch/master/graph/badge.svg)](https://codecov.io/gh/streakphp/streak)
-Running test
-------------
+Running checks & tests locally
+------------------------------
+
+`docker-compose up --detach --build`
+
+`docker-compose exec -T php composer validate --strict --no-interaction --ansi`
+
+`docker-compose exec -T php composer install --no-scripts --no-interaction --ansi`
+
+`docker-compose exec -T php xphp -dxdebug.mode=coverage bin/phpunit --color=always --configuration=phpunit.xml.dist`
+
+`docker-compose run -T php bin/phpunit`
+
+`docker-compose exec -T php bin/rector --dry-run --ansi`
+
+`docker-compose exec -T php bin/deptrac --no-interaction --cache-file=./build/.deptrac/.deptrac.cache --ansi`
-`docker-compose run --rm php bin/phpunit`
+`docker-compose exec -T php bin/php-cs-fixer fix --diff --dry-run --ansi --config=.php-cs-fixer.dist.php`
diff --git a/codecov.yml b/codecov.yml
index a8cd4f88..bf08d671 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -1,7 +1,27 @@
+codecov:
+ branch: master
+ max_report_age: 24
+ require_ci_to_pass: yes
+
+comment:
+ layout: "reach, diff, flags, files"
+ behavior: new
+ require_changes: false
+ require_base: true
+ require_head: true
+
+parsers:
+ gcov:
+ branch_detection:
+ conditional: yes
+ loop: yes
+ method: yes
+ macro: yes
+
coverage:
precision: 2
round: down
- range: "70...100"
+ range: "90...100"
status:
project:
diff --git a/composer.json b/composer.json
index e9141891..178bb186 100644
--- a/composer.json
+++ b/composer.json
@@ -40,7 +40,7 @@
"friendsofphp/php-cs-fixer": "^3.0",
"php-amqplib/rabbitmq-bundle": "^2.6.0",
"phpunit/phpunit": "^9.5.4",
- "rector/rector": "^0.10.19",
+ "rector/rector": "0.12.18",
"qossmic/deptrac-shim": "^0.13.0"
},
"config": {
diff --git a/docker-compose.yml b/docker-compose.yml
index 64c66d31..7ffe177e 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,12 +1,14 @@
-version: '3'
+version: '3.7'
services:
php:
image: streakphp/php80-cli:latest
+ init: true
volumes:
- .:/var/www/project
- ./docker/php/etc/php/8.0/cli/php.ini:/etc/php/8.0/cli/php.ini
working_dir: /var/www/project
+ entrypoint: tail -f /dev/null # keep container alive for development
depends_on:
- postgres
- redis
@@ -14,7 +16,6 @@ services:
COMPOSER_ALLOW_SUPERUSER: 1
COMPOSER_NO_INTERACTION: 1
COMPOSER_CACHE_DIR: /var/www/project/build/.composer
- XDEBUG_MODE: 'develop,debug,coverage'
postgres:
image: postgres:13-alpine
diff --git a/docs/images/logo.png b/docs/images/logo.png
new file mode 100644
index 00000000..49d1676b
Binary files /dev/null and b/docs/images/logo.png differ
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 5c578586..376a0ff6 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -4,6 +4,8 @@
colors="true"
cacheResultFile="build/.phpunit/.phpunit.result.cache"
bootstrap="tests/bootstrap.php"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
>
@@ -11,7 +13,7 @@
-
+
diff --git a/rector.php b/rector.php
index 6a68c12e..42b9628e 100644
--- a/rector.php
+++ b/rector.php
@@ -48,7 +48,6 @@
]);
// Run Rector only on changed files
- $parameters->set(Option::ENABLE_CACHE, true);
$parameters->set(Option::CACHE_DIR, __DIR__ . '/build/.rector');
$services = $configurator->services();
diff --git a/src/Application/Sensor.php b/src/Application/Sensor.php
index df71c79a..e6128044 100644
--- a/src/Application/Sensor.php
+++ b/src/Application/Sensor.php
@@ -20,7 +20,7 @@
*/
interface Sensor extends Producer
{
- public function sensorId(): Sensor\Id;
+ public function id(): Sensor\Id;
public function process(...$messages): void;
}
diff --git a/src/Application/Sensor/Id.php b/src/Application/Sensor/Id.php
index ccaa2523..004f56ee 100644
--- a/src/Application/Sensor/Id.php
+++ b/src/Application/Sensor/Id.php
@@ -13,11 +13,11 @@
namespace Streak\Application\Sensor;
-use Streak\Domain\Event\Producer;
+use Streak\Domain;
/**
* @author Alan Gabriel Bem
*/
-interface Id extends Producer\Id
+interface Id extends Domain\Id
{
}
diff --git a/src/Application/Sensor/Identification.php b/src/Application/Sensor/Identification.php
index 5f9d6b03..222eb75d 100644
--- a/src/Application/Sensor/Identification.php
+++ b/src/Application/Sensor/Identification.php
@@ -14,7 +14,6 @@
namespace Streak\Application\Sensor;
use Streak\Application\Sensor;
-use Streak\Domain;
/**
* @author Alan Gabriel Bem
@@ -28,21 +27,11 @@ public function __construct(Sensor\Id $id)
$this->identifyBy($id);
}
- public function sensorId(): Sensor\Id
+ public function id(): Sensor\Id
{
return $this->id;
}
- public function producerId(): Domain\Id
- {
- return $this->sensorId();
- }
-
- public function id(): Domain\Id
- {
- return $this->sensorId();
- }
-
protected function identifyBy(Sensor\Id $id): void
{
$this->id = $id;
diff --git a/src/Application/Sensor/Processing.php b/src/Application/Sensor/Processing.php
index 8b72e556..9f5dcdd2 100644
--- a/src/Application/Sensor/Processing.php
+++ b/src/Application/Sensor/Processing.php
@@ -13,8 +13,8 @@
namespace Streak\Application\Sensor;
+use Streak\Application\Sensor;
use Streak\Domain\Event;
-use Streak\Domain\Id;
/**
* @author Alan Gabriel Bem
@@ -27,7 +27,7 @@ trait Processing
private $events = [];
private $last;
- abstract public function producerId(): Id;
+ abstract public function id(): Sensor\Id;
final public function last(): ?Event\Envelope
{
@@ -140,7 +140,7 @@ final public function process(...$messages): void
}
if (false === $routed) {
- throw new \InvalidArgumentException();
+ throw new \InvalidArgumentException('No method found to process message.');
}
}
} catch (\Throwable $e) {
@@ -156,6 +156,6 @@ final public function process(...$messages): void
private function addEvent(Event $event): void
{
- $this->pending[] = Event\Envelope::new($event, $this->producerId());
+ $this->pending[] = Event\Envelope::new($event, $this->id());
}
}
diff --git a/src/Domain/Aggregate.php b/src/Domain/Aggregate.php
index 4979bfc4..eff01c7a 100644
--- a/src/Domain/Aggregate.php
+++ b/src/Domain/Aggregate.php
@@ -24,5 +24,5 @@
*/
interface Aggregate extends Domain\Entity
{
- public function aggregateId(): Domain\Aggregate\Id;
+ public function id(): Domain\Aggregate\Id;
}
diff --git a/src/Domain/Aggregate/Comparison.php b/src/Domain/Aggregate/Comparison.php
index 4e57a48e..dd1e464e 100644
--- a/src/Domain/Aggregate/Comparison.php
+++ b/src/Domain/Aggregate/Comparison.php
@@ -19,12 +19,14 @@
/**
* @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\Aggregate\ComparisonTest
*/
trait Comparison
{
use Entity\Comparison;
- abstract public function aggregateId(): Aggregate\Id;
+ abstract public function id(): Aggregate\Id;
final public function equals(object $aggregate): bool
{
@@ -36,7 +38,7 @@ final public function equals(object $aggregate): bool
return false;
}
- if (!$this->aggregateId()->equals($aggregate->aggregateId())) {
+ if (!$this->id()->equals($aggregate->id())) {
return false;
}
diff --git a/src/Domain/Event/Sourced/Aggregate/Id.php b/src/Domain/Aggregate/EventSourcing.php
similarity index 59%
rename from src/Domain/Event/Sourced/Aggregate/Id.php
rename to src/Domain/Aggregate/EventSourcing.php
index 525410f5..7f6f9971 100644
--- a/src/Domain/Event/Sourced/Aggregate/Id.php
+++ b/src/Domain/Aggregate/EventSourcing.php
@@ -11,13 +11,19 @@
declare(strict_types=1);
-namespace Streak\Domain\Event\Sourced\Aggregate;
+namespace Streak\Domain\Aggregate;
use Streak\Domain\Aggregate;
+use Streak\Domain\Entity;
/**
* @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\EventSourcingTest
*/
-interface Id extends Aggregate\Id
+trait EventSourcing //implements Event\Sourced\Aggregate
{
+ use Entity\EventSourcing;
+
+ abstract public function id(): Aggregate\Id;
}
diff --git a/src/Domain/Aggregate/Identification.php b/src/Domain/Aggregate/Identification.php
index dea44e14..e7d08c5f 100644
--- a/src/Domain/Aggregate/Identification.php
+++ b/src/Domain/Aggregate/Identification.php
@@ -18,6 +18,10 @@
/**
* @author Alan Gabriel Bem
+ *
+ * @property $id Aggregate\Id
+ *
+ * @see \Streak\Domain\Aggregate\IdentificationTest
*/
trait Identification
{
@@ -30,7 +34,7 @@ public function __construct(Aggregate\Id $id)
$this->identifyBy($id);
}
- public function aggregateId(): Aggregate\Id
+ public function id(): Aggregate\Id
{
return $this->id;
}
diff --git a/src/Domain/AggregateRoot.php b/src/Domain/AggregateRoot.php
index f6346ff0..9e93bf42 100644
--- a/src/Domain/AggregateRoot.php
+++ b/src/Domain/AggregateRoot.php
@@ -24,5 +24,5 @@
*/
interface AggregateRoot extends Domain\Aggregate
{
- public function aggregateRootId(): AggregateRoot\Id;
+ public function id(): AggregateRoot\Id;
}
diff --git a/src/Domain/AggregateRoot/Comparison.php b/src/Domain/AggregateRoot/Comparison.php
index 8dc32b74..306b00da 100644
--- a/src/Domain/AggregateRoot/Comparison.php
+++ b/src/Domain/AggregateRoot/Comparison.php
@@ -19,12 +19,14 @@
/**
* @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\AggregateRoot\ComparisonTest
*/
trait Comparison
{
use Aggregate\Comparison;
- abstract public function aggregateRootId(): AggregateRoot\Id;
+ abstract public function id(): AggregateRoot\Id;
final public function equals(object $root): bool
{
@@ -36,7 +38,7 @@ final public function equals(object $root): bool
return false;
}
- if (!$this->aggregateRootId()->equals($root->aggregateRootId())) {
+ if (!$this->id()->equals($root->id())) {
return false;
}
diff --git a/src/Domain/AggregateRoot/EventSourcing.php b/src/Domain/AggregateRoot/EventSourcing.php
new file mode 100644
index 00000000..72a73994
--- /dev/null
+++ b/src/Domain/AggregateRoot/EventSourcing.php
@@ -0,0 +1,140 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Streak\Domain\AggregateRoot;
+
+use Streak\Domain;
+use Streak\Domain\Aggregate;
+use Streak\Domain\AggregateRoot;
+use Streak\Domain\Event;
+
+/**
+ * @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\EventSourcingTest
+ */
+trait EventSourcing //implements Event\Sourced\AggregateRoot
+{
+ use Aggregate\EventSourcing;
+
+ /**
+ * @var Event\Envelope[]
+ */
+ private array $events = [];
+ private ?Event\Envelope $lastEvent = null;
+ private int $version = 0;
+
+ abstract public function id(): AggregateRoot\Id;
+
+ /**
+ * @throws \Throwable
+ */
+ final public function replay(Event\Stream $stream): void
+ {
+ foreach ($stream as $event) {
+ $this->applyEvent($event);
+
+ $this->version = $event->version();
+ }
+
+ $this->events = [];
+ }
+
+ final public function lastEvent(): ?Event\Envelope
+ {
+ return $this->lastEvent;
+ }
+
+ final public function version(): int
+ {
+ return $this->version;
+ }
+
+ /**
+ * @return Event\Envelope[]
+ */
+ final public function events(): array
+ {
+ return $this->events;
+ }
+
+ public function commit(): void
+ {
+ $this->version += \count($this->events);
+ $this->events = [];
+ }
+
+ /**
+ * @throws Event\Exception\TooManyEventApplyingMethodsFound
+ * @throws Domain\Exception\EventMismatched
+ * @throws \Throwable
+ */
+ final public function applyEvent(Event\Envelope $event): void
+ {
+ // $event was produced by $this aggregate or one of its embedded entities
+ if (!$this->id()->equals($event->producerId())) {
+ throw new Domain\Exception\EventMismatched($this, $event);
+ }
+
+ if (null === $event->version()) {
+ $event = $event->defineVersion($this->version + \count($this->events) + 1);
+ }
+
+ $applied = 0;
+ foreach ($this->eventSourcedEntities() as $entity) {
+ /** @var Event\Sourced\Entity $aggregate */
+ if ($entity->id()->equals($event->entityId())) {
+ do {
+ try {
+ $entity->applyEvent($event);
+ $applied++;
+ } catch (Event\Exception\NoEventApplyingMethodFound) {
+ }
+ } while ($entity = $entity->aggregate());
+
+ break; // we don't need to look for next entity
+ }
+ }
+
+ try {
+ $this->doApplyEvent($event);
+ } catch (Event\Exception\NoEventApplyingMethodFound $exception) {
+ if ($applied === 0) {
+ throw $exception;
+ }
+ }
+
+ $this->lastEvent = $event;
+ $this->events[] = $event;
+ }
+
+ /**
+ * @throws Event\Exception\NoEventApplyingMethodFound
+ * @throws Event\Exception\TooManyEventApplyingMethodsFound
+ * @throws \Throwable
+ */
+ private function apply(Event $event): void
+ {
+ $envelope = Event\Envelope::new($event, $this->id());
+
+ $this->applyEvent($envelope);
+ }
+
+ /**
+ * @return Event\Sourced\Entity[]
+ */
+ private function eventSourcedEntities(): iterable
+ {
+ yield from Event\Sourced\Entity\Helper::for($this)->extractEventSourcedEntities();
+ }
+}
diff --git a/src/Domain/AggregateRoot/Identification.php b/src/Domain/AggregateRoot/Identification.php
index 174724ad..23878131 100644
--- a/src/Domain/AggregateRoot/Identification.php
+++ b/src/Domain/AggregateRoot/Identification.php
@@ -18,6 +18,10 @@
/**
* @author Alan Gabriel Bem
+ *
+ * @property $id AggregateRoot\Id
+ *
+ * @see \Streak\Domain\AggregateRoot\IdentificationTest
*/
trait Identification
{
@@ -30,7 +34,7 @@ public function __construct(AggregateRoot\Id $id)
$this->identifyBy($id);
}
- public function aggregateRootId(): AggregateRoot\Id
+ public function id(): AggregateRoot\Id
{
return $this->id;
}
diff --git a/src/Domain/Entity.php b/src/Domain/Entity.php
index 7fe7545a..0420f936 100644
--- a/src/Domain/Entity.php
+++ b/src/Domain/Entity.php
@@ -18,5 +18,5 @@
*/
interface Entity extends Comparable, Identifiable
{
- public function entityId(): Entity\Id;
+ public function id(): Entity\Id;
}
diff --git a/src/Domain/Entity/Comparison.php b/src/Domain/Entity/Comparison.php
index d47d7402..3bff3810 100644
--- a/src/Domain/Entity/Comparison.php
+++ b/src/Domain/Entity/Comparison.php
@@ -18,10 +18,12 @@
/**
* @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\Entity\ComparisonTest
*/
trait Comparison
{
- abstract public function entityId(): Entity\Id;
+ abstract public function id(): Entity\Id;
final public function equals(object $entity): bool
{
@@ -33,7 +35,7 @@ final public function equals(object $entity): bool
return false;
}
- if (!$this->entityId()->equals($entity->entityId())) {
+ if (!$this->id()->equals($entity->id())) {
return false;
}
diff --git a/src/Domain/Entity/EventSourcing.php b/src/Domain/Entity/EventSourcing.php
new file mode 100644
index 00000000..327cf0e9
--- /dev/null
+++ b/src/Domain/Entity/EventSourcing.php
@@ -0,0 +1,86 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Streak\Domain\Entity;
+
+use Streak\Domain\Entity;
+use Streak\Domain\Event;
+use Streak\Domain\Exception\EventMismatched;
+
+/**
+ * @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\EventSourcingTest
+ */
+trait EventSourcing //implements Event\Sourced\Entity
+{
+ private ?Event\Sourced\AggregateRoot $aggregateRoot = null;
+ private ?Event\Sourced\Aggregate $aggregate = null;
+
+ public function registerAggregateRoot(Event\Sourced\AggregateRoot $aggregateRoot): void
+ {
+ $this->aggregateRoot = $aggregateRoot;
+ }
+
+ public function registerAggregate(Event\Sourced\Aggregate $aggregate): void
+ {
+ if ($this->id()->equals($aggregate->id())) {
+ throw new \BadMethodCallException('You can\'t register aggregate on itself.');
+ }
+
+ $this->aggregate = $aggregate;
+ $this->registerAggregateRoot($aggregate->aggregateRoot());
+ }
+
+ public function aggregateRoot(): Event\Sourced\AggregateRoot
+ {
+ if (null === $this->aggregateRoot) {
+ throw new \BadMethodCallException(sprintf('Aggregate root no registered. Did you forget to run %s::registerAggregateRoot()?', static::class));
+ }
+
+ return $this->aggregateRoot;
+ }
+
+ public function aggregate(): ?Event\Sourced\Aggregate
+ {
+ return $this->aggregate;
+ }
+
+ abstract public function id(): Entity\Id;
+
+ final public function applyEvent(Event\Envelope $event): void
+ {
+ if (false === $this->aggregateRoot()->id()->equals($event->producerId())) {
+ throw new EventMismatched($this, $event);
+ }
+
+ $this->doApplyEvent($event);
+ }
+
+ /**
+ * @throws Event\Exception\NoEventApplyingMethodFound
+ * @throws Event\Exception\TooManyEventApplyingMethodsFound
+ * @throws \Throwable
+ */
+ protected function apply(Event\EntityEvent $event): void
+ {
+ $event = Event\Envelope::new($event, $this->aggregateRoot()->id());
+
+ $this->aggregateRoot()->applyEvent($event);
+ }
+
+ private function doApplyEvent(Event\Envelope $event): void
+ {
+ Event\Sourced\Entity\Helper::for($this)->applyEvent($event);
+ }
+}
diff --git a/src/Domain/Entity/Identification.php b/src/Domain/Entity/Identification.php
index 4efcf70c..4131e0f2 100644
--- a/src/Domain/Entity/Identification.php
+++ b/src/Domain/Entity/Identification.php
@@ -13,27 +13,23 @@
namespace Streak\Domain\Entity;
-use Streak\Domain;
use Streak\Domain\Entity;
/**
* @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\Entity\IdentificationTest
*/
trait Identification
{
- private $id;
+ private Entity\Id $id;
public function __construct(Entity\Id $id)
{
$this->identifyBy($id);
}
- public function entityId(): Entity\Id
- {
- return $this->id;
- }
-
- public function id(): Domain\Id
+ public function id(): Entity\Id
{
return $this->id;
}
diff --git a/src/Domain/Event/Consumer.php b/src/Domain/Event/Consumer.php
index 138eef0f..45202781 100644
--- a/src/Domain/Event/Consumer.php
+++ b/src/Domain/Event/Consumer.php
@@ -18,7 +18,11 @@
/**
* @author Alan Gabriel Bem
*/
-interface Consumer extends Event\Replayable
+interface Consumer
{
- public function lastReplayed(): ?Event\Envelope; // TODO: remove (use last() instead?)
+ /**
+ * @throws Event\Exception\NoEventApplyingMethodFound
+ * @throws Event\Exception\TooManyEventApplyingMethodsFound
+ */
+ public function applyEvent(Event\Envelope $event): void;
}
diff --git a/src/Domain/Event/Sourced/Entity/Id.php b/src/Domain/Event/EntityEvent.php
similarity index 68%
rename from src/Domain/Event/Sourced/Entity/Id.php
rename to src/Domain/Event/EntityEvent.php
index beee3e46..a7a72afe 100644
--- a/src/Domain/Event/Sourced/Entity/Id.php
+++ b/src/Domain/Event/EntityEvent.php
@@ -11,13 +11,12 @@
declare(strict_types=1);
-namespace Streak\Domain\Event\Sourced\Entity;
+namespace Streak\Domain\Event;
use Streak\Domain\Entity;
+use Streak\Domain\Event;
-/**
- * @author Alan Gabriel Bem
- */
-interface Id extends Entity\Id
+interface EntityEvent extends Event
{
+ public function entityId(): Entity\Id;
}
diff --git a/src/Domain/Event/Envelope.php b/src/Domain/Event/Envelope.php
index db1dd59f..27cdda94 100644
--- a/src/Domain/Event/Envelope.php
+++ b/src/Domain/Event/Envelope.php
@@ -29,6 +29,8 @@ final class Envelope implements Domain\Envelope
public const METADATA_VERSION = 'version';
public const METADATA_PRODUCER_TYPE = 'producer_type';
public const METADATA_PRODUCER_ID = 'producer_id';
+ public const METADATA_ENTITY_TYPE = 'entity_type';
+ public const METADATA_ENTITY_ID = 'entity_id';
private array $metadata = [];
public function __construct(UUID $uuid, string $name, private Event $message, Domain\Id $producerId, ?int $version = null)
@@ -37,6 +39,13 @@ public function __construct(UUID $uuid, string $name, private Event $message, Do
$this->metadata[self::METADATA_NAME] = $name;
$this->metadata[self::METADATA_PRODUCER_TYPE] = $producerId::class;
$this->metadata[self::METADATA_PRODUCER_ID] = $producerId->toString();
+ if ($message instanceof EntityEvent) {
+ $this->metadata[self::METADATA_ENTITY_TYPE] = $message->entityId()::class;
+ $this->metadata[self::METADATA_ENTITY_ID] = $message->entityId()->toString();
+ } else {
+ $this->metadata[self::METADATA_ENTITY_TYPE] = $producerId::class;
+ $this->metadata[self::METADATA_ENTITY_ID] = $producerId->toString();
+ }
if (null !== $version) {
$this->metadata[self::METADATA_VERSION] = $version;
}
@@ -67,6 +76,11 @@ public function producerId(): Domain\Id
return $this->get(self::METADATA_PRODUCER_TYPE)::fromString($this->get(self::METADATA_PRODUCER_ID));
}
+ public function entityId(): Domain\Id
+ {
+ return $this->get(self::METADATA_ENTITY_TYPE)::fromString($this->get(self::METADATA_ENTITY_ID));
+ }
+
public function version(): ?int
{
return $this->get(self::METADATA_VERSION);
@@ -77,7 +91,7 @@ public function set(string $name, $value): self
if (empty($name)) {
throw new \InvalidArgumentException('Name of the attribute can not be empty.');
}
- if (!is_scalar($value)) {
+ if (!\is_scalar($value)) {
throw new \InvalidArgumentException(sprintf('Value for attribute "%s" is a scalar.', $name));
}
@@ -86,7 +100,8 @@ public function set(string $name, $value): self
$this->name(),
$this->message(),
$this->producerId(),
- $this->version()
+ $this->entityId(),
+ $this->version(),
);
$new->metadata = $this->metadata;
@@ -117,4 +132,15 @@ public function equals(object $envelope): bool
return true;
}
+
+ public function defineVersion(int $version): self
+ {
+ return new self(
+ $this->uuid(),
+ $this->name(),
+ $this->message(),
+ $this->producerId(),
+ $version,
+ );
+ }
}
diff --git a/src/Domain/Event/Exception/ConversionToObjectNotPossible.php b/src/Domain/Event/Exception/ConversionToObjectNotPossible.php
index 2ae9c974..0fc93efd 100644
--- a/src/Domain/Event/Exception/ConversionToObjectNotPossible.php
+++ b/src/Domain/Event/Exception/ConversionToObjectNotPossible.php
@@ -18,12 +18,8 @@
*/
class ConversionToObjectNotPossible extends ConversionNotPossible
{
- private array $array;
-
- public function __construct(array $array, \Throwable $previous = null)
+ public function __construct(private array $array, \Throwable $previous = null)
{
- $this->array = $array;
-
parent::__construct($previous);
}
diff --git a/src/Domain/Event/Exception/NoEventApplyingMethodFound.php b/src/Domain/Event/Exception/NoEventApplyingMethodFound.php
index 43724349..ab524c09 100644
--- a/src/Domain/Event/Exception/NoEventApplyingMethodFound.php
+++ b/src/Domain/Event/Exception/NoEventApplyingMethodFound.php
@@ -22,14 +22,14 @@
*/
class NoEventApplyingMethodFound extends \BadMethodCallException
{
- public function __construct(private Event\Consumer $consumer, private Event\Envelope $event, \Throwable $previous = null)
+ public function __construct(private object $object, private Event\Envelope $event, \Throwable $previous = null)
{
parent::__construct('No event applying method found.', 0, $previous);
}
- public function consumer(): Event\Consumer
+ public function object(): object
{
- return $this->consumer;
+ return $this->object;
}
public function event(): Event\Envelope
diff --git a/src/Domain/Event/Exception/TooManyEventApplyingMethodsFound.php b/src/Domain/Event/Exception/TooManyEventApplyingMethodsFound.php
index 3423f5bb..c8bb2cc3 100644
--- a/src/Domain/Event/Exception/TooManyEventApplyingMethodsFound.php
+++ b/src/Domain/Event/Exception/TooManyEventApplyingMethodsFound.php
@@ -22,14 +22,14 @@
*/
class TooManyEventApplyingMethodsFound extends \BadMethodCallException
{
- public function __construct(private Event\Consumer $consumer, private Event\Envelope $event, \Throwable $previous = null)
+ public function __construct(private object $object, private Event\Envelope $event, \Throwable $previous = null)
{
parent::__construct('Too many event applying methods found.', 0, $previous);
}
- public function consumer(): Event\Consumer
+ public function object(): object
{
- return $this->consumer;
+ return $this->object;
}
public function event(): Event\Envelope
diff --git a/src/Domain/Event/Listener.php b/src/Domain/Event/Listener.php
index fa418c80..70e199f5 100644
--- a/src/Domain/Event/Listener.php
+++ b/src/Domain/Event/Listener.php
@@ -21,7 +21,7 @@
*/
interface Listener extends Identifiable
{
- public function listenerId(): Listener\Id;
+ public function id(): Listener\Id;
/**
* @return bool whether event was processed/is supported
diff --git a/src/Domain/Event/Listener/Identifying.php b/src/Domain/Event/Listener/Identifying.php
index 55d3919c..1099d04d 100644
--- a/src/Domain/Event/Listener/Identifying.php
+++ b/src/Domain/Event/Listener/Identifying.php
@@ -13,7 +13,6 @@
namespace Streak\Domain\Event\Listener;
-use Streak\Domain;
use Streak\Domain\Event\Listener;
/**
@@ -28,16 +27,11 @@ public function __construct(Listener\Id $id)
$this->identifyBy($id);
}
- public function listenerId(): Listener\Id
+ public function id(): Listener\Id
{
return $this->id;
}
- public function id(): Domain\Id
- {
- return $this->listenerId();
- }
-
protected function identifyBy(Listener\Id $id): void
{
$this->id = $id;
diff --git a/src/Domain/Event/Producer.php b/src/Domain/Event/Producer.php
index 7dfb9e7d..4d27c94f 100644
--- a/src/Domain/Event/Producer.php
+++ b/src/Domain/Event/Producer.php
@@ -21,7 +21,7 @@
*/
interface Producer
{
- public function producerId(): Domain\Id;
+ public function id(): Domain\Id;
/**
* @return Event\Envelope[]
diff --git a/src/Domain/Event/Producer/Id.php b/src/Domain/Event/Producer/Id.php
deleted file mode 100644
index 40196053..00000000
--- a/src/Domain/Event/Producer/Id.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Producer;
-
-use Streak\Domain;
-
-/**
- * @author Alan Gabriel Bem
- */
-interface Id extends Domain\Id
-{
-// public static function from(string $value) : self;
-}
diff --git a/src/Domain/Event/Sourced/Aggregate.php b/src/Domain/Event/Sourced/Aggregate.php
index 100d3b0c..052e5808 100644
--- a/src/Domain/Event/Sourced/Aggregate.php
+++ b/src/Domain/Event/Sourced/Aggregate.php
@@ -19,6 +19,6 @@
/**
* @author Alan Gabriel Bem
*/
-interface Aggregate extends Domain\Aggregate, Event\Sourced
+interface Aggregate extends Domain\Aggregate, Event\Sourced\Entity
{
}
diff --git a/src/Domain/Event/Sourced/Aggregate/Identification.php b/src/Domain/Event/Sourced/Aggregate/Identification.php
deleted file mode 100644
index 68f48bb0..00000000
--- a/src/Domain/Event/Sourced/Aggregate/Identification.php
+++ /dev/null
@@ -1,44 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\Aggregate;
-
-use Streak\Domain;
-use Streak\Domain\Aggregate;
-use Streak\Domain\Event\Producer;
-use Streak\Domain\Event\Sourced as EventSourced;
-
-/**
- * @author Alan Gabriel Bem
- */
-trait Identification // implements Producer
-{
- use Aggregate\Identification {
- Aggregate\Identification::identifyBy as private identifyAggregateBy;
- }
-
- public function __construct(EventSourced\Aggregate\Id $id)
- {
- $this->identifyBy($id);
- }
-
- public function producerId(): Domain\Id
- {
- return $this->id;
- }
-
- protected function identifyBy(Aggregate\Id $id): void
- {
- $this->identifyAggregateBy($id);
- }
-}
diff --git a/src/Domain/Event/Sourced/AggregateRoot.php b/src/Domain/Event/Sourced/AggregateRoot.php
index 057ebf9c..3261def3 100644
--- a/src/Domain/Event/Sourced/AggregateRoot.php
+++ b/src/Domain/Event/Sourced/AggregateRoot.php
@@ -20,7 +20,7 @@
/**
* @author Alan Gabriel Bem
*/
-interface AggregateRoot extends Domain\AggregateRoot, Event\Sourced, Versionable
+interface AggregateRoot extends Domain\AggregateRoot, Event\Consumer, Event\Producer, Event\Replayable, Versionable
{
public function lastEvent(): ?Event\Envelope;
}
diff --git a/src/Domain/Event/Sourced/AggregateRoot/Id.php b/src/Domain/Event/Sourced/AggregateRoot/Id.php
deleted file mode 100644
index 4abdee62..00000000
--- a/src/Domain/Event/Sourced/AggregateRoot/Id.php
+++ /dev/null
@@ -1,23 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\AggregateRoot;
-
-use Streak\Domain\AggregateRoot;
-
-/**
- * @author Alan Gabriel Bem
- */
-interface Id extends AggregateRoot\Id
-{
-}
diff --git a/src/Domain/Event/Sourced/AggregateRoot/Identification.php b/src/Domain/Event/Sourced/AggregateRoot/Identification.php
deleted file mode 100644
index 583ac450..00000000
--- a/src/Domain/Event/Sourced/AggregateRoot/Identification.php
+++ /dev/null
@@ -1,44 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\AggregateRoot;
-
-use Streak\Domain;
-use Streak\Domain\AggregateRoot;
-use Streak\Domain\Event\Producer;
-use Streak\Domain\Event\Sourced as EventSourced;
-
-/**
- * @author Alan Gabriel Bem
- */
-trait Identification // implements Producer
-{
- use AggregateRoot\Identification {
- AggregateRoot\Identification::identifyBy as private identifyAggregateRootBy;
- }
-
- public function __construct(EventSourced\AggregateRoot\Id $id)
- {
- $this->identifyBy($id);
- }
-
- public function producerId(): Domain\Id
- {
- return $this->id;
- }
-
- protected function identifyBy(AggregateRoot\Id $id): void
- {
- $this->identifyAggregateRootBy($id);
- }
-}
diff --git a/src/Domain/Event/Sourced/Entity.php b/src/Domain/Event/Sourced/Entity.php
index 15e44b3a..26c89f0a 100644
--- a/src/Domain/Event/Sourced/Entity.php
+++ b/src/Domain/Event/Sourced/Entity.php
@@ -19,6 +19,13 @@
/**
* @author Alan Gabriel Bem
*/
-interface Entity extends Domain\Entity, Event\Sourced
+interface Entity extends Domain\Entity, Event\Consumer
{
+ public function registerAggregateRoot(Event\Sourced\AggregateRoot $aggregate): void;
+
+ public function registerAggregate(Event\Sourced\Aggregate $aggregate): void;
+
+ public function aggregateRoot(): Event\Sourced\AggregateRoot;
+
+ public function aggregate(): ?Event\Sourced\Aggregate;
}
diff --git a/src/Domain/Event/Sourced/Entity/Helper.php b/src/Domain/Event/Sourced/Entity/Helper.php
new file mode 100644
index 00000000..61e2efcf
--- /dev/null
+++ b/src/Domain/Event/Sourced/Entity/Helper.php
@@ -0,0 +1,179 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Streak\Domain\Event\Sourced\Entity;
+
+use Streak\Domain\Event;
+
+/**
+ * @author Alan Gabriel Bem
+ *
+ * @see \Streak\Domain\Event\Sourced\Entity\HelperTest
+ */
+final class Helper
+{
+ private function __construct(private object $object)
+ {
+ }
+
+ public static function for(object $object): self
+ {
+ return new self($object);
+ }
+
+ /**
+ * @throws Event\Exception\NoEventApplyingMethodFound
+ * @throws Event\Exception\TooManyEventApplyingMethodsFound
+ * @throws \Throwable
+ */
+ public function applyEvent(Event\Envelope $event): void
+ {
+ self::applyEventByArgumentType($event, $this->object);
+ }
+
+ /**
+ * @return Event\Sourced\Entity[]
+ */
+ public function extractEventSourcedEntities(): iterable
+ {
+ yield from self::doExtractEventSourcedEntities($this->object);
+ }
+
+ private static function applyEventByArgumentType(Event\Envelope $event, object &$entity): void
+ {
+ $reflection = new \ReflectionObject($entity);
+
+ $methods = [];
+ foreach ($reflection->getMethods() as $method) {
+ // Method name must start with "apply"
+ if ('apply' !== mb_substr($method->getName(), 0, 5)) {
+ continue;
+ }
+
+ // ...and have exactly one parameter...
+ if (1 !== $method->getNumberOfParameters()) {
+ continue;
+ }
+
+ // ...which is required...
+ if (1 !== $method->getNumberOfRequiredParameters()) {
+ continue;
+ }
+
+ $parameter = $method->getParameters()[0];
+ $parameter = $parameter->getType();
+
+ // ...is not an union...
+ if (!$parameter instanceof \ReflectionNamedType) {
+ continue;
+ }
+
+ $parameter = $parameter->getName();
+ $parameter = new \ReflectionClass($parameter);
+
+ // ..and its an event...
+ if (false === $parameter->isSubclassOf(Event::class)) {
+ continue;
+ }
+
+ $target = new \ReflectionClass($event->message());
+
+ // .. and $event is type or subtype of defined $parameter
+ while ($parameter->getName() !== $target->getName()) {
+ $target = $target->getParentClass();
+
+ if (false === $target) {
+ continue 2;
+ }
+ }
+
+ $methods[] = $method;
+ }
+
+ if (0 === \count($methods)) {
+ throw new Event\Exception\NoEventApplyingMethodFound($entity, $event);
+ }
+
+ // TODO: filter methods matching given event exactly and if it wont work, than filter by direct ascendants of given event and so on
+
+ if (\count($methods) > 1) {
+ throw new Event\Exception\TooManyEventApplyingMethodsFound($entity, $event);
+ }
+
+ $method = array_shift($methods);
+
+ $isPublic = $method->isPublic();
+ if (false === $isPublic) {
+ $method->setAccessible(true);
+ }
+
+ try {
+ $method->invoke($entity, $event->message());
+ } finally {
+ if (false === $isPublic) {
+ $method->setAccessible(false);
+ }
+ }
+ }
+
+ /**
+ * Extract event sourced entities recursively.
+ */
+ private static function doExtractEventSourcedEntities(object $object, array &$ignored = []): iterable
+ {
+ $ignored[] = $object;
+
+ $reflection = new \ReflectionObject($object);
+ foreach ($reflection->getProperties() as $property) {
+ $public = $property->isPublic();
+
+ if (false === $public) {
+ $property->setAccessible(true);
+ }
+
+ if (false === $property->isInitialized($object)) {
+ continue;
+ }
+
+ $entity = $property->getValue($object);
+
+ if (false === $public) {
+ $property->setAccessible(false);
+ }
+
+ if (true === is_iterable($entity)) {
+ $entities = $entity;
+ } else {
+ $entities = [$entity];
+ }
+
+ foreach ($entities as $entity) {
+ if (!$entity instanceof Event\Sourced\Entity) {
+ continue;
+ }
+
+ foreach ($ignored as $ignore) {
+ if ($entity->equals($ignore)) {
+ continue 2;
+ }
+ }
+
+ yield $entity;
+
+ foreach (self::doExtractEventSourcedEntities($entity, $ignored) as $entity) {
+ yield $entity;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Domain/Event/Sourced/Entity/Identification.php b/src/Domain/Event/Sourced/Entity/Identification.php
deleted file mode 100644
index 8dec9da1..00000000
--- a/src/Domain/Event/Sourced/Entity/Identification.php
+++ /dev/null
@@ -1,44 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\Entity;
-
-use Streak\Domain;
-use Streak\Domain\Entity;
-use Streak\Domain\Event\Producer;
-use Streak\Domain\Event\Sourced as EventSourced;
-
-/**
- * @author Alan Gabriel Bem
- */
-trait Identification // implements Producer
-{
- use Entity\Identification {
- Entity\Identification::identifyBy as private identifyEntityBy;
- }
-
- public function __construct(EventSourced\Entity\Id $id)
- {
- $this->identifyBy($id);
- }
-
- public function producerId(): Domain\Id
- {
- return $this->id;
- }
-
- protected function identifyBy(Entity\Id $id): void
- {
- $this->identifyEntityBy($id);
- }
-}
diff --git a/src/Domain/Event/Sourced.php b/src/Domain/Event/Sourced/Subscription.php
similarity index 67%
rename from src/Domain/Event/Sourced.php
rename to src/Domain/Event/Sourced/Subscription.php
index ca13f33a..090dc145 100644
--- a/src/Domain/Event/Sourced.php
+++ b/src/Domain/Event/Sourced/Subscription.php
@@ -11,14 +11,14 @@
declare(strict_types=1);
-namespace Streak\Domain\Event;
+namespace Streak\Domain\Event\Sourced;
-use Streak\Domain\Comparable;
use Streak\Domain\Event;
+use Streak\Domain\Versionable;
/**
* @author Alan Gabriel Bem
*/
-interface Sourced extends Event\Producer, Event\Consumer, Comparable
+interface Subscription extends Event\Subscription, Event\Producer, Event\Replayable, Versionable
{
}
diff --git a/src/Domain/Event/Sourced/Subscription/Id.php b/src/Domain/Event/Sourced/Subscription/Id.php
deleted file mode 100644
index ba95641d..00000000
--- a/src/Domain/Event/Sourced/Subscription/Id.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\Subscription;
-
-use Streak\Domain\Event\Subscription;
-use Streak\Domain\Id\UUID;
-
-/**
- * @author Alan Gabriel Bem
- */
-class Id extends UUID implements Subscription\Id
-{
-}
diff --git a/src/Domain/Event/Sourcing.php b/src/Domain/Event/Sourcing.php
deleted file mode 100644
index 904aa625..00000000
--- a/src/Domain/Event/Sourcing.php
+++ /dev/null
@@ -1,231 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event;
-
-use Streak\Domain;
-use Streak\Domain\Event;
-
-/**
- * @author Alan Gabriel Bem
- */
-trait Sourcing //implements Event\Consumer, Event\Producer, Domain\Identifiable, Domain\Versionable
-{
- /**
- * @var Event\Envelope[]
- */
- private array $events = [];
- private ?Event\Envelope $lastEvent = null;
- private bool $replaying = false;
- private ?Event\Envelope $lastReplayed = null;
- private int $version = 0;
-
- abstract public function producerId(): Domain\Id;
-
- /**
- * @throws \Throwable
- */
- final public function replay(Event\Stream $stream): void
- {
- try {
- $this->replaying = true;
-
- foreach ($stream as $event) {
- $this->applyEvent($event);
- }
-
- $this->replaying = false;
- } catch (Exception\SourcingObjectWithEventFailed $exception) {
- $this->replaying = false;
-
- throw $exception;
- }
- }
-
- final public function lastReplayed(): ?Event\Envelope
- {
- return $this->lastReplayed;
- }
-
- final public function lastEvent(): ?Event\Envelope
- {
- return $this->lastEvent;
- }
-
- final public function version(): int
- {
- return $this->version;
- }
-
- /**
- * @return Event\Envelope[]
- */
- final public function events(): array
- {
- return $this->events;
- }
-
- public function commit(): void
- {
- $this->version += \count($this->events);
- $this->events = [];
- }
-
- /**
- * @throws Event\Exception\NoEventApplyingMethodFound
- * @throws Event\Exception\TooManyEventApplyingMethodsFound
- * @throws \Throwable
- */
- private function apply(Event $event): void
- {
- $event = Event\Envelope::new(
- $event,
- $this->producerId(),
- $this->version + \count($this->events) + 1 // current version + number of not committed events + 1
- );
-
- $this->applyEvent($event);
- }
-
- /**
- * @throws Event\Exception\NoEventApplyingMethodFound
- * @throws Event\Exception\TooManyEventApplyingMethodsFound
- * @throws \Throwable
- */
- private function applyEvent(Event\Envelope $event): void
- {
- if (!$this instanceof Event\Consumer) {
- throw new Exception\SourcingObjectWithEventFailed($this, $event);
- }
-
- if (!$this->producerId()->equals($event->producerId())) {
- throw new Domain\Exception\EventAndConsumerMismatch($this, $event);
- }
-
- try {
- $version = $this->version; // backup
- $last = $this->lastEvent; // backup
- $lastReplayed = $this->lastReplayed; // backup
-
- if ($this->replaying) {
- $this->lastEvent = $event;
- $this->version = (int) $event->version();
- $this->lastReplayed = $event;
- } else {
- $this->lastEvent = $event;
- $this->events[] = $event;
- }
-
- $this->doApplyEvent($event);
- } catch (\Throwable $e) {
- // rollback changes
- if ($this->replaying) {
- $this->lastEvent = $last;
- $this->version = $version;
- $this->lastReplayed = $lastReplayed;
- } else {
- $this->lastEvent = $last;
- array_pop($this->events);
- }
-
- throw $e;
- }
- }
-
- /**
- * @throws Event\Exception\NoEventApplyingMethodFound
- * @throws Event\Exception\TooManyEventApplyingMethodsFound
- * @throws \Throwable
- */
- private function doApplyEvent(Event\Envelope $event): void
- {
- $reflection = new \ReflectionObject($this);
-
- $methods = [];
- foreach ($reflection->getMethods() as $method) {
- // method is not current method...
- if (__FUNCTION__ === $method->getName()) {
- continue;
- }
-
- // ...and its name must start with "apply"
- if ('apply' !== mb_substr($method->getName(), 0, 5)) {
- continue;
- }
-
- // ...and have exactly one parameter...
- if (1 !== $method->getNumberOfParameters()) {
- continue;
- }
-
- // ...which is required...
- if (1 !== $method->getNumberOfRequiredParameters()) {
- continue;
- }
-
- $parameter = $method->getParameters()[0];
- $parameter = $parameter->getType();
-
- // ...is not an union...
- if (!$parameter instanceof \ReflectionNamedType) {
- continue;
- }
-
- $parameter = $parameter->getName();
- $parameter = new \ReflectionClass($parameter);
-
- // ..and its an event...
- if (false === $parameter->isSubclassOf(Event::class)) {
- continue;
- }
-
- $target = new \ReflectionClass($event->message());
-
- // .. and $event is type or subtype of defined $parameter
- while ($parameter->getName() !== $target->getName()) {
- $target = $target->getParentClass();
-
- if (false === $target) {
- continue 2;
- }
- }
-
- $methods[] = $method;
- }
-
- if (0 === \count($methods)) {
- throw new Exception\NoEventApplyingMethodFound($this, $event);
- }
-
- // TODO: filter methods matching given event exactly and if it wont work, than filter by direct ascendants of given event and so on
-
- if (\count($methods) > 1) {
- throw new Exception\TooManyEventApplyingMethodsFound($this, $event);
- }
-
- $method = array_shift($methods);
-
- $isPublic = $method->isPublic();
- if (false === $isPublic) {
- $method->setAccessible(true);
- }
-
- try {
- $method->invoke($this, $event->message());
- } finally {
- if (false === $isPublic) {
- $method->setAccessible(false);
- }
- }
- }
-}
diff --git a/src/Domain/Event/Subscription.php b/src/Domain/Event/Subscription.php
index cb94d437..3526223f 100644
--- a/src/Domain/Event/Subscription.php
+++ b/src/Domain/Event/Subscription.php
@@ -26,7 +26,7 @@ interface Subscription
{
public function listener(): Event\Listener;
- public function subscriptionId(): Event\Listener\Id;
+ public function id(): Event\Listener\Id;
/**
* @throws Exception\SubscriptionAlreadyCompleted
diff --git a/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompleted.php b/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompleted.php
index 4c0587bc..368f8c14 100644
--- a/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompleted.php
+++ b/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompleted.php
@@ -24,7 +24,7 @@ class SubscriptionAlreadyCompleted extends \RuntimeException implements Subscrip
{
public function __construct(private Subscription $subscription)
{
- $message = sprintf('Subscription "%s#%s" is already completed.', $this->subscription->subscriptionId()::class, $this->subscription->subscriptionId()->toString());
+ $message = sprintf('Subscription "%s#%s" is already completed.', $this->subscription->id()::class, $this->subscription->id()->toString());
parent::__construct($message);
}
diff --git a/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyStarted.php b/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyStarted.php
index 49f6844d..ec3f8e22 100644
--- a/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyStarted.php
+++ b/src/Domain/Event/Subscription/Exception/SubscriptionAlreadyStarted.php
@@ -24,7 +24,7 @@ class SubscriptionAlreadyStarted extends \RuntimeException implements Subscripti
{
public function __construct(private Subscription $subscription)
{
- $id = $this->subscription->subscriptionId();
+ $id = $this->subscription->id();
$message = sprintf('Subscription "%s#%s" is already started.', $id::class, $id->toString());
diff --git a/src/Domain/Event/Subscription/Exception/SubscriptionNotStartedYet.php b/src/Domain/Event/Subscription/Exception/SubscriptionNotStartedYet.php
index 9044bda9..19c3dd2c 100644
--- a/src/Domain/Event/Subscription/Exception/SubscriptionNotStartedYet.php
+++ b/src/Domain/Event/Subscription/Exception/SubscriptionNotStartedYet.php
@@ -24,7 +24,7 @@ class SubscriptionNotStartedYet extends \RuntimeException implements Subscriptio
{
public function __construct(private Subscription $subscription)
{
- $message = sprintf('Subscription "%s#%s" is not started yet.', $this->subscription->subscriptionId()::class, $this->subscription->subscriptionId()->toString());
+ $message = sprintf('Subscription "%s#%s" is not started yet.', $this->subscription->id()::class, $this->subscription->id()->toString());
parent::__construct($message);
}
diff --git a/src/Domain/Event/Subscription/Exception/SubscriptionPaused.php b/src/Domain/Event/Subscription/Exception/SubscriptionPaused.php
index 1bd43cf6..4f925365 100644
--- a/src/Domain/Event/Subscription/Exception/SubscriptionPaused.php
+++ b/src/Domain/Event/Subscription/Exception/SubscriptionPaused.php
@@ -24,7 +24,7 @@ class SubscriptionPaused extends \RuntimeException implements Subscription\Excep
{
public function __construct(private Subscription $subscription)
{
- $message = sprintf('Subscription "%s#%s" is paused.', $this->subscription->subscriptionId()::class, $this->subscription->subscriptionId()->toString());
+ $message = sprintf('Subscription "%s#%s" is paused.', $this->subscription->id()::class, $this->subscription->id()->toString());
parent::__construct($message);
}
diff --git a/src/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossible.php b/src/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossible.php
index e495b6d5..db86d57e 100644
--- a/src/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossible.php
+++ b/src/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossible.php
@@ -24,7 +24,7 @@ class SubscriptionRestartNotPossible extends \RuntimeException implements Subscr
{
public function __construct(private Subscription $subscription)
{
- $message = sprintf('Subscription "%s#%s" restart is not possible.', $this->subscription->subscriptionId()::class, $this->subscription->subscriptionId()->toString());
+ $message = sprintf('Subscription "%s#%s" restart is not possible.', $this->subscription->id()::class, $this->subscription->id()->toString());
parent::__construct($message);
}
diff --git a/src/Domain/Event/Subscription/Repository/Filter.php b/src/Domain/Event/Subscription/Repository/Filter.php
index 963fd0f2..d6333781 100644
--- a/src/Domain/Event/Subscription/Repository/Filter.php
+++ b/src/Domain/Event/Subscription/Repository/Filter.php
@@ -15,6 +15,7 @@
/**
* @author Alan Gabriel Bem
+ * @see \Streak\Domain\Event\Subscription\Repository\FilterTest
*/
final class Filter
{
diff --git a/src/Domain/Exception/EventAndConsumerMismatch.php b/src/Domain/Exception/EventMismatched.php
similarity index 54%
rename from src/Domain/Exception/EventAndConsumerMismatch.php
rename to src/Domain/Exception/EventMismatched.php
index 60746a7d..cfa74d00 100644
--- a/src/Domain/Exception/EventAndConsumerMismatch.php
+++ b/src/Domain/Exception/EventMismatched.php
@@ -18,18 +18,18 @@
/**
* @author Alan Gabriel Bem
*
- * @see \Streak\Domain\Exception\EventAndConsumerMismatchTest
+ * @see \Streak\Domain\Exception\EventMismatchedTest
*/
-class EventAndConsumerMismatch extends \LogicException
+class EventMismatched extends \LogicException
{
- public function __construct(private Event\Consumer $consumer, private Event\Envelope $event, \Throwable $previous = null)
+ public function __construct(private object $object, private Event\Envelope $event, \Throwable $previous = null)
{
- parent::__construct('Event mismatched when applying on consumer.', 0, $previous);
+ parent::__construct('Event mismatched when applying on object.', 0, $previous);
}
- public function consumer(): Event\Consumer
+ public function object(): object
{
- return $this->consumer;
+ return $this->object;
}
public function event(): Event\Envelope
diff --git a/src/Infrastructure/Application/Sensor/CommittingSensor.php b/src/Infrastructure/Application/Sensor/CommittingSensor.php
index 15feea21..605cea24 100644
--- a/src/Infrastructure/Application/Sensor/CommittingSensor.php
+++ b/src/Infrastructure/Application/Sensor/CommittingSensor.php
@@ -14,7 +14,6 @@
namespace Streak\Infrastructure\Application\Sensor;
use Streak\Application\Sensor;
-use Streak\Domain;
use Streak\Domain\Event;
use Streak\Infrastructure\Domain\UnitOfWork;
@@ -29,9 +28,9 @@ public function __construct(private Sensor $sensor, private UnitOfWork $uow)
{
}
- public function producerId(): Domain\Id
+ public function id(): Sensor\Id
{
- return $this->sensor->producerId();
+ return $this->sensor->id();
}
/**
@@ -42,11 +41,6 @@ public function events(): array
return $this->sensor->events();
}
- public function sensorId(): Sensor\Id
- {
- return $this->sensor->sensorId();
- }
-
public function process(...$messages): void
{
$this->sensor->process(...$messages);
diff --git a/src/Infrastructure/Application/Sensor/LoggingSensor.php b/src/Infrastructure/Application/Sensor/LoggingSensor.php
index 7defaa3c..4d8f293a 100644
--- a/src/Infrastructure/Application/Sensor/LoggingSensor.php
+++ b/src/Infrastructure/Application/Sensor/LoggingSensor.php
@@ -16,7 +16,6 @@
use Psr\Log\LoggerInterface;
use Streak\Application;
use Streak\Application\Sensor;
-use Streak\Domain;
/**
* @author Alan Gabriel Bem
@@ -29,9 +28,9 @@ public function __construct(private Application\Sensor $sensor, private LoggerIn
{
}
- public function producerId(): Domain\Id
+ public function id(): Sensor\Id
{
- return $this->sensor->producerId();
+ return $this->sensor->id();
}
public function events(): array
@@ -39,11 +38,6 @@ public function events(): array
return $this->sensor->events();
}
- public function sensorId(): Sensor\Id
- {
- return $this->sensor->sensorId();
- }
-
public function process(...$messages): void
{
try {
diff --git a/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFound.php b/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFound.php
index e2de193d..bc809c68 100644
--- a/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFound.php
+++ b/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFound.php
@@ -24,7 +24,7 @@ class SnapshotNotFound extends \RuntimeException
{
public function __construct(private AggregateRoot $aggregate)
{
- parent::__construct(sprintf('Snapshot for aggregate "%s#%s" not found.', $this->aggregate->aggregateRootId()::class, $this->aggregate->aggregateRootId()->toString()));
+ parent::__construct(sprintf('Snapshot for aggregate "%s#%s" not found.', $this->aggregate->id()::class, $this->aggregate->id()->toString()));
}
public function aggregate(): AggregateRoot
diff --git a/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/InMemoryStorage.php b/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/InMemoryStorage.php
index da37a0f8..c88ef3cd 100644
--- a/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/InMemoryStorage.php
+++ b/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/InMemoryStorage.php
@@ -29,7 +29,7 @@ final class InMemoryStorage implements Snapshotter\Storage
public function find(AggregateRoot $aggregate): string
{
foreach ($this->snapshots as [$id, $snapshot]) {
- if ($aggregate->aggregateRootId()->equals($id)) {
+ if ($aggregate->id()->equals($id)) {
return $snapshot;
}
}
@@ -40,13 +40,13 @@ public function find(AggregateRoot $aggregate): string
public function store(AggregateRoot $aggregate, string $newSnapshot): void
{
foreach ($this->snapshots as $key => [$id, $snapshot]) {
- if ($aggregate->aggregateRootId()->equals($id)) {
+ if ($aggregate->id()->equals($id)) {
$this->snapshots[$key] = [$id, $newSnapshot];
return;
}
}
- $this->snapshots[] = [$aggregate->aggregateRootId(), $newSnapshot];
+ $this->snapshots[] = [$aggregate->id(), $newSnapshot];
}
}
diff --git a/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/RedisStorage.php b/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/RedisStorage.php
index 88d64cf3..af3316d1 100644
--- a/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/RedisStorage.php
+++ b/src/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/RedisStorage.php
@@ -23,11 +23,8 @@
*/
final class RedisStorage implements Storage, Resettable
{
- private \Redis $redis;
-
- public function __construct(\Redis $client)
+ public function __construct(private \Redis $redis)
{
- $this->redis = $client;
}
/**
@@ -57,9 +54,9 @@ public function reset(): bool
private function key(AggregateRoot $aggregate): string
{
return
- \get_class($aggregate).
- \get_class($aggregate->aggregateRootId()).
- $aggregate->aggregateRootId()->toString()
+ $aggregate::class.
+ $aggregate->id()::class.
+ $aggregate->id()->toString()
;
}
}
diff --git a/src/Infrastructure/Domain/Event/Converter/NestedObjectConverter.php b/src/Infrastructure/Domain/Event/Converter/NestedObjectConverter.php
index db3e1b9f..1536f27e 100644
--- a/src/Infrastructure/Domain/Event/Converter/NestedObjectConverter.php
+++ b/src/Infrastructure/Domain/Event/Converter/NestedObjectConverter.php
@@ -85,7 +85,7 @@ private function toArray($event): array
continue;
}
- if (is_scalar($value)) {
+ if (\is_scalar($value)) {
continue;
}
if (null === $value) {
diff --git a/src/Infrastructure/Domain/Event/Listener/CompositeFactory.php b/src/Infrastructure/Domain/Event/Listener/CompositeFactory.php
index 7ae95266..b736abbe 100644
--- a/src/Infrastructure/Domain/Event/Listener/CompositeFactory.php
+++ b/src/Infrastructure/Domain/Event/Listener/CompositeFactory.php
@@ -42,7 +42,7 @@ public function create(Listener\Id $id): Listener
foreach ($this->factories as $factory) {
try {
return $factory->create($id);
- } catch (Exception\InvalidIdGiven $e) {
+ } catch (Exception\InvalidIdGiven) {
continue;
}
}
diff --git a/src/Infrastructure/Domain/Event/LoggingListener.php b/src/Infrastructure/Domain/Event/LoggingListener.php
index f2a57ace..a2ebe843 100644
--- a/src/Infrastructure/Domain/Event/LoggingListener.php
+++ b/src/Infrastructure/Domain/Event/LoggingListener.php
@@ -32,14 +32,9 @@ public function __construct(private Event\Listener $listener, private LoggerInte
{
}
- public function id(): Domain\Id
+ public function id(): Listener\Id
{
- return $this->listenerId();
- }
-
- public function listenerId(): Listener\Id
- {
- return $this->listener->listenerId();
+ return $this->listener->id();
}
public function on(Event\Envelope $event): bool
diff --git a/src/Infrastructure/Domain/Event/NullListener.php b/src/Infrastructure/Domain/Event/NullListener.php
index a98dfa12..07c9d929 100644
--- a/src/Infrastructure/Domain/Event/NullListener.php
+++ b/src/Infrastructure/Domain/Event/NullListener.php
@@ -32,6 +32,6 @@ public function on(Event\Envelope $event): bool
public static function from(Event\Listener $listener)
{
- return new self($listener->listenerId());
+ return new self($listener->id());
}
}
diff --git a/src/Infrastructure/Domain/Event/Sourced/Subscription.php b/src/Infrastructure/Domain/Event/Sourced/Subscription.php
index b74701ee..f533a16f 100644
--- a/src/Infrastructure/Domain/Event/Sourced/Subscription.php
+++ b/src/Infrastructure/Domain/Event/Sourced/Subscription.php
@@ -19,7 +19,6 @@
use Streak\Domain\Event\Listener\State;
use Streak\Domain\Event\Subscription\Exception;
use Streak\Domain\EventStore;
-use Streak\Domain\Versionable;
use Streak\Infrastructure\Domain\Event\InMemoryStream;
use Streak\Infrastructure\Domain\Event\Sourced\Subscription\Event\SubscriptionCompleted;
use Streak\Infrastructure\Domain\Event\Sourced\Subscription\Event\SubscriptionIgnoredEvent;
@@ -36,12 +35,8 @@
*
* @see \Streak\Infrastructure\Domain\Event\Sourced\SubscriptionTest
*/
-final class Subscription implements Event\Subscription, Event\Sourced, Versionable
+final class Subscription implements Event\Sourced\Subscription
{
- use Event\Sourcing {
- Event\Sourcing::replay as private doReplay;
- }
-
private const LIMIT_TO_INITIAL_STREAM = 0;
private State $lastState;
private ?Event\Envelope $completedBy = null;
@@ -50,11 +45,24 @@ final class Subscription implements Event\Subscription, Event\Sourced, Versionab
private bool $starting = false;
private $lastProcessedEvent;
+ /**
+ * @var Event\Envelope[]
+ */
+ private array $events = [];
+ private ?Event\Envelope $lastEvent = null;
+ private bool $replaying = false;
+ private int $version = 0;
+
public function __construct(private Event\Listener $listener, private Domain\Clock $clock)
{
$this->lastState = InMemoryState::empty();
}
+ public function id(): Listener\Id
+ {
+ return $this->listener->id();
+ }
+
/**
* @throws Exception\SubscriptionAlreadyCompleted
* @throws Exception\SubscriptionNotStartedYet
@@ -243,7 +251,6 @@ public function replay(Event\Stream $stream): void
$this->doReplay($substream);
if ($this->completed()) {
- $this->lastReplayed = $last;
$this->lastEvent = $last;
$this->version = (int) $last->version();
@@ -267,7 +274,6 @@ public function replay(Event\Stream $stream): void
$this->doReplay(new InMemoryStream($changed));
}
- $this->lastReplayed = $last;
$this->lastEvent = $last;
$this->version = (int) $last->version();
}
@@ -278,23 +284,13 @@ public function equals(object $object): bool
return false;
}
- if (!$this->subscriptionId()->equals($object->subscriptionId())) {
+ if (!$this->id()->equals($object->id())) {
return false;
}
return true;
}
- public function producerId(): Domain\Id
- {
- return $this->subscriptionId();
- }
-
- public function subscriptionId(): Event\Listener\Id
- {
- return $this->listener->listenerId();
- }
-
public function listener(): Listener
{
return $this->listener;
@@ -320,6 +316,45 @@ public function completed(): bool
return null !== $this->completedBy;
}
+ public function lastEvent(): ?Event\Envelope
+ {
+ return $this->lastEvent;
+ }
+
+ public function version(): int
+ {
+ return $this->version;
+ }
+
+ /**
+ * @return Event\Envelope[]
+ */
+ public function events(): array
+ {
+ return $this->events;
+ }
+
+ public function commit(): void
+ {
+ $this->version += \count($this->events);
+ $this->events = [];
+ }
+
+ /**
+ * @throws \Throwable
+ */
+ private function doReplay(Event\Stream $stream): void
+ {
+ try {
+ $this->replaying = true;
+ foreach ($stream as $event) {
+ $this->applyEvent($event);
+ }
+ } finally {
+ $this->replaying = false;
+ }
+ }
+
/**
* @see applySubscriptionListenedToEvent
* @see applySubscriptionIgnoredEvent
@@ -363,46 +398,28 @@ private function doApplyEvent(Event\Envelope $event): void
{
if ($event->message() instanceof SubscriptionListenedToEvent) {
$this->applySubscriptionListenedToEvent($event);
-
- return;
}
if ($event->message() instanceof SubscriptionIgnoredEvent) {
$this->applySubscriptionIgnoredEvent($event);
-
- return;
}
if ($event->message() instanceof SubscriptionCompleted) {
$this->applySubscriptionCompleted();
-
- return;
}
if ($event->message() instanceof SubscriptionStarted) {
$this->applySubscriptionStarted($event);
-
- return;
}
if ($event->message() instanceof SubscriptionRestarted) {
$this->applySubscriptionRestarted($event);
-
- return;
}
if ($event->message() instanceof SubscriptionListenersStateChanged) {
$this->applySubscriptionListenersStateChanged($event);
-
- return;
}
if ($event->message() instanceof SubscriptionPaused) {
$this->applySubscriptionPaused($event);
-
- return;
}
if ($event->message() instanceof SubscriptionUnPaused) {
$this->applySubscriptionUnPaused($event);
-
- return;
}
-
- throw new Event\Exception\NoEventApplyingMethodFound($this, $event); // @codeCoverageIgnore
}
private function applySubscriptionListenedToEvent(Event\Envelope $event): void
@@ -457,4 +474,40 @@ private function applySubscriptionListenersStateChanged(Event\Envelope $event):
$this->listener->fromState($state);
}
}
+
+ /**
+ * @throws Event\Exception\NoEventApplyingMethodFound
+ * @throws Event\Exception\TooManyEventApplyingMethodsFound
+ * @throws \Throwable
+ */
+ private function apply(Event $event): void
+ {
+ $event = Event\Envelope::new(
+ $event,
+ $this->id(),
+ $this->version + \count($this->events) + 1
+ );
+
+ $this->applyEvent($event);
+ }
+
+ /**
+ * @throws \Throwable
+ */
+ private function applyEvent(Event\Envelope $event): void
+ {
+ if (!$this->id()->equals($event->producerId())) {
+ throw new Domain\Exception\EventMismatched($this, $event);
+ }
+
+ $this->doApplyEvent($event);
+
+ $this->lastEvent = $event;
+
+ if ($this->replaying) {
+ $this->version = $event->version();
+ } else {
+ $this->events[] = $event;
+ }
+ }
}
diff --git a/src/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryState.php b/src/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryState.php
index 8475e505..3364262a 100644
--- a/src/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryState.php
+++ b/src/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryState.php
@@ -102,7 +102,7 @@ private function validate(string $name, $value): void
$value = [$name => $value];
array_walk_recursive($value, function ($value, $key): void {
- if (true === is_scalar($value)) {
+ if (true === \is_scalar($value)) {
return;
}
if (null === $value) {
diff --git a/src/Infrastructure/Domain/Event/Subscription/CommittingSubscription.php b/src/Infrastructure/Domain/Event/Subscription/CommittingSubscription.php
index bd84b6f6..55d6ac7f 100644
--- a/src/Infrastructure/Domain/Event/Subscription/CommittingSubscription.php
+++ b/src/Infrastructure/Domain/Event/Subscription/CommittingSubscription.php
@@ -34,9 +34,9 @@ public function subscription(): Subscription
return $this->subscription;
}
- public function subscriptionId(): Event\Listener\Id
+ public function id(): Event\Listener\Id
{
- return $this->subscription->subscriptionId();
+ return $this->subscription->id();
}
public function listener(): Event\Listener
diff --git a/src/Infrastructure/Domain/Event/Subscription/DAO/DAORepository.php b/src/Infrastructure/Domain/Event/Subscription/DAO/DAORepository.php
index 489c7f21..0249f855 100644
--- a/src/Infrastructure/Domain/Event/Subscription/DAO/DAORepository.php
+++ b/src/Infrastructure/Domain/Event/Subscription/DAO/DAORepository.php
@@ -44,7 +44,7 @@ public function find(Event\Listener\Id $id): ?Event\Subscription
public function has(Event\Subscription $subscription): bool
{
- return $this->dao->exists($subscription->subscriptionId());
+ return $this->dao->exists($subscription->id());
}
public function add(Event\Subscription $subscription): void
diff --git a/src/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAO.php b/src/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAO.php
index ce593c95..409ebb42 100644
--- a/src/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAO.php
+++ b/src/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAO.php
@@ -87,8 +87,8 @@ public function all(array $types = [], ?bool $completed = null): iterable
public function toRow(DAO\Subscription $subscription): array
{
// dehydrate
- $row['subscription_type'] = $subscription->subscriptionId()::class;
- $row['subscription_id'] = $subscription->subscriptionId()->toString();
+ $row['subscription_type'] = $subscription->id()::class;
+ $row['subscription_id'] = $subscription->id()->toString();
$row['subscription_version'] = $subscription->version();
$reflection = new \ReflectionObject($subscription);
diff --git a/src/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDao.php b/src/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDao.php
index b00a14aa..be4e54ea 100644
--- a/src/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDao.php
+++ b/src/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDao.php
@@ -83,7 +83,7 @@ public function shouldSave(Subscription $subscription): bool
private function key(Subscription $subscription): string
{
- return sprintf('%s_%s', $subscription->subscriptionId()::class, $subscription->subscriptionId()->toString());
+ return sprintf('%s_%s', $subscription->id()::class, $subscription->id()->toString());
}
private function rememberVersion(Subscription $subscription): void
diff --git a/src/Infrastructure/Domain/Event/Subscription/DAO/InMemoryDAO.php b/src/Infrastructure/Domain/Event/Subscription/DAO/InMemoryDAO.php
index 145234dd..56360950 100644
--- a/src/Infrastructure/Domain/Event/Subscription/DAO/InMemoryDAO.php
+++ b/src/Infrastructure/Domain/Event/Subscription/DAO/InMemoryDAO.php
@@ -32,7 +32,7 @@ class InMemoryDAO implements DAO
public function save(Subscription $subscription): void
{
foreach ($this->subscriptions as $key => $stored) {
- if ($stored->subscriptionId()->equals($subscription->subscriptionId())) {
+ if ($stored->id()->equals($subscription->id())) {
$this->subscriptions[$key] = $subscription;
return;
@@ -45,7 +45,7 @@ public function save(Subscription $subscription): void
public function one(Listener\Id $id): ?Subscription
{
foreach ($this->subscriptions as $key => $stored) {
- if ($stored->subscriptionId()->equals($id)) {
+ if ($stored->id()->equals($id)) {
return $stored;
}
}
@@ -62,7 +62,7 @@ public function all(array $types = [], ?bool $completed = null): iterable
{
foreach ($this->subscriptions as $key => $stored) {
if (\count($types)) {
- $type = $stored->subscriptionId()::class;
+ $type = $stored->id()::class;
if (false === \in_array($type, $types)) {
continue;
}
diff --git a/src/Infrastructure/Domain/Event/Subscription/DAO/Subscription.php b/src/Infrastructure/Domain/Event/Subscription/DAO/Subscription.php
index c995f50e..3c09522f 100644
--- a/src/Infrastructure/Domain/Event/Subscription/DAO/Subscription.php
+++ b/src/Infrastructure/Domain/Event/Subscription/DAO/Subscription.php
@@ -47,9 +47,9 @@ public function listener(): Listener
return $this->listener;
}
- public function subscriptionId(): Listener\Id
+ public function id(): Listener\Id
{
- return $this->listener->listenerId();
+ return $this->listener->id();
}
public function subscribeTo(EventStore $store, ?int $limit = null): iterable
diff --git a/src/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscription.php b/src/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscription.php
index fb34627b..84272f7d 100644
--- a/src/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscription.php
+++ b/src/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscription.php
@@ -40,9 +40,9 @@ public function listener(): Listener
return $this->subscription->listener();
}
- public function subscriptionId(): Listener\Id
+ public function id(): Listener\Id
{
- return $this->subscription->subscriptionId();
+ return $this->subscription->id();
}
public function subscribeTo(EventStore $store, ?int $limit = null): iterable
diff --git a/src/Infrastructure/Domain/Event/Subscription/EventSourcedRepository.php b/src/Infrastructure/Domain/Event/Subscription/EventSourcedRepository.php
index 0f530343..4a71a14a 100644
--- a/src/Infrastructure/Domain/Event/Subscription/EventSourcedRepository.php
+++ b/src/Infrastructure/Domain/Event/Subscription/EventSourcedRepository.php
@@ -43,7 +43,7 @@ public function find(Event\Listener\Id $id): ?Event\Subscription
$unwrapped = $this->unwrap($subscription);
$filter = new EventStore\Filter();
- $filter = $filter->filterProducerIds($unwrapped->producerId());
+ $filter = $filter->filterProducerIds($unwrapped->id());
$stream = $this->store->stream($filter);
@@ -66,7 +66,7 @@ public function has(Event\Subscription $subscription): bool
$unwrapped = $this->unwrap($subscription);
$filter = new EventStore\Filter();
- $filter = $filter->filterProducerIds($unwrapped->producerId());
+ $filter = $filter->filterProducerIds($unwrapped->id());
$stream = $this->store->stream($filter);
@@ -104,6 +104,7 @@ public function all(?Filter $filter = null): iterable
$ids = [];
foreach ($stream as $event) {
+ /** @var $event Event\Envelope */
if ($event->message() instanceof SubscriptionStarted) {
$ids[] = $event->producerId();
}
@@ -137,21 +138,18 @@ public function all(?Filter $filter = null): iterable
}
}
- /**
- * @return Event\Sourced|Subscription
- */
- private function unwrap(Event\Subscription $subscription): Event\Sourced
+ private function unwrap(Event\Subscription $subscription): Event\Sourced\Subscription
{
$exception = new Exception\ObjectNotSupported($subscription);
- if ($subscription instanceof Event\Sourced) {
+ if ($subscription instanceof Event\Sourced\Subscription) {
return $subscription;
}
while ($subscription instanceof Subscription\Decorator) {
$subscription = $subscription->subscription();
- if ($subscription instanceof Event\Sourced) {
+ if ($subscription instanceof Event\Sourced\Subscription) {
return $subscription;
}
}
diff --git a/src/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscription.php b/src/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscription.php
index 92857113..bae41b48 100644
--- a/src/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscription.php
+++ b/src/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscription.php
@@ -31,7 +31,7 @@ public function __construct(private Listener\Id $id, private Subscription\Reposi
{
}
- public function subscriptionId(): Listener\Id
+ public function id(): Listener\Id
{
return $this->id;
}
@@ -74,7 +74,7 @@ public function completed(): bool
public function subscription(): Subscription
{
if (null === $this->subscription) {
- $this->subscription = $this->repository->find($this->subscriptionId());
+ $this->subscription = $this->repository->find($this->id());
}
return $this->subscription;
diff --git a/src/Infrastructure/Domain/EventStore/DbalPostgresEventStore.php b/src/Infrastructure/Domain/EventStore/DbalPostgresEventStore.php
index 849201c9..ae47ce1c 100644
--- a/src/Infrastructure/Domain/EventStore/DbalPostgresEventStore.php
+++ b/src/Infrastructure/Domain/EventStore/DbalPostgresEventStore.php
@@ -451,7 +451,7 @@ public function event(UUID $uuid): ?Event\Envelope
return $this->fromRow($row);
}
- public function producerId($class, $id): Domain\Id
+ private function toId($class, $id): Domain\Id
{
$reflection = new \ReflectionClass($class);
@@ -643,18 +643,21 @@ private function fromRow(array $row): Event\Envelope
$body = json_decode($body, true);
$body = $this->converter->arrayToObject($body);
- $producerId = $this->producerId($row['producer_type'], $row['producer_id']);
+ /* TODO: store entity type and id as columns */
+ $metadata = $row['metadata'];
+ $metadata = json_decode($metadata, true);
+
+ $producerId = $this->toId($row['producer_type'], $row['producer_id']);
+ $entityId = $this->toId($metadata['entity_type'], $metadata['entity_id']);
$event = new Event\Envelope(
$uuid,
$row['type'],
$body,
$producerId,
- $row['producer_version']
+ $row['producer_version'],
);
- $metadata = $row['metadata'];
- $metadata = json_decode($metadata, true);
$metadata[self::EVENT_METADATA_NUMBER] = $row['number'];
foreach ($metadata as $name => $value) {
@@ -702,7 +705,7 @@ private function extractIdForConcurrentWrite(UniqueConstraintViolationException
return null; // @codeCoverageIgnore
}
- return $this->producerId($matches['type'], $matches['id']);
+ return $this->toId($matches['type'], $matches['id']);
}
private function extractIdForEventAlreadyInStore(UniqueConstraintViolationException $e)
diff --git a/src/Infrastructure/Domain/Testing/AggregateRoot/Scenario.php b/src/Infrastructure/Domain/Testing/AggregateRoot/Scenario.php
index c9a89012..a8fd0d2e 100644
--- a/src/Infrastructure/Domain/Testing/AggregateRoot/Scenario.php
+++ b/src/Infrastructure/Domain/Testing/AggregateRoot/Scenario.php
@@ -27,24 +27,14 @@
*/
class Scenario implements Scenario\Given, Scenario\When, Scenario\Then
{
- private Domain\CommandHandler $handler;
- private InMemoryEventStore $store;
- private Domain\AggregateRoot\Factory $factory;
- private Snapshotter $snapshotter;
- private UnitOfWork $uow;
private ?Domain\AggregateRoot\Id $id = null;
/**
* @var Domain\Event\Envelope[]
*/
private array $events = [];
- public function __construct(Domain\CommandHandler $handler, InMemoryEventStore $store, Domain\AggregateRoot\Factory $factory, Snapshotter $snapshotter, UnitOfWork $uow)
+ public function __construct(private Domain\CommandHandler $handler, private InMemoryEventStore $store, private Domain\AggregateRoot\Factory $factory, private Snapshotter $snapshotter, private UnitOfWork $uow)
{
- $this->handler = $handler;
- $this->store = $store;
- $this->factory = $factory;
- $this->snapshotter = $snapshotter;
- $this->uow = $uow;
}
public function for(Domain\AggregateRoot\Id $id): Given
diff --git a/src/Infrastructure/Domain/Testing/Listener/Scenario.php b/src/Infrastructure/Domain/Testing/Listener/Scenario.php
index eb07458e..b7044f7e 100644
--- a/src/Infrastructure/Domain/Testing/Listener/Scenario.php
+++ b/src/Infrastructure/Domain/Testing/Listener/Scenario.php
@@ -28,10 +28,6 @@
*/
class Scenario implements Scenario\Given, Scenario\When, Scenario\Then, Domain\CommandHandler
{
- private Application\CommandBus $bus;
-
- private Event\Listener\Factory $factory;
-
/**
* @var Event\Envelope[]
*/
@@ -56,11 +52,9 @@ class Scenario implements Scenario\Given, Scenario\When, Scenario\Then, Domain\C
*/
private array $expectedErrors = [];
- public function __construct(Application\CommandBus $bus, Event\Listener\Factory $factory)
+ public function __construct(private Application\CommandBus $bus, private Event\Listener\Factory $factory)
{
- $this->bus = $bus;
$this->bus->register($this);
- $this->factory = $factory;
}
public function given(Domain\Event ...$events): Scenario\When
@@ -110,10 +104,10 @@ public function assert(callable $constraint = null): void
$previousState = $currentState;
$previousListener = $listener;
- $listener = $this->factory->create($previousListener->listenerId());
+ $listener = $this->factory->create($previousListener->id());
$listener->fromState($currentState);
- Assert::assertEquals($previousListener, $listener, sprintf('Listener "%s" that listened to %s" and generated incomplete state. Please review your Listener\Stateful::toState() and Listener\Stateful::fromState() methods.', \get_class($listener), \get_class($event)));
+ Assert::assertEquals($previousListener, $listener, sprintf('Listener "%s" that listened to %s" and generated incomplete state. Please review your Listener\Stateful::toState() and Listener\Stateful::fromState() methods.', $listener::class, $event::class));
}
$this->replaying = false;
}
@@ -128,7 +122,7 @@ public function assert(callable $constraint = null): void
$stream = $listener->filter($stream);
$stream = iterator_to_array($stream);
- Assert::assertEquals([$this->when], $stream, sprintf('Listener is not listening to %s event.', \get_class($this->when)));
+ Assert::assertEquals([$this->when], $stream, sprintf('Listener is not listening to %s event.', $this->when::class));
}
Assert::assertNotEmpty($this->expectedCommands, 'At least one then() clause is required.');
@@ -137,7 +131,7 @@ public function assert(callable $constraint = null): void
$listener->on($this->when);
if (!$listener instanceof Event\Listener\Stateful) {
- Assert::assertEquals($listener, $new, sprintf('State introduced when listener "%s" listened to "%s" event, but listener is not implementing "%s" interface.', \get_class($listener), \get_class($this->when), Event\Listener\Stateful::class));
+ Assert::assertEquals($listener, $new, sprintf('State introduced when listener "%s" listened to "%s" event, but listener is not implementing "%s" interface.', $listener::class, $this->when::class, Event\Listener\Stateful::class));
}
Assert::assertEquals($this->expectedCommands, $this->actualCommands, 'Expected commands do not match actual commands dispatched by the listener.');
diff --git a/src/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWork.php b/src/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWork.php
index 4e3579df..37df8a39 100644
--- a/src/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWork.php
+++ b/src/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWork.php
@@ -57,7 +57,7 @@ public function remove(object $producer): void
foreach ($this->uncommited as $key => $current) {
// @var $current Event\Producer
- if ($current->producerId()->equals($producer->producerId())) {
+ if ($current->id()->equals($producer->id())) {
unset($this->uncommited[$key]);
return;
@@ -73,7 +73,7 @@ public function has(object $producer): bool
foreach ($this->uncommited as $current) {
// @var $current Event\Producer
- if ($current->producerId()->equals($producer->producerId())) {
+ if ($current->id()->equals($producer->id())) {
return true;
}
}
diff --git a/src/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWork.php b/src/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWork.php
index 7dd2185d..88793707 100644
--- a/src/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWork.php
+++ b/src/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWork.php
@@ -43,7 +43,7 @@ public function add(object $producer): void
$this->uow->add($producer);
if ($producer instanceof Event\Sourced\AggregateRoot) {
- $id = $producer->producerId();
+ $id = $producer->id();
$version = $producer->version();
$this->versions->attach($id, $version);
}
@@ -52,7 +52,7 @@ public function add(object $producer): void
public function remove(object $producer): void
{
if ($producer instanceof Event\Sourced\AggregateRoot) {
- $id = $producer->producerId();
+ $id = $producer->id();
$this->versions->offsetUnset($id);
}
@@ -90,10 +90,10 @@ public function commit(): \Generator
continue;
}
- $versionBeforeCommit = $this->versions->offsetGet($committed->producerId());
+ $versionBeforeCommit = $this->versions->offsetGet($committed->id());
$versionAfterCommit = $committed->version();
- $this->versions->offsetUnset($committed->producerId());
+ $this->versions->offsetUnset($committed->id());
if (!$this->isReadyForSnapshot($versionBeforeCommit, $versionAfterCommit)) {
yield $committed;
diff --git a/src/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWork.php b/src/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWork.php
index 8606b746..93fa4864 100644
--- a/src/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWork.php
+++ b/src/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWork.php
@@ -53,7 +53,7 @@ public function remove(object $subscription): void
}
foreach ($this->uncommited as $key => $current) {
- if ($current->subscriptionId()->equals($subscription->subscriptionId())) {
+ if ($current->id()->equals($subscription->id())) {
unset($this->uncommited[$key]);
return;
@@ -68,7 +68,7 @@ public function has(object $subscription): bool
}
foreach ($this->uncommited as $current) {
- if ($current->subscriptionId()->equals($subscription->subscriptionId())) {
+ if ($current->id()->equals($subscription->id())) {
return true;
}
}
diff --git a/tests/Application/Sensor/IdentificationTest.php b/tests/Application/Sensor/IdentificationTest.php
index ec8c7f2f..00a44192 100644
--- a/tests/Application/Sensor/IdentificationTest.php
+++ b/tests/Application/Sensor/IdentificationTest.php
@@ -34,8 +34,6 @@ public function testObject(): void
{
$identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
- self::assertSame($this->id, $identification->sensorId());
- self::assertSame($this->id, $identification->producerId());
self::assertSame($this->id, $identification->id());
}
}
diff --git a/tests/Application/Sensor/ProcessingTest.php b/tests/Application/Sensor/ProcessingTest.php
index d088a8fd..c0d25103 100644
--- a/tests/Application/Sensor/ProcessingTest.php
+++ b/tests/Application/Sensor/ProcessingTest.php
@@ -47,8 +47,6 @@ public function testObject(): void
$sensor = new SensorStub1($this->id);
self::assertSame($this->id, $sensor->id());
- self::assertSame($this->id, $sensor->producerId());
- self::assertSame($this->id, $sensor->sensorId());
self::assertNull($sensor->last());
self::assertEmpty($sensor->events());
@@ -123,6 +121,16 @@ public function testTransactionalityOfProcessMethod(): void
// no new assertions here please
}
+
+ public function testNoMethodFound(): void
+ {
+ $sensor = new SensorStub2($this->id);
+
+ $this->expectExceptionObject(new \InvalidArgumentException('No method found to process message.'));
+
+ $stdClass = new \stdClass();
+ $sensor->process($stdClass);
+ }
}
namespace Streak\Application\Sensor\ProcessingTest;
@@ -219,51 +227,36 @@ public function processStringAndThrowAnException(string $string): void
class ArrayProcessed implements Event
{
- private array $array;
-
- public function __construct(array $array)
+ public function __construct(private array $array)
{
- $this->array = $array;
}
}
class IntegerProcessed implements Event
{
- private int $integer;
-
- public function __construct(int $array)
+ public function __construct(private int $integer)
{
- $this->integer = $array;
}
}
class StringProcessed implements Event
{
- private string $string;
-
- public function __construct(string $string)
+ public function __construct(private string $string)
{
- $this->string = $string;
}
}
class StdClassProcessed implements Event
{
- private \stdClass $stdClass;
-
- public function __construct(\stdClass $stdClass)
+ public function __construct(private \stdClass $stdClass)
{
- $this->stdClass = $stdClass;
}
}
class BooleanProcessed implements Event
{
- private bool $boolean;
-
- public function __construct(bool $boolean)
+ public function __construct(private bool $boolean)
{
- $this->boolean = $boolean;
}
}
@@ -281,30 +274,21 @@ class B2 extends A
class AProcessed implements Event
{
- private A $a;
-
- public function __construct(A $a)
+ public function __construct(private A $a)
{
- $this->a = $a;
}
}
class B2Processed implements Event
{
- private B2 $b2;
-
- public function __construct(B2 $b2)
+ public function __construct(private B2 $b2)
{
- $this->b2 = $b2;
}
}
class B1Processed implements Event
{
- private B1 $b1;
-
- public function __construct(B1 $b1)
+ public function __construct(private B1 $b1)
{
- $this->b1 = $b1;
}
}
diff --git a/tests/Domain/Aggregate/ComparisonTest.php b/tests/Domain/Aggregate/ComparisonTest.php
index 6fb44237..d0dbb9fc 100644
--- a/tests/Domain/Aggregate/ComparisonTest.php
+++ b/tests/Domain/Aggregate/ComparisonTest.php
@@ -81,30 +81,16 @@ public function testObject(): void
use Streak\Domain;
use Streak\Domain\Aggregate;
-use Streak\Domain\Entity;
class ComparisonStub implements Domain\Aggregate
{
use Aggregate\Comparison;
- private Aggregate\Id $id;
-
- public function __construct(Aggregate\Id $id)
- {
- $this->id = $id;
- }
-
- public function aggregateId(): Aggregate\Id
- {
- return $this->id;
- }
-
- public function entityId(): Entity\Id
+ public function __construct(private Aggregate\Id $id)
{
- return $this->id;
}
- public function id(): Domain\Id
+ public function id(): Aggregate\Id
{
return $this->id;
}
@@ -114,19 +100,11 @@ class NonAggregateComparisonStub
{
use Aggregate\Comparison;
- private Aggregate\Id $id;
-
- public function __construct(Aggregate\Id $id)
+ public function __construct(private Aggregate\Id $id)
{
- $this->id = $id;
- }
-
- public function aggregateId(): Aggregate\Id
- {
- return $this->id;
}
- public function entityId(): Entity\Id
+ public function id(): Aggregate\Id
{
return $this->id;
}
diff --git a/tests/Domain/Aggregate/IdentificationTest.php b/tests/Domain/Aggregate/IdentificationTest.php
index cc666325..0bd56ab6 100644
--- a/tests/Domain/Aggregate/IdentificationTest.php
+++ b/tests/Domain/Aggregate/IdentificationTest.php
@@ -34,8 +34,6 @@ public function testObject(): void
{
$identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
- self::assertSame($this->id, $identification->aggregateId());
- self::assertSame($this->id, $identification->entityId());
self::assertSame($this->id, $identification->id());
}
}
diff --git a/tests/Domain/AggregateRoot/ComparisonTest.php b/tests/Domain/AggregateRoot/ComparisonTest.php
index a10127a4..11773df2 100644
--- a/tests/Domain/AggregateRoot/ComparisonTest.php
+++ b/tests/Domain/AggregateRoot/ComparisonTest.php
@@ -80,37 +80,17 @@ public function testObject(): void
namespace Streak\Domain\AggregateRoot\ComparisonTest;
use Streak\Domain;
-use Streak\Domain\Aggregate;
use Streak\Domain\AggregateRoot;
-use Streak\Domain\Entity;
class ComparisonStub implements Domain\AggregateRoot
{
use AggregateRoot\Comparison;
- private AggregateRoot\Id $id;
-
- public function __construct(AggregateRoot\Id $id)
- {
- $this->id = $id;
- }
-
- public function aggregateRootId(): AggregateRoot\Id
- {
- return $this->id;
- }
-
- public function aggregateId(): Aggregate\Id
- {
- return $this->id;
- }
-
- public function entityId(): Entity\Id
+ public function __construct(private AggregateRoot\Id $id)
{
- return $this->id;
}
- public function id(): Domain\Id
+ public function id(): AggregateRoot\Id
{
return $this->id;
}
@@ -120,24 +100,11 @@ class NonAggregateRootComparisonStub
{
use AggregateRoot\Comparison;
- private AggregateRoot\Id $id;
-
- public function __construct(AggregateRoot\Id $id)
- {
- $this->id = $id;
- }
-
- public function aggregateRootId(): AggregateRoot\Id
+ public function __construct(private AggregateRoot\Id $id)
{
- return $this->id;
- }
-
- public function aggregateId(): Aggregate\Id
- {
- return $this->id;
}
- public function entityId(): Entity\Id
+ public function id(): AggregateRoot\Id
{
return $this->id;
}
diff --git a/tests/Domain/AggregateRoot/IdentificationTest.php b/tests/Domain/AggregateRoot/IdentificationTest.php
index 59bbcc56..6dec46e8 100644
--- a/tests/Domain/AggregateRoot/IdentificationTest.php
+++ b/tests/Domain/AggregateRoot/IdentificationTest.php
@@ -34,9 +34,6 @@ public function testObject(): void
{
$identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
- self::assertSame($this->id, $identification->aggregateRootId());
- self::assertSame($this->id, $identification->aggregateId());
- self::assertSame($this->id, $identification->entityId());
self::assertSame($this->id, $identification->id());
}
}
diff --git a/tests/Domain/Entity/ComparisonTest.php b/tests/Domain/Entity/ComparisonTest.php
index 64a86551..39b9b471 100644
--- a/tests/Domain/Entity/ComparisonTest.php
+++ b/tests/Domain/Entity/ComparisonTest.php
@@ -86,19 +86,11 @@ class ComparisonStub implements Domain\Entity
{
use Entity\Comparison;
- private Entity\Id $id;
-
- public function __construct(Entity\Id $id)
- {
- $this->id = $id;
- }
-
- public function entityId(): Entity\Id
+ public function __construct(private Entity\Id $id)
{
- return $this->id;
}
- public function id(): Domain\Id
+ public function id(): Entity\Id
{
return $this->id;
}
@@ -108,14 +100,11 @@ class NonEntityComparisonStub
{
use Entity\Comparison;
- private Entity\Id $id;
-
- public function __construct(Entity\Id $id)
+ public function __construct(private Entity\Id $id)
{
- $this->id = $id;
}
- public function entityId(): Entity\Id
+ public function id(): Entity\Id
{
return $this->id;
}
diff --git a/tests/Domain/Entity/IdentificationTest.php b/tests/Domain/Entity/IdentificationTest.php
index 434257a6..bc52992b 100644
--- a/tests/Domain/Entity/IdentificationTest.php
+++ b/tests/Domain/Entity/IdentificationTest.php
@@ -34,7 +34,6 @@ public function testObject(): void
{
$identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
- self::assertSame($this->id, $identification->entityId());
self::assertSame($this->id, $identification->id());
}
}
diff --git a/tests/Domain/Event/EnvelopeTest.php b/tests/Domain/Event/EnvelopeTest.php
index a9906358..344af0e4 100644
--- a/tests/Domain/Event/EnvelopeTest.php
+++ b/tests/Domain/Event/EnvelopeTest.php
@@ -14,6 +14,7 @@
namespace Streak\Domain\Event;
use PHPUnit\Framework\TestCase;
+use Streak\Domain\Entity;
use Streak\Domain\Event;
use Streak\Domain\Id\UUID;
@@ -25,10 +26,16 @@
class EnvelopeTest extends TestCase
{
private Event $event1;
+ private Event $event2;
+ private Entity\Id $entityId1;
+ private Entity\Id $entityId2;
protected function setUp(): void
{
$this->event1 = $this->getMockBuilder(Event::class)->setMockClassName('dushf9fguiewhfh')->getMockForAbstractClass();
+ $this->event2 = $this->getMockBuilder(Event::class)->setMockClassName('y7rb7wfe77fcw7e')->getMockForAbstractClass();
+ $this->entityId1 = Event\EnvelopeTest\EntityId::random();
+ $this->entityId2 = Event\EnvelopeTest\EntityId::random();
}
public function testEnvelope(): void
@@ -48,7 +55,7 @@ public function testEnvelope(): void
self::assertSame($this->event1, $envelope1a->message());
self::assertSame(\PHP_INT_MAX, $envelope1a->version());
self::assertSame(\PHP_INT_MAX, $envelope1a->get($envelope1a::METADATA_VERSION));
- self::assertSame(['uuid' => $envelope1a->uuid()->toString(), 'name' => $envelope1a->name(), 'producer_type' => 'Streak\Domain\Id\UUID', 'producer_id' => $envelope1a->producerId()->toString(), 'version' => $envelope1a->version()], $envelope1a->metadata());
+ self::assertSame(['uuid' => $envelope1a->uuid()->toString(), 'name' => $envelope1a->name(), 'producer_type' => 'Streak\Domain\Id\UUID', 'producer_id' => $envelope1a->producerId()->toString(), 'entity_type' => 'Streak\Domain\Id\UUID', 'entity_id' => $envelope1a->producerId()->toString(), 'version' => $envelope1a->version()], $envelope1a->metadata());
self::assertNull($envelope1a->get('attr-1'));
$envelope1b = $envelope1a->set('attr-1', 'value-1');
@@ -56,19 +63,19 @@ public function testEnvelope(): void
self::assertNotSame($envelope1a, $envelope1b);
self::assertNull($envelope1a->get('attr-1'));
- self::assertSame(['uuid' => $envelope1a->uuid()->toString(), 'name' => $envelope1a->name(), 'producer_type' => 'Streak\Domain\Id\UUID', 'producer_id' => $envelope1a->producerId()->toString(), 'version' => $envelope1a->version(), 'attr-1' => 'value-1'], $envelope1b->metadata());
+ self::assertSame(['uuid' => $envelope1a->uuid()->toString(), 'name' => $envelope1a->name(), 'producer_type' => 'Streak\Domain\Id\UUID', 'producer_id' => $envelope1a->producerId()->toString(), 'entity_type' => 'Streak\Domain\Id\UUID', 'entity_id' => $envelope1a->producerId()->toString(), 'version' => $envelope1a->version(), 'attr-1' => 'value-1'], $envelope1b->metadata());
self::assertSame('value-1', $envelope1b->get('attr-1'));
- $envelope2a = new Event\Envelope($uuid, 'dushf9fguiewhfh', $this->event1, $producerId, \PHP_INT_MAX);
- $envelope2b = new Event\Envelope($uuid, 'dushf9fguiewhfh', $this->event1, $producerId, \PHP_INT_MAX);
+ $envelope2a = new Event\Envelope($uuid, 'dushf9fguiewhfh', $this->event1, $producerId, $producerId, \PHP_INT_MAX);
+ $envelope2b = new Event\Envelope($uuid, 'dushf9fguiewhfh', $this->event1, $producerId, $producerId, \PHP_INT_MAX);
self::assertInstanceOf(Envelope::class, $envelope2a);
- self::assertTrue($envelope2a->uuid()->equals($uuid));
+ self::assertEquals($envelope2a->uuid(), $uuid);
self::assertSame('dushf9fguiewhfh', $envelope2a->name());
- self::assertTrue($envelope2a->producerId()->equals($producerId));
+ self::assertEquals($envelope2a->producerId(), $producerId);
self::assertSame($this->event1, $envelope2a->message());
self::assertSame(\PHP_INT_MAX, $envelope2a->version());
- self::assertSame(['uuid' => $envelope2a->uuid()->toString(), 'name' => $envelope2a->name(), 'producer_type' => 'Streak\Domain\Id\UUID', 'producer_id' => $envelope2a->producerId()->toString(), 'version' => $envelope2a->version()], $envelope2a->metadata());
+ self::assertSame(['uuid' => $envelope2a->uuid()->toString(), 'name' => $envelope2a->name(), 'producer_type' => 'Streak\Domain\Id\UUID', 'producer_id' => $envelope2a->producerId()->toString(), 'entity_type' => 'Streak\Domain\Id\UUID', 'entity_id' => $envelope2a->producerId()->toString(), 'version' => $envelope2a->version()], $envelope2a->metadata());
self::assertTrue($envelope1a->equals($envelope1a));
self::assertTrue($envelope2a->equals($envelope2a));
@@ -77,6 +84,38 @@ public function testEnvelope(): void
self::assertTrue($envelope2a->equals($envelope2b));
self::assertFalse($envelope1a->equals(new \stdClass()));
+
+ $envelope3 = Event\Envelope::new($this->event2, $producerId);
+ $envelope3 = $envelope3->defineEntityId($this->entityId2);
+
+ self::assertNull($envelope3->version());
+ self::assertSame('y7rb7wfe77fcw7e', $envelope3->name());
+ self::assertEquals($envelope3->producerId(), $producerId);
+ self::assertEquals($envelope3->entityId(), $this->entityId2);
+
+ $envelope4 = $envelope3->defineVersion(1);
+
+ self::assertTrue($envelope3->equals($envelope4));
+ self::assertTrue($envelope4->equals($envelope3));
+
+ self::assertSame(1, $envelope4->version());
+ self::assertSame('y7rb7wfe77fcw7e', $envelope4->name());
+ self::assertTrue($envelope4->producerId()->equals($producerId));
+ self::assertTrue($envelope4->entityId()->equals($this->entityId2));
+
+ $envelope5 = $envelope4->defineVersion(2);
+
+ self::assertSame(2, $envelope5->version());
+ self::assertSame('y7rb7wfe77fcw7e', $envelope5->name());
+ self::assertTrue($envelope5->producerId()->equals($producerId));
+ self::assertTrue($envelope5->entityId()->equals($this->entityId2));
+
+ $envelope6 = $envelope5->defineEntityId($this->entityId2);
+
+ self::assertSame(2, $envelope6->version());
+ self::assertSame('y7rb7wfe77fcw7e', $envelope6->name());
+ self::assertTrue($envelope6->producerId()->equals($producerId));
+ self::assertTrue($envelope6->entityId()->equals($this->entityId2));
}
public function testSettingEmptyAttributeName(): void
@@ -112,3 +151,12 @@ public function testSettingNonScalarAttribute($value): void
$envelope->set('attr-1', $value);
}
}
+
+namespace Streak\Domain\Event\EnvelopeTest;
+
+use Streak\Domain\Entity;
+use Streak\Domain\Id\UUID;
+
+class EntityId extends UUID implements Entity\Id
+{
+}
diff --git a/tests/Domain/Event/Exception/AggregateAlreadyRegisteredTest.php b/tests/Domain/Event/Exception/AggregateAlreadyRegisteredTest.php
index 8f787d78..ca1679ac 100644
--- a/tests/Domain/Event/Exception/AggregateAlreadyRegisteredTest.php
+++ b/tests/Domain/Event/Exception/AggregateAlreadyRegisteredTest.php
@@ -34,7 +34,7 @@ public function testException(): void
{
$exception = new AggregateAlreadyRegistered($this->aggregate);
- self::assertEquals('Aggregate already registered.', $exception->getMessage());
+ self::assertSame('Aggregate already registered.', $exception->getMessage());
self::assertSame($this->aggregate, $exception->aggregate());
}
}
diff --git a/tests/Domain/Event/Exception/EventNotSupportedTest.php b/tests/Domain/Event/Exception/EventNotSupportedTest.php
index fc5abaf0..5d65ad12 100644
--- a/tests/Domain/Event/Exception/EventNotSupportedTest.php
+++ b/tests/Domain/Event/Exception/EventNotSupportedTest.php
@@ -30,7 +30,7 @@ class EventNotSupportedTest extends TestCase
protected function setUp(): void
{
$producerId = $this->getMockBuilder(Domain\Id::class)->getMockForAbstractClass();
- $this->event = new Event\Envelope(UUID::random(), 'event', $this->getMockBuilder(Event::class)->getMockForAbstractClass(), $producerId, null);
+ $this->event = new Event\Envelope(UUID::random(), 'event', $this->getMockBuilder(Event::class)->getMockForAbstractClass(), $producerId, $producerId, null);
}
public function testException(): void
diff --git a/tests/Domain/Event/Exception/NoEventApplyingMethodFoundTest.php b/tests/Domain/Event/Exception/NoEventApplyingMethodFoundTest.php
index a83d12ee..7dba6718 100644
--- a/tests/Domain/Event/Exception/NoEventApplyingMethodFoundTest.php
+++ b/tests/Domain/Event/Exception/NoEventApplyingMethodFoundTest.php
@@ -24,20 +24,20 @@
*/
class NoEventApplyingMethodFoundTest extends TestCase
{
- private Event\Consumer $consumer;
+ private Event\Sourced\Entity $entity;
private Event\Envelope $event;
protected function setUp(): void
{
- $this->consumer = $this->getMockBuilder(Event\Consumer::class)->getMockForAbstractClass();
- $this->event = Event\Envelope::new($this->getMockBuilder(Domain\Event::class)->getMockForAbstractClass(), Domain\Id\UUID::random());
+ $this->entity = $this->getMockBuilder(Event\Sourced\Entity::class)->getMockForAbstractClass();
+ $this->event = Event\Envelope::new($this->getMockBuilder(Domain\Event::class)->getMockForAbstractClass(), $producerId = Domain\Id\UUID::random());
}
public function testException(): void
{
- $exception = new NoEventApplyingMethodFound($this->consumer, $this->event);
+ $exception = new NoEventApplyingMethodFound($this->entity, $this->event);
- self::assertSame($this->consumer, $exception->consumer());
+ self::assertSame($this->entity, $exception->object());
self::assertSame($this->event, $exception->event());
}
}
diff --git a/tests/Domain/Event/Exception/NotSupportedTypeTest.php b/tests/Domain/Event/Exception/NotSupportedTypeTest.php
index 5d738dae..5f89f2fe 100644
--- a/tests/Domain/Event/Exception/NotSupportedTypeTest.php
+++ b/tests/Domain/Event/Exception/NotSupportedTypeTest.php
@@ -29,7 +29,7 @@ public function testItCreates(string $expectedMessage, $value): void
{
$exception = new NotSupportedType($value);
self::assertEquals($value, $exception->value());
- self::assertEquals($expectedMessage, $exception->getMessage());
+ self::assertSame($expectedMessage, $exception->getMessage());
}
public function typesProvider(): array
diff --git a/tests/Domain/Event/Exception/TooManyEventApplyingMethodsFoundTest.php b/tests/Domain/Event/Exception/TooManyEventApplyingMethodsFoundTest.php
index 4f9d1daf..e9b9439c 100644
--- a/tests/Domain/Event/Exception/TooManyEventApplyingMethodsFoundTest.php
+++ b/tests/Domain/Event/Exception/TooManyEventApplyingMethodsFoundTest.php
@@ -24,21 +24,21 @@
*/
class TooManyEventApplyingMethodsFoundTest extends TestCase
{
- private Event\Consumer $consumer;
+ private Event\Sourced\Entity $entity;
private Event\Envelope $event;
protected function setUp(): void
{
- $this->consumer = $this->getMockBuilder(Event\Consumer::class)->getMockForAbstractClass();
+ $this->entity = $this->getMockBuilder(Event\Sourced\Entity::class)->getMockForAbstractClass();
$this->event = Event\Envelope::new($this->getMockBuilder(Event::class)->getMockForAbstractClass(), UUID::random());
}
public function testException(): void
{
- $exception = new TooManyEventApplyingMethodsFound($this->consumer, $this->event);
+ $exception = new TooManyEventApplyingMethodsFound($this->entity, $this->event);
- self::assertSame($this->consumer, $exception->consumer());
+ self::assertSame($this->entity, $exception->object());
self::assertSame($this->event, $exception->event());
}
}
diff --git a/tests/Domain/Event/Listener/ListeningTest.php b/tests/Domain/Event/Listener/ListeningTest.php
index 04edb752..ca10dbe0 100644
--- a/tests/Domain/Event/Listener/ListeningTest.php
+++ b/tests/Domain/Event/Listener/ListeningTest.php
@@ -309,11 +309,8 @@ class SupportedEvent3ThatCausesException implements Event
}
class SupportedEvent4 implements Event
{
- private $value;
-
- public function __construct($value)
+ public function __construct(private $value)
{
- $this->value = $value;
}
public function value()
diff --git a/tests/Domain/Event/Sourced/Aggregate/IdentificationTest.php b/tests/Domain/Event/Sourced/Aggregate/IdentificationTest.php
deleted file mode 100644
index fab96161..00000000
--- a/tests/Domain/Event/Sourced/Aggregate/IdentificationTest.php
+++ /dev/null
@@ -1,42 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\Aggregate;
-
-use PHPUnit\Framework\TestCase;
-use Streak\Domain\Event;
-
-/**
- * @author Alan Gabriel Bem
- *
- * @covers \Streak\Domain\Event\Sourced\Aggregate\Identification
- */
-class IdentificationTest extends TestCase
-{
- private Event\Sourced\Aggregate\Id $id;
-
- protected function setUp(): void
- {
- $this->id = $this->getMockBuilder(Event\Sourced\Aggregate\Id::class)->getMockForAbstractClass();
- }
-
- public function testObject(): void
- {
- $identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
-
- self::assertSame($this->id, $identification->producerId());
- self::assertSame($this->id, $identification->aggregateId());
- self::assertSame($this->id, $identification->entityId());
- self::assertSame($this->id, $identification->id());
- }
-}
diff --git a/tests/Domain/Event/Sourced/AggregateRoot/IdentificationTest.php b/tests/Domain/Event/Sourced/AggregateRoot/IdentificationTest.php
deleted file mode 100644
index 52917056..00000000
--- a/tests/Domain/Event/Sourced/AggregateRoot/IdentificationTest.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\AggregateRoot;
-
-use PHPUnit\Framework\TestCase;
-use Streak\Domain\Event;
-
-/**
- * @author Alan Gabriel Bem
- *
- * @covers \Streak\Domain\Event\Sourced\AggregateRoot\Identification
- */
-class IdentificationTest extends TestCase
-{
- private Event\Sourced\AggregateRoot\Id $id;
-
- protected function setUp(): void
- {
- $this->id = $this->getMockBuilder(Event\Sourced\AggregateRoot\Id::class)->getMockForAbstractClass();
- }
-
- public function testObject(): void
- {
- $identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
-
- self::assertSame($this->id, $identification->producerId());
- self::assertSame($this->id, $identification->aggregateRootId());
- self::assertSame($this->id, $identification->aggregateId());
- self::assertSame($this->id, $identification->entityId());
- self::assertSame($this->id, $identification->id());
- }
-}
diff --git a/tests/Domain/Event/Sourced/Entity/HelperTest.php b/tests/Domain/Event/Sourced/Entity/HelperTest.php
new file mode 100644
index 00000000..56845c88
--- /dev/null
+++ b/tests/Domain/Event/Sourced/Entity/HelperTest.php
@@ -0,0 +1,244 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Streak\Domain\Event\Sourced\Entity;
+
+use PHPUnit\Framework\TestCase;
+use Streak\Domain\Event;
+use Streak\Domain\Event\Sourced\Entity\HelperTest\EventSourcedEntityStub;
+use Streak\Domain\Event\Sourced\Entity\HelperTest\EventSourcedEntityStubId;
+
+/**
+ * @covers \Streak\Domain\Event\Sourced\Entity\Helper
+ */
+class HelperTest extends TestCase
+{
+ public function testExtractingEventSourcedEntities(): void
+ {
+ $entity5 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db5'));
+ $entity4 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db4'));
+ $entity3 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db3'));
+ $entity2 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db2'), $entity3, $entity5);
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db1'), $entity2, $entity4);
+
+ $helper = Helper::for($entity1);
+
+ $actual = $helper->extractEventSourcedEntities();
+ $actual = iterator_to_array($actual);
+
+ $expected = [$entity2, $entity3, $entity5, $entity4];
+
+ self::assertSame($expected, $actual);
+ }
+
+ public function testApplyingEvents(): void
+ {
+ $entity5 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db5'));
+ $entity4 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db4'));
+ $entity3 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db3'));
+ $entity2 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db2'), $entity3, $entity5);
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('a1880189-03a6-43aa-963f-610002a77db1'), $entity2, $entity4);
+
+ $event1 = new Event\Sourced\Entity\HelperTest\EventSourcedEntityStubEvent1();
+ $event1 = Event\Envelope::new($event1, $entity1->id());
+ $event2 = new Event\Sourced\Entity\HelperTest\EventSourcedEntityStubEvent2();
+ $event2 = Event\Envelope::new($event2, $entity1->id());
+ $event3 = new Event\Sourced\Entity\HelperTest\EventSourcedEntityStubEvent3();
+ $event3 = Event\Envelope::new($event3, $entity1->id());
+ $event4 = new Event\Sourced\Entity\HelperTest\EventSourcedEntityStubEvent4();
+ $event4 = Event\Envelope::new($event4, $entity1->id());
+
+ $helper = Helper::for($entity1);
+
+ $helper->applyEvent($event1);
+
+ self::assertEquals([$event1->message()], $entity1->appliedEvents());
+ self::assertEquals([], $entity2->appliedEvents());
+ self::assertEquals([], $entity3->appliedEvents());
+ self::assertEquals([], $entity4->appliedEvents());
+ self::assertEquals([], $entity5->appliedEvents());
+
+ $helper->applyEvent($event2);
+
+ self::assertEquals([$event1->message(), $event2->message()], $entity1->appliedEvents());
+ self::assertEquals([], $entity2->appliedEvents());
+ self::assertEquals([], $entity3->appliedEvents());
+ self::assertEquals([], $entity4->appliedEvents());
+ self::assertEquals([], $entity5->appliedEvents());
+
+ try {
+ $helper->applyEvent($event3);
+ self::fail();
+ } catch (Event\Exception\NoEventApplyingMethodFound $exception) {
+ self::assertSame($event3, $exception->event());
+ self::assertSame($entity1, $exception->object());
+ }
+
+ self::assertEquals([$event1->message(), $event2->message()], $entity1->appliedEvents());
+ self::assertEquals([], $entity2->appliedEvents());
+ self::assertEquals([], $entity3->appliedEvents());
+ self::assertEquals([], $entity4->appliedEvents());
+ self::assertEquals([], $entity5->appliedEvents());
+
+ $this->expectExceptionObject(new Event\Exception\TooManyEventApplyingMethodsFound($entity1, $event4));
+
+ try {
+ $helper->applyEvent($event4);
+ self::fail();
+ } catch (Event\Exception\TooManyEventApplyingMethodsFound $exception) {
+ self::assertSame($event4, $exception->event());
+ self::assertSame($entity1, $exception->object());
+ self::assertEquals([$event1->message(), $event2->message()], $entity1->appliedEvents());
+ self::assertEquals([], $entity2->appliedEvents());
+ self::assertEquals([], $entity3->appliedEvents());
+ self::assertEquals([], $entity4->appliedEvents());
+ self::assertEquals([], $entity5->appliedEvents());
+
+ throw $exception;
+ }
+ }
+}
+
+namespace Streak\Domain\Event\Sourced\Entity\HelperTest;
+
+use Streak\Domain\Entity;
+use Streak\Domain\Event;
+use Streak\Domain\Id\UUID;
+
+final class EventSourcedEntityStubId extends UUID implements Entity\Id
+{
+}
+
+final class EventSourcedEntityStub implements Event\Sourced\Entity
+{
+ use Entity\Comparison;
+
+ private self $self;
+ private int $integer;
+ private string $string;
+ private object $object;
+ private array $arrayOfIntegers;
+ private array $arrayOfStrings;
+ private array $arrayOfObjects;
+ private array $arrayOfMixed;
+ private string $nonInitializedString;
+ private int $nonInitializedInteger;
+ private object $nonInitializedObject;
+ private array $nonInitializedArray;
+
+ /**
+ * @var Event\Envelope[]
+ */
+ private array $appliedEvents = [];
+
+ public function __construct(private EventSourcedEntityStubId $id, private ?self $entity = null, ?self $entity2 = null)
+ {
+ $this->self = $this;
+ $this->integer = 1;
+ $this->string = 'string';
+ $this->object = new \stdClass();
+ $this->arrayOfIntegers = [-1, 0, 1];
+ $this->arrayOfStrings = ['string 1', 'string 2'];
+ $this->arrayOfObjects = [new \stdClass(), new \stdClass()];
+ $this->arrayOfMixed = [-1, 0, 1, 'string 1', 'string 2', new \stdClass(), new \stdClass(), $this, $entity, $entity2, null];
+ }
+
+ public function id(): Entity\Id
+ {
+ return $this->id;
+ }
+
+ public function appliedEvents(): array
+ {
+ return $this->appliedEvents;
+ }
+
+ public function applyEvent(Event\Envelope $event): void
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ public function registerAggregateRoot(Event\Sourced\AggregateRoot $aggregate): void
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ public function registerAggregate(Event\Sourced\Aggregate $aggregate): void
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ public function aggregateRoot(): Event\Sourced\AggregateRoot
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ public function aggregate(): ?Event\Sourced\Aggregate
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ private function applyEventSourcedEntityStubEvent1(EventSourcedEntityStubEvent1 $event): bool
+ {
+ $this->appliedEvents[] = $event;
+
+ return true;
+ }
+
+ private function applyEventSourcedEntityStubEvent2(EventSourcedEntityStubEvent2 $event): bool
+ {
+ $this->appliedEvents[] = $event;
+
+ return true;
+ }
+
+ private function applyEventSourcedEntityStubEvent4a(EventSourcedEntityStubEvent4 $event): bool
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ private function applyEventSourcedEntityStubEvent4b(EventSourcedEntityStubEvent4 $event): bool
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ private function applyTwoArgumentsAtOnce(int $arg1, int $arg2): bool
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ private function applyNonRequiredArguments(int $arg1 = null): bool
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+
+ private function applyMixedArguments($arg1): bool
+ {
+ throw new \RuntimeException(__METHOD__ . ' should not be invoked.');
+ }
+}
+
+class EventSourcedEntityStubEvent1 implements Event
+{
+}
+
+class EventSourcedEntityStubEvent2 implements Event
+{
+}
+
+class EventSourcedEntityStubEvent3 implements Event
+{
+}
+class EventSourcedEntityStubEvent4 implements Event
+{
+}
diff --git a/tests/Domain/Event/Sourced/Entity/IdentificationTest.php b/tests/Domain/Event/Sourced/Entity/IdentificationTest.php
deleted file mode 100644
index 6fd98adf..00000000
--- a/tests/Domain/Event/Sourced/Entity/IdentificationTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event\Sourced\Entity;
-
-use PHPUnit\Framework\TestCase;
-use Streak\Domain\Event;
-
-/**
- * @author Alan Gabriel Bem
- *
- * @covers \Streak\Domain\Event\Sourced\Entity\Identification
- */
-class IdentificationTest extends TestCase
-{
- private Event\Sourced\Entity\Id $id;
-
- protected function setUp(): void
- {
- $this->id = $this->getMockBuilder(Event\Sourced\Entity\Id::class)->getMockForAbstractClass();
- }
-
- public function testObject(): void
- {
- $identification = $this->getMockBuilder(Identification::class)->setConstructorArgs([$this->id])->getMockForTrait();
-
- self::assertSame($this->id, $identification->producerId());
- self::assertSame($this->id, $identification->entityId());
- self::assertSame($this->id, $identification->id());
- }
-}
diff --git a/tests/Domain/Event/SourcingTest.php b/tests/Domain/Event/SourcingTest.php
deleted file mode 100644
index 38fdaa10..00000000
--- a/tests/Domain/Event/SourcingTest.php
+++ /dev/null
@@ -1,449 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-declare(strict_types=1);
-
-namespace Streak\Domain\Event;
-
-use PHPUnit\Framework\TestCase;
-use Streak\Domain;
-use Streak\Domain\AggregateRoot;
-use Streak\Domain\Event;
-use Streak\Infrastructure\Domain\Event\InMemoryStream;
-
-/**
- * @author Alan Gabriel Bem
- *
- * @covers \Streak\Domain\Event\Sourcing
- */
-class SourcingTest extends TestCase
-{
- private AggregateRoot\Id $id1;
-
- private AggregateRoot\Id $id2;
-
- private Event\Envelope $event1;
-
- private Event\Envelope $event2;
-
- protected function setUp(): void
- {
- $this->id1 = new class('f5e65690-e50d-4312-a175-b004ec1bd42a') extends Domain\Id\UUID implements AggregateRoot\Id {
- };
- $this->id2 = new class('f84d8230-90a8-416f-af09-5ba315214888') extends Domain\Id\UUID implements AggregateRoot\Id {
- };
- $this->event1 = Event\Envelope::new($this->getMockBuilder(Event::class)->setMockClassName('event1')->getMockForAbstractClass(), $this->id1, 1);
- $this->event2 = Event\Envelope::new($this->getMockBuilder(Event::class)->setMockClassName('event2')->getMockForAbstractClass(), $this->id2, 1);
- }
-
- public function testSuccessfullyApplyingEventWithPublicHandlingMethod(): void
- {
- $event = new SourcingTest\EventStubForTestingPublicHandlingMethod();
- $event = Event\Envelope::new($event, $this->id1, 1);
-
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- self::assertFalse($sourcing->isEventStubForTestingPublicHandlingMethodApplied());
- self::assertNull($sourcing->lastReplayed());
- self::assertNull($sourcing->lastEvent());
- self::assertEquals(0, $sourcing->version());
- self::assertEmpty($sourcing->events());
-
- $sourcing->replay(new InMemoryStream($event));
-
- self::assertTrue($sourcing->isEventStubForTestingPublicHandlingMethodApplied());
- self::assertSame($event, $sourcing->lastReplayed());
- self::assertEquals($event, $sourcing->lastEvent());
- self::assertEquals(1, $sourcing->version());
- self::assertEmpty($sourcing->events());
-
- $sourcing->commit();
-
- self::assertTrue($sourcing->isEventStubForTestingPublicHandlingMethodApplied());
- self::assertSame($event, $sourcing->lastReplayed());
- self::assertEquals($event, $sourcing->lastEvent());
- self::assertEquals(1, $sourcing->version());
- self::assertEmpty($sourcing->events());
- }
-
- public function testSuccessfullyApplyingEventWithNonPublicHandlingMethod(): void
- {
- $event = new SourcingTest\EventStubForTestingNonPublicHandlingMethod();
- $event = Event\Envelope::new($event, $this->id1, 1);
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- self::assertFalse($sourcing->isEventStubForTestingNonPublicHandlingMethodApplied());
-
- $sourcing->replay(new InMemoryStream($event));
-
- self::assertTrue($sourcing->isEventStubForTestingNonPublicHandlingMethodApplied());
- self::assertSame($event, $sourcing->lastReplayed());
- self::assertEquals($event, $sourcing->lastEvent());
- self::assertEquals(1, $sourcing->version());
- self::assertEmpty($sourcing->events());
- }
-
- public function testAggregateWithMissingHandlingMethodForGivenEvent(): void
- {
- $event = new SourcingTest\EventStubForTestingMissingHandlingMethod();
- $event = Event\Envelope::new($event, $this->id1, 1);
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- $exception = new Domain\Event\Exception\NoEventApplyingMethodFound($sourcing, $event);
- $this->expectExceptionObject($exception);
-
- $sourcing->replay(new InMemoryStream($event));
- }
-
- public function testAggregateWithTwoOrMoreHandlingMethodsPresentForGivenEvent(): void
- {
- $event = new SourcingTest\EventStubForTestingTwoOrMoreHandlingMethodsPresent();
- $event = Event\Envelope::new($event, $this->id1, 1);
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- $exception = new Domain\Event\Exception\TooManyEventApplyingMethodsFound($sourcing, $event);
- $this->expectExceptionObject($exception);
-
- $sourcing->replay(new InMemoryStream($event));
- }
-
- public function testAggregateWithTwoOrMoreParametersPresentOnHandlingMethod(): void
- {
- $event = new SourcingTest\EventStubForTestingTwoOrMoreParametersPresentOnHandlingMethod();
- $event = Event\Envelope::new($event, $this->id1, 1);
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- $exception = new Domain\Event\Exception\NoEventApplyingMethodFound($sourcing, $event);
- $this->expectExceptionObject($exception);
-
- $sourcing->replay(new InMemoryStream($event));
- }
-
- public function testAggregateWithOptionalParameterOnHandlingMethodForGivenEvent(): void
- {
- $event = new SourcingTest\EventStubForTestingOptionalParameterOnHandlingMethod();
- $event = Event\Envelope::new($event, $this->id1, 1);
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- $exception = new Domain\Event\Exception\NoEventApplyingMethodFound($sourcing, $event);
- $this->expectExceptionObject($exception);
-
- $sourcing->replay(new InMemoryStream($event));
- }
-
- public function testApplyingMethodPresentForEventsParentClassOnly(): void
- {
- $event1 = new SourcingTest\EventWhichIsSubclassOfEvent7();
- $event1 = Event\Envelope::new($event1, $this->id1, 1);
- $event2 = new SourcingTest\AnotherEventWhichIsSubclassOfEvent7();
- $event2 = Event\Envelope::new($event2, $this->id1, 2);
-
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- self::assertEquals(0, $sourcing->numberOfAppliesOfEvent7());
-
- $sourcing->replay(new InMemoryStream($event1, $event2));
-
- self::assertEquals(2, $sourcing->numberOfAppliesOfEvent7());
- self::assertSame($event2, $sourcing->lastReplayed());
- self::assertEquals($event2, $sourcing->lastEvent());
- self::assertEquals(2, $sourcing->version());
- self::assertEmpty($sourcing->events());
- }
-
-// public function testApplyingMethodPresentForEventsParentClassAndOnlyOneOfChildren()
-// {
-// $this->id
-// ->expects(self::exactly(2))
-// ->method('equals')
-// ->willReturn(true)
-// ;
-//
-// $event1 = new SourcingTest\EventWhichIsSubclassOfEvent8($this->id);
-// $event2 = new SourcingTest\AnotherEventWhichIsSubclassOfEvent8($this->id);
-//
-// $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id);
-//
-// self::assertFalse($sourcing->isEvent8Applied());
-// self::assertFalse($sourcing->isEvent8aApplied());
-//
-// $sourcing->replay($event1, $event2);
-//
-// self::assertTrue($sourcing->isEvent8Applied());
-// self::assertTrue($sourcing->isEvent8aApplied());
-// self::assertSame($event2, $sourcing->lastReplayed());
-// self::assertEmpty($sourcing->events());
-// }
-
- public function testApplyingEventViaCommand(): void
- {
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
- self::assertEmpty($sourcing->events());
- self::assertNull($sourcing->lastEvent());
-
- self::assertFalse($sourcing->isEvent9Applied());
-
- $sourcing->command1($this->id1);
-
- self::assertTrue($sourcing->isEvent9Applied());
-
- $event = new SourcingTest\EventStubForTestingApplyingViaCommand();
-
- self::assertNull($sourcing->lastReplayed());
- self::assertEquals($event, $sourcing->lastEvent()->message());
- self::assertEquals(0, $sourcing->version());
- self::assertEquals([$event], $sourcing->events());
-
- $sourcing->commit();
-
- self::assertNull($sourcing->lastReplayed());
- self::assertEquals($event, $sourcing->lastEvent()->message());
- self::assertEquals(1, $sourcing->version());
- self::assertEquals([], $sourcing->events());
- }
-
- public function testApplyingEventViaCommandResultingInAnException(): void
- {
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- try {
- self::assertEmpty($sourcing->events());
- self::assertNull($sourcing->lastEvent());
- self::assertNull($sourcing->lastReplayed());
-
- $sourcing->command2($this->id1);
-
- self::fail();
- } catch (\Exception $thrown) {
- self::assertEquals(new \Exception('Command resulting in an exception'), $thrown);
- self::assertEmpty($sourcing->events());
- self::assertNull($sourcing->lastEvent());
- self::assertNull($sourcing->lastReplayed());
- }
- }
-
- public function testEventSourcingNonConsumer(): void
- {
- $sourcing = new Domain\Event\SourcingTest\EventSourcedNonConsumer($this->id1);
-
- $exception = new Domain\Event\Exception\SourcingObjectWithEventFailed($sourcing, $this->event1);
- $this->expectExceptionObject($exception);
-
- $sourcing->replay(new InMemoryStream($this->event1));
- }
-
- public function testEventAndConsumerMismatch(): void
- {
- $sourcing = new SourcingTest\EventSourcedAggregateRootStub($this->id1);
-
- $exception = new Domain\Exception\EventAndConsumerMismatch($sourcing, $this->event2);
- $this->expectExceptionObject($exception);
-
- $sourcing->replay(new InMemoryStream($this->event2));
- }
-}
-
-namespace Streak\Domain\Event\SourcingTest;
-
-use Streak\Domain;
-use Streak\Domain\AggregateRoot;
-use Streak\Domain\Event;
-
-class EventSourcedAggregateRootStub implements Event\Consumer
-{
- use Event\Sourcing;
-
- private \Streak\Domain\Id $id;
-
- private bool $eventStubForTestingPublicHandlingMethodApplied = false;
- private bool $eventStubForTestingNonPublicHandlingMethodApplied = false;
- private int $numberOfAppliesOfEvent7 = 0;
- private bool $event8Applied = false;
- private bool $event8aApplied = false;
- private bool $event9Applied = false;
-
- public function __construct(AggregateRoot\Id $id)
- {
- $this->id = $id;
- }
-
- public function producerId(): Domain\Id
- {
- return $this->id;
- }
-
- public function applyEventStubForTestingPublicHandlingMethodApplied(EventStubForTestingPublicHandlingMethod $event): void
- {
- $this->eventStubForTestingPublicHandlingMethodApplied = true;
- }
-
- public function applyEvent2(EventStubForTestingTwoOrMoreHandlingMethodsPresent $event2): void
- {
- }
-
- public function applyEvent2Deux(EventStubForTestingTwoOrMoreHandlingMethodsPresent $event2): void
- {
- }
-
- public function applyEvent4(EventStubForTestingTwoOrMoreParametersPresentOnHandlingMethod $event, mixed $thisParameterUnneeded): void
- {
- }
-
- public function applyEvent5(EventStubForTestingOptionalParameterOnHandlingMethod $optionalEventIsInvalid = null): void
- {
- }
-
- public function command1(AggregateRoot\Id $id): void
- {
- $this->apply(new EventStubForTestingApplyingViaCommand());
- }
-
- public function command2(AggregateRoot\Id $id): void
- {
- $this->apply(new EventStubForTestingApplyingViaCommandResultingInException());
- }
-
- public function isEventStubForTestingPublicHandlingMethodApplied(): bool
- {
- return $this->eventStubForTestingPublicHandlingMethodApplied;
- }
-
- public function isEventStubForTestingNonPublicHandlingMethodApplied(): bool
- {
- return $this->eventStubForTestingNonPublicHandlingMethodApplied;
- }
-
- public function isEvent8Applied(): bool
- {
- return $this->event8Applied;
- }
-
- public function isEvent8aApplied(): bool
- {
- return $this->event8aApplied;
- }
-
- public function isEvent9Applied(): bool
- {
- return $this->event9Applied;
- }
-
- public function numberOfAppliesOfEvent7(): int
- {
- return $this->numberOfAppliesOfEvent7;
- }
-
- public function id(): Domain\Id
- {
- return $this->id;
- }
-
- private function applyEventStubForTestingNonPublicHandlingMethodApplied(EventStubForTestingNonPublicHandlingMethod $event): void
- {
- $this->eventStubForTestingNonPublicHandlingMethodApplied = true;
- }
-
- private function applyEvent7(Event7 $event): void
- {
- ++$this->numberOfAppliesOfEvent7;
- }
-
- private function applyEvent8(Event8 $event): void
- {
- $this->event8Applied = true;
- }
-
- private function applyEvent8a(EventWhichIsSubclassOfEvent8 $event): void
- {
- $this->event8aApplied = true;
- }
-
- private function applyEvent9(EventStubForTestingApplyingViaCommand $event): void
- {
- $this->event9Applied = true;
- }
-
- private function applyEvent10(EventStubForTestingApplyingViaCommandResultingInException $event): void
- {
- throw new \Exception('Command resulting in an exception');
- }
-
- private function applyNonEvent(\stdClass $parameter): void
- {
- }
-
- private function applySomethingElse($parameters): void
- {
- }
-}
-
-class EventStubForTestingPublicHandlingMethod implements Event
-{
-}
-class EventStubForTestingMismatching implements Event
-{
-}
-class EventStubForTestingTwoOrMoreHandlingMethodsPresent implements Event
-{
-}
-class EventStubForTestingMissingHandlingMethod implements Event
-{
-}
-class EventStubForTestingTwoOrMoreParametersPresentOnHandlingMethod implements Event
-{
-}
-class EventStubForTestingOptionalParameterOnHandlingMethod implements Event
-{
-}
-class EventStubForTestingNonPublicHandlingMethod implements Event
-{
-}
-class Event7 implements Event
-{
-}
-class EventWhichIsSubclassOfEvent7 extends Event7
-{
-}
-class AnotherEventWhichIsSubclassOfEvent7 extends Event7
-{
-}
-class Event8 implements Event
-{
-}
-class EventWhichIsSubclassOfEvent8 extends Event8
-{
-}
-class AnotherEventWhichIsSubclassOfEvent8 extends Event8
-{
-}
-class EventStubForTestingApplyingViaCommand implements Event
-{
-}
-class EventStubForTestingApplyingViaCommandResultingInException implements Event
-{
-}
-
-class EventSourcedNonConsumer
-{
- use Event\Sourcing;
-
- private \Streak\Domain\Id $id;
-
- public function __construct(AggregateRoot\Id $id)
- {
- $this->id = $id;
- }
-
- public function producerId(): Domain\Id
- {
- return $this->id;
- }
-}
diff --git a/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompletedTest.php b/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompletedTest.php
index 12941a09..f443d792 100644
--- a/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompletedTest.php
+++ b/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyCompletedTest.php
@@ -38,7 +38,7 @@ public function testException(): void
{
$this->subscription
->expects(self::atLeastOnce())
- ->method('subscriptionId')
+ ->method('id')
->willReturn($this->subscriptionId)
;
diff --git a/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyStartedTest.php b/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyStartedTest.php
index 7a3b953f..d9bf47a5 100644
--- a/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyStartedTest.php
+++ b/tests/Domain/Event/Subscription/Exception/SubscriptionAlreadyStartedTest.php
@@ -38,7 +38,7 @@ public function testException(): void
{
$this->subscription
->expects(self::atLeastOnce())
- ->method('subscriptionId')
+ ->method('id')
->willReturn($this->subscriptionId)
;
diff --git a/tests/Domain/Event/Subscription/Exception/SubscriptionNotStartedYetTest.php b/tests/Domain/Event/Subscription/Exception/SubscriptionNotStartedYetTest.php
index ac4a6305..96b90af6 100644
--- a/tests/Domain/Event/Subscription/Exception/SubscriptionNotStartedYetTest.php
+++ b/tests/Domain/Event/Subscription/Exception/SubscriptionNotStartedYetTest.php
@@ -38,7 +38,7 @@ public function testException(): void
{
$this->subscription
->expects(self::atLeastOnce())
- ->method('subscriptionId')
+ ->method('id')
->willReturn($this->subscriptionId)
;
diff --git a/tests/Domain/Event/Subscription/Exception/SubscriptionPausedTest.php b/tests/Domain/Event/Subscription/Exception/SubscriptionPausedTest.php
index abeef08e..e10217ca 100644
--- a/tests/Domain/Event/Subscription/Exception/SubscriptionPausedTest.php
+++ b/tests/Domain/Event/Subscription/Exception/SubscriptionPausedTest.php
@@ -37,7 +37,7 @@ public function testException(): void
{
$this->subscription
->expects(self::atLeastOnce())
- ->method('subscriptionId')
+ ->method('id')
->willReturn($this->subscriptionId)
;
diff --git a/tests/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossibleTest.php b/tests/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossibleTest.php
index 46ab94d1..d8a86f31 100644
--- a/tests/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossibleTest.php
+++ b/tests/Domain/Event/Subscription/Exception/SubscriptionRestartNotPossibleTest.php
@@ -38,7 +38,7 @@ public function testException(): void
{
$this->subscription
->expects(self::atLeastOnce())
- ->method('subscriptionId')
+ ->method('id')
->willReturn($this->subscriptionId)
;
diff --git a/tests/Domain/Event/Sourced/Subscription/Repository/FilterTest.php b/tests/Domain/Event/Subscription/Repository/FilterTest.php
similarity index 94%
rename from tests/Domain/Event/Sourced/Subscription/Repository/FilterTest.php
rename to tests/Domain/Event/Subscription/Repository/FilterTest.php
index 3d770f52..68db7241 100644
--- a/tests/Domain/Event/Sourced/Subscription/Repository/FilterTest.php
+++ b/tests/Domain/Event/Subscription/Repository/FilterTest.php
@@ -11,10 +11,9 @@
declare(strict_types=1);
-namespace Streak\Domain\Event\Sourced\Subscription\Repository;
+namespace Streak\Domain\Event\Subscription\Repository;
use PHPUnit\Framework\TestCase;
-use Streak\Domain\Event\Subscription\Repository\Filter;
/**
* @author Alan Gabriel Bem
diff --git a/tests/Domain/EventSourcingTest.php b/tests/Domain/EventSourcingTest.php
new file mode 100644
index 00000000..85ac0bd0
--- /dev/null
+++ b/tests/Domain/EventSourcingTest.php
@@ -0,0 +1,748 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Streak\Domain;
+
+use PHPUnit\Framework\TestCase;
+use Streak\Domain\EventSourcingTest\EventSourcedAggregateRootStub;
+use Streak\Domain\EventSourcingTest\EventSourcedAggregateRootStubId;
+use Streak\Domain\EventSourcingTest\EventSourcedAggregateStub;
+use Streak\Domain\EventSourcingTest\EventSourcedAggregateStubId;
+use Streak\Domain\EventSourcingTest\EventSourcedEntityStub;
+use Streak\Domain\EventSourcingTest\EventSourcedEntityStubId;
+use Streak\Domain\Exception\EventMismatched;
+use Streak\Infrastructure\Domain\Event\InMemoryStream;
+
+/**
+ * @author Alan Gabriel Bem
+ *
+ * @covers \Streak\Domain\AggregateRoot\EventSourcing
+ * @covers \Streak\Domain\Aggregate\EventSourcing
+ * @covers \Streak\Domain\Entity\EventSourcing
+ */
+class EventSourcingTest extends TestCase
+{
+ public function testSuccessfullyApplyingEventOnAggregateRoot(): void
+ {
+ $aggregateRootId1 = new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a');
+ $aggregateRoot1 = new EventSourcedAggregateRootStub($aggregateRootId1);
+
+ $event = new EventSourcingTest\Event1();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+
+ $aggregateRoot1->command($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub($aggregateRootId1);
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnAggregateRootButNotAggregate(): void
+ {
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+
+ $event = new EventSourcingTest\Event1();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+
+ $aggregateRoot1->command($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnAggregateRootButNotAggregateAndEntity(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event1();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $aggregateRoot1->command($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $freshEntity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $freshEntity1);
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+ $freshEntity1->registerAggregate($freshAggregate1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnAggregateAndAggregateRoot(): void
+ {
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+
+ $event = new EventSourcingTest\Event1();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+
+ $aggregateRoot1->commandOnAggregate1($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnAggregateAndAggregateRootButNotEntity(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event1();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $aggregateRoot1->commandOnAggregate1($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $freshEntity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $freshEntity1);
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+ $freshEntity1->registerAggregate($freshAggregate1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnAggregateButNotAggregateRoot(): void
+ {
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+
+ $event = new EventSourcingTest\Event2();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+
+ $aggregateRoot1->commandOnAggregate1($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnEntityAndAggregateAndAggregateRoot(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event1();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $aggregateRoot1->commandOnEntity1OfAggregate1($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+ self::assertEquals([$event], $entity1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+ self::assertEquals([$event], $entity1->appliedEvents());
+
+ $freshEntity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $freshEntity1);
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+ $freshEntity1->registerAggregate($freshAggregate1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnEntityAndAggregateButNotAggregateRoot(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event2();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $aggregateRoot1->commandOnEntity1OfAggregate1($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+ self::assertEquals([$event], $entity1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEquals([$event], $aggregate1->appliedEvents());
+ self::assertEquals([$event], $entity1->appliedEvents());
+
+ $freshEntity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $freshEntity1);
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+ $freshEntity1->registerAggregate($freshAggregate1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testSuccessfullyApplyingEventOnEntityAndAggregateRootButNotAggregate(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event4();
+
+ self::assertNull($aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEmpty($aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEmpty($entity1->appliedEvents());
+
+ $aggregateRoot1->commandOnEntity1OfAggregate1($event);
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(0, $aggregateRoot1->version());
+ self::assertEquals([$event], $aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEquals([$event], $entity1->appliedEvents());
+
+ $stream = $aggregateRoot1->events();
+
+ $aggregateRoot1->commit();
+
+ self::assertEquals($event, $aggregateRoot1->lastEvent());
+ self::assertSame(1, $aggregateRoot1->version());
+ self::assertEmpty($aggregateRoot1->events());
+ self::assertEquals([$event], $aggregateRoot1->appliedEvents());
+ self::assertEmpty($aggregate1->appliedEvents());
+ self::assertEquals([$event], $entity1->appliedEvents());
+
+ $freshEntity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $freshAggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $freshEntity1);
+ $freshAggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $freshAggregate1);
+ $freshAggregate1->registerAggregateRoot($freshAggregateRoot1);
+ $freshEntity1->registerAggregate($freshAggregate1);
+
+ $freshAggregateRoot1->replay(new InMemoryStream(...$stream));
+
+ self::assertNotSame($aggregateRoot1, $freshAggregateRoot1);
+ self::assertEquals($aggregateRoot1, $freshAggregateRoot1);
+ }
+
+ public function testMismatchedEventOnAggregateRoot(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event4();
+ $event = Event\Envelope::new($event, new EventSourcedAggregateStubId('61888494-fd58-412c-86c3-03cf81aca443'), 1);
+
+ try {
+ $aggregateRoot1->applyEvent($event);
+ self::fail();
+ } catch (EventMismatched $exception) {
+ self::assertSame($aggregateRoot1, $exception->object());
+ self::assertSame($event, $exception->event());
+ }
+ }
+
+ public function testMismatchedEventOnAggregate(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event2();
+ $event = Event\Envelope::new($event, new EventSourcedAggregateStubId('61888494-fd58-412c-86c3-03cf81aca443'), 1);
+
+ try {
+ $aggregate1->applyEvent($event);
+ self::fail();
+ } catch (EventMismatched $exception) {
+ self::assertSame($aggregate1, $exception->object());
+ self::assertSame($event, $exception->event());
+ }
+ }
+
+ public function testMismatchedEventOnEntity(): void
+ {
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'), $entity1);
+ $aggregateRoot1 = new EventSourcedAggregateRootStub(new EventSourcedAggregateRootStubId('f5e65690-e50d-4312-a175-b004ec1bd42a'), $aggregate1);
+ $aggregate1->registerAggregateRoot($aggregateRoot1);
+ $entity1->registerAggregate($aggregate1);
+
+ $event = new EventSourcingTest\Event2();
+ $event = Event\Envelope::new($event, new EventSourcedAggregateStubId('61888494-fd58-412c-86c3-03cf81aca443'), 1);
+
+ try {
+ $entity1->applyEvent($event);
+ self::fail();
+ } catch (EventMismatched $exception) {
+ self::assertSame($entity1, $exception->object());
+ self::assertSame($event, $exception->event());
+ }
+ }
+
+ public function testRegisteringAggregateOnItself(): void
+ {
+ $this->expectExceptionObject(new \BadMethodCallException('You can\'t register aggregate on itself.'));
+
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+ $aggregate1->registerAggregate($aggregate1);
+ }
+
+ public function testObtainingAggregateRootOnAggregateWhenItsNotRegistered(): void
+ {
+ $this->expectExceptionObject(new \BadMethodCallException('Aggregate root no registered. Did you forget to run Streak\Domain\EventSourcingTest\EventSourcedAggregateStub::registerAggregateRoot()?'));
+
+ $aggregate1 = new EventSourcedAggregateStub(new EventSourcedAggregateStubId('51b37ad0-9e18-47fb-89ba-8d860472c852'));
+
+ $aggregate1->aggregateRoot();
+ }
+
+ public function testObtainingAggregateRootOnEntityWhenItsNotRegistered(): void
+ {
+ $this->expectExceptionObject(new \BadMethodCallException('Aggregate root no registered. Did you forget to run Streak\Domain\EventSourcingTest\EventSourcedEntityStub::registerAggregateRoot()?'));
+
+ $entity1 = new EventSourcedEntityStub(new EventSourcedEntityStubId('bafbcfd1-0355-42b4-bd3f-0a5379570574'));
+
+ $entity1->aggregateRoot();
+ }
+}
+
+namespace Streak\Domain\EventSourcingTest;
+
+use Streak\Domain;
+use Streak\Domain\Aggregate;
+use Streak\Domain\AggregateRoot;
+use Streak\Domain\Entity;
+use Streak\Domain\Event;
+
+class EventSourcedAggregateRootStubId extends Domain\Id\UUID implements AggregateRoot\Id
+{
+}
+
+class EventSourcedAggregateRootStub implements Event\Sourced\AggregateRoot
+{
+ use AggregateRoot\Comparison;
+ use AggregateRoot\EventSourcing;
+ use AggregateRoot\Identification;
+
+ private array $appliedEvents = [];
+
+ public function __construct(
+ EventSourcedAggregateRootStubId $id,
+ private ?EventSourcedAggregateStub $aggregate1 = null,
+ private ?EventSourcedAggregateStub $aggregate2 = null,
+ private ?EventSourcedEntityStub $entity1 = null,
+ private ?EventSourcedEntityStub $entity2 = null,
+ ) {
+ $this->identifyBy($id);
+ }
+
+ public function entity1(): ?Event\Sourced\Entity
+ {
+ return $this->entity1;
+ }
+
+ public function entity2(): ?Event\Sourced\Entity
+ {
+ return $this->entity2;
+ }
+
+ public function command(Event $event): void
+ {
+ $this->apply($event);
+ }
+
+ public function commandOnAggregate1(Event $event): void
+ {
+ $this->aggregate1->commandOnAggregate($event);
+ }
+
+ public function commandOnEntity1OfAggregate1(Event $event): void
+ {
+ $this->aggregate1->commandOnEntity1($event);
+ }
+
+ public function commandOnEntity2OfAggregate1(Event $event): void
+ {
+ $this->aggregate1->commandOnEntity2($event);
+ }
+
+ public function commandOnEntity1(Event $event): void
+ {
+ $this->entity1->command($event);
+ }
+
+ public function commandOnAggregate2(Event $event): void
+ {
+ $this->aggregate2->commandOnAggregate($event);
+ }
+
+ public function commandOnEntity1OfAggregate2(Event $event): void
+ {
+ $this->aggregate2->commandOnEntity1($event);
+ }
+
+ public function commandOnEntity2OfAggregate2(Event $event): void
+ {
+ $this->aggregate2->commandOnEntity2($event);
+ }
+
+ public function commandOnEntity2(Event $event): void
+ {
+ $this->entity1->command($event);
+ }
+
+ public function appliedEvents(): array
+ {
+ return $this->appliedEvents;
+ }
+
+ private function applyEvent1(Event1 $event): void
+ {
+ $this->appliedEvents = [$event];
+ }
+
+ private function applyEvent4(Event4 $event): void
+ {
+ $this->appliedEvents[] = $event;
+ }
+}
+
+class EventSourcedAggregateStubId extends Domain\Id\UUID implements Aggregate\Id
+{
+}
+
+class EventSourcedAggregateStub implements Event\Sourced\Aggregate
+{
+ use Aggregate\Comparison;
+ use Aggregate\EventSourcing;
+ use Aggregate\Identification;
+
+ /**
+ * @var Event\Envelope[]
+ */
+ private array $appliedEvents = [];
+
+ public function __construct(
+ EventSourcedAggregateStubId $id,
+ private ?EventSourcedEntityStub $entity1 = null,
+ private ?EventSourcedEntityStub $entity2 = null,
+ ) {
+ $this->identifyBy($id);
+ }
+
+ public function commandOnAggregate(Event $event): void
+ {
+ $this->apply($event);
+ }
+
+ public function commandOnEntity1(Event $event): void
+ {
+ $this->entity1->command($event);
+ }
+
+ public function commandOnEntity2(Event $event): void
+ {
+ $this->entity2->command($event);
+ }
+
+ public function appliedEvents(): array
+ {
+ return $this->appliedEvents;
+ }
+
+ private function applyEvent1(Event1 $event): void
+ {
+ $this->appliedEvents = [$event];
+ }
+
+ private function applyEvent2(Event2 $event): void
+ {
+ $this->appliedEvents = [$event];
+ }
+}
+
+class EventSourcedEntityStubId extends Domain\Id\UUID implements Entity\Id
+{
+}
+
+class EventSourcedEntityStub implements Event\Sourced\Entity
+{
+ use Entity\Comparison;
+ use Entity\EventSourcing;
+ use Entity\Identification;
+
+ /**
+ * @var Event\Envelope[]
+ */
+ private array $appliedEvents = [];
+
+ public function __construct(EventSourcedEntityStubId $id)
+ {
+ $this->identifyBy($id);
+ }
+
+ public function command(Event $event): void
+ {
+ $this->apply($event);
+ }
+
+ public function appliedEvents(): array
+ {
+ return $this->appliedEvents;
+ }
+
+ private function applyEvent1(Event1 $event): void
+ {
+ $this->appliedEvents[] = $event;
+ }
+
+ private function applyEvent2(Event2 $event): void
+ {
+ $this->appliedEvents[] = $event;
+ }
+
+ private function applyEvent3(Event3 $event): void
+ {
+ $this->appliedEvents[] = $event;
+ }
+
+ private function applyEvent4(Event4 $event): void
+ {
+ $this->appliedEvents[] = $event;
+ }
+}
+
+class Event1 implements Event
+{
+}
+
+class Event2 implements Event
+{
+}
+
+class Event3 implements Event
+{
+}
+
+class Event4 implements Event
+{
+}
diff --git a/tests/Domain/Exception/EventAndConsumerMismatchTest.php b/tests/Domain/Exception/EventMismatchedTest.php
similarity index 66%
rename from tests/Domain/Exception/EventAndConsumerMismatchTest.php
rename to tests/Domain/Exception/EventMismatchedTest.php
index 67da2ea5..0a873e82 100644
--- a/tests/Domain/Exception/EventAndConsumerMismatchTest.php
+++ b/tests/Domain/Exception/EventMismatchedTest.php
@@ -21,25 +21,25 @@
/**
* @author Alan Gabriel Bem
*
- * @covers \Streak\Domain\Exception\EventAndConsumerMismatch
+ * @covers \Streak\Domain\Exception\EventMismatched
*/
-class EventAndConsumerMismatchTest extends TestCase
+class EventMismatchedTest extends TestCase
{
- private Event\Consumer $consumer;
+ private Event\Sourced\Entity $entity;
private Domain\Event\Envelope $event;
protected function setUp(): void
{
- $this->consumer = $this->getMockBuilder(Event\Consumer::class)->getMockForAbstractClass();
+ $this->entity = $this->getMockBuilder(Event\Sourced\Entity::class)->getMockForAbstractClass();
$this->event = Event\Envelope::new($this->getMockBuilder(Domain\Event::class)->getMockForAbstractClass(), UUID::random());
}
public function testException(): void
{
- $exception = new EventAndConsumerMismatch($this->consumer, $this->event);
+ $exception = new EventMismatched($this->entity, $this->event);
- self::assertSame($this->consumer, $exception->consumer());
+ self::assertSame($this->entity, $exception->object());
self::assertSame($this->event, $exception->event());
}
}
diff --git a/tests/Infrastructure/Application/Sensor/CommittingSensorTest.php b/tests/Infrastructure/Application/Sensor/CommittingSensorTest.php
index 9806bfea..884eefb1 100644
--- a/tests/Infrastructure/Application/Sensor/CommittingSensorTest.php
+++ b/tests/Infrastructure/Application/Sensor/CommittingSensorTest.php
@@ -49,21 +49,12 @@ public function testSensor(): void
$this->sensor
->expects(self::once())
- ->method('sensorId')
+ ->method('id')
->with()
->willReturn($this->sensorId)
;
- self::assertSame($this->sensorId, $sensor->sensorId());
-
- $this->sensor
- ->expects(self::once())
- ->method('producerId')
- ->with()
- ->willReturn($this->sensorId)
- ;
-
- self::assertSame($this->sensorId, $sensor->producerId());
+ self::assertSame($this->sensorId, $sensor->id());
$this->sensor
->expects(self::once())
diff --git a/tests/Infrastructure/Application/Sensor/LoggingSensorTest.php b/tests/Infrastructure/Application/Sensor/LoggingSensorTest.php
index 55877581..937e1ad3 100644
--- a/tests/Infrastructure/Application/Sensor/LoggingSensorTest.php
+++ b/tests/Infrastructure/Application/Sensor/LoggingSensorTest.php
@@ -62,19 +62,11 @@ public function testObject(): void
$this->sensor
->expects(self::once())
- ->method('sensorId')
+ ->method('id')
->willReturn($this->sensorId)
;
- self::assertSame($this->sensorId, $sensor->sensorId());
-
- $this->sensor
- ->expects(self::once())
- ->method('producerId')
- ->willReturn($this->sensorId)
- ;
-
- self::assertSame($this->sensorId, $sensor->producerId());
+ self::assertSame($this->sensorId, $sensor->id());
$this->sensor
->expects(self::once())
diff --git a/tests/Infrastructure/Domain/AggregateRoot/Repository/EventSourcedRepositoryTest.php b/tests/Infrastructure/Domain/AggregateRoot/Repository/EventSourcedRepositoryTest.php
index bf63495d..4e8f1ad8 100644
--- a/tests/Infrastructure/Domain/AggregateRoot/Repository/EventSourcedRepositoryTest.php
+++ b/tests/Infrastructure/Domain/AggregateRoot/Repository/EventSourcedRepositoryTest.php
@@ -34,7 +34,7 @@ class EventSourcedRepositoryTest extends TestCase
private Domain\AggregateRoot $nonEventSourcedAggregateRoot;
private Event\Sourced\AggregateRoot $aggregateRoot;
- private Event\Sourced\AggregateRoot\Id $aggregateRootId;
+ private Domain\AggregateRoot\Id $aggregateRootId;
private Domain\Event\Envelope $event1;
@@ -50,7 +50,7 @@ protected function setUp(): void
$this->nonEventSourcedAggregateRoot = $this->getMockBuilder(Domain\AggregateRoot::class)->getMockForAbstractClass();
$this->aggregateRoot = $this->getMockBuilder(Event\Sourced\AggregateRoot::class)->getMockForAbstractClass();
- $this->aggregateRootId = $this->getMockBuilder(Event\Sourced\AggregateRoot\Id::class)->getMockForAbstractClass();
+ $this->aggregateRootId = $this->getMockBuilder(Domain\AggregateRoot\Id::class)->getMockForAbstractClass();
$this->event1 = Event\Envelope::new($this->getMockBuilder(Domain\Event::class)->getMockForAbstractClass(), $this->aggregateRootId, 1);
$this->stream = $this->getMockBuilder(Event\Stream::class)->getMockForAbstractClass();
diff --git a/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFoundTest.php b/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFoundTest.php
index 180bd2f8..dffbb244 100644
--- a/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFoundTest.php
+++ b/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/Exception/SnapshotNotFoundTest.php
@@ -37,7 +37,7 @@ public function testException(): void
{
$this->aggregate
->expects(self::atLeastOnce())
- ->method('aggregateRootId')
+ ->method('id')
->willReturn($this->aggregateId)
;
$this->aggregateId
diff --git a/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/PostgresStorageTest.php b/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/PostgresStorageTest.php
index 27549ce4..74393be6 100644
--- a/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/PostgresStorageTest.php
+++ b/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/PostgresStorageTest.php
@@ -115,20 +115,20 @@ public function testItFinds(): void
]);
$snapshot = $this->storage->find($this->createAggregateRootStub($id));
- self::assertEquals('snapshot', $snapshot);
+ self::assertSame('snapshot', $snapshot);
}
public function testItDoesntFindWhenTableDoesNotExists(): void
{
$this->givenSnapshotsTableDoesNotExists();
- self::expectException(SnapshotNotFound::class);
+ $this->expectException(SnapshotNotFound::class);
$this->storage->find($this->createAggregateRootStub('3e7c8ffa-6bc6-4070-a6b5-30f9ae1c06fe'));
}
public function testItDoesntFindWhenRowDoesNotExist(): void
{
$this->givenSnapshotsTableExists();
- self::expectException(SnapshotNotFound::class);
+ $this->expectException(SnapshotNotFound::class);
$this->storage->find($this->createAggregateRootStub('3e7c8ffa-6bc6-4070-a6b5-30f9ae1c06fe'));
}
@@ -171,16 +171,13 @@ private function createAggregateRootStub(string $id): AggregateRoot
class IdStub implements AggregateRoot\Id
{
- private string $id;
-
/**
* IdMock constructor.
*
* @param $id
*/
- public function __construct(string $id)
+ public function __construct(private string $id)
{
- $this->id = $id;
}
public function equals(object $object): bool
diff --git a/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/TestCase.php b/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/TestCase.php
index 24bd051b..e429a434 100644
--- a/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/TestCase.php
+++ b/tests/Infrastructure/Domain/AggregateRoot/Snapshotter/Storage/TestCase.php
@@ -38,11 +38,11 @@ protected function setUp(): void
$this->aggregateId1 = new Storage\StorageTestCase\ExtendedUUID1('9bf583d5-d4ff-4cf3-bc53-8ffb6be0c67b');
$this->aggregate1 = $this->getMockBuilder(AggregateRoot::class)->setMockClassName('streak__aggregate_1')->getMockForAbstractClass();
- $this->aggregate1->method('aggregateRootId')->with()->willReturn($this->aggregateId1);
+ $this->aggregate1->method('id')->with()->willReturn($this->aggregateId1);
$this->aggregateId2 = new Storage\StorageTestCase\ExtendedUUID2('d61546c6-cc51-4584-90f8-34203fd79b41');
$this->aggregate2 = $this->getMockBuilder(AggregateRoot::class)->setMockClassName('streak__aggregate_2')->getMockForAbstractClass();
- $this->aggregate2->method('aggregateRootId')->with()->willReturn($this->aggregateId2);
+ $this->aggregate2->method('id')->with()->willReturn($this->aggregateId2);
}
public function testObject(): void
diff --git a/tests/Infrastructure/Domain/Event/Converter/NestedObjectConverterTest.php b/tests/Infrastructure/Domain/Event/Converter/NestedObjectConverterTest.php
index 0582a35c..513fc2aa 100644
--- a/tests/Infrastructure/Domain/Event/Converter/NestedObjectConverterTest.php
+++ b/tests/Infrastructure/Domain/Event/Converter/NestedObjectConverterTest.php
@@ -177,7 +177,7 @@ public function testNestedArrayToObject(): void
public function testItDoesntConvertWrongNestedType(): void
{
- self::expectException(Event\Exception\ConversionToArrayNotPossible::class);
+ $this->expectException(Event\Exception\ConversionToArrayNotPossible::class);
$converter = new NestedObjectConverter();
$converter->objectToArray(new NestedResource(tmpfile()));
}
@@ -185,78 +185,37 @@ public function testItDoesntConvertWrongNestedType(): void
class NestedResource
{
- /**
- * @var resource
- */
- private $resource;
-
/**
* @param resource $resource
*/
- public function __construct($resource)
+ public function __construct(private $resource)
{
- $this->resource = $resource;
}
}
class Event1Stub implements Event
{
- public string $publicStringProperty;
- public int $publicIntegerProperty;
- public float $publicFloatProperty;
- public array $publicArrayProperty;
- public $publicAnyTypeProperty;
public array $publicEmptyArrayProperty;
- protected string $protectedStringProperty;
- protected int $protectedIntegerProperty;
- protected float $protectedFloatProperty;
- protected array $protectedArrayProperty;
- protected $protectedAnyTypeProperty;
protected array $protectedEmptyArrayProperty;
- private string $privateStringProperty;
- private int $privateIntegerProperty;
- private float $privateFloatProperty;
- private array $privateArrayProperty;
- private $privateAnyTypeProperty;
private array $privateEmptyArrayProperty;
public function __construct(
- string $privateStringProperty,
- string $publicStringProperty,
- string $protectedStringProperty,
- int $privateIntegerProperty,
- int $publicIntegerProperty,
- int $protectedIntegerProperty,
- float $privateFloatProperty,
- float $publicFloatProperty,
- float $protectedFloatProperty,
- array $privateArrayProperty,
- array $publicArrayProperty,
- array $protectedArrayProperty,
- $privateAnyTypeProperty,
- $publicAnyTypeProperty,
- $protectedAnyTypeProperty
+ private string $privateStringProperty,
+ public string $publicStringProperty,
+ protected string $protectedStringProperty,
+ private int $privateIntegerProperty,
+ public int $publicIntegerProperty,
+ protected int $protectedIntegerProperty,
+ private float $privateFloatProperty,
+ public float $publicFloatProperty,
+ protected float $protectedFloatProperty,
+ private array $privateArrayProperty,
+ public array $publicArrayProperty,
+ protected array $protectedArrayProperty,
+ private $privateAnyTypeProperty,
+ public $publicAnyTypeProperty,
+ protected $protectedAnyTypeProperty
) {
- $this->privateStringProperty = $privateStringProperty;
- $this->publicStringProperty = $publicStringProperty;
- $this->protectedStringProperty = $protectedStringProperty;
-
- $this->privateIntegerProperty = $privateIntegerProperty;
- $this->publicIntegerProperty = $publicIntegerProperty;
- $this->protectedIntegerProperty = $protectedIntegerProperty;
-
- $this->privateFloatProperty = $privateFloatProperty;
- $this->publicFloatProperty = $publicFloatProperty;
- $this->protectedFloatProperty = $protectedFloatProperty;
-
- $this->privateArrayProperty = $privateArrayProperty;
- $this->publicArrayProperty = $publicArrayProperty;
- $this->protectedArrayProperty = $protectedArrayProperty;
-
- $this->privateAnyTypeProperty = $privateAnyTypeProperty;
- $this->publicAnyTypeProperty = $publicAnyTypeProperty;
- $this->protectedAnyTypeProperty = $protectedAnyTypeProperty;
-
$this->privateEmptyArrayProperty = [];
$this->publicEmptyArrayProperty = [];
$this->protectedEmptyArrayProperty = [];
@@ -269,63 +228,36 @@ public function producerId(): Domain\Id
class EventA implements Event
{
- private string $property1;
-
- public function __construct(string $property1)
+ public function __construct(private string $property1)
{
- $this->property1 = $property1;
}
}
class EventB extends EventA
{
- private $property2;
-
- public function __construct($property1, $property2)
+ public function __construct($property1, private $property2)
{
parent::__construct($property1);
- $this->property2 = $property2;
}
}
class EventC implements Event
{
- private Event $event;
-
- public function __construct(Event $event)
+ public function __construct(private Event $event)
{
- $this->event = $event;
}
}
class ParentObject
{
- private object $objectProperty;
-
- private string $scalarProperty;
-
- private array $arrayProperty;
-
- public function __construct(string $scalarProperty, object $objectProperty, array $arrayProperty)
+ public function __construct(private string $scalarProperty, private object $objectProperty, private array $arrayProperty)
{
- $this->objectProperty = $objectProperty;
- $this->scalarProperty = $scalarProperty;
- $this->arrayProperty = $arrayProperty;
}
}
class ChildObject
{
- private string $scalarProperty;
-
- private array $arrayProperty;
-
- private ?self $child;
-
- public function __construct(string $scalarProperty, array $arrayProperty, self $childObject = null)
+ public function __construct(private string $scalarProperty, private array $arrayProperty, private ?self $child = null)
{
- $this->scalarProperty = $scalarProperty;
- $this->arrayProperty = $arrayProperty;
- $this->child = $childObject;
}
}
diff --git a/tests/Infrastructure/Domain/Event/Envelope/ComparatorTest.php b/tests/Infrastructure/Domain/Event/Envelope/ComparatorTest.php
index eeb15f37..de8afff9 100644
--- a/tests/Infrastructure/Domain/Event/Envelope/ComparatorTest.php
+++ b/tests/Infrastructure/Domain/Event/Envelope/ComparatorTest.php
@@ -49,8 +49,8 @@ protected function setUp(): void
$this->uuid = UUID::random();
$this->event1 = $this->getMockBuilder(Event::class)->getMockForAbstractClass();
- $this->envelope1a = new Event\Envelope($this->uuid, 'name', $this->event1, UUID::random());
- $this->envelope1b = new Event\Envelope($this->uuid, 'name', $this->event1, UUID::random());
+ $this->envelope1a = new Event\Envelope($this->uuid, 'name', $this->event1, UUID::random(), UUID::random());
+ $this->envelope1b = new Event\Envelope($this->uuid, 'name', $this->event1, UUID::random(), UUID::random());
$this->event2 = $this->getMockBuilder(Event::class)->getMockForAbstractClass();
$this->envelope2 = Event\Envelope::new($this->event2, UUID::random());
}
@@ -117,7 +117,15 @@ public function testAccepting($expected, $actual): void
public function testEqualEnvelopes(): void
{
- self::assertNull($this->comparator->assertEquals($this->envelope1a, $this->envelope1b));
+// $this->expectNotToPerformAssertions();
+
+ try {
+ $this->comparator->assertEquals($this->envelope1a, $this->envelope1b);
+ } catch (ComparisonFailure) {
+ self::fail();
+ }
+
+ $this->addToAssertionCount(1); // tests without assertions does not report any coverage, so this is a hack @link https://github.com/sebastianbergmann/phpunit/pull/3348
}
public function testNotEqualEnvelopes(): void
diff --git a/tests/Infrastructure/Domain/Event/LoggingListenerTest.php b/tests/Infrastructure/Domain/Event/LoggingListenerTest.php
index d05347a5..3fb5d3d3 100644
--- a/tests/Infrastructure/Domain/Event/LoggingListenerTest.php
+++ b/tests/Infrastructure/Domain/Event/LoggingListenerTest.php
@@ -131,11 +131,11 @@ public function testObject(): void
$this->listener2
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->listenerId)
;
- self::assertSame($this->listenerId, $listener->listenerId());
+ self::assertSame($this->listenerId, $listener->id());
self::assertSame($this->listenerId, $listener->id());
$listener->reset();
diff --git a/tests/Infrastructure/Domain/Event/NullListenerTest.php b/tests/Infrastructure/Domain/Event/NullListenerTest.php
index 742b6807..9c76a109 100644
--- a/tests/Infrastructure/Domain/Event/NullListenerTest.php
+++ b/tests/Infrastructure/Domain/Event/NullListenerTest.php
@@ -41,14 +41,14 @@ public function testObject(): void
{
$this->listener
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id)
;
$listener = NullListener::from($this->listener);
self::assertInstanceOf(NullListener::class, $listener);
- self::assertSame($this->id, $listener->listenerId());
+ self::assertSame($this->id, $listener->id());
self::assertTrue($listener->on($this->event));
}
diff --git a/tests/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryStateTest.php b/tests/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryStateTest.php
index 537f0dc0..32da5bf8 100644
--- a/tests/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryStateTest.php
+++ b/tests/Infrastructure/Domain/Event/Sourced/Subscription/InMemoryStateTest.php
@@ -30,7 +30,7 @@ class InMemoryStateTest extends TestCase
protected function setUp(): void
{
- $this->stub = new class() implements State {
+ $this->stub = new class () implements State {
public function equals(object $object): bool
{
throw new \BadMethodCallException('Do not call method State::equals() on this stub.');
diff --git a/tests/Infrastructure/Domain/Event/Sourced/SubscriptionTest.php b/tests/Infrastructure/Domain/Event/Sourced/SubscriptionTest.php
index 5c2bcab6..94ac2599 100644
--- a/tests/Infrastructure/Domain/Event/Sourced/SubscriptionTest.php
+++ b/tests/Infrastructure/Domain/Event/Sourced/SubscriptionTest.php
@@ -18,6 +18,7 @@
use Streak\Domain\Event;
use Streak\Domain\Event\Listener;
use Streak\Domain\EventStore;
+use Streak\Domain\Exception\EventMismatched;
use Streak\Domain\Id\UUID;
use Streak\Infrastructure\Domain\Clock\FixedClock;
use Streak\Infrastructure\Domain\Event\InMemoryStream;
@@ -83,7 +84,7 @@ protected function setUp(): void
$this->listener8 = $this->getMockBuilder(FilteringListener::class)->getMock();
$this->listener9 = $this->getMockBuilder(StatefulListener::class)->getMock();
- $this->id1 = new class('f5e65690-e50d-4312-a175-b004ec1bd42a') extends UUID implements Listener\Id {
+ $this->id1 = new class ('f5e65690-e50d-4312-a175-b004ec1bd42a') extends UUID implements Listener\Id {
};
$this->store = $this->getMockBuilder(EventStore::class)->getMockForAbstractClass();
@@ -111,7 +112,7 @@ public function testListener(): void
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -122,9 +123,7 @@ public function testListener(): void
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -135,9 +134,7 @@ public function testListener(): void
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
@@ -146,9 +143,7 @@ public function testListener(): void
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -295,7 +290,7 @@ public function testListenerWithPicker(): void
$this->listener7
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener7
@@ -310,18 +305,14 @@ public function testListenerWithPicker(): void
$subscription = new Subscription($this->listener7, $this->clock);
self::assertSame($subscription->listener(), $this->listener7);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event3);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event3, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event3, $now)], $subscription->events());
@@ -399,28 +390,25 @@ public function testListenerWithFilterer(): void
$this->listener8
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener8, $this->clock);
self::assertSame($subscription->listener(), $this->listener8);
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event2);
- self::assertNull($subscription->lastReplayed());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event2, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event2, $now)], $subscription->events());
$subscription->commit();
- self::assertNull($subscription->lastReplayed());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event2, $now), $subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -489,7 +477,7 @@ public function testTransactionalListenerWithoutReplaying(): void
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -500,27 +488,21 @@ public function testTransactionalListenerWithoutReplaying(): void
$subscription = new Subscription($this->listener3, $this->clock);
self::assertSame($subscription->listener(), $this->listener3);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -612,7 +594,7 @@ public function testReplayingListener(): void
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -623,9 +605,7 @@ public function testReplayingListener(): void
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -641,9 +621,7 @@ public function testReplayingListener(): void
$subscription->replay($this->stream1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertSame($event2, $subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(3, $subscription->version());
self::assertEquals($event2, $subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -706,7 +684,7 @@ public function testReplayingStatefulListenerWithExistingState(): void
$this->listener9
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -714,7 +692,6 @@ public function testReplayingStatefulListenerWithExistingState(): void
$subscription = new Subscription($this->listener9, $this->clock);
self::assertSame($subscription->listener(), $this->listener9);
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -741,7 +718,6 @@ public function testReplayingStatefulListenerWithExistingState(): void
$subscription->replay($this->stream1);
- self::assertSame($event3, $subscription->lastReplayed());
self::assertSame(4, $subscription->version());
self::assertEquals($event3, $subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -813,14 +789,13 @@ public function testReplayingStatefulListenerWithoutExistingState(): void
$this->listener9
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener9, $this->clock);
self::assertSame($subscription->listener(), $this->listener9);
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -836,7 +811,6 @@ public function testReplayingStatefulListenerWithoutExistingState(): void
$subscription->replay($this->stream1);
- self::assertSame($event2, $subscription->lastReplayed());
self::assertSame(3, $subscription->version());
self::assertEquals($event2, $subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -914,7 +888,7 @@ public function testReplayingListenerWithAnEmptyStream(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -925,9 +899,7 @@ public function testReplayingListenerWithAnEmptyStream(): void
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -937,9 +909,7 @@ public function testReplayingListenerWithAnEmptyStream(): void
$subscription->replay($this->stream1);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -951,7 +921,7 @@ public function testCompletingListener(): void
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -960,7 +930,6 @@ public function testCompletingListener(): void
self::assertSame($subscription->listener(), $this->listener3);
self::assertFalse($subscription->completed());
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -973,7 +942,6 @@ public function testCompletingListener(): void
$subscription->replay($this->stream1);
- self::assertSame($event0, $subscription->lastReplayed());
self::assertSame($event0, $subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(1, $subscription->version());
@@ -1017,7 +985,6 @@ public function testCompletingListener(): void
self::assertEquals([$this->event1, $this->event2], $events);
self::assertTrue($subscription->completed());
self::assertEquals([new SubscriptionListenedToEvent($this->event1, $now), new SubscriptionListenedToEvent($this->event2, $now), new SubscriptionCompleted($now)], $subscription->events());
- self::assertSame($event0, $subscription->lastReplayed());
self::assertEquals(new SubscriptionCompleted($now), $subscription->lastEvent());
self::assertSame(1, $subscription->version());
self::assertFalse($subscription->paused());
@@ -1026,7 +993,6 @@ public function testCompletingListener(): void
self::assertTrue($subscription->completed());
self::assertEmpty($subscription->events());
- self::assertSame($event0, $subscription->lastReplayed());
self::assertEquals(new SubscriptionCompleted($now), $subscription->lastEvent());
self::assertSame(4, $subscription->version());
self::assertFalse($subscription->paused());
@@ -1035,7 +1001,6 @@ public function testCompletingListener(): void
self::assertTrue($subscription->completed());
self::assertEmpty($subscription->events());
- self::assertSame($event0, $subscription->lastReplayed());
self::assertEquals(new SubscriptionCompleted($now), $subscription->lastEvent());
self::assertSame(4, $subscription->version());
self::assertFalse($subscription->paused());
@@ -1044,7 +1009,6 @@ public function testCompletingListener(): void
self::assertTrue($subscription->completed());
self::assertEmpty($subscription->events());
- self::assertSame($event0, $subscription->lastReplayed());
self::assertEquals(new SubscriptionCompleted($now), $subscription->lastEvent());
self::assertSame(4, $subscription->version());
self::assertFalse($subscription->paused());
@@ -1053,7 +1017,6 @@ public function testCompletingListener(): void
self::assertTrue($subscription->completed());
self::assertEmpty($subscription->events());
- self::assertSame($event0, $subscription->lastReplayed());
self::assertEquals(new SubscriptionCompleted($now), $subscription->lastEvent());
self::assertSame(4, $subscription->version());
self::assertFalse($subscription->paused());
@@ -1062,7 +1025,6 @@ public function testCompletingListener(): void
self::assertTrue($subscription->completed());
self::assertEmpty($subscription->events());
- self::assertSame($event0, $subscription->lastReplayed());
self::assertEquals(new SubscriptionCompleted($now), $subscription->lastEvent());
self::assertSame(4, $subscription->version());
self::assertFalse($subscription->paused());
@@ -1078,16 +1040,14 @@ public function testStartingAlreadyStartedSubscription(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -1104,7 +1064,7 @@ public function testSubscribingAlreadyCompletedListener(): void
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -1126,7 +1086,6 @@ public function testSubscribingAlreadyCompletedListener(): void
$subscription->replay($this->stream1);
self::assertTrue($subscription->completed());
- self::assertSame($event2, $subscription->lastReplayed());
self::assertSame($event2, $subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(3, $subscription->version());
@@ -1149,7 +1108,7 @@ public function testSubscribingRestartedAndCompletedListener(): void
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -1177,7 +1136,6 @@ public function testSubscribingRestartedAndCompletedListener(): void
$subscription->replay($this->stream1);
self::assertTrue($subscription->completed());
- self::assertSame($event5, $subscription->lastReplayed());
self::assertSame($event5, $subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(6, $subscription->version());
@@ -1198,16 +1156,14 @@ public function testNotStartedListener(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -1232,7 +1188,7 @@ public function testRestartingSubscriptionForResettableButNonReplayableListener(
{
$this->listener4
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -1240,7 +1196,6 @@ public function testRestartingSubscriptionForResettableButNonReplayableListener(
$subscription = new Subscription($this->listener4, $this->clock);
self::assertSame($subscription->listener(), $this->listener4);
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -1259,21 +1214,18 @@ public function testRestartingSubscriptionForResettableButNonReplayableListener(
$subscription->replay($this->stream1);
- self::assertSame($event3, $subscription->lastReplayed());
self::assertSame($event3, $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(4, $subscription->version());
$subscription->restart();
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionRestarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionRestarted($this->event1, $now)], $subscription->events());
self::assertSame(4, $subscription->version());
$subscription->commit();
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionRestarted($this->event1, $now), $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(5, $subscription->version());
@@ -1281,7 +1233,6 @@ public function testRestartingSubscriptionForResettableButNonReplayableListener(
$subscription->restart();
// nothing changed as consecutive restarts are ignored
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionRestarted($this->event1, $now), $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(5, $subscription->version());
@@ -1319,14 +1270,12 @@ public function testRestartingSubscriptionForResettableButNonReplayableListener(
$events = iterator_to_array($events);
self::assertSame([$this->event1, $this->event3, $this->event4, $this->event5], $events);
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionListenedToEvent($this->event5, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionListenedToEvent($this->event1, $now), new SubscriptionListenedToEvent($this->event3, $now), new SubscriptionIgnoredEvent($this->event4, $now), new SubscriptionListenedToEvent($this->event5, $now)], $subscription->events());
self::assertSame(5, $subscription->version());
$subscription->commit();
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionListenedToEvent($this->event5, $now), $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(9, $subscription->version());
@@ -1336,16 +1285,14 @@ public function testRestartingNotStartedSubscription(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
@@ -1358,7 +1305,7 @@ public function testRestartingCompletedSubscription(): void
{
$this->listener6
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -1366,7 +1313,6 @@ public function testRestartingCompletedSubscription(): void
$subscription = new Subscription($this->listener6, $this->clock);
self::assertSame($subscription->listener(), $this->listener6);
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -1403,7 +1349,6 @@ public function testRestartingCompletedSubscription(): void
$subscription->replay($this->stream1);
- self::assertSame($event3, $subscription->lastReplayed());
self::assertSame($event3, $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(4, $subscription->version());
@@ -1411,7 +1356,6 @@ public function testRestartingCompletedSubscription(): void
$subscription->restart();
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionRestarted($this->event2, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionRestarted($this->event2, $now)], $subscription->events());
self::assertSame(4, $subscription->version());
@@ -1419,7 +1363,6 @@ public function testRestartingCompletedSubscription(): void
$subscription->commit();
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionRestarted($this->event2, $now), $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(5, $subscription->version());
@@ -1453,7 +1396,6 @@ public function testRestartingCompletedSubscription(): void
$events = iterator_to_array($events);
self::assertSame([$this->event2, $this->event3, $this->event4, $this->event5], $events);
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionListenedToEvent($this->event5, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionListenedToEvent($this->event2, $now), new SubscriptionListenedToEvent($this->event3, $now), new SubscriptionListenedToEvent($this->event4, $now), new SubscriptionListenedToEvent($this->event5, $now)], $subscription->events());
self::assertSame(5, $subscription->version());
@@ -1461,7 +1403,6 @@ public function testRestartingCompletedSubscription(): void
$subscription->commit();
- self::assertSame($event3, $subscription->lastReplayed());
self::assertEquals(new SubscriptionListenedToEvent($this->event5, $now), $subscription->lastEvent());
self::assertSame([], $subscription->events());
self::assertSame(9, $subscription->version());
@@ -1472,7 +1413,7 @@ public function testRestartingNonResettableListener(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -1481,7 +1422,6 @@ public function testRestartingNonResettableListener(): void
self::assertSame($subscription->listener(), $this->listener1);
self::assertFalse($subscription->completed());
- self::assertNull($subscription->lastReplayed());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
@@ -1499,7 +1439,6 @@ public function testRestartingNonResettableListener(): void
$subscription->replay($this->stream1);
- self::assertSame($event2, $subscription->lastReplayed());
self::assertSame($event2, $subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(3, $subscription->version());
@@ -1528,13 +1467,13 @@ public function testEquals(): void
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($id1)
;
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($id2)
;
@@ -1563,33 +1502,28 @@ public function testStartingSubscriptionWithResettableListenerWithFirstEventIgno
$this->listener4
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener4, $this->clock);
self::assertSame($subscription->listener(), $this->listener4);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
+
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -1633,33 +1567,27 @@ public function testStartingSubscriptionWithResettableListenerWithFirstEventNotI
$this->listener4
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener4, $this->clock);
self::assertSame($subscription->listener(), $this->listener4);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -1703,33 +1631,27 @@ public function testRestartingFreshlyStartedSubscription(): void
$this->listener4
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener4, $this->clock);
self::assertSame($subscription->listener(), $this->listener4);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -1737,9 +1659,7 @@ public function testRestartingFreshlyStartedSubscription(): void
$subscription->restart();
// nothing changed as consecutive restarts are ignored
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -1773,7 +1693,7 @@ public function testNonPositiveLimitGivenWhileSubscribingToTheEventStoreAfterSta
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
@@ -1808,7 +1728,7 @@ public function testContinuousListeningWithNumberOfEventsBeingExactlyImposedLimi
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1819,27 +1739,21 @@ public function testContinuousListeningWithNumberOfEventsBeingExactlyImposedLimi
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -1900,7 +1814,7 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1911,27 +1825,21 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -1988,7 +1896,7 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1999,27 +1907,21 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -2076,7 +1978,7 @@ public function testContinuousListeningWithNumberOfEventsBeingLessThanImposedLim
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -2087,27 +1989,21 @@ public function testContinuousListeningWithNumberOfEventsBeingLessThanImposedLim
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -2168,34 +2064,28 @@ public function testCompletingListenerWhileContinuousListening(): void
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener3, $this->clock);
self::assertSame($subscription->listener(), $this->listener3);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertNull($subscription->lastEvent());
self::assertEmpty($subscription->events());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([new SubscriptionStarted($this->event1, $now)], $subscription->events());
$subscription->commit();
- self::assertSame($this->id1, $subscription->subscriptionId());
- self::assertSame($this->id1, $subscription->producerId());
- self::assertNull($subscription->lastReplayed());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertEquals(new SubscriptionStarted($this->event1, $now), $subscription->lastEvent());
self::assertEquals([], $subscription->events());
@@ -2256,6 +2146,51 @@ public function testCompletingListenerWhileContinuousListening(): void
self::assertEquals([], $subscription->events());
self::assertSame(7, $subscription->version());
}
+
+ public function testReplayingMismatchedEvent(): void
+ {
+ $now = new \DateTime('2018-09-28 19:12:32.763188 +00:00');
+
+ $this->listener1
+ ->expects(self::atLeastOnce())
+ ->method('id')
+ ->willReturn($this->id1)
+ ;
+ $this->listener1
+ ->expects(self::never())
+ ->method('replay')
+ ;
+
+ $subscription = new Subscription($this->listener1, $this->clock);
+
+ self::assertSame($subscription->listener(), $this->listener1);
+ self::assertSame($this->id1, $subscription->id());
+ self::assertNull($subscription->lastEvent());
+ self::assertEmpty($subscription->events());
+ self::assertSame(0, $subscription->version());
+
+ $event0 = new SubscriptionStarted($this->event1, $now);
+ $event0 = Event\Envelope::new($event0, $this->id1, 1);
+ $event1 = new SubscriptionListenedToEvent($this->event1, $now);
+ $event1 = Event\Envelope::new($event1, $this->id1, 2);
+ $event2 = new SubscriptionListenedToEvent($this->event2, $now);
+ $event2 = Event\Envelope::new($event2, UUID::random(), 3);
+
+ $this->stream1 = new InMemoryStream($event0, $event1, $event2);
+
+ try {
+ $subscription->replay($this->stream1);
+ self::fail();
+ } catch (EventMismatched $exception) {
+ self::assertSame($event2, $exception->event());
+ self::assertSame($subscription, $exception->object());
+
+ self::assertSame($this->id1, $subscription->id());
+ self::assertSame(1, $subscription->version());
+ self::assertEquals($event0, $subscription->lastEvent());
+ self::assertEmpty($subscription->events());
+ }
+ }
}
namespace Streak\Infrastructure\Domain\Event\Sourced\SubscriptionTest;
@@ -2290,3 +2225,7 @@ abstract class StatefulListener implements Listener, Listener\Stateful
abstract class IterableStream implements Event\Stream, \IteratorAggregate
{
}
+
+class UnsupportedEvent implements Event
+{
+}
diff --git a/tests/Infrastructure/Domain/Event/Subscription/CommittingSubscriptionTest.php b/tests/Infrastructure/Domain/Event/Subscription/CommittingSubscriptionTest.php
index 8fc294af..6e7286f3 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/CommittingSubscriptionTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/CommittingSubscriptionTest.php
@@ -43,7 +43,7 @@ protected function setUp(): void
{
$this->listener = $this->getMockBuilder(Listener::class)->addMethods(['replay', 'reset', 'completed'])->getMockForAbstractClass();
- $this->id1 = new class('f5e65690-e50d-4312-a175-b004ec1bd42a') extends UUID implements Listener\Id {
+ $this->id1 = new class ('f5e65690-e50d-4312-a175-b004ec1bd42a') extends UUID implements Listener\Id {
};
$this->store = $this->getMockBuilder(EventStore::class)->getMockForAbstractClass();
@@ -68,7 +68,7 @@ public function testListener(): void
;
$this->subscription
->expects(self::atLeastOnce())
- ->method('subscriptionId')
+ ->method('id')
->willReturn($this->id1)
;
$this->subscription
@@ -98,7 +98,7 @@ public function testListener(): void
;
self::assertSame($this->listener, $subscription->listener());
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(\PHP_INT_MAX, $subscription->version());
self::assertTrue($subscription->starting());
self::assertFalse($subscription->starting());
diff --git a/tests/Infrastructure/Domain/Event/Subscription/DAO/DAOTestCase.php b/tests/Infrastructure/Domain/Event/Subscription/DAO/DAOTestCase.php
index a5eb61a7..e1b00715 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/DAO/DAOTestCase.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/DAO/DAOTestCase.php
@@ -46,8 +46,8 @@ protected function setUp(): void
{
$this->subscriptions = $this->getMockBuilder(Event\Subscription\Factory::class)->getMockForAbstractClass();
$this->listeners = $this->getMockBuilder(Event\Listener\Factory::class)->getMockForAbstractClass();
- $this->listener1 = $this->getMockBuilder(CompletableListener::class)->setMockClassName('listener1')->getMock();
- $this->listener2 = $this->getMockBuilder(CompletableListener::class)->setMockClassName('listener2')->getMock();
+ $this->listener1 = $this->getMockBuilder(CompletableListener::class)->setMockClassName('listener1_sydteu')->getMockForAbstractClass();
+ $this->listener2 = $this->getMockBuilder(CompletableListener::class)->setMockClassName('listener2_dhafg6')->getMockForAbstractClass();
$this->event = Event\Envelope::new(new EventStub(), UUID::random());
$this->clock = new FixedClock(new \DateTime('2018-09-28 19:12:32.763188 +00:00'));
$this->dao = $this->newDAO(new Subscription\Factory($this->clock), $this->listeners);
@@ -70,22 +70,23 @@ public function testDAO(): void
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($listenerId1)
;
$this->listener2
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($listenerId2)
;
$this->listener1
+ ->expects(self::atLeastOnce())
->method('completed')
->willReturnOnConsecutiveCalls(false, true)
;
$this->listener2
+ ->expects(self::never())
->method('completed')
- ->willReturnOnConsecutiveCalls(false, false)
;
$all = $this->dao->all();
diff --git a/tests/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAOTest.php b/tests/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAOTest.php
index 44385979..be2164d5 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAOTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/DAO/DbalPostgresDAOTest.php
@@ -59,7 +59,7 @@ public function testDAO(): void
$listener3 = $this->getMockBuilder(DAO\DbalPostgresDAOTest\CompletableListener::class)->setMockClassName('listener3')->getMock();
$listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($listenerId3)
;
$subscription3 = new Subscription($listener3, $this->clock);
diff --git a/tests/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDaoTest.php b/tests/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDaoTest.php
index 714714b0..b7adcdef 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDaoTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/DAO/IdentityMappingDaoTest.php
@@ -15,10 +15,7 @@
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
-use Streak\Domain\Event;
-use Streak\Domain\Event\Envelope;
use Streak\Domain\Event\Listener\Id;
-use Streak\Domain\Id\UUID;
use Streak\Infrastructure\Domain\Event\Subscription\DAO;
/**
@@ -159,7 +156,7 @@ public function testItReturnsOne(): void
$subscription = $this->createSubscriptionStub('eea81580-4e00-4680-8f87-e96054d3c41b', 'SubscriptionId', 100);
$this->dao->expects(self::once())->method('one')->willReturn($subscription);
$dao = new IdentityMappingDao($this->dao);
- self::assertSame($subscription, $dao->one($subscription->subscriptionId()));
+ self::assertSame($subscription, $dao->one($subscription->id()));
}
public function testItExists(): void
@@ -175,19 +172,12 @@ public function testItExists(): void
private function createSubscriptionStub(string $subscriptionId, string $subscriptionIdClassName, int $version): Subscription
{
$result = $this->getMockBuilder(Subscription::class)->disableOriginalConstructor()->getMock();
- $result->method('subscriptionId')->willReturn($this->createSubscriptionIdStub($subscriptionIdClassName, $subscriptionId));
+ $result->method('id')->willReturn($this->createSubscriptionIdStub($subscriptionIdClassName, $subscriptionId));
$result->method('version')->willReturn($version);
return $result;
}
- private function createEnvelopeStub(string $id): Envelope
- {
- $event = $this->getMockBuilder(Event::class)->getMock();
-
- return new Envelope(new UUID($id), 'test', $event, new UUID($id));
- }
-
private function createSubscriptionIdStub(string $className, string $id): Id
{
$result = $this->getMockBuilder(Id::class)->setMockClassName($className)->getMock();
diff --git a/tests/Infrastructure/Domain/Event/Subscription/DAO/SubscriptionTest.php b/tests/Infrastructure/Domain/Event/Subscription/DAO/SubscriptionTest.php
index bc81e8ac..d67f1a7e 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/DAO/SubscriptionTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/DAO/SubscriptionTest.php
@@ -68,7 +68,7 @@ protected function setUp(): void
$this->listener8 = $this->getMockBuilder(FilteringListener::class)->getMock();
$this->listener9 = $this->getMockBuilder(StatefulListener::class)->getMock();
- $this->id1 = new class('f5e65690-e50d-4312-a175-b004ec1bd42a') extends UUID implements Listener\Id {
+ $this->id1 = new class ('f5e65690-e50d-4312-a175-b004ec1bd42a') extends UUID implements Listener\Id {
};
$this->store = $this->getMockBuilder(EventStore::class)->getMockForAbstractClass();
@@ -90,7 +90,7 @@ public function testListener(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -101,7 +101,7 @@ public function testListener(): void
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertFalse($subscription->starting());
self::assertFalse($subscription->paused());
@@ -111,7 +111,7 @@ public function testListener(): void
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertTrue($subscription->starting());
self::assertFalse($subscription->paused());
@@ -202,7 +202,7 @@ public function testStatefulListener(): void
{
$this->listener9
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -242,13 +242,13 @@ public function testStatefulListener(): void
$subscription = new Subscription($this->listener9, $this->clock);
self::assertSame($subscription->listener(), $this->listener9);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertFalse($subscription->starting());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertTrue($subscription->starting());
@@ -312,7 +312,7 @@ public function testListenerWithPicker(): void
{
$this->listener7
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener7
@@ -327,12 +327,12 @@ public function testListenerWithPicker(): void
$subscription = new Subscription($this->listener7, $this->clock);
self::assertSame($subscription->listener(), $this->listener7);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event3);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2, $this->event3);
@@ -386,14 +386,14 @@ public function testListenerWithFilterer(): void
$this->listener8
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener8, $this->clock);
self::assertSame($subscription->listener(), $this->listener8);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event2);
@@ -450,7 +450,7 @@ public function testTransactionalListenerWithoutReplaying(): void
{
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -461,12 +461,12 @@ public function testTransactionalListenerWithoutReplaying(): void
$subscription = new Subscription($this->listener3, $this->clock);
self::assertSame($subscription->listener(), $this->listener3);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -536,21 +536,21 @@ public function testCompletingListener(): void
{
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener3, $this->clock);
self::assertSame($subscription->listener(), $this->listener3);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
self::assertFalse($subscription->completed());
self::assertFalse($subscription->paused());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
self::assertFalse($subscription->completed());
self::assertFalse($subscription->paused());
@@ -647,14 +647,14 @@ public function testStartingAlreadyStartedSubscription(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
$subscription->startFor($this->event1);
@@ -667,7 +667,7 @@ public function testStartingStatefulSubscription(): void
{
$this->listener9
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener9
@@ -679,7 +679,7 @@ public function testStartingStatefulSubscription(): void
$subscription = new Subscription($this->listener9, $this->clock);
self::assertSame($subscription->listener(), $this->listener9);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
$subscription->startFor($this->event1);
}
@@ -688,14 +688,14 @@ public function testNotStartedListener(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
$this->store
->expects(self::never())
@@ -718,7 +718,7 @@ public function testRestartingSubscription(): void
{
$this->listener4
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener4
@@ -729,12 +729,12 @@ public function testRestartingSubscription(): void
$subscription = new Subscription($this->listener4, $this->clock);
self::assertSame($subscription->listener(), $this->listener4);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -783,14 +783,14 @@ public function testRestartingNotStartedSubscription(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
$this->expectExceptionObject(new Event\Subscription\Exception\SubscriptionNotStartedYet($subscription));
@@ -801,19 +801,19 @@ public function testRestartingCompletedSubscription(): void
{
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener3, $this->clock);
self::assertSame($subscription->listener(), $this->listener3);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -888,19 +888,19 @@ public function testRestartingNonResettableListener(): void
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -969,13 +969,13 @@ public function testNonPositiveLimitGivenWhileSubscribingToTheEventStoreAfterSta
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->with()
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener1, $this->clock);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
$subscription->startFor($this->event1);
$this->store
@@ -1002,7 +1002,7 @@ public function testContinuousListeningWithNumberOfEventsBeingExactlyImposedLimi
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1013,12 +1013,12 @@ public function testContinuousListeningWithNumberOfEventsBeingExactlyImposedLimi
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -1069,7 +1069,7 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1080,12 +1080,12 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -1132,7 +1132,7 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1143,12 +1143,12 @@ public function testContinuousListeningWithNumberOfEventsBeingMoreThanImposedLim
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -1195,7 +1195,7 @@ public function testContinuousListeningWithNumberOfEventsBeingLessThanImposedLim
{
$this->listener1
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$this->listener1
@@ -1206,12 +1206,12 @@ public function testContinuousListeningWithNumberOfEventsBeingLessThanImposedLim
$subscription = new Subscription($this->listener1, $this->clock);
self::assertSame($subscription->listener(), $this->listener1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
@@ -1262,19 +1262,19 @@ public function testCompletingListenerWhileContinuousListening(): void
{
$this->listener3
->expects(self::atLeastOnce())
- ->method('listenerId')
+ ->method('id')
->willReturn($this->id1)
;
$subscription = new Subscription($this->listener3, $this->clock);
self::assertSame($subscription->listener(), $this->listener3);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(0, $subscription->version());
$subscription->startFor($this->event1);
- self::assertSame($this->id1, $subscription->subscriptionId());
+ self::assertSame($this->id1, $subscription->id());
self::assertSame(1, $subscription->version());
$this->stream1 = new InMemoryStream($this->event1, $this->event2);
diff --git a/tests/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscriptionTest.php b/tests/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscriptionTest.php
index ae48c7cd..f9aa85d3 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscriptionTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/DbalTransactionalSubscriptionTest.php
@@ -128,12 +128,12 @@ public function testObject(): void
$this->subscription
->expects(self::once())
- ->method('subscriptionId')
+ ->method('id')
->with()
->willReturn($this->subscriptionId)
;
- self::assertSame($this->subscriptionId, $subscription->subscriptionId());
+ self::assertSame($this->subscriptionId, $subscription->id());
$this->subscription
->expects(self::once())
diff --git a/tests/Infrastructure/Domain/Event/Subscription/EventSourcedRepositoryTest.php b/tests/Infrastructure/Domain/Event/Subscription/EventSourcedRepositoryTest.php
index d5dcd4f5..825f7883 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/EventSourcedRepositoryTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/EventSourcedRepositoryTest.php
@@ -84,13 +84,13 @@ protected function setUp(): void
$this->nonEventSourcedSubscription3 = $this->getMockBuilder(DecoratedSubscription::class)->setMockClassName('nonEventSourcedSubscription3')->getMock();
$this->nonEventSourcedSubscription3->method('subscription')->willReturn($this->nonEventSourcedSubscription2);
- $this->id1 = new class('f5e65690-e50d-4312-a175-b004ec1bd42a') extends Domain\Id\UUID implements Listener\Id {
+ $this->id1 = new class ('f5e65690-e50d-4312-a175-b004ec1bd42a') extends Domain\Id\UUID implements Listener\Id {
};
- $this->id2 = new class('d01286b0-7dd6-4520-b714-0e9903ab39af') extends Domain\Id\UUID implements Listener\Id {
+ $this->id2 = new class ('d01286b0-7dd6-4520-b714-0e9903ab39af') extends Domain\Id\UUID implements Listener\Id {
};
- $this->id3 = new class('39ab6175-7cd7-4c94-95c1-03d05c2e2fa2') extends Domain\Id\UUID implements Listener\Id {
+ $this->id3 = new class ('39ab6175-7cd7-4c94-95c1-03d05c2e2fa2') extends Domain\Id\UUID implements Listener\Id {
};
- $this->id4 = new class('2d40c01d-7aa9-4757-ac28-de3733431cc5') extends Domain\Id\UUID implements Listener\Id {
+ $this->id4 = new class ('2d40c01d-7aa9-4757-ac28-de3733431cc5') extends Domain\Id\UUID implements Listener\Id {
};
$this->event1 = Event\Envelope::new($this->getMockBuilder(Event::class)->setMockClassName('event1')->getMockForAbstractClass(), UUID::random());
@@ -153,7 +153,7 @@ public function testFindingNotExistingSubscription(): void
$this->eventSourcedSubscription1
->expects(self::once())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -177,7 +177,7 @@ public function testCheckingForExistingSubscription(): void
$this->eventSourcedSubscription1
->expects(self::once())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -192,7 +192,7 @@ public function testCheckingForNotExistingSubscription(): void
$this->eventSourcedSubscription1
->expects(self::once())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -232,7 +232,7 @@ public function testFindingSubscription(): void
$this->eventSourcedSubscription1
->expects(self::once())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -288,7 +288,7 @@ public function testFindingPreviouslyRestartedSubscription(): void
$this->eventSourcedSubscription1
->expects(self::once())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -324,7 +324,7 @@ public function testAddingEventSourcedSubscription(): void
$this->eventSourcedSubscription1
->expects(self::atLeastOnce())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -339,7 +339,7 @@ public function testAddingDecoratedEventSourcedSubscription(): void
$this->eventSourcedSubscription1
->expects(self::atLeastOnce())
- ->method('producerId')
+ ->method('id')
->willReturn($this->id1)
;
@@ -413,7 +413,7 @@ public function testFindingSubscriptions(): void
use Streak\Domain\Event;
-abstract class EventSourcedSubscription implements Event\Subscription, Event\Sourced
+abstract class EventSourcedSubscription implements Event\Sourced\Subscription
{
}
diff --git a/tests/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscriptionTest.php b/tests/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscriptionTest.php
index 65a0cacc..65fb4e43 100644
--- a/tests/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscriptionTest.php
+++ b/tests/Infrastructure/Domain/Event/Subscription/LazyLoadedSubscriptionTest.php
@@ -64,7 +64,7 @@ public function testObject(): void
->willReturn($this->subscription)
;
- self::assertSame($this->id, $subscription->subscriptionId());
+ self::assertSame($this->id, $subscription->id());
$this->subscription
->expects(self::once())
diff --git a/tests/Infrastructure/Domain/EventStore/EventStoreTestCase.php b/tests/Infrastructure/Domain/EventStore/EventStoreTestCase.php
index 7fdfee20..d262107b 100644
--- a/tests/Infrastructure/Domain/EventStore/EventStoreTestCase.php
+++ b/tests/Infrastructure/Domain/EventStore/EventStoreTestCase.php
@@ -317,7 +317,7 @@ public function testItGetsEvent(): void
$uuid2 = new Id\UUID('5e04364e-4590-403b-9f8f-3ae14f6dcce6');
$event = new EventStoreTestCase\Event1();
- $event = new Event\Envelope($uuid1, 'event1', $event, new EventStoreTestCase\ProducerId1('producer1'), 1);
+ $event = new Event\Envelope($uuid1, 'event1', $event, new EventStoreTestCase\ProducerId1('producer1'), new EventStoreTestCase\ProducerId1('producer1'), 1);
$this->store->add($event);
@@ -334,11 +334,8 @@ abstract protected function newEventStore(): EventStore;
abstract class ValueId implements Domain\Id
{
- private string $value;
-
- public function __construct(string $value)
+ public function __construct(private string $value)
{
- $this->value = $value;
}
public function equals(object $id): bool
diff --git a/tests/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWorkTest.php b/tests/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWorkTest.php
index 82cb5091..0746ad6d 100644
--- a/tests/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWorkTest.php
+++ b/tests/Infrastructure/Domain/UnitOfWork/EventStoreUnitOfWorkTest.php
@@ -18,9 +18,9 @@
use Streak\Domain\EventStore;
use Streak\Domain\Exception\ConcurrentWriteDetected;
use Streak\Domain\Id\UUID;
+use Streak\Infrastructure\Domain\EventStoreUnitOfWorkTest\NonVersionableEventSourcedStub;
+use Streak\Infrastructure\Domain\EventStoreUnitOfWorkTest\VersionableEventSourcedStub;
use Streak\Infrastructure\Domain\UnitOfWork\Exception\ObjectNotSupported;
-use Streak\Infrastructure\Domain\UnitOfWorkTest\NonVersionableEventSourcedStub;
-use Streak\Infrastructure\Domain\UnitOfWorkTest\VersionableEventSourcedStub;
/**
* @author Alan Gabriel Bem
@@ -69,7 +69,7 @@ public function testObject(): void
$uow = new EventStoreUnitOfWork($this->store);
self::assertEmpty($uow->uncommitted());
- self::assertEquals(0, $uow->count());
+ self::assertSame(0, $uow->count());
self::assertFalse($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertFalse($uow->has($object3));
@@ -78,7 +78,7 @@ public function testObject(): void
$uow->remove($object1);
self::assertEmpty($uow->uncommitted());
- self::assertEquals(0, $uow->count());
+ self::assertSame(0, $uow->count());
self::assertFalse($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertFalse($uow->has($object3));
@@ -87,7 +87,7 @@ public function testObject(): void
$uow->add($object1);
self::assertSame([$object1], $uow->uncommitted());
- self::assertEquals(1, $uow->count());
+ self::assertSame(1, $uow->count());
self::assertTrue($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertFalse($uow->has($object3));
@@ -96,7 +96,7 @@ public function testObject(): void
$uow->add($object2);
self::assertSame([$object1, $object2], $uow->uncommitted());
- self::assertEquals(2, $uow->count());
+ self::assertSame(2, $uow->count());
self::assertTrue($uow->has($object1));
self::assertTrue($uow->has($object2));
self::assertFalse($uow->has($object3));
@@ -105,7 +105,7 @@ public function testObject(): void
$uow->remove($object2);
self::assertSame([$object1], $uow->uncommitted());
- self::assertEquals(1, $uow->count());
+ self::assertSame(1, $uow->count());
self::assertTrue($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertFalse($uow->has($object3));
@@ -114,7 +114,7 @@ public function testObject(): void
$uow->add($object3);
self::assertSame([$object1, $object3], $uow->uncommitted());
- self::assertEquals(2, $uow->count());
+ self::assertSame(2, $uow->count());
self::assertTrue($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertTrue($uow->has($object3));
@@ -123,7 +123,7 @@ public function testObject(): void
$uow->add($object4);
self::assertSame([$object1, $object3, $object4], $uow->uncommitted());
- self::assertEquals(3, $uow->count());
+ self::assertSame(3, $uow->count());
self::assertTrue($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertTrue($uow->has($object3));
@@ -159,7 +159,7 @@ public function testObject(): void
self::assertTrue($object1->commited());
self::assertFalse($object2->commited());
self::assertTrue($object3->commited());
- self::assertEquals(0, $uow->count());
+ self::assertSame(0, $uow->count());
self::assertFalse($uow->has($object1));
self::assertFalse($uow->has($object2));
self::assertFalse($uow->has($object3));
@@ -246,7 +246,7 @@ public function testError(): void
// retry
try {
iterator_to_array($uow->commit());
- } catch (\RuntimeException $exception3) {
+ } catch (\RuntimeException) {
self::fail();
} finally {
self::assertSame(0, $uow->count());
@@ -259,7 +259,7 @@ public function testError(): void
try {
iterator_to_array($uow->commit());
self::fail();
- } catch (ConcurrentWriteDetected $exception4) {
+ } catch (ConcurrentWriteDetected) {
self::assertSame(0, $uow->count());
self::assertFalse($uow->has($object1));
self::assertFalse($uow->has($object2));
@@ -282,23 +282,19 @@ public function testWrongObject(): void
}
}
-namespace Streak\Infrastructure\Domain\UnitOfWorkTest;
+namespace Streak\Infrastructure\Domain\EventStoreUnitOfWorkTest;
use Streak\Domain;
use Streak\Domain\Event;
use Streak\Domain\Versionable;
-class VersionableEventSourcedStub implements Event\Sourced, Versionable
+class VersionableEventSourcedStub implements Event\Producer, Event\Consumer, Event\Replayable, Versionable
{
- private Domain\Id $id;
- private int $version;
private array $events;
private bool $commited = false;
- public function __construct(Domain\Id $id, int $version, Event\Envelope ...$events)
+ public function __construct(private Domain\Id $id, private int $version, Event\Envelope ...$events)
{
- $this->id = $id;
- $this->version = $version;
$this->events = $events;
}
@@ -307,12 +303,7 @@ public function equals(object $object): bool
throw new \BadMethodCallException();
}
- public function lastReplayed(): ?Event\Envelope
- {
- throw new \BadMethodCallException();
- }
-
- public function producerId(): Domain\Id
+ public function id(): Domain\Id
{
return $this->id;
}
@@ -327,6 +318,16 @@ public function replay(Event\Stream $events): void
throw new \BadMethodCallException();
}
+ public function lastEvent(): ?Event\Envelope
+ {
+ throw new \BadMethodCallException();
+ }
+
+ public function applyEvent(Event\Envelope $event): void
+ {
+ throw new \BadMethodCallException();
+ }
+
public function version(): int
{
return $this->version;
@@ -343,14 +344,12 @@ public function commited(): bool
}
}
-class NonVersionableEventSourcedStub implements Event\Sourced
+class NonVersionableEventSourcedStub implements Event\Producer, Event\Consumer, Event\Replayable
{
- private Domain\Id $id;
private array $events;
- public function __construct(Domain\Id $id, Event\Envelope ...$events)
+ public function __construct(private Domain\Id $id, Event\Envelope ...$events)
{
- $this->id = $id;
$this->events = $events;
}
@@ -359,14 +358,14 @@ public function equals(object $object): bool
throw new \BadMethodCallException();
}
- public function lastReplayed(): ?Event\Envelope
+ public function id(): Domain\Id
{
- throw new \BadMethodCallException();
+ return $this->id;
}
- public function producerId(): Domain\Id
+ public function applyEvent(Event\Envelope $event): void
{
- return $this->id;
+ throw new \BadMethodCallException();
}
public function events(): array
diff --git a/tests/Infrastructure/Domain/UnitOfWork/Exception/ObjectNotSupportedTest.php b/tests/Infrastructure/Domain/UnitOfWork/Exception/ObjectNotSupportedTest.php
index 866cb0b5..65d0a1e3 100644
--- a/tests/Infrastructure/Domain/UnitOfWork/Exception/ObjectNotSupportedTest.php
+++ b/tests/Infrastructure/Domain/UnitOfWork/Exception/ObjectNotSupportedTest.php
@@ -27,6 +27,6 @@ public function testIt(): void
$exception = new ObjectNotSupported($object, $previous);
self::assertSame($object, $exception->object());
self::assertSame($previous, $exception->getPrevious());
- self::assertEquals('Object is not supported.', $exception->getMessage());
+ self::assertSame('Object is not supported.', $exception->getMessage());
}
}
diff --git a/tests/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWorkTest.php b/tests/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWorkTest.php
index 2e8d4830..6ea17054 100644
--- a/tests/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWorkTest.php
+++ b/tests/Infrastructure/Domain/UnitOfWork/SnapshottingUnitOfWorkTest.php
@@ -15,6 +15,7 @@
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
+use Streak\Domain\AggregateRoot;
use Streak\Domain\Event;
use Streak\Infrastructure\Domain\AggregateRoot\Snapshotter;
use Streak\Infrastructure\Domain\UnitOfWork;
@@ -34,11 +35,11 @@ class SnapshottingUnitOfWorkTest extends TestCase
private Event\Sourced\AggregateRoot $aggregateRoot1;
- private Event\Sourced\AggregateRoot\Id $aggregateRootId1;
+ private AggregateRoot\Id $aggregateRootId1;
private Event\Sourced\AggregateRoot $aggregateRoot2;
- private Event\Sourced\AggregateRoot\Id $aggregateRootId2;
+ private AggregateRoot\Id $aggregateRootId2;
protected function setUp(): void
{
@@ -46,9 +47,9 @@ protected function setUp(): void
$this->snapshotter = $this->getMockBuilder(Snapshotter::class)->getMockForAbstractClass();
$this->producer = $this->getMockBuilder(Event\Producer::class)->setMockClassName('s__producer')->getMockForAbstractClass();
$this->aggregateRoot1 = $this->getMockBuilder(Event\Sourced\AggregateRoot::class)->setMockClassName('s__ar1')->getMockForAbstractClass();
- $this->aggregateRootId1 = $this->getMockBuilder(Event\Sourced\AggregateRoot\Id::class)->getMockForAbstractClass();
+ $this->aggregateRootId1 = $this->getMockBuilder(AggregateRoot\Id::class)->getMockForAbstractClass();
$this->aggregateRoot2 = $this->getMockBuilder(Event\Sourced\AggregateRoot::class)->setMockClassName('s__ar2')->getMockForAbstractClass();
- $this->aggregateRootId2 = $this->getMockBuilder(Event\Sourced\AggregateRoot\Id::class)->getMockForAbstractClass();
+ $this->aggregateRootId2 = $this->getMockBuilder(AggregateRoot\Id::class)->getMockForAbstractClass();
}
public function testObject(): void
@@ -57,12 +58,12 @@ public function testObject(): void
$this->producer
->expects(self::never()) // we do not handle this type of object
- ->method('producerId')
+ ->method('id')
;
$this->aggregateRoot1
->expects(self::atLeastOnce())
- ->method('producerId')
+ ->method('id')
->willReturn($this->aggregateRootId1)
;
@@ -78,7 +79,7 @@ public function testObject(): void
$this->aggregateRoot2
->expects(self::atLeastOnce())
- ->method('producerId')
+ ->method('id')
->willReturn($this->aggregateRootId2)
;
@@ -237,7 +238,7 @@ public function testCommitInterval(int $beforeVersion, int $afterVersion, int $s
$this->aggregateRoot1
->expects(self::atLeastOnce())
- ->method('producerId')
+ ->method('id')
->willReturn($this->aggregateRootId1)
;
@@ -276,7 +277,7 @@ public function commitIntervalProvider(): array
*/
public function testItDoesNotCreateWithWrongInterval(int $interval): void
{
- self::expectException(InvalidArgumentException::class);
+ $this->expectException(InvalidArgumentException::class);
new SnapshottingUnitOfWork($this->uow, $this->snapshotter, 0);
}
diff --git a/tests/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWorkTest.php b/tests/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWorkTest.php
index f310a5d1..c5437792 100644
--- a/tests/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWorkTest.php
+++ b/tests/Infrastructure/Domain/UnitOfWork/SubscriptionDAOUnitOfWorkTest.php
@@ -54,14 +54,14 @@ public function testItAddsDecorator(): void
public function testItDoesNotAddsNotSupportedSubscription(): void
{
$subscription = $this->getMockBuilder(Subscription::class)->getMock();
- self::expectException(ObjectNotSupported::class);
+ $this->expectException(ObjectNotSupported::class);
$this->uow->add($subscription);
}
public function testHasOnNotSupportedObject(): void
{
$subscription = $this->getMockBuilder(Subscription::class)->getMock();
- self::expectException(ObjectNotSupported::class);
+ $this->expectException(ObjectNotSupported::class);
$this->uow->has($subscription);
}
@@ -69,11 +69,11 @@ public function testItRemoves(): void
{
$subscription = $this->createSubscriptionStub('1');
$this->uow->add($subscription);
- self::assertEquals(1, $this->uow->count());
+ self::assertSame(1, $this->uow->count());
$this->uow->remove($subscription);
self::assertFalse($this->uow->has($subscription));
self::assertEmpty($this->uow->uncommitted());
- self::assertEquals(0, $this->uow->count());
+ self::assertSame(0, $this->uow->count());
}
public function testItRemovesNonExistedSubscription(): void
@@ -87,7 +87,7 @@ public function testItRemovesNonExistedSubscription(): void
public function testItDoesNotRemoveNotSupportedSubscription(): void
{
$subscription = $this->getMockBuilder(Subscription::class)->getMock();
- self::expectException(ObjectNotSupported::class);
+ $this->expectException(ObjectNotSupported::class);
$this->uow->remove($subscription);
}
@@ -106,7 +106,7 @@ public function testItCommitsWithException(): void
$subscription = $this->createSubscriptionStub('1');
$this->uow->add($subscription);
$this->dao->expects(self::once())->method('save')->with($subscription)->willThrowException(new \Exception());
- self::expectException(\Exception::class);
+ $this->expectException(\Exception::class);
iterator_to_array($this->uow->commit());
self::assertEquals([$subscription], $this->uow->uncommitted());
}
@@ -118,7 +118,7 @@ private function createSubscriptionDecoratorStub(string $id): Subscription\Decor
{
$result = $this->getMockBuilder(DecoratedSubscription::class)->getMock();
$result->method('subscription')->willReturn($this->createSubscriptionStub($id));
- $result->method('subscriptionId')->willReturn($this->createIdStub($id));
+ $result->method('id')->willReturn($this->createIdStub($id));
return $result;
}
@@ -129,7 +129,7 @@ private function createSubscriptionDecoratorStub(string $id): Subscription\Decor
private function createSubscriptionStub(string $id): DAO\Subscription
{
$result = $this->getMockBuilder(DAO\Subscription::class)->disableOriginalConstructor()->getMock();
- $result->method('subscriptionId')->willReturn($this->createIdStub($id));
+ $result->method('id')->willReturn($this->createIdStub($id));
return $result;
}
diff --git a/tests/Infrastructure/Serializer/PhpSerializerTest.php b/tests/Infrastructure/Serializer/PhpSerializerTest.php
index 300c447e..26ef4acb 100644
--- a/tests/Infrastructure/Serializer/PhpSerializerTest.php
+++ b/tests/Infrastructure/Serializer/PhpSerializerTest.php
@@ -34,7 +34,7 @@ public function testSerialize($value): void
$serialized = $serializer->serialize($value);
$unserialized = $serializer->unserialize($serialized);
- self::assertEquals(serialize($value), $serialized);
+ self::assertSame(serialize($value), $serialized);
self::assertEquals(unserialize($serialized), $unserialized);
self::assertEquals($value, $unserialized);
}