This commit is contained in:
deeaitch committed 2026-10-07 18:59:18 -04:00
1 parent 3dd9230fca
commit 8bf5dcff30
5 files changed
+120 -9

No files matched your search

+99 -8
View File
@@ -42,8 +42,8 @@ public:
std::string SignalLine(const std::string &start, const std::string &length,
const std::string &order, const std::string &factor,
const std::string &offset, const std::string &minimum,
const std::string &maximum) {
return "SG_ Value : " + start + "|" + length + "@" + order +
const std::string &maximum, const std::string &name = "Value") {
return "SG_ " + name + " : " + start + "|" + length + "@" + order +
" (" + factor + "," + offset + ") [" + minimum + "|" + maximum + "] \"\" ECU";
}
@@ -67,6 +67,9 @@ private Q_SLOTS:
void multiplexingBoundaries();
void validFrames();
void invalidFrames();
void duplicateFrames();
void duplicateSignals();
void distinctDefinitions();
void integration();
void invalidSignals();
void validSignals();
@@ -134,6 +137,93 @@ void DbcParserTest::invalidFrames() {
}
}
void DbcParserTest::duplicateFrames() {
Fixture fixture;
struct DuplicateCase {
const char *firstId;
const char *duplicateId;
const char *message;
};
const DuplicateCase cases[] = {
{"1", "1", "Duplicate standard frame CAN ID: 1"},
{"2147483649", "2147483649", "Duplicate extended frame CAN ID: 1"},
{"2048", "2147485696", "Duplicate extended frame CAN ID: 2048"},
{"2147485696", "2048", "Duplicate extended frame CAN ID: 2048"},
{"536870911", "2684354559", "Duplicate extended frame CAN ID: 536870911"}
};
const DbcParser parser;
for (const DuplicateCase &test : cases) {
fixture.Write("BO_ " + std::string(test.firstId) + " First: 8 ECU\n"
"BO_ 2 Other: 8 ECU\n\n"
" BO_\t" + test.duplicateId + "\tSecond: 8 ECU\n");
try {
parser.ParseFile(fixture.path.string());
CHECK(false, "Duplicate frame must be rejected");
} catch (const std::runtime_error &error) {
QCOMPARE(std::string(error.what()), fixture.path.string() + ":4: " + test.message);
}
}
fixture.Write("BO_ 1 First: 8 ECU\n");
QCOMPARE(parser.ParseFile(fixture.path.string()).frames.size(), std::size_t(1U));
}
void DbcParserTest::duplicateSignals() {
Fixture fixture;
const std::string first = "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n";
const std::string duplicates[] = {
first,
" SG_\tState : 16|8@1+ (2,1) [0|511] \"V\" ECU\n",
"SG_ State m1 : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
};
for (const std::string &duplicate : duplicates) {
fixture.Write("BO_ 1 Frame: 8 ECU\n" + first +
"SG_ Other : 8|8@1+ (1,0) [0|255] \"\" ECU\n\n" + duplicate);
try {
DbcParser().ParseFile(fixture.path.string());
CHECK(false, "Duplicate signal must be rejected");
} catch (const std::runtime_error &error) {
QCOMPARE(std::string(error.what()), fixture.path.string() +
":5: Duplicate signal name 'State' in frame 'Frame'.");
}
}
}
void DbcParserTest::distinctDefinitions() {
Fixture fixture;
fixture.Write("BO_ 1 Shared: 1 ECU\n"
"SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
"BO_ 2147483649 Shared: 1 ECU\n"
"SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
"BO_ 2 Shared: 2 ECU\n"
"SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
"SG_ state : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
"CM_ BO_ 1 \"Standard\";\n"
"CM_ BO_ 2147483649 \"Extended\";\n"
"CM_ SG_ 1 State \"Standard state\";\n"
"CM_ SG_ 2147483649 State \"Extended state\";\n");
const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
QCOMPARE(parsed.frames.size(), std::size_t(3U));
QCOMPARE(parsed.frames[0].canId, parsed.frames[1].canId);
CHECK(!parsed.frames[0].isExtended && parsed.frames[1].isExtended,
"Standard and extended frames with the same numeric ID remain distinct");
QCOMPARE(parsed.frames[0].comment, std::string("Standard"));
QCOMPARE(parsed.frames[1].comment, std::string("Extended"));
QCOMPARE(parsed.frames[0].signals[0].comment, std::string("Standard state"));
QCOMPARE(parsed.frames[1].signals[0].comment, std::string("Extended state"));
QCOMPARE(parsed.frames[2].signals.size(), std::size_t(2U));
const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
RawCanFrame raw;
raw.canId = 1U;
raw.data = {7U};
const DecodedFrameValue standard = DbcDecoder().Decode(runtime, raw);
QVERIFY(standard.valid);
QCOMPARE(standard.definition->comment, std::string("Standard"));
raw.isExtended = true;
const DecodedFrameValue extended = DbcDecoder().Decode(runtime, raw);
QVERIFY(extended.valid);
QCOMPARE(extended.definition->comment, std::string("Extended"));
}
void DbcParserTest::integration() {
Fixture fixture;
fixture.Write(
@@ -324,7 +414,7 @@ void DbcParserTest::validSignals() {
const DbcParser signalParser;
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");
SignalLine("8", "8", "1-", "-1", "0", "-255", "0", "Negative") + "\n");
const DbcDatabase factors = signalParser.ParseFile(fixture.path.string());
CHECK(factors.frames[0].signals.size() == 2U &&
factors.frames[0].signals[0].factor == 0.0 &&
@@ -506,17 +596,18 @@ void DbcParserTest::invalidValueDescriptions() {
}
}
for (const std::string suffix: {
"BO_ 1 Other: 8 ECU\n", // Ambiguous normalized frame reference.
"SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n",// Ambiguous signal reference.
"BO_ 1 Other: 8 ECU\n", // Duplicate frame definition.
"SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n",// Duplicate signal definition.
""}) {
fixture.Write("VAL_ 1 " + std::string(suffix.empty() ? "Missing" : "State") +
" 0 \"Description\";\n" + definitions + suffix);
try {
DbcParser().ParseFile(fixture.path.string());
CHECK(false, "Deferred missing or ambiguous reference");
CHECK(false, "Missing reference or duplicate definition");
} catch (const std::runtime_error &error) {
CHECK(std::string(error.what()).find(fixture.path.string() + ":1: ") == 0,
"Deferred reference retains source location");
const std::string line = suffix.empty() ? "1" : "4";
CHECK(std::string(error.what()).find(fixture.path.string() + ":" + line + ": ") == 0,
"Error retains the reference or duplicate definition source location");
}
}
for (const std::string number: {"+1", "1x", "0x10", "1.5", "1e2", "--1",