diff options
Diffstat (limited to 'tests/test_carddelegate.cpp')
| -rw-r--r-- | tests/test_carddelegate.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/tests/test_carddelegate.cpp b/tests/test_carddelegate.cpp index d5e55b5..a14671d 100644 --- a/tests/test_carddelegate.cpp +++ b/tests/test_carddelegate.cpp @@ -18,6 +18,9 @@ #include "carddelegate.h" +#include "cardlayout.h" +#include "tagchip.h" +#include "tagcolors.h" #include "threadlistmodel.h" #include <QTest> @@ -30,6 +33,9 @@ private slots: void theAccentLiftsAMutedAccountColour(); void theAccentKeepsEachAccountTellableApart(); void anAccountWithNoColourFallsBackToTheNeutralLine(); + void aSiblingChipIsMutedButStaysLegibleAndRecognisable(); + void aSiblingChipFontIsSmallerThanItsOwnTier(); + void aSiblingChipsPaddingShrinksWithItsFont(); }; namespace { @@ -131,5 +137,127 @@ void TestCardDelegate::anAccountWithNoColourFallsBackToTheNeutralLine() ThreadListModel::threadLineColour()); } +void TestCardDelegate::aSiblingChipIsMutedButStaysLegibleAndRecognisable() +{ + // Item 111: a card shows its own tags at full size and the rest of the + // conversation's smaller and muted. "Muted" has two hard requirements that + // a look at the screen will not catch, so they are asserted here. + for (const QColor &colour : sampleAccounts()) { + const QColor muted = CardDelegate::mutedChipColour(colour); + + // Actually muted, or the tier is not distinguishable at all. + QVERIFY2(saturationOf(muted) < saturationOf(colour), + qPrintable(QStringLiteral("%1 was not drained at all") + .arg(colour.name()))); + + // Same HUE. A sibling's `signed` has to stay recognisably the same + // colour as a full-size `signed` elsewhere in the list, or the muting + // reads as a different tag rather than a quieter one. + float h1 = 0, h2 = 0, s = 0, l = 0, a = 0; + colour.getHslF(&h1, &s, &l, &a); + muted.getHslF(&h2, &s, &l, &a); + QVERIFY2(qAbs(h1 - h2) < 0.001f, + qPrintable(QStringLiteral("%1 changed hue when muted") + .arg(colour.name()))); + + // Same LIGHTNESS, which is what keeps the text legible: TagColors + // picks the text colour from the fill, and a fill that drifted toward + // black or white could flip that choice or land mid-grey where neither + // works. Blending toward the background would do exactly that, which + // is the mistake accentLineColour() records. + QCOMPARE(lightnessOf(muted), lightnessOf(colour)); + QCOMPARE(TagColors::textColourOn(muted), + TagColors::textColourOn(colour)); + } + + // An invalid colour stays invalid rather than becoming a real one. + QVERIFY(!CardDelegate::mutedChipColour(QColor()).isValid()); +} + +void TestCardDelegate::aSiblingChipFontIsSmallerThanItsOwnTier() +{ + // Size is what says whose tag a chip is, so the two tiers must differ, and + // by enough to SEE. The first version subtracted a point from smallFont(), + // and the user reported the tiers as indistinguishable: on their 14pt + // desktop that gave 13 and 12, a 7% step. + // + // The step is now a fraction of the card font, so it does not shrink as + // the desktop's font grows. Asserted as a ratio rather than as a size, to + // keep this about the DISTINCTION rather than about the constant. + QFont card; + card.setPointSizeF(14.0); // The user's own desktop size. + const qreal own = CardLayout::smallFont(card).pointSizeF(); + const qreal sibling = CardLayout::siblingFont(card).pointSizeF(); + + QVERIFY(sibling < own); + QVERIFY2(sibling < own * 0.85, + qPrintable(QStringLiteral("sibling %1pt against own %2pt is under " + "a 15%% step, which reads as the same " + "size") + .arg(sibling) + .arg(own))); + + // Proportional, not a fixed subtraction: the step must survive a larger + // desktop font rather than becoming proportionally smaller. + QFont big; + big.setPointSizeF(28.0); + QVERIFY(CardLayout::siblingFont(big).pointSizeF() + < CardLayout::smallFont(big).pointSizeF() * 0.85); + + // The pixel branch too: qt6ct sets fonts in PIXELS, and pointSizeF() is -1 + // for those, so a point-only implementation silently returns the original + // size and both tiers render identically. CLAUDE.md records this trap. + QFont pixels; + pixels.setPixelSize(14); + QVERIFY(pixels.pointSizeF() < 0); + QVERIFY2(CardLayout::siblingFont(pixels).pixelSize() + < CardLayout::smallFont(pixels).pixelSize(), + "a pixel-sized desktop font gives both tiers the same size, so " + "the distinction disappears entirely"); + + // Floored rather than shrinking without limit. + QFont tiny; + tiny.setPointSizeF(6.0); + QVERIFY(CardLayout::siblingFont(tiny).pointSizeF() >= 6.0); +} + +void TestCardDelegate::aSiblingChipsPaddingShrinksWithItsFont() +{ + // Half of "smaller" is the padding, and leaving it fixed is why the first + // version still looked the same size. kPaddingX is 9 a side: on a sibling + // chip that is 18px of padding around roughly 30px of text, so the chip + // stayed wide while its letters shrank, which reads as "same chip, smaller + // text" rather than as a smaller chip. + QFont card; + card.setPointSizeF(14.0); + const QFontMetrics ownMetrics(CardLayout::smallFont(card)); + const QFontMetrics siblingMetrics(CardLayout::siblingFont(card)); + + const QString tag = QStringLiteral("signed"); + // Through CardDelegate::chipSize(), which is what the paint loop calls. + // Calling TagChip::sizeFor() directly here proved what THAT function does + // and nothing about whether the delegate asks it for a scaled padding: a + // mutation dropping the scale at the call site survived that version of + // this test. + const QSize own = CardDelegate::chipSize(ownMetrics, tag, true); + const QSize scaled = CardDelegate::chipSize(siblingMetrics, tag, false); + const QSize unscaled = TagChip::sizeFor(siblingMetrics, tag); + + // The font alone is not enough: scaling the padding as well takes off + // measurably more width. + QVERIFY2(scaled.width() < unscaled.width(), + "the padding did not scale, so the chip keeps full-size margins " + "around smaller letters"); + QVERIFY(scaled.width() < own.width()); + QVERIFY(scaled.height() < own.height()); + + // Floored rather than collapsing to nothing: the corner radius is half the + // height, so a chip with no horizontal padding has its text on the curve. + const QSize tiny = TagChip::sizeFor(siblingMetrics, tag, 0.0); + QVERIFY2(tiny.width() > siblingMetrics.horizontalAdvance(tag), + "a zero scale left no horizontal padding at all, so the text sits " + "on the chip's rounded end"); +} + QTEST_MAIN(TestCardDelegate) #include "test_carddelegate.moc" |
