192 lines
7.3 KiB
Swift
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)))
|
|
}
|
|
}
|