#include "dbc_parser.h" #include #include #include #include #include struct Fixture { std::filesystem::path path = std::filesystem::temp_directory_path() / ("dbc_parser_test_" + std::to_string ( std::chrono::steady_clock::now().time_since_epoch().count()) + ".dbc"); ~Fixture() { std::error_code error; std::filesystem::remove (path, error); } void Write (const std::string &text) const { std::ofstream output (path); output << text; if (!output) throw std::runtime_error ("Cannot write test fixture."); } }; int main() { Fixture fixture; int failures = 0; std::size_t count = 0U; const auto check = [&] (bool passed, const std::string &name) { ++count; if (!passed) { ++failures; std::cerr << "FAIL: " << name << '\n'; } }; struct ValidCase { const char *line; std::uint32_t id; bool extended; unsigned length; }; const ValidCase valid[] = { {"BO_ 0 Frame: 0 ECU", 0U, false, 0U}, {"BO_ 2047 Frame: 8 ECU", 2047U, false, 8U}, {"BO_ 2048 Frame: 64 ECU", 2048U, true, 64U}, {"BO_ 536870911 Frame: 255 ECU", 0x1FFFFFFFU, true, 255U}, {"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) { 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); } catch (const std::exception &error) { check (false, error.what()); } } const char *invalid[] = { "BO_ invalid", "BO_", "BO_ 1", "BO_ 1 : 8 ECU", "BO_ 1 Frame 8 ECU", "BO_ 1 Frame:", "BO_ 1 Frame: 8", "BO_ 1 Frame: 8 ECU extra", "BO_ 1 Two Names: 8 ECU", "BO_ -1 Frame: 8 ECU", "BO_ +1 Frame: 8 ECU", "BO_ 1x Frame: 8 ECU", "BO_ 0x123 Frame: 8 ECU", "BO_ 1.5 Frame: 8 ECU", "BO_ 4294967296 Frame: 8 ECU", "BO_ 999999999999999999999 Frame: 8 ECU", "BO_ 536870912 Frame: 8 ECU", "BO_ 1073741824 Frame: 8 ECU", "BO_ 2684354560 Frame: 8 ECU", "BO_ 4294967295 Frame: 8 ECU", "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) { fixture.Write (std::string ("VERSION \"test\"\n\n") + line + '\n'); try { DbcParser().ParseFile (fixture.path.string()); check (false, line); } catch (const std::runtime_error &error) { const std::string prefix = fixture.path.string() + ":3: "; check (std::string (error.what()).find (prefix) == 0U && std::string (error.what()).size() > prefix.size(), line); } } fixture.Write ( "BO_TX_BU_ 256 : ECU;\nBO_ 256 Frame: 8 ECU\n" " 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()); 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", "Integration"); fixture.Write ("\nSG_ Speed : invalid\n"); try { DbcParser().ParseFile (fixture.path.string()); check (false, "Signal error location"); } catch (const std::runtime_error &error) { check (std::string (error.what()).find (fixture.path.string() + ":2: ") == 0U, "Signal error location"); } if (failures != 0) return 1; std::cout << "All " << count << " parser cases passed.\n"; return 0; }