95 lines
3.9 KiB
C++
95 lines
3.9 KiB
C++
#include "dbc_parser.h"
|
|
|
|
#include <chrono>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
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;
|
|
}
|