diff --git a/autotests/plugins/cli7zplugin/cli7ztest.cpp b/autotests/plugins/cli7zplugin/cli7ztest.cpp index 503e9ef1..71a17056 100644 --- a/autotests/plugins/cli7zplugin/cli7ztest.cpp +++ b/autotests/plugins/cli7zplugin/cli7ztest.cpp @@ -1,422 +1,428 @@ /* * Copyright (c) 2016 Ragnar Thomsen * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cli7ztest.h" #include "testhelper.h" #include #include #include #include #include QTEST_GUILESS_MAIN(Cli7zTest) using namespace Kerfuffle; void Cli7zTest::initTestCase() { m_plugin = new Plugin(this); foreach (Plugin *plugin, m_pluginManger.availablePlugins()) { if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_cli7z")) { m_plugin = plugin; return; } } } void Cli7zTest::testArchive_data() { QTest::addColumn("archivePath"); QTest::addColumn("expectedFileName"); QTest::addColumn("isReadOnly"); QTest::addColumn("isSingleFolder"); QTest::addColumn("expectedEncryptionType"); QTest::addColumn("expectedSubfolderName"); QString archivePath = QFINDTESTDATA("data/one_toplevel_folder.7z"); QTest::newRow("archive with one top-level folder") << archivePath << QFileInfo(archivePath).fileName() << false << true << Archive::Unencrypted << QStringLiteral("A"); } void Cli7zTest::testArchive() { if (!m_plugin->isValid()) { QSKIP("cli7z plugin not available. Skipping test.", SkipSingle); } QFETCH(QString, archivePath); auto loadJob = Archive::load(archivePath, m_plugin, this); QVERIFY(loadJob); TestHelper::startAndWaitForResult(loadJob); auto archive = loadJob->archive(); QVERIFY(archive); if (!archive->isValid()) { QSKIP("Could not load the cli7z plugin. Skipping test.", SkipSingle); } QFETCH(QString, expectedFileName); QCOMPARE(QFileInfo(archive->fileName()).fileName(), expectedFileName); QFETCH(bool, isReadOnly); QCOMPARE(archive->isReadOnly(), isReadOnly); QFETCH(bool, isSingleFolder); QCOMPARE(archive->isSingleFolder(), isSingleFolder); QFETCH(Archive::EncryptionType, expectedEncryptionType); QCOMPARE(archive->encryptionType(), expectedEncryptionType); QFETCH(QString, expectedSubfolderName); QCOMPARE(archive->subfolderName(), expectedSubfolderName); } void Cli7zTest::testList_data() { QTest::addColumn("outputTextFile"); QTest::addColumn("expectedEntriesCount"); QTest::addColumn("isMultiVolume"); // Is zero for non-multi-volume archives: QTest::addColumn("numberOfVolumes"); + QTest::addColumn("compressionMethods"); // Index of some entry to be tested. QTest::addColumn("someEntryIndex"); // Entry metadata. QTest::addColumn("expectedName"); QTest::addColumn("isDirectory"); QTest::addColumn("isPasswordProtected"); QTest::addColumn("expectedSize"); QTest::addColumn("expectedTimestamp"); // p7zip version 16.02 tests QTest::newRow("normal-file-1602") - << QFINDTESTDATA("data/archive-with-symlink-1602.txt") << 10 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-1602.txt") << 10 << false << 0 << QStringList{QStringLiteral("LZMA2")} << 4 << QStringLiteral("testarchive/dir2/file2.txt") << false << false << (qulonglong) 32 << QStringLiteral("2015-05-17T20:41:48"); QTest::newRow("encrypted-1602") - << QFINDTESTDATA("data/archive-encrypted-1602.txt") << 4 << false << 0 + << QFINDTESTDATA("data/archive-encrypted-1602.txt") << 4 << false << 0 << QStringList{QStringLiteral("LZMA2"), QStringLiteral("7zAES")} << 1 << QStringLiteral("file2.txt") << false << true << (qulonglong) 14 << QStringLiteral("2016-03-02T22:37:55"); QTest::newRow("multi-volume-1602") - << QFINDTESTDATA("data/archive-multivol-1602.txt") << 2 << true << 5 + << QFINDTESTDATA("data/archive-multivol-1602.txt") << 2 << true << 5 << QStringList{QStringLiteral("LZMA2")} << 1 << QStringLiteral("largefile2") << false << false << (qulonglong) 2097152 << QStringLiteral("2016-07-17T11:26:19"); // p7zip version 15.14 tests QTest::newRow("normal-file-1514") - << QFINDTESTDATA("data/archive-with-symlink-1514.txt") << 10 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-1514.txt") << 10 << false << 0 << QStringList{QStringLiteral("LZMA2")} << 4 << QStringLiteral("testarchive/dir2/file2.txt") << false << false << (qulonglong) 32 << QStringLiteral("2015-05-17T19:41:48"); QTest::newRow("encrypted-1514") - << QFINDTESTDATA("data/archive-encrypted-1514.txt") << 9 << false << 0 + << QFINDTESTDATA("data/archive-encrypted-1514.txt") << 9 << false << 0 << QStringList{QStringLiteral("LZMA2"), QStringLiteral("7zAES")} << 3 << QStringLiteral("testarchive/dir1/file1.txt") << false << true << (qulonglong) 32 << QStringLiteral("2015-05-17T19:41:48"); // p7zip version 15.09 tests QTest::newRow("normal-file-1509") - << QFINDTESTDATA("data/archive-with-symlink-1509.txt") << 10 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-1509.txt") << 10 << false << 0 << QStringList{QStringLiteral("LZMA2")} << 4 << QStringLiteral("testarchive/dir2/file2.txt") << false << false << (qulonglong) 32 << QStringLiteral("2015-05-17T19:41:48"); QTest::newRow("encrypted-1509") - << QFINDTESTDATA("data/archive-encrypted-1509.txt") << 9 << false << 0 + << QFINDTESTDATA("data/archive-encrypted-1509.txt") << 9 << false << 0 << QStringList{QStringLiteral("LZMA2"), QStringLiteral("7zAES")} << 3 << QStringLiteral("testarchive/dir1/file1.txt") << false << true << (qulonglong) 32 << QStringLiteral("2015-05-17T19:41:48"); // p7zip version 9.38.1 tests QTest::newRow("normal-file-9381") - << QFINDTESTDATA("data/archive-with-symlink-9381.txt") << 10 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-9381.txt") << 10 << false << 0 << QStringList{QStringLiteral("LZMA2")} << 4 << QStringLiteral("testarchive/dir2/file2.txt") << false << false << (qulonglong) 32 << QStringLiteral("2015-05-17T19:41:48"); QTest::newRow("encrypted-9381") - << QFINDTESTDATA("data/archive-encrypted-9381.txt") << 9 << false << 0 + << QFINDTESTDATA("data/archive-encrypted-9381.txt") << 9 << false << 0 << QStringList{QStringLiteral("LZMA2"), QStringLiteral("7zAES")} << 3 << QStringLiteral("testarchive/dir1/file1.txt") << false << true << (qulonglong) 32 << QStringLiteral("2015-05-17T19:41:48"); } void Cli7zTest::testList() { qRegisterMetaType("Archive::Entry*"); CliPlugin *plugin = new CliPlugin(this, {QStringLiteral("dummy.7z")}); - QSignalSpy signalSpy(plugin, &CliPlugin::entry); + QSignalSpy signalSpyEntry(plugin, &CliPlugin::entry); + QSignalSpy signalSpyCompMethod(plugin, &CliPlugin::compressionMethodFound); QFETCH(QString, outputTextFile); QFETCH(int, expectedEntriesCount); QFile outputText(outputTextFile); QVERIFY(outputText.open(QIODevice::ReadOnly)); QTextStream outputStream(&outputText); while (!outputStream.atEnd()) { const QString line(outputStream.readLine()); QVERIFY(plugin->readListLine(line)); } - QCOMPARE(signalSpy.count(), expectedEntriesCount); + QCOMPARE(signalSpyEntry.count(), expectedEntriesCount); QFETCH(bool, isMultiVolume); QCOMPARE(plugin->isMultiVolume(), isMultiVolume); QFETCH(int, numberOfVolumes); QCOMPARE(plugin->numberOfVolumes(), numberOfVolumes); + QCOMPARE(signalSpyCompMethod.count(), 1); + QFETCH(QStringList, compressionMethods); + QCOMPARE(signalSpyCompMethod.at(0).at(0).toStringList(), compressionMethods); + QFETCH(int, someEntryIndex); - QVERIFY(someEntryIndex < signalSpy.count()); - Archive::Entry *entry = signalSpy.at(someEntryIndex).at(0).value(); + QVERIFY(someEntryIndex < signalSpyEntry.count()); + Archive::Entry *entry = signalSpyEntry.at(someEntryIndex).at(0).value(); QFETCH(QString, expectedName); QCOMPARE(entry->fullPath(), expectedName); QFETCH(bool, isDirectory); QCOMPARE(entry->isDir(), isDirectory); QFETCH(bool, isPasswordProtected); QCOMPARE(entry->property("isPasswordProtected").toBool(), isPasswordProtected); QFETCH(qulonglong, expectedSize); QCOMPARE(entry->property("size").toULongLong(), expectedSize); QFETCH(QString, expectedTimestamp); QCOMPARE(entry->property("timestamp").toString(), expectedTimestamp); plugin->deleteLater(); } void Cli7zTest::testListArgs_data() { QTest::addColumn("archiveName"); QTest::addColumn("password"); QTest::addColumn("expectedArgs"); QTest::newRow("unencrypted") << QStringLiteral("/tmp/foo.7z") << QString() << QStringList { QStringLiteral("l"), QStringLiteral("-slt"), QStringLiteral("/tmp/foo.7z") }; QTest::newRow("header-encrypted") << QStringLiteral("/tmp/foo.7z") << QStringLiteral("1234") << QStringList { QStringLiteral("l"), QStringLiteral("-slt"), QStringLiteral("-p1234"), QStringLiteral("/tmp/foo.7z") }; } void Cli7zTest::testListArgs() { QFETCH(QString, archiveName); CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)}); QVERIFY(plugin); const QStringList listArgs = { QStringLiteral("l"), QStringLiteral("-slt"), QStringLiteral("$PasswordSwitch"), QStringLiteral("$Archive") }; QFETCH(QString, password); const auto replacedArgs = plugin->substituteListVariables(listArgs, password); QFETCH(QStringList, expectedArgs); QCOMPARE(replacedArgs, expectedArgs); plugin->deleteLater(); } void Cli7zTest::testAddArgs_data() { QTest::addColumn("archiveName"); QTest::addColumn("password"); QTest::addColumn("encryptHeader"); QTest::addColumn("compressionLevel"); QTest::addColumn("volumeSize"); QTest::addColumn("expectedArgs"); QTest::newRow("unencrypted") << QStringLiteral("/tmp/foo.7z") << QString() << false << 5 << 0UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("-mx=5") }; QTest::newRow("encrypted") << QStringLiteral("/tmp/foo.7z") << QStringLiteral("1234") << false << 5 << 0UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("-p1234"), QStringLiteral("-mx=5") }; QTest::newRow("header-encrypted") << QStringLiteral("/tmp/foo.7z") << QStringLiteral("1234") << true << 5 << 0UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("-p1234"), QStringLiteral("-mhe=on"), QStringLiteral("-mx=5") }; QTest::newRow("multi-volume") << QStringLiteral("/tmp/foo.7z") << QString() << false << 5 << 2500UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("-mx=5"), QStringLiteral("-v2500k") }; } void Cli7zTest::testAddArgs() { QFETCH(QString, archiveName); CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)}); QVERIFY(plugin); const QStringList addArgs = { QStringLiteral("a"), QStringLiteral("$Archive"), QStringLiteral("$PasswordSwitch"), QStringLiteral("$CompressionLevelSwitch"), QStringLiteral("$MultiVolumeSwitch"), QStringLiteral("$Files") }; QFETCH(QString, password); QFETCH(bool, encryptHeader); QFETCH(int, compressionLevel); QFETCH(ulong, volumeSize); QStringList replacedArgs = plugin->substituteAddVariables(addArgs, {}, password, encryptHeader, compressionLevel, volumeSize); QFETCH(QStringList, expectedArgs); QCOMPARE(replacedArgs, expectedArgs); plugin->deleteLater(); } void Cli7zTest::testExtractArgs_data() { QTest::addColumn("archiveName"); QTest::addColumn>("files"); QTest::addColumn("preservePaths"); QTest::addColumn("password"); QTest::addColumn("expectedArgs"); QTest::newRow("preserve paths, encrypted") << QStringLiteral("/tmp/foo.7z") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << true << QStringLiteral("1234") << QStringList { QStringLiteral("x"), QStringLiteral("-p1234"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; QTest::newRow("preserve paths, unencrypted") << QStringLiteral("/tmp/foo.7z") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << true << QString() << QStringList { QStringLiteral("x"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; QTest::newRow("without paths, encrypted") << QStringLiteral("/tmp/foo.7z") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << false << QStringLiteral("1234") << QStringList { QStringLiteral("e"), QStringLiteral("-p1234"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; QTest::newRow("without paths, unencrypted") << QStringLiteral("/tmp/foo.7z") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << false << QString() << QStringList { QStringLiteral("e"), QStringLiteral("/tmp/foo.7z"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; } void Cli7zTest::testExtractArgs() { QFETCH(QString, archiveName); CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)}); QVERIFY(plugin); const QStringList extractArgs = { QStringLiteral("$PreservePathSwitch"), QStringLiteral("$PasswordSwitch"), QStringLiteral("$Archive"), QStringLiteral("$Files") }; QFETCH(QList, files); QFETCH(bool, preservePaths); QFETCH(QString, password); QStringList replacedArgs = plugin->substituteExtractVariables(extractArgs, files, preservePaths, password); QVERIFY(replacedArgs.size() >= extractArgs.size()); QFETCH(QStringList, expectedArgs); QCOMPARE(replacedArgs, expectedArgs); plugin->deleteLater(); } diff --git a/autotests/plugins/clirarplugin/clirartest.cpp b/autotests/plugins/clirarplugin/clirartest.cpp index df358b7c..9e27b87d 100644 --- a/autotests/plugins/clirarplugin/clirartest.cpp +++ b/autotests/plugins/clirarplugin/clirartest.cpp @@ -1,483 +1,495 @@ /* * Copyright (c) 2011,2014 Raphael Kubo da Costa * Copyright (c) 2015,2016 Ragnar Thomsen * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "clirartest.h" #include #include #include #include #include QTEST_GUILESS_MAIN(CliRarTest) using namespace Kerfuffle; void CliRarTest::initTestCase() { m_plugin = new Plugin(this); foreach (Plugin *plugin, m_pluginManger.availablePlugins()) { if (plugin->metaData().pluginId() == QStringLiteral("kerfuffle_clirar")) { m_plugin = plugin; return; } } } void CliRarTest::testArchive_data() { QTest::addColumn("archivePath"); QTest::addColumn("expectedFileName"); QTest::addColumn("isReadOnly"); QTest::addColumn("isSingleFolder"); QTest::addColumn("expectedEncryptionType"); QTest::addColumn("expectedSubfolderName"); QString archivePath = QFINDTESTDATA("data/one_toplevel_folder.rar"); QTest::newRow("archive with one top-level folder") << archivePath << QFileInfo(archivePath).fileName() << false << true << Archive::Unencrypted << QStringLiteral("A"); } void CliRarTest::testArchive() { if (!m_plugin->isValid()) { QSKIP("clirar plugin not available. Skipping test.", SkipSingle); } QFETCH(QString, archivePath); auto loadJob = Archive::load(archivePath, m_plugin, this); QVERIFY(loadJob); TestHelper::startAndWaitForResult(loadJob); auto archive = loadJob->archive(); QVERIFY(archive); if (!archive->isValid()) { QSKIP("Could not load the clirar plugin. Skipping test.", SkipSingle); } QFETCH(QString, expectedFileName); QCOMPARE(QFileInfo(archive->fileName()).fileName(), expectedFileName); QFETCH(bool, isReadOnly); QCOMPARE(archive->isReadOnly(), isReadOnly); QFETCH(bool, isSingleFolder); QCOMPARE(archive->isSingleFolder(), isSingleFolder); QFETCH(Archive::EncryptionType, expectedEncryptionType); QCOMPARE(archive->encryptionType(), expectedEncryptionType); QFETCH(QString, expectedSubfolderName); QCOMPARE(archive->subfolderName(), expectedSubfolderName); } void CliRarTest::testList_data() { QTest::addColumn("outputTextFile"); QTest::addColumn("errorMessage"); QTest::addColumn("expectedEntriesCount"); QTest::addColumn("isMultiVolume"); // Is zero for non-multi-volume archives: QTest::addColumn("numberOfVolumes"); + QTest::addColumn("compressionMethods"); // Index of some entry to be tested. QTest::addColumn("someEntryIndex"); // Entry metadata. QTest::addColumn("expectedName"); QTest::addColumn("isDirectory"); QTest::addColumn("isPasswordProtected"); QTest::addColumn("symlinkTarget"); QTest::addColumn("expectedSize"); QTest::addColumn("expectedCompressedSize"); QTest::addColumn("expectedTimestamp"); // Unrar 5 tests QTest::newRow("normal-file-unrar5") - << QFINDTESTDATA("data/archive-with-symlink-unrar5.txt") << QString() << 8 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-unrar5.txt") << QString() << 8 << false << 0 << QStringList{QStringLiteral("RAR4")} << 2 << QStringLiteral("rartest/file2.txt") << false << false << QString() << (qulonglong) 14 << (qulonglong) 23 << QStringLiteral("2016-03-21T08:57:36"); QTest::newRow("symlink-unrar5") - << QFINDTESTDATA("data/archive-with-symlink-unrar5.txt") << QString() << 8 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-unrar5.txt") << QString() << 8 << false << 0 << QStringList{QStringLiteral("RAR4")} << 3 << QStringLiteral("rartest/linktofile1.txt") << false << false << QStringLiteral("file1.txt") << (qulonglong) 9 << (qulonglong) 9 << QStringLiteral("2016-03-21T08:58:16"); QTest::newRow("encrypted-unrar5") - << QFINDTESTDATA("data/archive-encrypted-unrar5.txt") << QString() << 7 << false << 0 + << QFINDTESTDATA("data/archive-encrypted-unrar5.txt") << QString() << 7 << false << 0 << QStringList{QStringLiteral("RAR4")} << 2 << QStringLiteral("rartest/file2.txt") << false << true << QString() << (qulonglong) 14 << (qulonglong) 32 << QStringLiteral("2016-03-21T17:03:36"); QTest::newRow("recovery-record-unrar5") - << QFINDTESTDATA("data/archive-recovery-record-unrar5.txt") << QString() << 3 << false << 0 + << QFINDTESTDATA("data/archive-recovery-record-unrar5.txt") << QString() << 3 << false << 0 << QStringList{QStringLiteral("RAR4")} << 0 << QStringLiteral("file1.txt") << false << false << QString() << (qulonglong) 32 << (qulonglong) 33 << QStringLiteral("2015-07-26T19:04:38"); QTest::newRow("corrupt-archive-unrar5") - << QFINDTESTDATA("data/archive-corrupt-file-header-unrar5.txt") << QString() << 8 << false << 0 + << QFINDTESTDATA("data/archive-corrupt-file-header-unrar5.txt") << QString() << 8 << false << 0 << QStringList{QStringLiteral("RAR4")} << 6 << QStringLiteral("dir1/") << true << false << QString() << (qulonglong) 0 << (qulonglong) 0 << QStringLiteral("2015-05-14T01:45:24"); //Note: The number of entries will be the total number of all entries in all volumes, i.e. if a file spans 3 volumes it will count as 3 entries. QTest::newRow("multivolume-archive-unrar5") - << QFINDTESTDATA("data/archive-multivol-unrar5.txt") << QString() << 6 << true << 5 + << QFINDTESTDATA("data/archive-multivol-unrar5.txt") << QString() << 6 << true << 5 << QStringList{QStringLiteral("RAR4")} << 5 << QStringLiteral("largefile2") << false << false << QString() << (qulonglong) 2097152 << (qulonglong) 11231 << QStringLiteral("2016-07-17T11:26:19"); + QTest::newRow("RAR5-open-with-unrar5") + << QFINDTESTDATA("data/archive-RARv5-unrar5.txt") << QString() << 9 << false << 0 << QStringList{QStringLiteral("RAR5")} + << 4 << QStringLiteral("testarchive/dir1/file1.txt") << false << false << QString() << (qulonglong) 32 << (qulonglong) 32 << QStringLiteral("2015-05-17T20:41:48"); + // Unrar 4 tests QTest::newRow("normal-file-unrar4") - << QFINDTESTDATA("data/archive-with-symlink-unrar4.txt") << QString() << 8 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-unrar4.txt") << QString() << 8 << false << 0 << QStringList{QStringLiteral("RAR4")} << 2 << QStringLiteral("rartest/file2.txt") << false << false << QString() << (qulonglong) 14 << (qulonglong) 23 << QStringLiteral("2016-03-21T08:57:00"); QTest::newRow("symlink-unrar4") - << QFINDTESTDATA("data/archive-with-symlink-unrar4.txt") << QString() << 8 << false << 0 + << QFINDTESTDATA("data/archive-with-symlink-unrar4.txt") << QString() << 8 << false << 0 << QStringList{QStringLiteral("RAR4")} << 3 << QStringLiteral("rartest/linktofile1.txt") << false << false << QStringLiteral("file1.txt") << (qulonglong) 9 << (qulonglong) 9 << QStringLiteral("2016-03-21T08:58:00"); QTest::newRow("encrypted-unrar4") - << QFINDTESTDATA("data/archive-encrypted-unrar4.txt") << QString() << 7 << false << 0 + << QFINDTESTDATA("data/archive-encrypted-unrar4.txt") << QString() << 7 << false << 0 << QStringList{QStringLiteral("RAR4")} << 2 << QStringLiteral("rartest/file2.txt") << false << true << QString() << (qulonglong) 14 << (qulonglong) 32 << QStringLiteral("2016-03-21T17:03:00"); QTest::newRow("recovery-record-unrar4") - << QFINDTESTDATA("data/archive-recovery-record-unrar4.txt") << QString() << 3 << false << 0 + << QFINDTESTDATA("data/archive-recovery-record-unrar4.txt") << QString() << 3 << false << 0 << QStringList{QStringLiteral("RAR4")} << 0 << QStringLiteral("file1.txt") << false << false << QString() << (qulonglong) 32 << (qulonglong) 33 << QStringLiteral("2015-07-26T19:04:00"); QTest::newRow("corrupt-archive-unrar4") - << QFINDTESTDATA("data/archive-corrupt-file-header-unrar4.txt") << QString() << 8 << false << 0 + << QFINDTESTDATA("data/archive-corrupt-file-header-unrar4.txt") << QString() << 8 << false << 0 << QStringList{QStringLiteral("RAR4")} << 6 << QStringLiteral("dir1/") << true << false << QString() << (qulonglong) 0 << (qulonglong) 0 << QStringLiteral("2015-05-14T01:45:00"); QTest::newRow("RAR5-open-with-unrar4") << QFINDTESTDATA("data/archive-RARv5-unrar4.txt") << QStringLiteral("Your unrar executable is version 4.20, which is too old to handle this archive. Please update to a more recent version.") - << 0 << false << 0 << 0 << QString() << true << false << QString() << (qulonglong) 0 << (qulonglong) 0 << QString(); + << 0 << false << 0 << QStringList() << 0 << QString() << true << false << QString() << (qulonglong) 0 << (qulonglong) 0 << QString(); //Note: The number of entries will be the total number of all entries in all volumes, i.e. if a file spans 3 volumes it will count as 3 entries. QTest::newRow("multivolume-archive-unrar4") - << QFINDTESTDATA("data/archive-multivol-unrar4.txt") << QString() << 6 << true << 5 + << QFINDTESTDATA("data/archive-multivol-unrar4.txt") << QString() << 6 << true << 5 << QStringList{QStringLiteral("RAR4")} << 5 << QStringLiteral("largefile2") << false << false << QString() << (qulonglong) 2097152 << (qulonglong) 11231 << QStringLiteral("2016-07-17T11:26:00"); // Unrar 3 tests QTest::newRow("RAR5-open-with-unrar3") << QFINDTESTDATA("data/archive-RARv5-unrar3.txt") << QStringLiteral("Unrar reported a non-RAR archive. The installed unrar version (3.71) is old. Try updating your unrar.") - << 0 << false << 0 << 0 << QString() << true << false << QString() << (qulonglong) 0 << (qulonglong) 0 << QString(); + << 0 << false << 0 << QStringList() << 0 << QString() << true << false << QString() << (qulonglong) 0 << (qulonglong) 0 << QString(); /* * Check that the plugin will not crash when reading corrupted archives, which * have lines such as "Unexpected end of archive" or "??? - the file header is * corrupt" instead of a file name and the header string after it. * * See bug 262857 and commit 2042997013432cdc6974f5b26d39893a21e21011. */ QTest::newRow("corrupt-archive-unrar3") - << QFINDTESTDATA("data/archive-corrupt-file-header-unrar3.txt") << QString() << 1 << true << 1 + << QFINDTESTDATA("data/archive-corrupt-file-header-unrar3.txt") << QString() << 1 << true << 1 << QStringList{QStringLiteral("RAR4")} << 0 << QStringLiteral("some-file.ext") << false << false << QString() << (qulonglong) 732522496 << (qulonglong) 14851208 << QStringLiteral("2010-10-29T20:47:00"); } void CliRarTest::testList() { qRegisterMetaType("Archive::Entry*"); CliPlugin *rarPlugin = new CliPlugin(this, {QStringLiteral("dummy.rar")}); QSignalSpy signalSpyEntry(rarPlugin, &CliPlugin::entry); + QSignalSpy signalSpyCompMethod(rarPlugin, &CliPlugin::compressionMethodFound); QSignalSpy signalSpyError(rarPlugin, &CliPlugin::error); QFETCH(QString, outputTextFile); QFETCH(int, expectedEntriesCount); QFile outputText(outputTextFile); QVERIFY(outputText.open(QIODevice::ReadOnly)); QTextStream outputStream(&outputText); while (!outputStream.atEnd()) { const QString line(outputStream.readLine()); if (!rarPlugin->readListLine(line)) { break; } } QFETCH(QString, errorMessage); if (!errorMessage.isEmpty()) { QCOMPARE(signalSpyError.count(), 1); QCOMPARE(signalSpyError.at(0).at(0).toString(), errorMessage); return; } QCOMPARE(signalSpyEntry.count(), expectedEntriesCount); QFETCH(bool, isMultiVolume); QCOMPARE(rarPlugin->isMultiVolume(), isMultiVolume); QFETCH(int, numberOfVolumes); QCOMPARE(rarPlugin->numberOfVolumes(), numberOfVolumes); + QVERIFY(signalSpyCompMethod.count() > 0); + QFETCH(QStringList, compressionMethods); + if (!compressionMethods.isEmpty()) { + QCOMPARE(signalSpyCompMethod.at(0).at(0).toStringList(), compressionMethods); + } + QFETCH(int, someEntryIndex); QVERIFY(someEntryIndex < signalSpyEntry.count()); Archive::Entry *entry = signalSpyEntry.at(someEntryIndex).at(0).value(); QFETCH(QString, expectedName); QCOMPARE(entry->fullPath(), expectedName); QFETCH(bool, isDirectory); QCOMPARE(entry->isDir(), isDirectory); QFETCH(bool, isPasswordProtected); QCOMPARE(entry->property("isPasswordProtected").toBool(), isPasswordProtected); QFETCH(QString, symlinkTarget); QCOMPARE(entry->property("link").toString(), symlinkTarget); QFETCH(qulonglong, expectedSize); QCOMPARE(entry->property("size").toULongLong(), expectedSize); QFETCH(qulonglong, expectedCompressedSize); QCOMPARE(entry->property("compressedSize").toULongLong(), expectedCompressedSize); QFETCH(QString, expectedTimestamp); QCOMPARE(entry->property("timestamp").toString(), expectedTimestamp); rarPlugin->deleteLater(); } void CliRarTest::testListArgs_data() { QTest::addColumn("archiveName"); QTest::addColumn("password"); QTest::addColumn("expectedArgs"); QTest::newRow("unencrypted") << QStringLiteral("/tmp/foo.rar") << QString() << QStringList { QStringLiteral("vt"), QStringLiteral("-v"), QStringLiteral("/tmp/foo.rar") }; QTest::newRow("header-encrypted") << QStringLiteral("/tmp/foo.rar") << QStringLiteral("1234") << QStringList { QStringLiteral("vt"), QStringLiteral("-v"), QStringLiteral("-p1234"), QStringLiteral("/tmp/foo.rar") }; } void CliRarTest::testListArgs() { QFETCH(QString, archiveName); CliPlugin *plugin = new CliPlugin(this, {QVariant(archiveName)}); QVERIFY(plugin); const QStringList listArgs = { QStringLiteral("vt"), QStringLiteral("-v"), QStringLiteral("$PasswordSwitch"), QStringLiteral("$Archive") }; QFETCH(QString, password); const auto replacedArgs = plugin->substituteListVariables(listArgs, password); QFETCH(QStringList, expectedArgs); QCOMPARE(replacedArgs, expectedArgs); plugin->deleteLater(); } void CliRarTest::testAddArgs_data() { QTest::addColumn("archiveName"); QTest::addColumn("password"); QTest::addColumn("encryptHeader"); QTest::addColumn("compressionLevel"); QTest::addColumn("volumeSize"); QTest::addColumn("expectedArgs"); QTest::newRow("unencrypted") << QStringLiteral("/tmp/foo.rar") << QString() << false << 3 << 0UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("-m3") }; QTest::newRow("encrypted") << QStringLiteral("/tmp/foo.rar") << QStringLiteral("1234") << false << 3 << 0UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("-p1234"), QStringLiteral("-m3") }; QTest::newRow("header-encrypted") << QStringLiteral("/tmp/foo.rar") << QStringLiteral("1234") << true << 3 << 0UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("-hp1234"), QStringLiteral("-m3") }; QTest::newRow("multi-volume") << QStringLiteral("/tmp/foo.rar") << QString() << false << 3 << 2500UL << QStringList { QStringLiteral("a"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("-m3"), QStringLiteral("-v2500k") }; } void CliRarTest::testAddArgs() { QFETCH(QString, archiveName); CliPlugin *rarPlugin = new CliPlugin(this, {QVariant(archiveName)}); QVERIFY(rarPlugin); const QStringList addArgs = { QStringLiteral("a"), QStringLiteral("$Archive"), QStringLiteral("$PasswordSwitch"), QStringLiteral("$CompressionLevelSwitch"), QStringLiteral("$MultiVolumeSwitch"), QStringLiteral("$Files") }; QFETCH(QString, password); QFETCH(bool, encryptHeader); QFETCH(int, compressionLevel); QFETCH(ulong, volumeSize); QStringList replacedArgs = rarPlugin->substituteAddVariables(addArgs, {}, password, encryptHeader, compressionLevel, volumeSize); QFETCH(QStringList, expectedArgs); QCOMPARE(replacedArgs, expectedArgs); rarPlugin->deleteLater(); } void CliRarTest::testExtractArgs_data() { QTest::addColumn("archiveName"); QTest::addColumn>("files"); QTest::addColumn("preservePaths"); QTest::addColumn("password"); QTest::addColumn("expectedArgs"); QTest::newRow("preserve paths, encrypted") << QStringLiteral("/tmp/foo.rar") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << true << QStringLiteral("1234") << QStringList { QStringLiteral("-kb"), QStringLiteral("-p-"), QStringLiteral("x"), QStringLiteral("-p1234"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; QTest::newRow("preserve paths, unencrypted") << QStringLiteral("/tmp/foo.rar") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << true << QString() << QStringList { QStringLiteral("-kb"), QStringLiteral("-p-"), QStringLiteral("x"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; QTest::newRow("without paths, encrypted") << QStringLiteral("/tmp/foo.rar") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << false << QStringLiteral("1234") << QStringList { QStringLiteral("-kb"), QStringLiteral("-p-"), QStringLiteral("e"), QStringLiteral("-p1234"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; QTest::newRow("without paths, unencrypted") << QStringLiteral("/tmp/foo.rar") << QList { new Archive::Entry(this, QStringLiteral("aDir/textfile2.txt"), QStringLiteral("aDir")), new Archive::Entry(this, QStringLiteral("c.txt"), QString()) } << false << QString() << QStringList { QStringLiteral("-kb"), QStringLiteral("-p-"), QStringLiteral("e"), QStringLiteral("/tmp/foo.rar"), QStringLiteral("aDir/textfile2.txt"), QStringLiteral("c.txt"), }; } void CliRarTest::testExtractArgs() { QFETCH(QString, archiveName); CliPlugin *rarPlugin = new CliPlugin(this, {QVariant(archiveName)}); QVERIFY(rarPlugin); const QStringList extractArgs = { QStringLiteral("-kb"), QStringLiteral("-p-"), QStringLiteral("$PreservePathSwitch"), QStringLiteral("$PasswordSwitch"), QStringLiteral("$Archive"), QStringLiteral("$Files") }; QFETCH(QList, files); QFETCH(bool, preservePaths); QFETCH(QString, password); QStringList replacedArgs = rarPlugin->substituteExtractVariables(extractArgs, files, preservePaths, password); QVERIFY(replacedArgs.size() >= extractArgs.size()); QFETCH(QStringList, expectedArgs); QCOMPARE(replacedArgs, expectedArgs); rarPlugin->deleteLater(); } diff --git a/autotests/plugins/clirarplugin/data/archive-RARv5-unrar5.txt b/autotests/plugins/clirarplugin/data/archive-RARv5-unrar5.txt new file mode 100644 index 00000000..459f77a8 --- /dev/null +++ b/autotests/plugins/clirarplugin/data/archive-RARv5-unrar5.txt @@ -0,0 +1,96 @@ + +UNRAR 5.40 freeware Copyright (c) 1993-2016 Alexander Roshal + +Archive: testrar5.rar +Details: RAR 5 + + Name: testarchive/file4.txt + Type: File + Size: 32 + Packed size: 32 + Ratio: 100% + mtime: 2015-07-26 18:53:21,000 + Attributes: -rw-rw-r-- + CRC32: A04F9191 + Host OS: Unix + Compression: RAR 5.0(v50) -m0 -md=128K + + Name: testarchive/dir2/file2.txt + Type: File + Size: 32 + Packed size: 32 + Ratio: 100% + mtime: 2015-05-17 20:41:48,000 + Attributes: -rw-rw-r-- + CRC32: D49ECBCA + Host OS: Unix + Compression: RAR 5.0(v50) -m3 -md=128K + + Name: testarchive/file1.txt + Type: File + Size: 43 + Packed size: 35 + Ratio: 81% + mtime: 2015-09-13 14:05:45,000 + Attributes: -rw-rw-r-- + CRC32: 94E02716 + Host OS: Unix + Compression: RAR 5.0(v50) -m3 -md=128K + + Name: testarchive/file2.txt + Type: File + Size: 32 + Packed size: 32 + Ratio: 100% + mtime: 2015-05-18 14:57:37,000 + Attributes: -rw-rw-r-- + CRC32: D49ECBCA + Host OS: Unix + Compression: RAR 5.0(v50) -m3 -md=128K + + Name: testarchive/dir1/file1.txt + Type: File + Size: 32 + Packed size: 32 + Ratio: 100% + mtime: 2015-05-17 20:41:48,000 + Attributes: -rw-rw-r-- + CRC32: 034EE5C7 + Host OS: Unix + Compression: RAR 5.0(v50) -m3 -md=128K + + Name: testarchive/file3.txt + Type: File + Size: 32 + Packed size: 32 + Ratio: 100% + mtime: 2015-05-13 17:26:42,000 + Attributes: -rw-rw-r-- + CRC32: 99D12E31 + Host OS: Unix + Compression: RAR 5.0(v50) -m3 -md=128K + + Name: testarchive/dir2 + Type: Directory + mtime: 2015-05-14 01:43:41,000 + Attributes: drwxrwxr-x + CRC32: 00000000 + Host OS: Unix + Compression: RAR 5.0(v50) -m0 -md=0K + + Name: testarchive/dir1 + Type: Directory + mtime: 2015-05-14 01:45:24,000 + Attributes: drwxrwxr-x + CRC32: 00000000 + Host OS: Unix + Compression: RAR 5.0(v50) -m0 -md=0K + + Name: testarchive + Type: Directory + mtime: 2016-10-09 19:01:48,000 + Attributes: drwxrwxr-x + CRC32: 00000000 + Host OS: Unix + Compression: RAR 5.0(v50) -m0 -md=0K +