pass 1
This commit is contained in:
33
GazeTests/Helpers/MockTimeProvider.swift
Normal file
33
GazeTests/Helpers/MockTimeProvider.swift
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// MockTimeProvider.swift
|
||||
// GazeTests
|
||||
//
|
||||
// Mock time provider for deterministic timer testing.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@testable import Gaze
|
||||
|
||||
/// A mock time provider for deterministic testing.
|
||||
/// Allows manual control over time in tests.
|
||||
final class MockTimeProvider: TimeProviding, @unchecked Sendable {
|
||||
private var currentTime: Date
|
||||
|
||||
init(startTime: Date = Date()) {
|
||||
self.currentTime = startTime
|
||||
}
|
||||
|
||||
func now() -> Date {
|
||||
currentTime
|
||||
}
|
||||
|
||||
/// Advances time by the specified interval
|
||||
func advance(by interval: TimeInterval) {
|
||||
currentTime = currentTime.addingTimeInterval(interval)
|
||||
}
|
||||
|
||||
/// Sets the current time to a specific date
|
||||
func setTime(_ date: Date) {
|
||||
currentTime = date
|
||||
}
|
||||
}
|
||||
65
GazeTests/Helpers/TestServiceContainer.swift
Normal file
65
GazeTests/Helpers/TestServiceContainer.swift
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// TestServiceContainer.swift
|
||||
// GazeTests
|
||||
//
|
||||
// Test-specific dependency injection container.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@testable import Gaze
|
||||
|
||||
/// A dependency injection container configured for testing.
|
||||
/// Provides injectable dependencies and test-specific utilities.
|
||||
@MainActor
|
||||
final class TestServiceContainer {
|
||||
/// The settings manager instance
|
||||
private(set) var settingsManager: any SettingsProviding
|
||||
|
||||
/// The timer engine instance
|
||||
private var _timerEngine: TimerEngine?
|
||||
|
||||
/// Time provider for deterministic testing
|
||||
let timeProvider: TimeProviding
|
||||
|
||||
/// Creates a test container with default mock settings
|
||||
convenience init() {
|
||||
self.init(settings: AppSettings())
|
||||
}
|
||||
|
||||
/// Creates a test container with custom settings
|
||||
init(settings: AppSettings) {
|
||||
self.settingsManager = EnhancedMockSettingsManager(settings: settings)
|
||||
self.timeProvider = MockTimeProvider()
|
||||
}
|
||||
|
||||
/// Creates a test container with a custom settings manager
|
||||
init(settingsManager: any SettingsProviding) {
|
||||
self.settingsManager = settingsManager
|
||||
self.timeProvider = MockTimeProvider()
|
||||
}
|
||||
|
||||
/// Gets or creates the timer engine for testing
|
||||
var timerEngine: TimerEngine {
|
||||
if let engine = _timerEngine {
|
||||
return engine
|
||||
}
|
||||
let engine = TimerEngine(
|
||||
settingsManager: settingsManager,
|
||||
enforceModeService: nil,
|
||||
timeProvider: timeProvider
|
||||
)
|
||||
_timerEngine = engine
|
||||
return engine
|
||||
}
|
||||
|
||||
/// Sets a custom timer engine
|
||||
func setTimerEngine(_ engine: TimerEngine) {
|
||||
_timerEngine = engine
|
||||
}
|
||||
|
||||
/// Resets the container for test isolation
|
||||
func reset() {
|
||||
_timerEngine?.stop()
|
||||
_timerEngine = nil
|
||||
}
|
||||
}
|
||||
@@ -14,31 +14,30 @@ final class ServiceContainerTests: XCTestCase {
|
||||
func testProductionContainerCreation() {
|
||||
let container = ServiceContainer.shared
|
||||
|
||||
XCTAssertFalse(container.isTestEnvironment)
|
||||
XCTAssertNotNil(container.settingsManager)
|
||||
XCTAssertNotNil(container.enforceModeService)
|
||||
}
|
||||
|
||||
func testTestContainerCreation() {
|
||||
let settings = AppSettings.onlyLookAwayEnabled
|
||||
let container = ServiceContainer.forTesting(settings: settings)
|
||||
let container = TestServiceContainer(settings: settings)
|
||||
|
||||
XCTAssertTrue(container.isTestEnvironment)
|
||||
XCTAssertEqual(container.settingsManager.settings.lookAwayTimer.enabled, true)
|
||||
XCTAssertEqual(container.settingsManager.settings.blinkTimer.enabled, false)
|
||||
}
|
||||
|
||||
func testTimerEngineCreation() {
|
||||
let container = ServiceContainer.forTesting()
|
||||
let container = TestServiceContainer()
|
||||
let timerEngine = container.timerEngine
|
||||
|
||||
XCTAssertNotNil(timerEngine)
|
||||
// Second access should return the same instance
|
||||
XCTAssertTrue(container.timerEngine === timerEngine)
|
||||
XCTAssertTrue(container.timeProvider is MockTimeProvider)
|
||||
}
|
||||
|
||||
func testCustomTimerEngineInjection() {
|
||||
let container = ServiceContainer.forTesting()
|
||||
let container = TestServiceContainer()
|
||||
let mockSettings = EnhancedMockSettingsManager(settings: .shortIntervals)
|
||||
let customEngine = TimerEngine(
|
||||
settingsManager: mockSettings,
|
||||
@@ -51,10 +50,10 @@ final class ServiceContainerTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testContainerReset() {
|
||||
let container = ServiceContainer.forTesting()
|
||||
let container = TestServiceContainer()
|
||||
|
||||
// Access timer engine to create it
|
||||
_ = container.timerEngine
|
||||
let existingEngine = container.timerEngine
|
||||
|
||||
// Reset should clear the timer engine
|
||||
container.reset()
|
||||
@@ -62,5 +61,6 @@ final class ServiceContainerTests: XCTestCase {
|
||||
// Accessing again should create a new instance
|
||||
let newEngine = container.timerEngine
|
||||
XCTAssertNotNil(newEngine)
|
||||
XCTAssertFalse(existingEngine === newEngine)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,28 +202,28 @@ extension AppSettings {
|
||||
@MainActor
|
||||
func createTestContainer(
|
||||
settings: AppSettings = .defaults
|
||||
) -> ServiceContainer {
|
||||
return ServiceContainer.forTesting(settings: settings)
|
||||
) -> TestServiceContainer {
|
||||
return TestServiceContainer(settings: settings)
|
||||
}
|
||||
|
||||
/// Creates a complete test environment with all mocks
|
||||
@MainActor
|
||||
struct TestEnvironment {
|
||||
let container: ServiceContainer
|
||||
let container: TestServiceContainer
|
||||
let windowManager: MockWindowManager
|
||||
let settingsManager: EnhancedMockSettingsManager
|
||||
let timeProvider: MockTimeProvider
|
||||
|
||||
init(settings: AppSettings = .defaults) {
|
||||
self.settingsManager = EnhancedMockSettingsManager(settings: settings)
|
||||
self.container = ServiceContainer(settingsManager: settingsManager)
|
||||
self.container = TestServiceContainer(settingsManager: settingsManager)
|
||||
self.windowManager = MockWindowManager()
|
||||
self.timeProvider = MockTimeProvider()
|
||||
}
|
||||
|
||||
/// Creates an AppDelegate with all test dependencies
|
||||
func createAppDelegate() -> AppDelegate {
|
||||
return AppDelegate(serviceContainer: container, windowManager: windowManager)
|
||||
return AppDelegate(serviceContainer: serviceContainer, windowManager: windowManager)
|
||||
}
|
||||
|
||||
/// Resets all mock state
|
||||
@@ -231,6 +231,13 @@ struct TestEnvironment {
|
||||
windowManager.reset()
|
||||
settingsManager.reset()
|
||||
}
|
||||
|
||||
private var serviceContainer: ServiceContainer {
|
||||
ServiceContainer(
|
||||
settingsManager: settingsManager,
|
||||
enforceModeService: EnforceModeService.shared
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - XCTest Extensions
|
||||
|
||||
Reference in New Issue
Block a user