Files
Gas-Tank-AR-App/GasTankARTests/ARFlowStateMachineTests.swift
2026-09-02 20:54:36 +02:00

192 lines
7.3 KiB
Swift

//
// ARFlowStateMachineTests.swift
// GasTankARTests
//
// Created by Dennis Nemec on 26.08.26.
//
import Testing
@testable import GasTankAR
struct ARFlowStateMachineTests {
// MARK: - Start & Initialisierung
@Test func startsInWorldNotInitializedAndRunsConfiguration() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
let commands = machine.reduce(.started)
#expect(machine.state == .worldNotInitialized)
#expect(commands.contains(.runConfiguration(useImages: false, useInitialMap: true, resetTracking: false)))
}
@Test func initializingTracking() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingInitializing)
#expect(machine.state == .initializingWorld)
}
// MARK: - Scene erfolgreich initialisiert → Location wählen / wiederherstellen
@Test func normalTrackingWithoutStoredTransformGoesToSelectLocation() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal)
#expect(machine.state == .selectLocation)
#expect(machine.hasPlacedTank == false)
}
@Test func normalTrackingWithStoredTransformRestoresTank() {
var machine = ARFlowStateMachine(hasStoredTransform: true)
_ = machine.reduce(.started)
let commands = machine.reduce(.trackingNormal)
#expect(machine.state == .immersive)
#expect(machine.hasPlacedTank == true)
#expect(commands.contains(.placeTank(.storedTransform)))
}
// MARK: - Platzieren
@Test func captureFromSelectLocationPlacesTankAndPersists() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal) // → selectLocation
let commands = machine.reduce(.captureConfirmed)
#expect(machine.state == .immersive)
#expect(machine.hasPlacedTank == true)
#expect(commands.contains(.placeTank(.screenCenter)))
#expect(commands.contains(.persistWorldMap))
#expect(commands.contains(.persistTankTransform))
}
@Test func captureIsIgnoredOutsideSelectLocation() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started) // worldNotInitialized
let commands = machine.reduce(.captureConfirmed)
#expect(commands.isEmpty)
#expect(machine.state == .worldNotInitialized)
}
// MARK: - Eskalation bei zu wenigen Merkmalen
@Test func insufficientFeaturesEscalatesToShowOptions() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
let first = machine.reduce(.trackingInsufficientFeatures)
#expect(machine.state == .initializingNotPossible)
#expect(first.contains(.startMoveAroundTimer))
_ = machine.reduce(.moveAroundTimerFired)
#expect(machine.state == .userMovesAround)
_ = machine.reduce(.showOptionsTimerFired)
#expect(machine.state == .showOptions)
}
@Test func timersDoNothingInWrongState() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
// Kein initializingNotPossible aktiv → moveAroundTimer ignoriert.
let commands = machine.reduce(.moveAroundTimerFired)
#expect(commands.isEmpty)
#expect(machine.state == .worldNotInitialized)
}
// MARK: - Anker-Erkennung (Marker)
@Test func placeAnchorMarkerStartsImageDetection() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal) // selectLocation
let commands = machine.reduce(.placeAnchorMarkerTapped)
#expect(machine.state == .anchorDetection)
#expect(commands.contains(.runConfiguration(useImages: true, useInitialMap: false, resetTracking: false)))
#expect(commands.contains(.startAnchorDetectionTimer))
}
@Test func anchorDetectionTimeoutAsksToCancel() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal)
_ = machine.reduce(.placeAnchorMarkerTapped)
_ = machine.reduce(.anchorDetectionTimerFired)
#expect(machine.state == .askToCancel)
}
@Test func imageAnchorDetectedPlacesTank() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal)
_ = machine.reduce(.placeAnchorMarkerTapped)
let commands = machine.reduce(.imageAnchorDetected)
#expect(machine.state == .immersive)
#expect(machine.hasPlacedTank == true)
#expect(commands.contains(.placeTank(.imageAnchor)))
}
@Test func imageAnchorIgnoredWhenNotDetecting() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal) // selectLocation
let commands = machine.reduce(.imageAnchorDetected)
#expect(commands.isEmpty)
#expect(machine.state == .selectLocation)
}
// MARK: - Relokalisierung
@Test func relocalizingStartsTimerAndTimeoutFails() {
var machine = ARFlowStateMachine(hasStoredTransform: true)
_ = machine.reduce(.started)
let relocating = machine.reduce(.trackingRelocalizing)
#expect(machine.state == .relocating)
#expect(relocating.contains(.startRelocationTimer))
_ = machine.reduce(.relocationTimerFired)
#expect(machine.state == .relocationFailed)
}
@Test func normalTrackingWhilePlacedGoesImmersive() {
var machine = ARFlowStateMachine(hasStoredTransform: false)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal)
_ = machine.reduce(.captureConfirmed) // placed → immersive
_ = machine.reduce(.trackingRelocalizing)
#expect(machine.state == .relocating)
_ = machine.reduce(.trackingNormal)
#expect(machine.state == .immersive)
}
// MARK: - Neu platzieren / Neustart
@Test func repositionClearsTankAndReturnsToSelectLocation() {
var machine = ARFlowStateMachine(hasStoredTransform: true)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingNormal) // restored → immersive
let commands = machine.reduce(.repositionTapped)
#expect(machine.state == .selectLocation)
#expect(machine.hasPlacedTank == false)
#expect(machine.hasStoredTransform == false)
#expect(commands.contains(.removeTank))
#expect(commands.contains(.clearStoredTransform))
}
@Test func restartResetsTracking() {
var machine = ARFlowStateMachine(hasStoredTransform: true)
_ = machine.reduce(.started)
_ = machine.reduce(.trackingRelocalizing)
_ = machine.reduce(.relocationTimerFired) // relocationFailed
let commands = machine.reduce(.restartTapped)
#expect(machine.state == .worldNotInitialized)
#expect(machine.hasStoredTransform == false)
#expect(commands.contains(.runConfiguration(useImages: false, useInitialMap: false, resetTracking: true)))
}
}