diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CMakeLists.txt | 12 | ||||
-rw-r--r-- | tests/TestUtil.h | 19 | ||||
-rw-r--r-- | tests/data/.gitattributes | 2 | ||||
-rw-r--r-- | tests/data/1.json | 43 | ||||
-rw-r--r-- | tests/data/2.json | 31 | ||||
-rw-r--r-- | tests/data/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tests/data/channels.json | 23 | ||||
-rw-r--r-- | tests/data/errorChannels.json | 23 | ||||
-rw-r--r-- | tests/data/fileOneA | 1 | ||||
-rw-r--r-- | tests/data/fileOneB | 3 | ||||
-rw-r--r-- | tests/data/fileThree | 1 | ||||
-rw-r--r-- | tests/data/fileTwo | 1 | ||||
-rw-r--r-- | tests/data/garbageChannels.json | 22 | ||||
-rw-r--r-- | tests/data/index.json | 9 | ||||
-rw-r--r-- | tests/data/noChannels.json | 5 | ||||
-rw-r--r-- | tests/data/oneChannel.json | 11 | ||||
-rw-r--r-- | tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml | 17 | ||||
-rw-r--r-- | tests/test.manifest | 27 | ||||
-rw-r--r-- | tests/test.rc | 28 | ||||
-rw-r--r-- | tests/tst_DownloadUpdateTask.cpp | 271 | ||||
-rw-r--r-- | tests/tst_UpdateChecker.cpp | 163 | ||||
-rw-r--r-- | tests/tst_pathutils.cpp | 32 | ||||
-rw-r--r-- | tests/tst_userutils.cpp | 7 |
23 files changed, 730 insertions, 25 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e115af17..2d851404 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -8,6 +8,9 @@ macro(add_unit_test name) unset(srcs) foreach(arg ${testname} ${ARGN}) list(APPEND srcs ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) + if (WIN32) + list(APPEND srcs ${CMAKE_CURRENT_SOURCE_DIR}/test.rc) + endif() endforeach() add_executable(tst_${name} ${srcs}) qt5_use_modules(tst_${name} Test Core Network Widgets) @@ -20,6 +23,8 @@ endmacro() add_unit_test(pathutils tst_pathutils.cpp) add_unit_test(userutils tst_userutils.cpp) +add_unit_test(UpdateChecker tst_UpdateChecker.cpp) +add_unit_test(DownloadUpdateTask tst_DownloadUpdateTask.cpp) # Tests END # @@ -79,4 +84,9 @@ if(MultiMC_CODE_COVERAGE) add_custom_target(MultiMC_RUN_TESTS DEPENDS MultiMC_GENERATE_COVERAGE_HTML) endif(MultiMC_CODE_COVERAGE) -add_subdirectory(data) + +add_custom_target(MultiMC_Test_Data + ALL + COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/data + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/data ${CMAKE_CURRENT_BINARY_DIR}/data +) diff --git a/tests/TestUtil.h b/tests/TestUtil.h index 64ee1675..fd25d24f 100644 --- a/tests/TestUtil.h +++ b/tests/TestUtil.h @@ -15,15 +15,30 @@ struct TestsInternal f.open(QFile::ReadOnly); return f.readAll(); } + static QString readFileUtf8(const QString &fileName) + { + return QString::fromUtf8(readFile(fileName)); + } }; #define MULTIMC_GET_TEST_FILE(file) TestsInternal::readFile(QFINDTESTDATA( file )) +#define MULTIMC_GET_TEST_FILE_UTF8(file) TestsInternal::readFileUtf8(QFINDTESTDATA( file )) +#ifdef Q_OS_LINUX +# define _MMC_EXTRA_ARGV , "-platform", "offscreen" +# define _MMC_EXTRA_ARGC 2 +#else +# define _MMC_EXTRA_ARGV +# define _MMC_EXTRA_ARGC 0 +#endif + + + #define QTEST_GUILESS_MAIN_MULTIMC(TestObject) \ int main(int argc, char *argv[]) \ { \ - char *argv_[] = { argv[0] }; \ - int argc_ = 1; \ + char *argv_[] = { argv[0] _MMC_EXTRA_ARGV }; \ + int argc_ = 1 + _MMC_EXTRA_ARGC; \ MultiMC app(argc_, argv_, QDir::temp().absoluteFilePath("MultiMC_Test")); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ TestObject tc; \ diff --git a/tests/data/.gitattributes b/tests/data/.gitattributes new file mode 100644 index 00000000..9ac803f0 --- /dev/null +++ b/tests/data/.gitattributes @@ -0,0 +1,2 @@ +* -text -diff + diff --git a/tests/data/1.json b/tests/data/1.json new file mode 100644 index 00000000..f9f99b22 --- /dev/null +++ b/tests/data/1.json @@ -0,0 +1,43 @@ +{ + "ApiVersion": 0, + "Id": 1, + "Name": "1.0.1", + "Files": [ + { + "Path": "fileOne", + "Sources": [ + { + "SourceType": "http", + "Url": "$PWD/tests/data/fileOneA" + } + ], + "Executable": true, + "Perms": 493, + "MD5": "9eb84090956c484e32cb6c08455a667b" + }, + { + "Path": "fileTwo", + "Sources": [ + { + "SourceType": "http", + "Url": "$PWD/tests/data/fileTwo" + } + ], + "Executable": false, + "Perms": 644, + "MD5": "38f94f54fa3eb72b0ea836538c10b043" + }, + { + "Path": "fileThree", + "Sources": [ + { + "SourceType": "http", + "Url": "$PWD/tests/data/fileThree" + } + ], + "Executable": false, + "Perms": "750", + "MD5": "f12df554b21e320be6471d7154130e70" + } + ] +} diff --git a/tests/data/2.json b/tests/data/2.json new file mode 100644 index 00000000..bb59b9b6 --- /dev/null +++ b/tests/data/2.json @@ -0,0 +1,31 @@ +{ + "ApiVersion": 0, + "Id": 1, + "Name": "1.0.1", + "Files": [ + { + "Path": "fileOne", + "Sources": [ + { + "SourceType": "http", + "Url": "$PWD/tests/data/fileOneB" + } + ], + "Executable": true, + "Perms": 493, + "MD5": "42915a71277c9016668cce7b82c6b577" + }, + { + "Path": "fileTwo", + "Sources": [ + { + "SourceType": "http", + "Url": "$PWD/tests/data/fileTwo" + } + ], + "Executable": false, + "Perms": 644, + "MD5": "38f94f54fa3eb72b0ea836538c10b043" + } + ] +} diff --git a/tests/data/CMakeLists.txt b/tests/data/CMakeLists.txt deleted file mode 100644 index eee5a596..00000000 --- a/tests/data/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_custom_target(MultiMC_Test_Data - ALL - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} -) diff --git a/tests/data/channels.json b/tests/data/channels.json new file mode 100644 index 00000000..6bf65a82 --- /dev/null +++ b/tests/data/channels.json @@ -0,0 +1,23 @@ +{ + "format_version": 0, + "channels": [ + { + "id": "develop", + "name": "Develop", + "description": "The channel called \"develop\"", + "url": "$PWD/tests/data/" + }, + { + "id": "stable", + "name": "Stable", + "description": "It's stable at least", + "url": "ftp://username@host/path/to/stuff" + }, + { + "id": "42", + "name": "The Channel", + "description": "This is the channel that is going to answer all of your questions", + "url": "https://dent.me/tea" + } + ] +} diff --git a/tests/data/errorChannels.json b/tests/data/errorChannels.json new file mode 100644 index 00000000..333cd445 --- /dev/null +++ b/tests/data/errorChannels.json @@ -0,0 +1,23 @@ +{ + "format_version": 0, + "channels": [ + { + "id": "", + "name": "Develop", + "description": "The channel called \"develop\"", + "url": "http://example.org/stuff" + }, + { + "id": "stable", + "name": "", + "description": "It's stable at least", + "url": "ftp://username@host/path/to/stuff" + }, + { + "id": "42", + "name": "The Channel", + "description": "This is the channel that is going to answer all of your questions", + "url": "" + } + ] +} diff --git a/tests/data/fileOneA b/tests/data/fileOneA new file mode 100644 index 00000000..f2e41136 --- /dev/null +++ b/tests/data/fileOneA @@ -0,0 +1 @@ +stuff diff --git a/tests/data/fileOneB b/tests/data/fileOneB new file mode 100644 index 00000000..f9aba922 --- /dev/null +++ b/tests/data/fileOneB @@ -0,0 +1,3 @@ +stuff + +more stuff that came in the new version diff --git a/tests/data/fileThree b/tests/data/fileThree new file mode 100644 index 00000000..6353ff16 --- /dev/null +++ b/tests/data/fileThree @@ -0,0 +1 @@ +this is yet another file diff --git a/tests/data/fileTwo b/tests/data/fileTwo new file mode 100644 index 00000000..aad9a93a --- /dev/null +++ b/tests/data/fileTwo @@ -0,0 +1 @@ +some other stuff diff --git a/tests/data/garbageChannels.json b/tests/data/garbageChannels.json new file mode 100644 index 00000000..1450fb9c --- /dev/null +++ b/tests/data/garbageChannels.json @@ -0,0 +1,22 @@ +{ + "format_version": 0, + "channels": [ + { + "id": "develop", + "name": "Develop", + "description": "The channel called \"develop\"", +aa "url": "http://example.org/stuff" + }, +a "id": "stable", + "name": "Stable", + "description": "It's stable at least", + "url": "ftp://username@host/path/to/stuff" + }, + { + "id": "42"f + "name": "The Channel", + "description": "This is the channel that is going to answer all of your questions", + "url": "https://dent.me/tea" + } + ] +} diff --git a/tests/data/index.json b/tests/data/index.json new file mode 100644 index 00000000..20ceb9f4 --- /dev/null +++ b/tests/data/index.json @@ -0,0 +1,9 @@ +{ + "ApiVersion": 0, + "Versions": [ + { "Id": 0, "Name": "1.0.0" }, + { "Id": 1, "Name": "1.0.1" }, + { "Id": 2, "Name": "1.0.2" }, + { "Id": 3, "Name": "1.0.3" } + ] +} diff --git a/tests/data/noChannels.json b/tests/data/noChannels.json new file mode 100644 index 00000000..bbb2cb70 --- /dev/null +++ b/tests/data/noChannels.json @@ -0,0 +1,5 @@ +{ + "format_version": 0, + "channels": [ + ] +} diff --git a/tests/data/oneChannel.json b/tests/data/oneChannel.json new file mode 100644 index 00000000..84727ac7 --- /dev/null +++ b/tests/data/oneChannel.json @@ -0,0 +1,11 @@ +{ + "format_version": 0, + "channels": [ + { + "id": "develop", + "name": "Develop", + "description": "The channel called \"develop\"", + "url": "http://example.org/stuff" + } + ] +} diff --git a/tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml b/tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml new file mode 100644 index 00000000..09c162ca --- /dev/null +++ b/tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml @@ -0,0 +1,17 @@ +<update version="3"> + <install> + <file> + <source>sourceOne</source> + <dest>destOne</dest> + <mode>0777</mode> + </file> + <file> + <source>MultiMC.exe</source> + <dest>M/u/l/t/i/M/C/e/x/e</dest> + <mode>0644</mode> + </file> + </install> + <uninstall> + <file>toDelete.abc</file> + </uninstall> +</update> diff --git a/tests/test.manifest b/tests/test.manifest new file mode 100644 index 00000000..8b4dbb98 --- /dev/null +++ b/tests/test.manifest @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> + <assemblyIdentity name="MultiMC.Test.0" type="win32" version="5.0.0.0" /> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> + <dependency> + <dependentAssembly> + <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/> + </dependentAssembly> + </dependency> + <description>Custom Minecraft launcher for managing multiple installs.</description> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!--The ID below indicates app support for Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!--The ID below indicates app support for Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!--The ID below indicates app support for Windows Developer Preview / Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + </application> + </compatibility> +</assembly>
\ No newline at end of file diff --git a/tests/test.rc b/tests/test.rc new file mode 100644 index 00000000..a288dba6 --- /dev/null +++ b/tests/test.rc @@ -0,0 +1,28 @@ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +1 RT_MANIFEST "test.manifest" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1,0,0,0 +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "MultiMC Contributors" + VALUE "FileDescription", "Testcase" + VALUE "FileVersion", "1.0.0.0" + VALUE "ProductName", "MultiMC Testcase" + VALUE "ProductVersion", "5" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04b0 // Unicode + END +END diff --git a/tests/tst_DownloadUpdateTask.cpp b/tests/tst_DownloadUpdateTask.cpp new file mode 100644 index 00000000..3b2c6793 --- /dev/null +++ b/tests/tst_DownloadUpdateTask.cpp @@ -0,0 +1,271 @@ +#include <QTest> +#include <QSignalSpy> + +#include "TestUtil.h" + +#include "logic/updater/DownloadUpdateTask.h" +#include "logic/updater/UpdateChecker.h" +#include "depends/util/include/pathutils.h" + +DownloadUpdateTask::FileSourceList encodeBaseFile(const char *suffix) +{ + auto base = qApp->applicationDirPath(); + QUrl localFile = QUrl::fromLocalFile(base + suffix); + QString localUrlString = localFile.toString(QUrl::FullyEncoded); + auto item = DownloadUpdateTask::FileSource("http", localUrlString); + return DownloadUpdateTask::FileSourceList({item}); +} + +Q_DECLARE_METATYPE(DownloadUpdateTask::VersionFileList) +Q_DECLARE_METATYPE(DownloadUpdateTask::UpdateOperation) + +bool operator==(const DownloadUpdateTask::FileSource &f1, + const DownloadUpdateTask::FileSource &f2) +{ + return f1.type == f2.type && f1.url == f2.url && f1.compressionType == f2.compressionType; +} +bool operator==(const DownloadUpdateTask::VersionFileEntry &v1, + const DownloadUpdateTask::VersionFileEntry &v2) +{ + return v1.path == v2.path && v1.mode == v2.mode && v1.sources == v2.sources && + v1.md5 == v2.md5; +} +bool operator==(const DownloadUpdateTask::UpdateOperation &u1, + const DownloadUpdateTask::UpdateOperation &u2) +{ + return u1.type == u2.type && u1.file == u2.file && u1.dest == u2.dest && u1.mode == u2.mode; +} + +QDebug operator<<(QDebug dbg, const DownloadUpdateTask::FileSource &f) +{ + dbg.nospace() << "FileSource(type=" << f.type << " url=" << f.url + << " comp=" << f.compressionType << ")"; + return dbg.maybeSpace(); +} + +QDebug operator<<(QDebug dbg, const DownloadUpdateTask::VersionFileEntry &v) +{ + dbg.nospace() << "VersionFileEntry(path=" << v.path << " mode=" << v.mode + << " md5=" << v.md5 << " sources=" << v.sources << ")"; + return dbg.maybeSpace(); +} + +QDebug operator<<(QDebug dbg, const DownloadUpdateTask::UpdateOperation::Type &t) +{ + switch (t) + { + case DownloadUpdateTask::UpdateOperation::OP_COPY: + dbg << "OP_COPY"; + break; + case DownloadUpdateTask::UpdateOperation::OP_DELETE: + dbg << "OP_DELETE"; + break; + case DownloadUpdateTask::UpdateOperation::OP_MOVE: + dbg << "OP_MOVE"; + break; + case DownloadUpdateTask::UpdateOperation::OP_CHMOD: + dbg << "OP_CHMOD"; + break; + } + return dbg.maybeSpace(); +} + +QDebug operator<<(QDebug dbg, const DownloadUpdateTask::UpdateOperation &u) +{ + dbg.nospace() << "UpdateOperation(type=" << u.type << " file=" << u.file + << " dest=" << u.dest << " mode=" << u.mode << ")"; + return dbg.maybeSpace(); +} + +class DownloadUpdateTaskTest : public QObject +{ + Q_OBJECT +private +slots: + void initTestCase() + { + } + void cleanupTestCase() + { + } + + void test_writeInstallScript() + { + DownloadUpdateTask task( + QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(), 0); + + DownloadUpdateTask::UpdateOperationList ops; + + ops << DownloadUpdateTask::UpdateOperation::CopyOp("sourceOne", "destOne", 0777) + << DownloadUpdateTask::UpdateOperation::CopyOp("MultiMC.exe", "M/u/l/t/i/M/C/e/x/e") + << DownloadUpdateTask::UpdateOperation::DeleteOp("toDelete.abc"); + auto testFile = "tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml"; + const QString script = QDir::temp().absoluteFilePath("MultiMCUpdateScript.xml"); + QVERIFY(task.writeInstallScript(ops, script)); + QCOMPARE(TestsInternal::readFileUtf8(script).replace(QRegExp("[\r\n]+"), "\n"), + MULTIMC_GET_TEST_FILE_UTF8(testFile).replace(QRegExp("[\r\n]+"), "\n")); + } + + void test_parseVersionInfo_data() + { + QTest::addColumn<QByteArray>("data"); + QTest::addColumn<DownloadUpdateTask::VersionFileList>("list"); + QTest::addColumn<QString>("error"); + QTest::addColumn<bool>("ret"); + + QTest::newRow("one") + << MULTIMC_GET_TEST_FILE("tests/data/1.json") + << (DownloadUpdateTask::VersionFileList() + << DownloadUpdateTask::VersionFileEntry{"fileOne", + 493, + encodeBaseFile("/tests/data/fileOneA"), + "9eb84090956c484e32cb6c08455a667b"} + << DownloadUpdateTask::VersionFileEntry{"fileTwo", + 644, + encodeBaseFile("/tests/data/fileTwo"), + "38f94f54fa3eb72b0ea836538c10b043"} + << DownloadUpdateTask::VersionFileEntry{"fileThree", + 750, + encodeBaseFile("/tests/data/fileThree"), + "f12df554b21e320be6471d7154130e70"}) + << QString() << true; + QTest::newRow("two") + << MULTIMC_GET_TEST_FILE("tests/data/2.json") + << (DownloadUpdateTask::VersionFileList() + << DownloadUpdateTask::VersionFileEntry{"fileOne", + 493, + encodeBaseFile("/tests/data/fileOneB"), + "42915a71277c9016668cce7b82c6b577"} + << DownloadUpdateTask::VersionFileEntry{"fileTwo", + 644, + encodeBaseFile("/tests/data/fileTwo"), + "38f94f54fa3eb72b0ea836538c10b043"}) + << QString() << true; + } + void test_parseVersionInfo() + { + QFETCH(QByteArray, data); + QFETCH(DownloadUpdateTask::VersionFileList, list); + QFETCH(QString, error); + QFETCH(bool, ret); + + DownloadUpdateTask::VersionFileList outList; + QString outError; + bool outRet = DownloadUpdateTask("", 0).parseVersionInfo(data, &outList, &outError); + QCOMPARE(outRet, ret); + QCOMPARE(outList, list); + QCOMPARE(outError, error); + } + + void test_processFileLists_data() + { + QTest::addColumn<DownloadUpdateTask *>("downloader"); + QTest::addColumn<DownloadUpdateTask::VersionFileList>("currentVersion"); + QTest::addColumn<DownloadUpdateTask::VersionFileList>("newVersion"); + QTest::addColumn<DownloadUpdateTask::UpdateOperationList>("expectedOperations"); + + DownloadUpdateTask *downloader = new DownloadUpdateTask(QString(), -1); + + // update fileOne, keep fileTwo, remove fileThree + QTest::newRow("test 1") + << downloader << (DownloadUpdateTask::VersionFileList() + << DownloadUpdateTask::VersionFileEntry{ + "tests/data/fileOne", 493, + DownloadUpdateTask::FileSourceList() + << DownloadUpdateTask::FileSource( + "http", "http://host/path/fileOne-1"), + "9eb84090956c484e32cb6c08455a667b"} + << DownloadUpdateTask::VersionFileEntry{ + "tests/data/fileTwo", 644, + DownloadUpdateTask::FileSourceList() + << DownloadUpdateTask::FileSource( + "http", "http://host/path/fileTwo-1"), + "38f94f54fa3eb72b0ea836538c10b043"} + << DownloadUpdateTask::VersionFileEntry{ + "tests/data/fileThree", 420, + DownloadUpdateTask::FileSourceList() + << DownloadUpdateTask::FileSource( + "http", "http://host/path/fileThree-1"), + "f12df554b21e320be6471d7154130e70"}) + << (DownloadUpdateTask::VersionFileList() + << DownloadUpdateTask::VersionFileEntry{ + "tests/data/fileOne", 493, + DownloadUpdateTask::FileSourceList() + << DownloadUpdateTask::FileSource("http", + "http://host/path/fileOne-2"), + "42915a71277c9016668cce7b82c6b577"} + << DownloadUpdateTask::VersionFileEntry{ + "tests/data/fileTwo", 644, + DownloadUpdateTask::FileSourceList() + << DownloadUpdateTask::FileSource("http", + "http://host/path/fileTwo-2"), + "38f94f54fa3eb72b0ea836538c10b043"}) + << (DownloadUpdateTask::UpdateOperationList() + << DownloadUpdateTask::UpdateOperation::DeleteOp("tests/data/fileThree") + << DownloadUpdateTask::UpdateOperation::CopyOp( + PathCombine(downloader->updateFilesDir(), + QString("tests/data/fileOne").replace("/", "_")), + "tests/data/fileOne", 493)); + } + void test_processFileLists() + { + QFETCH(DownloadUpdateTask *, downloader); + QFETCH(DownloadUpdateTask::VersionFileList, currentVersion); + QFETCH(DownloadUpdateTask::VersionFileList, newVersion); + QFETCH(DownloadUpdateTask::UpdateOperationList, expectedOperations); + + DownloadUpdateTask::UpdateOperationList operations; + + downloader->processFileLists(new NetJob("Dummy"), currentVersion, newVersion, + operations); + qDebug() << (operations == expectedOperations); + qDebug() << operations; + qDebug() << expectedOperations; + QCOMPARE(operations, expectedOperations); + } + + void test_masterTest() + { + QLOG_INFO() << "#####################"; + MMC->m_version.build = 1; + MMC->m_version.channel = "develop"; + auto channels = + QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/channels.json")); + auto root = QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")); + QLOG_DEBUG() << "channels: " << channels; + QLOG_DEBUG() << "root: " << root; + MMC->updateChecker()->setChannelListUrl(channels.toString()); + MMC->updateChecker()->setCurrentChannel("develop"); + + DownloadUpdateTask task(root.toString(), 2); + + QSignalSpy succeededSpy(&task, SIGNAL(succeeded())); + + task.start(); + + QVERIFY(succeededSpy.wait()); + } + + void test_OSXPathFixup() + { + QString path, pathOrig; + bool result; + // Proper OSX path + pathOrig = path = "MultiMC.app/Foo/Bar/Baz"; + qDebug() << "Proper OSX path: " << path; + result = DownloadUpdateTask::fixPathForOSX(path); + QCOMPARE(path, QString("../../Foo/Bar/Baz")); + QCOMPARE(result, true); + + // Bad OSX path + pathOrig = path = "translations/klingon.lol"; + qDebug() << "Bad OSX path: " << path; + result = DownloadUpdateTask::fixPathForOSX(path); + QCOMPARE(path, pathOrig); + QCOMPARE(result, false); + } +}; + +QTEST_GUILESS_MAIN_MULTIMC(DownloadUpdateTaskTest) + +#include "tst_DownloadUpdateTask.moc" diff --git a/tests/tst_UpdateChecker.cpp b/tests/tst_UpdateChecker.cpp new file mode 100644 index 00000000..162d0009 --- /dev/null +++ b/tests/tst_UpdateChecker.cpp @@ -0,0 +1,163 @@ +#include <QTest> +#include <QSignalSpy> + +#include "TestUtil.h" +#include "logic/updater/UpdateChecker.h" + +Q_DECLARE_METATYPE(UpdateChecker::ChannelListEntry) + +bool operator==(const UpdateChecker::ChannelListEntry &e1, const UpdateChecker::ChannelListEntry &e2) +{ + return e1.id == e2.id && + e1.name == e2.name && + e1.description == e2.description && + e1.url == e2.url; +} + +QDebug operator<<(QDebug dbg, const UpdateChecker::ChannelListEntry &c) +{ + dbg.nospace() << "ChannelListEntry(id=" << c.id << " name=" << c.name << " description=" << c.description << " url=" << c.url << ")"; + return dbg.maybeSpace(); +} + +class UpdateCheckerTest : public QObject +{ + Q_OBJECT +private +slots: + void initTestCase() + { + + } + void cleanupTestCase() + { + + } + + static QString findTestDataUrl(const char *file) + { + return QUrl::fromLocalFile(QFINDTESTDATA(file)).toString(); + } + void tst_ChannelListParsing_data() + { + QTest::addColumn<QString>("channel"); + QTest::addColumn<QString>("channelUrl"); + QTest::addColumn<bool>("hasChannels"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QList<UpdateChecker::ChannelListEntry> >("result"); + + QTest::newRow("garbage") + << QString() + << findTestDataUrl("tests/data/garbageChannels.json") + << false + << false + << QList<UpdateChecker::ChannelListEntry>(); + QTest::newRow("errors") + << QString() + << findTestDataUrl("tests/data/errorChannels.json") + << false + << true + << QList<UpdateChecker::ChannelListEntry>(); + QTest::newRow("no channels") + << QString() + << findTestDataUrl("tests/data/noChannels.json") + << false + << true + << QList<UpdateChecker::ChannelListEntry>(); + QTest::newRow("one channel") + << QString("develop") + << findTestDataUrl("tests/data/oneChannel.json") + << true + << true + << (QList<UpdateChecker::ChannelListEntry>() << UpdateChecker::ChannelListEntry{"develop", "Develop", "The channel called \"develop\"", "http://example.org/stuff"}); + QTest::newRow("several channels") + << QString("develop") + << findTestDataUrl("tests/data/channels.json") + << true + << true + << (QList<UpdateChecker::ChannelListEntry>() + << UpdateChecker::ChannelListEntry{"develop", "Develop", "The channel called \"develop\"", "$PWD/tests/data/"} + << UpdateChecker::ChannelListEntry{"stable", "Stable", "It's stable at least", "ftp://username@host/path/to/stuff"} + << UpdateChecker::ChannelListEntry{"42", "The Channel", "This is the channel that is going to answer all of your questions", "https://dent.me/tea"}); + } + void tst_ChannelListParsing() + { + QFETCH(QString, channel); + QFETCH(QString, channelUrl); + QFETCH(bool, hasChannels); + QFETCH(bool, valid); + QFETCH(QList<UpdateChecker::ChannelListEntry>, result); + + UpdateChecker checker; + + QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded())); + QVERIFY(channelListLoadedSpy.isValid()); + + checker.setCurrentChannel(channel); + checker.setChannelListUrl(channelUrl); + + checker.updateChanList(); + + if (valid) + { + QVERIFY(channelListLoadedSpy.wait()); + QCOMPARE(channelListLoadedSpy.size(), 1); + } + else + { + channelListLoadedSpy.wait(); + QCOMPARE(channelListLoadedSpy.size(), 0); + } + + QCOMPARE(checker.hasChannels(), hasChannels); + QCOMPARE(checker.getChannelList(), result); + } + + void tst_UpdateChecking_data() + { + QTest::addColumn<QString>("channel"); + QTest::addColumn<QString>("channelUrl"); + QTest::addColumn<int>("currentBuild"); + QTest::addColumn<QList<QVariant> >("result"); + + QTest::newRow("valid channel") + << "develop" << findTestDataUrl("tests/data/channels.json") + << 2 + << (QList<QVariant>() << QString() << "1.0.3" << 3); + } + + void tst_UpdateChecking() + { + QFETCH(QString, channel); + QFETCH(QString, channelUrl); + QFETCH(int, currentBuild); + QFETCH(QList<QVariant>, result); + + MMC->m_version.build = currentBuild; + + UpdateChecker checker; + checker.setCurrentChannel(channel); + checker.setChannelListUrl(channelUrl); + + QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(QString,QString,int))); + QVERIFY(updateAvailableSpy.isValid()); + QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded())); + QVERIFY(channelListLoadedSpy.isValid()); + + checker.updateChanList(); + QVERIFY(channelListLoadedSpy.wait()); + + checker.m_channels[0].url = QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(); + + checker.checkForUpdate(false); + + QVERIFY(updateAvailableSpy.wait()); + QList<QVariant> res = result; + res[0] = checker.m_channels[0].url; + QCOMPARE(updateAvailableSpy.first(), res); + } +}; + +QTEST_GUILESS_MAIN_MULTIMC(UpdateCheckerTest) + +#include "tst_UpdateChecker.moc" diff --git a/tests/tst_pathutils.cpp b/tests/tst_pathutils.cpp index 1e4a83bf..a1310d00 100644 --- a/tests/tst_pathutils.cpp +++ b/tests/tst_pathutils.cpp @@ -23,13 +23,12 @@ slots: QTest::addColumn<QString>("path1"); QTest::addColumn<QString>("path2"); -#if defined(Q_OS_UNIX) - QTest::newRow("unix 1") << "/abc/def/ghi/jkl" << "/abc/def" << "ghi/jkl"; - QTest::newRow("unix 2") << "/abc/def/ghi/jkl" << "/abc/def/" << "ghi/jkl"; -#elif defined(Q_OS_WIN) - QTest::newRow("win, from C:") << "C:\\abc" << "C:" << "abc\\def"; - QTest::newRow("win 1") << "C:\\abc\\def\\ghi\\jkl" << "C:\\abc\\def" << "ghi\\jkl"; - QTest::newRow("win 2") << "C:\\abc\\def\\ghi\\jkl" << "C:\\abc\\def\\" << "ghi\\jkl"; + QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc/def" << "ghi/jkl"; + QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/def/" << "ghi/jkl"; +#if defined(Q_OS_WIN) + QTest::newRow("win native, from C:") << "C:/abc" << "C:" << "abc"; + QTest::newRow("win native 1") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def" << "ghi\\jkl"; + QTest::newRow("win native 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\def\\" << "ghi\\jkl"; #endif } void test_PathCombine1() @@ -48,16 +47,15 @@ slots: QTest::addColumn<QString>("path2"); QTest::addColumn<QString>("path3"); -#if defined(Q_OS_UNIX) - QTest::newRow("unix 1") << "/abc/def/ghi/jkl" << "/abc" << "def" << "ghi/jkl"; - QTest::newRow("unix 2") << "/abc/def/ghi/jkl" << "/abc/" << "def" << "ghi/jkl"; - QTest::newRow("unix 3") << "/abc/def/ghi/jkl" << "/abc" << "def/" << "ghi/jkl"; - QTest::newRow("unix 4") << "/abc/def/ghi/jkl" << "/abc/" << "def/" << "ghi/jkl"; -#elif defined(Q_OS_WIN) - QTest::newRow("win 1") << "C:\\abc\\def\\ghi\\jkl" << "C:\\abc" << "def" << "ghi\\jkl"; - QTest::newRow("win 2") << "C:\\abc\\def\\ghi\\jkl" << "C:\\abc\\" << "def" << "ghi\\jkl"; - QTest::newRow("win 3") << "C:\\abc\\def\\ghi\\jkl" << "C:\\abc" << "def\\" << "ghi\\jkl"; - QTest::newRow("win 4") << "C:\\abc\\def\\ghi\\jkl" << "C:\\abc\\" << "def" << "ghi\\jkl"; + QTest::newRow("qt 1") << "/abc/def/ghi/jkl" << "/abc" << "def" << "ghi/jkl"; + QTest::newRow("qt 2") << "/abc/def/ghi/jkl" << "/abc/" << "def" << "ghi/jkl"; + QTest::newRow("qt 3") << "/abc/def/ghi/jkl" << "/abc" << "def/" << "ghi/jkl"; + QTest::newRow("qt 4") << "/abc/def/ghi/jkl" << "/abc/" << "def/" << "ghi/jkl"; +#if defined(Q_OS_WIN) + QTest::newRow("win 1") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def" << "ghi\\jkl"; + QTest::newRow("win 2") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl"; + QTest::newRow("win 3") << "C:/abc/def/ghi/jkl" << "C:\\abc" << "def\\" << "ghi\\jkl"; + QTest::newRow("win 4") << "C:/abc/def/ghi/jkl" << "C:\\abc\\" << "def" << "ghi\\jkl"; #endif } void test_PathCombine2() diff --git a/tests/tst_userutils.cpp b/tests/tst_userutils.cpp index 62bee985..3bc980c0 100644 --- a/tests/tst_userutils.cpp +++ b/tests/tst_userutils.cpp @@ -23,6 +23,9 @@ slots: QCOMPARE(Util::getDesktopDir(), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); } +// this is only valid on linux +// FIXME: implement on windows, OSX, then test. +#if defined(Q_OS_LINUX) void test_createShortcut_data() { QTest::addColumn<QString>("location"); @@ -40,7 +43,7 @@ slots: #if defined(Q_OS_LINUX) << MULTIMC_GET_TEST_FILE("data/tst_userutils-test_createShortcut-unix") #elif defined(Q_OS_WIN) - << QString() + << QByteArray() #endif ; } @@ -59,8 +62,10 @@ slots: //QDir().remove(location); } +#endif }; + QTEST_GUILESS_MAIN_MULTIMC(UserUtilsTest) #include "tst_userutils.moc" |