// Headless tests of the stream focus seam (Core/DescentStreamFocus.h). #include "Tests/DescentTestCommon.h" #include "Core/DescentMath.h" #include "Core/DescentStreamFocus.h" #if WITH_DEV_AUTOMATION_TESTS IMPLEMENT_SIMPLE_AUTOMATION_TEST(FDescentStreamFocusTest, "Descent.Stream.Focus", DESCENT_TEST_FLAGS) bool FDescentStreamFocusTest::RunTest(const FString& Parameters) { FDescentTestWorld TW; UDescentStreamFocusSubsystem* F = TW.Sub(); if (!TestNotNull(TEXT("the stream focus subsystem exists in a game world"), F)) { return false; } // A test world has no player, so the default view focus has no point; nothing registered, nothing to stream. TArray Points; F->GetFocusPoints(Points); TestEqual(TEXT("no player and nothing registered: no points"), Points.Num(), 0); TestTrue(TEXT("the view location is part of the default"), F->GetUseViewLocation()); FDescentStreamPoint View; TestFalse(TEXT("there is no view point without a player controller"), F->GetViewPoint(View)); // Registered points, ordered by owner name whatever the registration order, with their radii. const FDescentHandle HB = F->RegisterFocus(TEXT("Beacon"), [](FDescentStreamPoint& Out) { Out.LocationUU = Descent::MetresToUU(FVector(300.0, 50.0, -400.0)); Out.RadiusM = 60.0; return true; }); const FDescentHandle HA = F->RegisterFocus(TEXT("Carrier"), [](FDescentStreamPoint& Out) { Out.LocationUU = Descent::MetresToUU(FVector(0.0, 0.0, -30.0)); Out.RadiusM = 120.0; return true; }); TestTrue(TEXT("handles valid"), HA.IsValid() && HB.IsValid() && HA != HB); F->GetFocusPoints(Points); if (TestEqual(TEXT("two points"), Points.Num(), 2)) { TestEqual(TEXT("first by owner name: Beacon"), Points[0].Owner, FName(TEXT("Beacon"))); TestEqual(TEXT("second: Carrier"), Points[1].Owner, FName(TEXT("Carrier"))); TestEqual(TEXT("radius carried"), Points[1].RadiusM, 120.0, 0.0); TestTrue(TEXT("location in Unreal units"), Points[1].LocationUU.Equals(FVector(0.0, 0.0, -3000.0))); } // A provider that has no point this time (the actor is gone) is skipped. bool bAlive = true; const FDescentHandle HT = F->RegisterFocus(TEXT("Tender"), [&bAlive](FDescentStreamPoint& Out) { Out.LocationUU = FVector(1.0, 2.0, 3.0); return bAlive; }); F->GetFocusPoints(Points); TestEqual(TEXT("three points while the Tender is alive"), Points.Num(), 3); bAlive = false; F->GetFocusPoints(Points); TestEqual(TEXT("two once it has no point"), Points.Num(), 2); // Unregister. TestTrue(TEXT("unregister"), F->UnregisterFocus(HB)); TestFalse(TEXT("unregister twice"), F->UnregisterFocus(HB)); F->UnregisterFocus(HT); F->GetFocusPoints(Points); TestEqual(TEXT("only the carrier is left"), Points.Num(), 1); F->SetUseViewLocation(false); TestFalse(TEXT("view location switched off"), F->GetUseViewLocation()); F->UnregisterFocus(HA); F->GetFocusPoints(Points); TestEqual(TEXT("nothing left"), Points.Num(), 0); AddExpectedError(TEXT("has an empty function"), EAutomationExpectedErrorFlags::Contains, 1); TestFalse(TEXT("an empty provider is refused"), F->RegisterFocus(TEXT("Empty"), UDescentStreamFocusSubsystem::FFocusFn()).IsValid()); return true; } #endif // WITH_DEV_AUTOMATION_TESTS