// Unit tests for graph_force_layout_should_pause — el helper puro que el // caller usa para decidir si parar la simulacion tras N frames consecutivos // con energia < umbral. La logica del contador es responsabilidad del caller; // la funcion solo decide "ya cumple" en base al contador y al umbral. #define CATCH_CONFIG_MAIN #include "catch_amalgamated.hpp" #include "viz/graph_force_layout.h" TEST_CASE("should_pause requires consecutive frames over threshold", "[viz][pause]") { const int min_consec = 30; REQUIRE_FALSE(graph_force_layout_should_pause(0, min_consec)); REQUIRE_FALSE(graph_force_layout_should_pause(1, min_consec)); REQUIRE_FALSE(graph_force_layout_should_pause(29, min_consec)); REQUIRE (graph_force_layout_should_pause(30, min_consec)); REQUIRE (graph_force_layout_should_pause(31, min_consec)); REQUIRE (graph_force_layout_should_pause(1000, min_consec)); } TEST_CASE("should_pause with min_consecutive=0 always pauses", "[viz][pause]") { // Edge case: si el caller pide 0 frames, considerar siempre convergido. REQUIRE(graph_force_layout_should_pause(0, 0)); REQUIRE(graph_force_layout_should_pause(1, 0)); } TEST_CASE("should_pause emulating a low->high->low sequence", "[viz][pause]") { // Simula la logica del demo: el caller resetea low_frames cuando energy // sube. should_pause solo depende del valor actual. int low = 0; const int target = 5; // Acumulamos hasta 4: aun no. for (int i = 0; i < 4; ++i) { low++; REQUIRE_FALSE(graph_force_layout_should_pause(low, target)); } // El caller detecta energia alta -> reset. low = 0; REQUIRE_FALSE(graph_force_layout_should_pause(low, target)); // Acumulamos los 5 que pide el target. for (int i = 0; i < 5; ++i) low++; REQUIRE(graph_force_layout_should_pause(low, target)); }