general: 14.0 new min

This commit is contained in:
Michael Freno
2026-01-15 22:31:48 -05:00
parent 77bc2f9a92
commit 1ace5fd3f7
24 changed files with 689 additions and 929 deletions

View File

@@ -27,7 +27,8 @@ final class OnboardingNavigationTests: XCTestCase {
// MARK: - Navigation Tests
func testOnboardingStartsAtWelcomePage() {
let onboarding = OnboardingContainerView(settingsManager: testEnv.settingsManager as! SettingsManager)
// Use real SettingsManager for view initialization test since @Bindable requires concrete type
let onboarding = OnboardingContainerView(settingsManager: SettingsManager.shared)
// Verify initial state
XCTAssertFalse(testEnv.settingsManager.settings.hasCompletedOnboarding)

View File

@@ -39,7 +39,7 @@ final class SettingsManagerTests: XCTestCase {
let defaults = AppSettings.defaults
XCTAssertTrue(defaults.lookAwayTimer.enabled)
XCTAssertTrue(defaults.blinkTimer.enabled)
XCTAssertFalse(defaults.blinkTimer.enabled) // Blink timer is disabled by default
XCTAssertTrue(defaults.postureTimer.enabled)
XCTAssertFalse(defaults.hasCompletedOnboarding)
}
@@ -92,7 +92,7 @@ final class SettingsManagerTests: XCTestCase {
let expectation = XCTestExpectation(description: "Settings changed")
var receivedSettings: AppSettings?
settingsManager.$settings
settingsManager.settingsPublisher
.dropFirst() // Skip initial value
.sink { settings in
receivedSettings = settings
@@ -102,6 +102,7 @@ final class SettingsManagerTests: XCTestCase {
// Trigger change
settingsManager.settings.playSounds = !settingsManager.settings.playSounds
settingsManager.save()
await fulfillment(of: [expectation], timeout: 1.0)
XCTAssertNotNil(receivedSettings)

View File

@@ -13,13 +13,18 @@ import XCTest
/// Enhanced mock settings manager with full control over state
@MainActor
final class EnhancedMockSettingsManager: ObservableObject, SettingsProviding {
@Published var settings: AppSettings
@Observable
final class EnhancedMockSettingsManager: SettingsProviding {
var settings: AppSettings
var settingsPublisher: Published<AppSettings>.Publisher {
$settings
@ObservationIgnored
private let _settingsSubject: CurrentValueSubject<AppSettings, Never>
var settingsPublisher: AnyPublisher<AppSettings, Never> {
_settingsSubject.eraseToAnyPublisher()
}
@ObservationIgnored
private let timerConfigKeyPaths: [TimerType: WritableKeyPath<AppSettings, TimerConfiguration>] = [
.lookAway: \.lookAwayTimer,
.blink: \.blinkTimer,
@@ -27,13 +32,18 @@ final class EnhancedMockSettingsManager: ObservableObject, SettingsProviding {
]
// Track method calls for verification
@ObservationIgnored
private(set) var saveCallCount = 0
@ObservationIgnored
private(set) var saveImmediatelyCallCount = 0
@ObservationIgnored
private(set) var loadCallCount = 0
@ObservationIgnored
private(set) var resetToDefaultsCallCount = 0
init(settings: AppSettings = .defaults) {
self.settings = settings
self._settingsSubject = CurrentValueSubject(settings)
}
func timerConfiguration(for type: TimerType) -> TimerConfiguration {
@@ -48,6 +58,7 @@ final class EnhancedMockSettingsManager: ObservableObject, SettingsProviding {
preconditionFailure("Unknown timer type: \(type)")
}
settings[keyPath: keyPath] = configuration
_settingsSubject.send(settings)
}
func allTimerConfigurations() -> [TimerType: TimerConfiguration] {
@@ -60,10 +71,12 @@ final class EnhancedMockSettingsManager: ObservableObject, SettingsProviding {
func save() {
saveCallCount += 1
_settingsSubject.send(settings)
}
func saveImmediately() {
saveImmediatelyCallCount += 1
_settingsSubject.send(settings)
}
func load() {
@@ -73,6 +86,7 @@ final class EnhancedMockSettingsManager: ObservableObject, SettingsProviding {
func resetToDefaults() {
resetToDefaultsCallCount += 1
settings = .defaults
_settingsSubject.send(settings)
}
// Test helpers
@@ -82,6 +96,7 @@ final class EnhancedMockSettingsManager: ObservableObject, SettingsProviding {
loadCallCount = 0
resetToDefaultsCallCount = 0
settings = .defaults
_settingsSubject.send(settings)
}
}

View File

@@ -23,9 +23,8 @@ final class BlinkSetupViewTests: XCTestCase {
}
func testBlinkSetupInitialization() {
let view = BlinkSetupView(
settingsManager: testEnv.settingsManager as! SettingsManager
)
// Use real SettingsManager for view initialization test since @Bindable requires concrete type
let view = BlinkSetupView(settingsManager: SettingsManager.shared)
XCTAssertNotNil(view)
}

View File

@@ -23,10 +23,8 @@ final class GeneralSetupViewTests: XCTestCase {
}
func testGeneralSetupInitialization() {
let view = GeneralSetupView(
settingsManager: testEnv.settingsManager as! SettingsManager,
isOnboarding: true
)
// Use real SettingsManager for view initialization test since @Bindable requires concrete type
let view = GeneralSetupView(settingsManager: SettingsManager.shared, isOnboarding: true)
XCTAssertNotNil(view)
}

View File

@@ -23,9 +23,8 @@ final class LookAwaySetupViewTests: XCTestCase {
}
func testLookAwaySetupInitialization() {
let view = LookAwaySetupView(
settingsManager: testEnv.settingsManager as! SettingsManager
)
// Use real SettingsManager for view initialization test since @Bindable requires concrete type
let view = LookAwaySetupView(settingsManager: SettingsManager.shared)
XCTAssertNotNil(view)
}

View File

@@ -23,9 +23,8 @@ final class PostureSetupViewTests: XCTestCase {
}
func testPostureSetupInitialization() {
let view = PostureSetupView(
settingsManager: testEnv.settingsManager as! SettingsManager
)
// Use real SettingsManager for view initialization test since @Bindable requires concrete type
let view = PostureSetupView(settingsManager: SettingsManager.shared)
XCTAssertNotNil(view)
}