This commit is contained in:
deeaitch committed 2026-10-07 18:50:11 -04:00
1 parent a0938cb29c
commit 3dd9230fca
21 files changed
+491 -450

No files matched your search

+28 -21
View File
@@ -49,7 +49,7 @@ void DbcDecoderTest::decode_data() {
{"Intel signed regression", ByteOrder::Intel, 0U, 16U, ValueType::Signed, {0xFE, 0xFF}, true, -2, 0.5, 10.0, 9.0},
{"Intel short payload", ByteOrder::Intel, 0U, 16U, ValueType::Unsigned, {0x12}, false, 0, 1.0, 0.0, 0.0}};
for (const auto &test: cases)
for (const DecodeCase &test: cases)
QTest::newRow(test.name) << test;
}
@@ -76,19 +76,25 @@ void DbcDecoderTest::decode() {
frame.canId = definition.canId;
frame.data = test.data;
const DecodedFrameValue result = DbcDecoder().Decode(database, frame);
const bool passed = result.valid &&
(result.definition == &database.frames[0]) &&
(result.signals.size() == 1U) &&
(result.signals[0].definition == &database.frames[0].signals[0]) &&
(result.signals[0].valid == test.valid) &&
(!test.valid || (((test.valueType == ValueType::Signed)
? (std::get_if<std::int64_t>(&result.signals[0].rawValue) &&
std::get<std::int64_t>(result.signals[0].rawValue) == test.rawValue)
: (std::get_if<std::uint64_t>(&result.signals[0].rawValue) &&
std::get<std::uint64_t>(result.signals[0].rawValue) ==
static_cast<std::uint64_t>(test.rawValue))) &&
(result.signals[0].physicalValue == test.physicalValue)));
QVERIFY2(passed, test.name);
QVERIFY2(result.valid, test.name);
QCOMPARE(result.definition, &database.frames[0]);
QCOMPARE(result.signals.size(), std::size_t(1U));
const DecodedSignalValue &decoded = result.signals[0];
QCOMPARE(decoded.definition, &database.frames[0].signals[0]);
QCOMPARE(decoded.valid, test.valid);
if (!test.valid)
return;
if (test.valueType == ValueType::Signed) {
const std::int64_t *raw = std::get_if<std::int64_t>(&decoded.rawValue);
QVERIFY(raw != nullptr);
QCOMPARE(*raw, test.rawValue);
} else {
const std::uint64_t *raw = std::get_if<std::uint64_t>(&decoded.rawValue);
QVERIFY(raw != nullptr);
QCOMPARE(*raw, static_cast<std::uint64_t>(test.rawValue));
}
QCOMPARE(decoded.physicalValue, test.physicalValue);
}
void DbcDecoderTest::boundaries() {
@@ -115,13 +121,13 @@ void DbcDecoderTest::boundaries() {
const unsigned shift = (order == ByteOrder::Intel ? byte : 7U - byte) * 8U;
frame.data.push_back(static_cast<std::uint8_t>(bits >> shift));
}
const auto result = DbcDecoder().Decode(database, frame);
const DecodedFrameValue result = DbcDecoder().Decode(database, frame);
const std::int64_t signedExpected = bits <= 0x7FFFFFFFFFFFFFFFULL
? static_cast<std::int64_t>(bits)
: std::numeric_limits<std::int64_t>::min() +
static_cast<std::int64_t>(bits - 0x8000000000000000ULL);
const auto &decoded = result.signals.at(0U);
const auto expected = type == ValueType::Unsigned
const DecodedSignalValue &decoded = result.signals.at(0U);
const RawSignalValue expected = type == ValueType::Unsigned
? std::variant<std::int64_t, std::uint64_t>(bits)
: std::variant<std::int64_t, std::uint64_t>(signedExpected);
const double physical = (type == ValueType::Unsigned
@@ -131,7 +137,7 @@ void DbcDecoderTest::boundaries() {
10.0;
std::ostringstream actualText;
std::ostringstream expectedText;
if (const auto *signedValue = std::get_if<std::int64_t>(&decoded.rawValue))
if (const std::int64_t *signedValue = std::get_if<std::int64_t>(&decoded.rawValue))
actualText << *signedValue;
else
actualText << std::get<std::uint64_t>(decoded.rawValue);
@@ -139,9 +145,10 @@ void DbcDecoderTest::boundaries() {
expectedText << bits;
else
expectedText << signedExpected;
QVERIFY2(decoded.valid && decoded.rawValue == expected &&
decoded.physicalValue == physical && actualText.str() == expectedText.str(),
expectedText.str().c_str());
QVERIFY(decoded.valid);
QVERIFY(decoded.rawValue == expected);
QCOMPARE(decoded.physicalValue, physical);
QCOMPARE(actualText.str(), expectedText.str());
}
}
}
+36 -34
View File
@@ -92,16 +92,17 @@ void DbcParserTest::validFrames() {
{"BO_ 2147483649 Frame: 8 ECU", 1U, true, 8U},
{"BO_ 2684354559 Frame: 8 ECU", 0x1FFFFFFFU, true, 8U},
{" BO_\t256\tFrame :\t8\tECU \r", 256U, false, 8U}};
for (const auto &test: valid) {
for (const ValidCase &test: valid) {
fixture.Write(std::string(test.line) + '\n');
try {
const auto database = DbcParser().ParseFile(fixture.path.string());
CHECK(database.frames.size() == 1U && database.frames[0].name == "Frame" &&
database.frames[0].canId == test.id &&
database.frames[0].isExtended == test.extended &&
database.frames[0].dlc == test.length &&
database.frames[0].transmitter == "ECU",
test.line);
const DbcDatabase database = DbcParser().ParseFile(fixture.path.string());
QCOMPARE(database.frames.size(), std::size_t(1U));
const FrameInfo &frame = database.frames[0];
QCOMPARE(frame.name, std::string("Frame"));
QCOMPARE(frame.canId, test.id);
QCOMPARE(frame.isExtended, test.extended);
QCOMPARE(static_cast<unsigned>(frame.dlc), test.length);
QCOMPARE(frame.transmitter, std::string("ECU"));
} catch (const std::exception &error) { CHECK(false, error.what()); }
}
}
@@ -119,7 +120,7 @@ void DbcParserTest::invalidFrames() {
"BO_ 1 Frame: -1 ECU", "BO_ 1 Frame: +8 ECU", "BO_ 1 Frame: 8x ECU",
"BO_ 1 Frame: 8.5 ECU", "BO_ 1 Frame: 256 ECU",
"BO_ 1 Frame: 4294967296 ECU", "BO_\tinvalid"};
for (const auto *line: invalid) {
for (const char *line: invalid) {
fixture.Write(std::string("VERSION \"test\"\n\n") + line + '\n');
try {
DbcParser().ParseFile(fixture.path.string());
@@ -140,7 +141,7 @@ void DbcParserTest::integration() {
" SG_ Speed : 0|16@1+ (0.5,1) [0|100] \"rpm\" ECU\n"
"CM_ BO_ 256 \"Frame comment\";\nCM_ SG_ 256 Speed \"Signal comment\";\n"
"BO_ 257 Second: 8 ECU\n");
const auto database = DbcParser().ParseFile(fixture.path.string());
const DbcDatabase database = DbcParser().ParseFile(fixture.path.string());
CHECK(database.frames.size() == 2U && database.frames[0].signals.size() == 1U &&
database.frames[0].comment == "Frame comment" &&
database.frames[0].signals[0].comment == "Signal comment",
@@ -324,7 +325,7 @@ void DbcParserTest::validSignals() {
fixture.Write("BO_ 1 Frame: 8 ECU\n" +
SignalLine("0", "8", "1+", "0", "0", "0", "0") + "\n" +
SignalLine("8", "8", "1-", "-1", "0", "-255", "0") + "\n");
const auto factors = signalParser.ParseFile(fixture.path.string());
const DbcDatabase factors = signalParser.ParseFile(fixture.path.string());
CHECK(factors.frames[0].signals.size() == 2U &&
factors.frames[0].signals[0].factor == 0.0 &&
factors.frames[0].signals[1].factor == -1.0,
@@ -345,26 +346,27 @@ void DbcParserTest::validSignals() {
{"56", "1", "0+", 8U},
{"3", "12", "0+", 2U},
{"2039", "1", "1+", 255U}};
for (const auto &test: validSignals) {
for (const SignalCase &test: validSignals) {
fixture.Write("BO_ 1 Frame: " + std::to_string(test.payload) + " ECU\n" +
SignalLine(test.start, test.length, test.order, ".5e+1", "-2.5E-1", "-1.", "+2e2") + "\n");
try {
const auto parsed = signalParser.ParseFile(fixture.path.string());
const auto &signal = parsed.frames.at(0).signals.at(0);
CHECK(signal.startBit == std::stoul(test.start) &&
signal.length == std::stoul(test.length) &&
signal.isLittleEndian == (test.order[0] == '1') &&
signal.isSigned == (test.order[1] == '-') &&
signal.factor == 5.0 && signal.offset == -0.25 &&
signal.minimum == -1.0 && signal.maximum == 200.0,
"Valid signal boundary and numeric metadata");
const DbcDatabase parsed = signalParser.ParseFile(fixture.path.string());
const SignalInfo &signal = parsed.frames.at(0).signals.at(0);
QCOMPARE(signal.startBit, static_cast<std::uint32_t>(std::stoul(test.start)));
QCOMPARE(signal.length, static_cast<std::uint32_t>(std::stoul(test.length)));
QCOMPARE(signal.isLittleEndian, test.order[0] == '1');
QCOMPARE(signal.isSigned, test.order[1] == '-');
QCOMPARE(signal.factor, 5.0);
QCOMPARE(signal.offset, -0.25);
QCOMPARE(signal.minimum, -1.0);
QCOMPARE(signal.maximum, 200.0);
} catch (const std::exception &error) { CHECK(false, error.what()); }
}
fixture.Write("BO_ 1 Frame: 8 ECU\n"
"SG_\tValue\t:\t0 | 8 @1+ ( 1 , 0 ) [ 0 | 255 ] \"rpm\" ECU1,\tECU2\n");
try {
const auto parsed = signalParser.ParseFile(fixture.path.string());
const auto &signal = parsed.frames.at(0).signals.at(0);
const DbcDatabase parsed = signalParser.ParseFile(fixture.path.string());
const SignalInfo &signal = parsed.frames.at(0).signals.at(0);
CHECK(signal.name == "Value" && signal.unit == "rpm" &&
signal.receivers == std::vector<std::string>({"ECU1", "ECU2"}),
"Signal tabs, spaces, and receiver list");
@@ -405,7 +407,7 @@ void DbcParserTest::independentSessions() {
"Independent parse context");
}
fixture.Write("BO_ 2 Second: 8 ECU\n");
const auto recovered = parser.ParseFile(fixture.path.string());
const DbcDatabase recovered = parser.ParseFile(fixture.path.string());
CHECK(recovered.frames.size() == 1U && recovered.frames[0].canId == 2U,
"Fresh parse after error");
}
@@ -424,9 +426,9 @@ void DbcParserTest::valueDescriptions() {
"BO_ 2048 Unsigned: 8 ECU\n"
"SG_ State : 0|64@1+ (1,0) [0|2e20] \"\" ECU\n"
"VAL_ 2147485696 State 9223372036854775808 \"High\" 18446744073709551615 \"Full\";\n");
const auto parsed = DbcParser().ParseFile(fixture.path.string());
const auto runtime = DbcDecodeBuilder().Build(parsed);
const auto tree = DbcTreeBuilder().Build(parsed);
const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed);
CHECK(tree->GetChild(0)->GetSignal() == nullptr, "Frame node");
for (std::size_t index = 0; index < parsed.frames.size(); ++index) {
CHECK(tree->GetChild(index)->GetChild(0)->GetSignal()->valueDescriptions ==
@@ -444,9 +446,9 @@ void DbcParserTest::valueDescriptions() {
const std::string expected[] = {"Off", "On", "Error with spaces; and \"quotes\"", ""};
for (unsigned value = 0; value < 5; ++value) {
frame.data[0] = value;
const auto decoded = DbcDecoder().Decode(runtime, frame).signals[0];
const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
CHECK(decoded.valid && decoded.physicalValue == value * 2 + 10, "Numeric scaling unchanged");
const auto description = decoded.GetValueDescription();
const std::string *description = decoded.GetValueDescription();
CHECK(value < 4 ? description && *description == expected[value] : !description,
"Raw lookup and unknown value");
}
@@ -455,21 +457,21 @@ void DbcParserTest::valueDescriptions() {
std::uint64_t bits;
const char *description;
};
for (const auto &test: {Boundary{0x8000000000000000ULL, "Minimum"},
for (const Boundary &test: {Boundary{0x8000000000000000ULL, "Minimum"},
Boundary{0xFFFFFFFFFFFFFFFFULL, "Negative"},
Boundary{0x7FFFFFFFFFFFFFFFULL, "Maximum"}}) {
for (unsigned byte = 0; byte < 8; ++byte)
frame.data[byte] = static_cast<std::uint8_t>(test.bits >> (byte * 8));
const auto decoded = DbcDecoder().Decode(runtime, frame).signals[0];
const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
CHECK(decoded.GetValueDescription() && *decoded.GetValueDescription() == test.description,
"Signed boundaries and distinct extended frame");
}
frame.canId = 2048;
for (const auto &test: {Boundary{0x8000000000000000ULL, "High"},
for (const Boundary &test: {Boundary{0x8000000000000000ULL, "High"},
Boundary{0xFFFFFFFFFFFFFFFFULL, "Full"}}) {
for (unsigned byte = 0; byte < 8; ++byte)
frame.data[byte] = static_cast<std::uint8_t>(test.bits >> (byte * 8));
const auto decoded = DbcDecoder().Decode(runtime, frame).signals[0];
const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
CHECK(decoded.GetValueDescription() && *decoded.GetValueDescription() == test.description,
"Unsigned boundaries");
}
@@ -494,7 +496,7 @@ void DbcParserTest::invalidValueDescriptions() {
"VAL_ 4294967296 State 0 \"Bad ID\";", "VAL_ Environment 0 \"Unsupported\";",
"VAL_ 1 State 0 \"Bad\\q escape\";"}) {
fixture.Write(definitions + statement + '\n');
const auto line = statement.find('\n') == std::string::npos ? 3 : 4;
const int line = statement.find('\n') == std::string::npos ? 3 : 4;
try {
DbcParser().ParseFile(fixture.path.string());
CHECK(false, statement);
+2 -2
View File
@@ -16,7 +16,7 @@ int main() {
frame.signals.push_back(signal);
database.frames.push_back(frame);
database.frames.push_back(frame);
auto root = DbcTreeBuilder().Build(database);
std::unique_ptr<TreeNode> root = DbcTreeBuilder().Build(database);
Check(root->GetParent() == nullptr && root->GetRow() == 0);
root->AddChild(nullptr);
Check(root->GetChildCount() == 2 && !root->GetChild(2));
@@ -28,6 +28,6 @@ int main() {
Check(leaf->GetParent() == child && leaf->GetRow() == position);
}
}
auto transferred = std::move(root);
std::unique_ptr<TreeNode> transferred = std::move(root);
Check(transferred->GetChild(0)->GetParent() == transferred.get());
}