getting going

This commit is contained in:
Michael Freno
2026-01-08 00:31:34 -05:00
parent c2c5736bfd
commit 658bbd8e02
24 changed files with 2058 additions and 1 deletions

View File

@@ -0,0 +1,125 @@
//
// SettingsManagerTests.swift
// GazeTests
//
// Created by Mike Freno on 1/7/26.
//
import XCTest
@testable import Gaze
@MainActor
final class SettingsManagerTests: XCTestCase {
var settingsManager: SettingsManager!
override func setUp() async throws {
try await super.setUp()
settingsManager = SettingsManager.shared
// Clear any existing settings
UserDefaults.standard.removeObject(forKey: "gazeAppSettings")
settingsManager.load()
}
override func tearDown() async throws {
UserDefaults.standard.removeObject(forKey: "gazeAppSettings")
try await super.tearDown()
}
func testDefaultSettings() {
let defaults = AppSettings.defaults
XCTAssertTrue(defaults.lookAwayTimer.enabled)
XCTAssertEqual(defaults.lookAwayTimer.intervalSeconds, 20 * 60)
XCTAssertEqual(defaults.lookAwayCountdownSeconds, 20)
XCTAssertTrue(defaults.blinkTimer.enabled)
XCTAssertEqual(defaults.blinkTimer.intervalSeconds, 5 * 60)
XCTAssertTrue(defaults.postureTimer.enabled)
XCTAssertEqual(defaults.postureTimer.intervalSeconds, 30 * 60)
XCTAssertFalse(defaults.hasCompletedOnboarding)
XCTAssertFalse(defaults.launchAtLogin)
XCTAssertTrue(defaults.playSounds)
}
func testSaveAndLoad() {
var settings = AppSettings.defaults
settings.lookAwayTimer.enabled = false
settings.lookAwayCountdownSeconds = 30
settings.hasCompletedOnboarding = true
settingsManager.settings = settings
settingsManager.load()
XCTAssertFalse(settingsManager.settings.lookAwayTimer.enabled)
XCTAssertEqual(settingsManager.settings.lookAwayCountdownSeconds, 30)
XCTAssertTrue(settingsManager.settings.hasCompletedOnboarding)
}
func testTimerConfigurationRetrieval() {
let lookAwayConfig = settingsManager.timerConfiguration(for: .lookAway)
XCTAssertTrue(lookAwayConfig.enabled)
XCTAssertEqual(lookAwayConfig.intervalSeconds, 20 * 60)
let blinkConfig = settingsManager.timerConfiguration(for: .blink)
XCTAssertTrue(blinkConfig.enabled)
XCTAssertEqual(blinkConfig.intervalSeconds, 5 * 60)
let postureConfig = settingsManager.timerConfiguration(for: .posture)
XCTAssertTrue(postureConfig.enabled)
XCTAssertEqual(postureConfig.intervalSeconds, 30 * 60)
}
func testUpdateTimerConfiguration() {
var newConfig = TimerConfiguration(enabled: false, intervalSeconds: 10 * 60)
settingsManager.updateTimerConfiguration(for: .lookAway, configuration: newConfig)
let retrieved = settingsManager.timerConfiguration(for: .lookAway)
XCTAssertFalse(retrieved.enabled)
XCTAssertEqual(retrieved.intervalSeconds, 10 * 60)
}
func testResetToDefaults() {
settingsManager.settings.lookAwayTimer.enabled = false
settingsManager.settings.hasCompletedOnboarding = true
settingsManager.resetToDefaults()
XCTAssertTrue(settingsManager.settings.lookAwayTimer.enabled)
XCTAssertFalse(settingsManager.settings.hasCompletedOnboarding)
}
func testCodableEncoding() {
let settings = AppSettings.defaults
let encoder = JSONEncoder()
let data = try? encoder.encode(settings)
XCTAssertNotNil(data)
}
func testCodableDecoding() {
let settings = AppSettings.defaults
let encoder = JSONEncoder()
let data = try! encoder.encode(settings)
let decoder = JSONDecoder()
let decoded = try? decoder.decode(AppSettings.self, from: data)
XCTAssertNotNil(decoded)
XCTAssertEqual(decoded, settings)
}
func testTimerConfigurationIntervalMinutes() {
var config = TimerConfiguration(enabled: true, intervalSeconds: 600)
XCTAssertEqual(config.intervalMinutes, 10)
config.intervalMinutes = 20
XCTAssertEqual(config.intervalSeconds, 1200)
}
}

