Closes #29
This commit is contained in:
1 parent
a702cffd93
commit
8d06165979
18 files changed
+611
-215
No files matched your search
+237
-44
@@ -103,6 +103,8 @@ private Q_SLOTS:
|
||||
void diagnosticFormatting();
|
||||
void multiplexing();
|
||||
void multiplexingBoundaries();
|
||||
void extendedMultiplexing();
|
||||
void extendedMultiplexingErrors();
|
||||
void validFrames();
|
||||
void invalidFrames();
|
||||
void duplicateFrames();
|
||||
@@ -458,41 +460,40 @@ void DbcParserTest::diagnosticErrors() {
|
||||
std::size_t line;
|
||||
};
|
||||
const ErrorCase cases[] = {
|
||||
{"UNKNOWN_ data;\n\nBO_ invalid Frame: 1 ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 3U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_MUL_VAL_ 1 Value Mode 1-2;\n",
|
||||
DbcDiagnosticCode::UnsupportedStatement, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nVAL_ 1 Missing 0 \"Off\";\n",
|
||||
DbcDiagnosticCode::InvalidValueDescription, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 2U},
|
||||
{"VAL_ broken\n", DbcDiagnosticCode::InvalidValueDescription, 1U},
|
||||
{"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 1U},
|
||||
{"BO_ 1 Frame: 1 ECU\nBO_ 1 Duplicate: 1 ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 3U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nVAL_ 2 Missing 0 \"Off\";\n",
|
||||
DbcDiagnosticCode::InvalidValueDescription, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"VAL_ 1 Value 0 \"Off\";\nVAL_ 1 Value 0 \"Duplicate\";\n",
|
||||
DbcDiagnosticCode::InvalidValueDescription, 4U},
|
||||
{"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n"
|
||||
"SG_ Value m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 3U},
|
||||
{"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Other M : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 3U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ First : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Second : 7|8@0+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 3U}
|
||||
};
|
||||
{"UNKNOWN_ data;\n\nBO_ invalid Frame: 1 ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 3U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_MUL_VAL_ 1 Value Mode 1-2;\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nVAL_ 1 Missing 0 \"Off\";\n",
|
||||
DbcDiagnosticCode::InvalidValueDescription, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 2U},
|
||||
{"VAL_ broken\n", DbcDiagnosticCode::InvalidValueDescription, 1U},
|
||||
{"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 1U},
|
||||
{"BO_ 1 Frame: 1 ECU\nBO_ 1 Duplicate: 1 ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 3U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidStatement, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nVAL_ 2 Missing 0 \"Off\";\n",
|
||||
DbcDiagnosticCode::InvalidValueDescription, 2U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"VAL_ 1 Value 0 \"Off\";\nVAL_ 1 Value 0 \"Duplicate\";\n",
|
||||
DbcDiagnosticCode::InvalidValueDescription, 4U},
|
||||
{"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n"
|
||||
"SG_ Value m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 3U},
|
||||
{"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Other M : 8|8@1- (1,0) [-128|127] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 3U},
|
||||
{"BO_ 1 Frame: 1 ECU\nSG_ First : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Second : 7|8@0+ (1,0) [0|255] \"\" ECU\n",
|
||||
DbcDiagnosticCode::InvalidMultiplexing, 3U}};
|
||||
for (const ErrorCase &test : cases) {
|
||||
fixture.Write(test.text);
|
||||
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
@@ -980,15 +981,14 @@ void DbcParserTest::multiplexing() {
|
||||
"Unavailable selector does not imply inactive branch");
|
||||
|
||||
const std::vector<std::string> invalid = {
|
||||
first,
|
||||
selector + "SG_ Other M : 16|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
"SG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
|
||||
selector + "SG_ TooLarge m256 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
selector + first + "SG_ Same m1 : 15|8@0+ (1,0) [0|255] \"\" ECU\n",
|
||||
selector + "SG_ Collision m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
selector + first + "SG_ Always : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
"SG_MUL_VAL_ 1 First Mode 1-2;\n"
|
||||
};
|
||||
first,
|
||||
selector + "SG_ Other M : 16|8@1- (1,0) [-128|127] \"\" ECU\n",
|
||||
"SG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
|
||||
selector + "SG_ TooLarge m256 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
selector + first + "SG_ Same m1 : 15|8@0+ (1,0) [0|255] \"\" ECU\n",
|
||||
selector + "SG_ Collision m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
selector + first + "SG_ Always : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
|
||||
"SG_MUL_VAL_ 1 First Mode 1-2;\n"};
|
||||
for (const std::string &signals : invalid) {
|
||||
fixture.Write("BO_ 1 Frame: 3 ECU\n" + signals);
|
||||
bool rejected = false;
|
||||
@@ -1374,6 +1374,199 @@ void DbcParserTest::invalidValueDescriptions() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DbcParserTest::extendedMultiplexing() {
|
||||
Fixture fixture;
|
||||
// Forward references, multiple ranges, repeated range statements, and nested siblings.
|
||||
fixture.Write(
|
||||
"SG_MUL_VAL_ 1 Child Root 1-2, 4-4;\n"
|
||||
"SG_MUL_VAL_ 1 Leaf Child 3-5;\n"
|
||||
"SG_MUL_VAL_ 1 Leaf Child 7-7;\n"
|
||||
"SG_MUL_VAL_ 1 Sibling Root 6-6;\n"
|
||||
"SG_MUL_VAL_ 1 Other Sibling 3-5;\n"
|
||||
"BO_ 1 Frame: 4 ECU\n"
|
||||
"SG_ Leaf m99 : 16|8@1- (2,1) [-128|127] \"\" ECU\n"
|
||||
"SG_ Other m0 : 23|8@0+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Child m1M : 8|8@1+ (10,3) [0|255] \"\" ECU\n"
|
||||
"SG_ Sibling m6M : 15|8@0+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Root M : 0|8@1+ (10,3) [0|255] \"\" ECU\n"
|
||||
"SG_ Common : 24|8@1+ (1,0) [0|255] \"\" ECU\n");
|
||||
const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
|
||||
const DecodeDatabase database = DbcDecodeBuilder().Build(parsed);
|
||||
const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed);
|
||||
const Multiplexing &metadata = tree->GetChild(0U)->GetChild(0U)->GetSignal()->multiplexing;
|
||||
CHECK(metadata.selector == "Child" && metadata.ranges.size() == 2U &&
|
||||
metadata.ranges[1].minimum == 7U,
|
||||
"Tree preserves ranges and selector name");
|
||||
CHECK(database.GetFrames()[0].signals[2].multiplexing.role == MultiplexRole::BranchSelector,
|
||||
"Runtime preserves nested selector role");
|
||||
RawCanFrame raw;
|
||||
raw.canId = 1U;
|
||||
raw.data = {2U, 4U, 255U, 8U};
|
||||
DecodedFrameValue result = DbcDecoder().Decode(database, raw);
|
||||
CHECK(result.signals[0].valid && result.signals[0].physicalValue == -1.0 &&
|
||||
result.signals[1].status == SignalDecodeStatus::Inactive && result.signals[2].valid &&
|
||||
result.signals[3].status == SignalDecodeStatus::Inactive && result.signals[5].valid,
|
||||
"Nested raw conditions select one path and preserve definition order");
|
||||
const std::vector<SignalKey> selection = {SignalKey(FrameKey(1U, false), "Leaf")};
|
||||
result = DbcDecoder().Decode(database, raw, selection);
|
||||
CHECK(result.signals.size() == 1U && result.signals[0].valid,
|
||||
"Selection reads all ancestors internally");
|
||||
for (std::uint8_t root: {1U, 2U, 4U}) {
|
||||
for (std::uint8_t child: {3U, 5U, 7U}) {
|
||||
raw.data = {root, child, 9U, 8U};
|
||||
CHECK(DbcDecoder().Decode(database, raw, selection).signals[0].valid,
|
||||
"Inclusive endpoints and separated ranges");
|
||||
}
|
||||
}
|
||||
raw.data = {6U, 4U, 9U, 8U};
|
||||
result = DbcDecoder().Decode(database, raw);
|
||||
CHECK(result.signals[0].status == SignalDecodeStatus::Inactive && result.signals[1].valid &&
|
||||
result.signals[3].valid,
|
||||
"Overlapping sibling selector path becomes active");
|
||||
raw.data = {0U};
|
||||
CHECK(DbcDecoder().Decode(database, raw, selection).signals[0].status == SignalDecodeStatus::Inactive,
|
||||
"Inactive root does not require child selector bytes");
|
||||
raw.data = {1U};
|
||||
CHECK(DbcDecoder().Decode(database, raw, selection).signals[0].status == SignalDecodeStatus::SelectorUnavailable,
|
||||
"Active root with missing child selector");
|
||||
raw.data = {1U, 3U};
|
||||
CHECK(DbcDecoder().Decode(database, raw, selection).signals[0].status == SignalDecodeStatus::InsufficientPayload,
|
||||
"Active nested leaf needs its bytes");
|
||||
raw.data = {1U, 6U};
|
||||
CHECK(DbcDecoder().Decode(database, raw, selection).signals[0].status == SignalDecodeStatus::Inactive,
|
||||
"Gap between explicit ranges does not fall back to mN");
|
||||
raw.data.clear();
|
||||
CHECK(DbcDecoder().Decode(database, raw, selection).signals[0].status == SignalDecodeStatus::SelectorUnavailable,
|
||||
"Missing root selector");
|
||||
|
||||
fixture.Write("BO_ 1 Frame: 9 ECU\n"
|
||||
"SG_ Root M : 0|64@1+ (1,0) [0|1] \"\" ECU\n"
|
||||
"SG_ Leaf m0 : 64|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_MUL_VAL_ 1 Leaf Root 18446744073709551614-18446744073709551615;\n");
|
||||
raw.data.assign(9U, 255U);
|
||||
CHECK(DbcDecoder().Decode(DbcDecodeBuilder().Build(DbcParser().ParseFile(fixture.path.string())), raw).signals[1].valid,
|
||||
"64-bit ranges retain exact UINT64_MAX without expansion");
|
||||
|
||||
fixture.Write("BO_ 1 Frame: 4 ECU\n"
|
||||
"SG_ Root M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Second M : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ A m0 : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ B m0 : 24|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_MUL_VAL_ 1 A Root 1-1;\nSG_MUL_VAL_ 1 B Second 2-2;\n");
|
||||
raw.data = {1U, 2U, 9U, 10U};
|
||||
result = DbcDecoder().Decode(DbcDecodeBuilder().Build(DbcParser().ParseFile(fixture.path.string())), raw);
|
||||
CHECK(result.signals[2].valid && result.signals[3].valid, "Independent explicit selectors");
|
||||
|
||||
fixture.Write("BO_ 1 Deep: 5 ECU\n"
|
||||
"SG_ Root M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Child m1M : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Grandchild m2M : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Leaf : 24|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_MUL_VAL_ 1 Grandchild Child 2-2;\n"
|
||||
"SG_MUL_VAL_ 1 Leaf Grandchild 3-3;\n");
|
||||
const DecodeDatabase deep = DbcDecodeBuilder().Build(DbcParser().ParseFile(fixture.path.string()));
|
||||
raw.data = {1U, 2U, 3U, 9U, 0U};
|
||||
CHECK(DbcDecoder().Decode(deep, raw).signals[3].valid, "Three selector levels and an unmarked extended branch");
|
||||
raw.data = {1U, 0U};
|
||||
CHECK(DbcDecoder().Decode(deep, raw).signals[3].status == SignalDecodeStatus::Inactive,
|
||||
"Inactive middle ancestor skips missing descendant bytes");
|
||||
|
||||
// Marker fallback also works on a nested selector without its own SG_MUL_VAL_.
|
||||
fixture.Write("BO_ 1 Frame: 3 ECU\n"
|
||||
"SG_ Root M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Child m1M : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Leaf m2 : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_MUL_VAL_ 1 Leaf Child 2-2;\n");
|
||||
raw.data = {1U, 2U, 9U};
|
||||
CHECK(DbcDecoder().Decode(DbcDecodeBuilder().Build(DbcParser().ParseFile(fixture.path.string())), raw).signals[2].valid,
|
||||
"mNM retains implicit root fallback");
|
||||
}
|
||||
|
||||
void DbcParserTest::extendedMultiplexingErrors() {
|
||||
Fixture fixture;
|
||||
const std::string definitions =
|
||||
"BO_ 1 Frame: 3 ECU\n"
|
||||
"SG_ Root M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Child m1M : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Leaf m2 : 16|8@1+ (1,0) [0|255] \"\" ECU\n";
|
||||
for (const std::string statement: {
|
||||
"SG_MUL_VAL_ 1 Leaf Root 3-2;", "SG_MUL_VAL_ 1 Leaf Root -1-2;",
|
||||
"SG_MUL_VAL_ 1 Leaf Root 1-256;", "SG_MUL_VAL_ 1 Leaf Root 1-2,;",
|
||||
"SG_MUL_VAL_ 1 Leaf Root 1-2 trailing;", "SG_MUL_VAL_ 1 Leaf Root 1-2",
|
||||
"SG_MUL_VAL_ 1 Leaf Root 0-18446744073709551616;",
|
||||
"SG_MUL_VAL_ 1 Leaf Missing 1-2;", "SG_MUL_VAL_ 1 Missing Root 1-2;",
|
||||
"SG_MUL_VAL_ 2 Leaf Root 1-2;", "SG_MUL_VAL_ 1 Leaf Leaf 1-2;"}) {
|
||||
fixture.Write(statement + "\n" + definitions);
|
||||
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
CHECK(result.HasErrors() && result.database.frames.empty(), statement);
|
||||
CHECK(result.diagnostics.back().code == DbcDiagnosticCode::InvalidMultiplexing &&
|
||||
result.diagnostics.back().lineNumber == 1U,
|
||||
"Extended error retains source statement location");
|
||||
}
|
||||
for (const std::string statements: {
|
||||
"SG_MUL_VAL_ 1 Root Child 1-1;\nSG_MUL_VAL_ 1 Child Root 1-1;\n",
|
||||
"SG_MUL_VAL_ 1 Child Child 1-1;\n",
|
||||
"SG_MUL_VAL_ 1 Leaf Root 1-1;\nSG_MUL_VAL_ 1 Leaf Child 1-1;\n"}) {
|
||||
fixture.Write(definitions + statements);
|
||||
CHECK(DbcParser().ParseFileWithDiagnostics(fixture.path.string()).HasErrors(), "Cyclic or conflicting parents rejected");
|
||||
}
|
||||
// Range intersection and inherited root conditions must both protect overlaps.
|
||||
const std::string overlapping =
|
||||
"BO_ 1 Frame: 4 ECU\n"
|
||||
"SG_ Root M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ Child m1M : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ A m0 : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_ B m0 : 23|8@0+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_MUL_VAL_ 1 A Child 2-4;\n"
|
||||
"SG_MUL_VAL_ 1 Child Root 1-1;\n";
|
||||
for (const std::string condition: {"SG_MUL_VAL_ 1 B Child 4-6;\n",
|
||||
"SG_MUL_VAL_ 1 B Root 1-1;\n"}) {
|
||||
fixture.Write(overlapping + condition);
|
||||
CHECK(DbcParser().ParseFileWithDiagnostics(fixture.path.string()).HasErrors(),
|
||||
"Overlapping ranges or compatible ancestors cannot share bits");
|
||||
}
|
||||
fixture.Write(overlapping + "SG_MUL_VAL_ 1 B Child 5-6;\n");
|
||||
CHECK(!DbcParser().ParseFileWithDiagnostics(fixture.path.string()).HasErrors(),
|
||||
"Disjoint adjacent ranges may share bits");
|
||||
fixture.Write(overlapping + "SG_ Second M : 24|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SG_MUL_VAL_ 1 B Second 2-4;\n");
|
||||
const DbcParseResult independent = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
CHECK(independent.HasErrors() && independent.diagnostics.back().message ==
|
||||
"Signals overlap without mutually exclusive multiplexing conditions.",
|
||||
"Independent selector conditions do not imply exclusion");
|
||||
|
||||
// Validate manually constructed runtime graphs with the same rules.
|
||||
fixture.Write(definitions + "SG_MUL_VAL_ 1 Leaf Child 2-3;\n");
|
||||
const DecodeDatabase valid = DbcDecodeBuilder().Build(DbcParser().ParseFile(fixture.path.string()));
|
||||
for (unsigned kind = 0U; kind < 6U; ++kind) {
|
||||
std::vector<DecodeFrame> frames = valid.GetFrames();
|
||||
Multiplexing &leaf = frames[0].signals[2].multiplexing;
|
||||
switch (kind) {
|
||||
case 0:
|
||||
leaf.selector = "Missing";
|
||||
break;
|
||||
case 1:
|
||||
leaf.ranges[0] = {4U, 3U};
|
||||
break;
|
||||
case 2:
|
||||
leaf.ranges[0] = {0U, 256U};
|
||||
break;
|
||||
case 3:
|
||||
leaf.ranges.clear();
|
||||
break;
|
||||
case 4:
|
||||
frames[0].signals[0].multiplexing.selector = "Child";
|
||||
frames[0].signals[0].multiplexing.ranges = {{1U, 1U}};
|
||||
break;
|
||||
case 5:
|
||||
frames[0].signals[1].valueType = ValueType::Signed;
|
||||
break;
|
||||
}
|
||||
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase(frames));
|
||||
}
|
||||
}
|
||||
|
||||
int RunParserTests(int argc, char **argv) {
|
||||
DbcParserTest tests;
|
||||
return QTest::qExec(&tests, argc, argv);
|
||||
|
||||
Reference in new issue
Block a user