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