690d5c14c9c72ed25cc2d95cfeb71a0e8a9e9f95
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickanimatedimage / tst_qquickanimatedimage.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QtQml/qqmlengine.h>
43 #include <QtQml/qqmlcomponent.h>
44 #include <QtQuick/qquickview.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <private/qquickimage_p.h>
47 #include <private/qquickanimatedimage_p.h>
48 #include <QSignalSpy>
49 #include <QtQml/qqmlcontext.h>
50
51 #include "../../shared/testhttpserver.h"
52 #include "../../shared/util.h"
53
54 Q_DECLARE_METATYPE(QQuickImageBase::Status)
55
56 class tst_qquickanimatedimage : public QQmlDataTest
57 {
58     Q_OBJECT
59 public:
60     tst_qquickanimatedimage() {}
61
62 private slots:
63     void cleanup();
64     void play();
65     void pause();
66     void stopped();
67     void setFrame();
68     void frameCount();
69     void mirror_running();
70     void mirror_notRunning();
71     void mirror_notRunning_data();
72     void remote();
73     void remote_data();
74     void sourceSize();
75     void sourceSizeChanges();
76     void sourceSizeReadOnly();
77     void invalidSource();
78     void qtbug_16520();
79     void progressAndStatusChanges();
80 };
81
82 void tst_qquickanimatedimage::cleanup()
83 {
84     QQuickCanvas canvas;
85     canvas.releaseResources();
86 }
87
88 void tst_qquickanimatedimage::play()
89 {
90     QQmlEngine engine;
91     QQmlComponent component(&engine, testFileUrl("stickman.qml"));
92     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
93     QVERIFY(anim);
94     QVERIFY(anim->isPlaying());
95
96     delete anim;
97 }
98
99 void tst_qquickanimatedimage::pause()
100 {
101     QQmlEngine engine;
102     QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
103     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
104     QVERIFY(anim);
105
106     QTRY_VERIFY(anim->isPaused());
107     QTRY_VERIFY(anim->isPlaying());
108
109     delete anim;
110 }
111
112 void tst_qquickanimatedimage::stopped()
113 {
114     QQmlEngine engine;
115     QQmlComponent component(&engine, testFileUrl("stickmanstopped.qml"));
116     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
117     QVERIFY(anim);
118     QVERIFY(!anim->isPlaying());
119     QCOMPARE(anim->currentFrame(), 0);
120
121     delete anim;
122 }
123
124 void tst_qquickanimatedimage::setFrame()
125 {
126     QQmlEngine engine;
127     QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
128     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
129     QVERIFY(anim);
130     QVERIFY(anim->isPlaying());
131     QCOMPARE(anim->currentFrame(), 2);
132
133     delete anim;
134 }
135
136 void tst_qquickanimatedimage::frameCount()
137 {
138     QQmlEngine engine;
139     QQmlComponent component(&engine, testFileUrl("colors.qml"));
140     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
141     QVERIFY(anim);
142     QVERIFY(anim->isPlaying());
143     QCOMPARE(anim->frameCount(), 3);
144
145     delete anim;
146 }
147
148 void tst_qquickanimatedimage::mirror_running()
149 {
150     // test where mirror is set to true after animation has started
151
152     QQuickView canvas;
153     canvas.show();
154
155     canvas.setSource(testFileUrl("hearts.qml"));
156     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas.rootObject());
157     QVERIFY(anim);
158
159     int width = anim->property("width").toInt();
160
161     QCOMPARE(anim->currentFrame(), 0);
162     QPixmap frame0 = QPixmap::fromImage(canvas.grabFrameBuffer());
163
164     anim->setCurrentFrame(1);
165     QPixmap frame1 = QPixmap::fromImage(canvas.grabFrameBuffer());
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 = QPixmap::fromImage(canvas.grabFrameBuffer());
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 = QPixmap::fromImage(canvas.grabFrameBuffer());
181
182     QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
183
184     QTransform transform;
185     transform.translate(width, 0).scale(-1, 1.0);
186     QPixmap frame0_expected = frame0.transformed(transform);
187     QPixmap frame1_expected = frame1.transformed(transform);
188
189     QCOMPARE(frame0_flipped, frame0_expected);
190     QCOMPARE(frame1_flipped, frame1_expected);
191
192     delete anim;
193 }
194
195 void tst_qquickanimatedimage::mirror_notRunning()
196 {
197     QFETCH(QUrl, fileUrl);
198
199     QQuickView canvas;
200     canvas.show();
201
202     canvas.setSource(fileUrl);
203     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas.rootObject());
204     QVERIFY(anim);
205
206     int width = anim->property("width").toInt();
207     QPixmap screenshot = QPixmap::fromImage(canvas.grabFrameBuffer());
208
209     QTransform transform;
210     transform.translate(width, 0).scale(-1, 1.0);
211     QPixmap expected = screenshot.transformed(transform);
212
213     int frame = anim->currentFrame();
214     bool playing = anim->isPlaying();
215     bool paused = anim->isPlaying();
216
217     anim->setProperty("mirror", true);
218     screenshot = QPixmap::fromImage(canvas.grabFrameBuffer());
219
220     QCOMPARE(screenshot, expected);
221
222     // mirroring should not change the current frame or playing status
223     QCOMPARE(anim->currentFrame(), frame);
224     QCOMPARE(anim->isPlaying(), playing);
225     QCOMPARE(anim->isPaused(), paused);
226
227     delete anim;
228 }
229
230 void tst_qquickanimatedimage::mirror_notRunning_data()
231 {
232     QTest::addColumn<QUrl>("fileUrl");
233
234     QTest::newRow("paused") << testFileUrl("stickmanpause.qml");
235     QTest::newRow("stopped") << testFileUrl("stickmanstopped.qml");
236 }
237
238 void tst_qquickanimatedimage::remote_data()
239 {
240     QTest::addColumn<QString>("fileName");
241     QTest::addColumn<bool>("paused");
242
243     QTest::newRow("playing") << "stickman.qml" << false;
244     QTest::newRow("paused") << "stickmanpause.qml" << true;
245 }
246
247 void tst_qquickanimatedimage::remote()
248 {
249     QFETCH(QString, fileName);
250     QFETCH(bool, paused);
251
252     TestHTTPServer server(14449);
253     QVERIFY(server.isValid());
254     server.serveDirectory(dataDirectory());
255
256     QQmlEngine engine;
257     QQmlComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
258     QTRY_VERIFY(component.isReady());
259
260     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
261     QVERIFY(anim);
262
263     QTRY_VERIFY(anim->isPlaying());
264     if (paused) {
265         QTRY_VERIFY(anim->isPaused());
266         QCOMPARE(anim->currentFrame(), 2);
267     }
268     QVERIFY(anim->status() != QQuickAnimatedImage::Error);
269
270     delete anim;
271 }
272
273 void tst_qquickanimatedimage::sourceSize()
274 {
275     QQmlEngine engine;
276     QQmlComponent component(&engine, testFileUrl("stickmanscaled.qml"));
277     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
278     QVERIFY(anim);
279     QCOMPARE(anim->width(),240.0);
280     QCOMPARE(anim->height(),180.0);
281     QCOMPARE(anim->sourceSize(),QSize(160,120));
282
283     delete anim;
284 }
285
286 void tst_qquickanimatedimage::sourceSizeReadOnly()
287 {
288     QQmlEngine engine;
289     QQmlComponent component(&engine, testFileUrl("stickmanerror1.qml"));
290     QVERIFY(component.isError());
291     QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
292 }
293
294 void tst_qquickanimatedimage::invalidSource()
295 {
296     QQmlEngine engine;
297     QQmlComponent component(&engine);
298     component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
299     QVERIFY(component.isReady());
300
301     QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
302
303     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
304     QVERIFY(anim);
305
306     QVERIFY(!anim->isPlaying());
307     QVERIFY(!anim->isPaused());
308     QCOMPARE(anim->currentFrame(), 0);
309     QCOMPARE(anim->frameCount(), 0);
310     QTRY_VERIFY(anim->status() == 3);
311
312     delete anim;
313 }
314
315 void tst_qquickanimatedimage::sourceSizeChanges()
316 {
317     TestHTTPServer server(14449);
318     QVERIFY(server.isValid());
319     server.serveDirectory(dataDirectory());
320
321     QQmlEngine engine;
322     QQmlComponent component(&engine);
323     component.setData("import QtQuick 2.0\nAnimatedImage { source: srcImage }", QUrl::fromLocalFile(""));
324     QTRY_VERIFY(component.isReady());
325     QQmlContext *ctxt = engine.rootContext();
326     ctxt->setContextProperty("srcImage", "");
327     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage*>(component.create());
328     QVERIFY(anim != 0);
329
330     QSignalSpy sourceSizeSpy(anim, SIGNAL(sourceSizeChanged()));
331
332     // Local
333     ctxt->setContextProperty("srcImage", QUrl(""));
334     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
335     QTRY_VERIFY(sourceSizeSpy.count() == 0);
336
337     ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
338     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
339     QTRY_VERIFY(sourceSizeSpy.count() == 1);
340
341     ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
342     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
343     QTRY_VERIFY(sourceSizeSpy.count() == 1);
344
345     ctxt->setContextProperty("srcImage", testFileUrl("hearts_copy.gif"));
346     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
347     QTRY_VERIFY(sourceSizeSpy.count() == 1);
348
349     ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
350     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
351     QTRY_VERIFY(sourceSizeSpy.count() == 2);
352
353     ctxt->setContextProperty("srcImage", QUrl(""));
354     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
355     QTRY_VERIFY(sourceSizeSpy.count() == 3);
356
357     // Remote
358     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts.gif"));
359     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
360     QTRY_VERIFY(sourceSizeSpy.count() == 4);
361
362     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts.gif"));
363     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
364     QTRY_VERIFY(sourceSizeSpy.count() == 4);
365
366     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts_copy.gif"));
367     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
368     QTRY_VERIFY(sourceSizeSpy.count() == 4);
369
370     ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/colors.gif"));
371     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
372     QTRY_VERIFY(sourceSizeSpy.count() == 5);
373
374     ctxt->setContextProperty("srcImage", QUrl(""));
375     QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
376     QTRY_VERIFY(sourceSizeSpy.count() == 6);
377
378     delete anim;
379 }
380
381 void tst_qquickanimatedimage::qtbug_16520()
382 {
383     TestHTTPServer server(14449);
384     QVERIFY(server.isValid());
385     server.serveDirectory(dataDirectory());
386
387     QQmlEngine engine;
388     QQmlComponent component(&engine, testFileUrl("qtbug-16520.qml"));
389     QTRY_VERIFY(component.isReady());
390
391     QQuickRectangle *root = qobject_cast<QQuickRectangle *>(component.create());
392     QVERIFY(root);
393     QQuickAnimatedImage *anim = root->findChild<QQuickAnimatedImage*>("anim");
394     QVERIFY(anim != 0);
395
396     anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
397     QTRY_VERIFY(anim->opacity() == 0);
398     QTRY_VERIFY(anim->opacity() == 1);
399
400     delete anim;
401     delete root;
402 }
403
404 void tst_qquickanimatedimage::progressAndStatusChanges()
405 {
406     TestHTTPServer server(14449);
407     QVERIFY(server.isValid());
408     server.serveDirectory(dataDirectory());
409
410     QQmlEngine engine;
411     QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
412     QQmlContext *ctxt = engine.rootContext();
413     ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
414     QQmlComponent component(&engine);
415     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
416     QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
417     QVERIFY(obj != 0);
418     QVERIFY(obj->status() == QQuickImage::Ready);
419     QTRY_VERIFY(obj->progress() == 1.0);
420
421     qRegisterMetaType<QQuickImageBase::Status>();
422     QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
423     QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
424     QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
425
426     // Same image
427     ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
428     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
429     QTRY_VERIFY(obj->progress() == 1.0);
430     QTRY_COMPARE(sourceSpy.count(), 0);
431     QTRY_COMPARE(progressSpy.count(), 0);
432     QTRY_COMPARE(statusSpy.count(), 0);
433
434     // Loading local file
435     ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
436     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
437     QTRY_VERIFY(obj->progress() == 1.0);
438     QTRY_COMPARE(sourceSpy.count(), 1);
439     QTRY_COMPARE(progressSpy.count(), 0);
440     QTRY_COMPARE(statusSpy.count(), 1);
441
442     // Loading remote file
443     ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
444     QTRY_VERIFY(obj->status() == QQuickImage::Loading);
445     QTRY_VERIFY(obj->progress() == 0.0);
446     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
447     QTRY_VERIFY(obj->progress() == 1.0);
448     QTRY_COMPARE(sourceSpy.count(), 2);
449     QTRY_VERIFY(progressSpy.count() > 1);
450     QTRY_COMPARE(statusSpy.count(), 3);
451
452     ctxt->setContextProperty("srcImage", "");
453     QTRY_VERIFY(obj->status() == QQuickImage::Null);
454     QTRY_VERIFY(obj->progress() == 0.0);
455     QTRY_COMPARE(sourceSpy.count(), 3);
456     QTRY_VERIFY(progressSpy.count() > 2);
457     QTRY_COMPARE(statusSpy.count(), 4);
458
459     delete obj;
460 }
461
462 QTEST_MAIN(tst_qquickanimatedimage)
463
464 #include "tst_qquickanimatedimage.moc"