98 lines
3.8 KiB
Swift
98 lines
3.8 KiB
Swift
//
|
|
// TankModelSelectionTests.swift
|
|
// GasTankARTests
|
|
//
|
|
// Created by Dennis Nemec on 14.09.26.
|
|
//
|
|
|
|
import Testing
|
|
import Foundation
|
|
import RealityKit
|
|
@testable import GasTankAR
|
|
|
|
/// Prüft, dass für eine Tank-Auswahl im AR-Modus die richtige Datei geladen wird:
|
|
/// Der Katalog aus dem echten App-Bundle (`Tanks.json`) muss vollständig sein,
|
|
/// jede referenzierte Datei muss existieren und die AR-Factory muss das echte
|
|
/// Modell (statt des Ersatzkörpers) erzeugen.
|
|
struct TankModelSelectionTests {
|
|
|
|
/// Katalog, geladen aus dem realen App-Bundle (dem Test-Host).
|
|
private static func bundleCatalog() -> TankCatalog {
|
|
let bundle = Bundle(for: TankEntityFactory.self)
|
|
return TankCatalog(loader: BundleTankCatalogLoader(bundle: bundle))
|
|
}
|
|
|
|
// MARK: - Katalog aus dem Bundle
|
|
|
|
@Test func bundleCatalogContainsAllNineVariants() {
|
|
let catalog = Self.bundleCatalog()
|
|
#expect(catalog.definitions.count == 9)
|
|
// 3 Größen, jeweils oberirdisch weiß/grün + unterirdisch oliv.
|
|
#expect(catalog.sizes(for: .aboveGround).count == 3)
|
|
#expect(catalog.sizes(for: .belowGround).count == 3)
|
|
}
|
|
|
|
@Test func everyModelFileExistsInBundle() {
|
|
let bundle = Bundle(for: TankEntityFactory.self)
|
|
let catalog = Self.bundleCatalog()
|
|
|
|
for def in catalog.definitions {
|
|
let url = bundle.url(forResource: def.modelResourceName, withExtension: def.modelFileExtension)
|
|
#expect(url != nil, "Modell-Datei fehlt im Bundle: \(def.modelPath)")
|
|
}
|
|
}
|
|
|
|
@Test func everyVariantHasItsMeasuredDomeCenter() {
|
|
let expected: [String: Float] = [
|
|
"DG-2700_wh.usdz": -0.426,
|
|
"DG-2700_mi.usdz": -0.426,
|
|
"DG-2700_ol.usdz": -0.498,
|
|
"DG-4850_wh.usdz": -1.317,
|
|
"DG-4850_mi.usdz": -1.317,
|
|
"DG-4850_ol.usdz": -1.395,
|
|
"DG-6400_wh.usdz": -1.939,
|
|
"DG-6400_mi.usdz": -1.939,
|
|
"DG-6400_ol.usdz": -2.018,
|
|
]
|
|
let definitions = Self.bundleCatalog().definitions
|
|
#expect(definitions.count == expected.count)
|
|
for definition in definitions {
|
|
let measured = expected[definition.modelPath]
|
|
#expect(measured != nil, "Kein Domschachtmaß für \(definition.modelPath)")
|
|
if let measured {
|
|
#expect(abs(definition.domeCenterX - measured) < 0.001)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Auswahl → richtige Datei
|
|
|
|
@Test func aboveGroundColorsMapToExpectedFiles() {
|
|
let catalog = Self.bundleCatalog()
|
|
let white = catalog.resolvedDefinition(for: Tank(size: .t1_2, color: .white, placement: .aboveGround))
|
|
let green = catalog.resolvedDefinition(for: Tank(size: .t1_2, color: .green, placement: .aboveGround))
|
|
#expect(white?.modelPath == "DG-2700_wh.usdz")
|
|
#expect(green?.modelPath == "DG-2700_mi.usdz")
|
|
}
|
|
|
|
@Test func belowGroundMapsToUndergroundFile() {
|
|
let catalog = Self.bundleCatalog()
|
|
let def = catalog.resolvedDefinition(for: Tank(size: .t2_9, color: .olive, placement: .belowGround))
|
|
#expect(def?.modelPath == "DG-6400_ol.usdz")
|
|
}
|
|
|
|
// MARK: - AR-Factory lädt das echte Modell (kein Ersatzkörper)
|
|
|
|
@MainActor
|
|
@Test func factoryLoadsRealModelNotFallbackCube() {
|
|
// Repräsentative oberirdische Konfiguration: der Tank ist deutlich länger
|
|
// als der 0,3 m große Ersatzwürfel, der nur bei fehlendem Modell entsteht.
|
|
let tank = Tank(size: .t2_9, color: .white, placement: .aboveGround)
|
|
let factory = TankEntityFactory(catalog: Self.bundleCatalog())
|
|
let container = factory.makeContainer(for: tank)
|
|
|
|
let bounds = container.visualBounds(relativeTo: nil)
|
|
#expect(bounds.extents.x > 0.5, "Es wurde vermutlich der Ersatzwürfel geladen statt des echten Modells.")
|
|
}
|
|
}
|