#include #include "fgc/ScanGrid.h" using namespace fgc; TEST_CASE("parseScanCsv reads waypoints and skips comments/blanks") { auto pts = parseScanCsv("# header\n\n-90,10\n0, 20 \n90,30\n"); REQUIRE(pts.size() == 3); CHECK(pts[0].yaw_deg == doctest::Approx(-90.0)); CHECK(pts[1].pitch_deg == doctest::Approx(20.0)); CHECK(pts[2].yaw_deg == doctest::Approx(90.0)); } TEST_CASE("parseScanCsv throws on a malformed line") { CHECK_THROWS(parseScanCsv("0,0\nnonsense\n")); CHECK_THROWS(parseScanCsv("1,abc\n")); } TEST_CASE("generateScanGrid produces yaw_intervals x pitch_levels points") { ScanConfig c; c.yaw_intervals = 3; c.yaw_min_deg = -90; c.yaw_max_deg = 90; c.pitch_levels = "10,30"; auto pts = generateScanGrid(c); REQUIRE(pts.size() == 6); // pitch-major, yaw inner (min -> max) CHECK(pts[0].yaw_deg == doctest::Approx(-90.0)); CHECK(pts[0].pitch_deg == doctest::Approx(10.0)); CHECK(pts[1].yaw_deg == doctest::Approx(0.0)); CHECK(pts[2].yaw_deg == doctest::Approx(90.0)); CHECK(pts[3].pitch_deg == doctest::Approx(30.0)); } TEST_CASE("ScanGrid cursor ping-pongs at both ends") { ScanGrid g({{0, 0}, {1, 0}, {2, 0}}); CHECK(g.current().yaw_deg == doctest::Approx(0.0)); g.advance(); CHECK(g.current().yaw_deg == doctest::Approx(1.0)); g.advance(); CHECK(g.current().yaw_deg == doctest::Approx(2.0)); g.advance(); CHECK(g.current().yaw_deg == doctest::Approx(1.0)); // reversed g.advance(); CHECK(g.current().yaw_deg == doctest::Approx(0.0)); g.advance(); CHECK(g.current().yaw_deg == doctest::Approx(1.0)); // reversed again } TEST_CASE("ScanGrid single point and empty are safe") { ScanGrid one({{5, 5}}); one.advance(); CHECK(one.current().yaw_deg == doctest::Approx(5.0)); ScanGrid none; CHECK(none.empty()); }