Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 79 additions & 2 deletions Tests/Management/TileChangeManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,85 @@ public void TileChangeEvents()
[Test]
public void TileChangeEntityDestroyedDeregisterEvents()
{
// TODO: Issue 8 (https://github.com/Wizcorp/TileSystem/issues/8)
Assert.Fail();
// A tile manager should deregister an entity when it raises a Destroy event.

TileChangeManager manager = new TileChangeManager();

// Our mock entity should implement both IEntity (for raising Destroy) and IChangeTile (for performing movement)
Mock<IEntity> mockEntity = new Mock<IEntity>();
Mock<IChangeTile> mockMovable = mockEntity.As<IChangeTile>();

// Our mock creator is used only to create our mocked entity.
Mock<ICreateEntities> mockCreator = new Mock<ICreateEntities>();

// Two mocked tiles to move between
Mock<ITile> mockTileFrom = new Mock<ITile>();
Mock<ITile> mockTileTo = new Mock<ITile>();

// Our first mock solver will be checked to ensure it's receiving the events.
Mock<ISolver> mockSolverOne = new Mock<ISolver>();

// These tile change args classes will permit the solver to be invoked upon event propogation.
TileChangedArgs tileStartArgs = new TileChangedArgs(mockTileFrom.Object, mockTileTo.Object, TileChangeType.Start);
TileChangedArgs tileChangeArgs = new TileChangedArgs(mockTileFrom.Object, mockTileTo.Object, TileChangeType.Change);
TileChangedArgs tileFinishArgs = new TileChangedArgs(mockTileFrom.Object, mockTileTo.Object, TileChangeType.Finish);

// Our mocked movable entity should emit tile change start, changing, and finished events.
mockMovable.Setup(movable => movable.StartChangeTile(mockTileFrom.Object, mockTileTo.Object))
.Raises(m => m.ChangeStarted += null, mockMovable.Object, tileStartArgs);

mockMovable.Setup(movable => movable.ChangeTile(mockTileFrom.Object, mockTileTo.Object))
.Raises(m => m.Changing += null, mockMovable.Object, tileChangeArgs);

mockMovable.Setup(movable => movable.FinishChangeTile(mockTileFrom.Object, mockTileTo.Object))
.Raises(m => m.ChangeFinished += null, mockMovable.Object, tileFinishArgs);

// Register the entity creator with the tile manager.
manager.RegisterEntityCreator(mockCreator.Object);

// Our first solver must be added before it will receive events.
manager.Add(mockSolverOne.Object);

// Raise an entity creation event to register that entity for tile change events.
mockCreator.Raise(creator => creator.EntityCreated += null, mockCreator.Object, new EntityCreatedArgs(mockTileFrom.Object, mockEntity.Object));

// Move the entity.
mockMovable.Object.StartChangeTile(mockTileFrom.Object, mockTileTo.Object);
mockMovable.Object.ChangeTile(mockTileFrom.Object, mockTileTo.Object);
mockMovable.Object.FinishChangeTile(mockTileFrom.Object, mockTileTo.Object);

// The entity's movement should have invoked each corresponding state transition method once.
// Solver One has received one set of events.

// Add a second solver, for differential comparison.
Mock<ISolver> mockSolverTwo = new Mock<ISolver>();
manager.Add(mockSolverTwo.Object);

// Move the entity a second time.
mockMovable.Object.StartChangeTile(mockTileFrom.Object, mockTileTo.Object);
mockMovable.Object.ChangeTile(mockTileFrom.Object, mockTileTo.Object);
mockMovable.Object.FinishChangeTile(mockTileFrom.Object, mockTileTo.Object);

// The two solvers should have again incremented their movement method invocation count once each.
// Solver One has received two sets of events, Solver Two has received one set of events.

// Raise a Destroy event from the entity (via its IEntity mock), which should trigger deregistration.
mockEntity.Raise(movable => movable.Destroyed += null, new EntityDestroyedArgs(mockEntity.Object));

// Move the entity a third time.
mockMovable.Object.StartChangeTile(mockTileFrom.Object, mockTileTo.Object);
mockMovable.Object.ChangeTile(mockTileFrom.Object, mockTileTo.Object);
mockMovable.Object.FinishChangeTile(mockTileFrom.Object, mockTileTo.Object);

// Because the entity was deregistered, neither solver incremented its movement method invocation count.
// Solver One has received two sets of events, Solver Two has received one set of events.
// Should deregistration be faulty, we'd expect the invocation counts to stand at 3 and 2, repsectively.
mockSolverOne.Verify(solver => solver.Solve(mockEntity.Object, tileStartArgs), Times.Exactly(2));
mockSolverOne.Verify(solver => solver.Solve(mockEntity.Object, tileChangeArgs), Times.Exactly(2));
mockSolverOne.Verify(solver => solver.Solve(mockEntity.Object, tileFinishArgs), Times.Exactly(2));
mockSolverTwo.Verify(solver => solver.Solve(mockEntity.Object, tileStartArgs), Times.Exactly(1));
mockSolverTwo.Verify(solver => solver.Solve(mockEntity.Object, tileChangeArgs), Times.Exactly(1));
mockSolverTwo.Verify(solver => solver.Solve(mockEntity.Object, tileFinishArgs), Times.Exactly(1));
}

[Test]
Expand Down