package org.terst.doot.widget import org.junit.Assert.* import org.junit.Test import org.terst.doot.widget.data.* import java.time.Instant import java.time.temporal.ChronoUnit class SlotPackerTest { private fun makeEvent(startIso: String, endIso: String): WidgetItem = WidgetItem( id = "evt-$startIso", title = "Event", source = "calendar", type = "event", start = startIso, end = endIso ) private fun makeTask(id: String): WidgetItem = WidgetItem( id = id, title = "Task $id", source = "todoist", type = "task", completable = true ) private val now = Instant.parse("2026-06-28T10:15:00Z") @Test fun `empty tasks returns empty fragments`() { val result = SlotPacker.pack(emptyList(), emptyList(), now) assertTrue(result.isEmpty()) } @Test fun `single task gets slot starting at now`() { val result = SlotPacker.pack(listOf(makeTask("t1")), emptyList(), now) assertEquals(1, result.size) assertEquals(1, result[0].slots.size) assertEquals(now, result[0].slots[0].slotStart) assertEquals(now.plus(1, ChronoUnit.HOURS), result[0].slots[0].slotEnd) } @Test fun `three tasks with no events form one fragment`() { val tasks = listOf(makeTask("t1"), makeTask("t2"), makeTask("t3")) val result = SlotPacker.pack(tasks, emptyList(), now) assertEquals(1, result.size) assertEquals(3, result[0].slots.size) assertEquals(result[0].slots[0].slotEnd, result[0].slots[1].slotStart) assertEquals(result[0].slots[1].slotEnd, result[0].slots[2].slotStart) } @Test fun `event between tasks splits into two fragments`() { val tasks = listOf(makeTask("t1"), makeTask("t2"), makeTask("t3")) // Event at 11:15–12:15 falls between slot 1 (10:15–11:15) and slot 2 val event = makeEvent("2026-06-28T11:15:00Z", "2026-06-28T12:15:00Z") val result = SlotPacker.pack(tasks, listOf(event), now) assertEquals(2, result.size) assertEquals(1, result[0].slots.size) // t1 before event assertEquals(2, result[1].slots.size) // t2, t3 after event } @Test fun `task slot jumps past overlapping event`() { val tasks = listOf(makeTask("t1")) // Event occupies 10:00–11:30, overlaps with now (10:15) val event = makeEvent("2026-06-28T10:00:00Z", "2026-06-28T11:30:00Z") val result = SlotPacker.pack(tasks, listOf(event), now) assertEquals(1, result.size) val slotStart = result[0].slots[0].slotStart assertEquals(Instant.parse("2026-06-28T11:30:00Z"), slotStart) } @Test fun `fragment startTime and endTime match first and last slot`() { val tasks = listOf(makeTask("t1"), makeTask("t2")) val result = SlotPacker.pack(tasks, emptyList(), now) val frag = result[0] assertEquals(frag.slots.first().slotStart, frag.startTime) assertEquals(frag.slots.last().slotEnd, frag.endTime) } }