1+ #include < QFontDatabase>
12#include < QtTest/QtTest>
3+ #include < QPainter>
24#include " shellwidget.h"
35
46#if defined(Q_OS_WIN) && defined(USE_STATIC_QT)
@@ -14,9 +16,52 @@ private slots:
1416 void clearRegion ();
1517 void fontDescriptionFromQFont ();
1618 void fontDescriptionToQFont ();
19+ void render ();
20+ private:
21+ QString outputFolderPath ();
22+ QString outputFilePath (const QString& name);
23+ QString originalFilePath (const QString& name);
24+ void saveWidgetOutput (ShellWidget& w, QString name);
25+ void diffWidgetOutput (QString name);
26+
27+ private slots:
28+ void initTestCase () noexcept ;
1729};
1830
1931
32+ void Test::initTestCase () noexcept
33+ {
34+ const QStringList fonts{
35+ QStringLiteral (" third-party/DejaVuSansMono.ttf" ),
36+ QStringLiteral (" third-party/DejaVuSansMono-Bold.ttf" ),
37+ QStringLiteral (" third-party/DejaVuSansMono-BoldOblique.ttf" ) };
38+
39+ for (const auto & path : fonts) {
40+ QString abs_path_to_font (CMAKE_SOURCE_DIR);
41+ abs_path_to_font.append (" /" ).append (path);
42+ QFontDatabase::addApplicationFont (abs_path_to_font);
43+ }
44+ }
45+
46+ QString Test::outputFolderPath ()
47+ {
48+ auto folderName = " test_shellwidget_output" ;
49+ QDir ().mkpath (folderName);
50+ return folderName;
51+ }
52+
53+ // / Render Output file path to save a file
54+ QString Test::outputFilePath (const QString& name)
55+ {
56+ return QDir (outputFolderPath ()).filePath (name);
57+ }
58+
59+ // / Previous output from rendering, from the source test folder
60+ QString Test::originalFilePath (const QString& name)
61+ {
62+ return QDir (QDir (TEST_SOURCE_DIR).filePath (" renderoutput" )).filePath (name);
63+ }
64+
2065void Test::clearRegion ()
2166{
2267 ShellWidget *w = new ShellWidget ();
@@ -126,5 +171,86 @@ void Test::fontDescriptionToQFont()
126171 QCOMPARE (varInvalidHeight, QVariant{ QString{ " Invalid font height" } });
127172}
128173
174+ void Test::saveWidgetOutput (ShellWidget& w, QString name)
175+ {
176+ QImage img (w.size (), QImage::Format_ARGB32);
177+ QPainter painter (&img);
178+ w.render (&painter);
179+ QCOMPARE (img.save (outputFilePath (name)), true );
180+ }
181+
182+ void Test::diffWidgetOutput (QString name)
183+ {
184+ auto p1 = outputFilePath (name);
185+ auto output = QImage (p1);
186+ qDebug () << " Loading" << p1 << output;
187+ auto p2 = originalFilePath (name);
188+ auto expected = QImage (p2);
189+ qDebug () << " Loading" << p2 << expected;
190+
191+ QCOMPARE (output.isNull (), false );
192+ QCOMPARE (expected.isNull (), false );
193+
194+ QImage diff (output.size (), QImage::Format_RGB32);
195+ diff.fill (Qt::white);
196+
197+ bool failed = false ;
198+
199+ for (int y=0 ; y < output.height (); y++) {
200+ for (int x=0 ; x < output.width (); x++) {
201+ auto outputColor = output.pixel (x, y);
202+ auto expectedColor = expected.pixel (x, y);
203+
204+ if (outputColor != expectedColor) {
205+ // qWarning() << "Pixel color mismatch at position " << x << y;
206+ // qWarning() << " output:" << outputColor << "expected:" << expectedColor;
207+ diff.setPixel (x, y, Qt::red);
208+ failed = true ;
209+ }
210+ }
211+ }
212+
213+ auto outpath = outputFilePath (" diff_" + name);
214+ qDebug () << " Saving diff" << outpath;
215+
216+
217+ if (QGuiApplication::platformName () != " xcb" ) {
218+ auto msg = QString (" Skipping render test in non X11: %1" )
219+ .arg (QGuiApplication::platformName ());
220+ QSKIP (qPrintable (msg));
221+ }
222+
223+ QCOMPARE (diff.save (outpath), true );
224+
225+ QCOMPARE (output.width (), expected.width ());
226+ QCOMPARE (output.height (), expected.height ());
227+
228+ if (failed) {
229+ qWarning () << " Failing diff, check the output diff image" << outpath;
230+ QCOMPARE (failed, false );
231+ }
232+ }
233+
234+ // / This is mostly an example it renders a shell widget and saves it as an image.
235+ // / For more complicated tests we may want to parametrize these.
236+ void Test::render ()
237+ {
238+ ShellWidget w;
239+ w.setShellFont (QFont (" DejaVu Sans Mono" , 11 , QFont::Weight::Normal, false ));
240+ w.resizeShell (20 , 20 );
241+ w.show ();
242+
243+ w.put (" hello" , 2 , 2 , HighlightAttribute ());
244+ w.put (" fffffff" , 3 , 3 , HighlightAttribute (Qt::red, Qt::black, Qt::white, false , false , false , false , false , false ));
245+ w.put (" italic text" , 4 , 3 , HighlightAttribute (Qt::white, Qt::black, Qt::white, false , true , false , false , false , false ));
246+ w.put (" bold text" , 5 , 3 , HighlightAttribute (Qt::white, Qt::black, Qt::white, false , false , true , false , false , false ));
247+ w.put (" underline text" , 6 , 3 , HighlightAttribute (Qt::white, Qt::black, Qt::white, false , false , false , true , false , false ));
248+ w.put (" undercurl text" , 7 , 3 , HighlightAttribute (Qt::white, Qt::black, Qt::red, false , false , false , false , true , false ));
249+
250+ auto name = " shellwidget_render_works.png" ;
251+ saveWidgetOutput (w, name);
252+ diffWidgetOutput (name);
253+ }
254+
129255QTEST_MAIN (Test)
130256#include " test_shellwidget.moc"
0 commit comments