test(brush): add 6 EditorBrush::getInfluence tests

Locks in the recent NaN/zero-radius/zero-falloff guards:
- inner radius returns full influence (1.0)
- at/beyond outer radius returns 0
- rim falls off as 1 - t² (smooth)
- NaN/inf distance rejected (returns 0, not 1 from short-circuit)
- zero/negative/NaN radius rejected
- zero falloff produces hard-edge brush
This commit is contained in:
Kelsi 2026-05-06 08:05:43 -07:00
parent c9c4665642
commit 2400271a4f
2 changed files with 59 additions and 0 deletions

View file

@ -421,6 +421,7 @@ add_executable(test_editor_units
${CMAKE_SOURCE_DIR}/tools/editor/npc_spawner.cpp
${CMAKE_SOURCE_DIR}/tools/editor/quest_editor.cpp
${CMAKE_SOURCE_DIR}/tools/editor/content_pack.cpp
${CMAKE_SOURCE_DIR}/tools/editor/editor_brush.cpp
${CMAKE_SOURCE_DIR}/src/core/logger.cpp
)
target_include_directories(test_editor_units PRIVATE

View file

@ -219,3 +219,61 @@ TEST_CASE("WCP unpack rejects bad magic", "[wcp]") {
"test_wcp_out/dest"));
fs::remove_all("test_wcp_out");
}
// ============== EditorBrush::getInfluence tests ==============
#include "editor_brush.hpp"
#include <cmath>
#include <limits>
TEST_CASE("EditorBrush::getInfluence is full inside the inner radius", "[brush]") {
EditorBrush b;
b.settings().radius = 10.0f;
b.settings().falloff = 0.5f; // inner radius = 5
REQUIRE(b.getInfluence(0.0f) == 1.0f);
REQUIRE(b.getInfluence(4.0f) == 1.0f);
REQUIRE(b.getInfluence(5.0f) == 1.0f);
}
TEST_CASE("EditorBrush::getInfluence is zero at or beyond radius", "[brush]") {
EditorBrush b;
b.settings().radius = 10.0f;
b.settings().falloff = 0.5f;
REQUIRE(b.getInfluence(10.0f) == 0.0f);
REQUIRE(b.getInfluence(20.0f) == 0.0f);
}
TEST_CASE("EditorBrush::getInfluence smoothly falls off in the rim", "[brush]") {
EditorBrush b;
b.settings().radius = 10.0f;
b.settings().falloff = 1.0f; // inner radius = 0
// At t=0.5 the falloff should be 1 - 0.5^2 = 0.75
REQUIRE(b.getInfluence(5.0f) == Catch::Approx(0.75f).margin(0.001f));
}
TEST_CASE("EditorBrush::getInfluence rejects NaN distance", "[brush]") {
EditorBrush b;
b.settings().radius = 10.0f;
b.settings().falloff = 0.5f;
REQUIRE(b.getInfluence(std::numeric_limits<float>::quiet_NaN()) == 0.0f);
REQUIRE(b.getInfluence(std::numeric_limits<float>::infinity()) == 0.0f);
}
TEST_CASE("EditorBrush::getInfluence rejects non-positive radius", "[brush]") {
EditorBrush b;
b.settings().radius = 0.0f;
REQUIRE(b.getInfluence(5.0f) == 0.0f);
b.settings().radius = -10.0f;
REQUIRE(b.getInfluence(5.0f) == 0.0f);
b.settings().radius = std::numeric_limits<float>::quiet_NaN();
REQUIRE(b.getInfluence(5.0f) == 0.0f);
}
TEST_CASE("EditorBrush::getInfluence handles zero falloff (hard edge)", "[brush]") {
EditorBrush b;
b.settings().radius = 10.0f;
b.settings().falloff = 0.0f;
REQUIRE(b.getInfluence(0.0f) == 1.0f);
REQUIRE(b.getInfluence(9.99f) == 1.0f);
REQUIRE(b.getInfluence(10.0f) == 0.0f);
}