86c185c0798a2d60575614655f57602fb16dbe8e
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick1 / qdeclarativeanimatedimage / tst_qdeclarativeanimatedimage.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QtDeclarative/qdeclarativeengine.h>
43 #include <QtDeclarative/qdeclarativecomponent.h>
44 #include <QtQuick1/qdeclarativeview.h>
45 #include <private/qdeclarativerectangle_p.h>
46 #include <private/qdeclarativeimage_p.h>
47 #include <private/qdeclarativeanimatedimage_p.h>
48 #include <QSignalSpy>
49 #include <QtDeclarative/qdeclarativecontext.h>
50
51 #include "../../shared/testhttpserver.h"
52
53 class tst_qdeclarativeanimatedimage : public QObject
54 {
55     Q_OBJECT
56 public:
57     tst_qdeclarativeanimatedimage() {}
58
59 private slots:
60     void play();
61     void pause();
62     void stopped();
63     void setFrame();
64     void frameCount();
65     void mirror_running();
66     void mirror_notRunning();
67     void mirror_notRunning_data();
68     void remote();
69     void remote_data();
70     void sourceSize();
71     void sourceSizeReadOnly();
72     void invalidSource();
73     void qtbug_16520();
74     void progressAndStatusChanges();
75
76 private:
77     QPixmap grabScene(QGraphicsScene *scene, int width, int height);
78 };
79
80 QPixmap tst_qdeclarativeanimatedimage::grabScene(QGraphicsScene *scene, int width, int height)
81 {
82     QPixmap screenshot(width, height);
83     screenshot.fill();
84     QPainter p_screenshot(&screenshot);
85     scene->render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height));
86     return screenshot;
87 }
88
89 void tst_qdeclarativeanimatedimage::play()
90 {
91     QDeclarativeEngine engine;
92     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickman.qml"));
93     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
94     QVERIFY(anim);
95     QVERIFY(anim->isPlaying());
96
97     delete anim;
98 }
99
100 void tst_qdeclarativeanimatedimage::pause()
101 {
102     QDeclarativeEngine engine;
103     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml"));
104     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
105     QVERIFY(anim);
106     QVERIFY(anim->isPlaying());
107     QVERIFY(anim->isPaused());
108
109     delete anim;
110 }
111
112 void tst_qdeclarativeanimatedimage::stopped()
113 {
114     QDeclarativeEngine engine;
115     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanstopped.qml"));
116     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
117     QVERIFY(anim);
118     QVERIFY(!anim->isPlaying());
119     QCOMPARE(anim->currentFrame(), 0);
120
121     delete anim;
122 }
123
124 void tst_qdeclarativeanimatedimage::setFrame()
125 {
126     QDeclarativeEngine engine;
127     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml"));
128     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
129     QVERIFY(anim);
130     QVERIFY(anim->isPlaying());
131     QCOMPARE(anim->currentFrame(), 2);
132
133     delete anim;
134 }
135
136 void tst_qdeclarativeanimatedimage::frameCount()
137 {
138     QDeclarativeEngine engine;
139     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/colors.qml"));
140     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
141     QVERIFY(anim);
142     QVERIFY(anim->isPlaying());
143     QCOMPARE(anim->frameCount(), 3);
144
145     delete anim;
146 }
147
148 void tst_qdeclarativeanimatedimage::mirror_running()
149 {
150     // test where mirror is set to true after animation has started
151
152     QDeclarativeEngine engine;
153     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/hearts.qml"));
154     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
155     QVERIFY(anim);
156
157     QGraphicsScene scene;
158     int width = anim->property("width").toInt();
159     int height = anim->property("height").toInt();
160     scene.addItem(qobject_cast<QGraphicsObject *>(anim));
161
162     QCOMPARE(anim->currentFrame(), 0);
163     QPixmap frame0 = grabScene(&scene, width, height);
164     anim->setCurrentFrame(1);
165     QPixmap frame1 = grabScene(&scene, width, height);
166
167     anim->setCurrentFrame(0);
168
169     QSignalSpy spy(anim, SIGNAL(frameChanged()));
170     anim->setPlaying(true);
171
172     QTRY_VERIFY(spy.count() == 1); spy.clear();
173     anim->setProperty("mirror", true);
174
175     QCOMPARE(anim->currentFrame(), 1);
176     QPixmap frame1_flipped = grabScene(&scene, width, height);
177
178     QTRY_VERIFY(spy.count() == 1); spy.clear();
179     QCOMPARE(anim->currentFrame(), 0);  // animation only has 2 frames, should cycle back to first
180     QPixmap frame0_flipped = grabScene(&scene, width, height);
181
182     QTransform transform;
183     transform.translate(width, 0).scale(-1, 1.0);
184     QPixmap frame0_expected = frame0.transformed(transform);
185     QPixmap frame1_expected = frame1.transformed(transform);
186
187     QCOMPARE(frame0_flipped, frame0_expected);
188     QCOMPARE(frame1_flipped, frame1_expected);
189 }
190
191 void tst_qdeclarativeanimatedimage::mirror_notRunning()
192 {
193     QFETCH(QUrl, fileUrl);
194
195     QDeclarativeEngine engine;
196     QDeclarativeComponent component(&engine, fileUrl);
197     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
198     QVERIFY(anim);
199
200     QGraphicsScene scene;
201     int width = anim->property("width").toInt();
202     int height = anim->property("height").toInt();
203     scene.addItem(qobject_cast<QGraphicsObject *>(anim));
204     QPixmap screenshot = grabScene(&scene, width, height);
205
206     QTransform transform;
207     transform.translate(width, 0).scale(-1, 1.0);
208     QPixmap expected = screenshot.transformed(transform);
209
210     int frame = anim->currentFrame();
211     bool playing = anim->isPlaying();
212     bool paused = anim->isPlaying();
213
214     anim->setProperty("mirror", true);
215     screenshot = grabScene(&scene, width, height);
216
217     QCOMPARE(screenshot, expected);
218
219     // mirroring should not change the current frame or playing status
220     QCOMPARE(anim->currentFrame(), frame);
221     QCOMPARE(anim->isPlaying(), playing);
222     QCOMPARE(anim->isPaused(), paused);
223
224     delete anim;
225 }
226
227 void tst_qdeclarativeanimatedimage::mirror_notRunning_data()
228 {
229     QTest::addColumn<QUrl>("fileUrl");
230
231     QTest::newRow("paused") << QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml");
232     QTest::newRow("stopped") << QUrl::fromLocalFile(SRCDIR "/data/stickmanstopped.qml");
233 }
234
235 void tst_qdeclarativeanimatedimage::remote()
236 {
237     QFETCH(QString, fileName);
238     QFETCH(bool, paused);
239
240     TestHTTPServer server(14449);
241     QVERIFY(server.isValid());
242     server.serveDirectory(SRCDIR "/data");
243
244     QDeclarativeEngine engine;
245     QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
246     QTRY_VERIFY(component.isReady());
247
248     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
249     QVERIFY(anim);
250
251     QTRY_VERIFY(anim->isPlaying());
252     if (paused) {
253         QTRY_VERIFY(anim->isPaused());
254         QCOMPARE(anim->currentFrame(), 2);
255     }
256     QVERIFY(anim->status() != QDeclarative1AnimatedImage::Error);
257
258     delete anim;
259 }
260
261 void tst_qdeclarativeanimatedimage::sourceSize()
262 {
263     QDeclarativeEngine engine;
264     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanscaled.qml"));
265     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
266     QVERIFY(anim);
267     QCOMPARE(anim->width(),240.0);
268     QCOMPARE(anim->height(),180.0);
269     QCOMPARE(anim->sourceSize(),QSize(160,120));
270
271     delete anim;
272 }
273
274 void tst_qdeclarativeanimatedimage::sourceSizeReadOnly()
275 {
276     QDeclarativeEngine engine;
277     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanerror1.qml"));
278     QVERIFY(component.isError());
279     QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
280 }
281
282 void tst_qdeclarativeanimatedimage::remote_data()
283 {
284     QTest::addColumn<QString>("fileName");
285     QTest::addColumn<bool>("paused");
286
287     QTest::newRow("playing") << "stickman.qml" << false;
288     QTest::newRow("paused") << "stickmanpause.qml" << true;
289 }
290
291 void tst_qdeclarativeanimatedimage::invalidSource()
292 {
293     QDeclarativeEngine engine;
294     QDeclarativeComponent component(&engine);
295     component.setData("import QtQuick 1.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
296     QVERIFY(component.isReady());
297
298     QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
299
300     QDeclarative1AnimatedImage *anim = qobject_cast<QDeclarative1AnimatedImage *>(component.create());
301     QVERIFY(anim);
302
303     QVERIFY(!anim->isPlaying());
304     QVERIFY(!anim->isPaused());
305     QCOMPARE(anim->currentFrame(), 0);
306     QCOMPARE(anim->frameCount(), 0);
307     QTRY_VERIFY(anim->status() == 3);
308 }
309
310 void tst_qdeclarativeanimatedimage::qtbug_16520()
311 {
312     TestHTTPServer server(14449);
313     QVERIFY(server.isValid());
314     server.serveDirectory(SRCDIR "/data");
315
316     QDeclarativeEngine engine;
317     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/qtbug-16520.qml"));
318     QTRY_VERIFY(component.isReady());
319
320     QDeclarative1Rectangle *root = qobject_cast<QDeclarative1Rectangle *>(component.create());
321     QVERIFY(root);
322     QDeclarative1AnimatedImage *anim = root->findChild<QDeclarative1AnimatedImage*>("anim");
323
324     anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
325
326     QTRY_VERIFY(anim->opacity() == 0);
327     QTRY_VERIFY(anim->opacity() == 1);
328
329     delete anim;
330 }
331
332 void tst_qdeclarativeanimatedimage::progressAndStatusChanges()
333 {
334     TestHTTPServer server(14449);
335     QVERIFY(server.isValid());
336     server.serveDirectory(SRCDIR "/data");
337
338     QDeclarativeEngine engine;
339     QString componentStr = "import QtQuick 1.0\nAnimatedImage { source: srcImage }";
340     QDeclarativeContext *ctxt = engine.rootContext();
341     ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/stickman.gif"));
342     QDeclarativeComponent component(&engine);
343     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
344     QDeclarative1Image *obj = qobject_cast<QDeclarative1Image*>(component.create());
345     QVERIFY(obj != 0);
346     QVERIFY(obj->status() == QDeclarative1Image::Ready);
347     QTRY_VERIFY(obj->progress() == 1.0);
348
349     QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
350     QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
351     QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QDeclarative1ImageBase::Status)));
352
353     // Loading local file
354     ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.gif"));
355     QTRY_VERIFY(obj->status() == QDeclarative1Image::Ready);
356     QTRY_VERIFY(obj->progress() == 1.0);
357     QTRY_COMPARE(sourceSpy.count(), 1);
358     QTRY_COMPARE(progressSpy.count(), 0);
359     QTRY_COMPARE(statusSpy.count(), 0);
360
361     // Loading remote file
362     ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
363     QTRY_VERIFY(obj->status() == QDeclarative1Image::Loading);
364     QTRY_VERIFY(obj->progress() == 0.0);
365     QTRY_VERIFY(obj->status() == QDeclarative1Image::Ready);
366     QTRY_VERIFY(obj->progress() == 1.0);
367     QTRY_COMPARE(sourceSpy.count(), 2);
368     QTRY_VERIFY(progressSpy.count() > 1);
369     QTRY_COMPARE(statusSpy.count(), 2);
370
371     ctxt->setContextProperty("srcImage", "");
372     QTRY_VERIFY(obj->status() == QDeclarative1Image::Null);
373     QTRY_VERIFY(obj->progress() == 0.0);
374     QTRY_COMPARE(sourceSpy.count(), 3);
375     QTRY_VERIFY(progressSpy.count() > 2);
376     QTRY_COMPARE(statusSpy.count(), 3);
377 }
378
379 QTEST_MAIN(tst_qdeclarativeanimatedimage)
380
381 #include "tst_qdeclarativeanimatedimage.moc"