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)
|
||||
(cmd: @unchecked) match
|
||||
case moveCmd: MoveCommand =>
|
||||
if moveCmd.undo() then
|
||||
moveCmd.previousBoard.foreach(currentBoard = _)
|
||||
moveCmd.previousHistory.foreach(currentHistory = _)
|
||||
moveCmd.previousTurn.foreach(currentTurn = _)
|
||||
invoker.undo()
|
||||
notifyObservers(BoardResetEvent(currentBoard, currentHistory, currentTurn))
|
||||
moveCmd.previousBoard.foreach(currentBoard = _)
|
||||
moveCmd.previousHistory.foreach(currentHistory = _)
|
||||
moveCmd.previousTurn.foreach(currentTurn = _)
|
||||
invoker.undo()
|
||||
notifyObservers(BoardResetEvent(currentBoard, currentHistory, currentTurn))
|
||||
else
|
||||
notifyObservers(InvalidMoveEvent(currentBoard, currentHistory, currentTurn, "Nothing to undo."))
|
||||
|
||||
@@ -161,14 +160,10 @@ class GameEngine extends Observable:
|
||||
val cmd = invoker.history(invoker.getCurrentIndex + 1)
|
||||
(cmd: @unchecked) match
|
||||
case moveCmd: MoveCommand =>
|
||||
if moveCmd.execute() then
|
||||
moveCmd.moveResult.foreach {
|
||||
case de.nowchess.chess.command.MoveResult.Successful(newBoard, newHistory, newTurn, captured) =>
|
||||
updateGameState(newBoard, newHistory, newTurn)
|
||||
invoker.redo()
|
||||
emitMoveEvent(moveCmd.from.toString, moveCmd.to.toString, captured, newTurn)
|
||||
case _ => ()
|
||||
}
|
||||
for case de.nowchess.chess.command.MoveResult.Successful(nb, nh, nt, cap) <- moveCmd.moveResult do
|
||||
updateGameState(nb, nh, nt)
|
||||
invoker.redo()
|
||||
emitMoveEvent(moveCmd.from.toString, moveCmd.to.toString, cap, nt)
|
||||
else
|
||||
notifyObservers(InvalidMoveEvent(currentBoard, currentHistory, currentTurn, "Nothing to redo."))
|
||||
|
||||
|
||||
@@ -268,6 +268,39 @@ class GameEngineTest extends AnyFunSuite with Matchers:
|
||||
val initialEvents = observer.events.size
|
||||
engine.processUserInput("q")
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
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