Skip to content

Commit 17921d9

Browse files
committed
test(driver-memory): pin the exclusive token end, and add the changeset
The `Intl.DateTimeFormat` fence dropped `fractionalSecondDigits` — it is not in this package's `lib` view of `DateTimeFormatOptions` — and reads the sub-second half off the window literal instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADLdAs2pVcH17h9tZKWMBg
1 parent b94d3e9 commit 17921d9

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
"@objectstack/driver-memory": patch
3+
---
4+
5+
`driver-memory` analytics: `dateRange: 'today'` no longer counts the first instant of tomorrow (#16179)
6+
7+
`parseDateRangeString('today')` returns the day's start instant and the **next** day's start instant, and the analytics call site compared that upper bound with `$lte`. `nextUtcCalendarDay` widens only a bare `YYYY-MM-DD` and returns `null` for a full timestamp — its documented contract — so the half-open branch was never taken and the window closed at both ends. `'today'` was one day **plus one instant** long: two adjacent day windows overlapped at midnight and a row stamped exactly there was counted in **both**, silently.
8+
9+
Measured through `MemoryAnalyticsService.query()` against the built package, rows at `2026-09-06T00:00:00.000Z` / `2026-09-06T12:00:00.000Z` / `2026-09-07T00:00:00.000Z`, clock frozen inside 2026-09-06:
10+
11+
| `dateRange` | before | after |
12+
|:--|:--|:--|
13+
| `'today'` | all three, including `2026-09-07T00:00:00.000Z` | the first two |
14+
| `['2026-09-06T00:00:00.000Z', '2026-09-07T00:00:00.000Z']` | all three | all three — **unchanged** |
15+
16+
**An explicit `dateRange: [a, b]` is deliberately untouched.** `$lte` on a caller-written timestamp end is the reading this package publishes today, and narrowing it would silently change what an existing query answers; the repair is confined to what the driver's own preset resolution emits. A bare-day end likewise keeps its whole-day widening (`< nextUtcCalendarDay(day)`).
17+
18+
⚠️ Behaviour change for a caller using `dateRange: 'today'`: a row stamped at exactly the next day's midnight — `00:00:00.000` in the query's timezone — moves out of today's answer and into tomorrow's. That is the double-count being removed, not coverage being lost.

packages/drivers/driver-memory/src/memory-analytics-date-range-token-end-exclusive.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,14 @@ const iso = (t: number) => new Date(t).toISOString();
138138
* asserted to be a local midnight by this function.
139139
*/
140140
function localClock(instant: string, zone: string): string {
141+
// ⛔ No `fractionalSecondDigits`: it is not in this package's `lib` view of
142+
// `Intl.DateTimeFormatOptions`. The sub-second half is checked directly on
143+
// the literal instead — see the fence below.
141144
return new Intl.DateTimeFormat('en-CA', {
142145
timeZone: zone,
143146
hourCycle: 'h23',
144147
year: 'numeric', month: '2-digit', day: '2-digit',
145148
hour: '2-digit', minute: '2-digit', second: '2-digit',
146-
fractionalSecondDigits: 3,
147149
}).format(new Date(instant));
148150
}
149151

@@ -253,10 +255,13 @@ describe("#16179 — 'today' stops BEFORE tomorrow's first instant", () => {
253255
it('every window literal is a local midnight in its own zone — checked against `Intl`, not against the code under test', () => {
254256
for (const c of CELLS) {
255257
for (const bound of c.window) {
258+
// The clock half, from the tz database.
256259
expect(
257260
localClock(bound, c.zone),
258261
`${label(c)}: ${bound} is not midnight in ${c.zone}`,
259-
).toMatch(/ 00:00:00\.000$/);
262+
).toMatch(/ 00:00:00$/);
263+
// The sub-second half, read off the literal itself.
264+
expect(bound, `${label(c)}: ${bound} carries a sub-second part`).toMatch(/\.000Z$/);
260265
}
261266
}
262267
});

0 commit comments

Comments
 (0)