#include #include "fgc/HelpText.h" #include using namespace fgc; namespace { std::string join(const std::vector& v) { std::string s; for (const auto& l : v) s += l + "\n"; return s; } } // namespace TEST_CASE("helpCatalog is well-formed") { const auto& cat = helpCatalog(); REQUIRE_FALSE(cat.empty()); for (const auto& sec : cat) { CHECK_FALSE(sec.title.empty()); CHECK_FALSE(sec.entries.empty()); for (const auto& e : sec.entries) { CHECK_FALSE(e.syntax.empty()); CHECK_FALSE(e.summary.empty()); } } } TEST_CASE("renderHelp() with no topic lists every section and entry") { std::string out = join(renderHelp("")); CHECK(out.find("help ") != std::string::npos); // the usage hint // Each catalog section title and entry syntax should appear. for (const auto& sec : helpCatalog()) { CHECK(out.find(sec.title) != std::string::npos); for (const auto& e : sec.entries) CHECK(out.find(e.syntax) != std::string::npos); } // A couple of the commands. CHECK(out.find("gimbal move") != std::string::npos); CHECK(out.find("gimbal pitch setup") != std::string::npos); CHECK(out.find("gimbal heading setup") != std::string::npos); } TEST_CASE("renderHelp(
) expands that section with detail") { std::string out = join(renderHelp("positioning")); CHECK(out.find("gimbal move ,") != std::string::npos); // Detail lines (example) are only emitted in topic mode. CHECK(out.find("gimbal move 30,-10") != std::string::npos); } TEST_CASE("renderHelp() matches the gimbal commands, case-insensitively") { std::string lower = join(renderHelp("gimbal")); std::string upper = join(renderHelp("GIMBAL")); CHECK(lower.find("gimbal move ,") != std::string::npos); CHECK(lower.find("gimbal pitch setup") != std::string::npos); // The removed `gimbal calib` must not linger anywhere in the catalog. CHECK(lower.find("gimbal calib") == std::string::npos); CHECK(lower == upper); } TEST_CASE("renderHelp(imu) matches the whole imu family") { // `imu` is both a section title and the verb of every entry in it, so the // topic lookup must find the family either way. std::string out = join(renderHelp("imu")); for (const char* sub : {"imu status", "imu config", "imu profile", "imu zero", "imu norotation"}) CHECK(out.find(sub) != std::string::npos); CHECK(join(renderHelp("imu")) == join(renderHelp("IMU"))); } TEST_CASE("help detail stays a short paragraph") { // The catalog is operator-facing reference, not prose: cap it so entries do // not creep back to half-screen blocks. for (const auto& sec : helpCatalog()) for (const auto& e : sec.entries) CHECK(e.detail.size() <= 5); } TEST_CASE("renderHelp(unknown) reports no match") { std::string out = join(renderHelp("definitely-not-a-command")); CHECK(out.find("No help topic") != std::string::npos); }