Skip to content

test(sleep): pin the night-caption label and date pairing (#2199) - #2224

Merged
ryanbr merged 1 commit into
mainfrom
test/sleep-night-caption-pairing
Sep 15, 2026
Merged

ryanbr merged 1 commit into
mainfrom
test/sleep-night-caption-pairing

Conversation

@ryanbr

@ryanbr ryanbr commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

Test-only. Pins the caption pairing reported in #2199.

What was not pinned

The Sleep nav header stacks two lines computed from opposite ends of the night:

  • the relative label counts from the wake day (calendarNightsAgo, the key navDays groups by)
  • the date beneath it prints the onset day (clockLabelFor)

Individually both are covered. What nothing asserted is that they agree row by row, which is the only thing a reader ever sees. The reporter's screen had a correctly counted "1 night ago" sitting above a date belonging to a different night, and no test asserted that combination.

The fixtures made that hard to see. nightOn wakes at 07:00 from an 01:00 onset on the same calendar day, so onset and wake answer every anchor question identically and the two rules are indistinguishable.

What this adds

A crossMidnightNight fixture (onset 22:50, wake 06:48 the next morning) and the reporter's own three rows asserted verbatim, with a Monday pinned as today:

Last night      Sun 13 Sep
1 night ago     Sat 12 Sep
2 nights ago    Fri 11 Sep

The hero label is passed as null so it walks the stage-less path, the one that used to borrow the newest night's date.

Mutation-checked

A regression pin that does not go red on the regression is worth nothing, so I broke the source two ways and confirmed this test catches both.

1. Reintroduce the borrow (navDays.getOrNull(offset) to getOrNull(0)):

FAILED nightCaptionPairsEachLabelWithItsOwnOnsetDate_issue2199
  row "1 night ago" printed Sun 13 Sep · 22:50 - 06:48, expected it to start Sat 12 Sep

That failure message is the reporter's bug in their own terms.

2. Anchor the label on onset instead of wake (endTs to startTs):

FAILED nightCaptionPairsEachLabelWithItsOwnOnsetDate_issue2199
  expected:<[Last night]> but was:<[1 night ago]>

Worth being accurate about what is new here: neither mutation is caught only by this test. navHeaderClockLabel_datesTheBrowsedNight_notTheNewestOne also fails on the first, and twoNightsEitherSideOfTheRollKeepDistinctLabels on the second. An earlier draft of this description claimed the existing suite could not have caught a row dating itself from the wrong night, and the mutation run disproved that. What this test adds is the pairing: the two lines asserted together, per row, on nights that actually cross midnight, phrased so a failure reads back as the symptom a reporter would describe.

Verification

./gradlew -p android :app:compileFullDebugUnitTestKotlin
./gradlew -p android :app:syncRoomSchemaSnapshot          # own invocation
./gradlew -p android :app:testFullDebugUnitTest --tests "com.noop.ui.SleepHeroLogicTest"

tests="14" skipped="0" failures="0" errors="0" on unmutated main, with the new case present in the result XML rather than filtered out, and the result timestamp checked against the clock. Passes as of #2201, so this locks in current behaviour rather than describing a pending change.

Known limit

This covers navHeaderClockLabel, not its call site. The original defect was a call-site expression (night?.clockLabel ?: model?.clockLabel), and SleepScreen.kt could regress the same way by passing the model's label as the first argument, which no unit test here would catch. The comment above that call site is currently the only thing guarding it.

No production code is touched, so there is no parity twin to add. The Swift side has its own nightRelativeLabel and would want the same cross-midnight fixture, which is worth doing separately if this shape proves useful.

The Sleep nav header stacks two lines that are computed from opposite ends
of the night: `calendarNightsAgo` counts from the WAKE day (the key navDays
groups by) while `clockLabelFor` prints the ONSET day. For a real night those
are different calendar dates, so the pairing only reads correctly if every row
resolves its own night.

Nothing pinned that pairing. The existing fixtures wake at 07:00 from an 01:00
onset the same calendar day, so onset and wake answer every anchor question
identically and the suite could not have caught a row that dated itself from
the wrong night.

This adds a cross-midnight fixture and asserts the reporter's own three rows
verbatim, passing a null hero label so it walks the stage-less path that used
to borrow the newest night's date.

    Last night      Sun 13 Sep
    1 night ago     Sat 12 Sep
    2 nights ago    Fri 11 Sep

Test only, no behaviour change. Passes on main as of #2201.
@ryanbr
ryanbr merged commit 3c8bfe6 into main Sep 15, 2026
3 checks passed
@ryanbr
ryanbr deleted the test/sleep-night-caption-pairing branch September 15, 2026 03:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant