Add the watch coverage policy and snapshot trimming
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cbec421367
commit
19454379e5
@@ -0,0 +1,118 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import CalendarrCore
|
||||
|
||||
/// The watch payload is a narrower snapshot, not a different one. These tests
|
||||
/// pin down the part that is easy to get wrong: the coverage window has to
|
||||
/// shrink with the events, or the watch renders an empty week it knows nothing
|
||||
/// about.
|
||||
struct WatchTrimmingTests {
|
||||
|
||||
private static let cal = Calendar(identifier: .gregorian)
|
||||
private static let now = Date(timeIntervalSince1970: 1_789_000_000)
|
||||
|
||||
private static func event(_ id: String, dayOffset: Int, hour: Int = 9) -> SnapshotEvent {
|
||||
let dayStart = cal.startOfDay(for: now)
|
||||
let day = cal.date(byAdding: .day, value: dayOffset, to: dayStart)!
|
||||
let start = cal.date(byAdding: .hour, value: hour, to: day)!
|
||||
return SnapshotEvent(id: id, title: "Event \(id)",
|
||||
start: start, end: start.addingTimeInterval(3600),
|
||||
isAllDay: false, colorHex: "#4285f4",
|
||||
location: "", calendarKey: "local:1")
|
||||
}
|
||||
|
||||
private static func snapshot(_ events: [SnapshotEvent]) -> CalendarrSnapshot {
|
||||
let dayStart = cal.startOfDay(for: now)
|
||||
return CalendarrSnapshot(
|
||||
writtenAt: now,
|
||||
coverageStart: cal.date(byAdding: .day, value: -SnapshotCoverage.daysBehind, to: dayStart)!,
|
||||
coverageEnd: cal.date(byAdding: .day, value: SnapshotCoverage.daysAhead, to: dayStart)!,
|
||||
isLoggedIn: true,
|
||||
writerVersion: "1.0",
|
||||
events: events,
|
||||
theme: SnapshotTheme(today: "#1", text: "#2", background: "#3",
|
||||
line: "#4", primary: "#5", accent: "#6"),
|
||||
language: "de")
|
||||
}
|
||||
|
||||
@Test("The window narrows to the watch policy, not just the events")
|
||||
func narrowsWindow() {
|
||||
let trimmed = Self.snapshot([]).trimmedForWatch(now: Self.now, calendar: Self.cal)
|
||||
let dayStart = Self.cal.startOfDay(for: Self.now)
|
||||
|
||||
#expect(trimmed.coverageStart == Self.cal.date(byAdding: .day, value: -WatchCoverage.daysBehind, to: dayStart))
|
||||
#expect(trimmed.coverageEnd == Self.cal.date(byAdding: .day, value: WatchCoverage.daysAhead, to: dayStart))
|
||||
}
|
||||
|
||||
@Test("Events outside the watch window are dropped")
|
||||
func dropsEventsOutsideWindow() {
|
||||
let inside = Self.event("in", dayOffset: 3)
|
||||
let outside = Self.event("out", dayOffset: 30)
|
||||
let trimmed = Self.snapshot([inside, outside]).trimmedForWatch(now: Self.now, calendar: Self.cal)
|
||||
|
||||
#expect(trimmed.events.map(\.id) == ["in"])
|
||||
}
|
||||
|
||||
@Test("An event still running at the window start is kept")
|
||||
func keepsRunningEvent() {
|
||||
let dayStart = Self.cal.startOfDay(for: Self.now)
|
||||
let start = Self.cal.date(byAdding: .day, value: -5, to: dayStart)!
|
||||
let running = SnapshotEvent(id: "running", title: "Urlaub",
|
||||
start: start,
|
||||
end: Self.cal.date(byAdding: .day, value: 5, to: dayStart)!,
|
||||
isAllDay: true, colorHex: "#4285f4",
|
||||
location: "", calendarKey: "local:1")
|
||||
let trimmed = Self.snapshot([running]).trimmedForWatch(now: Self.now, calendar: Self.cal)
|
||||
|
||||
#expect(trimmed.events.map(\.id) == ["running"])
|
||||
}
|
||||
|
||||
@Test("Metadata survives trimming unchanged")
|
||||
func preservesMetadata() {
|
||||
let original = Self.snapshot([Self.event("a", dayOffset: 1)])
|
||||
let trimmed = original.trimmedForWatch(now: Self.now, calendar: Self.cal)
|
||||
|
||||
#expect(trimmed.language == "de")
|
||||
#expect(trimmed.isLoggedIn == true)
|
||||
#expect(trimmed.writerVersion == "1.0")
|
||||
#expect(trimmed.theme.accent == "#6")
|
||||
#expect(trimmed.writtenAt == original.writtenAt)
|
||||
#expect(trimmed.schemaVersion == CalendarrSnapshot.currentSchema)
|
||||
}
|
||||
|
||||
@Test("When the event cap truncates, coverageEnd pulls back to what we can prove")
|
||||
func capPullsBackCoverage() {
|
||||
var many: [SnapshotEvent] = []
|
||||
for day in 0..<14 {
|
||||
for hour in 8..<18 { many.append(Self.event("d\(day)h\(hour)", dayOffset: day, hour: hour)) }
|
||||
}
|
||||
#expect(many.count > WatchCoverage.maxEvents)
|
||||
|
||||
let trimmed = Self.snapshot(many).trimmedForWatch(now: Self.now, calendar: Self.cal)
|
||||
|
||||
#expect(trimmed.events.count <= WatchCoverage.maxEvents)
|
||||
#expect(trimmed.events.allSatisfy { $0.start < trimmed.coverageEnd })
|
||||
let dayStart = Self.cal.startOfDay(for: Self.now)
|
||||
let fullEnd = Self.cal.date(byAdding: .day, value: WatchCoverage.daysAhead, to: dayStart)!
|
||||
#expect(trimmed.coverageEnd < fullEnd)
|
||||
#expect(trimmed.coverageEnd > trimmed.coverageStart)
|
||||
}
|
||||
|
||||
@Test("Trimming never widens a window the writer already narrowed")
|
||||
func neverWidens() {
|
||||
let dayStart = Self.cal.startOfDay(for: Self.now)
|
||||
let narrow = CalendarrSnapshot(
|
||||
writtenAt: Self.now,
|
||||
coverageStart: dayStart,
|
||||
coverageEnd: Self.cal.date(byAdding: .day, value: 2, to: dayStart)!,
|
||||
isLoggedIn: true, writerVersion: "1.0", events: [],
|
||||
theme: SnapshotTheme(today: "#1", text: "#2", background: "#3",
|
||||
line: "#4", primary: "#5", accent: "#6"),
|
||||
language: "de")
|
||||
|
||||
let trimmed = narrow.trimmedForWatch(now: Self.now, calendar: Self.cal)
|
||||
|
||||
#expect(trimmed.coverageStart == dayStart)
|
||||
#expect(trimmed.coverageEnd == Self.cal.date(byAdding: .day, value: 2, to: dayStart))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user