c9e8c4b38c
numerous icon tests expect the actual production plasma theme to be present it won't however be resolved because we disable qstandardpaths' default fallbacks by switching it into testing mode. this ultimately means the test run needs to have XDG_DATA_DIRS in the environment, if it doesn't test data will not be present furthermore QSKIP tests that depend on: - hicolor icon theme to be present - production plasma themes this allows the entire test to pass in less than optimal environments by means of skipping but also gives a reasonable hint as to why tests are skipped in the first place. also moving forward if a test isn't guarded we still have the warning about failure potential allowing someone to quickly figure out why things failed REVIEW: 127764
472 lines
16 KiB
C++
472 lines
16 KiB
C++
/******************************************************************************
|
|
* Copyright 2016 David Rosca <nowrep@gmail.com> *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public License *
|
|
* along with this library; see the file COPYING.LIB. If not, write to *
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
|
* Boston, MA 02110-1301, USA. *
|
|
*******************************************************************************/
|
|
|
|
#include "iconitemtest.h"
|
|
|
|
#include <QIcon>
|
|
#include <QQmlEngine>
|
|
#include <QQmlContext>
|
|
#include <QQmlComponent>
|
|
#include <QQuickItemGrabResult>
|
|
#include <QtTest/QSignalSpy>
|
|
|
|
#include <KIconLoader>
|
|
#include <KIconEngine>
|
|
#include <KIconTheme>
|
|
|
|
#include "plasma/theme.h"
|
|
#include "plasma/svg.h"
|
|
|
|
static bool imageIsEmpty(const QImage &img)
|
|
{
|
|
for (int i = 0; i < img.width(); ++i) {
|
|
for (int j = 0; j < img.height(); ++j) {
|
|
if (img.pixel(i, j) != 0) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void IconItemTest::initTestCase()
|
|
{
|
|
if (qgetenv("XDG_DATA_DIRS").isEmpty()) {
|
|
QWARN("\n"
|
|
" !!!\n"
|
|
" Switching QStandardPaths into testing mode.\n"
|
|
" Make sure xdg data can be found or set XDG_DATA_DIRS.\n"
|
|
" !!!\n");
|
|
}
|
|
|
|
// make our theme in search path
|
|
qputenv("XDG_DATA_DIRS",
|
|
qgetenv("XDG_DATA_DIRS") + ":" + QFINDTESTDATA("data").toLocal8Bit());
|
|
|
|
// set default icon theme to test-theme
|
|
QStandardPaths::setTestModeEnabled(true);
|
|
|
|
QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
|
|
|
|
if(!QDir(configPath).mkpath(QStringLiteral("."))) {
|
|
qFatal("Failed to create test configuration directory.");
|
|
}
|
|
|
|
QFile::remove(configPath);
|
|
|
|
QIcon::setThemeSearchPaths({QFINDTESTDATA("data/icons")});
|
|
QIcon::setThemeName("test-theme");
|
|
|
|
KConfigGroup cg(KSharedConfig::openConfig(), "Icons");
|
|
cg.writeEntry("Theme", "test-theme");
|
|
KConfigGroup plasmaConfig(KSharedConfig::openConfig("plasmarc"), "Theme");
|
|
plasmaConfig.writeEntry("name", "default");
|
|
|
|
cg.sync(); // sync explicitly so it will be correctly parsed
|
|
KSharedConfig::openConfig()->reparseConfiguration();
|
|
KIconTheme::reconfigure();
|
|
KIconLoader::global()->reconfigure(QString());
|
|
|
|
m_view = new QQuickView();
|
|
m_view->setSource(QUrl::fromLocalFile(QFINDTESTDATA("data/view.qml")));
|
|
m_view->show();
|
|
QTest::qWaitForWindowExposed(m_view);
|
|
|
|
if (!m_view->rootObject() || !m_view->rootObject()->grabToImage()) {
|
|
QSKIP("Cannot grab item to image.");
|
|
}
|
|
}
|
|
|
|
void IconItemTest::cleanupTestCase()
|
|
{
|
|
delete m_view;
|
|
}
|
|
|
|
void IconItemTest::cleanup()
|
|
{
|
|
qDeleteAll(m_view->rootObject()->childItems());
|
|
}
|
|
|
|
QQuickItem *IconItemTest::createIconItem()
|
|
{
|
|
QByteArray iconQml =
|
|
"import QtQuick 2.0;"
|
|
"import org.kde.plasma.core 2.0 as PlasmaCore;"
|
|
"PlasmaCore.IconItem {"
|
|
" id: root;"
|
|
"}";
|
|
|
|
QQmlComponent component(m_view->engine());
|
|
|
|
QSignalSpy spy(&component, SIGNAL(statusChanged(QQmlComponent::Status)));
|
|
component.setData(iconQml, QUrl("test://iconTest"));
|
|
if (component.status() != QQmlComponent::Ready) {
|
|
spy.wait();
|
|
}
|
|
|
|
QQuickItem *item = qobject_cast<QQuickItem*>(component.create(m_view->engine()->rootContext()));
|
|
Q_ASSERT(item && qstrcmp(item->metaObject()->className(), "IconItem") == 0);
|
|
item->setParentItem(m_view->rootObject());
|
|
return item;
|
|
}
|
|
|
|
QImage IconItemTest::grabImage(QQuickItem *item)
|
|
{
|
|
QSharedPointer<QQuickItemGrabResult> grab = item->grabToImage();
|
|
QSignalSpy spy(grab.data(), SIGNAL(ready()));
|
|
spy.wait();
|
|
return grab->image();
|
|
}
|
|
|
|
Plasma::Svg *IconItemTest::findPlasmaSvg(QQuickItem *item)
|
|
{
|
|
return item->findChild<Plasma::Svg *>();
|
|
}
|
|
|
|
void IconItemTest::changeTheme(Plasma::Theme *theme, const QString &themeName)
|
|
{
|
|
if (theme->themeName() != themeName) {
|
|
QSignalSpy spy(theme, SIGNAL(themeChanged()));
|
|
theme->setThemeName(themeName);
|
|
spy.wait();
|
|
}
|
|
}
|
|
|
|
// ------ Tests
|
|
|
|
void IconItemTest::loadPixmap()
|
|
{
|
|
QScopedPointer<QQuickItem> item(createIconItem());
|
|
QPixmap sourcePixmap(QFINDTESTDATA("data/test_image.png"));
|
|
|
|
item->setProperty("source", sourcePixmap);
|
|
QVERIFY(item->property("valid").toBool());
|
|
|
|
QImage capture = grabImage(item.data());
|
|
QCOMPARE(capture, sourcePixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied));
|
|
QCOMPARE(sourcePixmap, item->property("source").value<QPixmap>());
|
|
}
|
|
|
|
//tests setting icon from a QImage
|
|
void IconItemTest::loadImage()
|
|
{
|
|
QScopedPointer<QQuickItem> item(createIconItem());
|
|
QImage sourceImage(QFINDTESTDATA("data/test_image.png"));
|
|
|
|
item->setProperty("source", sourceImage);
|
|
QVERIFY(item->property("valid").toBool());
|
|
|
|
QImage capture = grabImage(item.data());
|
|
QCOMPARE(capture, sourceImage.convertToFormat(QImage::Format_ARGB32_Premultiplied));
|
|
QCOMPARE(sourceImage, item->property("source").value<QImage>());
|
|
}
|
|
|
|
void IconItemTest::invalidIcon()
|
|
{
|
|
QString name("tst-plasma-framework-invalid-icon-name");
|
|
KIconLoader iconLoader("tst_plasma-framework");
|
|
if (iconLoader.hasIcon(name)) {
|
|
QSKIP("Current icon theme has 'tst-plasma-framework-invalid-icon-name' icon.");
|
|
}
|
|
|
|
QQuickItem *item = createIconItem();
|
|
item->setProperty("source", name);
|
|
QVERIFY(!item->property("valid").toBool());
|
|
QVERIFY(imageIsEmpty(grabImage(item)));
|
|
}
|
|
|
|
void IconItemTest::usesPlasmaTheme()
|
|
{
|
|
Plasma::Theme theme;
|
|
if (!theme.themeName().startsWith("default")) {
|
|
QSKIP("Current Plasma theme is not Breeze.");
|
|
}
|
|
|
|
// usesPlasmaTheme = true (default)
|
|
QQuickItem *item1 = createIconItem();
|
|
item1->setProperty("source", "konversation");
|
|
QVERIFY(item1->property("valid").toBool());
|
|
QCOMPARE(QStringLiteral("konversation"), item1->property("source").toString());
|
|
|
|
Plasma::Svg svg;
|
|
svg.setContainsMultipleImages(true);
|
|
svg.setImagePath("icons/konversation");
|
|
|
|
QImage img1 = grabImage(item1);
|
|
QImage img2 = svg.image(QSize(item1->width(), item1->height()), "konversation");
|
|
QVERIFY(!imageIsEmpty(img1));
|
|
QVERIFY(!imageIsEmpty(img2));
|
|
QCOMPARE(img1, img2);
|
|
|
|
// usesPlasmaTheme = false
|
|
QQuickItem *item2 = createIconItem();
|
|
item2->setProperty("usesPlasmaTheme", false);
|
|
item2->setProperty("source", "konversation");
|
|
|
|
img1 = grabImage(item2);
|
|
// This depends on konversation icon being different in Plasma Breeze theme
|
|
// and our test icon theme
|
|
QVERIFY(img1 != img2);
|
|
}
|
|
|
|
void IconItemTest::animation()
|
|
{
|
|
if (!Plasma::Theme().themeName().startsWith("default")) {
|
|
// This this depends on the production default theme.
|
|
QSKIP("Current Plasma theme is not Breeze.");
|
|
}
|
|
|
|
// animated = true (default)
|
|
QQuickItem *item1 = createIconItem();
|
|
item1->setProperty("source", "user-away");
|
|
// first icon is not animated
|
|
QImage userAwayImg = grabImage(item1);
|
|
|
|
item1->setProperty("source", "user-busy");
|
|
grabImage(item1);
|
|
item1->setProperty("source", "user-away");
|
|
// animation from user-busy -> user-away
|
|
QVERIFY(userAwayImg != grabImage(item1));
|
|
|
|
// animated = false
|
|
QQuickItem *item2 = createIconItem();
|
|
item2->setProperty("animated", false);
|
|
item2->setProperty("source", "user-busy");
|
|
QImage userBusyImg = grabImage(item2);
|
|
|
|
item2->setProperty("source", "user-away");
|
|
QCOMPARE(userAwayImg, grabImage(item2));
|
|
|
|
item2->setProperty("source", "user-busy");
|
|
QCOMPARE(userBusyImg, grabImage(item2));
|
|
}
|
|
|
|
void IconItemTest::animationAfterHide()
|
|
{
|
|
if (!Plasma::Theme().themeName().startsWith("default")) {
|
|
// This this depends on the production default theme.
|
|
QSKIP("Current Plasma theme is not Breeze.");
|
|
}
|
|
|
|
QQuickItem *item1 = createIconItem();
|
|
QQuickItem *item2 = createIconItem();
|
|
item1->setProperty("source", "user-away");
|
|
item2->setProperty("source", "user-busy");
|
|
// first icon is not animated
|
|
QImage userAwayImg = grabImage(item1);
|
|
QImage userBusyImg = grabImage(item2);
|
|
|
|
item1->setProperty("source", "user-busy");
|
|
grabImage(item1);
|
|
item1->setProperty("visible", "false");
|
|
item1->setProperty("visible", "true");
|
|
item1->setProperty("source", "user-away");
|
|
// icon was hidden, no animation
|
|
QCOMPARE(userAwayImg, grabImage(item1));
|
|
|
|
item1->setProperty("source", "user-busy");
|
|
QVERIFY(userBusyImg != grabImage(item1));
|
|
}
|
|
|
|
void IconItemTest::bug_359388()
|
|
{
|
|
if (!KIconTheme::list().contains("hicolor")) {
|
|
// This test depends on hicolor icon theme to resolve the icon.
|
|
QSKIP("hicolor icon theme not available");
|
|
}
|
|
|
|
QString name("bug359388");
|
|
KIconLoader iconLoader("tst_plasma-framework");
|
|
QIcon customThemeIcon(new KIconEngine(name, &iconLoader));
|
|
if (iconLoader.hasIcon(name)) {
|
|
QSKIP("Current icon theme has 'bug359388' icon.");
|
|
}
|
|
|
|
iconLoader.addAppDir("tst_plasma-framework", QFINDTESTDATA("data/bug359388"));
|
|
|
|
QQuickItem *item1 = createIconItem();
|
|
item1->setProperty("source", customThemeIcon);
|
|
QVERIFY(item1->property("valid").toBool());
|
|
QCOMPARE(customThemeIcon, item1->property("source").value<QIcon>());
|
|
|
|
QQuickItem *item2 = createIconItem();
|
|
item2->setProperty("source", QIcon(QFINDTESTDATA("data/bug359388/hicolor/22x22/apps/" + name + ".svg")));
|
|
QVERIFY(item2->property("valid").toBool());
|
|
|
|
QCOMPARE(grabImage(item1), grabImage(item2));
|
|
}
|
|
|
|
void IconItemTest::loadSvg()
|
|
{
|
|
QString name("tst-plasma-framework-test-icon");
|
|
|
|
QQuickItem *item = createIconItem();
|
|
item->setProperty("animated", false);
|
|
item->setSize(QSize(22, 22));
|
|
item->setProperty("source", name);
|
|
QVERIFY(item->property("valid").toBool());
|
|
|
|
Plasma::Svg *svg;
|
|
svg = findPlasmaSvg(item);
|
|
Q_ASSERT(svg);
|
|
QCOMPARE(svg->imagePath(), QFINDTESTDATA("data/icons/test-theme/apps/22/" + name + ".svg"));
|
|
|
|
// we only have 32x32 and 22x22 version in the theme, thus 32x32 is a better match.
|
|
item->setSize(QSize(64, 64));
|
|
// just to update the icon
|
|
grabImage(item);
|
|
svg = findPlasmaSvg(item);
|
|
Q_ASSERT(svg);
|
|
QCOMPARE(svg->imagePath(), QFINDTESTDATA("data/icons/test-theme/apps/32/" + name + ".svg"));
|
|
}
|
|
|
|
void IconItemTest::themeChange()
|
|
{
|
|
if (!Plasma::Theme().themeName().startsWith("default")) {
|
|
// This this depends on the production themes (infer their presence from default).
|
|
QSKIP("Current Plasma theme is not Breeze.");
|
|
}
|
|
|
|
// Icon from Plasma theme
|
|
QQuickItem *item1 = createIconItem();
|
|
item1->setProperty("animated", false);
|
|
item1->setProperty("source", "zoom-fit-height");
|
|
Plasma::Svg *svg1 = item1->findChild<Plasma::Svg*>();
|
|
changeTheme(svg1->theme(), "breeze-light");
|
|
QImage img1 = grabImage(item1);
|
|
changeTheme(svg1->theme(), "breeze-dark");
|
|
QImage img2 = grabImage(item1);
|
|
QVERIFY(img1 != img2);
|
|
|
|
// Icon from icon theme
|
|
QQuickItem *item2 = createIconItem();
|
|
item2->setProperty("animated", false);
|
|
item2->setProperty("width", 22);
|
|
item2->setProperty("height", 22);
|
|
item2->setProperty("source", "tst-plasma-framework-test-icon");
|
|
Plasma::Svg *svg2 = item2->findChild<Plasma::Svg*>();
|
|
changeTheme(svg2->theme(), "breeze-light");
|
|
img1 = grabImage(item2);
|
|
changeTheme(svg2->theme(), "breeze-dark");
|
|
img2 = grabImage(item2);
|
|
QVERIFY(img1 != img2);
|
|
}
|
|
|
|
void IconItemTest::qiconFromTheme()
|
|
{
|
|
// Icon from Plasma theme
|
|
QQuickItem *item1 = createIconItem();
|
|
QIcon icon1 = QIcon::fromTheme("konversation");
|
|
item1->setProperty("source", icon1);
|
|
QVERIFY(item1->findChild<Plasma::Svg*>());
|
|
QVERIFY(!imageIsEmpty(grabImage(item1)));
|
|
QCOMPARE(icon1, item1->property("source").value<QIcon>());
|
|
|
|
// Icon from icon theme
|
|
QQuickItem *item2 = createIconItem();
|
|
QIcon icon2 = QIcon::fromTheme("tst-plasma-framework-test-icon");
|
|
item2->setProperty("source", icon2);
|
|
QVERIFY(item2->findChild<Plasma::Svg*>());
|
|
QVERIFY(!imageIsEmpty(grabImage(item2)));
|
|
QCOMPARE(icon2, item2->property("source").value<QIcon>());
|
|
}
|
|
|
|
void IconItemTest::changeColorGroup()
|
|
{
|
|
if (!Plasma::Theme().themeName().startsWith("default")) {
|
|
// This this depends on the production default theme.
|
|
QSKIP("Current Plasma theme is not Breeze.");
|
|
}
|
|
|
|
// Icon from Plasma theme
|
|
QQuickItem *item = createIconItem();
|
|
item->setProperty("animated", false);
|
|
item->setProperty("source", "zoom-fit-height");
|
|
Plasma::Svg *svg = item->findChild<Plasma::Svg*>();
|
|
// not using "breeze" theme as that one follows system color scheme
|
|
// and that one might not have a complementary group or a broken one
|
|
changeTheme(svg->theme(), "breeze-light");
|
|
QSignalSpy spy(svg, SIGNAL(repaintNeeded()));
|
|
QVERIFY(spy.isValid());
|
|
QImage img1 = grabImage(item);
|
|
item->setProperty("colorGroup", Plasma::Theme::ComplementaryColorGroup);
|
|
QTRY_VERIFY(spy.count() == 1);
|
|
QImage img2 = grabImage(item);
|
|
QVERIFY(img1 != img2);
|
|
}
|
|
|
|
void IconItemTest::animatingActiveChange()
|
|
{
|
|
QQuickItem *item1 = createIconItem();
|
|
item1->setProperty("animated", false);
|
|
item1->setProperty("source", "tst-plasma-framework-test-icon");
|
|
QImage img1 = grabImage(item1);
|
|
|
|
QQuickItem *item2 = createIconItem();
|
|
item2->setProperty("animated", false);
|
|
item2->setProperty("active", true);
|
|
item2->setProperty("source", "tst-plasma-framework-test-icon");
|
|
QImage img2 = grabImage(item2);
|
|
QVERIFY(img1 != img2);
|
|
|
|
item1->setProperty("active", true);
|
|
img1 = grabImage(item1);
|
|
QVERIFY(img1 != img2); // animation is running
|
|
}
|
|
|
|
void IconItemTest::animatingEnabledChange()
|
|
{
|
|
QQuickItem *item1 = createIconItem();
|
|
item1->setProperty("animated", false);
|
|
item1->setProperty("source", "tst-plasma-framework-test-icon");
|
|
QImage img1 = grabImage(item1);
|
|
|
|
QQuickItem *item2 = createIconItem();
|
|
item2->setProperty("animated", false);
|
|
item2->setProperty("enabled", false);
|
|
item2->setProperty("source", "tst-plasma-framework-test-icon");
|
|
QImage img2 = grabImage(item2);
|
|
QVERIFY(img1 != img2);
|
|
|
|
item1->setProperty("enabled", false);
|
|
img1 = grabImage(item1);
|
|
QVERIFY(img1 != img2); // animation is running
|
|
}
|
|
|
|
void IconItemTest::windowChanged()
|
|
{
|
|
QQuickItem *item = createIconItem();
|
|
item->setProperty("animated", false);
|
|
item->setProperty("source", "tst-plasma-framework-test-icon");
|
|
QImage img = grabImage(item);
|
|
|
|
QQuickView newView;
|
|
newView.setSource(QUrl::fromLocalFile(QFINDTESTDATA("data/view.qml")));
|
|
newView.show();
|
|
QTest::qWaitForWindowExposed(&newView);
|
|
|
|
item->setProperty("visible", false);
|
|
item->setParentItem(newView.rootObject());
|
|
item->setProperty("visible", true);
|
|
QCOMPARE(grabImage(item), img);
|
|
}
|
|
|
|
QTEST_MAIN(IconItemTest)
|
|
|