fwt_software/tests/test_diagparser.cpp

82 lines
2.7 KiB
C++

#include <doctest/doctest.h>
#include "fgc/DiagParser.h"
using namespace fgc;
namespace {
// A DIAG stream as captured on the wire: DG lines interleaved with an ST line.
const char* kDiag =
"DG BEGIN Y\n"
"ST Y:A,5,5,80084000,0,8,8,S P:A,5,5,80084000,0,8,8,S\n"
"DG Y S12500 FWD ERR_PEAK 234 ERR_RMS 45 ERR_STILL 89 CS_MIN 10 CS_MAX 20 "
"SG_MIN 456 PWM_AVG 128 FLAGS 0x00000000 PASS\n"
"DG Y S25000 REV ERR_PEAK 300 ERR_RMS 50 ERR_STILL 100 CS_MIN 11 CS_MAX 21 "
"SG_MIN 400 PWM_AVG 130 FLAGS 0x00000000 PASS\n"
"DG Y RESULT PASS\n"
"DG BEGIN P\n"
"DG P S12500 FWD ERR_PEAK -1 ERR_RMS -1 ERR_STILL -1 CS_MIN 12 CS_MAX 22 "
"SG_MIN 0 PWM_AVG 64 FLAGS 0x00000020 FAIL\n"
"DG P RESULT FAIL\n"
"DG DONE\n";
} // namespace
TEST_CASE("parseDiag decodes axes, tests and results") {
DiagResult d = parseDiag(kDiag);
REQUIRE(d.valid);
CHECK(d.done);
REQUIRE(d.axes.size() == 2);
const DiagAxis& y = d.axes[0];
CHECK(y.axis == 'Y');
CHECK(y.has_result);
CHECK(y.pass);
REQUIRE(y.tests.size() == 2);
CHECK(y.tests[0].speed == 12500);
CHECK(y.tests[0].fwd);
CHECK(y.tests[0].err_peak == 234);
CHECK(y.tests[0].err_still == 89);
CHECK(y.tests[0].cs_min == 10);
CHECK(y.tests[0].cs_max == 20);
CHECK(y.tests[0].sg_min == 456);
CHECK(y.tests[0].pass);
CHECK_FALSE(y.tests[1].fwd); // REV
const DiagAxis& p = d.axes[1];
CHECK(p.axis == 'P');
CHECK_FALSE(p.pass); // RESULT FAIL
REQUIRE(p.tests.size() == 1);
CHECK(p.tests[0].err_peak == -1); // no encoder
CHECK(p.tests[0].flags == 0x20u);
CHECK_FALSE(p.tests[0].pass);
}
TEST_CASE("DiagResult::allPass requires every axis result to pass") {
CHECK_FALSE(parseDiag(kDiag).allPass()); // P failed
DiagResult ok = parseDiag(
"DG BEGIN Y\nDG Y RESULT PASS\nDG BEGIN P\nDG P RESULT PASS\nDG DONE\n");
CHECK(ok.allPass());
}
TEST_CASE("parseDiag handles empty/garbage and incomplete streams") {
CHECK_FALSE(parseDiag("").valid);
CHECK_FALSE(parseDiag("ST Y:A,1,1,0,0,0,0,S\nnothing\n").valid);
DiagResult inc = parseDiag("DG BEGIN Y\nDG Y RESULT PASS\n"); // no DG DONE
CHECK(inc.valid);
CHECK_FALSE(inc.done);
}
TEST_CASE("formatDiag renders a summary") {
auto bad = formatDiag(DiagResult{});
REQUIRE(bad.size() == 1);
CHECK(bad[0].find("no diagnostic") != std::string::npos);
auto good = formatDiag(parseDiag(kDiag));
std::string joined;
for (const auto& l : good) joined += l + "\n";
CHECK(joined.find("[Y]") != std::string::npos);
CHECK(joined.find("[P]") != std::string::npos);
CHECK(joined.find("overall: FAIL") != std::string::npos);
}