test: add tests for undo and redo notifications in GameEngine
Build & Test (NowChessSystems) TeamCity build finished
Build & Test (NowChessSystems) TeamCity build finished
This commit is contained in:
@@ -147,12 +147,11 @@ class GameEngine extends Observable:
|
|||||||
val cmd = invoker.history(invoker.getCurrentIndex)
|
val cmd = invoker.history(invoker.getCurrentIndex)
|
||||||
(cmd: @unchecked) match
|
(cmd: @unchecked) match
|
||||||
case moveCmd: MoveCommand =>
|
case moveCmd: MoveCommand =>
|
||||||
if moveCmd.undo() then
|
moveCmd.previousBoard.foreach(currentBoard = _)
|
||||||
moveCmd.previousBoard.foreach(currentBoard = _)
|
moveCmd.previousHistory.foreach(currentHistory = _)
|
||||||
moveCmd.previousHistory.foreach(currentHistory = _)
|
moveCmd.previousTurn.foreach(currentTurn = _)
|
||||||
moveCmd.previousTurn.foreach(currentTurn = _)
|
invoker.undo()
|
||||||
invoker.undo()
|
notifyObservers(BoardResetEvent(currentBoard, currentHistory, currentTurn))
|
||||||
notifyObservers(BoardResetEvent(currentBoard, currentHistory, currentTurn))
|
|
||||||
else
|
else
|
||||||
notifyObservers(InvalidMoveEvent(currentBoard, currentHistory, currentTurn, "Nothing to undo."))
|
notifyObservers(InvalidMoveEvent(currentBoard, currentHistory, currentTurn, "Nothing to undo."))
|
||||||
|
|
||||||
@@ -161,14 +160,10 @@ class GameEngine extends Observable:
|
|||||||
val cmd = invoker.history(invoker.getCurrentIndex + 1)
|
val cmd = invoker.history(invoker.getCurrentIndex + 1)
|
||||||
(cmd: @unchecked) match
|
(cmd: @unchecked) match
|
||||||
case moveCmd: MoveCommand =>
|
case moveCmd: MoveCommand =>
|
||||||
if moveCmd.execute() then
|
for case de.nowchess.chess.command.MoveResult.Successful(nb, nh, nt, cap) <- moveCmd.moveResult do
|
||||||
moveCmd.moveResult.foreach {
|
updateGameState(nb, nh, nt)
|
||||||
case de.nowchess.chess.command.MoveResult.Successful(newBoard, newHistory, newTurn, captured) =>
|
invoker.redo()
|
||||||
updateGameState(newBoard, newHistory, newTurn)
|
emitMoveEvent(moveCmd.from.toString, moveCmd.to.toString, cap, nt)
|
||||||
invoker.redo()
|
|
||||||
emitMoveEvent(moveCmd.from.toString, moveCmd.to.toString, captured, newTurn)
|
|
||||||
case _ => ()
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
notifyObservers(InvalidMoveEvent(currentBoard, currentHistory, currentTurn, "Nothing to redo."))
|
notifyObservers(InvalidMoveEvent(currentBoard, currentHistory, currentTurn, "Nothing to redo."))
|
||||||
|
|
||||||
|
|||||||
@@ -268,6 +268,39 @@ class GameEngineTest extends AnyFunSuite with Matchers:
|
|||||||
val initialEvents = observer.events.size
|
val initialEvents = observer.events.size
|
||||||
engine.processUserInput("q")
|
engine.processUserInput("q")
|
||||||
observer.events.size shouldBe initialEvents
|
observer.events.size shouldBe initialEvents
|
||||||
|
|
||||||
|
test("GameEngine undo notifies with BoardResetEvent after successful undo"):
|
||||||
|
val engine = new GameEngine()
|
||||||
|
engine.processUserInput("e2e4")
|
||||||
|
engine.processUserInput("e7e5")
|
||||||
|
val observer = new MockObserver()
|
||||||
|
engine.subscribe(observer)
|
||||||
|
observer.events.clear()
|
||||||
|
|
||||||
|
engine.undo()
|
||||||
|
|
||||||
|
// Should have received a BoardResetEvent on undo
|
||||||
|
observer.events.size should be > 0
|
||||||
|
observer.events.exists(_.isInstanceOf[BoardResetEvent]) shouldBe true
|
||||||
|
|
||||||
|
test("GameEngine redo notifies with MoveExecutedEvent after successful redo"):
|
||||||
|
val engine = new GameEngine()
|
||||||
|
engine.processUserInput("e2e4")
|
||||||
|
engine.processUserInput("e7e5")
|
||||||
|
val boardAfterSecondMove = engine.board
|
||||||
|
|
||||||
|
engine.undo()
|
||||||
|
val observer = new MockObserver()
|
||||||
|
engine.subscribe(observer)
|
||||||
|
observer.events.clear()
|
||||||
|
|
||||||
|
engine.redo()
|
||||||
|
|
||||||
|
// Should have received a MoveExecutedEvent for the redo
|
||||||
|
observer.events.size shouldBe 1
|
||||||
|
observer.events.head shouldBe a[MoveExecutedEvent]
|
||||||
|
engine.board shouldBe boardAfterSecondMove
|
||||||
|
engine.turn shouldBe Color.White
|
||||||
|
|
||||||
// Mock Observer for testing
|
// Mock Observer for testing
|
||||||
private class MockObserver extends Observer:
|
private class MockObserver extends Observer:
|
||||||
|
|||||||
@@ -166,4 +166,24 @@ class TerminalUITest extends AnyFunSuite with Matchers {
|
|||||||
|
|
||||||
out.toString should include("Captured: Knight(White) on A8") // Depending on how piece/coord serialize
|
out.toString should include("Captured: Knight(White) on A8") // Depending on how piece/coord serialize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("TerminalUI processes valid move input via processUserInput") {
|
||||||
|
val in = new ByteArrayInputStream("e2e4\nq\n".getBytes)
|
||||||
|
val out = new ByteArrayOutputStream()
|
||||||
|
|
||||||
|
val engine = new GameEngine()
|
||||||
|
val ui = new TerminalUI(engine)
|
||||||
|
|
||||||
|
Console.withIn(in) {
|
||||||
|
Console.withOut(out) {
|
||||||
|
ui.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val output = out.toString
|
||||||
|
output should include("White's turn.")
|
||||||
|
output should include("Game over. Goodbye!")
|
||||||
|
// The move should have been processed and the board displayed
|
||||||
|
engine.turn shouldBe Color.Black
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user