// Movement/Tests/FT_SurfaceClassification.ts import { BFL_Vectors } from '#root/Math/Libraries/BFL_Vectors.ts'; import { AC_Movement } from '#root/Movement/Components/AC_Movement.ts'; import { E_SurfaceType } from '#root/Movement/Enums/E_SurfaceType.ts'; import { S_AngleThresholds } from '#root/Movement/Structs/S_AngleThresholds.ts'; import type { S_SurfaceTestCase } from '#root/Movement/Structs/S_SurfaceTestCase.ts'; import { EFunctionalTestResult } from '#root/UE/EFunctionalTestResult.ts'; import { FunctionalTest } from '#root/UE/FunctionalTest.ts'; import { MathLibrary } from '#root/UE/MathLibrary.ts'; /** * Functional Test: Surface Classification System * Tests angle-based surface type detection across all boundary conditions * Validates Walkable/SteepSlope/Wall/Ceiling classification accuracy */ export class FT_SurfaceClassification extends FunctionalTest { // ════════════════════════════════════════════════════════════════════════════════════════ // GRAPHS // ════════════════════════════════════════════════════════════════════════════════════════ // ──────────────────────────────────────────────────────────────────────────────────────── // EventGraph // ──────────────────────────────────────────────────────────────────────────────────────── /** * Test preparation - converts angle thresholds to radians * Called before main test execution to prepare test data */ EventPrepareTest(): void { this.AngleThresholdsRads = { Walkable: MathLibrary.DegreesToRadians( this.MovementComponent.AngleThresholdsDegrees.Walkable ), SteepSlope: MathLibrary.DegreesToRadians( this.MovementComponent.AngleThresholdsDegrees.SteepSlope ), Wall: MathLibrary.DegreesToRadians( this.MovementComponent.AngleThresholdsDegrees.Wall ), }; } /** * Test execution - validates surface classification for all test cases * Tests boundary conditions and edge cases for each surface type */ EventStartTest(): void { this.TestCases.forEach( ({ AngleDegrees, ExpectedType, Description }, arrayIndex) => { const surfaceType = this.MovementComponent.ClassifySurface( BFL_Vectors.GetNormalFromAngle(AngleDegrees), this.AngleThresholdsRads ); if (surfaceType === ExpectedType) { this.FinishTest(EFunctionalTestResult.Succeeded); } else { this.FinishTest( EFunctionalTestResult.Failed, `Movement Component test ${arrayIndex + 1} FAIL: ${Description} (${AngleDegrees}°) expected ${ExpectedType}, got ${surfaceType}` ); } } ); } // ════════════════════════════════════════════════════════════════════════════════════════ // VARIABLES // ════════════════════════════════════════════════════════════════════════════════════════ /** * Movement system component - provides surface classification functionality * @category Components */ private MovementComponent = new AC_Movement(); /** * Comprehensive test cases covering all surface type boundaries * Tests edge cases and typical angles for each classification * @category Test Data */ private TestCases: S_SurfaceTestCase[] = [ { AngleDegrees: 0.0, ExpectedType: E_SurfaceType.Walkable, Description: 'Flat surface', }, { AngleDegrees: 25.0, ExpectedType: E_SurfaceType.Walkable, Description: 'Gentle slope', }, { AngleDegrees: 49.0, ExpectedType: E_SurfaceType.Walkable, Description: 'Max walkable', }, { AngleDegrees: 51.0, ExpectedType: E_SurfaceType.SteepSlope, Description: 'Steep slope', }, { AngleDegrees: 70.0, ExpectedType: E_SurfaceType.SteepSlope, Description: 'Very steep', }, { AngleDegrees: 84.0, ExpectedType: E_SurfaceType.SteepSlope, Description: 'Max steep', }, { AngleDegrees: 90.0, ExpectedType: E_SurfaceType.Wall, Description: 'Vertical wall', }, { AngleDegrees: 94.0, ExpectedType: E_SurfaceType.Wall, Description: 'Max wall', }, { AngleDegrees: 120.0, ExpectedType: E_SurfaceType.Ceiling, Description: 'Overhang', }, { AngleDegrees: 180.0, ExpectedType: E_SurfaceType.Ceiling, Description: 'Ceiling', }, ]; /** * Runtime cached angle thresholds in radians * Converted during preparation for accurate classification testing * @category Test State */ private AngleThresholdsRads: S_AngleThresholds = { Walkable: 0.0, SteepSlope: 0.0, Wall: 0.0, }; }