This commit is contained in:
deeaitch committed 2026-10-14 10:41:17 -04:00
1 parent d87c100398
commit 4ae4e527b8
5 files changed
+138 -10

No files matched your search

+95
View File
@@ -3,7 +3,9 @@
#include "dbc_parser.h"
#include "dbc_statement_handler.h"
#include "dbc_tree_builder.h"
#include <clocale>
#include <limits>
#include <locale>
#include <QtTest>
#include <chrono>
@@ -28,6 +30,27 @@ struct Fixture {
}
};
class CommaDecimalPunctuation : public std::numpunct<char> {
protected:
char do_decimal_point() const override { return ','; }
char do_thousands_sep() const override { return '.'; }
std::string do_grouping() const override { return "\3"; }
};
class ApplicationLocaleGuard {
public:
ApplicationLocaleGuard()
: previousCppLocale(std::locale()), previousCLocale(std::setlocale(LC_ALL, nullptr)) {}
~ApplicationLocaleGuard() {
std::locale::global(previousCppLocale);
std::setlocale(LC_ALL, previousCLocale.c_str());
}
private:
std::locale previousCppLocale;
std::string previousCLocale;
};
class CountingHandler : public DbcStatementHandler {
public:
inline static int instances = 0;
@@ -50,6 +73,7 @@ std::string SignalLine(const std::string &start, const std::string &length,
class DbcParserTest : public QObject {
Q_OBJECT
private:
void CheckPhysicalNumbers();
void RejectSignal(const Fixture &fixture, const std::string &line, unsigned payload = 8U) {
fixture.Write("BO_ 1 Frame: " + std::to_string(payload) + " ECU\n\n" + line + "\n");
try {
@@ -81,6 +105,8 @@ private Q_SLOTS:
void integration();
void invalidSignals();
void validSignals();
void physicalNumbersCppLocale();
void physicalNumbersCLocale();
void dispatch();
void independentSessions();
void valueDescriptions();
@@ -824,6 +850,75 @@ void DbcParserTest::validSignals() {
} catch (const std::exception &error) { CHECK(false, error.what()); }
}
void DbcParserTest::CheckPhysicalNumbers() {
Fixture fixture;
struct PhysicalCase {
const char *factor;
const char *offset;
const char *minimum;
const char *maximum;
double expectedFactor;
double expectedOffset;
double expectedMinimum;
double expectedMaximum;
};
const PhysicalCase valid[] = {
{"+1.25", "-0.5", "-2.75", "255.5", 1.25, -0.5, -2.75, 255.5},
{"+.5e+1", "-2.5E-1", "-1.", "+2e2", 5.0, -0.25, -1.0, 200.0},
{"0e-999", "+0.", "-.0", ".0e+999", 0.0, 0.0, 0.0, 0.0},
{"1.7976931348623157e308", "2.2250738585072014e-308", "-1e308", "+1e308",
std::numeric_limits<double>::max(), std::numeric_limits<double>::min(), -1e308, 1e308}};
for (const PhysicalCase &test: valid) {
fixture.Write("BO_ 1 Frame: 1 ECU\n" +
SignalLine("0", "8", "1+", test.factor, test.offset, test.minimum, test.maximum) + "\n");
const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
QVERIFY(!result.HasErrors());
QVERIFY(result.diagnostics.empty());
QCOMPARE(result.database.frames.size(), std::size_t(1));
const SignalInfo &signal = result.database.frames[0].signals[0];
QCOMPARE(signal.factor, test.expectedFactor);
QCOMPARE(signal.offset, test.expectedOffset);
QCOMPARE(signal.minimum, test.expectedMinimum);
QCOMPARE(signal.maximum, test.expectedMaximum);
}
const char *invalid[] = {"1,5", "1.234,5", "1,234.5", "1junk", "nan", "inf", "-inf",
"1e999", "1e-999", "1e-320", "-1e-320", "0x1p2", "1e", "1.2.3"};
for (const char *value: invalid) {
RejectSignal(fixture, SignalLine("0", "8", "1+", value, "0", "0", "255"));
RejectSignal(fixture, SignalLine("0", "8", "1+", "1", value, "0", "255"));
RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", value, "255"));
RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", "0", value));
}
RejectSignal(fixture, SignalLine("0", "8", "1+", "1.25", "0", "2.5", "1.5"));
}
void DbcParserTest::physicalNumbersCppLocale() {
const ApplicationLocaleGuard guard;
std::locale::global(std::locale(std::locale::classic(), new CommaDecimalPunctuation));
QCOMPARE(std::use_facet<std::numpunct<char>>(std::locale()).decimal_point(), ',');
CheckPhysicalNumbers();
QCOMPARE(std::use_facet<std::numpunct<char>>(std::locale()).decimal_point(), ',');
}
void DbcParserTest::physicalNumbersCLocale() {
const ApplicationLocaleGuard guard;
bool found = false;
const char *names[] = {"de_DE.UTF-8", "de_DE.utf8", "fr_FR.UTF-8", "fr_FR.utf8",
"German_Germany.1252", "French_France.1252"};
for (const char *name: names) {
if (std::setlocale(LC_NUMERIC, name) && std::string(std::localeconv()->decimal_point) == ",") {
found = true;
break;
}
}
if (!found)
QSKIP("No named comma-decimal C locale is installed; generate de_DE.UTF-8 and set LOCPATH.");
QCOMPARE(std::string(std::localeconv()->decimal_point), std::string(","));
CheckPhysicalNumbers();
QCOMPARE(std::string(std::localeconv()->decimal_point), std::string(","));
}
void DbcParserTest::dispatch() {
CountingHandler::instances = 0;
CountingHandler::calls = 0;