Skip to content

Commit

Permalink
Update asserts and deps
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHash committed Jun 11, 2020
1 parent 977f82b commit f4c7d5c
Show file tree
Hide file tree
Showing 22 changed files with 496 additions and 144 deletions.
1 change: 0 additions & 1 deletion composer.json
Expand Up @@ -9,7 +9,6 @@
"minimum-stability": "dev",
"require": {
"php": "^7.4",
"beberlei/assert": "^3.0",
"daikon/interop": "master@dev",
"daikon/message-bus": "master@dev",
"daikon/metadata": "master@dev",
Expand Down
494 changes: 425 additions & 69 deletions composer.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions psalm.xml
Expand Up @@ -39,6 +39,7 @@
<MissingConstructor errorLevel="info" />
<MissingClosureParamType errorLevel="info" />
<MissingParamType errorLevel="info" />
<MixedClone errorLevel="suppress" />

<RedundantCondition errorLevel="info" />

Expand Down
1 change: 0 additions & 1 deletion src/Aggregate/AggregateIdInterface.php
Expand Up @@ -12,5 +12,4 @@

interface AggregateIdInterface extends ValueObjectInterface
{
public function __toString(): string;
}
8 changes: 5 additions & 3 deletions src/Aggregate/AggregateIdTrait.php
Expand Up @@ -8,7 +8,7 @@

namespace Daikon\EventSourcing\Aggregate;

use Assert\Assertion;
use Daikon\Interop\Assertion;

trait AggregateIdTrait
{
Expand All @@ -17,7 +17,9 @@ trait AggregateIdTrait
/** @param string $id */
public static function fromNative($id): self
{
Assertion::regex($id, static::PATTERN);
if (defined('static::PATTERN')) {
Assertion::regex($id, static::PATTERN);
}
return new static($id);
}

Expand All @@ -26,7 +28,7 @@ public function toNative(): string
return $this->id;
}

/** @param self $comparator */
/** @param static $comparator */
public function equals($comparator): bool
{
Assertion::isInstanceOf($comparator, static::class);
Expand Down
3 changes: 2 additions & 1 deletion src/Aggregate/AggregateRevision.php
Expand Up @@ -9,9 +9,10 @@
namespace Daikon\EventSourcing\Aggregate;

use Assert\Assertion;
use Daikon\Interop\MakeEmptyInterface;
use Daikon\ValueObject\ValueObjectInterface;

final class AggregateRevision implements ValueObjectInterface
final class AggregateRevision implements MakeEmptyInterface, ValueObjectInterface
{
private const INITIAL = 1;

Expand Down
14 changes: 8 additions & 6 deletions src/Aggregate/AggregateRootTrait.php
Expand Up @@ -8,10 +8,10 @@

namespace Daikon\EventSourcing\Aggregate;

use Assert\Assertion;
use Daikon\EventSourcing\Aggregate\Event\DomainEventInterface;
use Daikon\EventSourcing\Aggregate\Event\DomainEventSequence;
use Daikon\EventSourcing\Aggregate\Event\DomainEventSequenceInterface;
use Daikon\Interop\Assertion;
use Daikon\Interop\RuntimeException;
use ReflectionClass;

Expand Down Expand Up @@ -81,7 +81,7 @@ private function reconstitute(DomainEventInterface $historicalEvent): self
private function assertExpectedRevision(DomainEventInterface $event, AggregateRevision $expectedRevision): void
{
Assertion::true($expectedRevision->equals($event->getAggregateRevision()), sprintf(
'Given event revision %s does not match expected AR revision at %s',
'Given event revision %s does not match expected AR revision at %s.',
(string)$event->getAggregateRevision(),
(string)$expectedRevision
));
Expand All @@ -90,7 +90,7 @@ private function assertExpectedRevision(DomainEventInterface $event, AggregateRe
private function assertExpectedIdentifier(DomainEventInterface $event, AggregateIdInterface $expectedId): void
{
Assertion::true($expectedId->equals($event->getAggregateId()), sprintf(
'Given event identifier %s does not match expected AR identifier at %s',
'Given event identifier %s does not match expected AR identifier at %s.',
(string)$event->getAggregateId(),
(string)$expectedId
));
Expand All @@ -100,10 +100,12 @@ private function invokeEventHandler(DomainEventInterface $event): void
{
$handlerName = preg_replace('/Event$/', '', (new ReflectionClass($event))->getShortName());
$handlerMethod = 'when'.ucfirst($handlerName);
$handler = [ $this, $handlerMethod ];
$handler = [$this, $handlerMethod];
if (!is_callable($handler)) {
throw new RuntimeException(sprintf('Handler "%s" is not callable on '.static::class, $handlerMethod));
throw new RuntimeException(
sprintf("Handler '%s' is not callable on '%s'.", $handlerMethod, static::class)
);
}
call_user_func($handler, $event);
$handler($event);
}
}
4 changes: 2 additions & 2 deletions src/Aggregate/AnnotatesAggregate.php
Expand Up @@ -8,7 +8,7 @@

namespace Daikon\EventSourcing\Aggregate;

use Daikon\Interop\RuntimeException;
use Daikon\Interop\InvalidArgumentException;
use ReflectionClass;

trait AnnotatesAggregate
Expand Down Expand Up @@ -41,6 +41,6 @@ private static function getAnnotation(string $key): string
}
}

throw new RuntimeException("Missing @$key annotation on ".static::class);
throw new InvalidArgumentException(sprintf("Missing @%s annotation on '%s'.", $key, static::class));
}
}
6 changes: 4 additions & 2 deletions src/Aggregate/Command/CommandHandler.php
Expand Up @@ -40,9 +40,11 @@ public function handle(EnvelopeInterface $envelope): void
$handlerMethod = 'handle'.ucfirst($handlerName);
$handler = [$this, $handlerMethod];
if (!is_callable($handler)) {
throw new RuntimeException(sprintf('Handler "%s" is not callable on '.static::class, $handlerMethod));
throw new RuntimeException(
sprintf("Handler '%s' is not callable on '%s'.", $handlerMethod, static::class)
);
}
$this->commit(...call_user_func($handler, $commandMessage, $envelope->getMetadata()));
$this->commit(...$handler($commandMessage, $envelope->getMetadata()));
}

