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 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 | |
29 | #include <QtTest/QtTest> |
30 | #include <QDebug> |
31 | #include "qmediaservice.h" |
32 | #include "qmediaplaylist.h" |
33 | #include <private/qmediaplaylistcontrol_p.h> |
34 | #include <private/qmediaplaylistsourcecontrol_p.h> |
35 | #include <private/qmediaplaylistnavigator_p.h> |
36 | #include <private/qmediapluginloader_p.h> |
37 | |
38 | #include "qm3uhandler.h" |
39 | |
40 | //TESTED_COMPONENT=src/multimedia |
41 | |
42 | #include "mockplaylistservice.h" |
43 | #include "mockmediaplaylistcontrol.h" |
44 | #include "mockmediaplaylistsourcecontrol.h" |
45 | #include "mockreadonlyplaylistprovider.h" |
46 | |
47 | QT_USE_NAMESPACE |
48 | |
49 | class MockPlaylistObject : public QMediaObject |
50 | { |
51 | Q_OBJECT |
52 | public: |
53 | MockPlaylistObject(QObject *parent = 0) |
54 | : QMediaObject(parent, mockService = new MockPlaylistService) |
55 | { |
56 | } |
57 | |
58 | MockPlaylistService *mockService; |
59 | }; |
60 | |
61 | class tst_QMediaPlaylist : public QObject |
62 | { |
63 | Q_OBJECT |
64 | public slots: |
65 | void init(); |
66 | void cleanup(); |
67 | void initTestCase(); |
68 | |
69 | private slots: |
70 | void construction(); |
71 | void append(); |
72 | void insert(); |
73 | void clear(); |
74 | void removeMedia(); |
75 | void currentItem(); |
76 | void saveAndLoad(); |
77 | void loadM3uFile(); |
78 | void loadPLSFile(); |
79 | void playbackMode(); |
80 | void playbackMode_data(); |
81 | void shuffle(); |
82 | void readOnlyPlaylist(); |
83 | void setMediaObject(); |
84 | |
85 | void testCurrentIndexChanged_signal(); |
86 | void testCurrentMediaChanged_signal(); |
87 | void testLoaded_signal(); |
88 | void testMediaChanged_signal(); |
89 | void testPlaybackModeChanged_signal(); |
90 | void testEnums(); |
91 | |
92 | void mediaPlayListProvider(); |
93 | // TC for Abstract control classes |
94 | void mediaPlayListControl(); |
95 | void mediaPlayListSourceControl(); |
96 | |
97 | |
98 | private: |
99 | QMediaContent content1; |
100 | QMediaContent content2; |
101 | QMediaContent content3; |
102 | }; |
103 | |
104 | void tst_QMediaPlaylist::init() |
105 | { |
106 | } |
107 | |
108 | void tst_QMediaPlaylist::initTestCase() |
109 | { |
110 | qRegisterMetaType<QMediaContent>(); |
111 | content1 = QMediaContent(QUrl(QLatin1String("file:///1" ))); |
112 | content2 = QMediaContent(QUrl(QLatin1String("file:///2" ))); |
113 | content3 = QMediaContent(QUrl(QLatin1String("file:///3" ))); |
114 | |
115 | } |
116 | |
117 | void tst_QMediaPlaylist::cleanup() |
118 | { |
119 | } |
120 | |
121 | void tst_QMediaPlaylist::construction() |
122 | { |
123 | QMediaPlaylist playlist; |
124 | QCOMPARE(playlist.mediaCount(), 0); |
125 | QVERIFY(playlist.isEmpty()); |
126 | } |
127 | |
128 | void tst_QMediaPlaylist::append() |
129 | { |
130 | QMediaPlaylist playlist; |
131 | QVERIFY(!playlist.isReadOnly()); |
132 | |
133 | playlist.addMedia(content: content1); |
134 | QCOMPARE(playlist.mediaCount(), 1); |
135 | QCOMPARE(playlist.media(0), content1); |
136 | |
137 | QSignalSpy aboutToBeInsertedSignalSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int,int))); |
138 | QSignalSpy insertedSignalSpy(&playlist, SIGNAL(mediaInserted(int,int))); |
139 | playlist.addMedia(content: content2); |
140 | QCOMPARE(playlist.mediaCount(), 2); |
141 | QCOMPARE(playlist.media(1), content2); |
142 | |
143 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
144 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 1); |
145 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1); |
146 | |
147 | QCOMPARE(insertedSignalSpy.count(), 1); |
148 | QCOMPARE(insertedSignalSpy.first()[0].toInt(), 1); |
149 | QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1); |
150 | |
151 | aboutToBeInsertedSignalSpy.clear(); |
152 | insertedSignalSpy.clear(); |
153 | |
154 | QMediaContent content4(QUrl(QLatin1String("file:///4" ))); |
155 | QMediaContent content5(QUrl(QLatin1String("file:///5" ))); |
156 | playlist.addMedia(items: QList<QMediaContent>() << content3 << content4 << content5); |
157 | QCOMPARE(playlist.mediaCount(), 5); |
158 | QCOMPARE(playlist.media(2), content3); |
159 | QCOMPARE(playlist.media(3), content4); |
160 | QCOMPARE(playlist.media(4), content5); |
161 | |
162 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
163 | QCOMPARE(aboutToBeInsertedSignalSpy[0][0].toInt(), 2); |
164 | QCOMPARE(aboutToBeInsertedSignalSpy[0][1].toInt(), 4); |
165 | |
166 | QCOMPARE(insertedSignalSpy.count(), 1); |
167 | QCOMPARE(insertedSignalSpy[0][0].toInt(), 2); |
168 | QCOMPARE(insertedSignalSpy[0][1].toInt(), 4); |
169 | |
170 | aboutToBeInsertedSignalSpy.clear(); |
171 | insertedSignalSpy.clear(); |
172 | |
173 | playlist.addMedia(items: QList<QMediaContent>()); |
174 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 0); |
175 | QCOMPARE(insertedSignalSpy.count(), 0); |
176 | } |
177 | |
178 | void tst_QMediaPlaylist::insert() |
179 | { |
180 | QMediaPlaylist playlist; |
181 | QVERIFY(!playlist.isReadOnly()); |
182 | |
183 | playlist.addMedia(content: content1); |
184 | QCOMPARE(playlist.mediaCount(), 1); |
185 | QCOMPARE(playlist.media(0), content1); |
186 | |
187 | playlist.addMedia(content: content2); |
188 | QCOMPARE(playlist.mediaCount(), 2); |
189 | QCOMPARE(playlist.media(1), content2); |
190 | |
191 | QSignalSpy aboutToBeInsertedSignalSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int,int))); |
192 | QSignalSpy insertedSignalSpy(&playlist, SIGNAL(mediaInserted(int,int))); |
193 | |
194 | playlist.insertMedia(index: 1, content: content3); |
195 | QCOMPARE(playlist.mediaCount(), 3); |
196 | QCOMPARE(playlist.media(0), content1); |
197 | QCOMPARE(playlist.media(1), content3); |
198 | QCOMPARE(playlist.media(2), content2); |
199 | |
200 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
201 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 1); |
202 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1); |
203 | |
204 | QCOMPARE(insertedSignalSpy.count(), 1); |
205 | QCOMPARE(insertedSignalSpy.first()[0].toInt(), 1); |
206 | QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1); |
207 | |
208 | aboutToBeInsertedSignalSpy.clear(); |
209 | insertedSignalSpy.clear(); |
210 | |
211 | QMediaContent content4(QUrl(QLatin1String("file:///4" ))); |
212 | QMediaContent content5(QUrl(QLatin1String("file:///5" ))); |
213 | playlist.insertMedia(index: 1, items: QList<QMediaContent>() << content4 << content5); |
214 | |
215 | QCOMPARE(playlist.media(0), content1); |
216 | QCOMPARE(playlist.media(1), content4); |
217 | QCOMPARE(playlist.media(2), content5); |
218 | QCOMPARE(playlist.media(3), content3); |
219 | QCOMPARE(playlist.media(4), content2); |
220 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
221 | QCOMPARE(aboutToBeInsertedSignalSpy[0][0].toInt(), 1); |
222 | QCOMPARE(aboutToBeInsertedSignalSpy[0][1].toInt(), 2); |
223 | |
224 | QCOMPARE(insertedSignalSpy.count(), 1); |
225 | QCOMPARE(insertedSignalSpy[0][0].toInt(), 1); |
226 | QCOMPARE(insertedSignalSpy[0][1].toInt(), 2); |
227 | |
228 | aboutToBeInsertedSignalSpy.clear(); |
229 | insertedSignalSpy.clear(); |
230 | |
231 | playlist.insertMedia(index: 1, items: QList<QMediaContent>()); |
232 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 0); |
233 | QCOMPARE(insertedSignalSpy.count(), 0); |
234 | |
235 | playlist.clear(); |
236 | playlist.addMedia(content: content1); |
237 | aboutToBeInsertedSignalSpy.clear(); |
238 | insertedSignalSpy.clear(); |
239 | |
240 | playlist.insertMedia(index: -10, content: content2); |
241 | QCOMPARE(playlist.media(0), content2); |
242 | QCOMPARE(playlist.media(1), content1); |
243 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
244 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 0); |
245 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 0); |
246 | QCOMPARE(insertedSignalSpy.count(), 1); |
247 | QCOMPARE(insertedSignalSpy.first()[0].toInt(), 0); |
248 | QCOMPARE(insertedSignalSpy.first()[1].toInt(), 0); |
249 | |
250 | aboutToBeInsertedSignalSpy.clear(); |
251 | insertedSignalSpy.clear(); |
252 | |
253 | playlist.insertMedia(index: 10, content: content3); |
254 | QCOMPARE(playlist.media(0), content2); |
255 | QCOMPARE(playlist.media(1), content1); |
256 | QCOMPARE(playlist.media(2), content3); |
257 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
258 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 2); |
259 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 2); |
260 | QCOMPARE(insertedSignalSpy.count(), 1); |
261 | QCOMPARE(insertedSignalSpy.first()[0].toInt(), 2); |
262 | QCOMPARE(insertedSignalSpy.first()[1].toInt(), 2); |
263 | |
264 | aboutToBeInsertedSignalSpy.clear(); |
265 | insertedSignalSpy.clear(); |
266 | |
267 | playlist.insertMedia(index: -10, items: QList<QMediaContent>() << content4 << content5); |
268 | QCOMPARE(playlist.media(0), content4); |
269 | QCOMPARE(playlist.media(1), content5); |
270 | QCOMPARE(playlist.media(2), content2); |
271 | QCOMPARE(playlist.media(3), content1); |
272 | QCOMPARE(playlist.media(4), content3); |
273 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
274 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 0); |
275 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1); |
276 | QCOMPARE(insertedSignalSpy.count(), 1); |
277 | QCOMPARE(insertedSignalSpy.first()[0].toInt(), 0); |
278 | QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1); |
279 | |
280 | aboutToBeInsertedSignalSpy.clear(); |
281 | insertedSignalSpy.clear(); |
282 | |
283 | QMediaContent content6(QUrl(QLatin1String("file:///6" ))); |
284 | QMediaContent content7(QUrl(QLatin1String("file:///7" ))); |
285 | playlist.insertMedia(index: 10, items: QList<QMediaContent>() << content6 << content7); |
286 | QCOMPARE(playlist.media(0), content4); |
287 | QCOMPARE(playlist.media(1), content5); |
288 | QCOMPARE(playlist.media(2), content2); |
289 | QCOMPARE(playlist.media(3), content1); |
290 | QCOMPARE(playlist.media(4), content3); |
291 | QCOMPARE(playlist.media(5), content6); |
292 | QCOMPARE(playlist.media(6), content7); |
293 | QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); |
294 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 5); |
295 | QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 6); |
296 | QCOMPARE(insertedSignalSpy.count(), 1); |
297 | QCOMPARE(insertedSignalSpy.first()[0].toInt(), 5); |
298 | QCOMPARE(insertedSignalSpy.first()[1].toInt(), 6); |
299 | } |
300 | |
301 | |
302 | void tst_QMediaPlaylist::currentItem() |
303 | { |
304 | QMediaPlaylist playlist; |
305 | playlist.addMedia(content: content1); |
306 | playlist.addMedia(content: content2); |
307 | |
308 | QCOMPARE(playlist.currentIndex(), -1); |
309 | QCOMPARE(playlist.currentMedia(), QMediaContent()); |
310 | |
311 | QCOMPARE(playlist.nextIndex(), 0); |
312 | QCOMPARE(playlist.nextIndex(2), 1); |
313 | QCOMPARE(playlist.previousIndex(), 1); |
314 | QCOMPARE(playlist.previousIndex(2), 0); |
315 | |
316 | playlist.setCurrentIndex(0); |
317 | QCOMPARE(playlist.currentIndex(), 0); |
318 | QCOMPARE(playlist.currentMedia(), content1); |
319 | |
320 | QCOMPARE(playlist.nextIndex(), 1); |
321 | QCOMPARE(playlist.nextIndex(2), -1); |
322 | QCOMPARE(playlist.previousIndex(), -1); |
323 | QCOMPARE(playlist.previousIndex(2), -1); |
324 | |
325 | playlist.setCurrentIndex(1); |
326 | QCOMPARE(playlist.currentIndex(), 1); |
327 | QCOMPARE(playlist.currentMedia(), content2); |
328 | |
329 | QCOMPARE(playlist.nextIndex(), -1); |
330 | QCOMPARE(playlist.nextIndex(2), -1); |
331 | QCOMPARE(playlist.previousIndex(), 0); |
332 | QCOMPARE(playlist.previousIndex(2), -1); |
333 | |
334 | playlist.setCurrentIndex(2); |
335 | |
336 | QCOMPARE(playlist.currentIndex(), -1); |
337 | QCOMPARE(playlist.currentMedia(), QMediaContent()); |
338 | } |
339 | |
340 | void tst_QMediaPlaylist::clear() |
341 | { |
342 | QMediaPlaylist playlist; |
343 | playlist.addMedia(content: content1); |
344 | playlist.addMedia(content: content2); |
345 | |
346 | playlist.clear(); |
347 | QVERIFY(playlist.isEmpty()); |
348 | QCOMPARE(playlist.mediaCount(), 0); |
349 | } |
350 | |
351 | void tst_QMediaPlaylist::removeMedia() |
352 | { |
353 | QMediaPlaylist playlist; |
354 | playlist.addMedia(content: content1); |
355 | playlist.addMedia(content: content2); |
356 | playlist.addMedia(content: content3); |
357 | |
358 | QSignalSpy aboutToBeRemovedSignalSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int,int))); |
359 | QSignalSpy removedSignalSpy(&playlist, SIGNAL(mediaRemoved(int,int))); |
360 | playlist.removeMedia(pos: 1); |
361 | QCOMPARE(playlist.mediaCount(), 2); |
362 | QCOMPARE(playlist.media(1), content3); |
363 | |
364 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); |
365 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 1); |
366 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1); |
367 | |
368 | QCOMPARE(removedSignalSpy.count(), 1); |
369 | QCOMPARE(removedSignalSpy.first()[0].toInt(), 1); |
370 | QCOMPARE(removedSignalSpy.first()[1].toInt(), 1); |
371 | |
372 | aboutToBeRemovedSignalSpy.clear(); |
373 | removedSignalSpy.clear(); |
374 | |
375 | playlist.removeMedia(start: 0,end: 1); |
376 | QVERIFY(playlist.isEmpty()); |
377 | |
378 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); |
379 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0); |
380 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1); |
381 | |
382 | QCOMPARE(removedSignalSpy.count(), 1); |
383 | QCOMPARE(removedSignalSpy.first()[0].toInt(), 0); |
384 | QCOMPARE(removedSignalSpy.first()[1].toInt(), 1); |
385 | |
386 | |
387 | playlist.addMedia(content: content1); |
388 | playlist.addMedia(content: content2); |
389 | playlist.addMedia(content: content3); |
390 | |
391 | playlist.removeMedia(start: 0,end: 1); |
392 | QCOMPARE(playlist.mediaCount(), 1); |
393 | QCOMPARE(playlist.media(0), content3); |
394 | |
395 | QCOMPARE(playlist.removeMedia(-1), false); |
396 | QCOMPARE(playlist.removeMedia(1), false); |
397 | |
398 | playlist.addMedia(content: content1); |
399 | aboutToBeRemovedSignalSpy.clear(); |
400 | removedSignalSpy.clear(); |
401 | |
402 | playlist.removeMedia(start: -10, end: 10); |
403 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); |
404 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0); |
405 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1); |
406 | QCOMPARE(removedSignalSpy.count(), 1); |
407 | QCOMPARE(removedSignalSpy.first()[0].toInt(), 0); |
408 | QCOMPARE(removedSignalSpy.first()[1].toInt(), 1); |
409 | |
410 | playlist.addMedia(content: content1); |
411 | playlist.addMedia(content: content2); |
412 | playlist.addMedia(content: content3); |
413 | aboutToBeRemovedSignalSpy.clear(); |
414 | removedSignalSpy.clear(); |
415 | |
416 | QCOMPARE(playlist.removeMedia(10, -10), false); |
417 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 0); |
418 | QCOMPARE(removedSignalSpy.count(), 0); |
419 | QCOMPARE(playlist.removeMedia(-10, -5), false); |
420 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 0); |
421 | QCOMPARE(removedSignalSpy.count(), 0); |
422 | QCOMPARE(playlist.removeMedia(5, 10), false); |
423 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 0); |
424 | QCOMPARE(removedSignalSpy.count(), 0); |
425 | |
426 | playlist.removeMedia(start: 1, end: 10); |
427 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); |
428 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 1); |
429 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 2); |
430 | QCOMPARE(removedSignalSpy.count(), 1); |
431 | QCOMPARE(removedSignalSpy.first()[0].toInt(), 1); |
432 | QCOMPARE(removedSignalSpy.first()[1].toInt(), 2); |
433 | |
434 | playlist.addMedia(content: content2); |
435 | playlist.addMedia(content: content3); |
436 | aboutToBeRemovedSignalSpy.clear(); |
437 | removedSignalSpy.clear(); |
438 | |
439 | playlist.removeMedia(start: -10, end: 1); |
440 | QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); |
441 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0); |
442 | QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1); |
443 | QCOMPARE(removedSignalSpy.count(), 1); |
444 | QCOMPARE(removedSignalSpy.first()[0].toInt(), 0); |
445 | QCOMPARE(removedSignalSpy.first()[1].toInt(), 1); |
446 | } |
447 | |
448 | void tst_QMediaPlaylist::saveAndLoad() |
449 | { |
450 | QMediaPlaylist playlist; |
451 | playlist.addMedia(content: content1); |
452 | playlist.addMedia(content: content2); |
453 | playlist.addMedia(content: content3); |
454 | |
455 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
456 | QVERIFY(playlist.errorString().isEmpty()); |
457 | |
458 | QBuffer buffer; |
459 | buffer.open(openMode: QBuffer::ReadWrite); |
460 | |
461 | bool res = playlist.save(device: &buffer, format: "unsupported_format" ); |
462 | QVERIFY(!res); |
463 | QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError); |
464 | QVERIFY(!playlist.errorString().isEmpty()); |
465 | |
466 | QSignalSpy loadedSignal(&playlist, SIGNAL(loaded())); |
467 | QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed())); |
468 | playlist.load(device: &buffer, format: "unsupported_format" ); |
469 | QTRY_VERIFY(loadedSignal.isEmpty()); |
470 | QCOMPARE(errorSignal.size(), 1); |
471 | QVERIFY(playlist.error() != QMediaPlaylist::NoError); |
472 | QVERIFY(!playlist.errorString().isEmpty()); |
473 | |
474 | res = playlist.save(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.unsupported_format" )), format: "unsupported_format" ); |
475 | QVERIFY(!res); |
476 | QVERIFY(playlist.error() != QMediaPlaylist::NoError); |
477 | QVERIFY(!playlist.errorString().isEmpty()); |
478 | |
479 | loadedSignal.clear(); |
480 | errorSignal.clear(); |
481 | playlist.load(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.unsupported_format" )), format: "unsupported_format" ); |
482 | QTRY_VERIFY(loadedSignal.isEmpty()); |
483 | QCOMPARE(errorSignal.size(), 1); |
484 | QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError); |
485 | QVERIFY(!playlist.errorString().isEmpty()); |
486 | |
487 | res = playlist.save(device: &buffer, format: "m3u" ); |
488 | |
489 | QVERIFY(res); |
490 | QVERIFY(buffer.pos() > 0); |
491 | buffer.seek(off: 0); |
492 | |
493 | QMediaPlaylist playlist2; |
494 | QSignalSpy loadedSignal2(&playlist2, SIGNAL(loaded())); |
495 | QSignalSpy errorSignal2(&playlist2, SIGNAL(loadFailed())); |
496 | playlist2.load(device: &buffer, format: "m3u" ); |
497 | QCOMPARE(loadedSignal2.size(), 1); |
498 | QTRY_VERIFY(errorSignal2.isEmpty()); |
499 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
500 | |
501 | QCOMPARE(playlist.mediaCount(), playlist2.mediaCount()); |
502 | QCOMPARE(playlist.media(0), playlist2.media(0)); |
503 | QCOMPARE(playlist.media(1), playlist2.media(1)); |
504 | QCOMPARE(playlist.media(3), playlist2.media(3)); |
505 | res = playlist.save(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.m3u" )), format: "m3u" ); |
506 | QVERIFY(res); |
507 | |
508 | loadedSignal2.clear(); |
509 | errorSignal2.clear(); |
510 | playlist2.clear(); |
511 | QVERIFY(playlist2.isEmpty()); |
512 | playlist2.load(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.m3u" )), format: "m3u" ); |
513 | QCOMPARE(loadedSignal2.size(), 1); |
514 | QTRY_VERIFY(errorSignal2.isEmpty()); |
515 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
516 | |
517 | QCOMPARE(playlist.mediaCount(), playlist2.mediaCount()); |
518 | QCOMPARE(playlist.media(0), playlist2.media(0)); |
519 | QCOMPARE(playlist.media(1), playlist2.media(1)); |
520 | QCOMPARE(playlist.media(3), playlist2.media(3)); |
521 | } |
522 | |
523 | void tst_QMediaPlaylist::loadM3uFile() |
524 | { |
525 | QMediaPlaylist playlist; |
526 | |
527 | // Try to load playlist that does not exist in the testdata folder |
528 | QSignalSpy loadSpy(&playlist, SIGNAL(loaded())); |
529 | QSignalSpy loadFailedSpy(&playlist, SIGNAL(loadFailed())); |
530 | QString testFileName = QFINDTESTDATA("testdata" ); |
531 | playlist.load(location: QUrl::fromLocalFile(localfile: testFileName + "/missing_file.m3u" )); |
532 | QTRY_VERIFY(loadSpy.isEmpty()); |
533 | QVERIFY(!loadFailedSpy.isEmpty()); |
534 | QVERIFY(playlist.error() != QMediaPlaylist::NoError); |
535 | |
536 | loadSpy.clear(); |
537 | loadFailedSpy.clear(); |
538 | testFileName = QFINDTESTDATA("testdata/test.m3u" ); |
539 | playlist.load(location: QUrl::fromLocalFile(localfile: testFileName)); |
540 | QTRY_VERIFY(!loadSpy.isEmpty()); |
541 | QVERIFY(loadFailedSpy.isEmpty()); |
542 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
543 | QCOMPARE(playlist.mediaCount(), 7); |
544 | |
545 | QCOMPARE(playlist.media(0).request().url(), QUrl(QLatin1String("http://test.host/path" ))); |
546 | QCOMPARE(playlist.media(1).request().url(), QUrl(QLatin1String("http://test.host/path" ))); |
547 | testFileName = QFINDTESTDATA("testdata/testfile" ); |
548 | QCOMPARE(playlist.media(2).request().url(), |
549 | QUrl::fromLocalFile(testFileName)); |
550 | testFileName = QFINDTESTDATA("testdata" ); |
551 | QCOMPARE(playlist.media(3).request().url(), |
552 | QUrl::fromLocalFile(testFileName + "/testdir/testfile" )); |
553 | QCOMPARE(playlist.media(4).request().url(), QUrl(QLatin1String("file:///testdir/testfile" ))); |
554 | QCOMPARE(playlist.media(5).request().url(), QUrl(QLatin1String("file://path/name#suffix" ))); |
555 | //ensure #2 suffix is not stripped from path |
556 | testFileName = QFINDTESTDATA("testdata/testfile2#suffix" ); |
557 | QCOMPARE(playlist.media(6).request().url(), QUrl::fromLocalFile(testFileName)); |
558 | |
559 | // check ability to load from QNetworkRequest |
560 | loadSpy.clear(); |
561 | loadFailedSpy.clear(); |
562 | playlist.load(request: QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.m3u" )))); |
563 | QTRY_VERIFY(!loadSpy.isEmpty()); |
564 | QVERIFY(loadFailedSpy.isEmpty()); |
565 | } |
566 | |
567 | void tst_QMediaPlaylist::loadPLSFile() |
568 | { |
569 | QMediaPlaylist playlist; |
570 | |
571 | // Try to load playlist that does not exist in the testdata folder |
572 | QSignalSpy loadSpy(&playlist, SIGNAL(loaded())); |
573 | QSignalSpy loadFailedSpy(&playlist, SIGNAL(loadFailed())); |
574 | QString testFileName = QFINDTESTDATA("testdata" ); |
575 | playlist.load(location: QUrl::fromLocalFile(localfile: testFileName + "/missing_file.pls" )); |
576 | QTRY_VERIFY(loadSpy.isEmpty()); |
577 | QVERIFY(!loadFailedSpy.isEmpty()); |
578 | QVERIFY(playlist.error() != QMediaPlaylist::NoError); |
579 | |
580 | // Try to load empty playlist |
581 | loadSpy.clear(); |
582 | loadFailedSpy.clear(); |
583 | testFileName = QFINDTESTDATA("testdata/empty.pls" ); |
584 | playlist.load(location: QUrl::fromLocalFile(localfile: testFileName)); |
585 | QTRY_VERIFY(!loadSpy.isEmpty()); |
586 | QVERIFY(loadFailedSpy.isEmpty()); |
587 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
588 | QCOMPARE(playlist.mediaCount(), 0); |
589 | |
590 | // Try to load regular playlist |
591 | loadSpy.clear(); |
592 | loadFailedSpy.clear(); |
593 | testFileName = QFINDTESTDATA("testdata/test.pls" ); |
594 | playlist.load(location: QUrl::fromLocalFile(localfile: testFileName)); |
595 | QTRY_VERIFY(!loadSpy.isEmpty()); |
596 | QVERIFY(loadFailedSpy.isEmpty()); |
597 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
598 | QCOMPARE(playlist.mediaCount(), 7); |
599 | |
600 | QCOMPARE(playlist.media(0).request().url(), QUrl(QLatin1String("http://test.host/path" ))); |
601 | QCOMPARE(playlist.media(1).request().url(), QUrl(QLatin1String("http://test.host/path" ))); |
602 | testFileName = QFINDTESTDATA("testdata/testfile" ); |
603 | QCOMPARE(playlist.media(2).request().url(), |
604 | QUrl::fromLocalFile(testFileName)); |
605 | testFileName = QFINDTESTDATA("testdata" ); |
606 | QCOMPARE(playlist.media(3).request().url(), |
607 | QUrl::fromLocalFile(testFileName + "/testdir/testfile" )); |
608 | QCOMPARE(playlist.media(4).request().url(), QUrl(QLatin1String("file:///testdir/testfile" ))); |
609 | QCOMPARE(playlist.media(5).request().url(), QUrl(QLatin1String("file://path/name#suffix" ))); |
610 | //ensure #2 suffix is not stripped from path |
611 | testFileName = QFINDTESTDATA("testdata/testfile2#suffix" ); |
612 | QCOMPARE(playlist.media(6).request().url(), QUrl::fromLocalFile(testFileName)); |
613 | |
614 | // Try to load a totem-pl generated playlist |
615 | // (Format doesn't respect the spec) |
616 | loadSpy.clear(); |
617 | loadFailedSpy.clear(); |
618 | playlist.clear(); |
619 | testFileName = QFINDTESTDATA("testdata/totem-pl-example.pls" ); |
620 | playlist.load(location: QUrl::fromLocalFile(localfile: testFileName)); |
621 | QTRY_VERIFY(!loadSpy.isEmpty()); |
622 | QVERIFY(loadFailedSpy.isEmpty()); |
623 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
624 | QCOMPARE(playlist.mediaCount(), 1); |
625 | QCOMPARE(playlist.media(0).request().url(), QUrl(QLatin1String("http://test.host/path" ))); |
626 | |
627 | |
628 | // check ability to load from QNetworkRequest |
629 | loadSpy.clear(); |
630 | loadFailedSpy.clear(); |
631 | playlist.load(request: QNetworkRequest(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.pls" )))); |
632 | QTRY_VERIFY(!loadSpy.isEmpty()); |
633 | QVERIFY(loadFailedSpy.isEmpty()); |
634 | } |
635 | |
636 | void tst_QMediaPlaylist::playbackMode_data() |
637 | { |
638 | QTest::addColumn<QMediaPlaylist::PlaybackMode>(name: "playbackMode" ); |
639 | QTest::addColumn<int>(name: "expectedPrevious" ); |
640 | QTest::addColumn<int>(name: "pos" ); |
641 | QTest::addColumn<int>(name: "expectedNext" ); |
642 | |
643 | QTest::newRow(dataTag: "Sequential, 0" ) << QMediaPlaylist::Sequential << -1 << 0 << 1; |
644 | QTest::newRow(dataTag: "Sequential, 1" ) << QMediaPlaylist::Sequential << 0 << 1 << 2; |
645 | QTest::newRow(dataTag: "Sequential, 2" ) << QMediaPlaylist::Sequential << 1 << 2 << -1; |
646 | |
647 | QTest::newRow(dataTag: "Loop, 0" ) << QMediaPlaylist::Loop << 2 << 0 << 1; |
648 | QTest::newRow(dataTag: "Loop, 1" ) << QMediaPlaylist::Loop << 0 << 1 << 2; |
649 | QTest::newRow(dataTag: "Lopp, 2" ) << QMediaPlaylist::Loop << 1 << 2 << 0; |
650 | |
651 | QTest::newRow(dataTag: "ItemOnce, 1" ) << QMediaPlaylist::CurrentItemOnce << -1 << 1 << -1; |
652 | QTest::newRow(dataTag: "ItemInLoop, 1" ) << QMediaPlaylist::CurrentItemInLoop << 1 << 1 << 1; |
653 | |
654 | // Bit difficult to test random this way |
655 | } |
656 | |
657 | void tst_QMediaPlaylist::playbackMode() |
658 | { |
659 | QFETCH(QMediaPlaylist::PlaybackMode, playbackMode); |
660 | QFETCH(int, expectedPrevious); |
661 | QFETCH(int, pos); |
662 | QFETCH(int, expectedNext); |
663 | |
664 | QMediaPlaylist playlist; |
665 | playlist.addMedia(content: content1); |
666 | playlist.addMedia(content: content2); |
667 | playlist.addMedia(content: content3); |
668 | |
669 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Sequential); |
670 | QCOMPARE(playlist.currentIndex(), -1); |
671 | |
672 | playlist.setPlaybackMode(playbackMode); |
673 | QCOMPARE(playlist.playbackMode(), playbackMode); |
674 | |
675 | playlist.setCurrentIndex(pos); |
676 | QCOMPARE(playlist.currentIndex(), pos); |
677 | QCOMPARE(playlist.nextIndex(), expectedNext); |
678 | QCOMPARE(playlist.previousIndex(), expectedPrevious); |
679 | |
680 | playlist.next(); |
681 | QCOMPARE(playlist.currentIndex(), expectedNext); |
682 | |
683 | playlist.setCurrentIndex(pos); |
684 | playlist.previous(); |
685 | QCOMPARE(playlist.currentIndex(), expectedPrevious); |
686 | } |
687 | |
688 | void tst_QMediaPlaylist::shuffle() |
689 | { |
690 | QMediaPlaylist playlist; |
691 | QList<QMediaContent> contentList; |
692 | |
693 | for (int i=0; i<100; i++) { |
694 | QMediaContent content(QUrl::fromLocalFile(localfile: QString::number(i))); |
695 | contentList.append(t: content); |
696 | playlist.addMedia(content); |
697 | } |
698 | |
699 | playlist.shuffle(); |
700 | |
701 | QList<QMediaContent> shuffledContentList; |
702 | for (int i=0; i<playlist.mediaCount(); i++) |
703 | shuffledContentList.append(t: playlist.media(index: i)); |
704 | |
705 | QVERIFY(contentList != shuffledContentList); |
706 | |
707 | } |
708 | |
709 | void tst_QMediaPlaylist::readOnlyPlaylist() |
710 | { |
711 | MockPlaylistObject mediaObject; |
712 | mediaObject.mockService->mockControl->setReadOnly(true); |
713 | |
714 | QMediaPlaylist playlist; |
715 | mediaObject.bind(&playlist); |
716 | |
717 | QVERIFY(playlist.isReadOnly()); |
718 | QVERIFY(!playlist.isEmpty()); |
719 | QCOMPARE(playlist.mediaCount(), 3); |
720 | |
721 | QCOMPARE(playlist.media(0), content1); |
722 | QCOMPARE(playlist.media(1), content2); |
723 | QCOMPARE(playlist.media(2), content3); |
724 | QCOMPARE(playlist.media(3), QMediaContent()); |
725 | |
726 | //it's a read only playlist, so all the modification should fail |
727 | QVERIFY(!playlist.addMedia(content1)); |
728 | QCOMPARE(playlist.mediaCount(), 3); |
729 | QVERIFY(!playlist.addMedia(QList<QMediaContent>() << content1 << content2)); |
730 | QCOMPARE(playlist.mediaCount(), 3); |
731 | QVERIFY(!playlist.insertMedia(1, content1)); |
732 | QCOMPARE(playlist.mediaCount(), 3); |
733 | QVERIFY(!playlist.insertMedia(1, QList<QMediaContent>() << content1 << content2)); |
734 | QCOMPARE(playlist.mediaCount(), 3); |
735 | QVERIFY(!playlist.removeMedia(1)); |
736 | QCOMPARE(playlist.mediaCount(), 3); |
737 | QVERIFY(!playlist.removeMedia(0,2)); |
738 | QCOMPARE(playlist.mediaCount(), 3); |
739 | QVERIFY(!playlist.clear()); |
740 | QCOMPARE(playlist.mediaCount(), 3); |
741 | |
742 | //but it is still allowed to append/insert an empty list |
743 | QVERIFY(playlist.addMedia(QList<QMediaContent>())); |
744 | QVERIFY(playlist.insertMedia(1, QList<QMediaContent>())); |
745 | |
746 | playlist.shuffle(); |
747 | //it's still the same |
748 | QCOMPARE(playlist.media(0), content1); |
749 | QCOMPARE(playlist.media(1), content2); |
750 | QCOMPARE(playlist.media(2), content3); |
751 | QCOMPARE(playlist.media(3), QMediaContent()); |
752 | |
753 | |
754 | //load to read only playlist should fail, |
755 | //unless underlaying provider supports it |
756 | QBuffer buffer; |
757 | buffer.open(openMode: QBuffer::ReadWrite); |
758 | buffer.write(data: QByteArray("file:///1\nfile:///2" )); |
759 | buffer.seek(off: 0); |
760 | |
761 | QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed())); |
762 | playlist.load(device: &buffer, format: "m3u" ); |
763 | QCOMPARE(errorSignal.size(), 1); |
764 | QCOMPARE(playlist.error(), QMediaPlaylist::AccessDeniedError); |
765 | QVERIFY(!playlist.errorString().isEmpty()); |
766 | QCOMPARE(playlist.mediaCount(), 3); |
767 | |
768 | errorSignal.clear(); |
769 | playlist.load(location: QUrl::fromLocalFile(localfile: QLatin1String("tmp.m3u" )), format: "m3u" ); |
770 | |
771 | QCOMPARE(errorSignal.size(), 1); |
772 | QCOMPARE(playlist.error(), QMediaPlaylist::AccessDeniedError); |
773 | QVERIFY(!playlist.errorString().isEmpty()); |
774 | QCOMPARE(playlist.mediaCount(), 3); |
775 | } |
776 | |
777 | void tst_QMediaPlaylist::setMediaObject() |
778 | { |
779 | QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3" ))); |
780 | QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3" ))); |
781 | QMediaContent content2(QUrl(QLatin1String("test://video/movie1.mp4" ))); |
782 | QMediaContent content3(QUrl(QLatin1String("test://video/movie2.mp4" ))); |
783 | |
784 | { |
785 | MockPlaylistObject mediaObject; |
786 | |
787 | QMediaPlaylist playlist; |
788 | QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int))); |
789 | QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); |
790 | QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int))); |
791 | QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int))); |
792 | QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int))); |
793 | QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int))); |
794 | QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int))); |
795 | |
796 | QVERIFY(playlist.isEmpty()); |
797 | |
798 | mediaObject.bind(&playlist); |
799 | |
800 | // Playlist is now using the service's control, nothing should have changed |
801 | QVERIFY(playlist.isEmpty()); |
802 | QCOMPARE(playlist.currentIndex(), -1); |
803 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Sequential); |
804 | QCOMPARE(currentIndexSpy.count(), 0); |
805 | QCOMPARE(playbackModeSpy.count(), 0); |
806 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
807 | QCOMPARE(mediaInsertedSpy.count(), 0); |
808 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
809 | QCOMPARE(mediaRemovedSpy.count(), 0); |
810 | QCOMPARE(mediaChangedSpy.count(), 0); |
811 | |
812 | // add items to service's playlist control |
813 | playlist.addMedia(content: content0); |
814 | playlist.addMedia(content: content1); |
815 | playlist.setCurrentIndex(1); |
816 | playlist.setPlaybackMode(QMediaPlaylist::Random); |
817 | QCOMPARE(playlist.mediaCount(), 2); |
818 | QCOMPARE(playlist.currentIndex(), 1); |
819 | QCOMPARE(playlist.currentMedia(), content1); |
820 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Random); |
821 | |
822 | currentIndexSpy.clear(); |
823 | playbackModeSpy.clear(); |
824 | mediaAboutToBeInsertedSpy.clear(); |
825 | mediaInsertedSpy.clear(); |
826 | mediaAboutToBeRemovedSpy.clear(); |
827 | mediaRemovedSpy.clear(); |
828 | mediaChangedSpy.clear(); |
829 | |
830 | // unbind the playlist, reverting back to the internal control. |
831 | // playlist content should't have changed. |
832 | mediaObject.unbind(&playlist); |
833 | QCOMPARE(playlist.mediaCount(), 2); |
834 | QCOMPARE(playlist.currentIndex(), 1); |
835 | QCOMPARE(playlist.currentMedia(), content1); |
836 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Random); |
837 | QCOMPARE(playbackModeSpy.count(), 0); |
838 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
839 | QCOMPARE(mediaInsertedSpy.count(), 0); |
840 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
841 | QCOMPARE(mediaRemovedSpy.count(), 0); |
842 | QCOMPARE(mediaChangedSpy.count(), 0); |
843 | } |
844 | { |
845 | MockPlaylistObject mediaObject; |
846 | |
847 | QMediaPlaylist playlist; |
848 | QVERIFY(playlist.isEmpty()); |
849 | // Add items to playlist before binding to the service (internal control) |
850 | playlist.addMedia(content: content0); |
851 | playlist.addMedia(content: content1); |
852 | playlist.addMedia(content: content2); |
853 | playlist.setCurrentIndex(2); |
854 | playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce); |
855 | |
856 | QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int))); |
857 | QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); |
858 | QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int))); |
859 | QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int))); |
860 | QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int))); |
861 | QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int))); |
862 | QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int))); |
863 | |
864 | // Bind playlist, content should be unchanged |
865 | mediaObject.bind(&playlist); |
866 | QCOMPARE(playlist.mediaCount(), 3); |
867 | QCOMPARE(playlist.currentIndex(), 2); |
868 | QCOMPARE(playlist.currentMedia(), content2); |
869 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce); |
870 | QCOMPARE(currentIndexSpy.count(), 0); |
871 | QCOMPARE(playbackModeSpy.count(), 0); |
872 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
873 | QCOMPARE(mediaInsertedSpy.count(), 0); |
874 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
875 | QCOMPARE(mediaRemovedSpy.count(), 0); |
876 | QCOMPARE(mediaChangedSpy.count(), 0); |
877 | |
878 | // Clear playlist content (service's playlist control) |
879 | playlist.clear(); |
880 | playlist.setCurrentIndex(-1); |
881 | playlist.setPlaybackMode(QMediaPlaylist::Random); |
882 | |
883 | currentIndexSpy.clear(); |
884 | playbackModeSpy.clear(); |
885 | mediaAboutToBeInsertedSpy.clear(); |
886 | mediaInsertedSpy.clear(); |
887 | mediaAboutToBeRemovedSpy.clear(); |
888 | mediaRemovedSpy.clear(); |
889 | mediaChangedSpy.clear(); |
890 | |
891 | // unbind playlist from service, reverting back to the internal control. |
892 | // playlist should still be empty |
893 | mediaObject.unbind(&playlist); |
894 | QCOMPARE(playlist.mediaCount(), 0); |
895 | QCOMPARE(playlist.currentIndex(), -1); |
896 | QCOMPARE(playlist.currentMedia(), QMediaContent()); |
897 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Random); |
898 | QCOMPARE(playbackModeSpy.count(), 0); |
899 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
900 | QCOMPARE(mediaInsertedSpy.count(), 0); |
901 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
902 | QCOMPARE(mediaRemovedSpy.count(), 0); |
903 | QCOMPARE(mediaChangedSpy.count(), 0); |
904 | } |
905 | { |
906 | MockPlaylistObject mediaObject; |
907 | |
908 | QMediaPlaylist playlist; |
909 | QVERIFY(playlist.isEmpty()); |
910 | // Add items to playlist before attaching to media player (internal control) |
911 | playlist.addMedia(content: content0); |
912 | playlist.addMedia(content: content1); |
913 | playlist.setCurrentIndex(-1); |
914 | playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce); |
915 | |
916 | // Add items to service's playlist before binding |
917 | QMediaPlaylistProvider *pp = mediaObject.mockService->mockControl->playlistProvider(); |
918 | pp->addMedia(content: content2); |
919 | pp->addMedia(content: content3); |
920 | mediaObject.mockService->mockControl->setCurrentIndex(1); |
921 | mediaObject.mockService->mockControl->setPlaybackMode(QMediaPlaylist::Random); |
922 | |
923 | QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int))); |
924 | QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); |
925 | QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int))); |
926 | QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int))); |
927 | QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int))); |
928 | QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int))); |
929 | QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int))); |
930 | |
931 | // Bind playlist, it should contain only what was explicitly added to the playlist. |
932 | // Anything that was present in the service's control should have been cleared |
933 | mediaObject.bind(&playlist); |
934 | QCOMPARE(playlist.mediaCount(), 2); |
935 | QCOMPARE(playlist.currentIndex(), -1); |
936 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce); |
937 | QCOMPARE(currentIndexSpy.count(), 0); |
938 | QCOMPARE(playbackModeSpy.count(), 0); |
939 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
940 | QCOMPARE(mediaInsertedSpy.count(), 0); |
941 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
942 | QCOMPARE(mediaRemovedSpy.count(), 0); |
943 | QCOMPARE(mediaChangedSpy.count(), 0); |
944 | |
945 | // do some changes |
946 | playlist.removeMedia(pos: 0); // content0 |
947 | playlist.addMedia(content: content3); |
948 | playlist.setCurrentIndex(0); |
949 | |
950 | currentIndexSpy.clear(); |
951 | playbackModeSpy.clear(); |
952 | mediaAboutToBeInsertedSpy.clear(); |
953 | mediaInsertedSpy.clear(); |
954 | mediaAboutToBeRemovedSpy.clear(); |
955 | mediaRemovedSpy.clear(); |
956 | mediaChangedSpy.clear(); |
957 | |
958 | // unbind playlist from service |
959 | mediaObject.unbind(&playlist); |
960 | QCOMPARE(playlist.mediaCount(), 2); |
961 | QCOMPARE(playlist.currentIndex(), 0); |
962 | QCOMPARE(playlist.currentMedia(), content1); |
963 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce); |
964 | QCOMPARE(currentIndexSpy.count(), 0); |
965 | QCOMPARE(playbackModeSpy.count(), 0); |
966 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
967 | QCOMPARE(mediaInsertedSpy.count(), 0); |
968 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
969 | QCOMPARE(mediaRemovedSpy.count(), 0); |
970 | QCOMPARE(mediaChangedSpy.count(), 0); |
971 | |
972 | // bind again, nothing should have changed |
973 | mediaObject.bind(&playlist); |
974 | QCOMPARE(playlist.mediaCount(), 2); |
975 | QCOMPARE(playlist.currentIndex(), 0); |
976 | QCOMPARE(playlist.currentMedia(), content1); |
977 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce); |
978 | QCOMPARE(currentIndexSpy.count(), 0); |
979 | QCOMPARE(playbackModeSpy.count(), 0); |
980 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
981 | QCOMPARE(mediaInsertedSpy.count(), 0); |
982 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
983 | QCOMPARE(mediaRemovedSpy.count(), 0); |
984 | QCOMPARE(mediaChangedSpy.count(), 0); |
985 | } |
986 | { |
987 | MockPlaylistObject mediaObject; |
988 | mediaObject.mockService->mockControl->setReadOnly(true); |
989 | |
990 | QMediaPlaylist playlist; |
991 | QVERIFY(playlist.isEmpty()); |
992 | // Add items to playlist before binding to the service internal control) |
993 | playlist.addMedia(content: content0); |
994 | playlist.addMedia(content: content1); |
995 | playlist.setCurrentIndex(-1); |
996 | playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce); |
997 | |
998 | QSignalSpy currentIndexSpy(&playlist, SIGNAL(currentIndexChanged(int))); |
999 | QSignalSpy playbackModeSpy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); |
1000 | QSignalSpy mediaAboutToBeInsertedSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int, int))); |
1001 | QSignalSpy mediaInsertedSpy(&playlist, SIGNAL(mediaInserted(int, int))); |
1002 | QSignalSpy mediaAboutToBeRemovedSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int, int))); |
1003 | QSignalSpy mediaRemovedSpy(&playlist, SIGNAL(mediaRemoved(int, int))); |
1004 | QSignalSpy mediaChangedSpy(&playlist, SIGNAL(mediaChanged(int, int))); |
1005 | |
1006 | // Bind playlist. Since the service's control is read-only, no synchronization |
1007 | // should be done with the internal control. The mediaRemoved() and mediaInserted() |
1008 | // should be emitted to notify about the change. |
1009 | mediaObject.bind(&playlist); |
1010 | QCOMPARE(playlist.mediaCount(), 3); |
1011 | QCOMPARE(playlist.currentIndex(), -1); |
1012 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce); |
1013 | QCOMPARE(currentIndexSpy.count(), 0); |
1014 | QCOMPARE(playbackModeSpy.count(), 0); |
1015 | |
1016 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 1); |
1017 | QCOMPARE(mediaAboutToBeRemovedSpy.last().at(0).toInt(), 0); |
1018 | QCOMPARE(mediaAboutToBeRemovedSpy.last().at(1).toInt(), 1); |
1019 | QCOMPARE(mediaRemovedSpy.count(), 1); |
1020 | QCOMPARE(mediaRemovedSpy.last().at(0).toInt(), 0); |
1021 | QCOMPARE(mediaRemovedSpy.last().at(1).toInt(), 1); |
1022 | |
1023 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 1); |
1024 | QCOMPARE(mediaAboutToBeInsertedSpy.last().at(0).toInt(), 0); |
1025 | QCOMPARE(mediaAboutToBeInsertedSpy.last().at(1).toInt(), 2); |
1026 | QCOMPARE(mediaInsertedSpy.count(), 1); |
1027 | QCOMPARE(mediaInsertedSpy.last().at(0).toInt(), 0); |
1028 | QCOMPARE(mediaInsertedSpy.last().at(1).toInt(), 2); |
1029 | |
1030 | QCOMPARE(mediaChangedSpy.count(), 0); |
1031 | |
1032 | currentIndexSpy.clear(); |
1033 | playbackModeSpy.clear(); |
1034 | mediaAboutToBeInsertedSpy.clear(); |
1035 | mediaInsertedSpy.clear(); |
1036 | mediaAboutToBeRemovedSpy.clear(); |
1037 | mediaRemovedSpy.clear(); |
1038 | mediaChangedSpy.clear(); |
1039 | |
1040 | // detach playlist from player |
1041 | mediaObject.unbind(&playlist); |
1042 | QCOMPARE(playlist.mediaCount(), 3); |
1043 | QCOMPARE(playlist.currentIndex(), -1); |
1044 | QCOMPARE(playlist.playbackMode(), QMediaPlaylist::CurrentItemOnce); |
1045 | QCOMPARE(currentIndexSpy.count(), 0); |
1046 | QCOMPARE(playbackModeSpy.count(), 0); |
1047 | QCOMPARE(mediaAboutToBeInsertedSpy.count(), 0); |
1048 | QCOMPARE(mediaInsertedSpy.count(), 0); |
1049 | QCOMPARE(mediaAboutToBeRemovedSpy.count(), 0); |
1050 | QCOMPARE(mediaRemovedSpy.count(), 0); |
1051 | QCOMPARE(mediaChangedSpy.count(), 0); |
1052 | } |
1053 | } |
1054 | |
1055 | void tst_QMediaPlaylist::testCurrentIndexChanged_signal() |
1056 | { |
1057 | //create an instance of QMediaPlaylist class. |
1058 | QMediaPlaylist playlist; |
1059 | playlist.addMedia(content: content1); //set the media to playlist |
1060 | playlist.addMedia(content: content2); //set the media to playlist |
1061 | |
1062 | QSignalSpy spy(&playlist, SIGNAL(currentIndexChanged(int))); |
1063 | QVERIFY(spy.size()== 0); |
1064 | QCOMPARE(playlist.currentIndex(), -1); |
1065 | |
1066 | //set the current index for playlist. |
1067 | playlist.setCurrentIndex(0); |
1068 | QVERIFY(spy.size()== 1); //verify the signal emission. |
1069 | QCOMPARE(playlist.currentIndex(), 0); //verify the current index of playlist |
1070 | |
1071 | //set the current index for playlist. |
1072 | playlist.setCurrentIndex(1); |
1073 | QVERIFY(spy.size()== 2); //verify the signal emission. |
1074 | QCOMPARE(playlist.currentIndex(), 1); //verify the current index of playlist |
1075 | } |
1076 | |
1077 | void tst_QMediaPlaylist::testCurrentMediaChanged_signal() |
1078 | { |
1079 | //create an instance of QMediaPlaylist class. |
1080 | QMediaPlaylist playlist; |
1081 | playlist.addMedia(content: content1); //set the media to playlist |
1082 | playlist.addMedia(content: content2); //set the media to playlist |
1083 | |
1084 | QSignalSpy spy(&playlist, SIGNAL(currentMediaChanged(QMediaContent))); |
1085 | QVERIFY(spy.size()== 0); |
1086 | QCOMPARE(playlist.currentIndex(), -1); |
1087 | QCOMPARE(playlist.currentMedia(), QMediaContent()); |
1088 | |
1089 | //set the current index for playlist. |
1090 | playlist.setCurrentIndex(0); |
1091 | QVERIFY(spy.size()== 1); //verify the signal emission. |
1092 | QCOMPARE(playlist.currentIndex(), 0); //verify the current index of playlist |
1093 | QCOMPARE(playlist.currentMedia(), content1); //verify the current media of playlist |
1094 | |
1095 | //set the current index for playlist. |
1096 | playlist.setCurrentIndex(1); |
1097 | QVERIFY(spy.size()== 2); //verify the signal emission. |
1098 | QCOMPARE(playlist.currentIndex(), 1); //verify the current index of playlist |
1099 | QCOMPARE(playlist.currentMedia(), content2); //verify the current media of playlist |
1100 | } |
1101 | |
1102 | void tst_QMediaPlaylist::testLoaded_signal() |
1103 | { |
1104 | //create an instance of QMediaPlaylist class. |
1105 | QMediaPlaylist playlist; |
1106 | playlist.addMedia(content: content1); //set the media to playlist |
1107 | playlist.addMedia(content: content2); //set the media to playlist |
1108 | playlist.addMedia(content: content3); //set the media to playlist |
1109 | |
1110 | QSignalSpy spy(&playlist, SIGNAL(loaded())); |
1111 | QVERIFY(spy.size()== 0); |
1112 | |
1113 | QBuffer buffer; |
1114 | buffer.open(openMode: QBuffer::ReadWrite); |
1115 | |
1116 | //load the playlist |
1117 | playlist.load(device: &buffer,format: "m3u" ); |
1118 | QVERIFY(spy.size()== 1); //verify the signal emission. |
1119 | } |
1120 | |
1121 | void tst_QMediaPlaylist::testMediaChanged_signal() |
1122 | { |
1123 | //create an instance of QMediaPlaylist class. |
1124 | QMediaPlaylist playlist; |
1125 | |
1126 | QSignalSpy spy(&playlist, SIGNAL(mediaChanged(int,int))); |
1127 | |
1128 | // Add media to playlist |
1129 | playlist.addMedia(content: content1); //set the media to playlist |
1130 | playlist.addMedia(content: content2); //set the media to playlist |
1131 | playlist.addMedia(content: content3); //set the media to playlist |
1132 | |
1133 | // Adds/inserts do not cause change signals |
1134 | QVERIFY(spy.size() == 0); |
1135 | |
1136 | // Now change the list |
1137 | playlist.shuffle(); |
1138 | |
1139 | QVERIFY(spy.size() == 1); |
1140 | spy.clear(); |
1141 | |
1142 | //create media. |
1143 | QMediaContent content4(QUrl(QLatin1String("file:///4" ))); |
1144 | QMediaContent content5(QUrl(QLatin1String("file:///5" ))); |
1145 | |
1146 | //insert media to playlist |
1147 | playlist.insertMedia(index: 1, content: content4); |
1148 | playlist.insertMedia(index: 2, content: content5); |
1149 | // Adds/inserts do not cause change signals |
1150 | QVERIFY(spy.size() == 0); |
1151 | |
1152 | // And again |
1153 | playlist.shuffle(); |
1154 | |
1155 | QVERIFY(spy.size() == 1); |
1156 | } |
1157 | |
1158 | void tst_QMediaPlaylist::testPlaybackModeChanged_signal() |
1159 | { |
1160 | //create an instance of QMediaPlaylist class. |
1161 | QMediaPlaylist playlist; |
1162 | playlist.addMedia(content: content1); //set the media to playlist |
1163 | playlist.addMedia(content: content2); //set the media to playlist |
1164 | playlist.addMedia(content: content3); //set the media to playlist |
1165 | |
1166 | QSignalSpy spy(&playlist, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); |
1167 | QVERIFY(playlist.playbackMode()== QMediaPlaylist::Sequential); |
1168 | QVERIFY(spy.size() == 0); |
1169 | |
1170 | // Set playback mode to the playlist |
1171 | playlist.setPlaybackMode(QMediaPlaylist::CurrentItemOnce); |
1172 | QVERIFY(playlist.playbackMode()== QMediaPlaylist::CurrentItemOnce); |
1173 | QVERIFY(spy.size() == 1); |
1174 | |
1175 | // Set playback mode to the playlist |
1176 | playlist.setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); |
1177 | QVERIFY(playlist.playbackMode()== QMediaPlaylist::CurrentItemInLoop); |
1178 | QVERIFY(spy.size() == 2); |
1179 | |
1180 | // Set playback mode to the playlist |
1181 | playlist.setPlaybackMode(QMediaPlaylist::Sequential); |
1182 | QVERIFY(playlist.playbackMode()== QMediaPlaylist::Sequential); |
1183 | QVERIFY(spy.size() == 3); |
1184 | |
1185 | // Set playback mode to the playlist |
1186 | playlist.setPlaybackMode(QMediaPlaylist::Loop); |
1187 | QVERIFY(playlist.playbackMode()== QMediaPlaylist::Loop); |
1188 | QVERIFY(spy.size() == 4); |
1189 | |
1190 | // Set playback mode to the playlist |
1191 | playlist.setPlaybackMode(QMediaPlaylist::Random); |
1192 | QVERIFY(playlist.playbackMode()== QMediaPlaylist::Random); |
1193 | QVERIFY(spy.size() == 5); |
1194 | } |
1195 | |
1196 | void tst_QMediaPlaylist::testEnums() |
1197 | { |
1198 | //create an instance of QMediaPlaylist class. |
1199 | QMediaPlaylist playlist; |
1200 | playlist.addMedia(content: content1); //set the media to playlist |
1201 | playlist.addMedia(content: content2); //set the media to playlist |
1202 | playlist.addMedia(content: content3); //set the media to playlist |
1203 | QCOMPARE(playlist.error(), QMediaPlaylist::NoError); |
1204 | |
1205 | QBuffer buffer; |
1206 | buffer.open(openMode: QBuffer::ReadWrite); |
1207 | |
1208 | // checking for QMediaPlaylist::FormatNotSupportedError enum |
1209 | QVERIFY(!playlist.save(&buffer, "unsupported_format" )); |
1210 | QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError); |
1211 | |
1212 | playlist.load(device: &buffer,format: "unsupported_format" ); |
1213 | QVERIFY(playlist.error() == QMediaPlaylist::FormatNotSupportedError); |
1214 | } |
1215 | |
1216 | // MaemoAPI-1849:test QMediaPlayListControl constructor |
1217 | void tst_QMediaPlaylist::mediaPlayListControl() |
1218 | { |
1219 | // To check changes in abstract classe's pure virtual functions |
1220 | QObject parent; |
1221 | MockMediaPlaylistControl plylistctrl(false, &parent); |
1222 | } |
1223 | |
1224 | // MaemoAPI-1850:test QMediaPlayListSourceControl constructor |
1225 | void tst_QMediaPlaylist::mediaPlayListSourceControl() |
1226 | { |
1227 | // To check changes in abstract classe's pure virtual functions |
1228 | QObject parent; |
1229 | MockPlaylistSourceControl plylistsrcctrl(&parent); |
1230 | } |
1231 | |
1232 | // MaemoAPI-1852:test constructor |
1233 | void tst_QMediaPlaylist::mediaPlayListProvider() |
1234 | { |
1235 | // srcs of QMediaPlaylistProvider is incomplete |
1236 | QObject parent; |
1237 | MockReadOnlyPlaylistProvider provider(&parent); |
1238 | } |
1239 | |
1240 | QTEST_MAIN(tst_QMediaPlaylist) |
1241 | #include "tst_qmediaplaylist.moc" |
1242 | |
1243 | |