feat: persistance de l'historique des parties en JSON (okio)
This commit is contained in:
2 files changed
+80
No files matched your search
@@ -0,0 +1,32 @@
|
||||
package com.livrets.data
|
||||
|
||||
import com.livrets.game.GameResult
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
import okio.FileSystem
|
||||
import okio.Path
|
||||
|
||||
class HistoryRepository(
|
||||
private val filePath: Path,
|
||||
private val fileSystem: FileSystem = FileSystem.SYSTEM,
|
||||
) {
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
suspend fun load(): List<GameResult> = withContext(Dispatchers.IO) {
|
||||
if (!fileSystem.exists(filePath)) return@withContext emptyList()
|
||||
fileSystem.read(filePath) { readUtf8() }
|
||||
.let { json.decodeFromString(ListSerializer(GameResult.serializer()), it) }
|
||||
}
|
||||
|
||||
suspend fun save(result: GameResult) {
|
||||
val all = load() + result
|
||||
withContext(Dispatchers.IO) {
|
||||
filePath.parent?.let { fileSystem.createDirectories(it) }
|
||||
fileSystem.write(filePath) {
|
||||
writeUtf8(json.encodeToString(ListSerializer(GameResult.serializer()), all))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.livrets.data
|
||||
|
||||
import com.livrets.game.AnswerRecord
|
||||
import com.livrets.game.GameConfig
|
||||
import com.livrets.game.GameResult
|
||||
import com.livrets.game.Question
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.time.Instant
|
||||
import okio.fakefilesystem.FakeFileSystem
|
||||
import okio.Path.Companion.toPath
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class HistoryRepositoryTest {
|
||||
|
||||
private fun gameResult(date: String, score: Int) = GameResult(
|
||||
date = Instant.parse(date),
|
||||
config = GameConfig(10, 10, 12),
|
||||
records = List(score) {
|
||||
AnswerRecord(Question.Direct(2, 3), 6, 6, true, 900L)
|
||||
} + List(10 - score) {
|
||||
AnswerRecord(Question.Direct(2, 3), null, 6, false, 10_000L)
|
||||
},
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `chargement vide quand aucun fichier`() = runTest {
|
||||
val fs = FakeFileSystem()
|
||||
val repo = HistoryRepository("/docs/history.json".toPath(), fs)
|
||||
assertTrue(repo.load().isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `aller-retour sauvegarde puis chargement`() = runTest {
|
||||
val fs = FakeFileSystem()
|
||||
val repo = HistoryRepository("/docs/history.json".toPath(), fs)
|
||||
val first = gameResult("2026-01-01T00:00:00Z", score = 7)
|
||||
val second = gameResult("2026-02-02T00:00:00Z", score = 4)
|
||||
|
||||
repo.save(first)
|
||||
assertEquals(listOf(first), repo.load())
|
||||
|
||||
repo.save(second)
|
||||
assertEquals(listOf(first, second), repo.load())
|
||||
assertTrue(fs.exists("/docs/history.json".toPath()))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user