Skip to content

Commit

Permalink
update docs and add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBadura committed Mar 8, 2024
1 parent f31829f commit bb6fcc9
Show file tree
Hide file tree
Showing 6 changed files with 357 additions and 2 deletions.
3 changes: 2 additions & 1 deletion docs/pages/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ use Doctrine\DBAL\DriverManager;
use Patchlevel\EventSourcing\EventBus\DefaultEventBus;
use Patchlevel\EventSourcing\Projection\Projection\Store\DoctrineStore;
use Patchlevel\EventSourcing\Projection\Projectionist\DefaultProjectionist;
use Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorAccessorRepository;
use Patchlevel\EventSourcing\Repository\DefaultRepositoryManager;
use Patchlevel\EventSourcing\Serializer\DefaultEventSerializer;
use Patchlevel\EventSourcing\Store\DoctrineDbalStore;
Expand All @@ -306,7 +307,7 @@ $eventStore = new DoctrineDbalStore(

$hotelProjector = new HotelProjector($projectionConnection);

$projectorRepository = new ProjectorRepository([
$projectorRepository = new MetadataProjectorAccessorRepository([
$hotelProjector,
]);

Expand Down
13 changes: 12 additions & 1 deletion docs/pages/projection.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,17 @@ $retryStrategy = new ClockBasedRetryStrategy(

You can reactivate the projection manually or remove it and rebuild it from scratch.

### Projector Accessor

The projector accessor is responsible for providing the projectors to the projectionist.
We provide a metadata projector accessor repository by default.

```php
use Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorAccessorRepository;

$projectorAccessorRepository = new MetadataProjectorAccessorRepository([$projector1, $projector2, $projector3]);
```

### Projectionist

Now we can create the projectionist and plug together the necessary services.
Expand All @@ -481,7 +492,7 @@ use Patchlevel\EventSourcing\Projection\Projectionist\DefaultProjectionist;
$projectionist = new DefaultProjectionist(
$eventStore,
$projectionStore,
[$projector1, $projector2, $projector3],
$projectorAccessorRepository,
$retryStrategy,
);
```
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Unit\Projection\Projector;

use Patchlevel\EventSourcing\Attribute\Projector;
use Patchlevel\EventSourcing\Metadata\Projector\AttributeProjectorMetadataFactory;
use Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorAccessor;
use Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorAccessorRepository;
use PHPUnit\Framework\TestCase;

final class MetadataProjectorAccessorRepositoryTest extends TestCase
{
public function testEmpty(): void
{
$repository = new MetadataProjectorAccessorRepository(
[],
);

self::assertEquals([], $repository->all());
self::assertNull($repository->get('foo'));
}

public function testWithProjector(): void
{
$projector = new #[Projector('foo')]
class {
};
$metadataFactory = new AttributeProjectorMetadataFactory();

$repository = new MetadataProjectorAccessorRepository(
[$projector],
$metadataFactory,
);

$accessor = new MetadataProjectorAccessor(
$projector,
$metadataFactory->metadata($projector::class),
);

self::assertEquals([$accessor], $repository->all());
self::assertEquals($accessor, $repository->get('foo'));
}
}
206 changes: 206 additions & 0 deletions tests/Unit/Projection/Projector/MetadataProjectorAccessorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Unit\Projection\Projector;

use Patchlevel\EventSourcing\Attribute\Projector;
use Patchlevel\EventSourcing\Attribute\Setup;
use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\Attribute\Teardown;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\Metadata\Projector\AttributeProjectorMetadataFactory;
use Patchlevel\EventSourcing\Projection\Projection\RunMode;
use Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorAccessor;
use Patchlevel\EventSourcing\Tests\Unit\Fixture\ProfileCreated;
use PHPUnit\Framework\TestCase;

/** @covers \Patchlevel\EventSourcing\Projection\Projector\MetadataProjectorAccessor */
final class MetadataProjectorAccessorTest extends TestCase
{
public function testId(): void
{
$projector = new #[Projector('profile')]
class {
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

self::assertEquals('profile', $accessor->id());
}

public function testGroup(): void
{
$projector = new #[Projector('profile')]
class {
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

self::assertEquals('default', $accessor->group());
}

public function testRunMode(): void
{
$projector = new #[Projector('profile')]
class {
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

self::assertEquals(RunMode::FromBeginning, $accessor->runMode());
}

public function testSubscribeMethod(): void
{
$projector = new #[Projector('profile')]
class {
#[Subscribe(ProfileCreated::class)]
public function onProfileCreated(Message $message): void
{
}
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->subscribeMethods(ProfileCreated::class);

self::assertEquals([
$projector->onProfileCreated(...),
], $result);
}

public function testMultipleSubscribeMethod(): void
{
$projector = new #[Projector('profile')]
class {
#[Subscribe(ProfileCreated::class)]
public function onProfileCreated(Message $message): void
{
}

#[Subscribe(ProfileCreated::class)]
public function onFoo(Message $message): void
{
}
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->subscribeMethods(ProfileCreated::class);

self::assertEquals([
$projector->onProfileCreated(...),
$projector->onFoo(...),
], $result);
}

public function testSubscribeAllMethod(): void
{
$projector = new #[Projector('profile')]
class {
#[Subscribe('*')]
public function onProfileCreated(Message $message): void
{
}
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->subscribeMethods(ProfileCreated::class);

self::assertEquals([
$projector->onProfileCreated(...),
], $result);
}

public function testSetupMethod(): void
{
$projector = new #[Projector('profile')]
class {
#[Setup]
public function method(): void
{
}
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->setupMethod();

self::assertEquals($projector->method(...), $result);
}

public function testNotSetupMethod(): void
{
$projector = new #[Projector('profile')]
class {
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->setupMethod();

self::assertNull($result);
}

public function testTeardownMethod(): void
{
$projector = new #[Projector('profile')]
class {
#[Teardown]
public function method(): void
{
}
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->teardownMethod();

self::assertEquals($projector->method(...), $result);
}

public function testNotTeardownMethod(): void
{
$projector = new #[Projector('profile')]
class {
};

$accessor = new MetadataProjectorAccessor(
$projector,
(new AttributeProjectorMetadataFactory())->metadata($projector::class),
);

$result = $accessor->teardownMethod();

self::assertNull($result);
}
}
59 changes: 59 additions & 0 deletions tests/Unit/Repository/MessageDecorator/TraceDecoratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Unit\Repository\MessageDecorator;

use Patchlevel\EventSourcing\EventBus\HeaderNotFound;
use Patchlevel\EventSourcing\EventBus\Message;
use Patchlevel\EventSourcing\Repository\MessageDecorator\Trace;
use Patchlevel\EventSourcing\Repository\MessageDecorator\TraceDecorator;
use Patchlevel\EventSourcing\Repository\MessageDecorator\TraceHeader;
use Patchlevel\EventSourcing\Repository\MessageDecorator\TraceStack;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use stdClass;

/** @covers \Patchlevel\EventSourcing\Repository\MessageDecorator\TraceDecorator */
final class TraceDecoratorTest extends TestCase
{
use ProphecyTrait;

public function testWithoutTrace(): void
{
$this->expectException(HeaderNotFound::class);

$stack = new TraceStack();
$decorator = new TraceDecorator($stack);

$message = new Message(new stdClass());

$decoratedMessage = $decorator($message);

self::assertEquals($message, $decoratedMessage);

$decoratedMessage->header(TraceHeader::class);
}

public function testWithTrace(): void
{
$stack = new TraceStack();
$stack->add(new Trace('name', 'category'));

$decorator = new TraceDecorator($stack);

$message = new Message(new stdClass());

$decoratedMessage = $decorator($message);

self::assertEquals(
new TraceHeader([
[
'name' => 'name',
'category' => 'category',
],
]),
$decoratedMessage->header(TraceHeader::class),
);
}
}
33 changes: 33 additions & 0 deletions tests/Unit/Repository/MessageDecorator/TraceStackTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcing\Tests\Unit\Repository\MessageDecorator;

use Patchlevel\EventSourcing\Repository\MessageDecorator\Trace;
use Patchlevel\EventSourcing\Repository\MessageDecorator\TraceStack;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;

/** @covers \Patchlevel\EventSourcing\Repository\MessageDecorator\TraceStack */
final class TraceStackTest extends TestCase
{
use ProphecyTrait;

public function testStack(): void
{
$stack = new TraceStack();

self::assertEquals([], $stack->get());

$trace = new Trace('name', 'category');

$stack->add($trace);

self::assertEquals([$trace], $stack->get());

$stack->remove($trace);

self::assertEquals([], $stack->get());
}
}

0 comments on commit bb6fcc9

Please sign in to comment.