View File

@@ -0,0 +1,144 @@
//
// TimerEngineTests.swift
// GazeTests
//
// Created by Mike Freno on 1/7/26.
//
import XCTest
@testable import Gaze
@MainActor
final class TimerEngineTests: XCTestCase {
var timerEngine: TimerEngine!
var settingsManager: SettingsManager!
override func setUp() async throws {
try await super.setUp()
settingsManager = SettingsManager.shared
UserDefaults.standard.removeObject(forKey: "gazeAppSettings")
settingsManager.load()
timerEngine = TimerEngine(settingsManager: settingsManager)
}
override func tearDown() async throws {
timerEngine.stop()
UserDefaults.standard.removeObject(forKey: "gazeAppSettings")
try await super.tearDown()
}
func testTimerInitialization() {
timerEngine.start()
XCTAssertEqual(timerEngine.timerStates.count, 3)
XCTAssertNotNil(timerEngine.timerStates[.lookAway])
XCTAssertNotNil(timerEngine.timerStates[.blink])
XCTAssertNotNil(timerEngine.timerStates[.posture])
}
func testDisabledTimersNotInitialized() {
settingsManager.settings.blinkTimer.enabled = false
timerEngine.start()
XCTAssertEqual(timerEngine.timerStates.count, 2)
XCTAssertNotNil(timerEngine.timerStates[.lookAway])
XCTAssertNil(timerEngine.timerStates[.blink])
XCTAssertNotNil(timerEngine.timerStates[.posture])
}
func testTimerStateInitialValues() {
timerEngine.start()
let lookAwayState = timerEngine.timerStates[.lookAway]!
XCTAssertEqual(lookAwayState.type, .lookAway)
XCTAssertEqual(lookAwayState.remainingSeconds, 20 * 60)
XCTAssertFalse(lookAwayState.isPaused)
XCTAssertTrue(lookAwayState.isActive)
}
func testPauseAllTimers() {
timerEngine.start()
timerEngine.pause()
for (_, state) in timerEngine.timerStates {
XCTAssertTrue(state.isPaused)
}
}
func testResumeAllTimers() {
timerEngine.start()
timerEngine.pause()
timerEngine.resume()
for (_, state) in timerEngine.timerStates {
XCTAssertFalse(state.isPaused)
}
}
func testSkipNext() {
settingsManager.settings.lookAwayTimer.intervalSeconds = 60
timerEngine.start()
timerEngine.timerStates[.lookAway]?.remainingSeconds = 10
timerEngine.skipNext(type: .lookAway)
XCTAssertEqual(timerEngine.timerStates[.lookAway]?.remainingSeconds, 60)
}
func testGetTimeRemaining() {
timerEngine.start()
let timeRemaining = timerEngine.getTimeRemaining(for: .lookAway)
XCTAssertEqual(timeRemaining, TimeInterval(20 * 60))
}
func testGetFormattedTimeRemaining() {
timerEngine.start()
timerEngine.timerStates[.lookAway]?.remainingSeconds = 125
let formatted = timerEngine.getFormattedTimeRemaining(for: .lookAway)
XCTAssertEqual(formatted, "2:05")
}
func testGetFormattedTimeRemainingWithHours() {
timerEngine.start()
timerEngine.timerStates[.lookAway]?.remainingSeconds = 3665
let formatted = timerEngine.getFormattedTimeRemaining(for: .lookAway)
XCTAssertEqual(formatted, "1:01:05")
}
func testStop() {
timerEngine.start()
XCTAssertFalse(timerEngine.timerStates.isEmpty)
timerEngine.stop()
XCTAssertTrue(timerEngine.timerStates.isEmpty)
}
func testDismissReminderResetsTimer() {
timerEngine.start()
timerEngine.timerStates[.blink]?.remainingSeconds = 0
timerEngine.activeReminder = .blinkTriggered
timerEngine.dismissReminder()
XCTAssertNil(timerEngine.activeReminder)
XCTAssertEqual(timerEngine.timerStates[.blink]?.remainingSeconds, 5 * 60)
}
func testDismissLookAwayResumesTimers() {
timerEngine.start()
timerEngine.activeReminder = .lookAwayTriggered(countdownSeconds: 20)
timerEngine.pause()
timerEngine.dismissReminder()
for (_, state) in timerEngine.timerStates {
XCTAssertFalse(state.isPaused)
}
}
}