feat: validate and resolve unit movement

This commit is contained in:
Keith Solomon
2026-07-04 15:37:05 -05:00
parent 5297b41208
commit 1550e2920b
3 changed files with 125 additions and 0 deletions
+56
View File
@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace BattleForge\Tests\Unit\Domain;
use BattleForge\Domain\Battlefield;
use BattleForge\Domain\CombatEngine;
use BattleForge\Domain\CombatException;
use BattleForge\Domain\MatchState;
use BattleForge\Domain\Position;
use BattleForge\Domain\UnitState;
@@ -25,6 +27,60 @@ final class CombatEngineTest extends TestCase
self::assertSame(1, $next->unit('unit-1')->actionsRemaining);
}
public function testMoveUpdatesUnitAndAppendsActionLogWithoutMutatingMatch(): void
{
$match = new MatchState(
new Battlefield(8, 8),
[
$this->unit('alpha-1', 'alpha', new Position(0, 0)),
$this->unit('bravo-1', 'bravo', new Position(7, 7)),
],
'alpha',
);
$next = (new CombatEngine())->move($match, 'alpha-1', new Position(2, 0));
self::assertSame('0:0', $match->unit('alpha-1')->position->key());
self::assertSame('2:0', $next->unit('alpha-1')->position->key());
self::assertSame(1, $next->unit('alpha-1')->actionsRemaining);
self::assertSame(['alpha-1 moved to 2:0'], $next->actionLog);
}
public function testMoveRejectsUnitFromInactiveTeam(): void
{
$match = new MatchState(
new Battlefield(8, 8),
[
$this->unit('alpha-1', 'alpha', new Position(0, 0)),
$this->unit('bravo-1', 'bravo', new Position(7, 7)),
],
'alpha',
);
$this->expectException(CombatException::class);
$this->expectExceptionMessage("It is not this unit's turn.");
(new CombatEngine())->move($match, 'bravo-1', new Position(6, 7));
}
public function testMoveRejectsOccupiedDestination(): void
{
$match = new MatchState(
new Battlefield(8, 8),
[
$this->unit('alpha-1', 'alpha', new Position(0, 0)),
$this->unit('alpha-2', 'alpha', new Position(1, 0)),
$this->unit('bravo-1', 'bravo', new Position(7, 7)),
],
'alpha',
);
$this->expectException(CombatException::class);
$this->expectExceptionMessage('Destination is not reachable.');
(new CombatEngine())->move($match, 'alpha-1', new Position(1, 0));
}
private function unit(string $id, string $team, Position $position): UnitState
{
return new UnitState($id, $team, $position, 10, 10, 4, 2, 4, 2);