1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include <qtest.h>
29#include <QtTest/QSignalSpy>
30
31#include <QtGui/qscreen.h>
32#include <QtQml/qqmlengine.h>
33#include <QtQml/qqmlcomponent.h>
34#include <QtQuick/qquickview.h>
35#include <private/qquickitem_p.h>
36#include <private/qquickrectangle_p.h>
37
38#include "../../shared/util.h"
39
40class tst_qquickrectangle : public QQmlDataTest
41{
42 Q_OBJECT
43public:
44 tst_qquickrectangle();
45
46private slots:
47 void color();
48 void gradient();
49 void gradient_border();
50 void gradient_separate();
51 void gradient_multiple();
52 void gradient_preset();
53 void antialiasing();
54
55private:
56 QQmlEngine engine;
57};
58
59tst_qquickrectangle::tst_qquickrectangle()
60{
61}
62
63void tst_qquickrectangle::color()
64{
65 if (QGuiApplication::primaryScreen()->depth() < 24)
66 QSKIP("This test does not work at display depths < 24");
67
68 QQuickView view;
69 view.setSource(testFileUrl(fileName: "color.qml"));
70 view.show();
71
72 QVERIFY(QTest::qWaitForWindowExposed(&view));
73
74 if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
75 || (QGuiApplication::platformName() == QLatin1String("minimal")))
76 QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
77
78 QImage image = view.grabWindow();
79 QVERIFY(image.pixel(0,0) == QColor("#020202").rgba());
80}
81
82void tst_qquickrectangle::gradient()
83{
84 QQmlComponent component(&engine, testFileUrl(fileName: "gradient.qml"));
85 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(object: component.create());
86 QVERIFY(rect);
87
88 QQuickGradient *grad = qobject_cast<QQuickGradient *>(object: rect->gradient().toQObject());
89 QVERIFY(grad);
90
91 QQmlListProperty<QQuickGradientStop> stops = grad->stops();
92 QCOMPARE(stops.count(&stops), 2);
93 QCOMPARE(stops.at(&stops, 0)->position(), 0.0);
94 QCOMPARE(stops.at(&stops, 0)->color(), QColor("gray"));
95 QCOMPARE(stops.at(&stops, 1)->position(), 1.0);
96 QCOMPARE(stops.at(&stops, 1)->color(), QColor("white"));
97
98 QGradientStops gradientStops = grad->gradientStops();
99 QCOMPARE(gradientStops.count(), 2);
100 QCOMPARE(gradientStops.at(0).first, 0.0);
101 QCOMPARE(gradientStops.at(0).second, QColor("gray"));
102 QCOMPARE(gradientStops.at(1).first, 1.0);
103 QCOMPARE(gradientStops.at(1).second, QColor("white"));
104
105 QMetaObject::invokeMethod(obj: rect, member: "resetGradient");
106
107 grad = qobject_cast<QQuickGradient *>(object: rect->gradient().toQObject());
108 QVERIFY(!grad);
109
110 delete rect;
111}
112
113void tst_qquickrectangle::gradient_border()
114{
115 QQuickView view;
116 view.setSource(testFileUrl(fileName: "gradient-border.qml"));
117 view.show();
118
119 QVERIFY(QTest::qWaitForWindowExposed(&view));
120}
121
122// A gradient not defined inline with the Rectangle using it should still change
123// that Rectangle.
124void tst_qquickrectangle::gradient_separate()
125{
126 QQuickView view;
127 view.setSource(testFileUrl(fileName: "gradient-separate.qml"));
128 view.show();
129
130 QVERIFY(QTest::qWaitForWindowExposed(&view));
131
132 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(object: view.rootObject());
133 QVERIFY(rect);
134
135 // Start off clean
136 QQuickItemPrivate *rectPriv = QQuickItemPrivate::get(item: rect);
137 QTRY_COMPARE(rectPriv->dirtyAttributes & QQuickItemPrivate::Content, 0u);
138
139 QMetaObject::invokeMethod(obj: rect, member: "changeGradient");
140
141 // Changing the gradient should have scheduled an update of the item.
142 QVERIFY((rectPriv->dirtyAttributes & QQuickItemPrivate::Content) != 0);
143}
144
145// When a gradient is changed, every Rectangle connected to it must update.
146void tst_qquickrectangle::gradient_multiple()
147{
148 QQuickView view;
149 view.setSource(testFileUrl(fileName: "gradient-multiple.qml"));
150 view.show();
151
152 QVERIFY(QTest::qWaitForWindowExposed(&view));
153
154 QQuickRectangle *firstRect = qobject_cast<QQuickRectangle*>(object: view.rootObject()->property(name: "firstRectangle").value<QObject*>());
155 QQuickRectangle *secondRect = qobject_cast<QQuickRectangle*>(object: view.rootObject()->property(name: "secondRectangle").value<QObject*>());
156 QVERIFY(firstRect);
157 QVERIFY(secondRect);
158
159 // Start off clean
160 QQuickItemPrivate *firstRectPriv = QQuickItemPrivate::get(item: firstRect);
161 QQuickItemPrivate *secondRectPriv = QQuickItemPrivate::get(item: secondRect);
162 QTRY_VERIFY(!(firstRectPriv->dirtyAttributes & QQuickItemPrivate::Content));
163 bool secondIsDirty = secondRectPriv->dirtyAttributes & QQuickItemPrivate::Content;
164 QVERIFY(!secondIsDirty);
165
166 QMetaObject::invokeMethod(obj: view.rootObject(), member: "changeGradient");
167
168 // Changing the gradient should have scheduled an update of both items
169 QTRY_VERIFY(firstRectPriv->dirtyAttributes & QQuickItemPrivate::Content);
170 secondIsDirty = secondRectPriv->dirtyAttributes & QQuickItemPrivate::Content;
171 QVERIFY(secondIsDirty);
172}
173
174void tst_qquickrectangle::gradient_preset()
175{
176 QQuickView view;
177 view.setSource(testFileUrl(fileName: "gradient-preset.qml"));
178 view.show();
179
180 QVERIFY(QTest::qWaitForWindowExposed(&view));
181
182 QQuickRectangle *enumRect = view.rootObject()->findChild<QQuickRectangle *>(aName: "enum");
183 QVERIFY(enumRect);
184 QVERIFY(enumRect->gradient().isNumber());
185 QCOMPARE(enumRect->gradient().toUInt(), QGradient::NightFade);
186
187 QQuickRectangle *stringRect = view.rootObject()->findChild<QQuickRectangle *>(aName: "string");
188 QVERIFY(stringRect);
189 QVERIFY(stringRect->gradient().isString());
190 QCOMPARE(stringRect->gradient().toString(), QLatin1String("NightFade"));
191
192 for (int i = 1; i <= 5; ++i) {
193 QQuickRectangle *invalidRect = view.rootObject()->findChild<QQuickRectangle *>(qPrintable(QString("invalid%1").arg(i)));
194 QVERIFY(invalidRect);
195 QVERIFY(invalidRect->gradient().isUndefined());
196 }
197}
198
199void tst_qquickrectangle::antialiasing()
200{
201 QQmlComponent component(&engine);
202 component.setData("import QtQuick 2.0\n Rectangle {}", baseUrl: QUrl());
203 QScopedPointer<QObject> object(component.create());
204 QQuickRectangle *rect = qobject_cast<QQuickRectangle *>(object: object.data());
205 QVERIFY(rect);
206
207 QSignalSpy spy(rect, SIGNAL(antialiasingChanged(bool)));
208
209 QCOMPARE(rect->antialiasing(), false);
210
211 rect->setAntialiasing(true);
212 QCOMPARE(rect->antialiasing(), true);
213 QCOMPARE(spy.count(), 1);
214
215 rect->setAntialiasing(true);
216 QCOMPARE(spy.count(), 1);
217
218 rect->resetAntialiasing();
219 QCOMPARE(rect->antialiasing(), false);
220 QCOMPARE(spy.count(), 2);
221
222 rect->setRadius(5);
223 QCOMPARE(rect->antialiasing(), true);
224 QCOMPARE(spy.count(), 3);
225
226 rect->resetAntialiasing();
227 QCOMPARE(rect->antialiasing(), true);
228 QCOMPARE(spy.count(), 3);
229
230 rect->setRadius(0);
231 QCOMPARE(rect->antialiasing(), false);
232 QCOMPARE(spy.count(), 4);
233
234 rect->resetAntialiasing();
235 QCOMPARE(rect->antialiasing(), false);
236 QCOMPARE(spy.count(), 4);
237
238 rect->setRadius(5);
239 QCOMPARE(rect->antialiasing(), true);
240 QCOMPARE(spy.count(), 5);
241
242 rect->resetAntialiasing();
243 QCOMPARE(rect->antialiasing(), true);
244 QCOMPARE(spy.count(), 5);
245
246 rect->setAntialiasing(false);
247 QCOMPARE(rect->antialiasing(), false);
248 QCOMPARE(spy.count(), 6);
249
250 rect->resetAntialiasing();
251 QCOMPARE(rect->antialiasing(), true);
252 QCOMPARE(spy.count(), 7);
253}
254
255QTEST_MAIN(tst_qquickrectangle)
256
257#include "tst_qquickrectangle.moc"
258

source code of qtdeclarative/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp