getting going
This commit is contained in:
125
GazeTests/SettingsManagerTests.swift
Normal file
125
GazeTests/SettingsManagerTests.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
144
GazeTests/TimerEngineTests.swift
Normal file
144
GazeTests/TimerEngineTests.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user