82 lines
2.7 KiB
C++
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);
|
|
}
|