#include #include "fgc/CommandParser.h" using namespace fgc; TEST_CASE("parseCommand handles single-verb commands") { auto c = parseCommand("snapshot"); CHECK(c.verb == "snapshot"); CHECK(c.device.empty()); CHECK_FALSE(c.has_value); } TEST_CASE("parseCommand takes the second word as the device") { auto c = parseCommand("capture on"); CHECK(c.verb == "capture"); CHECK(c.device == "on"); CHECK(c.option.empty()); CHECK_FALSE(c.has_value); } TEST_CASE("parseCommand keeps option plus trailing numeric value") { auto c = parseCommand("gimbal nudge yaw 5"); CHECK(c.verb == "gimbal"); CHECK(c.device == "nudge"); CHECK(c.option == "yaw"); CHECK(c.has_value); CHECK(c.value == doctest::Approx(5.0)); } TEST_CASE("parseCommand joins non-numeric trailing words into the option") { auto c = parseCommand("set camera profile night"); CHECK(c.device == "camera"); CHECK(c.option == "profile night"); CHECK_FALSE(c.has_value); } TEST_CASE("parseCommand on empty input") { CHECK(parseCommand("").empty()); CHECK(parseCommand(" ").empty()); } TEST_CASE("parseAim reads yaw with an optional pitch") { auto tok = [](std::vector v) { v.insert(v.begin(), {"gimbal", "move"}); return v; }; auto both = parseAim(tok({"30,-10"}), 2); REQUIRE(both); CHECK(both->yaw == doctest::Approx(30.0)); REQUIRE(both->pitch); CHECK(*both->pitch == doctest::Approx(-10.0)); auto spaced = parseAim(tok({"30", "-10"}), 2); REQUIRE(spaced); REQUIRE(spaced->pitch); CHECK(*spaced->pitch == doctest::Approx(-10.0)); CHECK(parseAim(tok({"30,", "-10"}), 2)->pitch.has_value()); auto yaw_only = parseAim(tok({"90"}), 2); REQUIRE(yaw_only); CHECK(yaw_only->yaw == doctest::Approx(90.0)); CHECK_FALSE(yaw_only->pitch); CHECK_FALSE(parseAim(tok({}), 2)); CHECK_FALSE(parseAim(tok({"abc"}), 2)); CHECK_FALSE(parseAim(tok({"30,x"}), 2)); CHECK_FALSE(parseAim(tok({"1,2,3"}), 2)); } TEST_CASE("moveCommand sends both axes with a pitch, yaw alone without") { CHECK(moveCommand(100000, 250000) == "MOVE 100000,250000"); CHECK(moveCommand(-5, -7) == "MOVE -5,-7"); // The yaw-only form: a 1-axis firmware refuses the pair with "axis not present". CHECK(moveCommand(100000, std::nullopt) == "MOVE Y 100000"); }