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)
}
}
|