1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com> |
4 | ** Copyright (C) 2016 The Qt Company Ltd. |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the test suite of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include <QtTest/QtTest> |
31 | #include <QtCore/QString> |
32 | #include <QtCore/QCoreApplication> |
33 | #include <QtCore/QByteArray> |
34 | #include <QtCore/QDir> |
35 | #include <QtCore/QFile> |
36 | #include <QtCore/QProcess> |
37 | #include <QtCore/QDirIterator> |
38 | #include <QtCore/QMap> |
39 | #include <QtCore/QList> |
40 | #include <QtCore/QResource> |
41 | #include <QtCore/QLocale> |
42 | #include <QtCore/QtGlobal> |
43 | |
44 | #include <algorithm> |
45 | |
46 | typedef QMap<QString, QString> QStringMap; |
47 | Q_DECLARE_METATYPE(QStringMap) |
48 | |
49 | static QByteArray msgProcessStartFailed(const QProcess &p) |
50 | { |
51 | const QString result = QLatin1String("Could not start \"" ) |
52 | + QDir::toNativeSeparators(pathName: p.program()) + QLatin1String("\": " ) |
53 | + p.errorString(); |
54 | return result.toLocal8Bit(); |
55 | } |
56 | |
57 | static QByteArray msgProcessTimeout(const QProcess &p) |
58 | { |
59 | return '"' + QDir::toNativeSeparators(pathName: p.program()).toLocal8Bit() |
60 | + "\" timed out." ; |
61 | } |
62 | |
63 | static QByteArray msgProcessCrashed(QProcess &p) |
64 | { |
65 | return '"' + QDir::toNativeSeparators(pathName: p.program()).toLocal8Bit() |
66 | + "\" crashed.\n" + p.readAllStandardError(); |
67 | } |
68 | |
69 | static QByteArray msgProcessFailed(QProcess &p) |
70 | { |
71 | return '"' + QDir::toNativeSeparators(pathName: p.program()).toLocal8Bit() |
72 | + "\" returned " + QByteArray::number(p.exitCode()) + ":\n" |
73 | + p.readAllStandardError(); |
74 | } |
75 | |
76 | class tst_rcc : public QObject |
77 | { |
78 | Q_OBJECT |
79 | |
80 | private slots: |
81 | void initTestCase(); |
82 | |
83 | void rcc_data(); |
84 | void rcc(); |
85 | |
86 | void binary_data(); |
87 | void binary(); |
88 | |
89 | void readback_data(); |
90 | void readback(); |
91 | |
92 | void depFileGeneration_data(); |
93 | void depFileGeneration(); |
94 | |
95 | void python(); |
96 | |
97 | void cleanupTestCase(); |
98 | |
99 | private: |
100 | QString m_rcc; |
101 | QString m_dataPath; |
102 | }; |
103 | |
104 | void tst_rcc::initTestCase() |
105 | { |
106 | // rcc uses a QHash to store files in the resource system. |
107 | // we must force a certain hash order when testing or tst_rcc will fail, see QTBUG-25078 |
108 | QVERIFY(qputenv("QT_RCC_TEST" , "1" )); |
109 | m_rcc = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/rcc" ); |
110 | |
111 | m_dataPath = QFINDTESTDATA("data" ); |
112 | QVERIFY(!m_dataPath.isEmpty()); |
113 | } |
114 | |
115 | |
116 | static inline bool (const QString &line) |
117 | { |
118 | return line.startsWith(c: QLatin1Char('#')); |
119 | } |
120 | |
121 | static QString doCompare(const QStringList &actual, const QStringList &expected, |
122 | const QString &timeStampPath) |
123 | { |
124 | if (actual.size() != expected.size()) { |
125 | return QString("Length count different: actual: %1, expected: %2" ) |
126 | .arg(a: actual.size()).arg(a: expected.size()); |
127 | } |
128 | |
129 | QByteArray ba; |
130 | const bool isPython = isPythonComment(line: expected.constFirst()); |
131 | for (int i = 0, n = expected.size(); i != n; ++i) { |
132 | QString expectedLine = expected.at(i); |
133 | if (expectedLine.startsWith(s: "IGNORE:" )) |
134 | continue; |
135 | if (isPython && isPythonComment(line: expectedLine) && isPythonComment(line: actual.at(i))) |
136 | continue; |
137 | if (expectedLine.startsWith(s: "TIMESTAMP:" )) { |
138 | const QString relativePath = expectedLine.mid(position: strlen(s: "TIMESTAMP:" )); |
139 | const QFileInfo fi(timeStampPath + QLatin1Char('/') + relativePath); |
140 | if (!fi.isFile()) { |
141 | ba.append(a: "File " + fi.absoluteFilePath().toUtf8() + " does not exist!" ); |
142 | break; |
143 | } |
144 | const quint64 timeStamp = quint64(fi.lastModified().toMSecsSinceEpoch()); |
145 | expectedLine.clear(); |
146 | for (int shift = 56; shift >= 0; shift -= 8) { |
147 | expectedLine.append(s: QLatin1String("0x" )); |
148 | expectedLine.append(s: QString::number(quint8(timeStamp >> shift), base: 16)); |
149 | expectedLine.append(c: QLatin1Char(',')); |
150 | } |
151 | } |
152 | if (expectedLine != actual.at(i)) { |
153 | qDebug() << "LINES" << (i + 1) << "DIFFER" ; |
154 | ba.append( |
155 | a: "\n<<<<<< actual\n" + actual.at(i).toUtf8() + "\n======\n" + expectedLine.toUtf8() |
156 | + "\n>>>>>> expected\n" |
157 | ); |
158 | } |
159 | } |
160 | return ba; |
161 | } |
162 | |
163 | void tst_rcc::rcc_data() |
164 | { |
165 | QTest::addColumn<QString>(name: "directory" ); |
166 | QTest::addColumn<QString>(name: "qrcfile" ); |
167 | QTest::addColumn<QString>(name: "expected" ); |
168 | |
169 | const QString imagesPath = m_dataPath + QLatin1String("/images" ); |
170 | QTest::newRow(dataTag: "images" ) << imagesPath << "images.qrc" << "images.expected" ; |
171 | |
172 | const QString sizesPath = m_dataPath + QLatin1String("/sizes" ); |
173 | QTest::newRow(dataTag: "size-0" ) << sizesPath << "size-0.qrc" << "size-0.expected" ; |
174 | QTest::newRow(dataTag: "size-1" ) << sizesPath << "size-1.qrc" << "size-1.expected" ; |
175 | QTest::newRow(dataTag: "size-2-0-35-1" ) << sizesPath << "size-2-0-35-1.qrc" << "size-2-0-35-1.expected" ; |
176 | } |
177 | |
178 | static QStringList readLinesFromFile(const QString &fileName, |
179 | Qt::SplitBehavior splitBehavior) |
180 | { |
181 | QFile file(fileName); |
182 | |
183 | bool ok = file.open(flags: QIODevice::ReadOnly | QIODevice::Text); |
184 | if (!ok) { |
185 | QWARN(qPrintable(QString::fromLatin1("Could not open testdata file %1: %2" ) |
186 | .arg(fileName, file.errorString()))); |
187 | } |
188 | |
189 | return QString::fromUtf8(str: file.readAll()).split(sep: QLatin1Char('\n'), behavior: splitBehavior); |
190 | } |
191 | |
192 | void tst_rcc::rcc() |
193 | { |
194 | QFETCH(QString, directory); |
195 | QFETCH(QString, qrcfile); |
196 | QFETCH(QString, expected); |
197 | |
198 | // If the file expectedoutput.txt exists, compare the |
199 | // console output with the content of that file |
200 | |
201 | // Launch; force no compression, otherwise the output would be different |
202 | // depending on the compression algorithm we're using |
203 | QProcess process; |
204 | process.setWorkingDirectory(directory); |
205 | process.start(program: m_rcc, arguments: { "-no-compress" , qrcfile }); |
206 | QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData()); |
207 | if (!process.waitForFinished()) { |
208 | process.kill(); |
209 | QFAIL(msgProcessTimeout(process).constData()); |
210 | } |
211 | QVERIFY2(process.exitStatus() == QProcess::NormalExit, |
212 | msgProcessCrashed(process).constData()); |
213 | QVERIFY2(process.exitCode() == 0, |
214 | msgProcessFailed(process).constData()); |
215 | |
216 | const QChar cr = QLatin1Char('\r'); |
217 | const QString err = QString::fromLocal8Bit(str: process.readAllStandardError()).remove(c: cr); |
218 | const QString out = QString::fromLatin1(str: process.readAllStandardOutput()).remove(c: cr); |
219 | |
220 | if (!err.isEmpty()) { |
221 | qDebug() << "UNEXPECTED STDERR CONTENTS: " << err; |
222 | QFAIL("UNEXPECTED STDERR CONTENTS" ); |
223 | } |
224 | |
225 | const QChar nl = QLatin1Char('\n'); |
226 | const QStringList actualLines = out.split(sep: nl); |
227 | |
228 | const QStringList expectedLines = |
229 | readLinesFromFile(fileName: directory + QLatin1Char('/') + expected, splitBehavior: Qt::KeepEmptyParts); |
230 | QVERIFY(!expectedLines.isEmpty()); |
231 | |
232 | const QString diff = doCompare(actual: actualLines, expected: expectedLines, timeStampPath: directory); |
233 | if (diff.size()) |
234 | QFAIL(qPrintable(diff)); |
235 | } |
236 | |
237 | static QStringMap readExpectedFiles(const QString &fileName) |
238 | { |
239 | QStringMap expectedFiles; |
240 | |
241 | QStringList lines = readLinesFromFile(fileName, splitBehavior: Qt::SkipEmptyParts); |
242 | foreach (const QString &line, lines) { |
243 | QString resourceFileName = line.section(asep: QLatin1Char(' '), astart: 0, aend: 0, aflags: QString::SectionSkipEmpty); |
244 | QString actualFileName = line.section(asep: QLatin1Char(' '), astart: 1, aend: 1, aflags: QString::SectionSkipEmpty); |
245 | expectedFiles[resourceFileName] = actualFileName; |
246 | } |
247 | |
248 | return expectedFiles; |
249 | } |
250 | |
251 | /* |
252 | The following test looks for all *.qrc files under data/binary/. For each |
253 | .qrc file found, these files are processed (assuming the file found is |
254 | called "base.qrc"): |
255 | |
256 | - base.qrc : processed by rcc; creates base.rcc |
257 | - base.locale : (optional) list of locales to test, one per line |
258 | - base.expected : list of pairs (file path in resource, path to real file), |
259 | one per line; the pair separated by a whitespace; the paths to real files |
260 | relative to data/binary/ (for testing the C locale) |
261 | - base.localeName.expected : for each localeName in the base.locale file, |
262 | as the above .expected file |
263 | */ |
264 | |
265 | void tst_rcc::binary_data() |
266 | { |
267 | QTest::addColumn<QString>(name: "resourceFile" ); |
268 | QTest::addColumn<QLocale>(name: "locale" ); |
269 | QTest::addColumn<QString>(name: "baseDirectory" ); |
270 | QTest::addColumn<QStringMap>(name: "expectedFiles" ); |
271 | |
272 | QString dataPath = m_dataPath + QLatin1String("/binary/" ); |
273 | |
274 | QDirIterator iter(dataPath, QStringList() << QLatin1String("*.qrc" )); |
275 | while (iter.hasNext()) |
276 | { |
277 | iter.next(); |
278 | QFileInfo qrcFileInfo = iter.fileInfo(); |
279 | QString absoluteBaseName = QFileInfo(qrcFileInfo.absolutePath(), qrcFileInfo.baseName()).absoluteFilePath(); |
280 | QString rccFileName = absoluteBaseName + QLatin1String(".rcc" ); |
281 | |
282 | // same as above: force no compression |
283 | QProcess rccProcess; |
284 | rccProcess.setWorkingDirectory(dataPath); |
285 | rccProcess.start(program: m_rcc, arguments: { "-binary" , "-no-compress" , "-o" , rccFileName, qrcFileInfo.absoluteFilePath() }); |
286 | QVERIFY2(rccProcess.waitForStarted(), msgProcessStartFailed(rccProcess).constData()); |
287 | if (!rccProcess.waitForFinished()) { |
288 | rccProcess.kill(); |
289 | QFAIL(msgProcessTimeout(rccProcess).constData()); |
290 | } |
291 | QVERIFY2(rccProcess.exitStatus() == QProcess::NormalExit, |
292 | msgProcessCrashed(rccProcess).constData()); |
293 | QVERIFY2(rccProcess.exitCode() == 0, |
294 | msgProcessFailed(rccProcess).constData()); |
295 | |
296 | QByteArray output = rccProcess.readAllStandardOutput(); |
297 | if (!output.isEmpty()) |
298 | qWarning(msg: "rcc stdout: %s" , output.constData()); |
299 | |
300 | output = rccProcess.readAllStandardError(); |
301 | if (!output.isEmpty()) |
302 | qWarning(msg: "rcc stderr: %s" , output.constData()); |
303 | |
304 | QString localeFileName = absoluteBaseName + QLatin1String(".locale" ); |
305 | QFile localeFile(localeFileName); |
306 | if (localeFile.exists()) { |
307 | QStringList locales = readLinesFromFile(fileName: localeFileName, splitBehavior: Qt::SkipEmptyParts); |
308 | foreach (const QString &locale, locales) { |
309 | QString expectedFileName = QString::fromLatin1(str: "%1.%2.%3" ).arg(args&: absoluteBaseName, args: locale, args: QLatin1String("expected" )); |
310 | QStringMap expectedFiles = readExpectedFiles(fileName: expectedFileName); |
311 | QTest::newRow(qPrintable(qrcFileInfo.baseName() + QLatin1Char('_') + locale)) << rccFileName |
312 | << QLocale(locale) |
313 | << dataPath |
314 | << expectedFiles; |
315 | } |
316 | } |
317 | |
318 | // always test for the C locale as well |
319 | QString expectedFileName = absoluteBaseName + QLatin1String(".expected" ); |
320 | QStringMap expectedFiles = readExpectedFiles(fileName: expectedFileName); |
321 | QTest::newRow(qPrintable(qrcFileInfo.baseName() + QLatin1String("_C" ))) << rccFileName |
322 | << QLocale::c() |
323 | << dataPath |
324 | << expectedFiles; |
325 | } |
326 | } |
327 | |
328 | void tst_rcc::binary() |
329 | { |
330 | QFETCH(QString, baseDirectory); |
331 | QFETCH(QString, resourceFile); |
332 | QFETCH(QLocale, locale); |
333 | QFETCH(QStringMap, expectedFiles); |
334 | |
335 | const QString rootPrefix = QLatin1String("/test_root/" ); |
336 | const QString resourceRootPrefix = QLatin1Char(':') + rootPrefix; |
337 | |
338 | QLocale oldDefaultLocale; |
339 | QLocale::setDefault(locale); |
340 | QVERIFY(QFile::exists(resourceFile)); |
341 | QVERIFY(QResource::registerResource(resourceFile, rootPrefix)); |
342 | |
343 | { // need to destroy the iterators on the resource, in order to be able to unregister it |
344 | |
345 | // read all the files inside the resources |
346 | QDirIterator iter(resourceRootPrefix, QDir::Files, QDirIterator::Subdirectories); |
347 | QList<QString> filesFound; |
348 | while (iter.hasNext()) |
349 | filesFound << iter.next(); |
350 | |
351 | // add the test root prefix to the expected file names |
352 | QList<QString> expectedFileNames = expectedFiles.keys(); |
353 | for (QList<QString>::iterator i = expectedFileNames.begin(); i < expectedFileNames.end(); ++i) { |
354 | // poor man's canonicalPath, which doesn't work with resources |
355 | if ((*i).startsWith(c: QLatin1Char('/'))) |
356 | (*i).remove(i: 0, len: 1); |
357 | *i = resourceRootPrefix + *i; |
358 | } |
359 | |
360 | // check that we have all (and only) the expected files |
361 | std::sort(first: filesFound.begin(), last: filesFound.end()); |
362 | std::sort(first: expectedFileNames.begin(), last: expectedFileNames.end()); |
363 | QCOMPARE(filesFound, expectedFileNames); |
364 | |
365 | // now actually check the file contents |
366 | QDir directory(baseDirectory); |
367 | for (QStringMap::const_iterator i = expectedFiles.constBegin(); i != expectedFiles.constEnd(); ++i) { |
368 | QString resourceFileName = i.key(); |
369 | QString actualFileName = i.value(); |
370 | |
371 | QFile resourceFile(resourceRootPrefix + resourceFileName); |
372 | QVERIFY(resourceFile.open(QIODevice::ReadOnly)); |
373 | QByteArray resourceData = resourceFile.readAll(); |
374 | resourceFile.close(); |
375 | |
376 | QFile actualFile(QFileInfo(directory, actualFileName).absoluteFilePath()); |
377 | QVERIFY(actualFile.open(QIODevice::ReadOnly)); |
378 | QByteArray actualData = actualFile.readAll(); |
379 | actualFile.close(); |
380 | QCOMPARE(resourceData, actualData); |
381 | } |
382 | |
383 | } |
384 | |
385 | QVERIFY(QResource::unregisterResource(resourceFile, rootPrefix)); |
386 | QLocale::setDefault(oldDefaultLocale); |
387 | } |
388 | |
389 | void tst_rcc::readback_data() |
390 | { |
391 | QTest::addColumn<QString>(name: "resourceName" ); |
392 | QTest::addColumn<QString>(name: "fileSystemName" ); |
393 | |
394 | QTest::newRow(dataTag: "data-0" ) << ":data/data-0.txt" << "sizes/data/data-0.txt" ; |
395 | QTest::newRow(dataTag: "data-1" ) << ":data/data-1.txt" << "sizes/data/data-1.txt" ; |
396 | QTest::newRow(dataTag: "data-2" ) << ":data/data-2.txt" << "sizes/data/data-2.txt" ; |
397 | QTest::newRow(dataTag: "data-35" ) << ":data/data-35.txt" << "sizes/data/data-35.txt" ; |
398 | QTest::newRow(dataTag: "circle" ) << ":images/circle.png" << "images/images/circle.png" ; |
399 | QTest::newRow(dataTag: "square" ) << ":images/square.png" << "images/images/square.png" ; |
400 | QTest::newRow(dataTag: "triangle" ) << ":images/subdir/triangle.png" |
401 | << "images/images/subdir/triangle.png" ; |
402 | } |
403 | |
404 | void tst_rcc::readback() |
405 | { |
406 | QFETCH(QString, resourceName); |
407 | QFETCH(QString, fileSystemName); |
408 | |
409 | QFile resourceFile(resourceName); |
410 | QVERIFY(resourceFile.open(QIODevice::ReadOnly)); |
411 | QByteArray resourceData = resourceFile.readAll(); |
412 | resourceFile.close(); |
413 | |
414 | QFile fileSystemFile(m_dataPath + QLatin1Char('/') + fileSystemName); |
415 | QVERIFY(fileSystemFile.open(QIODevice::ReadOnly)); |
416 | QByteArray fileSystemData = fileSystemFile.readAll(); |
417 | fileSystemFile.close(); |
418 | |
419 | QCOMPARE(resourceData, fileSystemData); |
420 | } |
421 | |
422 | void tst_rcc::depFileGeneration_data() |
423 | { |
424 | QTest::addColumn<QString>(name: "qrcfile" ); |
425 | QTest::addColumn<QString>(name: "depfile" ); |
426 | QTest::addColumn<QString>(name: "expected" ); |
427 | |
428 | QTest::newRow(dataTag: "simple" ) << "simple.qrc" << "simple.d" << "simple.d.expected" ; |
429 | QTest::newRow(dataTag: "specialchar" ) << "specialchar.qrc" << "specialchar.d" << "specialchar.d.expected" ; |
430 | } |
431 | |
432 | void tst_rcc::depFileGeneration() |
433 | { |
434 | QFETCH(QString, qrcfile); |
435 | QFETCH(QString, depfile); |
436 | QFETCH(QString, expected); |
437 | const QString directory = m_dataPath + QLatin1String("/depfile" ); |
438 | |
439 | QProcess process; |
440 | process.setWorkingDirectory(directory); |
441 | process.start(program: m_rcc, arguments: { "-d" , depfile, "-o" , qrcfile + ".cpp" , qrcfile }); |
442 | QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData()); |
443 | if (!process.waitForFinished()) { |
444 | process.kill(); |
445 | QFAIL(msgProcessTimeout(process).constData()); |
446 | } |
447 | QVERIFY2(process.exitStatus() == QProcess::NormalExit, |
448 | msgProcessCrashed(process).constData()); |
449 | QVERIFY2(process.exitCode() == 0, |
450 | msgProcessFailed(process).constData()); |
451 | |
452 | QFile depFileOutput(directory + QLatin1String("/" ) + depfile); |
453 | QVERIFY(depFileOutput.open(QIODevice::ReadOnly | QIODevice::Text)); |
454 | QByteArray depFileData = depFileOutput.readAll(); |
455 | depFileOutput.close(); |
456 | |
457 | QFile depFileExpected(directory + QLatin1String("/" ) + expected); |
458 | QVERIFY(depFileExpected.open(QIODevice::ReadOnly | QIODevice::Text)); |
459 | QByteArray expectedData = depFileExpected.readAll(); |
460 | depFileExpected.close(); |
461 | |
462 | QCOMPARE(depFileData, expectedData); |
463 | } |
464 | |
465 | void tst_rcc::python() |
466 | { |
467 | const QString path = m_dataPath + QLatin1String("/sizes" ); |
468 | const QString testFileRoot = path + QLatin1String("/size-2-0-35-1" ); |
469 | const QString qrcFile = testFileRoot + QLatin1String(".qrc" ); |
470 | const QString expectedFile = testFileRoot + QLatin1String("_python.expected" ); |
471 | const QString actualFile = testFileRoot + QLatin1String(".rcc" ); |
472 | |
473 | QProcess process; |
474 | process.setWorkingDirectory(path); |
475 | process.start(program: m_rcc, arguments: { "-g" , "python" , "-o" , actualFile, qrcFile}); |
476 | QVERIFY2(process.waitForStarted(), msgProcessStartFailed(process).constData()); |
477 | if (!process.waitForFinished()) { |
478 | process.kill(); |
479 | QFAIL(msgProcessTimeout(process).constData()); |
480 | } |
481 | QVERIFY2(process.exitStatus() == QProcess::NormalExit, |
482 | msgProcessCrashed(process).constData()); |
483 | QVERIFY2(process.exitCode() == 0, |
484 | msgProcessFailed(process).constData()); |
485 | |
486 | const auto actualLines = readLinesFromFile(fileName: actualFile, splitBehavior: Qt::KeepEmptyParts); |
487 | QVERIFY(!actualLines.isEmpty()); |
488 | const auto expectedLines = readLinesFromFile(fileName: expectedFile, splitBehavior: Qt::KeepEmptyParts); |
489 | QVERIFY(!expectedLines.isEmpty()); |
490 | const QString diff = doCompare(actual: actualLines, expected: expectedLines, timeStampPath: path); |
491 | if (!diff.isEmpty()) |
492 | QFAIL(qPrintable(diff)); |
493 | } |
494 | |
495 | void tst_rcc::cleanupTestCase() |
496 | { |
497 | QDir dataDir(m_dataPath + QLatin1String("/binary" )); |
498 | QFileInfoList entries = dataDir.entryInfoList(nameFilters: QStringList() << QLatin1String("*.rcc" )); |
499 | QDir dataDepDir(m_dataPath + QLatin1String("/depfile" )); |
500 | entries += dataDepDir.entryInfoList(nameFilters: {QLatin1String("*.d" ), QLatin1String("*.qrc.cpp" )}); |
501 | foreach (const QFileInfo &entry, entries) |
502 | QFile::remove(fileName: entry.absoluteFilePath()); |
503 | } |
504 | |
505 | QTEST_MAIN(tst_rcc) |
506 | |
507 | #include "tst_rcc.moc" |
508 | |