protected function commit(AggregateRootInterface $aggregateRoot, MetadataInterface $metadata): void
Expand Down
20 changes: 8 additions & 12 deletions src/Aggregate/Event/DomainEventSequence.php
Expand Up @@ -9,9 +9,9 @@
namespace Daikon\EventSourcing\Aggregate\Event;

use Daikon\EventSourcing\Aggregate\AggregateRevision;
use Daikon\Interop\Assertion;
use Daikon\Interop\RuntimeException;
use Ds\Vector;
use InvalidArgumentException;

final class DomainEventSequence implements DomainEventSequenceInterface
{
Expand All @@ -20,10 +20,10 @@ final class DomainEventSequence implements DomainEventSequenceInterface
/** @param array $events */
public static function fromNative($events): self
{
return new self(array_map(function (array $state): DomainEventInterface {
$eventFqcn = self::resolveEventFqcn($state);
return call_user_func([$eventFqcn, 'fromNative'], $state);
}, $events));
return new self(array_map(
fn(array $state): DomainEventInterface => ([self::resolveEventFqcn($state), 'fromNative'])($state),
$events
));
}

public static function makeEmpty(): self
Expand All @@ -43,7 +43,7 @@ public function push(DomainEventInterface $event): self
$expectedRevision = $this->getHeadRevision()->increment();
if (!$this->isEmpty() && !$expectedRevision->equals($event->getAggregateRevision())) {
throw new RuntimeException(sprintf(
'Trying to add invalid revision %s to event-sequence, expected revision is %s',
'Trying to add invalid revision %s to event-sequence, expected revision is %s.',
(string)$event->getAggregateRevision(),
(string)$expectedRevision
));
Expand Down Expand Up @@ -131,13 +131,9 @@ public function getIterator(): Vector

private static function resolveEventFqcn(array $eventState): string
{
if (!isset($eventState['@type'])) {
throw new InvalidArgumentException("Missing expected key '@type' within given state array.");
}
Assertion::keyIsset($eventState, '@type', "Missing expected key '@type' within given state array.");
$eventFqcn = $eventState['@type'];
if (!class_exists($eventFqcn)) {
throw new InvalidArgumentException("Cannot find event class '$eventFqcn' given within state array.");
}
Assertion::classExists($eventFqcn, "Cannot find event class '$eventFqcn' given within state array.");
return $eventFqcn;
}

Expand Down
12 changes: 7 additions & 5 deletions src/Aggregate/Event/DomainEventSequenceInterface.php
Expand Up @@ -11,13 +11,17 @@
use Countable;
use Daikon\EventSourcing\Aggregate\AggregateRevision;
use Daikon\Interop\FromNativeInterface;
use Daikon\Interop\MakeEmptyInterface;
use Daikon\Interop\ToNativeInterface;
use IteratorAggregate;

interface DomainEventSequenceInterface extends IteratorAggregate, Countable, FromNativeInterface, ToNativeInterface
interface DomainEventSequenceInterface extends
IteratorAggregate,
Countable,
MakeEmptyInterface,
FromNativeInterface,
ToNativeInterface
{
public static function makeEmpty(): self;

public function push(DomainEventInterface $event): self;

public function append(DomainEventSequenceInterface $events): self;
Expand All @@ -32,8 +36,6 @@ public function getTail(): DomainEventInterface;

public function getHead(): DomainEventInterface;

public function isEmpty(): bool;

/** @return int|bool */
public function indexOf(DomainEventInterface $event);
}
1 change: 1 addition & 0 deletions src/Aggregate/Event/DomainEventTrait.php
Expand Up @@ -20,6 +20,7 @@ public function getAggregateRevision(): AggregateRevision
return $this->{static::getAnnotatedRevision()};
}

/** @return static */
public function withAggregateRevision(AggregateRevision $aggregateRevision): self
{
$copy = clone $this;
Expand Down
2 changes: 1 addition & 1 deletion src/EventStore/Commit/Commit.php
Expand Up @@ -10,13 +10,13 @@

namespace Daikon\EventSourcing\EventStore\Commit;

use Assert\Assertion;
use Daikon\EventSourcing\Aggregate\AggregateId;
use Daikon\EventSourcing\Aggregate\AggregateIdInterface;
use Daikon\EventSourcing\Aggregate\AggregateRevision;
use Daikon\EventSourcing\Aggregate\Event\DomainEventSequence;
use Daikon\EventSourcing\Aggregate\Event\DomainEventSequenceInterface;
use Daikon\EventSourcing\EventStore\Stream\Sequence;
use Daikon\Interop\Assertion;
use Daikon\Metadata\Metadata;
use Daikon\Metadata\MetadataInterface;
use DateTimeImmutable;
Expand Down
5 changes: 2 additions & 3 deletions src/EventStore/Commit/CommitSequence.php
Expand Up @@ -43,7 +43,7 @@ public function push(CommitInterface $commit): self
$nextRevision = $this->getHead()->getHeadRevision()->increment();
if (!$nextRevision->equals($commit->getTailRevision())) {
throw new RuntimeException(sprintf(
'Trying to add invalid revision %s to event-sequence, expected revision is %s',
'Trying to add invalid revision %s to event-sequence, expected revision is %s.',
(string)$commit->getHeadRevision(),
(string)$nextRevision
));
Expand Down Expand Up @@ -78,8 +78,7 @@ public function getHead(): CommitInterface
public function has(Sequence $sequence): bool
{
$offset = $sequence->toNative() - 1;
/** @psalm-suppress UndefinedMethod */
return isset($this->compositeVector[$offset]);
return isset($this->compositeVector->{$offset});
}

public function get(Sequence $sequence): CommitInterface
Expand Down
12 changes: 7 additions & 5 deletions src/EventStore/Commit/CommitSequenceInterface.php
Expand Up @@ -11,13 +11,17 @@
use Countable;
use Daikon\EventSourcing\EventStore\Stream\Sequence;
use Daikon\Interop\FromNativeInterface;
use Daikon\Interop\MakeEmptyInterface;
use Daikon\Interop\ToNativeInterface;
use IteratorAggregate;

interface CommitSequenceInterface extends IteratorAggregate, Countable, FromNativeInterface, ToNativeInterface
interface CommitSequenceInterface extends
IteratorAggregate,
Countable,
MakeEmptyInterface,
FromNativeInterface,
ToNativeInterface
{
public static function makeEmpty(): self;

public function push(CommitInterface $commit): self;

public function getTail(): CommitInterface;
Expand All @@ -30,7 +34,5 @@ public function has(Sequence $Sequence): bool;

public function getSlice(Sequence $start, Sequence $end): self;

public function isEmpty(): bool;

public function revisionOf(CommitInterface $commit): Sequence;
}
6 changes: 3 additions & 3 deletions src/EventStore/ConcurrencyRaceLost.php
Expand Up @@ -10,9 +10,9 @@

use Daikon\EventSourcing\Aggregate\Event\DomainEventSequenceInterface;
use Daikon\EventSourcing\Aggregate\AggregateIdInterface;
use Exception;
use Daikon\Interop\RuntimeException;

final class ConcurrencyRaceLost extends Exception
final class ConcurrencyRaceLost extends RuntimeException
{
private AggregateIdInterface $aggregateId;

Expand All @@ -22,7 +22,7 @@ public function __construct(AggregateIdInterface $aggregateId, DomainEventSequen
{
$this->aggregateId = $aggregateId;
$this->lostEvents = $lostEvents;
parent::__construct('Unable to catchup on stream: ' . $this->aggregateId);
parent::__construct('Unable to catchup on stream '.$this->aggregateId);
}

public function getAggregateId(): AggregateIdInterface
Expand Down
7 changes: 2 additions & 5 deletions src/EventStore/Storage/StreamStorageMap.php
Expand Up @@ -8,13 +8,10 @@

namespace Daikon\EventSourcing\EventStore\Storage;

use Daikon\DataStructure\TypedMapInterface;
use Daikon\DataStructure\TypedMapTrait;
use Daikon\DataStructure\TypedMap;

final class StreamStorageMap implements TypedMapInterface
final class StreamStorageMap extends TypedMap
{
use TypedMapTrait;

public function __construct(iterable $streamStores = [])
{
$this->init($streamStores, [StreamStorageInterface::class]);
Expand Down
5 changes: 2 additions & 3 deletions src/EventStore/Stream/Stream.php
Expand Up @@ -8,7 +8,6 @@

namespace Daikon\EventSourcing\EventStore\Stream;

use Assert\Assertion;
use Daikon\EventSourcing\Aggregate\AggregateId;
use Daikon\EventSourcing\Aggregate\AggregateIdInterface;
use Daikon\EventSourcing\Aggregate\AggregateRevision;
Expand All @@ -17,6 +16,7 @@
use Daikon\EventSourcing\EventStore\Commit\CommitInterface;
use Daikon\EventSourcing\EventStore\Commit\CommitSequence;
use Daikon\EventSourcing\EventStore\Commit\CommitSequenceInterface;
use Daikon\Interop\Assertion;
use Daikon\Metadata\MetadataInterface;
use Ds\Vector;

Expand Down Expand Up @@ -72,8 +72,7 @@ public function getHeadRevision(): AggregateRevision
public function appendEvents(DomainEventSequenceInterface $eventLog, MetadataInterface $metadata): self
{
return $this->appendCommit(
call_user_func(
[$this->commitImplementor, 'make'],
([$this->commitImplementor, 'make'])(
$this->aggregateId,
$this->getHeadSequence()->increment(),
$eventLog,
Expand Down
8 changes: 3 additions & 5 deletions src/EventStore/Stream/StreamMap.php
Expand Up @@ -8,15 +8,13 @@

namespace Daikon\EventSourcing\EventStore\Stream;

use Daikon\DataStructure\TypedMapInterface;
use Daikon\DataStructure\TypedMapTrait;
use Daikon\DataStructure\TypedMap;
use Daikon\EventSourcing\Aggregate\AggregateIdInterface;
use Daikon\Interop\MakeEmptyInterface;
use Daikon\Interop\ToNativeInterface;

final class StreamMap implements TypedMapInterface, ToNativeInterface
final class StreamMap extends TypedMap implements MakeEmptyInterface, ToNativeInterface
{
use TypedMapTrait;

public function __construct(iterable $streams = [])
{
$this->init($streams, [StreamInterface::class]);
Expand Down

0 comments on commit f4c7d5c

Please sign in to comment.