diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-28 20:46:44 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-28 20:46:44 +0200 |
| commit | d7c4d03f7d583767bc23406579e11bcc884dec18 (patch) | |
| tree | abe49fa75cb88d768a892cc11a8c2258869ead85 /tests | |
| parent | ae2ae2df75ed780a88423b77af3b31fbe2b26389 (diff) | |
| download | qtmaildir-thread-row-identity.tar.gz qtmaildir-thread-row-identity.zip | |
feat: count a card's messages, not its repliesthread-row-identity
The expander pill read "N replies" while the row stood for the
conversation: a thread of one message and four replies said "4 replies"
over rows that listed all five messages. The user's model is messages, so
it now reads "5 messages". A thread of one still shows nothing: its row is
the message, the pill is the expander, and there is nothing to open.
ReplyCountRole becomes MessageCountRole and CardLayout::Input::replyCount
becomes messageCount, so the names stop lying about what they carry. The
label is now translated under a CardLayout context, with Italian
"messaggio"/"messaggi" shipped; %n's untranslated fallback on this Qt does
not pluralise, so the two forms are separate entries. The card's densest
geometry test needs 460px rather than 400 now that the pill is one
character wider.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_cardlayout.cpp | 24 | ||||
| -rw-r--r-- | tests/test_mainwindow.cpp | 9 | ||||
| -rw-r--r-- | tests/test_threadlistmodel.cpp | 39 |
3 files changed, 39 insertions, 33 deletions
diff --git a/tests/test_cardlayout.cpp b/tests/test_cardlayout.cpp index c81296f..09afc5f 100644 --- a/tests/test_cardlayout.cpp +++ b/tests/test_cardlayout.cpp @@ -58,7 +58,7 @@ CardLayout::Input threadInput() CardLayout::Input in; in.isMessage = false; in.depth = 0; - in.replyCount = 3; + in.messageCount = 3; return in; } @@ -67,7 +67,7 @@ CardLayout::Input replyInput(int depth) CardLayout::Input in; in.isMessage = true; in.depth = depth; - in.replyCount = 0; + in.messageCount = 0; return in; } @@ -91,7 +91,7 @@ void TestCardLayout::everyCardIsTheSameHeight() const CardLayout deepReply = CardLayout::compute(replyInput(3), QRect(0, 0, 400, thread), font); CardLayout::Input noRepliesIn = threadInput(); - noRepliesIn.replyCount = 0; + noRepliesIn.messageCount = 0; const CardLayout noReplies = CardLayout::compute(noRepliesIn, QRect(0, 0, 400, thread), font); @@ -225,7 +225,7 @@ void TestCardLayout::expanderIsEmptyWithoutReplies() const QFont font; const int h = CardLayout::heightFor(font); CardLayout::Input in = threadInput(); - in.replyCount = 0; + in.messageCount = 0; const CardLayout card = CardLayout::compute(in, QRect(0, 0, 400, h), font); QVERIFY(card.expanderRect.isEmpty()); @@ -240,12 +240,12 @@ void TestCardLayout::theExpanderReadsAsAPillWithAWord() // NO triangle in the label since item 70: it is a drawn mark now, and a // glyph left here would be a second triangle beside the drawn one. The // label is the words alone, and the state no longer changes it. - QCOMPARE(CardLayout::expanderLabel(3, false), QStringLiteral("3 replies")); - QCOMPARE(CardLayout::expanderLabel(3, true), QStringLiteral("3 replies")); + QCOMPARE(CardLayout::expanderLabel(3, false), QStringLiteral("3 messages")); + QCOMPARE(CardLayout::expanderLabel(3, true), QStringLiteral("3 messages")); - // Singular, because "1 replies" is the kind of detail that makes an + // Singular, because "1 messages" is the kind of detail that makes an // interface look unfinished. - QCOMPARE(CardLayout::expanderLabel(1, false), QStringLiteral("1 reply")); + QCOMPARE(CardLayout::expanderLabel(1, false), QStringLiteral("1 message")); // The glyphs are gone from the label entirely. Asserted rather than assumed, // because a stray one would draw underneath the mark and look like a @@ -377,7 +377,11 @@ void TestCardLayout::marksDoNotCollideWithEachOtherOrTheExpander() // densest line two can get. Nothing may overlap anything. const QFont font; const int h = CardLayout::heightFor(font); - const QRect rect(0, 0, 400, h); + // 460 rather than 400: the pill reads "3 messages" now, a character wider + // than "3 replies" was, and 400 left the elastic subject narrower than the + // avatar gutter with all four marks out. The width is a stress value, not + // a spec. + const QRect rect(0, 0, 460, h); CardLayout::Input in = threadInput(); in.flagged = true; @@ -421,7 +425,7 @@ void TestCardLayout::marksDoNotCollideWithEachOtherOrTheExpander() // not leave the subject narrower than the avatar gutter beside it. QVERIFY2(card.subjectRect.width() > card.avatarRect.width(), "four marks left the subject narrower than the avatar gutter on a " - "400px card"); + "460px card"); } void TestCardLayout::dateIsFlushRight() diff --git a/tests/test_mainwindow.cpp b/tests/test_mainwindow.cpp index aecefb7..2e7d220 100644 --- a/tests/test_mainwindow.cpp +++ b/tests/test_mainwindow.cpp @@ -1396,10 +1396,11 @@ void TestMainWindow::aThreadWithRepliesDrawsAVisibleExpander() const QModelIndex first = model->index(0, 0, QModelIndex()); const QModelIndex second = model->index(1, 0, QModelIndex()); - // Guards: the model agrees about which thread has replies, and only that - // one is offered an expander at all. - QCOMPARE(model->data(first, ThreadListModel::ReplyCountRole).toInt(), 2); - QCOMPARE(model->data(second, ThreadListModel::ReplyCountRole).toInt(), 0); + // Guards: the model agrees about which thread has an expander, and only + // that one is offered one at all. The count is MESSAGES: the three-message + // thread reads 3, the lone message reads 0. + QCOMPARE(model->data(first, ThreadListModel::MessageCountRole).toInt(), 3); + QCOMPARE(model->data(second, ThreadListModel::MessageCountRole).toInt(), 0); const QFont font = view->font(); const int height = CardLayout::heightFor(font); diff --git a/tests/test_threadlistmodel.cpp b/tests/test_threadlistmodel.cpp index fba2d2d..28d3a8b 100644 --- a/tests/test_threadlistmodel.cpp +++ b/tests/test_threadlistmodel.cpp @@ -49,7 +49,7 @@ private slots: void appendingEmptyBatchIsNoOp(); void clearResetsModel(); void reportsSubjectAndAuthors(); - void theReplyCountExcludesTheRootMessage(); + void thePillCountsTheThreadsMessages(); void unreadThreadsRenderBold(); void readThreadsAreDimmedAndUnreadAreNot(); void flaggedThreadsShowAStar(); @@ -519,7 +519,7 @@ void TestThreadListModel::aFlatViewsAvatarFollowsTheRecipient() QStringLiteral("me@example.org")); } -void TestThreadListModel::theReplyCountExcludesTheRootMessage() +void TestThreadListModel::thePillCountsTheThreadsMessages() { ThreadListModel model; @@ -530,12 +530,14 @@ void TestThreadListModel::theReplyCountExcludesTheRootMessage() model.appendBatch({ single, multi }); // The count used to be a "(4)" suffix on the subject. It is the expander - // on the card's second line now, and it counts REPLIES: totalCount - // includes the root message, which is the card itself. + // on the card's second line now, and it counts MESSAGES: the row stands + // for the conversation since item 177, so a thread of one message and + // three replies reads "4 messages". A thread of one shows nothing to + // expand, so its count stays 0. QCOMPARE(model.data(model.index(0, 0), - ThreadListModel::ReplyCountRole).toInt(), 0); + ThreadListModel::MessageCountRole).toInt(), 0); QCOMPARE(model.data(model.index(1, 0), - ThreadListModel::ReplyCountRole).toInt(), 3); + ThreadListModel::MessageCountRole).toInt(), 4); // And the subject is bare, with no count spliced into it. QCOMPARE(model.data(model.index(1, 0), @@ -1483,9 +1485,9 @@ void TestThreadListModel::modelHasOneColumn() QStringLiteral("alice@example.org")); QVERIFY(index.data(ThreadListModel::DateRole).toDateTime().isValid()); - // A single-message thread offers no expander: totalCount includes the root - // message, which is the card itself. - QCOMPARE(index.data(ThreadListModel::ReplyCountRole).toInt(), 0); + // A single-message thread offers no expander: it is its own message and + // has nothing to open onto. + QCOMPARE(index.data(ThreadListModel::MessageCountRole).toInt(), 0); } void TestThreadListModel::aFlatThreadStillListsItsReplies() @@ -1520,12 +1522,11 @@ void TestThreadListModel::aFlatThreadStillListsItsReplies() .toString(), QStringLiteral("m1@example.org")); - // The pill counts REPLIES while the rows are MESSAGES, so since item 177 - // the rows are one more than the pill: the conversation lists its first - // message too. They must still move together, or the expander opens onto a - // number the card never promised. - QCOMPARE(root.data(ThreadListModel::ReplyCountRole).toInt(), - model.rowCount(root) - 1); + // The pill counts MESSAGES, which is exactly what the rows are: since item + // 177 a conversation lists every message under itself, so the number on + // the card and the number of rows it opens onto agree. + QCOMPARE(root.data(ThreadListModel::MessageCountRole).toInt(), + model.rowCount(root)); } void TestThreadListModel::theRootCardKnowsItsOwnMessage() @@ -1893,7 +1894,7 @@ void TestThreadListModel::flatModeOffersNoExpanderAndNoReplyCount() // the replies they received under a view that claims to be their outbox. // // Deliberately not a second model or a filtered query. The expander is - // driven by hasChildren() and the card's count by ReplyCountRole, both + // driven by hasChildren() and the card's count by MessageCountRole, both // already here, so flat mode is those two answering differently. ThreadListModel model; model.appendBatch({ makeThread(QStringLiteral("t1"), @@ -1906,13 +1907,13 @@ void TestThreadListModel::flatModeOffersNoExpanderAndNoReplyCount() // below: a test whose subject was already flat would pass either way. QVERIFY2(model.hasChildren(thread), "the fixture thread is not expandable, so this proves nothing"); - QCOMPARE(model.data(thread, ThreadListModel::ReplyCountRole).toInt(), 1); + QCOMPARE(model.data(thread, ThreadListModel::MessageCountRole).toInt(), 2); model.setFlatMode(true); QVERIFY2(!model.hasChildren(thread), "a flat list still offered an expander"); - QCOMPARE(model.data(thread, ThreadListModel::ReplyCountRole).toInt(), 0); + QCOMPARE(model.data(thread, ThreadListModel::MessageCountRole).toInt(), 0); // rowCount has to agree, or the view draws an expander it cannot open, or // opens onto rows the card said were not there. @@ -1943,7 +1944,7 @@ void TestThreadListModel::flatModeIsOffByDefaultAndReversible() model.setFlatMode(false); QVERIFY2(model.hasChildren(thread), "leaving flat mode did not restore the tree"); - QCOMPARE(model.data(thread, ThreadListModel::ReplyCountRole).toInt(), 1); + QCOMPARE(model.data(thread, ThreadListModel::MessageCountRole).toInt(), 2); } void TestThreadListModel::recipientsReplaceTheSenderWhenPresent() |
