Skip to content

Commit

Permalink
A player can join a memory game #15
Browse files Browse the repository at this point in the history
  • Loading branch information
marein committed Sep 22, 2018
1 parent ba6335b commit ab22f1d
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
75 changes: 75 additions & 0 deletions code/src/Memory/Domain/Model/Game/Event/PlayerJoined.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
declare(strict_types=1);

namespace Gambling\Memory\Domain\Model\Game\Event;

use Gambling\Common\Clock\Clock;
use Gambling\Common\Domain\DomainEvent;
use Gambling\Memory\Domain\Model\Game\GameId;
use Gambling\Memory\Domain\Model\Game\Player;

final class PlayerJoined implements DomainEvent
{
/**
* @var GameId
*/
private $gameId;

/**
* @var Player
*/
private $player;

/**
* @var \DateTimeImmutable
*/
private $occurredOn;

/**
* PlayerJoined constructor.
*
* @param GameId $gameId
* @param Player $player
*/
public function __construct(GameId $gameId, Player $player)
{
$this->gameId = $gameId;
$this->player = $player;
$this->occurredOn = Clock::instance()->now();
}

/**
* @inheritdoc
*/
public function aggregateId(): string
{
return $this->gameId->toString();
}

/**
* @inheritdoc
*/
public function payload(): array
{
return [
'gameId' => $this->gameId->toString(),
'playerId' => $this->player->id()
];
}

/**
* @inheritdoc
*/
public function occurredOn(): \DateTimeImmutable
{
return $this->occurredOn;
}

/**
* @inheritdoc
*/
public function name(): string
{
return 'PlayerJoined';
}
}
23 changes: 23 additions & 0 deletions code/src/Memory/Domain/Model/Game/Game.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Gambling\Common\Domain\IsAggregateRoot;
use Gambling\Memory\Domain\Model\Game\Dealer\Dealer;
use Gambling\Memory\Domain\Model\Game\Event\GameOpened;
use Gambling\Memory\Domain\Model\Game\Event\PlayerJoined;
use Gambling\Memory\Domain\Model\Game\Exception\PlayerAlreadyJoinedException;

/**
* Unlike in the connect four context, this game does not use the state pattern.
Expand Down Expand Up @@ -85,4 +87,25 @@ public static function open(Dealer $dealer, string $playerId): Game
]
);
}

/**
* A player joins in the game.
*
* @param string $playerId
*
* @throws PlayerAlreadyJoinedException
*/
public function join(string $playerId): void
{
$player = new Player($playerId);
$playerJoined = new PlayerJoined(
$this->gameId,
$player
);

$this->playerPool = $this->playerPool->join(
new Player($playerId)
);
$this->domainEvents[] = $playerJoined;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);

namespace Gambling\Memory\Domain\Model\Game\Event;

use Gambling\Common\Clock\Clock;
use Gambling\Memory\Domain\Model\Game\GameId;
use Gambling\Memory\Domain\Model\Game\Player;
use PHPUnit\Framework\TestCase;

final class PlayerJoinedTest extends TestCase
{
/**
* @test
*/
public function itShouldBeCreatedWithItsValues(): void
{
Clock::instance()->freeze();

$gameId = GameId::generate();
$playerId = 'playerId';
$payload = [
'gameId' => $gameId->toString(),
'playerId' => $playerId
];

$playerJoined = new PlayerJoined(
$gameId,
new Player($playerId)
);

$this->assertSame('PlayerJoined', $playerJoined->name());
$this->assertSame($gameId->toString(), $playerJoined->aggregateId());
$this->assertSame(Clock::instance()->now(), $playerJoined->occurredOn());
$this->assertSame($payload, $playerJoined->payload());

Clock::instance()->resume();
}
}
36 changes: 36 additions & 0 deletions code/tests/unit/Memory/Domain/Model/Game/GameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Gambling\Memory\Domain\Model\Game\Dealer\LazyDealer;
use Gambling\Memory\Domain\Model\Game\Event\GameOpened;
use Gambling\Memory\Domain\Model\Game\Event\PlayerJoined;
use PHPUnit\Framework\TestCase;

class GameTest extends TestCase
Expand All @@ -28,4 +29,39 @@ public function aGameCanBeOpened(): void
$this->assertSame(10, $gameOpened->payload()['numberOfCards']);
$this->assertSame('playerId1', $gameOpened->payload()['playerId']);
}

/**
* @test
*/
public function aPlayerCanJoin(): void
{
$game = $this->createOpenGame();

$game->join('playerId2');

$domainEvents = $game->flushDomainEvents();
$playerJoined = $domainEvents[0];

$this->assertCount(1, $domainEvents);
$this->assertInstanceOf(PlayerJoined::class, $playerJoined);
$this->assertSame($game->id()->toString(), $playerJoined->aggregateId());
$this->assertSame('playerId2', $playerJoined->payload()['playerId']);
}

/**
* Returns an open game ready for testing.
*
* @return Game
*/
private function createOpenGame(): Game
{
$game = Game::open(
new LazyDealer(5),
'playerId1'
);

$game->flushDomainEvents();

return $game;
}
}

0 comments on commit ab22f1d

Please sign in to comment.