summaryrefslogtreecommitdiff
path: root/core/src/commonTest/kotlin/coffee/liz/rookery/StoreTest.kt
blob: e5fc945ac593483dcfaf0d2be52f42972c7acb0d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package coffee.liz.rookery

import coffee.liz.rookery.model.Event
import coffee.liz.rookery.model.Penalty
import coffee.liz.rookery.model.Solve
import coffee.liz.rookery.store.Hlc
import coffee.liz.rookery.store.HlcClock
import coffee.liz.rookery.store.MemoryBlobStore
import coffee.liz.rookery.store.MemoryLogStorage
import coffee.liz.rookery.store.Repo
import coffee.liz.rookery.store.Store
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class StoreTest {
    @Test fun hlcOrdersAndRoundTrips() {
        var now = 1000L
        val c = HlcClock("a") { now }
        val a = c.tick(); val b = c.tick()
        assertTrue(b > a)
        now = 500 // clock went backwards
        assertTrue(c.tick() > b)
        c.observe(Hlc(9999, 7, "z"))
        assertTrue(c.tick() > Hlc(9999, 7, "z"))
        assertEquals(a, Hlc.parse(a.toString()))
        assertTrue(Hlc(5, 0, "a").toString() < Hlc(10, 0, "a").toString())
    }

    private fun solve(id: String, ms: Long) = Solve(id, "s", Event.E333, ms, Penalty.NONE, "R U", "", 1)

    @Test fun twoDevicesConvergeRegardlessOfOrder() {
        val shared = mutableListOf<String>()
        var t = 0L
        val a = Repo(Store("dev-a", MemoryLogStorage(shared), MemoryBlobStore()) { t })
        val b = Repo(Store("dev-b", MemoryLogStorage(shared), MemoryBlobStore()) { t })

        t = 10; a.addSolve(solve("x", 1000))
        t = 11; b.addSolve(solve("y", 2000))
        a.store.sync(); b.store.sync()
        // concurrent edits to the same field: later stamp wins on both sides
        t = 20; a.setPenalty("x", Penalty.PLUS2)
        t = 21; b.setPenalty("x", Penalty.DNF)
        t = 22; b.deleteSolve("y")
        a.store.sync(); b.store.sync()

        assertEquals(a.solves(), b.solves())
        assertEquals(listOf("x"), a.solves().map { it.id })
        assertEquals(Penalty.DNF, a.solves().single().penalty)
    }

    @Test fun letterPairWordsMergeAsSet() {
        val shared = mutableListOf<String>()
        var t = 0L
        val a = Repo(Store("a", MemoryLogStorage(shared), MemoryBlobStore()) { t })
        val b = Repo(Store("b", MemoryLogStorage(shared), MemoryBlobStore()) { t })
        t = 1; a.setPrimaryWord("AB", "abacus", 1)
        t = 2; b.setPrimaryWord("AB", "abba", 2)
        a.store.sync(); b.store.sync()
        val p = a.letterPairs().getValue("AB")
        assertEquals("abba", p.primary)
        assertEquals(setOf("abacus", "abba"), p.words)
        assertEquals(2, a.wordHistory().size)
    }
}