From 2400271a4f073b84ee205c553de6d8f9c3368c36 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 08:05:43 -0700 Subject: [PATCH] test(brush): add 6 EditorBrush::getInfluence tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- tests/CMakeLists.txt | 1 + tests/test_editor_units.cpp | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 69d9f521..47bbb27d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 diff --git a/tests/test_editor_units.cpp b/tests/test_editor_units.cpp index 6700b952..92fc6518 100644 --- a/tests/test_editor_units.cpp +++ b/tests/test_editor_units.cpp @@ -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 +#include + +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::quiet_NaN()) == 0.0f); + REQUIRE(b.getInfluence(std::numeric_limits::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::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); +}