fwt_software/tests/test_paths.cpp

66 lines
2.5 KiB
C++

#include <doctest/doctest.h>
#include "fgc/Paths.h"
#include <cstdlib>
using namespace fgc;
TEST_CASE("expandUser expands ~ and environment variables") {
setenv("HOME", "/home/tester", 1);
setenv("FOO", "bar", 1);
CHECK(paths::expandUser("~/x") == "/home/tester/x");
CHECK(paths::expandUser("~") == "/home/tester");
CHECK(paths::expandUser("$FOO/y") == "bar/y");
CHECK(paths::expandUser("${FOO}z") == "barz");
CHECK(paths::expandUser("/abs/path") == "/abs/path");
CHECK(paths::expandUser("") == "");
}
TEST_CASE("configSearchPaths honours the CLI argument first") {
auto p = paths::configSearchPaths("/explicit/config.ini");
REQUIRE(!p.empty());
CHECK(p.front() == "/explicit/config.ini");
}
TEST_CASE("hardwareSearchPaths looks in the documented order") {
unsetenv("FGC_HARDWARE");
auto p = paths::hardwareSearchPaths("", "/opt/fgc/config.ini");
auto at = [&](const std::string& s) {
for (size_t i = 0; i < p.size(); ++i)
if (p[i] == s) return static_cast<int>(i);
return -1;
};
// /etc is the normal answer on a tower - root-owned, per-device, and OUTSIDE
// the deploy tree - so it is searched before a checkout-local file.
REQUIRE(at("/etc/fire_gimbal_control/hardware.ini") >= 0);
REQUIRE(at("/opt/fgc/hardware.ini") >= 0);
CHECK(at("/etc/fire_gimbal_control/hardware.ini") < at("/opt/fgc/hardware.ini"));
SUBCASE("an explicit argument outranks everything") {
auto q = paths::hardwareSearchPaths("/tmp/mine.ini", "/opt/fgc/config.ini");
CHECK(q.front() == "/tmp/mine.ini");
}
SUBCASE("the environment outranks /etc but not the argument") {
setenv("FGC_HARDWARE", "/tmp/env.ini", 1);
auto q = paths::hardwareSearchPaths("/tmp/cli.ini", "/opt/fgc/config.ini");
REQUIRE(q.size() >= 2);
CHECK(q[0] == "/tmp/cli.ini");
CHECK(q[1] == "/tmp/env.ini");
unsetenv("FGC_HARDWARE");
}
SUBCASE("with no config path there is simply no sibling candidate") {
auto q = paths::hardwareSearchPaths("", "");
for (const auto& s : q) CHECK(s.find("/opt/fgc/") == std::string::npos);
}
}
TEST_CASE("resolveHardwarePath returns nothing when there is no hardware.ini") {
// Not an error: every existing tower is in this state until it is migrated,
// and the program must go on reading everything from config.ini.
unsetenv("FGC_HARDWARE");
CHECK_FALSE(paths::resolveHardwarePath("/nonexistent/nope.ini", "").has_value());
}