Add per-module unit-test dirs for the Release 2 scope
One unit-test/ directory per module/target, mirroring the existing TetraIF/unit-test/ layout (one QtTest executable per module, guarded by BUILD_TESTING and the module target, each registered with ctest): Lts/Common/CodeGen codegen_unit_test Lts/Common/LtsCoordinate ltscoordinate_unit_test Lts/Common/LtsSession ltssession_unit_test Lts/DDS/Core ddscore_unit_test Lts/DDS/QosProfile ddsqos_unit_test Lts/Tools/LogViewer logviewer_unit_test Lts/Tools/SqlBrowser sqlbrowser_unit_test Z/src/NGLLogger ngllogger_unit_test Z/src/WMS_Interface wms_json_ds_unit_test Z/src/nglapplication nglcoreapplication_unit_test Z/src/nglcompression nglcompression_unit_test Z/src/nglsettings nglsettings_unit_test Z/src/ngltranslator ngltranslator_unit_test Where a module is built with hidden visibility and has no export macro (LogViewer, SqlBrowser, ngltranslator, NGLLogger, nglcompression, nglsettings), its sources are compiled directly into the test executable, the same pattern as prtcnv_unit_test. ctest baseline in the container (QT_QPA_PLATFORM=offscreen): 20/23 passed (13 new + 7 pre-existing in-scope tests), 3 Not Run as before (nglcomp_test, GrantleeParserSmoke, utils_test). README: ctest baseline table extended to the 23 registered tests and section 2.4 now documents the per-module test layout. ddsview has no unit test (GUI tool, XmlHelper needs the DDS dynamic-xtypes runtime).
This commit is contained in:
1 parent
a62b729577
commit
09b6df8bc3
40 files changed
+4966
-17
No files matched your search
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# Unit tests for the SqlBrowser module.
|
||||
# One test executable per module, each registered with ctest.
|
||||
#
|
||||
if (NOT BUILD_TESTING)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# --- SqlBrowser: data model + add-table model.
|
||||
# --- The module is an executable, so the model sources are compiled directly
|
||||
# --- into the test (same pattern as the LogView test in TetraIF/unit-test).
|
||||
if (TARGET sqlbrowser)
|
||||
ADD_EXECUTABLE(sqlbrowser_unit_test
|
||||
sqlbrowser_unit_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../DataModel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../AddModel.cpp)
|
||||
TARGET_LINK_LIBRARIES(sqlbrowser_unit_test
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Test
|
||||
)
|
||||
ADD_TEST(NAME sqlbrowser_unit_test COMMAND $<TARGET_FILE:sqlbrowser_unit_test>)
|
||||
endif()
|
||||
+410
@@ -0,0 +1,410 @@
|
||||
//
|
||||
// Unit tests for the SqlBrowser module: DataModel (double-buffered table
|
||||
// model with role handling) and AddModel (add-row table model).
|
||||
//
|
||||
// These are the module's pure non-GUI logic classes. No database access is
|
||||
// involved: the DB work lives in QueryWorker/QueryThread (QSqlDatabase on a
|
||||
// worker thread). The remaining SqlBrowser classes are either widgets
|
||||
// (Query, BrowserWnd, LoginWnd, WaitWnd, AddLines) or DB/thread driven.
|
||||
// PresetManager is skipped as well: its constructor calls
|
||||
// QApplication::arguments() and its save path uses QInputDialog, so it
|
||||
// requires a running GUI application.
|
||||
//
|
||||
#include "../DataModel.h"
|
||||
#include "../AddModel.h"
|
||||
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtGui/QColor>
|
||||
#include <QtTest/QTest>
|
||||
|
||||
class sqlbrowser_unit_test : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
// DataModel
|
||||
void dataModelEmptyState();
|
||||
void dataModelSwapLists();
|
||||
void dataModelDataRoleHandling();
|
||||
void dataModelToolTipTimestamp();
|
||||
void dataModelHeaderData();
|
||||
void dataModelTableEditability();
|
||||
void dataModelSlotSetData();
|
||||
void dataModelSetDataAsyncSemantics();
|
||||
void dataModelDeleteLines();
|
||||
|
||||
// AddModel
|
||||
void addModelBasics();
|
||||
void addModelSetDataCreatesRow();
|
||||
void addModelStringifiesValues();
|
||||
void addModelRemoveRow();
|
||||
void addModelClear();
|
||||
void addModelTableName();
|
||||
};
|
||||
|
||||
// --- DataModel ----------------------------------------------------------------
|
||||
|
||||
void sqlbrowser_unit_test::dataModelEmptyState()
|
||||
{
|
||||
DataModel model;
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
QCOMPARE(model.columnCount(), 0);
|
||||
QVERIFY(model.getTableName().isEmpty());
|
||||
|
||||
Qt::ItemFlags flags = model.flags(QModelIndex());
|
||||
QVERIFY(flags & Qt::ItemIsSelectable);
|
||||
QVERIFY(flags & Qt::ItemIsEnabled);
|
||||
QVERIFY(!(flags & Qt::ItemIsEditable));
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelSwapLists()
|
||||
{
|
||||
DataModel model;
|
||||
|
||||
// columns/rows are staged in the write buffer first
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
model.addColumn(QStringLiteral("name"), QMetaType::QString);
|
||||
model.addColumn(QStringLiteral("ts"), QMetaType::LongLong);
|
||||
|
||||
Data row0;
|
||||
row0 << 1 << QStringLiteral("alpha") << static_cast<qint64>(1700000000000LL);
|
||||
model.addLine(row0);
|
||||
|
||||
// nothing is visible in the live model before the swap
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
QCOMPARE(model.columnCount(), 0);
|
||||
|
||||
model.slotSwapLists();
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.columnCount(), 3);
|
||||
|
||||
const HeaderList &live = model.getHeaderList();
|
||||
QCOMPARE(live.size(), 3);
|
||||
QCOMPARE(live.at(0).first, QStringLiteral("id"));
|
||||
QVERIFY(live.at(0).second == QMetaType::Int);
|
||||
QCOMPARE(live.at(1).first, QStringLiteral("name"));
|
||||
QVERIFY(live.at(1).second == QMetaType::QString);
|
||||
QCOMPARE(live.at(2).first, QStringLiteral("ts"));
|
||||
QVERIFY(live.at(2).second == QMetaType::LongLong);
|
||||
|
||||
// the write buffer is cleared by the swap: new staging does not leak
|
||||
// into the live model
|
||||
Data row1;
|
||||
row1 << 999 << QStringLiteral("leak");
|
||||
model.addLine(row1);
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 1);
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelDataRoleHandling()
|
||||
{
|
||||
DataModel model;
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
model.addColumn(QStringLiteral("name"), QMetaType::QString);
|
||||
model.addColumn(QStringLiteral("ts"), QMetaType::LongLong);
|
||||
|
||||
Data row0;
|
||||
row0 << 1 << QStringLiteral("alpha") << static_cast<qint64>(1700000000000LL);
|
||||
Data row1;
|
||||
row1 << 2 << QVariant() << static_cast<qint64>(5);
|
||||
Data row2;
|
||||
row2 << 3 << QStringLiteral("gamma") << QVariant();
|
||||
model.addLine(row0);
|
||||
model.addLine(row1);
|
||||
model.addLine(row2);
|
||||
model.slotSwapLists();
|
||||
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.columnCount(), 3);
|
||||
|
||||
// DisplayRole and EditRole both return the raw value
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 1);
|
||||
QCOMPARE(model.data(model.index(0, 1), Qt::DisplayRole).toString(), QStringLiteral("alpha"));
|
||||
QCOMPARE(model.data(model.index(0, 2), Qt::EditRole).toLongLong(), qint64(1700000000000));
|
||||
|
||||
// null cells are highlighted via BackgroundRole; filled cells are not
|
||||
QCOMPARE(model.data(model.index(1, 1), Qt::BackgroundRole).value<QColor>(), QColor(255, 255, 215));
|
||||
QVERIFY(!model.data(model.index(0, 0), Qt::BackgroundRole).isValid());
|
||||
|
||||
// other roles return nothing
|
||||
QVERIFY(!model.data(model.index(0, 1), Qt::DecorationRole).isValid());
|
||||
|
||||
// a valid parent index means "no children"
|
||||
QCOMPARE(model.rowCount(model.index(0, 0)), 0);
|
||||
QCOMPARE(model.columnCount(model.index(0, 0)), 0);
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelToolTipTimestamp()
|
||||
{
|
||||
DataModel model;
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
model.addColumn(QStringLiteral("name"), QMetaType::QString);
|
||||
model.addColumn(QStringLiteral("ts"), QMetaType::LongLong);
|
||||
|
||||
Data row0;
|
||||
row0 << 1 << QStringLiteral("alpha") << static_cast<qint64>(1700000000000);
|
||||
Data row1;
|
||||
row1 << 2 << QStringLiteral("beta") << static_cast<qint64>(5);
|
||||
model.addLine(row0);
|
||||
model.addLine(row1);
|
||||
model.slotSwapLists();
|
||||
|
||||
// 64 bit integer values above 1000000000 are rendered as timestamps
|
||||
const QVariant tooltip = model.data(model.index(0, 2), Qt::ToolTipRole);
|
||||
QVERIFY(tooltip.isValid());
|
||||
const QRegularExpression pattern(QStringLiteral("^\\d{2}\\.\\d{2}\\.\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}$"));
|
||||
QVERIFY(pattern.match(tooltip.toString()).hasMatch());
|
||||
|
||||
// below the threshold -> no tooltip
|
||||
QVERIFY(!model.data(model.index(1, 2), Qt::ToolTipRole).isValid());
|
||||
// non-integer types -> no tooltip
|
||||
QVERIFY(!model.data(model.index(0, 1), Qt::ToolTipRole).isValid());
|
||||
QVERIFY(!model.data(model.index(0, 0), Qt::ToolTipRole).isValid());
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelHeaderData()
|
||||
{
|
||||
DataModel model;
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
model.addColumn(QStringLiteral("name"), QMetaType::QString);
|
||||
model.addColumn(QStringLiteral("ts"), QMetaType::LongLong);
|
||||
model.slotSwapLists();
|
||||
|
||||
QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), QStringLiteral("id"));
|
||||
QCOMPARE(model.headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), QStringLiteral("name"));
|
||||
QCOMPARE(model.headerData(2, Qt::Horizontal, Qt::DisplayRole).toString(), QStringLiteral("ts"));
|
||||
|
||||
// ToolTipRole carries the QMetaType name of the column
|
||||
QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::ToolTipRole).toString(), QStringLiteral("int"));
|
||||
QCOMPARE(model.headerData(1, Qt::Horizontal, Qt::ToolTipRole).toString(), QStringLiteral("QString"));
|
||||
QCOMPARE(model.headerData(2, Qt::Horizontal, Qt::ToolTipRole).toString(), QStringLiteral("qlonglong"));
|
||||
|
||||
// out-of-range section and vertical orientation fall through to
|
||||
// QAbstractTableModel::headerData (1-based: section+1 horizontal, 1 vertical)
|
||||
QCOMPARE(model.headerData(9, Qt::Horizontal, Qt::DisplayRole).toString(), QStringLiteral("10"));
|
||||
QCOMPARE(model.headerData(0, Qt::Vertical, Qt::DisplayRole).toString(), QStringLiteral("1"));
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelTableEditability()
|
||||
{
|
||||
DataModel model;
|
||||
|
||||
// custom queries (empty table name) are read-only
|
||||
QVERIFY(!(model.flags(QModelIndex()) & Qt::ItemIsEditable));
|
||||
|
||||
// table queries are editable
|
||||
model.setTableName(QStringLiteral("users"));
|
||||
QCOMPARE(model.getTableName(), QStringLiteral("users"));
|
||||
QVERIFY(model.flags(QModelIndex()) & Qt::ItemIsEditable);
|
||||
|
||||
model.setTableName(QString());
|
||||
QVERIFY(!(model.flags(QModelIndex()) & Qt::ItemIsEditable));
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelSlotSetData()
|
||||
{
|
||||
DataModel model;
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
model.addColumn(QStringLiteral("name"), QMetaType::QString);
|
||||
Data row0;
|
||||
row0 << 1 << QStringLiteral("alpha");
|
||||
Data row1;
|
||||
row1 << 2 << QStringLiteral("beta");
|
||||
model.addLine(row0);
|
||||
model.addLine(row1);
|
||||
model.slotSwapLists();
|
||||
|
||||
// slotSetData applies the write to the live list (the DB answered)
|
||||
model.slotSetData(model.index(1, 1), QStringLiteral("delta"));
|
||||
QCOMPARE(model.data(model.index(1, 1), Qt::DisplayRole).toString(), QStringLiteral("delta"));
|
||||
QCOMPARE(model.data(model.index(0, 1), Qt::DisplayRole).toString(), QStringLiteral("alpha"));
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelSetDataAsyncSemantics()
|
||||
{
|
||||
DataModel model;
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
Data row0;
|
||||
row0 << 1;
|
||||
model.addLine(row0);
|
||||
model.slotSwapLists();
|
||||
|
||||
bool captured = false;
|
||||
QVariant capturedValue;
|
||||
DataModel *capturedModel = nullptr;
|
||||
QObject::connect(&model, &DataModel::signalSetData,
|
||||
[&captured, &capturedValue, &capturedModel](DataModel *m, const QModelIndex &,
|
||||
const QVariant &v) {
|
||||
captured = true;
|
||||
capturedModel = m;
|
||||
capturedValue = v;
|
||||
});
|
||||
|
||||
// EditRole: value is NOT applied locally; it is forwarded to the worker
|
||||
// and the call reports "not done yet"
|
||||
QVERIFY(!model.setData(model.index(0, 0), QStringLiteral("changed"), Qt::EditRole));
|
||||
QVERIFY(captured);
|
||||
QCOMPARE(capturedModel, static_cast<DataModel *>(&model));
|
||||
QCOMPARE(capturedValue.toString(), QStringLiteral("changed"));
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 1); // untouched
|
||||
|
||||
// non-EditRole values are accepted (true) and ignored
|
||||
QVERIFY(model.setData(model.index(0, 0), QStringLiteral("ignored"), Qt::DisplayRole));
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 1);
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::dataModelDeleteLines()
|
||||
{
|
||||
DataModel model;
|
||||
model.addColumn(QStringLiteral("id"), QMetaType::Int);
|
||||
Data row0;
|
||||
row0 << 1;
|
||||
Data row1;
|
||||
row1 << 2;
|
||||
Data row2;
|
||||
row2 << 3;
|
||||
model.addLine(row0);
|
||||
model.addLine(row1);
|
||||
model.addLine(row2);
|
||||
model.slotSwapLists();
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
|
||||
// delete in descending row order so the indices stay valid
|
||||
QList<QModelIndex> toDelete;
|
||||
toDelete << model.index(2, 0) << model.index(0, 0);
|
||||
model.deleteLines(toDelete);
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toInt(), 2);
|
||||
|
||||
// an empty index list is a no-op
|
||||
model.deleteLines(QList<QModelIndex>());
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
}
|
||||
|
||||
// --- AddModel --------------------------------------------------------------------
|
||||
|
||||
void sqlbrowser_unit_test::addModelBasics()
|
||||
{
|
||||
AddModel model;
|
||||
|
||||
// rowCount is always dataList + 1 (the trailing empty row for new data)
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.columnCount(), 0);
|
||||
|
||||
HeaderList headers;
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("id"), QMetaType::Int));
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("name"), QMetaType::QString));
|
||||
model.setHeaderList(headers);
|
||||
|
||||
QCOMPARE(model.columnCount(), 2);
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
|
||||
QVERIFY(model.getColumnType(0) == QMetaType::Int);
|
||||
QVERIFY(model.getColumnType(1) == QMetaType::QString);
|
||||
QVERIFY(model.getColumnType(-1) == QMetaType::UnknownType);
|
||||
QVERIFY(model.getColumnType(2) == QMetaType::UnknownType);
|
||||
|
||||
QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), QStringLiteral("id"));
|
||||
QCOMPARE(model.headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), QStringLiteral("name"));
|
||||
// only horizontal + displayRole
|
||||
QVERIFY(!model.headerData(0, Qt::Vertical, Qt::DisplayRole).isValid());
|
||||
QVERIFY(!model.headerData(0, Qt::Horizontal, Qt::EditRole).isValid());
|
||||
|
||||
const Qt::ItemFlags flags = model.flags(QModelIndex());
|
||||
QVERIFY(flags & Qt::ItemIsSelectable);
|
||||
QVERIFY(flags & Qt::ItemIsEnabled);
|
||||
QVERIFY(flags & Qt::ItemIsEditable);
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::addModelSetDataCreatesRow()
|
||||
{
|
||||
AddModel model;
|
||||
HeaderList headers;
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("id"), QMetaType::Int));
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("name"), QMetaType::QString));
|
||||
model.setHeaderList(headers);
|
||||
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
|
||||
// writing into the empty row materializes it
|
||||
QVERIFY(model.setData(model.index(0, 0), QStringLiteral("42"), Qt::EditRole));
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toString(), QStringLiteral("42"));
|
||||
// other columns of the new row are pre-filled with empty strings
|
||||
QCOMPARE(model.data(model.index(0, 1), Qt::DisplayRole).toString(), QString());
|
||||
|
||||
// the trailing empty row still has no data
|
||||
QVERIFY(!model.data(model.index(1, 0), Qt::DisplayRole).isValid());
|
||||
|
||||
// a second write materializes row 1
|
||||
QVERIFY(model.setData(model.index(1, 1), QStringLiteral("bob"), Qt::EditRole));
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
QCOMPARE(model.data(model.index(1, 1), Qt::DisplayRole).toString(), QStringLiteral("bob"));
|
||||
QCOMPARE(model.data(model.index(1, 0), Qt::DisplayRole).toString(), QString());
|
||||
|
||||
// non-EditRole values are rejected
|
||||
QVERIFY(!model.setData(model.index(0, 0), QStringLiteral("x"), Qt::DisplayRole));
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toString(), QStringLiteral("42"));
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::addModelStringifiesValues()
|
||||
{
|
||||
AddModel model;
|
||||
HeaderList headers;
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("id"), QMetaType::Int));
|
||||
model.setHeaderList(headers);
|
||||
|
||||
// stored values are stringified on write
|
||||
QVERIFY(model.setData(model.index(0, 0), 42, Qt::EditRole));
|
||||
const QVariant value = model.data(model.index(0, 0), Qt::DisplayRole);
|
||||
QCOMPARE(value.toString(), QStringLiteral("42"));
|
||||
QVERIFY(value.typeId() == QMetaType::QString);
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::addModelRemoveRow()
|
||||
{
|
||||
AddModel model;
|
||||
HeaderList headers;
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("id"), QMetaType::Int));
|
||||
model.setHeaderList(headers);
|
||||
|
||||
QVERIFY(model.setData(model.index(0, 0), QStringLiteral("1"), Qt::EditRole));
|
||||
QVERIFY(model.setData(model.index(1, 0), QStringLiteral("2"), Qt::EditRole));
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
|
||||
// out-of-range row
|
||||
QVERIFY(!model.removeRow(10));
|
||||
QCOMPARE(model.rowCount(), 3);
|
||||
|
||||
QVERIFY(model.removeRow(0));
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
QCOMPARE(model.data(model.index(0, 0), Qt::DisplayRole).toString(), QStringLiteral("2"));
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::addModelClear()
|
||||
{
|
||||
AddModel model;
|
||||
HeaderList headers;
|
||||
headers.append(QPair<QString, QMetaType::Type>(QStringLiteral("id"), QMetaType::Int));
|
||||
model.setHeaderList(headers);
|
||||
QVERIFY(model.setData(model.index(0, 0), QStringLiteral("1"), Qt::EditRole));
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
|
||||
model.clear();
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.columnCount(), 1); // header list survives clear()
|
||||
}
|
||||
|
||||
void sqlbrowser_unit_test::addModelTableName()
|
||||
{
|
||||
AddModel model;
|
||||
QCOMPARE(model.getTableName(), QString());
|
||||
model.setTablename(QStringLiteral("t_users"));
|
||||
QCOMPARE(model.getTableName(), QStringLiteral("t_users"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(sqlbrowser_unit_test)
|
||||
#include "sqlbrowser_unit_test.moc"
|
||||
Reference in new issue
Block a user