aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_threadlistmodel.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-08 10:20:14 +0200
committerDanilo M. <danix@danix.xyz>2026-08-08 10:20:14 +0200
commit02d218358347e5d7a29164bc70a346c57fe098ab (patch)
tree33c3292c2e1d215a0465640a195c5d720e88a719 /tests/test_threadlistmodel.cpp
parentbb3e119a55345e997efe80ec275e67acf7a04851 (diff)
downloadqtmaildir-02d218358347e5d7a29164bc70a346c57fe098ab.tar.gz
qtmaildir-02d218358347e5d7a29164bc70a346c57fe098ab.zip
refactor(model): convert ThreadListModel to QAbstractItemModel
A table cannot indent or expand, so message rows need a tree. This task changes only the base class and the index plumbing: no children are produced yet, so the 30 pre-existing tests in test_threadlistmodel are the regression net proving a thread row still behaves exactly as it did, and QAbstractItemModelTester checks the index/parent round trip a hand-written assertion would miss. Two things the table version could leave wrong and a tree cannot. columnCount returned 0 for a valid parent, which would give message rows no columns and render them blank. And rowCount now answers only for column 0, since a tree takes one set of children per row and offering them under every column draws an expander in each. The model stays two levels deep even though replies carry a reply depth of their own. The visual nesting past the first level comes from that depth, not from further parent-child structure, so no index calculation has to recurse.
Diffstat (limited to 'tests/test_threadlistmodel.cpp')
-rw-r--r--tests/test_threadlistmodel.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/tests/test_threadlistmodel.cpp b/tests/test_threadlistmodel.cpp
index e2ca09f..9684637 100644
--- a/tests/test_threadlistmodel.cpp
+++ b/tests/test_threadlistmodel.cpp
@@ -28,6 +28,7 @@ class TestThreadListModel : public QObject
Q_OBJECT
private slots:
void messageNodeHoldsDisplayFacts();
+ void rootRowsSurviveTheTreeConversion();
void startsEmpty();
void accountKeysComeFromTheAccountTags();
void accountKeysCoverAThreadSpanningTwoAccounts();
@@ -142,6 +143,39 @@ void TestThreadListModel::messageNodeHoldsDisplayFacts()
QVERIFY(!fresh.isUnread());
}
+void TestThreadListModel::rootRowsSurviveTheTreeConversion()
+{
+ // The point of this test is NOT the tree. It is that converting the base
+ // class from QAbstractTableModel changed nothing a thread row does: a table
+ // answers index() and parent() too, just trivially, and every existing test
+ // in this file is the real regression net beside it.
+ ThreadListModel model;
+ model.appendBatch({ makeThread(QStringLiteral("t1"),
+ QStringLiteral("A subject")) });
+
+ // A tree model reports its roots under an INVALID parent.
+ QCOMPARE(model.rowCount(QModelIndex()), 1);
+ QCOMPARE(model.columnCount(QModelIndex()), ThreadListModel::ColumnCount);
+
+ const QModelIndex root =
+ model.index(0, ThreadListModel::SubjectColumn, QModelIndex());
+ QVERIFY(root.isValid());
+ QVERIFY(!model.parent(root).isValid());
+ QCOMPARE(model.data(root, ThreadListModel::ThreadIdRole).toString(),
+ QStringLiteral("t1"));
+
+ // No children until a thread's messages are asked for. An expander drawn
+ // over a thread whose replies were never loaded would open onto nothing.
+ QCOMPARE(model.rowCount(root), 0);
+
+ // Qt's own conformance check. It walks index/parent/rowCount for
+ // consistency and catches the classic tree-model faults, such as a parent()
+ // that does not round-trip, which a hand-written assertion misses.
+ QAbstractItemModelTester tester(
+ &model, QAbstractItemModelTester::FailureReportingMode::Warning);
+ Q_UNUSED(tester);
+}
+
void TestThreadListModel::startsEmpty()
{
ThreadListModel model;