Compute complication timeline entries from event boundaries
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2e9989eab9
commit
d70cdca4e2
@@ -0,0 +1,89 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import CalendarrCore
|
||||
|
||||
struct ComplicationTimelineTests {
|
||||
|
||||
private static let now = Date(timeIntervalSince1970: 1_789_000_000)
|
||||
|
||||
private static func event(_ id: String, startOffset: TimeInterval,
|
||||
duration: TimeInterval) -> SnapshotEvent {
|
||||
SnapshotEvent(id: id, title: id,
|
||||
start: now.addingTimeInterval(startOffset),
|
||||
end: now.addingTimeInterval(startOffset + duration),
|
||||
isAllDay: false, colorHex: "#4285f4", location: "", calendarKey: "local:1")
|
||||
}
|
||||
|
||||
private static func snapshot(_ events: [SnapshotEvent]) -> CalendarrSnapshot {
|
||||
CalendarrSnapshot(writtenAt: now,
|
||||
coverageStart: now.addingTimeInterval(-86400),
|
||||
coverageEnd: now.addingTimeInterval(14 * 86400),
|
||||
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 first entry is always now, so the complication renders immediately")
|
||||
func startsAtNow() {
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: Self.snapshot([]))
|
||||
#expect(dates.first == Self.now)
|
||||
}
|
||||
|
||||
@Test("Entries are sorted and free of duplicates")
|
||||
func sortedAndDeduplicated() {
|
||||
let snap = Self.snapshot([Self.event("a", startOffset: 3600, duration: 1800),
|
||||
Self.event("b", startOffset: 5400, duration: 1800)])
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: snap)
|
||||
|
||||
#expect(dates == dates.sorted())
|
||||
#expect(Set(dates).count == dates.count)
|
||||
}
|
||||
|
||||
@Test("Event starts and ends inside the horizon become entries")
|
||||
func includesEventBoundaries() {
|
||||
let snap = Self.snapshot([Self.event("a", startOffset: 3600, duration: 1800)])
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: snap)
|
||||
|
||||
#expect(dates.contains(Self.now.addingTimeInterval(3600)))
|
||||
#expect(dates.contains(Self.now.addingTimeInterval(5400)))
|
||||
}
|
||||
|
||||
@Test("Boundaries outside the horizon are ignored")
|
||||
func ignoresBoundariesBeyondHorizon() {
|
||||
let snap = Self.snapshot([Self.event("far", startOffset: 40 * 3600, duration: 1800)])
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: snap, horizon: 24 * 3600)
|
||||
|
||||
#expect(dates.contains(Self.now.addingTimeInterval(40 * 3600)) == false)
|
||||
#expect(dates.allSatisfy { $0 <= Self.now.addingTimeInterval(24 * 3600) })
|
||||
}
|
||||
|
||||
@Test("Boundaries already in the past are ignored")
|
||||
func ignoresPastBoundaries() {
|
||||
let snap = Self.snapshot([Self.event("past", startOffset: -7200, duration: 1800)])
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: snap)
|
||||
|
||||
#expect(dates.allSatisfy { $0 >= Self.now })
|
||||
}
|
||||
|
||||
@Test("An empty calendar still gets hourly entries across the horizon")
|
||||
func fillsHourlyWhenEmpty() {
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: Self.snapshot([]),
|
||||
horizon: 24 * 3600)
|
||||
#expect(dates.count >= 24)
|
||||
}
|
||||
|
||||
@Test("The entry count is capped, keeping the earliest entries")
|
||||
func capsEntries() {
|
||||
var events: [SnapshotEvent] = []
|
||||
for i in 0..<300 {
|
||||
events.append(Self.event("e\(i)", startOffset: Double(i) * 60, duration: 30))
|
||||
}
|
||||
let dates = ComplicationTimeline.entryDates(from: Self.now, in: Self.snapshot(events),
|
||||
maxEntries: 50)
|
||||
|
||||
#expect(dates.count == 50)
|
||||
#expect(dates.first == Self.now)
|
||||
#expect(dates == dates.sorted())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user