62592c1d259274aca3577e88ceb2559215f0a92d
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / qquickanimatedimage / tst_qquickanimatedimage.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 <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 <QtDeclarative/qdeclarativecontext.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 QDeclarativeDataTest
57 {
58     Q_OBJECT
59 public:
60     tst_qquickanimatedimage() {}
61
62 private slots:
63     void play();
64     void pause();
65     void stopped();
66     void setFrame();
67     void frameCount();
68     void mirror_running();
69     void mirror_notRunning();
70     void mirror_notRunning_data();
71     void remote();
72     void remote_data();
73     void sourceSize();
74     void sourceSizeReadOnly();
75     void invalidSource();
76     void qtbug_16520();
77     void progressAndStatusChanges();
78
79 };
80
81 void tst_qquickanimatedimage::play()
82 {
83     QDeclarativeEngine engine;
84     QDeclarativeComponent component(&engine, testFileUrl("stickman.qml"));
85     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
86     QVERIFY(anim);
87     QVERIFY(anim->isPlaying());
88
89     delete anim;
90 }
91
92 void tst_qquickanimatedimage::pause()
93 {
94     QDeclarativeEngine engine;
95     QDeclarativeComponent component(&engine, testFileUrl("stickmanpause.qml"));
96     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
97     QVERIFY(anim);
98     QVERIFY(anim->isPlaying());
99     QVERIFY(anim->isPaused());
100
101     delete anim;
102 }
103
104 void tst_qquickanimatedimage::stopped()
105 {
106     QDeclarativeEngine engine;
107     QDeclarativeComponent component(&engine, testFileUrl("stickmanstopped.qml"));
108     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
109     QVERIFY(anim);
110     QVERIFY(!anim->isPlaying());
111     QCOMPARE(anim->currentFrame(), 0);
112
113     delete anim;
114 }
115
116 void tst_qquickanimatedimage::setFrame()
117 {
118     QDeclarativeEngine engine;
119     QDeclarativeComponent component(&engine, testFileUrl("stickmanpause.qml"));
120     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
121     QVERIFY(anim);
122     QVERIFY(anim->isPlaying());
123     QCOMPARE(anim->currentFrame(), 2);
124
125     delete anim;
126 }
127
128 void tst_qquickanimatedimage::frameCount()
129 {
130     QDeclarativeEngine engine;
131     QDeclarativeComponent component(&engine, testFileUrl("colors.qml"));
132     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
133     QVERIFY(anim);
134     QVERIFY(anim->isPlaying());
135     QCOMPARE(anim->frameCount(), 3);
136
137     delete anim;
138 }
139
140 void tst_qquickanimatedimage::mirror_running()
141 {
142     // test where mirror is set to true after animation has started
143
144     QQuickView *canvas = new QQuickView;
145     canvas->show();
146
147     canvas->setSource(testFileUrl("hearts.qml"));
148     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas->rootObject());
149     QVERIFY(anim);
150
151     int width = anim->property("width").toInt();
152
153     QCOMPARE(anim->currentFrame(), 0);
154     QPixmap frame0 = QPixmap::fromImage(canvas->grabFrameBuffer());
155
156     anim->setCurrentFrame(1);
157     QPixmap frame1 = QPixmap::fromImage(canvas->grabFrameBuffer());
158
159     anim->setCurrentFrame(0);
160
161     QSignalSpy spy(anim, SIGNAL(frameChanged()));
162     anim->setPlaying(true);
163
164     QTRY_VERIFY(spy.count() == 1); spy.clear();
165     anim->setProperty("mirror", true);
166
167     QCOMPARE(anim->currentFrame(), 1);
168     QPixmap frame1_flipped = QPixmap::fromImage(canvas->grabFrameBuffer());
169
170     QTRY_VERIFY(spy.count() == 1); spy.clear();
171     QCOMPARE(anim->currentFrame(), 0);  // animation only has 2 frames, should cycle back to first
172     QPixmap frame0_flipped = QPixmap::fromImage(canvas->grabFrameBuffer());
173
174     QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
175
176     QTransform transform;
177     transform.translate(width, 0).scale(-1, 1.0);
178     QPixmap frame0_expected = frame0.transformed(transform);
179     QPixmap frame1_expected = frame1.transformed(transform);
180
181     QCOMPARE(frame0_flipped, frame0_expected);
182     QCOMPARE(frame1_flipped, frame1_expected);
183
184     delete canvas;
185 }
186
187 void tst_qquickanimatedimage::mirror_notRunning()
188 {
189     QFETCH(QUrl, fileUrl);
190
191     QQuickView *canvas = new QQuickView;
192     canvas->show();
193
194     canvas->setSource(fileUrl);
195     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas->rootObject());
196     QVERIFY(anim);
197
198     int width = anim->property("width").toInt();
199     QPixmap screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
200
201     QTransform transform;
202     transform.translate(width, 0).scale(-1, 1.0);
203     QPixmap expected = screenshot.transformed(transform);
204
205     int frame = anim->currentFrame();
206     bool playing = anim->isPlaying();
207     bool paused = anim->isPlaying();
208
209     anim->setProperty("mirror", true);
210     screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
211
212     QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
213     QCOMPARE(screenshot, expected);
214
215     // mirroring should not change the current frame or playing status
216     QCOMPARE(anim->currentFrame(), frame);
217     QCOMPARE(anim->isPlaying(), playing);
218     QCOMPARE(anim->isPaused(), paused);
219
220     delete canvas;
221 }
222
223 void tst_qquickanimatedimage::mirror_notRunning_data()
224 {
225     QTest::addColumn<QUrl>("fileUrl");
226
227     QTest::newRow("paused") << testFileUrl("stickmanpause.qml");
228     QTest::newRow("stopped") << testFileUrl("stickmanstopped.qml");
229 }
230
231 void tst_qquickanimatedimage::remote()
232 {
233     QFETCH(QString, fileName);
234     QFETCH(bool, paused);
235
236     TestHTTPServer server(14449);
237     QVERIFY(server.isValid());
238     server.serveDirectory(dataDirectory());
239
240     QDeclarativeEngine engine;
241     QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
242     QTRY_VERIFY(component.isReady());
243
244     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
245     QVERIFY(anim);
246
247     QTRY_VERIFY(anim->isPlaying());
248     if (paused) {
249         QTRY_VERIFY(anim->isPaused());
250         QCOMPARE(anim->currentFrame(), 2);
251     }
252     QVERIFY(anim->status() != QQuickAnimatedImage::Error);
253
254     delete anim;
255 }
256
257 void tst_qquickanimatedimage::sourceSize()
258 {
259     QDeclarativeEngine engine;
260     QDeclarativeComponent component(&engine, testFileUrl("stickmanscaled.qml"));
261     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
262     QVERIFY(anim);
263     QCOMPARE(anim->width(),240.0);
264     QCOMPARE(anim->height(),180.0);
265     QCOMPARE(anim->sourceSize(),QSize(160,120));
266
267     delete anim;
268 }
269
270 void tst_qquickanimatedimage::sourceSizeReadOnly()
271 {
272     QDeclarativeEngine engine;
273     QDeclarativeComponent component(&engine, testFileUrl("stickmanerror1.qml"));
274     QVERIFY(component.isError());
275     QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
276 }
277
278 void tst_qquickanimatedimage::remote_data()
279 {
280     QTest::addColumn<QString>("fileName");
281     QTest::addColumn<bool>("paused");
282
283     QTest::newRow("playing") << "stickman.qml" << false;
284     QTest::newRow("paused") << "stickmanpause.qml" << true;
285 }
286
287 void tst_qquickanimatedimage::invalidSource()
288 {
289     QDeclarativeEngine engine;
290     QDeclarativeComponent component(&engine);
291     component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
292     QVERIFY(component.isReady());
293
294     QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
295
296     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
297     QVERIFY(anim);
298
299     QVERIFY(!anim->isPlaying());
300     QVERIFY(!anim->isPaused());
301     QCOMPARE(anim->currentFrame(), 0);
302     QCOMPARE(anim->frameCount(), 0);
303     QTRY_VERIFY(anim->status() == 3);
304 }
305
306 void tst_qquickanimatedimage::qtbug_16520()
307 {
308     TestHTTPServer server(14449);
309     QVERIFY(server.isValid());
310     server.serveDirectory(dataDirectory());
311
312     QDeclarativeEngine engine;
313     QDeclarativeComponent component(&engine, testFileUrl("qtbug-16520.qml"));
314     QTRY_VERIFY(component.isReady());
315
316     QQuickRectangle *root = qobject_cast<QQuickRectangle *>(component.create());
317     QVERIFY(root);
318     QQuickAnimatedImage *anim = root->findChild<QQuickAnimatedImage*>("anim");
319
320     anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
321
322     QTRY_VERIFY(anim->opacity() == 0);
323     QTRY_VERIFY(anim->opacity() == 1);
324
325     delete anim;
326 }
327
328 void tst_qquickanimatedimage::progressAndStatusChanges()
329 {
330     TestHTTPServer server(14449);
331     QVERIFY(server.isValid());
332     server.serveDirectory(dataDirectory());
333
334     QDeclarativeEngine engine;
335     QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
336     QDeclarativeContext *ctxt = engine.rootContext();
337     ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
338     QDeclarativeComponent component(&engine);
339     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
340     QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
341     QVERIFY(obj != 0);
342     QVERIFY(obj->status() == QQuickImage::Ready);
343     QTRY_VERIFY(obj->progress() == 1.0);
344
345     qRegisterMetaType<QQuickImageBase::Status>();
346     QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
347     QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
348     QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
349
350     // Loading local file
351     ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
352     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
353     QTRY_VERIFY(obj->progress() == 1.0);
354     QTRY_COMPARE(sourceSpy.count(), 1);
355     QTRY_COMPARE(progressSpy.count(), 0);
356     QTRY_COMPARE(statusSpy.count(), 0);
357
358     // Loading remote file
359     ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
360     QTRY_VERIFY(obj->status() == QQuickImage::Loading);
361     QTRY_VERIFY(obj->progress() == 0.0);
362     QTRY_VERIFY(obj->status() == QQuickImage::Ready);
363     QTRY_VERIFY(obj->progress() == 1.0);
364     QTRY_COMPARE(sourceSpy.count(), 2);
365     QTRY_VERIFY(progressSpy.count() > 1);
366     QTRY_COMPARE(statusSpy.count(), 2);
367
368     ctxt->setContextProperty("srcImage", "");
369     QTRY_VERIFY(obj->status() == QQuickImage::Null);
370     QTRY_VERIFY(obj->progress() == 0.0);
371     QTRY_COMPARE(sourceSpy.count(), 3);
372     QTRY_VERIFY(progressSpy.count() > 2);
373     QTRY_COMPARE(statusSpy.count(), 3);
374 }
375
376 QTEST_MAIN(tst_qquickanimatedimage)
377
378 #include "tst_qquickanimatedimage.moc"