81 lines
3.4 KiB
Kotlin
81 lines
3.4 KiB
Kotlin
package de.hoennig.gittally.watcher
|
|
|
|
import io.kotest.core.spec.style.FunSpec
|
|
import io.kotest.matchers.booleans.shouldBeFalse
|
|
import io.kotest.matchers.booleans.shouldBeTrue
|
|
import io.kotest.matchers.nulls.shouldBeNull
|
|
import io.kotest.matchers.shouldBe
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
import java.time.LocalDate
|
|
import java.time.LocalTime
|
|
|
|
class AutoBuildStateTest : FunSpec() {
|
|
private fun stateFile(): Path = Files.createTempDirectory("gittally-autobuild-test").resolve("auto-builds.json")
|
|
|
|
init {
|
|
test("latestDueSlot picks the latest slot at or before now") {
|
|
val times = listOf("01:00", "11:00", "13:00")
|
|
|
|
AutoBuildSlots.latestDueSlot(times, LocalTime.parse("00:59")).shouldBeNull()
|
|
AutoBuildSlots.latestDueSlot(times, LocalTime.parse("01:00")) shouldBe "01:00"
|
|
AutoBuildSlots.latestDueSlot(times, LocalTime.parse("12:00")) shouldBe "11:00"
|
|
AutoBuildSlots.latestDueSlot(times, LocalTime.parse("23:59")) shouldBe "13:00"
|
|
}
|
|
|
|
test("latestDueSlot skips invalid slots but keeps the valid ones") {
|
|
AutoBuildSlots.latestDueSlot(listOf("25:99", "nope", "02:00"), LocalTime.parse("12:00")) shouldBe "02:00"
|
|
AutoBuildSlots.latestDueSlot(listOf("25:99"), LocalTime.parse("12:00")).shouldBeNull()
|
|
}
|
|
|
|
test("latestDueSlot of an empty slot list is null") {
|
|
AutoBuildSlots.latestDueSlot(emptyList(), LocalTime.parse("12:00")).shouldBeNull()
|
|
}
|
|
|
|
test("markTriggered records exactly the branch, day, and slot") {
|
|
val state = FileAutoBuildState(stateFile())
|
|
val today = LocalDate.parse("2026-07-07")
|
|
|
|
state.isTriggered("main", today, "11:00").shouldBeFalse()
|
|
state.markTriggered("main", today, "11:00")
|
|
|
|
state.isTriggered("main", today, "11:00").shouldBeTrue()
|
|
state.isTriggered("main", today, "13:00").shouldBeFalse()
|
|
state.isTriggered("main", today.plusDays(1), "11:00").shouldBeFalse()
|
|
state.isTriggered("other", today, "11:00").shouldBeFalse()
|
|
}
|
|
|
|
test("triggers persist across instances") {
|
|
val file = stateFile()
|
|
val today = LocalDate.parse("2026-07-07")
|
|
FileAutoBuildState(file).markTriggered("main", today, "11:00")
|
|
|
|
FileAutoBuildState(file).isTriggered("main", today, "11:00").shouldBeTrue()
|
|
}
|
|
|
|
test("entries of past days are dropped on write") {
|
|
val file = stateFile()
|
|
val state = FileAutoBuildState(file)
|
|
val yesterday = LocalDate.parse("2026-07-06")
|
|
val today = LocalDate.parse("2026-07-07")
|
|
state.markTriggered("main", yesterday, "11:00")
|
|
|
|
state.markTriggered("main", today, "01:00")
|
|
|
|
state.isTriggered("main", yesterday, "11:00").shouldBeFalse()
|
|
state.isTriggered("main", today, "01:00").shouldBeTrue()
|
|
}
|
|
|
|
test("an unreadable state file is treated as empty") {
|
|
val file = stateFile()
|
|
Files.createDirectories(file.parent)
|
|
Files.writeString(file, "not json at all {")
|
|
val state = FileAutoBuildState(file)
|
|
|
|
state.isTriggered("main", LocalDate.parse("2026-07-07"), "11:00").shouldBeFalse()
|
|
state.markTriggered("main", LocalDate.parse("2026-07-07"), "11:00")
|
|
state.isTriggered("main", LocalDate.parse("2026-07-07"), "11:00").shouldBeTrue()
|
|
}
|
|
}
|
|
}
|