aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_querycompleter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_querycompleter.cpp')
-rw-r--r--tests/test_querycompleter.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/tests/test_querycompleter.cpp b/tests/test_querycompleter.cpp
index 09eedc3..6cf9651 100644
--- a/tests/test_querycompleter.cpp
+++ b/tests/test_querycompleter.cpp
@@ -20,7 +20,9 @@
#include <QTemporaryDir>
#include <QLineEdit>
+#include <QImage>
#include <QListView>
+#include <QPixmap>
#include "config.h"
#include "querycompleter.h"
@@ -81,6 +83,7 @@ private slots:
void returnRunsTheQueryOnceCompletionIsDone();
void returnRunsTheQueryAfterAMouseAccept();
void returnRunsTheQueryWhenThePopupMatchesNothing();
+ void theDescriptionSurvivesAModestPopupWidth();
};
// Copied from tests/test_config.cpp rather than shared, so the two test files
@@ -781,5 +784,97 @@ void TestQueryCompleter::returnRunsTheQueryWhenThePopupMatchesNothing()
QVERIFY(ran);
}
+void TestQueryCompleter::theDescriptionSurvivesAModestPopupWidth()
+{
+ // The delegate lends the description whatever the value does not need, up
+ // to 65% of the row. Under the previous even split the longest built-in
+ // description needed a ~650px popup to survive; it now needs ~500px, which
+ // is the difference between the column working at an ordinary window size
+ // and being decorative.
+ //
+ // 550px is chosen to sit inside that band: the current rule paints the text
+ // in full there, an even split cannot. A width outside the band would pass
+ // against both rules and prove nothing.
+ //
+ // The delegate is private to the .cpp, so this renders the real popup and
+ // reads the pixels back rather than reaching for the class: whether the text
+ // is legible on screen is a painting question, not an arithmetic one.
+ Config config;
+ QLineEdit edit;
+ edit.resize(550, edit.sizeHint().height());
+ edit.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&edit));
+ edit.setFocus();
+ QueryCompleter completer(&edit, config);
+
+ QTest::keyClicks(&edit, QStringLiteral("path"));
+ QListView *popup = findPopup();
+ QVERIFY(popup && popup->isVisible());
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+
+ // "path:" carries the longest built-in description, so it is the row that
+ // fails first if the column is starved.
+ const QModelIndex row = popup->model()->index(0, 0);
+ QVERIFY(row.isValid());
+ QCOMPARE(row.data(Qt::DisplayRole).toString(), QStringLiteral("path:"));
+
+ const QRect rect = popup->visualRect(row);
+ QVERIFY(rect.isValid());
+ QPixmap shot = popup->viewport()->grab(rect);
+ QVERIFY(!shot.isNull());
+ const QImage image = shot.toImage();
+
+ // Measure how much of the row carries ink, then compare that against the
+ // width the description needs when it is NOT elided.
+ //
+ // "Something was drawn" is too weak a check: the previous even-split rule
+ // also drew the description, just cut down to an ellipsis, so a blank-or-not
+ // test passes against the very code this replaces. What distinguishes the
+ // two is whether the full text fits, which is a width comparison.
+ const QRgb background = image.pixel(image.width() - 2, image.height() / 2);
+ int rightmostInk = -1;
+ int leftmostInkAfterValue = image.width();
+ for (int x = 0; x < image.width(); ++x) {
+ for (int y = 0; y < image.height(); ++y) {
+ if (image.pixel(x, y) != background) {
+ rightmostInk = qMax(rightmostInk, x);
+ break;
+ }
+ }
+ }
+ QVERIFY2(rightmostInk >= 0, "the row rendered entirely blank");
+
+ // The description is right-aligned, so the ink running to the right edge is
+ // the description itself. Walk left from there over the contiguous run to
+ // find how wide it was actually painted.
+ int x = rightmostInk;
+ int gapRun = 0;
+ while (x > 0 && gapRun < 8) {
+ bool column = false;
+ for (int y = 0; y < image.height(); ++y) {
+ if (image.pixel(x, y) != background) {
+ column = true;
+ break;
+ }
+ }
+ gapRun = column ? 0 : gapRun + 1;
+ if (column)
+ leftmostInkAfterValue = x;
+ --x;
+ }
+
+ const QFontMetrics metrics(popup->font());
+ const QString description = popup->model()->index(0, 1).data().toString();
+ QCOMPARE(description, QStringLiteral("directory below the Maildir root"));
+ const int painted = rightmostInk - leftmostInkAfterValue;
+ const int needed = metrics.horizontalAdvance(description);
+
+ // Allow a little slack for antialiasing at the glyph edges.
+ QVERIFY2(painted >= needed - 4,
+ qPrintable(QStringLiteral("description elided: painted %1px of the "
+ "%2px it needs")
+ .arg(painted).arg(needed)));
+}
+
QTEST_MAIN(TestQueryCompleter)
#include "test_querycompleter.moc"