Closes #25
This commit is contained in:
1 parent
e555ebb571
commit
849ce31e2f
17 files changed
+675
-35
No files matched your search
+133
-4
@@ -3,6 +3,7 @@
|
||||
#include "dbc_parser.h"
|
||||
#include "dbc_statement_handler.h"
|
||||
#include "dbc_tree_builder.h"
|
||||
#include <algorithm>
|
||||
#include <clocale>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
@@ -87,6 +88,9 @@ private:
|
||||
}
|
||||
}
|
||||
private Q_SLOTS:
|
||||
void attributes();
|
||||
void invalidAttributes();
|
||||
void attributeWarnings();
|
||||
void diagnostics();
|
||||
void diagnosticErrors();
|
||||
void diagnosticUnsupportedStatements();
|
||||
@@ -113,6 +117,133 @@ private Q_SLOTS:
|
||||
void invalidValueDescriptions();
|
||||
};
|
||||
|
||||
void DbcParserTest::attributes() {
|
||||
Fixture fixture;
|
||||
fixture.Write(
|
||||
"BA_ \"GenMsgCycleTime\" BO_ 1 25;\n"
|
||||
"BA_ \"VFrameFormat\" BO_ 2147483649 1;\n"
|
||||
"BA_ \"Label\" SG_ 1 Value \"a\\\"b\\\\c\";\n"
|
||||
"BA_ \"NodeLabel\" BU_ ECU \"node\";\n"
|
||||
"BA_ \"Environment\" EV_ Env 2;\n"
|
||||
"BA_DEF_DEF_ \"GenMsgCycleTime\" 100;\n"
|
||||
"BA_DEF_DEF_ \"VFrameFormat\" \"StandardCAN\";\n"
|
||||
"BA_DEF_DEF_ \"Label\" \"default\";\n"
|
||||
"BA_DEF_DEF_ \"BusLabel\" \"CAN\";\n"
|
||||
"BA_DEF_DEF_ \"Ratio\" 1.5e-1;\n"
|
||||
"BA_DEF_ BO_ \"GenMsgCycleTime\" INT 0 10000;\n"
|
||||
"BA_DEF_ BO_ \"VFrameFormat\" ENUM \"StandardCAN\",\"ExtendedCAN\",\"StandardCAN_FD\";\n"
|
||||
"BA_DEF_ SG_ \"Label\" STRING;\n"
|
||||
"BA_DEF_ \"BusLabel\" STRING;\n"
|
||||
"BA_DEF_ BO_ \"Ratio\" FLOAT -1 1;\n"
|
||||
"BA_DEF_ BU_ \"NodeLabel\" STRING;\n"
|
||||
"BA_DEF_ EV_ \"Environment\" HEX 0 255;\n"
|
||||
"BO_ 1 Standard: 1 ECU\n"
|
||||
"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"BO_ 2147483649 Extended: 1 ECU\n"
|
||||
"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n");
|
||||
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
QVERIFY(!result.HasErrors());
|
||||
QVERIFY(result.diagnostics.empty());
|
||||
const DbcDatabase &database = result.database;
|
||||
QCOMPARE(database.attributeDefinitions.size(), std::size_t(7));
|
||||
QCOMPARE(database.attributeAssignments.size(), std::size_t(5));
|
||||
QCOMPARE(std::get<std::string>(database.attributes.at("BusLabel")), std::string("CAN"));
|
||||
QCOMPARE(database.frames[0].cycleTimeMs.value(), 25U);
|
||||
QCOMPARE(database.frames[1].cycleTimeMs.value(), 100U);
|
||||
QCOMPARE(database.frames[1].frameFormat.value(), std::string("ExtendedCAN"));
|
||||
QVERIFY(!database.frames[1].hasPgn);
|
||||
QCOMPARE(std::get<double>(database.frames[0].attributes.at("Ratio")), 0.15);
|
||||
QCOMPARE(std::get<std::string>(database.frames[0].signals[0].attributes.at("Label")), std::string("a\"b\\c"));
|
||||
QCOMPARE(std::get<std::string>(database.frames[1].signals[0].attributes.at("Label")), std::string("default"));
|
||||
const DecodeDatabase runtime = DbcDecodeBuilder().Build(database);
|
||||
QCOMPARE(runtime.GetFrames()[0].cycleTimeMs.value(), 25U);
|
||||
QCOMPARE(runtime.GetFrames()[1].frameFormat.value(), std::string("ExtendedCAN"));
|
||||
QCOMPARE(runtime.GetFrames()[0].signals[0].attributes, database.frames[0].signals[0].attributes);
|
||||
const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(database);
|
||||
QCOMPARE(tree->GetChild(0)->GetFrame()->cycleTimeMs.value(), 25U);
|
||||
QCOMPARE(tree->GetChild(0)->GetChild(0)->GetSignal()->attributes, database.frames[0].signals[0].attributes);
|
||||
fixture.Write("BA_DEF_ BO_ \"Period\" INT 0 10;\nBA_DEF_DEF_ \"Period\" 1;\n"
|
||||
"BA_ \"Period\" BO_ 1 2;\nBA_ \"Period\" BO_ 1 3;\nBO_ 1 F: 0 ECU\n");
|
||||
const DbcDatabase repeated = DbcParser().ParseFile(fixture.path.string());
|
||||
QCOMPARE(std::get<std::int64_t>(repeated.frames[0].attributes.at("Period")), std::int64_t(3));
|
||||
|
||||
fixture.Write("BA_DEF_ BO_ \"GenMsgCycleTime\" INT 0 4294967295;\n"
|
||||
"BA_DEF_DEF_ \"GenMsgCycleTime\" 0;\n"
|
||||
"BA_ \"GenMsgCycleTime\" BO_ 1 4294967295;\n"
|
||||
"BA_DEF_ \"Wide\" INT -9223372036854775808 9223372036854775807;\n"
|
||||
"BA_DEF_DEF_ \"Wide\" -9223372036854775808;\n"
|
||||
"BA_DEF_ SG_ \"State\" ENUM \"off\",\"on\";\n"
|
||||
"BA_DEF_DEF_ \"State\" 1;\n"
|
||||
"BO_ 1 F: 0 ECU\nBO_ 2 Empty: 0 ECU\n");
|
||||
const DbcDatabase boundaries = DbcParser().ParseFile(fixture.path.string());
|
||||
QCOMPARE(boundaries.frames[0].cycleTimeMs.value(), std::numeric_limits<std::uint32_t>::max());
|
||||
QCOMPARE(boundaries.frames[1].cycleTimeMs.value(), 0U);
|
||||
QVERIFY(!boundaries.frames[0].frameFormat);
|
||||
QCOMPARE(std::get<std::int64_t>(boundaries.attributes.at("Wide")), std::numeric_limits<std::int64_t>::min());
|
||||
QCOMPARE(std::get<std::int64_t>(*boundaries.attributeDefinitions.at("State").defaultValue), std::int64_t(1));
|
||||
}
|
||||
|
||||
void DbcParserTest::invalidAttributes() {
|
||||
Fixture fixture;
|
||||
const std::vector<std::string> invalid = {
|
||||
"BA_DEF_ BO_ \"A\" INT 2 1;",
|
||||
"BA_DEF_ BO_ \"A\" FLOAT nan 1;",
|
||||
"BA_DEF_ BO_ \"A\" FLOAT 0 inf;",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 9223372036854775808;",
|
||||
"BA_DEF_ BO_ \"A\" STRING; trailing",
|
||||
"BA_DEF_ BO_ \"A\" ENUM;",
|
||||
"BA_DEF_ BO_ \"A\" ENUM \"one\",;",
|
||||
"BA_DEF_ BO_ \"A\" ENUM \"one\",\"one\";",
|
||||
"BA_DEF_ BO_ \"VFrameFormat\" STRING;",
|
||||
"BA_DEF_ SG_ \"GenMsgCycleTime\" INT 0 10;",
|
||||
"BA_ \"Unknown\" BO_ 1 0;",
|
||||
"BA_DEF_DEF_ \"Unknown\" 0;",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 1;\nBA_ \"A\" BO_ 1 2;",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 1;\nBA_ \"A\" BO_ 1 \"0\";",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 1;\nBA_ \"A\" SG_ 1 S 0;",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 1;\nBA_ \"A\" BO_ 2 0;",
|
||||
"BA_DEF_ SG_ \"A\" INT 0 1;\nBA_ \"A\" SG_ 1 Missing 0;",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 1;\nBA_DEF_ BO_ \"A\" INT 0 1;",
|
||||
"BA_DEF_ BO_ \"A\" INT 0 1;\nBA_DEF_DEF_ \"A\" 0;\nBA_DEF_DEF_ \"A\" 1;",
|
||||
"BA_DEF_ BO_ \"A\" STRING;\nBA_ \"A\" BO_ 1 \"bad\\q\";",
|
||||
"BA_DEF_ BO_ \"A\" STRING;\nBA_ \"A\" BO_ 1 \"unterminated;",
|
||||
"BA_DEF_ BO_ \"A\" ENUM \"one\";\nBA_DEF_DEF_ \"A\" \"missing\";",
|
||||
"BA_DEF_ BO_ \"A\" ENUM \"one\";\nBA_ \"A\" BO_ 1 1;",
|
||||
"BA_DEF_ BO_ \"GenMsgCycleTime\" INT -1 4294967296;\nBA_DEF_DEF_ \"GenMsgCycleTime\" -1;",
|
||||
"BA_DEF_ BO_ \"GenMsgCycleTime\" INT 0 4294967296;\nBA_ \"GenMsgCycleTime\" BO_ 1 4294967296;"};
|
||||
for (const std::string &statement: invalid) {
|
||||
fixture.Write("BO_ 1 F: 0 ECU\n" + statement + '\n');
|
||||
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
QVERIFY2(result.HasErrors(), statement.c_str());
|
||||
QVERIFY(result.database.frames.empty());
|
||||
QCOMPARE(result.diagnostics.back().code, DbcDiagnosticCode::InvalidAttribute);
|
||||
QCOMPARE(result.diagnostics.back().lineNumber, std::size_t(2 + std::count(statement.begin(), statement.end(), '\n')));
|
||||
QVERIFY_THROWS_EXCEPTION(std::runtime_error, DbcParser().ParseFile(fixture.path.string()));
|
||||
}
|
||||
}
|
||||
|
||||
void DbcParserTest::attributeWarnings() {
|
||||
Fixture fixture;
|
||||
fixture.Write("BA_DEF_ BO_ \"VFrameFormat\" ENUM \"StandardCAN\",\"ExtendedCAN\",\"J1939PG\",\"StandardCAN_FD\";\n"
|
||||
"BA_DEF_DEF_ \"VFrameFormat\" \"StandardCAN_FD\";\n"
|
||||
"BA_ \"VFrameFormat\" BO_ 1 2;\n"
|
||||
"BA_ \"VFrameFormat\" BO_ 2147483649 0;\n"
|
||||
"BO_ 1 F: 0 ECU\nBO_ 2147483649 E: 0 ECU\nBO_ 2 Default: 0 ECU\n");
|
||||
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
QVERIFY(!result.HasErrors());
|
||||
QCOMPARE(result.diagnostics.size(), std::size_t(3));
|
||||
const std::size_t lines[] = {3U, 4U, 2U};
|
||||
for (std::size_t index = 0; index < 3U; ++index) {
|
||||
QCOMPARE(result.diagnostics[index].code, DbcDiagnosticCode::UnsupportedAttribute);
|
||||
QCOMPARE(result.diagnostics[index].severity, DbcDiagnosticSeverity::Warning);
|
||||
QCOMPARE(result.diagnostics[index].lineNumber, lines[index]);
|
||||
QCOMPARE(result.diagnostics[index].filePath, fixture.path.string());
|
||||
}
|
||||
QCOMPARE(result.database.frames[0].frameFormat.value(), std::string("J1939PG"));
|
||||
QVERIFY(!result.database.frames[0].hasPgn);
|
||||
QVERIFY(result.database.frames[1].isExtended);
|
||||
}
|
||||
|
||||
void DbcParserTest::diagnostics() {
|
||||
Fixture fixture;
|
||||
fixture.Write("VERSION \"test\"\n"
|
||||
@@ -126,7 +257,7 @@ void DbcParserTest::diagnostics() {
|
||||
"BO_ 1 Frame: 1 ECU\n"
|
||||
"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
||||
"SIG_VALTYPE_ 1 Value : 1;\n"
|
||||
"BA_ \"SignalType\" SG_ 1 Value 1;\n"
|
||||
"BA_REL_ \"SignalType\" SG_ 1 Value 1;\n"
|
||||
"VENDOR_EXTENSION_ data;\n");
|
||||
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
|
||||
CHECK(!result.HasErrors() && result.database.frames.size() == 1U,
|
||||
@@ -264,9 +395,7 @@ void DbcParserTest::diagnosticUnsupportedStatements() {
|
||||
"CM_ SG_ 1 Value \"Signal comment\";\nVAL_ 1 Value 1 \"On\";\n";
|
||||
const std::vector<std::string> statements = {
|
||||
"SIG_VALTYPE_ 1 Value : 1;", "SIG_VALTYPE_ 1 Value : 2;",
|
||||
"BA_ \"SignalType\" SG_ 1 Value 1;",
|
||||
"BA_DEF_ SG_ \"SignalType\" INT 0 1;",
|
||||
"BA_DEF_DEF_ \"SignalType\" 0;",
|
||||
"BA_REL_ \"SignalType\" SG_ 1 Value 1;",
|
||||
"BA_DEF_REL_ BU_SG_REL_ \"Relation\" INT 0 1;",
|
||||
"BA_REL_ \"Relation\" BU_SG_REL_ ECU SG_ 1 Value 1;",
|
||||
"SGTYPE_ Type : 8@1+ (1,0) [0|255] \"\" 0, Table;",
|
||||
|
||||
Reference in new issue
Block a user