closes #4 Refactor DBC parsing into TypeFactory statement handlers
This commit is contained in:
1 parent
3bd9339baf
commit
88b5883dda
9 files changed
+511
-349
No files matched your search
+4
-1
@@ -33,7 +33,7 @@ Run from the repository root:
|
||||
|
||||
```sh
|
||||
g++ -std=c++17 -Wall -Wextra -Wpedantic -Werror -I. \
|
||||
tests/dbc_parser_test.cpp dbc_parser.cpp -o /tmp/dbc_parser_test
|
||||
tests/dbc_parser_test.cpp dbc_parser.cpp dbc_statement_handler.cpp -o /tmp/dbc_parser_test
|
||||
/tmp/dbc_parser_test
|
||||
```
|
||||
|
||||
@@ -45,3 +45,6 @@ boundaries, missing fields, malformed and overflowing numbers, reserved ID bits,
|
||||
error paths and line numbers, and integration with signals and comments.
|
||||
Temporary DBC fixtures are created in the system temporary directory and removed
|
||||
automatically.
|
||||
|
||||
Dispatch tests also verify exact keyword matching, handler construction and reuse,
|
||||
unknown statements, and independent parsing sessions, including recovery after errors.
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "dbc_parser.h"
|
||||
#include "dbc_statement_handler.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
@@ -19,6 +20,17 @@ struct Fixture {
|
||||
}
|
||||
};
|
||||
|
||||
class CountingHandler : public DbcStatementHandler {
|
||||
public:
|
||||
inline static int instances = 0;
|
||||
inline static int calls = 0;
|
||||
CountingHandler() { ++instances; }
|
||||
void Handle (const std::string &, DbcParseContext &context) const override {
|
||||
++calls;
|
||||
context.database.frames.emplace_back();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
Fixture fixture;
|
||||
int failures = 0;
|
||||
@@ -88,6 +100,33 @@ int main() {
|
||||
check (std::string (error.what()).find (fixture.path.string() + ":2: ") == 0U,
|
||||
"Signal error location");
|
||||
}
|
||||
DbcDatabase dispatchDatabase;
|
||||
DbcParseContext context {dispatchDatabase, nullptr};
|
||||
DbcStatementDispatcher dispatcher;
|
||||
dispatcher.RegisterType<CountingHandler> ("TEST_");
|
||||
check (dispatcher.Dispatch ("TEST_ first", context) &&
|
||||
dispatcher.Dispatch ("TEST_ second", context) &&
|
||||
CountingHandler::instances == 1 && CountingHandler::calls == 2 &&
|
||||
dispatchDatabase.frames.size() == 2U, "Factory dispatch and handler reuse");
|
||||
check (!dispatcher.Dispatch ("TEST_OTHER data", context) &&
|
||||
!dispatcher.Dispatch ("BO_TX_BU_ 1 : ECU;", context) &&
|
||||
!dispatcher.Dispatch ("VAL_ 1 Speed 0 \"Stopped\";", context) &&
|
||||
CountingHandler::calls == 2, "Exact and unknown keyword dispatch");
|
||||
const DbcParser parser;
|
||||
fixture.Write ("BO_ 1 First: 8 ECU\n");
|
||||
check (parser.ParseFile (fixture.path.string()).frames.size() == 1U, "First parse");
|
||||
fixture.Write ("SG_ Speed : invalid\n");
|
||||
try {
|
||||
parser.ParseFile (fixture.path.string());
|
||||
check (false, "Independent parse context");
|
||||
} catch (const std::runtime_error &error) {
|
||||
check (std::string (error.what()).find ("Signal found before any frame") !=
|
||||
std::string::npos, "Independent parse context");
|
||||
}
|
||||
fixture.Write ("BO_ 2 Second: 8 ECU\n");
|
||||
const auto recovered = parser.ParseFile (fixture.path.string());
|
||||
check (recovered.frames.size() == 1U && recovered.frames[0].canId == 2U,
|
||||
"Fresh parse after error");
|
||||
if (failures != 0) return 1;
|
||||
std::cout << "All " << count << " parser cases passed.\n";
|
||||
return 0;
|
||||
|
||||
@@ -3,5 +3,5 @@ TARGET = dbc_parser_test
|
||||
CONFIG += console c++17
|
||||
CONFIG -= app_bundle qt
|
||||
INCLUDEPATH += ..
|
||||
SOURCES += dbc_parser_test.cpp ../dbc_parser.cpp
|
||||
HEADERS += ../dbc_parser.h ../dbc_database.h ../frame_info.h ../signal_info.h
|
||||
SOURCES += dbc_parser_test.cpp ../dbc_parser.cpp ../dbc_statement_handler.cpp
|
||||
HEADERS += ../dbc_statement_handler.h ../typefactory.h ../dbc_parser.h ../dbc_database.h ../frame_info.h ../signal_info.h
|
||||
Reference in new issue
Block a user