137 lines
7.2 KiB
C++
137 lines
7.2 KiB
C++
#include "dbc_parser.h"
|
|
#include "dbc_tree_builder.h"
|
|
#include "dbc_tree_model.h"
|
|
#include <QAbstractItemModelTester>
|
|
#include <QSignalSpy>
|
|
#include <QTemporaryFile>
|
|
#include <QtTest>
|
|
#include <limits>
|
|
|
|
static std::unique_ptr<TreeNode> ParsedTree() {
|
|
QTemporaryFile fixture;
|
|
if (!fixture.open()) throw std::runtime_error("Fixture creation failed");
|
|
fixture.write("BO_ 256 Status: 8 ECU\n SG_ State : 0|8@1+ (1,0) [0|255] \"rpm\" ECU\n"
|
|
" SG_ Other : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
|
|
"BO_ 257 Second: 8 ECU\n SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
|
|
"CM_ BO_ 256 \"Frame comment\";\nCM_ SG_ 256 State \"Signal comment\";\n"
|
|
"VAL_ 256 State -1 \"Negative\" 0 \"Off\" 18446744073709551615 \"Maximum\";\n");
|
|
fixture.flush();
|
|
return DbcTreeBuilder().Build(DbcParser().ParseFile(fixture.fileName().toStdString()));
|
|
}
|
|
|
|
class ModelTest : public QObject {
|
|
Q_OBJECT
|
|
private Q_SLOTS:
|
|
void navigation() {
|
|
DbcTreeModel model;
|
|
QAbstractItemModelTester tester(&model, QAbstractItemModelTester::FailureReportingMode::QtTest);
|
|
QCOMPARE(model.rowCount(), 0);
|
|
model.SetTree(ParsedTree());
|
|
QCOMPARE(model.rowCount(), 2);
|
|
for (int row = 0; row < model.rowCount(); ++row) {
|
|
const QModelIndex frame = model.index(row, 0);
|
|
for (int column = 0; column < model.columnCount(); ++column) {
|
|
const QModelIndex frameColumn = model.index(row, column);
|
|
QVERIFY(!model.parent(frameColumn).isValid());
|
|
QCOMPARE(model.rowCount(frameColumn), column == 0 ? (row == 0 ? 2 : 1) : 0);
|
|
for (int signalRow = 0; signalRow < model.rowCount(frame); ++signalRow) {
|
|
const QModelIndex signal = model.index(signalRow, column, frame);
|
|
QCOMPARE(model.parent(signal), frame);
|
|
QCOMPARE(model.rowCount(signal), 0);
|
|
QVERIFY(!model.index(0, 0, signal).isValid());
|
|
QCOMPARE(model.flags(signal), Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
|
}
|
|
}
|
|
}
|
|
QVERIFY(!model.index(-1, 0).isValid());
|
|
QVERIFY(!model.index(2, 0).isValid());
|
|
QVERIFY(!model.index(0, -1).isValid());
|
|
QVERIFY(!model.index(0, model.columnCount()).isValid());
|
|
QVERIFY(!model.index(0, 0, model.index(0, 1)).isValid());
|
|
QVERIFY(!model.parent({}).isValid());
|
|
QVERIFY(!model.data({}).isValid());
|
|
QCOMPARE(model.flags({}), Qt::NoItemFlags);
|
|
DbcTreeModel other;
|
|
other.SetTree(ParsedTree());
|
|
const QModelIndex foreign = other.index(0, 0);
|
|
QVERIFY(!model.index(0, 0, foreign).isValid());
|
|
QVERIFY(!model.parent(foreign).isValid());
|
|
QCOMPARE(model.rowCount(foreign), 0);
|
|
QCOMPARE(model.columnCount(foreign), 0);
|
|
QVERIFY(!model.data(foreign).isValid());
|
|
QCOMPARE(model.flags(foreign), Qt::NoItemFlags);
|
|
}
|
|
void metadata() {
|
|
DbcTreeModel model;
|
|
model.SetTree(ParsedTree());
|
|
const QModelIndex frame = model.index(0, 0);
|
|
const QModelIndex signal = model.index(0, 0, frame);
|
|
QCOMPARE(model.data(frame).toString(), QString("Status"));
|
|
QCOMPARE(model.data(model.index(0, DbcTreeModel::CanId)).toString(), QString("0X100"));
|
|
QCOMPARE(model.data(frame, DbcTreeModel::CanIdRole).toUInt(), 256U);
|
|
QCOMPARE(model.data(frame, DbcTreeModel::PayloadLengthRole).toInt(), 8);
|
|
QCOMPARE(model.data(signal, DbcTreeModel::UnitRole).toString(), QString("rpm"));
|
|
const QVariantList expectedSignal = {"State", QVariant(), QVariant(), 0U, 8U,
|
|
"Intel", "Unsigned", "rpm", "Signal comment"};
|
|
const QVariantList expectedFrame = {"Status", "0X100", 8, QVariant(), QVariant(),
|
|
QVariant(), QVariant(), QVariant(), "Frame comment"};
|
|
for (int column = 0; column < model.columnCount(); ++column) {
|
|
QCOMPARE(model.data(model.index(0, column, frame)), expectedSignal.at(column));
|
|
QCOMPARE(model.data(model.index(0, column)), expectedFrame.at(column));
|
|
}
|
|
QCOMPARE(model.data(frame, DbcTreeModel::NodeTypeRole).toInt(), static_cast<int>(NodeType::Frame));
|
|
QCOMPARE(model.data(signal, DbcTreeModel::NodeTypeRole).toInt(), static_cast<int>(NodeType::Signal));
|
|
QCOMPARE(model.data(frame, DbcTreeModel::ExtendedRole).toBool(), false);
|
|
QVERIFY(!model.data(frame, DbcTreeModel::ValueDescriptionsRole).isValid());
|
|
QVERIFY(model.data(model.index(1, 0, frame), DbcTreeModel::ValueDescriptionsRole).toList().isEmpty());
|
|
|
|
QCOMPARE(model.data(signal, Qt::ToolTipRole).toString(), QString("Signal comment"));
|
|
QCOMPARE(model.data(signal, DbcTreeModel::StartBitRole).toUInt(), 0U);
|
|
QCOMPARE(model.data(signal, DbcTreeModel::BitLengthRole).toUInt(), 8U);
|
|
QCOMPARE(model.data(signal, DbcTreeModel::LittleEndianRole).toBool(), true);
|
|
QCOMPARE(model.data(signal, DbcTreeModel::SignedRole).toBool(), false);
|
|
QVERIFY(!model.data(signal, DbcTreeModel::CanIdRole).isValid());
|
|
QVERIFY(!model.data(frame, DbcTreeModel::UnitRole).isValid());
|
|
QVERIFY(!model.data(frame, Qt::EditRole).isValid());
|
|
const QVariantList values = model.data(signal, DbcTreeModel::ValueDescriptionsRole).toList();
|
|
QCOMPARE(values.size(), 3);
|
|
QCOMPARE(values.at(0).toMap().value("value").toLongLong(), -1LL);
|
|
QCOMPARE(values.at(2).toMap().value("value").toULongLong(), std::numeric_limits<qulonglong>::max());
|
|
QCOMPARE(values.at(2).toMap().value("description").toString(), QString("Maximum"));
|
|
for (int column = 0; column < model.columnCount(); ++column) {
|
|
QVERIFY(model.headerData(column, Qt::Horizontal).isValid());
|
|
QCOMPARE(model.data(model.index(0, column, frame), DbcTreeModel::ValueDescriptionsRole), QVariant(values));
|
|
}
|
|
QVERIFY(!model.headerData(-1, Qt::Horizontal).isValid());
|
|
QVERIFY(!model.headerData(model.columnCount(), Qt::Horizontal).isValid());
|
|
QVERIFY(!model.headerData(0, Qt::Vertical).isValid());
|
|
}
|
|
void replacement() {
|
|
DbcTreeModel model;
|
|
QAbstractItemModelTester tester(&model, QAbstractItemModelTester::FailureReportingMode::QtTest);
|
|
QSignalSpy resets(&model, &QAbstractItemModel::modelReset);
|
|
model.SetTree(ParsedTree());
|
|
QPersistentModelIndex frame(model.index(0, 0));
|
|
QPersistentModelIndex signal(model.index(0, 4, frame));
|
|
model.SetTree(ParsedTree());
|
|
QVERIFY(!frame.isValid());
|
|
QVERIFY(!signal.isValid());
|
|
QCOMPARE(model.rowCount(), 2);
|
|
QPersistentModelIndex replacement(model.index(1, 0));
|
|
model.SetTree(nullptr);
|
|
QVERIFY(!replacement.isValid());
|
|
QCOMPARE(model.rowCount(), 0);
|
|
QVERIFY(!model.index(0, 0).isValid());
|
|
model.SetTree(nullptr);
|
|
QCOMPARE(resets.count(), 4);
|
|
try {
|
|
model.SetTree(std::unique_ptr<TreeNode>(new TreeNode(FrameInfo())));
|
|
QFAIL("A frame cannot be the invisible model root");
|
|
} catch (const std::invalid_argument &) {
|
|
}
|
|
QCOMPARE(resets.count(), 4);
|
|
}
|
|
};
|
|
QTEST_GUILESS_MAIN(ModelTest)
|
|
#include "dbc_tree_model_test.moc"
|