dbcafd2869
Build & Test (NowChessSystems) TeamCity build finished
Reviewed-on: #28 Reviewed-by: Shahd Lala <shosho996@blackhole.local> Co-authored-by: Janis <janis.e.20@gmx.de> Co-committed-by: Janis <janis.e.20@gmx.de>
140 lines
4.9 KiB
Scala
140 lines
4.9 KiB
Scala
package de.nowchess.io
|
|
|
|
import de.nowchess.api.game.GameContext
|
|
import de.nowchess.api.board.{Square, File, Rank}
|
|
import de.nowchess.api.move.Move
|
|
import de.nowchess.io.json.{JsonExporter, JsonParser}
|
|
import java.nio.file.{Files, Paths}
|
|
import org.scalatest.funsuite.AnyFunSuite
|
|
import org.scalatest.matchers.should.Matchers
|
|
import scala.util.Using
|
|
|
|
class GameFileServiceSuite extends AnyFunSuite with Matchers:
|
|
|
|
test("saveGameToFile: writes JSON file successfully") {
|
|
val tmpFile = Files.createTempFile("chess_test_", ".json")
|
|
try
|
|
val context = GameContext.initial
|
|
val result = FileSystemGameService.saveGameToFile(context, tmpFile, JsonExporter)
|
|
|
|
assert(result.isRight)
|
|
assert(Files.exists(tmpFile))
|
|
assert(Files.size(tmpFile) > 0)
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|
|
|
|
test("loadGameFromFile: reads JSON file successfully") {
|
|
val tmpFile = Files.createTempFile("chess_test_", ".json")
|
|
try
|
|
val originalContext = GameContext.initial
|
|
|
|
// Save
|
|
FileSystemGameService.saveGameToFile(originalContext, tmpFile, JsonExporter)
|
|
|
|
// Load
|
|
val result = FileSystemGameService.loadGameFromFile(tmpFile, JsonParser)
|
|
|
|
assert(result.isRight)
|
|
val loaded = result.getOrElse(GameContext.initial)
|
|
assert(loaded == originalContext)
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|
|
|
|
test("loadGameFromFile: returns error on missing file") {
|
|
val nonExistentFile = Paths.get("/tmp/nonexistent_chess_game_file_12345.json")
|
|
val result = FileSystemGameService.loadGameFromFile(nonExistentFile, JsonParser)
|
|
|
|
assert(result.isLeft)
|
|
}
|
|
|
|
test("saveGameToFile: persists game with moves") {
|
|
val tmpFile = Files.createTempFile("chess_test_moves_", ".json")
|
|
try
|
|
val move1 = Move(Square(File.E, Rank.R2), Square(File.E, Rank.R4))
|
|
val move2 = Move(Square(File.E, Rank.R7), Square(File.E, Rank.R5))
|
|
val context = GameContext.initial
|
|
.withMove(move1)
|
|
.withMove(move2)
|
|
|
|
val saveResult = FileSystemGameService.saveGameToFile(context, tmpFile, JsonExporter)
|
|
assert(saveResult.isRight)
|
|
|
|
val loadResult = FileSystemGameService.loadGameFromFile(tmpFile, JsonParser)
|
|
assert(loadResult.isRight)
|
|
val loaded = loadResult.getOrElse(GameContext.initial)
|
|
assert(loaded.moves.length == 2)
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|
|
|
|
test("saveGameToFile: overwrites existing file") {
|
|
val tmpFile = Files.createTempFile("chess_test_overwrite_", ".json")
|
|
try
|
|
// Write first file
|
|
val context1 = GameContext.initial
|
|
FileSystemGameService.saveGameToFile(context1, tmpFile, JsonExporter)
|
|
val size1 = Files.size(tmpFile)
|
|
|
|
// Write second file (should overwrite)
|
|
val move = Move(Square(File.E, Rank.R2), Square(File.E, Rank.R4))
|
|
val context2 = GameContext.initial.withMove(move)
|
|
FileSystemGameService.saveGameToFile(context2, tmpFile, JsonExporter)
|
|
|
|
val loadResult = FileSystemGameService.loadGameFromFile(tmpFile, JsonParser)
|
|
assert(loadResult.isRight)
|
|
val loaded = loadResult.getOrElse(GameContext.initial)
|
|
assert(loaded.moves.length == 1)
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|
|
|
|
test("loadGameFromFile: handles invalid JSON in file") {
|
|
val tmpFile = Files.createTempFile("chess_test_invalid_", ".json")
|
|
try
|
|
Files.write(tmpFile, "{ invalid json}".getBytes())
|
|
val result = FileSystemGameService.loadGameFromFile(tmpFile, JsonParser)
|
|
|
|
assert(result.isLeft)
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|
|
|
|
test("round-trip: save and load preserves game state") {
|
|
val tmpFile = Files.createTempFile("chess_test_roundtrip_", ".json")
|
|
try
|
|
val move1 = Move(Square(File.A, Rank.R2), Square(File.A, Rank.R4))
|
|
val move2 = Move(Square(File.H, Rank.R7), Square(File.H, Rank.R5))
|
|
val original = GameContext.initial
|
|
.withMove(move1)
|
|
.withMove(move2)
|
|
.withHalfMoveClock(3)
|
|
|
|
FileSystemGameService.saveGameToFile(original, tmpFile, JsonExporter)
|
|
val loadResult = FileSystemGameService.loadGameFromFile(tmpFile, JsonParser)
|
|
|
|
assert(loadResult.isRight)
|
|
val loaded = loadResult.getOrElse(GameContext.initial)
|
|
assert(loaded.moves.length == 2)
|
|
assert(loaded.halfMoveClock == 3)
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|
|
|
|
test("saveGameToFile: handles exporter that throws exception") {
|
|
val tmpFile = Files.createTempFile("chess_test_exporter_error_", ".json")
|
|
try
|
|
val context = GameContext.initial
|
|
val faultyExporter = new GameContextExport {
|
|
def exportGameContext(c: GameContext): String =
|
|
throw new RuntimeException("Export failed")
|
|
}
|
|
|
|
val result = FileSystemGameService.saveGameToFile(context, tmpFile, faultyExporter)
|
|
assert(result.isLeft)
|
|
assert(result.left.toOption.get.contains("Failed to save file"))
|
|
finally
|
|
Files.deleteIfExists(tmpFile)
|
|
}
|