remindwall / RWPureSwift / Tests / AppTypesTests / BusWindowTests.swift
Back to remindwall — Current RemindWall
import Foundation
import Testing
@testable import AppTypes
@Suite("BusWindow Tests")
struct BusWindowTests {
private static let utc: Calendar = {
var c = Calendar(identifier: .gregorian)
c.timeZone = TimeZone(identifier: "UTC")!
return c
}()
// April 5, 2026 is a Sunday. Day-by-day offsets give us deterministic weekdays.
private static func date(weekdayOffset: Int, hour: Int, minute: Int) -> Date {
utc.date(from: DateComponents(
year: 2026, month: 4, day: 5 + weekdayOffset,
hour: hour, minute: minute
))!
}
@Test("default is Mon-Fri 06:30-09:00")
func defaultValues() {
let w = BusWindow.default
#expect(w.startHour == 6)
#expect(w.startMinute == 30)
#expect(w.endHour == 9)
#expect(w.endMinute == 0)
#expect(w.weekdays == [.Monday, .Tuesday, .Wednesday, .Thursday, .Friday])
}
@Test("init encodes all fields and round-trips")
func roundtrip() {
let w = BusWindow(
weekdays: [.Sunday, .Saturday],
startHour: 23, startMinute: 59,
endHour: 0, endMinute: 1
)
#expect(w.startHour == 23)
#expect(w.startMinute == 59)
#expect(w.endHour == 0)
#expect(w.endMinute == 1)
#expect(w.weekdays == [.Sunday, .Saturday])
}
@Test("empty weekday set encodes as zero mask")
func emptyWeekdays() {
let w = BusWindow(
weekdays: [],
startHour: 6, startMinute: 0,
endHour: 9, endMinute: 0
)
#expect(w.weekdays.isEmpty)
}
@Test("all weekdays encode to mask 0b1111111")
func allWeekdays() {
let w = BusWindow(
weekdays: Set(DaysOfWeek.allCases),
startHour: 6, startMinute: 0,
endHour: 9, endMinute: 0
)
#expect(w.weekdays == Set(DaysOfWeek.allCases))
}
@Test("startTimeDisplay formats AM correctly")
func startTimeDisplayAM() {
let w = BusWindow(weekdays: [], startHour: 6, startMinute: 30, endHour: 9, endMinute: 0)
#expect(w.startTimeDisplay == "6:30 AM")
}
@Test("startTimeDisplay formats PM correctly")
func startTimeDisplayPM() {
let w = BusWindow(weekdays: [], startHour: 22, startMinute: 0, endHour: 23, endMinute: 0)
#expect(w.startTimeDisplay == "10:00 PM")
}
@Test("midnight displays as 12:00 AM")
func midnightDisplay() {
let w = BusWindow(weekdays: [], startHour: 0, startMinute: 0, endHour: 1, endMinute: 0)
#expect(w.startTimeDisplay == "12:00 AM")
}
@Test("noon displays as 12:00 PM")
func noonDisplay() {
let w = BusWindow(weekdays: [], startHour: 12, startMinute: 0, endHour: 13, endMinute: 0)
#expect(w.startTimeDisplay == "12:00 PM")
}
@Test("startTotalMinutes computes correctly")
func startTotalMinutes() {
let w = BusWindow(weekdays: [], startHour: 6, startMinute: 30, endHour: 9, endMinute: 0)
#expect(w.startTotalMinutes == 390)
}
@Test("endTotalMinutes computes correctly")
func endTotalMinutes() {
let w = BusWindow(weekdays: [], startHour: 6, startMinute: 30, endHour: 9, endMinute: 15)
#expect(w.endTotalMinutes == 555)
}
// MARK: - isInWindow
@Test("default window: Monday 07:00 is in window")
func defaultMonday0700() {
// April 6, 2026 is a Monday (offset 1 from Sunday April 5)
let date = Self.date(weekdayOffset: 1, hour: 7, minute: 0)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc))
}
@Test("default window: Sunday 07:00 is NOT in window")
func defaultSunday0700() {
let date = Self.date(weekdayOffset: 0, hour: 7, minute: 0)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc) == false)
}
@Test("default window: Saturday 07:00 is NOT in window")
func defaultSaturday0700() {
let date = Self.date(weekdayOffset: 6, hour: 7, minute: 0)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc) == false)
}
@Test("default window: Friday 06:30 (exact start) is in window")
func defaultFridayExactStart() {
let date = Self.date(weekdayOffset: 5, hour: 6, minute: 30)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc))
}
@Test("default window: Friday 09:00 (exact end) is NOT in window")
func defaultFridayExactEnd() {
let date = Self.date(weekdayOffset: 5, hour: 9, minute: 0)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc) == false)
}
@Test("default window: Friday 06:29 (one minute before start) is NOT in window")
func defaultFridayOneMinuteBefore() {
let date = Self.date(weekdayOffset: 5, hour: 6, minute: 29)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc) == false)
}
@Test("default window: Friday 08:59 (one minute before end) is in window")
func defaultFridayOneMinuteBeforeEnd() {
let date = Self.date(weekdayOffset: 5, hour: 8, minute: 59)
#expect(BusWindow.default.isInWindow(date: date, calendar: Self.utc))
}
@Test("overnight window: Monday 23:00 (start=22:00, end=06:00) is in window")
func overnightInWindow() {
let w = BusWindow(
weekdays: [.Monday],
startHour: 22, startMinute: 0,
endHour: 6, endMinute: 0
)
let date = Self.date(weekdayOffset: 1, hour: 23, minute: 0)
#expect(w.isInWindow(date: date, calendar: Self.utc))
}
@Test("overnight window: Monday 03:00 wraps and is in window")
func overnightWrapInWindow() {
let w = BusWindow(
weekdays: [.Monday],
startHour: 22, startMinute: 0,
endHour: 6, endMinute: 0
)
let date = Self.date(weekdayOffset: 1, hour: 3, minute: 0)
#expect(w.isInWindow(date: date, calendar: Self.utc))
}
@Test("degenerate window (start == end) is never in window")
func degenerateWindow() {
let w = BusWindow(
weekdays: Set(DaysOfWeek.allCases),
startHour: 10, startMinute: 0,
endHour: 10, endMinute: 0
)
let date = Self.date(weekdayOffset: 1, hour: 10, minute: 0)
#expect(w.isInWindow(date: date, calendar: Self.utc) == false)
}
@Test("malformed raw value falls back to defaults without crashing")
func malformedRawValue() {
let bogus = BusWindow(rawValue: "not-a-window")
#expect(bogus.weekdays.isEmpty)
#expect(bogus.startHour == 6)
#expect(bogus.endHour == 9)
let date = Self.date(weekdayOffset: 1, hour: 7, minute: 0)
#expect(bogus.isInWindow(date: date, calendar: Self.utc) == false)
}
}