From 520fbc8c1160ebc72f5b9264d2f20d3cbf93961c Mon Sep 17 00:00:00 2001 From: David Badura Date: Thu, 21 Apr 2022 10:04:47 +0200 Subject: [PATCH] improve snapshot store apis --- Makefile | 2 +- phpunit.xml.dist | 1 - src/Aggregate/AggregateRoot.php | 13 ++++++------ src/Aggregate/MetadataNotPossible.php | 13 ++++++++++++ src/Snapshot/AdapterNotFound.php | 20 ++++++++++++++++++ src/Snapshot/DefaultSnapshotStore.php | 21 ++++++++++++------- tests/Unit/Aggregate/AggregateRootTest.php | 17 +++++++++++++++ .../Snapshot/DefaultSnapshotStoreTest.php | 17 +++++++++++++++ 8 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 src/Aggregate/MetadataNotPossible.php create mode 100644 src/Snapshot/AdapterNotFound.php diff --git a/Makefile b/Makefile index 68827aed..3e2e6c7a 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ psalm-baseline: vendor .PHONY: phpunit phpunit: vendor ## run phpunit tests - vendor/bin/phpunit --testdox --colors=always -v $(OPTIONS) + vendor/bin/phpunit --colors=always -v $(OPTIONS) .PHONY: infection infection: vendor ## run infection diff --git a/phpunit.xml.dist b/phpunit.xml.dist index bd5823b7..021ce531 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -26,7 +26,6 @@ - diff --git a/src/Aggregate/AggregateRoot.php b/src/Aggregate/AggregateRoot.php index 61d7ee3a..e711ddfa 100644 --- a/src/Aggregate/AggregateRoot.php +++ b/src/Aggregate/AggregateRoot.php @@ -29,7 +29,7 @@ abstract public function aggregateRootId(): string; protected function apply(object $event): void { - $metadata = self::metadata(static::class); + $metadata = self::metadata(); if (!array_key_exists($event::class, $metadata->applyMethods)) { if (!$metadata->suppressAll && !array_key_exists($event::class, $metadata->suppressEvents)) { @@ -93,16 +93,17 @@ final public function playhead(): int return $this->playhead; } - /** - * @param class-string $aggregateClass - */ - public static function metadata(string $aggregateClass): AggregateRootMetadata + public static function metadata(): AggregateRootMetadata { + if (static::class === self::class) { + throw new MetadataNotPossible(); + } + if (!self::$metadataFactory) { self::$metadataFactory = new AttributeAggregateRootMetadataFactory(); } - return self::$metadataFactory->metadata($aggregateClass); + return self::$metadataFactory->metadata(static::class); } public static function setMetadataFactory(AggregateRootMetadataFactory $metadataFactory): void diff --git a/src/Aggregate/MetadataNotPossible.php b/src/Aggregate/MetadataNotPossible.php new file mode 100644 index 00000000..dc96d885 --- /dev/null +++ b/src/Aggregate/MetadataNotPossible.php @@ -0,0 +1,13 @@ +getAdapter($aggregateClass); + $adapter = $this->adapter($aggregateClass); $adapter->save( $key, @@ -53,7 +54,7 @@ public function save(Snapshot $snapshot): void */ public function load(string $aggregateClass, string $id): Snapshot { - $adapter = $this->getAdapter($aggregateClass); + $adapter = $this->adapter($aggregateClass); $key = $this->key($aggregateClass, $id); try { @@ -80,15 +81,19 @@ public function freeMemory(): void /** * @param class-string $aggregateClass */ - private function getAdapter(string $aggregateClass): SnapshotAdapter + public function adapter(string $aggregateClass): SnapshotAdapter { - $snapshotName = $aggregateClass::metadata($aggregateClass)->snapshotStore; + $adapterName = $aggregateClass::metadata()->snapshotStore; - if (!$snapshotName) { + if (!$adapterName) { throw new SnapshotNotConfigured($aggregateClass); } - return $this->snapshotAdapters[$snapshotName]; + if (!array_key_exists($adapterName, $this->snapshotAdapters)) { + throw new AdapterNotFound($adapterName); + } + + return $this->snapshotAdapters[$adapterName]; } /** @@ -96,7 +101,7 @@ private function getAdapter(string $aggregateClass): SnapshotAdapter */ private function key(string $aggregateClass, string $aggregateId): string { - $aggregateName = $aggregateClass::metadata($aggregateClass)->name; + $aggregateName = $aggregateClass::metadata()->name; return sprintf('%s-%s', $aggregateName, $aggregateId); } @@ -104,7 +109,7 @@ private function key(string $aggregateClass, string $aggregateId): string private function shouldBeSaved(Snapshot $snapshot, string $key): bool { $aggregateClass = $snapshot->aggregate(); - $batchSize = $aggregateClass::metadata($snapshot->aggregate())->snapshotBatch; + $batchSize = $aggregateClass::metadata()->snapshotBatch; if (!$batchSize) { return true; diff --git a/tests/Unit/Aggregate/AggregateRootTest.php b/tests/Unit/Aggregate/AggregateRootTest.php index 53e8e441..b07d824e 100644 --- a/tests/Unit/Aggregate/AggregateRootTest.php +++ b/tests/Unit/Aggregate/AggregateRootTest.php @@ -5,9 +5,12 @@ namespace Patchlevel\EventSourcing\Tests\Unit\Aggregate; use DateTimeImmutable; +use Patchlevel\EventSourcing\Aggregate\AggregateRoot; use Patchlevel\EventSourcing\Aggregate\ApplyMethodNotFound; +use Patchlevel\EventSourcing\Aggregate\MetadataNotPossible; use Patchlevel\EventSourcing\Clock; use Patchlevel\EventSourcing\EventBus\Message as EventBusMessage; +use Patchlevel\EventSourcing\Metadata\AggregateRoot\AggregateRootMetadata; use Patchlevel\EventSourcing\Metadata\AggregateRoot\DuplicateApplyMethod; use Patchlevel\EventSourcing\Tests\Unit\Fixture\Email; use Patchlevel\EventSourcing\Tests\Unit\Fixture\Message; @@ -183,4 +186,18 @@ public function testDuplicateApplyMethods(): void ProfileInvalid::createProfile($profileId, $email); } + + public function testMetadata(): void + { + $metadata = Profile::metadata(); + + self::assertInstanceOf(AggregateRootMetadata::class, $metadata); + } + + public function testMetadataNotPossible(): void + { + $this->expectException(MetadataNotPossible::class); + + AggregateRoot::metadata(); + } } diff --git a/tests/Unit/Snapshot/DefaultSnapshotStoreTest.php b/tests/Unit/Snapshot/DefaultSnapshotStoreTest.php index 913046b4..16a14179 100644 --- a/tests/Unit/Snapshot/DefaultSnapshotStoreTest.php +++ b/tests/Unit/Snapshot/DefaultSnapshotStoreTest.php @@ -5,6 +5,7 @@ namespace Patchlevel\EventSourcing\Tests\Unit\Snapshot; use Patchlevel\EventSourcing\Snapshot\Adapter\SnapshotAdapter; +use Patchlevel\EventSourcing\Snapshot\AdapterNotFound; use Patchlevel\EventSourcing\Snapshot\DefaultSnapshotStore; use Patchlevel\EventSourcing\Snapshot\Snapshot; use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileWithSnapshot; @@ -157,4 +158,20 @@ public function testFreeMemory(): void $store->freeMemory(); $store->save($newSnapshot); } + + public function testAdapterIsMissing(): void + { + $this->expectException(AdapterNotFound::class); + + $store = new DefaultSnapshotStore([]); + $store->load(ProfileWithSnapshot::class, '1'); + } + + public function testGetAdapter(): void + { + $adapter = $this->prophesize(SnapshotAdapter::class)->reveal(); + $store = new DefaultSnapshotStore(['memory' => $adapter]); + + self::assertSame($adapter, $store->adapter(ProfileWithSnapshot::class)); + } }