Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion android/app/src/main/java/com/noop/ui/SleepScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3482,7 +3482,12 @@ internal fun displaySmoothed(
intervals: List<StageInterval>,
minDurationSec: Double,
): List<StageInterval> {
if (intervals.size <= 2 || minDurationSec <= 0.0) return intervals // Swift: guard count > 2
// Match Swift `Hypnogram.displaySmoothed`: guard ONLY on count. A minDurationSec <= 0 ("raw") must
// still fall through to coalesce() — Swift returns the coalesced timeline, not the un-merged epoch
// fragments. Short-circuiting on <= 0 here returned 60-100 raw fragments (the "comb"), diverging from
// the port. With minDurationSec = 0 the absorb loop's `duration < 0` filter is empty, so it breaks
// right after the first coalesce — same result as Swift.
if (intervals.size <= 2) return intervals // Swift: guard count > 2

// Coalesce adjacent same-stage runs (also bridges the zero-length seams between epochs).
fun coalesce(ivs: List<StageInterval>): MutableList<StageInterval> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,13 @@ class StageDisplaySmoothingTest {

@Test
fun zeroFloorReturnsCoalescedInputUnsmoothed() {
val raw = listOf(iv("light", 0.0, 10.0), iv("deep", 10.0, 20.0), iv("rem", 20.0, 30.0))
assertEquals(raw, displaySmoothed(raw, 0.0)) // smoothingSeconds: 0 → raw timeline
// minDurationSec = 0 ("raw") must still COALESCE adjacent same-stage runs (Swift parity) — NOT
// return the un-merged epoch fragments. Fixture has an adjacent light/light seam so it actually
// exercises the coalesce (the previous [light, deep, rem] fixture had none, so it passed even
// when the impl short-circuited to raw).
val raw = listOf(iv("light", 0.0, 10.0), iv("light", 10.0, 20.0), iv("deep", 20.0, 30.0))
val coalesced = listOf(iv("light", 0.0, 20.0), iv("deep", 20.0, 30.0))
assertEquals(coalesced, displaySmoothed(raw, 0.0))
}

@Test
Expand Down