This commit is contained in:
deeaitch committed 2026-10-13 08:17:49 -04:00
1 parent 7022c84941
commit c3d3bd51fb
72 files changed
+3703 -2484

No files matched your search

+27 -8
View File
@@ -24,7 +24,7 @@ make -j
make check
```
Or run `./tests/dbc_tests` directly. Parser, decoder, lifetime, and additional coverage
Or run `./tests/dbc_tests` directly. Parser, decoder, lifetime, validation, and additional coverage
suites run, and the executable returns nonzero when any suite fails. Decoder cases appear as
individual QtTest data rows; parser checks are grouped into named test slots.
Checks also run in release builds.
@@ -41,7 +41,8 @@ make check
```
`parser_tests.pri` and `decoder_tests.pri` include the original test sources;
`tests.pro` also includes `dbc_coverage_test.cpp` and `dbc_lifetime_test.cpp`.
`tests.pro` also includes `dbc_coverage_test.cpp`, `dbc_lifetime_test.cpp`, and
`dbc_validation_test.cpp`.
`../core/core.pri` supplies the library include path and linkage.
## Decoder coverage
@@ -52,10 +53,11 @@ signals, signed values, scaling, 64-bit extraction, signed/unsigned boundary val
payloads, and Intel regression cases. Frame validity means the definition was
found; frame status reports unknown frames, short payloads, and signal errors.
Tests exercise empty/short/exact/long payloads, ignored trailing bytes, signals
outside declared DLC, invalid enum metadata and overflowing start bits, and
preservation of successful signals. Physical conversion checks cover NaN/Inf
parameters, multiplication/addition overflow, finite limits, signed/unsigned raw
retention, and raw selector activation after physical conversion failure.
outside declared DLC, invalid enum metadata and overflowing start bits rejected
at construction, and preservation of successful signals on partial payloads.
Physical conversion checks cover NaN/Inf parameters rejected at construction,
multiplication/addition overflow, finite limits, signed/unsigned raw retention,
and raw selector activation after physical conversion failure.
## Parser coverage
@@ -116,8 +118,9 @@ of invalid markers, selector references/ranges, overlaps, and SG_MUL_VAL_.
`dbc_coverage_test.cpp` runs as part of `dbc_tests`. It covers signed boundaries
below 64 bits, deterministic extraction comparisons for both byte orders across
lengths 1–64, frame lookup failures, exact decode statuses, malformed runtime
multiplexing, PGN boundaries, comment handling, file formatting, metadata copying
lengths 1–64, frame lookup failures, exact decode statuses, construction rejection
of malformed runtime multiplexing, PGN boundaries, comment handling, file
formatting, metadata copying
and source lifetime, physical conversion, and TypeFactory registration/creation.
Direct resolver tests construct ambiguous databases through the public metadata
API, verify source locations, and check that ambiguous targets receive no values.
@@ -141,3 +144,19 @@ duplicate runtime keys, including manually supplied parsed metadata. Failed relo
leaves the active database intact; empty reload clears it. Invalid/unknown results
and insufficient payloads retain their documented ownership and status behavior.
Inactive branches and unavailable selectors also retain definitions across reload.
## Database validation coverage
`dbc_validation_test.cpp` checks direct construction and manually assembled
`DbcDatabase` input to `DbcDecodeBuilder`: standard/extended CAN ID limits,
encoded/reserved ID bits, duplicate keys, lengths 0/1–64/65/UINT32_MAX,
Intel/Motorola payload boundaries and overflowing start bits, invalid enums,
NaN and both infinities in every numeric parameter, and reversed physical ranges.
Selector tests include missing, duplicate, and signed selectors, branch ranges,
UINT64_MAX selection, mixed-order overlaps, and exclusive branches sharing bits.
Valid definitions cover the full byte-count storage range, including zero-byte
frames without signals and 255-byte frames. Existing extraction tests cover
lengths 1–64. Snapshot tests mutate retained frame, signal, and description aliases
after rvalue construction, and verify unchanged lookups and metadata. Failed
constructor/builder replacement preserves the active snapshot; clear removes its
index while saved handles remain alive.
+6 -13
View File
@@ -104,6 +104,7 @@ void CoverageTest::frameLookup() {
QVERIFY(absent.definition == nullptr);
QVERIFY(absent.signals.empty());
DecodeSignal signal;
signal.length = 8U;
DecodeDatabase database = SingleSignal(signal);
QVERIFY(decoder.FindFrame(database, 18U, false) == nullptr);
QVERIFY(decoder.FindFrame(database, 17U, true) == nullptr);
@@ -227,6 +228,10 @@ void CoverageTest::invalidSignalStatus() {
signal.startBit = start;
signal.length = length;
signal.byteOrder = order == 0 ? ByteOrder::Intel : ByteOrder::Motorola;
if (status == int(SignalDecodeStatus::InvalidDefinition)) {
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) SingleSignal(signal));
return;
}
const DecodeDatabase database = SingleSignal(signal);
RawCanFrame raw;
raw.canId = 17U;
@@ -272,19 +277,7 @@ void CoverageTest::malformedRuntimeMultiplexing() {
if (kind == 1) definitions[0].signals[0].valueType = ValueType::Signed;
if (kind == 2) definitions[0].signals[0].length = 65U;
if (kind == 3) definitions[0].signals[1].multiplexing.value = 2U;
const DecodeDatabase database(std::move(definitions));
RawCanFrame raw;
raw.canId = 17U;
raw.data = {1U, 42U, 99U};
const DecodedFrameValue result = DbcDecoder().Decode(database, raw);
QCOMPARE(int(result.signals[1].status), int(SignalDecodeStatus::InvalidDefinition));
QVERIFY(!result.signals[1].valid);
QVERIFY(result.signals[2].valid);
QCOMPARE(std::get<std::uint64_t>(result.signals[2].rawValue), std::uint64_t(99));
if (kind != 3) {
QCOMPARE(int(result.signals[0].status), int(SignalDecodeStatus::InvalidDefinition));
if (kind == 0) QCOMPARE(int(result.signals[3].status), int(SignalDecodeStatus::InvalidDefinition));
}
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase(definitions));
}
void CoverageTest::pgn_data() {
+19 -27
View File
@@ -4,6 +4,7 @@
#include <cmath>
#include <limits>
#include <sstream>
#include <stdexcept>
struct DecodeCase {
const char *name;
@@ -77,6 +78,10 @@ void DbcDecoderTest::decode() {
definition.canId = 0x123U;
definition.dlc = 8U;
definition.signals.push_back(signal);
if (test.length == 0U || test.length > 64U || test.startBit > 64U) {
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({definition}));
return;
}
const DecodeDatabase database({definition});
RawCanFrame frame;
@@ -253,22 +258,7 @@ void DbcDecoderTest::invalidDefinitions() {
case 7: bad.multiplexing.role = MultiplexRole::Branch; break;
}
definition.signals = {bad, good};
const DecodeDatabase database({definition});
RawCanFrame raw;
raw.data = {0xFFU, 0xFFU}; // Extra bytes must not rescue an invalid definition.
const DecodedFrameValue result = DbcDecoder().Decode(database, raw);
QVERIFY(result.valid);
QCOMPARE(result.status, FrameDecodeStatus::SignalErrors);
QCOMPARE(result.signals[0].status, SignalDecodeStatus::InvalidDefinition);
QVERIFY(!result.signals[0].valid && !result.signals[0].GetValueDescription());
QCOMPARE(result.signals[1].status, SignalDecodeStatus::Valid);
QCOMPARE(std::get<std::uint64_t>(result.signals[1].rawValue), std::uint64_t(15U));
QCOMPARE(result.signals[1].physicalValue, 15.0);
raw.data.clear();
const DecodedFrameValue shortResult = DbcDecoder().Decode(database, raw);
QCOMPARE(shortResult.status, FrameDecodeStatus::InsufficientPayload);
QCOMPARE(shortResult.signals[0].status, SignalDecodeStatus::InvalidDefinition);
QCOMPARE(shortResult.signals[1].status, SignalDecodeStatus::InsufficientPayload);
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({definition}));
}
}
@@ -313,6 +303,10 @@ void DbcDecoderTest::physicalConversion() {
definition.signals.push_back(signal);
RawCanFrame raw;
raw.data = {0x32U};
if (!std::isfinite(factor) || !std::isfinite(offset)) {
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({definition}));
continue;
}
const DecodedFrameValue result = DbcDecoder().Decode(DecodeDatabase({definition}), raw);
QVERIFY(result.valid);
QCOMPARE(result.status, finite ? FrameDecodeStatus::Valid : FrameDecodeStatus::SignalErrors);
@@ -340,25 +334,25 @@ void DbcDecoderTest::selectorConversionFailure() {
definition.dlc = 1U;
DecodeSignal selector;
selector.name = "Selector";
selector.length = 1U;
selector.length = 2U;
selector.multiplexing.role = MultiplexRole::Selector;
selector.factor = std::numeric_limits<double>::infinity();
selector.factor = std::numeric_limits<double>::max();
DecodeSignal branch;
branch.name = "Branch";
branch.startBit = 1U;
branch.length = 7U;
branch.startBit = 2U;
branch.length = 6U;
branch.multiplexing.role = MultiplexRole::Branch;
branch.multiplexing.value = 1U;
branch.multiplexing.value = 2U;
definition.signals = {branch, selector};
RawCanFrame raw;
raw.data = {85U};
raw.data = {170U};
const DecodedFrameValue result = DbcDecoder().Decode(DecodeDatabase({definition}), raw);
QCOMPARE(result.status, FrameDecodeStatus::SignalErrors);
QVERIFY(result.signals[0].valid);
QCOMPARE(result.signals[0].physicalValue, 42.0);
QCOMPARE(result.signals[1].status, SignalDecodeStatus::PhysicalConversionFailed);
QCOMPARE(std::get<std::uint64_t>(result.signals[1].rawValue), std::uint64_t(1U));
raw.data = {84U};
QCOMPARE(std::get<std::uint64_t>(result.signals[1].rawValue), std::uint64_t(2U));
raw.data = {168U};
selector.factor = 1.0;
definition.signals = {branch, selector};
const DecodedFrameValue inactive = DbcDecoder().Decode(DecodeDatabase({definition}), raw);
@@ -378,9 +372,7 @@ void DbcDecoderTest::zeroDlc() {
DecodeSignal signal;
signal.length = 8U;
definition.signals.push_back(signal);
const DecodedFrameValue invalid = DbcDecoder().Decode(DecodeDatabase({definition}), raw);
QCOMPARE(invalid.status, FrameDecodeStatus::SignalErrors);
QCOMPARE(invalid.signals[0].status, SignalDecodeStatus::InvalidDefinition);
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({definition}));
}
int RunDecoderTests(int argc, char **argv) {
+2
View File
@@ -175,6 +175,8 @@ void DbcLifetimeTest::duplicateKeys() {
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({frame, frame}));
DecodeSignal signal;
signal.name = "State";
signal.length = 1U;
frame.dlc = 1U;
frame.signals = {signal, signal};
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({frame}));
DbcDatabase parsed;
+2 -9
View File
@@ -603,16 +603,9 @@ void DbcParserTest::multiplexingBoundaries() {
"Adjacent large integers remain distinct");
std::vector<DecodeFrame> definitions = runtime.GetFrames();
definitions[0].signals[1].length = 0U;
runtime = DecodeDatabase(definitions);
result = DbcDecoder().Decode(runtime, raw);
CHECK(result.signals[0].status == SignalDecodeStatus::InvalidDefinition &&
result.signals[1].status == SignalDecodeStatus::InvalidDefinition,
"Malformed runtime selector distinguished from payload errors");
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, runtime = DecodeDatabase(definitions));
definitions[0].signals.pop_back();
runtime = DecodeDatabase(definitions);
result = DbcDecoder().Decode(runtime, raw);
CHECK(result.signals[0].status == SignalDecodeStatus::InvalidDefinition,
"Missing runtime selector");
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, runtime = DecodeDatabase(definitions));
fixture.Write("BO_ 1 Frame: 2 ECU\n\n"
"SG_ Branch m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
"SG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n");
+348
View File
@@ -0,0 +1,348 @@
// SPDX-License-Identifier: MIT
#include "dbc_decode_builder.h"
#include "dbc_decoder.h"
#include <QtTest>
#include <limits>
#include <stdexcept>
#include <utility>
namespace {
DecodeFrame ValidFrame() {
DecodeFrame frame;
frame.canId = 0x123U;
frame.dlc = 8U;
DecodeSignal signal;
signal.name = "Value";
signal.length = 8U;
frame.signals.push_back(signal);
return frame;
}
DbcDatabase ParsedDefinitions(const std::vector<DecodeFrame> &frames) {
DbcDatabase database;
for (const DecodeFrame &frame: frames) {
FrameInfo target;
target.canId = frame.canId;
target.isExtended = frame.isExtended;
target.dlc = frame.dlc;
for (const DecodeSignal &signal: frame.signals) {
SignalInfo copy;
copy.name = signal.name;
copy.startBit = signal.startBit;
copy.length = signal.length;
copy.isLittleEndian = signal.byteOrder == ByteOrder::Intel;
copy.isSigned = signal.valueType == ValueType::Signed;
copy.factor = signal.factor;
copy.offset = signal.offset;
copy.minimum = signal.minimum;
copy.maximum = signal.maximum;
copy.multiplexing = signal.multiplexing;
target.signals.push_back(copy);
}
database.frames.push_back(target);
}
return database;
}
}// namespace
class DbcValidationTest : public QObject {
Q_OBJECT
private Q_SLOTS:
void invalidMetadata_data();
void invalidMetadata();
void numericParameters_data();
void numericParameters();
void validBoundaries();
void multiplexingBoundaries();
void independentSnapshot();
void failedReplacement();
};
void DbcValidationTest::invalidMetadata_data() {
QTest::addColumn<int>("kind");
QTest::newRow("standard-id") << 0;
QTest::newRow("extended-id") << 1;
QTest::newRow("encoded-id") << 2;
QTest::newRow("duplicate-frame") << 3;
QTest::newRow("duplicate-signal") << 4;
QTest::newRow("zero-length") << 5;
QTest::newRow("65-bits") << 6;
QTest::newRow("length-overflow") << 7;
QTest::newRow("intel-start-overflow") << 8;
QTest::newRow("motorola-start-overflow") << 9;
QTest::newRow("intel-outside-payload") << 10;
QTest::newRow("motorola-outside-payload") << 11;
QTest::newRow("zero-payload") << 12;
QTest::newRow("inverted-range") << 13;
QTest::newRow("byte-order") << 14;
QTest::newRow("value-type") << 15;
QTest::newRow("multiplex-role") << 16;
QTest::newRow("missing-selector") << 17;
QTest::newRow("signed-selector") << 18;
QTest::newRow("two-selectors") << 19;
QTest::newRow("branch-range") << 20;
QTest::newRow("unconditional-overlap") << 21;
QTest::newRow("mixed-order-overlap") << 22;
QTest::newRow("same-branch-overlap") << 23;
QTest::newRow("selector-branch-overlap") << 24;
QTest::newRow("maximum-can-id") << 25;
}
void DbcValidationTest::invalidMetadata() {
QFETCH(int, kind);
std::vector<DecodeFrame> frames = {ValidFrame()};
DecodeFrame &frame = frames[0];
DecodeSignal &signal = frame.signals[0];
DecodeSignal other = signal;
other.name = "Other";
switch (kind) {
case 0:
frame.canId = 0x800U;
break;
case 1:
frame.isExtended = true;
frame.canId = 0x20000000U;
break;
case 2:
frame.isExtended = true;
frame.canId = 0x80000123U;
break;
case 3:
frames.push_back(frame);
break;
case 4:
frame.signals.push_back(signal);
break;
case 5:
signal.length = 0U;
break;
case 6:
signal.length = 65U;
break;
case 7:
signal.length = std::numeric_limits<std::uint32_t>::max();
break;
case 8:
signal.startBit = std::numeric_limits<std::uint32_t>::max();
break;
case 9:
signal.byteOrder = ByteOrder::Motorola;
signal.startBit = std::numeric_limits<std::uint32_t>::max();
break;
case 10:
signal.startBit = 57U;
break;
case 11:
signal.byteOrder = ByteOrder::Motorola;
signal.startBit = 56U;
break;
case 12:
frame.dlc = 0U;
break;
case 13:
signal.minimum = 2.0;
signal.maximum = 1.0;
break;
case 14:
signal.byteOrder = static_cast<ByteOrder>(99);
break;
case 15:
signal.valueType = static_cast<ValueType>(99);
break;
case 16:
signal.multiplexing.role = static_cast<MultiplexRole>(99);
break;
case 17:
signal.multiplexing.role = MultiplexRole::Branch;
break;
case 18:
signal.multiplexing.role = MultiplexRole::Selector;
signal.valueType = ValueType::Signed;
break;
case 19:
signal.multiplexing.role = MultiplexRole::Selector;
other.multiplexing.role = MultiplexRole::Selector;
other.startBit = 8U;
frame.signals.push_back(other);
break;
case 20:
case 23:
case 24:
signal.multiplexing.role = MultiplexRole::Selector;
other.multiplexing.role = MultiplexRole::Branch;
other.startBit = kind == 24 ? 0U : 8U;
other.multiplexing.value = kind == 20 ? 256U : 1U;
frame.signals.push_back(other);
if (kind == 23) {
other.name = "Third";
frame.signals.push_back(other);
}
break;
case 21:
frame.signals.push_back(other);
break;
case 22:
other.byteOrder = ByteOrder::Motorola;
other.startBit = 7U;
frame.signals.push_back(other);
break;
case 25:
frame.canId = std::numeric_limits<std::uint32_t>::max();
break;
}
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase(frames));
// Parsed metadata uses bools for byte order and signedness, so invalid enum
// values exist only in direct runtime definitions.
if (kind != 14 && kind != 15)
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DbcDecodeBuilder().Build(ParsedDefinitions(frames)));
}
void DbcValidationTest::numericParameters_data() {
QTest::addColumn<int>("field");
QTest::addColumn<double>("value");
const double values[] = {std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity()};
for (int field = 0; field < 4; ++field) {
for (int index = 0; index < 3; ++index) {
const QByteArray name = QByteArray::number(field) + "-" + QByteArray::number(index);
QTest::newRow(name.constData()) << field << values[index];
}
}
}
void DbcValidationTest::numericParameters() {
QFETCH(int, field);
QFETCH(double, value);
DecodeFrame frame = ValidFrame();
DecodeSignal &signal = frame.signals[0];
switch (field) {
case 0:
signal.factor = value;
break;
case 1:
signal.offset = value;
break;
case 2:
signal.minimum = value;
break;
case 3:
signal.maximum = value;
break;
}
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DecodeDatabase({frame}));
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, (void) DbcDecodeBuilder().Build(ParsedDefinitions({frame})));
}
void DbcValidationTest::validBoundaries() {
for (ByteOrder order: {ByteOrder::Intel, ByteOrder::Motorola}) {
for (std::uint8_t dlc: {std::uint8_t(8U), std::uint8_t(64U), std::uint8_t(255U)}) {
DecodeFrame standard = ValidFrame();
standard.canId = 0x7FFU;
standard.dlc = dlc;
DecodeSignal &signal = standard.signals[0];
signal.byteOrder = order;
signal.startBit = (std::uint32_t(dlc) - 8U) * 8U + (order == ByteOrder::Intel ? 0U : 7U);
signal.length = 64U;
signal.factor = -2.0;
signal.offset = std::numeric_limits<double>::max();
signal.minimum = -std::numeric_limits<double>::max();
signal.maximum = std::numeric_limits<double>::max();
DecodeFrame extended = standard;
extended.isExtended = true;
DecodeFrame maximum = extended;
maximum.canId = 0x1FFFFFFFU;
const std::vector<DecodeFrame> frames = {standard, extended, maximum};
const DecodeDatabase direct(frames);
const DecodeDatabase built = DbcDecodeBuilder().Build(ParsedDefinitions(frames));
for (const DecodeFrame &frame: frames) {
QVERIFY(direct.FindFrame(frame.GetKey()));
QVERIFY(built.FindSignal(SignalKey(frame.GetKey(), "Value")));
}
}
}
DecodeFrame empty;
empty.canId = 0U;
QVERIFY(DecodeDatabase({empty}).FindFrame(empty.GetKey()));
QVERIFY(DbcDecodeBuilder().Build(DbcDatabase()).GetFrames().empty());
}
void DbcValidationTest::multiplexingBoundaries() {
DecodeFrame frame = ValidFrame();
frame.dlc = 9U;
DecodeSignal &selector = frame.signals[0];
selector.length = 64U;
selector.multiplexing.role = MultiplexRole::Selector;
DecodeSignal first;
first.name = "First";
first.startBit = 64U;
first.length = 8U;
first.multiplexing.role = MultiplexRole::Branch;
first.multiplexing.value = std::numeric_limits<std::uint64_t>::max();
DecodeSignal second = first;
second.name = "Second";
second.byteOrder = ByteOrder::Motorola;
second.startBit = 71U;
second.multiplexing.value = 0U;
frame.signals.push_back(first);
frame.signals.push_back(second);
const DecodeDatabase direct({frame});
const DecodeDatabase built = DbcDecodeBuilder().Build(ParsedDefinitions({frame}));
RawCanFrame raw;
raw.canId = frame.canId;
raw.data.assign(9U, 255U);
for (const DecodeDatabase &database: {direct, built}) {
const DecodedFrameValue result = DbcDecoder().Decode(database, raw);
QCOMPARE(result.signals[1].status, SignalDecodeStatus::Valid);
QCOMPARE(result.signals[2].status, SignalDecodeStatus::Inactive);
}
}
void DbcValidationTest::independentSnapshot() {
std::vector<DecodeFrame> frames = {ValidFrame()};
DecodeFrame &alias = frames[0];
DecodeSignal &signalAlias = alias.signals[0];
signalAlias.valueDescriptions.emplace(std::uint64_t(1U), "One");
std::string &descriptionAlias = signalAlias.valueDescriptions.begin()->second;
const FrameKey key = alias.GetKey();
const DecodeDatabase database(std::move(frames));
alias.canId = 456U;
signalAlias.name = "Changed";
signalAlias.startBit = std::numeric_limits<std::uint32_t>::max();
descriptionAlias = "Changed";
const std::shared_ptr<const DecodeFrame> saved = database.FindFrame(key);
QVERIFY(saved);
QCOMPARE(saved->canId, key.canId);
QVERIFY(!database.FindFrame(FrameKey(456U, false)));
const std::shared_ptr<const DecodeSignal> signal = database.FindSignal(SignalKey(key, "Value"));
QVERIFY(signal);
QCOMPARE(signal->startBit, 0U);
QCOMPARE(signal->valueDescriptions.begin()->second, std::string("One"));
}
void DbcValidationTest::failedReplacement() {
const DecodeFrame valid = ValidFrame();
DecodeDatabase database({valid});
const std::shared_ptr<const DecodeFrame> original = database.FindFrame(valid.GetKey());
DecodeFrame invalid = valid;
invalid.canId = 0x800U;
QVERIFY_THROWS_EXCEPTION(std::invalid_argument, database = DecodeDatabase({invalid}));
QCOMPARE(database.FindFrame(valid.GetKey()).get(), original.get());
invalid = valid;
invalid.signals[0].factor = std::numeric_limits<double>::infinity();
QVERIFY_THROWS_EXCEPTION(std::invalid_argument,
database = DbcDecodeBuilder().Build(ParsedDefinitions({invalid})));
QCOMPARE(database.FindFrame(valid.GetKey()).get(), original.get());
QCOMPARE(database.GetFrames().size(), std::size_t(1U));
database = DecodeDatabase();
QVERIFY(database.GetFrames().empty());
QVERIFY(!database.FindFrame(valid.GetKey()));
QVERIFY(original);
}
int RunValidationTests(int argc, char **argv) {
DbcValidationTest tests;
return QTest::qExec(&tests, argc, argv);
}
#include "dbc_validation_test.moc"
+4 -1
View File
@@ -7,11 +7,14 @@ int RunCoverageTests(int argc, char **argv);
int RunLifetimeTests(int argc, char **argv);
int RunValidationTests(int argc, char **argv);
int main(int argc, char **argv) {
QCoreApplication application(argc, argv);
const int parserResult = RunParserTests(argc, argv);
const int decoderResult = RunDecoderTests(argc, argv);
const int coverageResult = RunCoverageTests(argc, argv);
const int lifetimeResult = RunLifetimeTests(argc, argv);
return parserResult | decoderResult | coverageResult | lifetimeResult;
const int validationResult = RunValidationTests(argc, argv);
return validationResult | parserResult | decoderResult | coverageResult | lifetimeResult;
}
+1 -1
View File
@@ -8,5 +8,5 @@ CONFIG -= app_bundle
include(../core/core.pri)
include(parser_tests.pri)
include(decoder_tests.pri)
SOURCES += main.cpp dbc_coverage_test.cpp dbc_lifetime_test.cpp
SOURCES += main.cpp dbc_coverage_test.cpp dbc_lifetime_test.cpp dbc_validation_test.cpp
CONFIG -= debug_and_release debug_and_release_target