1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | #include <QtTest/QtTest> |
29 | #include <QtTest/QSignalSpy> |
30 | #include <QtQml/qqmlengine.h> |
31 | #include <QtQml/qqmlcomponent.h> |
32 | #include <QtCore/qdir.h> |
33 | #include <QtCore/qfile.h> |
34 | #include <QtCore/qabstractitemmodel.h> |
35 | #include <QDebug> |
36 | #include "../../shared/util.h" |
37 | |
38 | #if defined (Q_OS_WIN) |
39 | #include <qt_windows.h> |
40 | #endif |
41 | |
42 | // From qquickfolderlistmodel.h |
43 | const int FileNameRole = Qt::UserRole+1; |
44 | enum SortField { Unsorted, Name, Time, Size, Type }; |
45 | enum Status { Null, Ready, Loading }; |
46 | |
47 | class tst_qquickfolderlistmodel : public QQmlDataTest |
48 | { |
49 | Q_OBJECT |
50 | public: |
51 | tst_qquickfolderlistmodel() {} |
52 | |
53 | public slots: |
54 | void removed(const QModelIndex &, int start, int end) { |
55 | removeStart = start; |
56 | removeEnd = end; |
57 | } |
58 | |
59 | private slots: |
60 | void initTestCase(); |
61 | void basicProperties(); |
62 | void status(); |
63 | void showFiles(); |
64 | void resetFiltering(); |
65 | void nameFilters(); |
66 | void refresh(); |
67 | void cdUp(); |
68 | #ifdef Q_OS_WIN32 |
69 | // WinCE/WinRT do not have drive APIs, so let's execute this test only on desktop Windows. |
70 | void changeDrive(); |
71 | #endif |
72 | void showDotAndDotDot(); |
73 | void showDotAndDotDot_data(); |
74 | void sortReversed(); |
75 | void introspectQrc(); |
76 | void sortCaseSensitive_data(); |
77 | void sortCaseSensitive(); |
78 | void updateProperties(); |
79 | void importBothVersions(); |
80 | private: |
81 | void checkNoErrors(const QQmlComponent& component); |
82 | QQmlEngine engine; |
83 | |
84 | int removeStart = 0; |
85 | int removeEnd = 0; |
86 | }; |
87 | |
88 | void tst_qquickfolderlistmodel::checkNoErrors(const QQmlComponent& component) |
89 | { |
90 | // Wait until the component is ready |
91 | QTRY_VERIFY(component.isReady() || component.isError()); |
92 | |
93 | if (component.isError()) { |
94 | QList<QQmlError> errors = component.errors(); |
95 | for (int ii = 0; ii < errors.count(); ++ii) { |
96 | const QQmlError &error = errors.at(i: ii); |
97 | QByteArray errorStr = QByteArray::number(error.line()) + ':' + |
98 | QByteArray::number(error.column()) + ':' + |
99 | error.description().toUtf8(); |
100 | qWarning() << errorStr; |
101 | } |
102 | } |
103 | QVERIFY(!component.isError()); |
104 | } |
105 | |
106 | void tst_qquickfolderlistmodel::initTestCase() |
107 | { |
108 | // The tests rely on a fixed number of files in the directory with the qml files |
109 | // (the data dir), so disable the disk cache to avoid creating .qmlc files and |
110 | // confusing the test. |
111 | qputenv(varName: "QML_DISABLE_DISK_CACHE" , value: "1" ); |
112 | QQmlDataTest::initTestCase(); |
113 | } |
114 | |
115 | void tst_qquickfolderlistmodel::basicProperties() |
116 | { |
117 | #ifdef Q_OS_ANDROID |
118 | QSKIP("[QTBUG-77335] Initial folder of FolderListModel on Android does not work properly," |
119 | " and from there on it is unreliable to change the folder" ); |
120 | #endif |
121 | QQmlComponent component(&engine, testFileUrl(fileName: "basic.qml" )); |
122 | checkNoErrors(component); |
123 | |
124 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
125 | QVERIFY(flm != nullptr); |
126 | QCOMPARE(flm->property("nameFilters" ).toStringList(), QStringList() << "*.qml" ); // from basic.qml |
127 | QCOMPARE(flm->property("folder" ).toUrl(), QUrl::fromLocalFile(QDir::currentPath())); |
128 | |
129 | // wait for the initial directory listing (it will find at least the "data" dir, |
130 | // and other dirs on Windows). |
131 | QTRY_VERIFY(flm->property("count" ).toInt() > 0); |
132 | |
133 | QSignalSpy folderChangedSpy(flm, SIGNAL(folderChanged())); |
134 | flm->setProperty(name: "folder" , value: dataDirectoryUrl()); |
135 | QVERIFY(folderChangedSpy.wait()); |
136 | QCOMPARE(flm->property("count" ).toInt(), 9); |
137 | QCOMPARE(flm->property("folder" ).toUrl(), dataDirectoryUrl()); |
138 | QCOMPARE(flm->property("parentFolder" ).toUrl(), QUrl::fromLocalFile(QDir(directory()).canonicalPath())); |
139 | QCOMPARE(flm->property("sortField" ).toInt(), int(Name)); |
140 | QCOMPARE(flm->property("nameFilters" ).toStringList(), QStringList() << "*.qml" ); |
141 | QCOMPARE(flm->property("sortReversed" ).toBool(), false); |
142 | QCOMPARE(flm->property("showFiles" ).toBool(), true); |
143 | QCOMPARE(flm->property("showDirs" ).toBool(), true); |
144 | QCOMPARE(flm->property("showDotAndDotDot" ).toBool(), false); |
145 | QCOMPARE(flm->property("showOnlyReadable" ).toBool(), false); |
146 | QCOMPARE(flm->data(flm->index(0),FileNameRole).toString(), QLatin1String("basic.qml" )); |
147 | QCOMPARE(flm->data(flm->index(1),FileNameRole).toString(), QLatin1String("dummy.qml" )); |
148 | |
149 | flm->setProperty(name: "folder" ,value: QUrl::fromLocalFile(localfile: "" )); |
150 | QCOMPARE(flm->property("folder" ).toUrl(), QUrl::fromLocalFile("" )); |
151 | } |
152 | |
153 | void tst_qquickfolderlistmodel::status() |
154 | { |
155 | QQmlComponent component(&engine, testFileUrl(fileName: "basic.qml" )); |
156 | checkNoErrors(component); |
157 | |
158 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
159 | QVERIFY(flm != nullptr); |
160 | QTRY_COMPARE(flm->property("status" ).toInt(), int(Ready)); |
161 | flm->setProperty(name: "folder" , value: QUrl::fromLocalFile(localfile: "" )); |
162 | QTRY_COMPARE(flm->property("status" ).toInt(), int(Null)); |
163 | flm->setProperty(name: "folder" , value: QUrl::fromLocalFile(localfile: QDir::currentPath())); |
164 | QTRY_COMPARE(flm->property("status" ).toInt(), int(Ready)); |
165 | } |
166 | |
167 | void tst_qquickfolderlistmodel::showFiles() |
168 | { |
169 | QQmlComponent component(&engine, testFileUrl(fileName: "basic.qml" )); |
170 | checkNoErrors(component); |
171 | |
172 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
173 | QVERIFY(flm != nullptr); |
174 | |
175 | flm->setProperty(name: "folder" , value: dataDirectoryUrl()); |
176 | QTRY_COMPARE(flm->property("count" ).toInt(), 9); // wait for refresh |
177 | QCOMPARE(flm->property("showFiles" ).toBool(), true); |
178 | |
179 | flm->setProperty(name: "showFiles" , value: false); |
180 | QCOMPARE(flm->property("showFiles" ).toBool(), false); |
181 | QTRY_COMPARE(flm->property("count" ).toInt(), 3); // wait for refresh |
182 | } |
183 | |
184 | void tst_qquickfolderlistmodel::resetFiltering() |
185 | { |
186 | // see QTBUG-17837 |
187 | QQmlComponent component(&engine, testFileUrl(fileName: "resetFiltering.qml" )); |
188 | checkNoErrors(component); |
189 | |
190 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
191 | QVERIFY(flm != nullptr); |
192 | |
193 | flm->setProperty(name: "folder" , value: testFileUrl(fileName: "resetfiltering" )); |
194 | // _q_directoryUpdated may be triggered if model was empty before, but there won't be a rowsRemoved signal |
195 | QTRY_COMPARE(flm->property("count" ).toInt(),3); // all files visible |
196 | |
197 | flm->setProperty(name: "folder" , value: testFileUrl(fileName: "resetfiltering/innerdir" )); |
198 | // _q_directoryChanged is triggered so it's a total model refresh |
199 | QTRY_COMPARE(flm->property("count" ).toInt(),1); // should just be "test2.txt" visible |
200 | |
201 | flm->setProperty(name: "folder" , value: testFileUrl(fileName: "resetfiltering" )); |
202 | // _q_directoryChanged is triggered so it's a total model refresh |
203 | QTRY_COMPARE(flm->property("count" ).toInt(),3); // all files visible |
204 | } |
205 | |
206 | void tst_qquickfolderlistmodel::nameFilters() |
207 | { |
208 | // see QTBUG-36576 |
209 | QQmlComponent component(&engine, testFileUrl(fileName: "resetFiltering.qml" )); |
210 | checkNoErrors(component); |
211 | |
212 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
213 | QVERIFY(flm != nullptr); |
214 | |
215 | connect(sender: flm, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
216 | receiver: this, SLOT(removed(QModelIndex,int,int))); |
217 | |
218 | QTRY_VERIFY(flm->rowCount() > 0); |
219 | flm->setProperty(name: "folder" , value: testFileUrl(fileName: "resetfiltering" )); |
220 | QTRY_COMPARE(flm->property("count" ).toInt(),3); // all files visible |
221 | |
222 | int count = flm->rowCount(); |
223 | flm->setProperty(name: "nameFilters" , value: QStringList() << "*.txt" ); |
224 | // _q_directoryUpdated triggered with range 0:1 |
225 | QTRY_COMPARE(flm->property("count" ).toInt(),1); |
226 | QCOMPARE(flm->data(flm->index(0),FileNameRole), QVariant("test.txt" )); |
227 | QCOMPARE(removeStart, 0); |
228 | QCOMPARE(removeEnd, count-1); |
229 | |
230 | flm->setProperty(name: "nameFilters" , value: QStringList() << "*.html" ); |
231 | QTRY_COMPARE(flm->property("count" ).toInt(),2); |
232 | QCOMPARE(flm->data(flm->index(0),FileNameRole), QVariant("test1.html" )); |
233 | QCOMPARE(flm->data(flm->index(1),FileNameRole), QVariant("test2.html" )); |
234 | |
235 | flm->setProperty(name: "nameFilters" , value: QStringList()); |
236 | QTRY_COMPARE(flm->property("count" ).toInt(),3); // all files visible |
237 | } |
238 | |
239 | void tst_qquickfolderlistmodel::refresh() |
240 | { |
241 | QQmlComponent component(&engine, testFileUrl(fileName: "basic.qml" )); |
242 | checkNoErrors(component); |
243 | |
244 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
245 | QVERIFY(flm != nullptr); |
246 | |
247 | flm->setProperty(name: "folder" , value: dataDirectoryUrl()); |
248 | QTRY_COMPARE(flm->property("count" ).toInt(), 9); // wait for refresh |
249 | |
250 | int count = flm->rowCount(); |
251 | |
252 | connect(sender: flm, SIGNAL(rowsRemoved(QModelIndex,int,int)), |
253 | receiver: this, SLOT(removed(QModelIndex,int,int))); |
254 | |
255 | flm->setProperty(name: "sortReversed" , value: true); |
256 | |
257 | QTRY_COMPARE(removeStart, 0); |
258 | QTRY_COMPARE(removeEnd, count-1); // wait for refresh |
259 | } |
260 | |
261 | void tst_qquickfolderlistmodel::cdUp() |
262 | { |
263 | enum { maxIterations = 50 }; |
264 | QQmlComponent component(&engine, testFileUrl(fileName: "basic.qml" )); |
265 | checkNoErrors(component); |
266 | |
267 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
268 | QVERIFY(flm != nullptr); |
269 | const QUrl startFolder = flm->property(name: "folder" ).toUrl(); |
270 | QVERIFY(startFolder.isValid()); |
271 | |
272 | // QTBUG-32139: Ensure navigating upwards terminates cleanly and does not |
273 | // return invalid Urls like "file:". |
274 | for (int i = 0; ; ++i) { |
275 | const QVariant folderV = flm->property(name: "parentFolder" ); |
276 | const QUrl folder = folderV.toUrl(); |
277 | if (!folder.isValid()) |
278 | break; |
279 | QVERIFY(folder.toString() != QLatin1String("file:" )); |
280 | QVERIFY2(i < maxIterations, |
281 | qPrintable(QString::fromLatin1("Unable to reach root after %1 iterations starting from %2, stuck at %3" ) |
282 | .arg(maxIterations).arg(QDir::toNativeSeparators(startFolder.toLocalFile()), |
283 | QDir::toNativeSeparators(folder.toLocalFile())))); |
284 | flm->setProperty(name: "folder" , value: folderV); |
285 | } |
286 | } |
287 | |
288 | #ifdef Q_OS_WIN32 |
289 | void tst_qquickfolderlistmodel::changeDrive() |
290 | { |
291 | QSKIP("QTBUG-26728" ); |
292 | class DriveMapper |
293 | { |
294 | public: |
295 | DriveMapper(const QString &dataDir) |
296 | { |
297 | size_t stringLen = dataDir.length(); |
298 | targetPath = new wchar_t[stringLen+1]; |
299 | dataDir.toWCharArray(targetPath); |
300 | targetPath[stringLen] = 0; |
301 | |
302 | DefineDosDevice(DDD_NO_BROADCAST_SYSTEM, L"X:" , targetPath); |
303 | } |
304 | |
305 | ~DriveMapper() |
306 | { |
307 | DefineDosDevice(DDD_EXACT_MATCH_ON_REMOVE | DDD_NO_BROADCAST_SYSTEM | DDD_REMOVE_DEFINITION, L"X:" , targetPath); |
308 | delete [] targetPath; |
309 | } |
310 | |
311 | private: |
312 | wchar_t *targetPath; |
313 | }; |
314 | |
315 | QString dataDir = testFile(0); |
316 | DriveMapper dm(dataDir); |
317 | QQmlComponent component(&engine, testFileUrl("basic.qml" )); |
318 | |
319 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create()); |
320 | QVERIFY(flm != 0); |
321 | |
322 | QSignalSpy folderChangeSpy(flm, SIGNAL(folderChanged())); |
323 | |
324 | flm->setProperty("folder" ,QUrl::fromLocalFile(dataDir)); |
325 | QCOMPARE(flm->property("folder" ).toUrl(), QUrl::fromLocalFile(dataDir)); |
326 | QTRY_COMPARE(folderChangeSpy.count(), 1); |
327 | |
328 | flm->setProperty("folder" ,QUrl::fromLocalFile("X:/resetfiltering/" )); |
329 | QCOMPARE(flm->property("folder" ).toUrl(), QUrl::fromLocalFile("X:/resetfiltering/" )); |
330 | QTRY_COMPARE(folderChangeSpy.count(), 2); |
331 | } |
332 | #endif |
333 | |
334 | void tst_qquickfolderlistmodel::showDotAndDotDot() |
335 | { |
336 | QFETCH(QUrl, folder); |
337 | QFETCH(QUrl, rootFolder); |
338 | QFETCH(bool, showDotAndDotDot); |
339 | QFETCH(bool, showDot); |
340 | QFETCH(bool, showDotDot); |
341 | |
342 | QQmlComponent component(&engine, testFileUrl(fileName: "showDotAndDotDot.qml" )); |
343 | checkNoErrors(component); |
344 | |
345 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
346 | QVERIFY(flm != nullptr); |
347 | |
348 | flm->setProperty(name: "folder" , value: folder); |
349 | flm->setProperty(name: "rootFolder" , value: rootFolder); |
350 | flm->setProperty(name: "showDotAndDotDot" , value: showDotAndDotDot); |
351 | |
352 | int count = 10; |
353 | if (showDot) count++; |
354 | if (showDotDot) count++; |
355 | QTRY_COMPARE(flm->property("count" ).toInt(), count); // wait for refresh |
356 | |
357 | if (showDot) |
358 | QCOMPARE(flm->data(flm->index(0),FileNameRole).toString(), QLatin1String("." )); |
359 | if (showDotDot) |
360 | QCOMPARE(flm->data(flm->index(1),FileNameRole).toString(), QLatin1String(".." )); |
361 | } |
362 | |
363 | void tst_qquickfolderlistmodel::showDotAndDotDot_data() |
364 | { |
365 | #ifdef Q_OS_ANDROID |
366 | QSKIP("Resource file system does not list '.' and '..' due to QDir::entryList() behavior" ); |
367 | #endif |
368 | QTest::addColumn<QUrl>(name: "folder" ); |
369 | QTest::addColumn<QUrl>(name: "rootFolder" ); |
370 | QTest::addColumn<bool>(name: "showDotAndDotDot" ); |
371 | QTest::addColumn<bool>(name: "showDot" ); |
372 | QTest::addColumn<bool>(name: "showDotDot" ); |
373 | |
374 | QTest::newRow(dataTag: "false" ) << dataDirectoryUrl() << QUrl() << false << false << false; |
375 | QTest::newRow(dataTag: "true" ) << dataDirectoryUrl() << QUrl() << true << true << true; |
376 | QTest::newRow(dataTag: "true but root" ) << dataDirectoryUrl() << dataDirectoryUrl() << true << true << false; |
377 | } |
378 | |
379 | void tst_qquickfolderlistmodel::sortReversed() |
380 | { |
381 | QQmlComponent component(&engine, testFileUrl(fileName: "sortReversed.qml" )); |
382 | checkNoErrors(component); |
383 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
384 | QVERIFY(flm != nullptr); |
385 | flm->setProperty(name: "folder" , value: dataDirectoryUrl()); |
386 | QTRY_COMPARE(flm->property("count" ).toInt(), 10); // wait for refresh |
387 | QCOMPARE(flm->data(flm->index(0),FileNameRole).toString(), QLatin1String("txtdir" )); |
388 | } |
389 | |
390 | void tst_qquickfolderlistmodel::introspectQrc() |
391 | { |
392 | QQmlComponent component(&engine, testFileUrl(fileName: "qrc.qml" )); |
393 | checkNoErrors(component); |
394 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
395 | QVERIFY(flm != nullptr); |
396 | QTRY_COMPARE(flm->property("count" ).toInt(), 1); // wait for refresh |
397 | QCOMPARE(flm->data(flm->index(0),FileNameRole).toString(), QLatin1String("hello.txt" )); |
398 | } |
399 | |
400 | void tst_qquickfolderlistmodel::sortCaseSensitive_data() |
401 | { |
402 | QTest::addColumn<bool>(name: "sortCaseSensitive" ); |
403 | QTest::addColumn<QStringList>(name: "expectedOrder" ); |
404 | |
405 | const QString upperFile = QLatin1String("Uppercase.txt" ); |
406 | const QString lowerFile = QLatin1String("lowercase.txt" ); |
407 | |
408 | QTest::newRow(dataTag: "caseSensitive" ) << true << (QStringList() << upperFile << lowerFile); |
409 | QTest::newRow(dataTag: "caseInsensitive" ) << false << (QStringList() << lowerFile << upperFile); |
410 | } |
411 | |
412 | void tst_qquickfolderlistmodel::sortCaseSensitive() |
413 | { |
414 | QFETCH(bool, sortCaseSensitive); |
415 | QFETCH(QStringList, expectedOrder); |
416 | QQmlComponent component(&engine); |
417 | component.setData("import Qt.labs.folderlistmodel 1.0\n" |
418 | "FolderListModel { }" , baseUrl: QUrl()); |
419 | checkNoErrors(component); |
420 | |
421 | QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(object: component.create()); |
422 | QVERIFY(flm != 0); |
423 | flm->setProperty(name: "folder" , value: testFileUrl(fileName: "sortdir" )); |
424 | flm->setProperty(name: "sortCaseSensitive" , value: sortCaseSensitive); |
425 | QTRY_COMPARE(flm->property("count" ).toInt(), 2); // wait for refresh |
426 | for (int i = 0; i < 2; ++i) |
427 | QTRY_COMPARE(flm->data(flm->index(i),FileNameRole).toString(), expectedOrder.at(i)); |
428 | } |
429 | |
430 | void tst_qquickfolderlistmodel::updateProperties() |
431 | { |
432 | QQmlComponent component(&engine, testFileUrl(fileName: "basic.qml" )); |
433 | checkNoErrors(component); |
434 | |
435 | QObject *folderListModel = component.create(); |
436 | QVERIFY(folderListModel); |
437 | |
438 | QVariant caseSensitive = folderListModel->property(name: "caseSensitive" ); |
439 | QVERIFY(caseSensitive.isValid()); |
440 | QCOMPARE(caseSensitive.toBool(), true); |
441 | folderListModel->setProperty(name: "caseSensitive" , value: false); |
442 | caseSensitive = folderListModel->property(name: "caseSensitive" ); |
443 | QVERIFY(caseSensitive.isValid()); |
444 | QCOMPARE(caseSensitive.toBool(), false); |
445 | |
446 | QVariant showOnlyReadable = folderListModel->property(name: "showOnlyReadable" ); |
447 | QVERIFY(showOnlyReadable.isValid()); |
448 | QCOMPARE(showOnlyReadable.toBool(), false); |
449 | folderListModel->setProperty(name: "showOnlyReadable" , value: true); |
450 | showOnlyReadable = folderListModel->property(name: "showOnlyReadable" ); |
451 | QVERIFY(showOnlyReadable.isValid()); |
452 | QCOMPARE(showOnlyReadable.toBool(), true); |
453 | |
454 | QVariant showDotAndDotDot = folderListModel->property(name: "showDotAndDotDot" ); |
455 | QVERIFY(showDotAndDotDot.isValid()); |
456 | QCOMPARE(showDotAndDotDot.toBool(), false); |
457 | folderListModel->setProperty(name: "showDotAndDotDot" , value: true); |
458 | showDotAndDotDot = folderListModel->property(name: "showDotAndDotDot" ); |
459 | QVERIFY(showDotAndDotDot.isValid()); |
460 | QCOMPARE(showDotAndDotDot.toBool(), true); |
461 | |
462 | QVariant showHidden = folderListModel->property(name: "showHidden" ); |
463 | QVERIFY(showHidden.isValid()); |
464 | QCOMPARE(showHidden.toBool(), false); |
465 | folderListModel->setProperty(name: "showHidden" , value: true); |
466 | showHidden = folderListModel->property(name: "showHidden" ); |
467 | QVERIFY(showHidden.isValid()); |
468 | QCOMPARE(showHidden.toBool(), true); |
469 | } |
470 | |
471 | void tst_qquickfolderlistmodel::importBothVersions() |
472 | { |
473 | { |
474 | QQmlComponent component(&engine, testFileUrl(fileName: "sortReversed.qml" )); |
475 | checkNoErrors(component); |
476 | QScopedPointer<QObject> obj(component.create()); |
477 | QVERIFY(obj); |
478 | } |
479 | { |
480 | QQmlComponent component(&engine, testFileUrl(fileName: "qrc.qml" )); |
481 | checkNoErrors(component); |
482 | QScopedPointer<QObject> obj(component.create()); |
483 | QVERIFY(obj); |
484 | } |
485 | } |
486 | |
487 | QTEST_MAIN(tst_qquickfolderlistmodel) |
488 | |
489 | #include "tst_qquickfolderlistmodel.moc" |
490 | |