Christopher Hotchkiss Christopher Hotchkiss
Login

Code

remindwall / RWPureSwift / Tests / AppTypesTests / ScreenOffScheduleTests.swift

Back to remindwall — Current RemindWall

Download this file

import Testing

@testable import AppTypes

@Suite("ScreenOffSchedule Tests")
struct ScreenOffScheduleTests {

    @Test("default schedule is 10 PM to 6 AM")
    func defaultSchedule() {
        let schedule = ScreenOffSchedule.default
        #expect(schedule.startHour == 22)
        #expect(schedule.startMinute == 0)
        #expect(schedule.endHour == 6)
        #expect(schedule.endMinute == 0)
    }

    @Test("init with start and end times encodes correctly")
    func initWithTimes() {
        let schedule = ScreenOffSchedule(startHour: 21, startMinute: 30, endHour: 7, endMinute: 15)
        #expect(schedule.startHour == 21)
        #expect(schedule.startMinute == 30)
        #expect(schedule.endHour == 7)
        #expect(schedule.endMinute == 15)
    }

    @Test("startTimeDisplay formats AM correctly")
    func startTimeDisplayAM() {
        let schedule = ScreenOffSchedule(startHour: 9, startMinute: 30, endHour: 6, endMinute: 0)
        #expect(schedule.startTimeDisplay == "9:30 AM")
    }

    @Test("startTimeDisplay formats PM correctly")
    func startTimeDisplayPM() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.startTimeDisplay == "10:00 PM")
    }

    @Test("endTimeDisplay formats AM correctly")
    func endTimeDisplayAM() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.endTimeDisplay == "6:00 AM")
    }

    @Test("midnight displays as 12:00 AM")
    func midnightDisplay() {
        let schedule = ScreenOffSchedule(startHour: 0, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.startTimeDisplay == "12:00 AM")
    }

    @Test("noon displays as 12:00 PM")
    func noonDisplay() {
        let schedule = ScreenOffSchedule(startHour: 12, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.startTimeDisplay == "12:00 PM")
    }

    @Test("roundtrip preserves all values")
    func roundtrip() {
        let schedule = ScreenOffSchedule(startHour: 23, startMinute: 59, endHour: 0, endMinute: 1)
        #expect(schedule.startHour == 23)
        #expect(schedule.startMinute == 59)
        #expect(schedule.endHour == 0)
        #expect(schedule.endMinute == 1)
    }

    @Test("boundary values at hour 0 and minute 0")
    func boundaryZero() {
        let schedule = ScreenOffSchedule(startHour: 0, startMinute: 0, endHour: 0, endMinute: 0)
        #expect(schedule.startHour == 0)
        #expect(schedule.startMinute == 0)
        #expect(schedule.endHour == 0)
        #expect(schedule.endMinute == 0)
    }

    @Test("startTotalMinutes computes correctly")
    func startTotalMinutes() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 30, endHour: 6, endMinute: 0)
        #expect(schedule.startTotalMinutes == 1350)
    }

    @Test("endTotalMinutes computes correctly")
    func endTotalMinutes() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 15)
        #expect(schedule.endTotalMinutes == 375)
    }

    // MARK: - isInOffWindow tests

    @Test("overnight window: 22:00-06:00, time 23:00 is in window")
    func overnightInWindow() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 23 * 60) == true)
    }

    @Test("overnight window: 22:00-06:00, time 05:59 is in window")
    func overnightEndBoundary() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 5 * 60 + 59) == true)
    }

    @Test("overnight window: 22:00-06:00, time 06:00 is NOT in window")
    func overnightExactEnd() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 6 * 60) == false)
    }

    @Test("overnight window: 22:00-06:00, time 12:00 is NOT in window")
    func overnightMidday() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 12 * 60) == false)
    }

    @Test("same-day window: 02:00-14:00, time 10:00 is in window")
    func sameDayInWindow() {
        let schedule = ScreenOffSchedule(startHour: 2, startMinute: 0, endHour: 14, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 10 * 60) == true)
    }

    @Test("same-day window: 02:00-14:00, time 01:00 is NOT in window")
    func sameDayBeforeStart() {
        let schedule = ScreenOffSchedule(startHour: 2, startMinute: 0, endHour: 14, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 1 * 60) == false)
    }

    @Test("degenerate window: start == end, always returns false")
    func degenerateWindow() {
        let schedule = ScreenOffSchedule(startHour: 10, startMinute: 0, endHour: 10, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 10 * 60) == false)
    }

    @Test("midnight boundary: time 00:00 in overnight window 22:00-06:00")
    func midnightInOvernight() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 0) == true)
    }

    @Test("exact start time is in window")
    func exactStartInWindow() {
        let schedule = ScreenOffSchedule(startHour: 22, startMinute: 0, endHour: 6, endMinute: 0)
        #expect(schedule.isInOffWindow(currentTotalMinutes: 22 * 60) == true)
    }
}