-
Notifications
You must be signed in to change notification settings - Fork 1
/
RaceResults.kt
60 lines (49 loc) · 2.43 KB
/
RaceResults.kt
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
package org.kollektions.examples.advanced
import org.kollektions.consumers.*
import org.kollektions.dispatchers.groupBy
import org.kollektions.transformations.*
import java.time.Duration
import java.time.LocalTime
import kotlin.test.Test
import kotlin.test.assertEquals
class RaceResults {
data class Finisher(val name: String, val time: LocalTime, val ageGroup: String)
val ageGroup1 = "10-99"
val ageGroup2 = "100-999"
val yoda = Finisher("Yoda", LocalTime.of(0, 25), ageGroup2)
val luke = Finisher("Luke", LocalTime.of(0, 26), ageGroup1)
val r2d2 = Finisher("R2D2", LocalTime.of(0, 27), ageGroup1)
val chewbacca = Finisher("Chewbacca", LocalTime.of(0, 28), ageGroup2)
private val finishers = listOf(yoda, luke, r2d2, chewbacca)
data class RaceResult(val finisher: Finisher, val overallPlace: Int, val ageGroupPlace: Int, val minutesAfterWinnerFinished: Int)
@Test
fun `uses states to store overall and age group place and best time`() {
val overallPlace = count<Finisher>()
val bestTime = FirstN<Finisher>(1)
val raceResults = finishers.consumeByOne(
keepStates(overallPlace, bestTime)
.groupBy(keyFactory = { finisher: Finisher -> finisher.ageGroup },
innerConsumerFactory = { ageGroupConsumer(overallPlace, bestTime) })
)
println(raceResults)
val expected = mapOf(
ageGroup2 to listOf(
RaceResult(yoda, overallPlace = 1, ageGroupPlace = 1, minutesAfterWinnerFinished = 0),
RaceResult(chewbacca, overallPlace = 4, ageGroupPlace = 2, minutesAfterWinnerFinished = 3)
),
ageGroup1 to listOf(
RaceResult(luke, overallPlace = 2, ageGroupPlace = 1, minutesAfterWinnerFinished = 1),
RaceResult(r2d2, overallPlace = 3, ageGroupPlace = 2, minutesAfterWinnerFinished = 2)
)
)
assertEquals(expected, raceResults)
}
private fun ageGroupConsumer(overallPlace: Counter<Finisher>, bestTime: FirstN<Finisher>): Consumer<Finisher> {
val ageGroupPlace = count<Finisher>()
return keepState(ageGroupPlace).mapTo { it: Finisher -> RaceResult(it,
overallPlace=overallPlace.counter.toInt(),
ageGroupPlace = ageGroupPlace.counter.toInt(),
minutesAfterWinnerFinished = Duration.between(bestTime.buffer[0].time, it.time).toMinutes().toInt())}
.asList()
}
}