90 lines
3.8 KiB
Swift
90 lines
3.8 KiB
Swift
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())
|
|
}
|
|
}
|