diff options
Diffstat (limited to '')
-rw-r--r-- | xbmc/test/CMakeLists.txt | 13 | ||||
-rw-r--r-- | xbmc/test/MtTestUtils.h | 45 | ||||
-rw-r--r-- | xbmc/test/TestBasicEnvironment.cpp | 122 | ||||
-rw-r--r-- | xbmc/test/TestBasicEnvironment.h | 25 | ||||
-rw-r--r-- | xbmc/test/TestDateTime.cpp | 660 | ||||
-rw-r--r-- | xbmc/test/TestDateTimeSpan.cpp | 80 | ||||
-rw-r--r-- | xbmc/test/TestFileItem.cpp | 132 | ||||
-rw-r--r-- | xbmc/test/TestTextureUtils.cpp | 51 | ||||
-rw-r--r-- | xbmc/test/TestURL.cpp | 72 | ||||
-rw-r--r-- | xbmc/test/TestUtil.cpp | 87 | ||||
-rw-r--r-- | xbmc/test/TestUtils.cpp | 324 | ||||
-rw-r--r-- | xbmc/test/TestUtils.h | 102 | ||||
-rw-r--r-- | xbmc/test/xbmc-test.cpp | 32 |
13 files changed, 1745 insertions, 0 deletions
diff --git a/xbmc/test/CMakeLists.txt b/xbmc/test/CMakeLists.txt new file mode 100644 index 0000000..7187270 --- /dev/null +++ b/xbmc/test/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SOURCES TestBasicEnvironment.cpp + TestFileItem.cpp + TestTextureUtils.cpp + TestURL.cpp + TestUtil.cpp + TestUtils.cpp + TestDateTime.cpp + TestDateTimeSpan.cpp) + +set(HEADERS TestBasicEnvironment.h + TestUtils.h) + +core_add_test_library(xbmc_test) diff --git a/xbmc/test/MtTestUtils.h b/xbmc/test/MtTestUtils.h new file mode 100644 index 0000000..e41dd5e --- /dev/null +++ b/xbmc/test/MtTestUtils.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005-2019 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "threads/SystemClock.h" + +#include <chrono> +#include <thread> + +namespace ConditionPoll +{ +/** + * This is usually enough time for the condition to have occurred in a test. + */ +constexpr unsigned int defaultTimeout{20000}; + +/** + * poll until the lambda returns true or the timeout occurs. If the timeout occurs then + * the function will return false. Otherwise it will return true. + */ +template<typename L> inline bool poll(unsigned int timeoutMillis, L lambda) +{ + XbmcThreads::EndTime<> endTime{std::chrono::milliseconds(timeoutMillis)}; + bool lastValue = false; + while (!endTime.IsTimePast() && (lastValue = lambda()) == false) + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + return lastValue; +} + +/** + * poll until the lambda returns true or the defaultTimeout occurs. If the timeout occurs then + * the function will return false. Otherwise it will return true. + */ +template<typename L> inline bool poll(L lambda) +{ + return poll(defaultTimeout, lambda); +} + +} diff --git a/xbmc/test/TestBasicEnvironment.cpp b/xbmc/test/TestBasicEnvironment.cpp new file mode 100644 index 0000000..7a35776 --- /dev/null +++ b/xbmc/test/TestBasicEnvironment.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "TestBasicEnvironment.h" + +#include "FileItem.h" +#include "ServiceBroker.h" +#include "ServiceManager.h" +#include "TestUtils.h" +#include "application/AppEnvironment.h" +#include "application/AppParams.h" +#include "application/Application.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" +#include "filesystem/SpecialProtocol.h" +#include "messaging/ApplicationMessenger.h" +#include "platform/Filesystem.h" +#include "profiles/ProfileManager.h" +#include "settings/SettingsComponent.h" +#include "windowing/WinSystem.h" + +#ifdef TARGET_DARWIN +#include "Util.h" +#endif + +#include <cstdio> +#include <cstdlib> +#include <climits> +#include <system_error> + +namespace fs = KODI::PLATFORM::FILESYSTEM; + +TestBasicEnvironment::TestBasicEnvironment() = default; + +void TestBasicEnvironment::SetUp() +{ + const auto params = std::make_shared<CAppParams>(); + params->SetPlatformDirectories(false); + + CAppEnvironment::SetUp(params); + + CServiceBroker::RegisterAppMessenger(std::make_shared<KODI::MESSAGING::CApplicationMessenger>()); + + XFILE::CFile *f; + + g_application.m_ServiceManager.reset(new CServiceManager()); + + if (!CXBMCTestUtils::Instance().SetReferenceFileBasePath()) + SetUpError(); + CXBMCTestUtils::Instance().setTestFileFactoryWriteInputFile( + XBMC_REF_FILE_PATH("xbmc/filesystem/test/reffile.txt") + ); + +//for darwin set framework path - else we get assert +//in guisettings init below +#ifdef TARGET_DARWIN + std::string frameworksPath = CUtil::GetFrameworksPath(); + CSpecialProtocol::SetXBMCFrameworksPath(frameworksPath); +#endif + /** + * @todo Something should be done about all the asserts in GUISettings so + * that the initialization of these components won't be needed. + */ + + /* Create a temporary directory and set it to be used throughout the + * test suite run. + */ + + std::error_code ec; + m_tempPath = fs::create_temp_directory(ec); + if (ec) + { + TearDown(); + SetUpError(); + } + + CSpecialProtocol::SetTempPath(m_tempPath); + CSpecialProtocol::SetProfilePath(m_tempPath); + + /* Create and delete a tempfile to initialize the VFS (really to initialize + * CLibcdio). This is done so that the initialization of the VFS does not + * affect the performance results of the test cases. + */ + /** @todo Make the initialization of the VFS here optional so it can be + * testable in a test case. + */ + f = XBMC_CREATETEMPFILE(""); + if (!f || !XBMC_DELETETEMPFILE(f)) + { + TearDown(); + SetUpError(); + } + + const CProfile profile("special://temp"); + CServiceBroker::GetSettingsComponent()->GetProfileManager()->AddProfile(profile); + CServiceBroker::GetSettingsComponent()->GetProfileManager()->CreateProfileFolders(); + + if (!g_application.m_ServiceManager->InitForTesting()) + exit(1); +} + +void TestBasicEnvironment::TearDown() +{ + XFILE::CDirectory::RemoveRecursive(m_tempPath); + + g_application.m_ServiceManager->DeinitTesting(); + + CServiceBroker::UnregisterAppMessenger(); + + CAppEnvironment::TearDown(); +} + +void TestBasicEnvironment::SetUpError() +{ + fprintf(stderr, "Setup of basic environment failed.\n"); + exit(EXIT_FAILURE); +} diff --git a/xbmc/test/TestBasicEnvironment.h b/xbmc/test/TestBasicEnvironment.h new file mode 100644 index 0000000..2b88dcc --- /dev/null +++ b/xbmc/test/TestBasicEnvironment.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include <string> + +#include <gtest/gtest.h> + +class TestBasicEnvironment : public testing::Environment +{ +public: + TestBasicEnvironment(); + + void SetUp() override; + void TearDown() override; +private: + void SetUpError(); + std::string m_tempPath; +}; diff --git a/xbmc/test/TestDateTime.cpp b/xbmc/test/TestDateTime.cpp new file mode 100644 index 0000000..7e51df8 --- /dev/null +++ b/xbmc/test/TestDateTime.cpp @@ -0,0 +1,660 @@ +/* + * Copyright (C) 2015-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "LangInfo.h" +#include "XBDateTime.h" +#include "guilib/LocalizeStrings.h" + +#include <array> +#include <iostream> + +#include <gtest/gtest.h> + +class TestDateTime : public testing::Test +{ +protected: + TestDateTime() = default; + ~TestDateTime() override = default; +}; + +TEST_F(TestDateTime, DateTimeOperators) +{ + CDateTime dateTime1(1991, 5, 14, 12, 34, 56); + CDateTime dateTime2(1991, 5, 14, 12, 34, 57); + + EXPECT_TRUE(dateTime1 < dateTime2); + EXPECT_FALSE(dateTime1 > dateTime2); + EXPECT_FALSE(dateTime1 == dateTime2); +} + +TEST_F(TestDateTime, FileTimeOperators) +{ + CDateTime dateTime1(1991, 5, 14, 12, 34, 56); + CDateTime dateTime2(1991, 5, 14, 12, 34, 57); + + KODI::TIME::FileTime fileTime1; + KODI::TIME::FileTime fileTime2; + + dateTime1.GetAsTimeStamp(fileTime1); + dateTime2.GetAsTimeStamp(fileTime2); + + CDateTime dateTime3(fileTime1); + + EXPECT_TRUE(dateTime3 < fileTime2); + EXPECT_FALSE(dateTime3 > fileTime2); + EXPECT_FALSE(dateTime3 == fileTime2); +} + +TEST_F(TestDateTime, SystemTimeOperators) +{ + CDateTime dateTime1(1991, 5, 14, 12, 34, 56); + CDateTime dateTime2(1991, 5, 14, 12, 34, 57); + + KODI::TIME::SystemTime systemTime; + dateTime2.GetAsSystemTime(systemTime); + + EXPECT_TRUE(dateTime1 < systemTime); + EXPECT_FALSE(dateTime1 > systemTime); + EXPECT_FALSE(dateTime1 == systemTime); +} + +TEST_F(TestDateTime, TimeTOperators) +{ + CDateTime dateTime1(1991, 5, 14, 12, 34, 56); + CDateTime dateTime2(1991, 5, 14, 12, 34, 57); + + time_t time; + dateTime2.GetAsTime(time); + + EXPECT_TRUE(dateTime1 < time); + EXPECT_FALSE(dateTime1 > time); + EXPECT_FALSE(dateTime1 == time); +} + +TEST_F(TestDateTime, TmOperators) +{ + { + CDateTime dateTime1(1991, 5, 14, 12, 34, 56); + + tm t1; + dateTime1.GetAsTm(t1); + + EXPECT_FALSE(dateTime1 < t1); + EXPECT_FALSE(dateTime1 > t1); + EXPECT_TRUE(dateTime1 == t1); + + CDateTime dateTime2(1991, 5, 14, 12, 34, 57); + + tm t2; + dateTime2.GetAsTm(t2); + + EXPECT_TRUE(dateTime1 < t2); + EXPECT_FALSE(dateTime1 > t2); + EXPECT_FALSE(dateTime1 == t2); + } + + // same test but opposite daylight saving + { + CDateTime dateTime1(1991, 1, 14, 12, 34, 56); + + tm t1; + dateTime1.GetAsTm(t1); + + EXPECT_FALSE(dateTime1 < t1); + EXPECT_FALSE(dateTime1 > t1); + EXPECT_TRUE(dateTime1 == t1); + + CDateTime dateTime2(1991, 1, 14, 12, 34, 57); + + tm t2; + dateTime2.GetAsTm(t2); + + EXPECT_TRUE(dateTime1 < t2); + EXPECT_FALSE(dateTime1 > t2); + EXPECT_FALSE(dateTime1 == t2); + } +} + +// no way to test this platform agnostically (for now) so just log it. +TEST_F(TestDateTime, GetCurrentDateTime) +{ + auto date = CDateTime::GetCurrentDateTime(); + std::cout << "Current Date: " << date.GetAsDBDateTime() << std::endl; +} + +// no way to test this platform agnostically (for now) so just log it. +TEST_F(TestDateTime, GetUTCDateTime) +{ + auto date = CDateTime::GetUTCDateTime(); + std::cout << "Current Date UTC: " << date.GetAsDBDateTime() << std::endl; +} + +TEST_F(TestDateTime, MonthStringToMonthNum) +{ + std::array<std::pair<std::string, std::string>, 12> months = {{ + {"Jan", "January"}, + {"Feb", "February"}, + {"Mar", "March"}, + {"Apr", "April"}, + {"May", "May"}, + {"Jun", "June"}, + {"Jul", "July"}, + {"Aug", "August"}, + {"Sep", "September"}, + {"Oct", "October"}, + {"Nov", "November"}, + {"Dec", "December"}, + }}; + + int i = 1; + for (const auto& month : months) + { + EXPECT_EQ(CDateTime::MonthStringToMonthNum(month.first), i); + EXPECT_EQ(CDateTime::MonthStringToMonthNum(month.second), i); + i++; + } +} + +// this method is broken as SetFromDBDate() will return true +TEST_F(TestDateTime, DISABLED_SetFromDateString) +{ + CDateTime dateTime; + EXPECT_TRUE(dateTime.SetFromDateString("tuesday may 14, 1991")); + + std::cout << "year: " << dateTime.GetYear() << std::endl; + std::cout << "month: " << dateTime.GetMonth() << std::endl; + std::cout << "day: " << dateTime.GetDay() << std::endl; + + EXPECT_EQ(dateTime.GetYear(), 1991); + EXPECT_EQ(dateTime.GetMonth(), 5); + EXPECT_EQ(dateTime.GetDay(), 14); +} + +TEST_F(TestDateTime, SetFromDBDate) +{ + CDateTime dateTime; + EXPECT_TRUE(dateTime.SetFromDBDate("1991-05-14")); + EXPECT_EQ(dateTime.GetYear(), 1991); + EXPECT_EQ(dateTime.GetMonth(), 5); + EXPECT_EQ(dateTime.GetDay(), 14); + + dateTime.Reset(); + EXPECT_TRUE(dateTime.SetFromDBDate("02-01-1993")); + EXPECT_EQ(dateTime.GetYear(), 1993); + EXPECT_EQ(dateTime.GetMonth(), 1); + EXPECT_EQ(dateTime.GetDay(), 2); +} + +// disabled on osx and freebsd as their mktime functions +// don't work for dates before 1900 +#if defined(TARGET_DARWIN_OSX) || defined(TARGET_FREEBSD) +TEST_F(TestDateTime, DISABLED_SetFromDBTime) +#else +TEST_F(TestDateTime, SetFromDBTime) +#endif +{ + CDateTime dateTime1; + EXPECT_TRUE(dateTime1.SetFromDBTime("12:34")); + EXPECT_EQ(dateTime1.GetHour(), 12); + EXPECT_EQ(dateTime1.GetMinute(), 34); + EXPECT_EQ(dateTime1.GetSecond(), 0); + + CDateTime dateTime2; + EXPECT_TRUE(dateTime2.SetFromDBTime("12:34:56")); + EXPECT_EQ(dateTime2.GetHour(), 12); + EXPECT_EQ(dateTime2.GetMinute(), 34); + EXPECT_EQ(dateTime2.GetSecond(), 56); +} + +TEST_F(TestDateTime, SetFromDBDateTime) +{ + CDateTime dateTime; + EXPECT_TRUE(dateTime.SetFromDBDateTime("1991-05-14 12:34:56")); + EXPECT_EQ(dateTime.GetYear(), 1991); + EXPECT_EQ(dateTime.GetMonth(), 5); + EXPECT_EQ(dateTime.GetDay(), 14); + EXPECT_EQ(dateTime.GetHour(), 12); + EXPECT_EQ(dateTime.GetMinute(), 34); + EXPECT_EQ(dateTime.GetSecond(), 56); +} + +TEST_F(TestDateTime, SetFromW3CDate) +{ + CDateTime dateTime; + EXPECT_TRUE(dateTime.SetFromW3CDate("1994-11-05T13:15:30Z")); + EXPECT_EQ(dateTime.GetYear(), 1994); + EXPECT_EQ(dateTime.GetMonth(), 11); + EXPECT_EQ(dateTime.GetDay(), 5); + EXPECT_EQ(dateTime.GetHour(), 0); + EXPECT_EQ(dateTime.GetMinute(), 0); + EXPECT_EQ(dateTime.GetSecond(), 0); +} + +TEST_F(TestDateTime, SetFromW3CDateTime) +{ + CDateTimeSpan bias = CDateTime::GetTimezoneBias(); + CDateTime dateTime; + dateTime.SetFromDBDateTime("1994-11-05 13:15:30"); + dateTime += bias; + std::string dateTimeStr = dateTime.GetAsDBDate() + "T" + dateTime.GetAsDBTime() + "Z"; + + CDateTime dateTime1; + EXPECT_TRUE(dateTime1.SetFromW3CDateTime(dateTimeStr)); + EXPECT_EQ(dateTime1.GetYear(), 1994); + EXPECT_EQ(dateTime1.GetMonth(), 11); + EXPECT_EQ(dateTime1.GetDay(), 5); + EXPECT_EQ(dateTime1.GetHour(), 13); + EXPECT_EQ(dateTime1.GetMinute(), 15); + EXPECT_EQ(dateTime1.GetSecond(), 30); + + CDateTime dateTime2; + EXPECT_TRUE(dateTime2.SetFromW3CDateTime("1994-11-05T08:15:30-05:00")); + EXPECT_EQ(dateTime2.GetYear(), 1994); + EXPECT_EQ(dateTime2.GetMonth(), 11); + EXPECT_EQ(dateTime2.GetDay(), 5); + EXPECT_EQ(dateTime2.GetHour(), 13); + EXPECT_EQ(dateTime2.GetMinute(), 15); + EXPECT_EQ(dateTime2.GetSecond(), 30); +} + +TEST_F(TestDateTime, SetFromUTCDateTime) +{ + CDateTimeSpan bias = CDateTime::GetTimezoneBias(); + + CDateTime dateTime1; + dateTime1.SetFromDBDateTime("1991-05-14 12:34:56"); + dateTime1 += bias; + + CDateTime dateTime2; + EXPECT_TRUE(dateTime2.SetFromUTCDateTime(dateTime1)); + EXPECT_EQ(dateTime2.GetYear(), 1991); + EXPECT_EQ(dateTime2.GetMonth(), 5); + EXPECT_EQ(dateTime2.GetDay(), 14); + EXPECT_EQ(dateTime2.GetHour(), 12); + EXPECT_EQ(dateTime2.GetMinute(), 34); + EXPECT_EQ(dateTime2.GetSecond(), 56); + + const time_t time = 674224496 + bias.GetSecondsTotal(); + + CDateTime dateTime3; + EXPECT_TRUE(dateTime3.SetFromUTCDateTime(time)); + EXPECT_EQ(dateTime3.GetYear(), 1991); + EXPECT_EQ(dateTime3.GetMonth(), 5); + EXPECT_EQ(dateTime3.GetDay(), 14); + EXPECT_EQ(dateTime3.GetHour(), 12); + EXPECT_EQ(dateTime3.GetMinute(), 34); + EXPECT_EQ(dateTime3.GetSecond(), 56); +} + +TEST_F(TestDateTime, SetFromRFC1123DateTime) +{ + std::string dateTime1("Mon, 21 Oct 2018 12:16:24 GMT"); + + CDateTime dateTime2; + EXPECT_TRUE(dateTime2.SetFromRFC1123DateTime(dateTime1)); + EXPECT_EQ(dateTime2.GetYear(), 2018); + EXPECT_EQ(dateTime2.GetMonth(), 10); + EXPECT_EQ(dateTime2.GetDay(), 21); + EXPECT_EQ(dateTime2.GetHour(), 12); + EXPECT_EQ(dateTime2.GetMinute(), 16); + EXPECT_EQ(dateTime2.GetSecond(), 24); +} + +TEST_F(TestDateTime, SetDateTime) +{ + CDateTime dateTime1; + EXPECT_TRUE(dateTime1.SetDateTime(1991, 05, 14, 12, 34, 56)); + EXPECT_EQ(dateTime1.GetYear(), 1991); + EXPECT_EQ(dateTime1.GetMonth(), 5); + EXPECT_EQ(dateTime1.GetDay(), 14); + EXPECT_EQ(dateTime1.GetHour(), 12); + EXPECT_EQ(dateTime1.GetMinute(), 34); + EXPECT_EQ(dateTime1.GetSecond(), 56); + + CDateTime dateTime2; + EXPECT_TRUE(dateTime2.SetDate(1991, 05, 14)); + EXPECT_EQ(dateTime2.GetYear(), 1991); + EXPECT_EQ(dateTime2.GetMonth(), 5); + EXPECT_EQ(dateTime2.GetDay(), 14); + EXPECT_EQ(dateTime2.GetHour(), 0); + EXPECT_EQ(dateTime2.GetMinute(), 0); + EXPECT_EQ(dateTime2.GetSecond(), 0); + +// disabled on osx and freebsd as their mktime functions +// don't work for dates before 1900 +#if !defined(TARGET_DARWIN_OSX) && !defined(TARGET_FREEBSD) + CDateTime dateTime3; + EXPECT_TRUE(dateTime3.SetTime(12, 34, 56)); + EXPECT_EQ(dateTime3.GetYear(), 1601); + EXPECT_EQ(dateTime3.GetMonth(), 1); + EXPECT_EQ(dateTime3.GetDay(), 1); + EXPECT_EQ(dateTime3.GetHour(), 12); + EXPECT_EQ(dateTime3.GetMinute(), 34); + EXPECT_EQ(dateTime3.GetSecond(), 56); +#endif +} + +TEST_F(TestDateTime, GetAsStrings) +{ + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + EXPECT_EQ(dateTime.GetAsSaveString(), "19910514_123456"); + EXPECT_EQ(dateTime.GetAsDBDateTime(), "1991-05-14 12:34:56"); + EXPECT_EQ(dateTime.GetAsDBDate(), "1991-05-14"); + EXPECT_EQ(dateTime.GetAsDBTime(), "12:34:56"); + EXPECT_EQ(dateTime.GetAsW3CDate(), "1991-05-14"); +} + +// disabled because we have no way to validate these values +// GetTimezoneBias() always returns a positive value so +// there is no way to detect the direction of the offset +TEST_F(TestDateTime, DISABLED_GetAsStringsWithBias) +{ + CDateTimeSpan bias = CDateTime::GetTimezoneBias(); + + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + CDateTime dateTimeWithBias(dateTime); + dateTimeWithBias += bias; + + EXPECT_EQ(dateTime.GetAsRFC1123DateTime(), "Tue, 14 May 1991 20:34:56 GMT"); + EXPECT_EQ(dateTime.GetAsW3CDateTime(false), "1991-05-14T12:34:56+08:00"); + EXPECT_EQ(dateTime.GetAsW3CDateTime(true), "1991-05-14T20:34:56Z"); +} + +TEST_F(TestDateTime, GetAsLocalized) +{ + // short date formats using "/" + // "DD/MM/YYYY", + // "MM/DD/YYYY", + // "YYYY/MM/DD", + // "D/M/YYYY", + // short date formats using "-" + // "DD-MM-YYYY", + // "MM-DD-YYYY", + // "YYYY-MM-DD", + // "YYYY-M-D", + // short date formats using "." + // "DD.MM.YYYY", + // "DD.M.YYYY", + // "D.M.YYYY", + // "D. M. YYYY", + // "YYYY.MM.DD" + + // "DDDD, D MMMM YYYY", + // "DDDD, DD MMMM YYYY", + // "DDDD, D. MMMM YYYY", + // "DDDD, DD. MMMM YYYY", + // "DDDD, MMMM D, YYYY", + // "DDDD, MMMM DD, YYYY", + // "DDDD D MMMM YYYY", + // "DDDD DD MMMM YYYY", + // "DDDD D. MMMM YYYY", + // "DDDD DD. MMMM YYYY", + // "D. MMMM YYYY", + // "DD. MMMM YYYY", + // "D. MMMM. YYYY", + // "DD. MMMM. YYYY", + // "YYYY. MMMM. D" + + ASSERT_TRUE(g_localizeStrings.Load(g_langInfo.GetLanguagePath(), "resource.language.en_gb")); + + // 24 hour clock must be set before time format + g_langInfo.Set24HourClock(false); + g_langInfo.SetTimeFormat("hh:mm:ss"); + + g_langInfo.SetShortDateFormat("MM/DD/YYYY"); + g_langInfo.SetLongDateFormat("DDDD, DD MMMM YYYY"); + + CDateTime dateTime1; + dateTime1.SetDateTime(1991, 05, 14, 12, 34, 56); + + // std::cout << "GetAsLocalizedDate: " << dateTime1.GetAsLocalizedDate(false) << std::endl; + // std::cout << "GetAsLocalizedDate: " << dateTime1.GetAsLocalizedDate(true) << std::endl; + // std::cout << "GetAsLocalizedDate: " << dateTime1.GetAsLocalizedDate(std::string("dd-mm-yyyy")) << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime1.GetAsLocalizedTime("hh-mm-ss", true) << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime1.GetAsLocalizedTime("hh-mm-ss", false) + // << std::endl; + // std::cout << "GetAsLocalizedDateTime: " << dateTime1.GetAsLocalizedDateTime(false, false) + // << std::endl; + // std::cout << "GetAsLocalizedDateTime: " << dateTime1.GetAsLocalizedDateTime(true, true) + // << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(0), false) + // << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(0), true) + // << std::endl; + + // std::cout << "1: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(1)) << std::endl; + // std::cout << "2: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(2)) << std::endl; + // std::cout << "3: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(3)) << std::endl; + // std::cout << "4: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(4)) << std::endl; + // std::cout << "5: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(5)) << std::endl; + // std::cout << "6: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(6)) << std::endl; + // std::cout << "7: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(7)) << std::endl; + // std::cout << "8: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(8)) << std::endl; + // std::cout << "14: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(14)) << std::endl; + // std::cout << "15: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(15)) << std::endl; + // std::cout << "16: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(16)) << std::endl; + // std::cout << "19: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(19)) << std::endl; + // std::cout << "27: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(27)) << std::endl; + // std::cout << "32: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(32)) << std::endl; + // std::cout << "64: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(64)) << std::endl; + // std::cout << "128: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(128)) << std::endl; + // std::cout << "256: " << dateTime1.GetAsLocalizedTime(TIME_FORMAT(256)) << std::endl; + + EXPECT_EQ(dateTime1.GetAsLocalizedDate(false), "05/14/1991"); + EXPECT_EQ(dateTime1.GetAsLocalizedDate(true), "Tuesday, 14 May 1991"); + EXPECT_EQ(dateTime1.GetAsLocalizedDate(std::string("dd-mm-yyyy")), + "14-05-1991"); // need to force overload function + EXPECT_EQ(dateTime1.GetAsLocalizedTime("hh-mm-ss", true), "12-34-56"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime("hh-mm-ss", false), "12-34"); + EXPECT_EQ(dateTime1.GetAsLocalizedDateTime(false, false), "05/14/1991 12:34"); + EXPECT_EQ(dateTime1.GetAsLocalizedDateTime(true, true), "Tuesday, 14 May 1991 12:34:56"); + + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(0), false), "12:34"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(0), true), "12:34:56"); + + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(1)), "56"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(2)), "34"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(3)), "34:56"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(4)), "12"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(5)), "12:56"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(6)), "12:34"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(7)), "12:34:56"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(8)), "PM"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(14)), "12:34 PM"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(15)), "12:34:56 PM"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(16)), "12"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(19)), "12:34:56"); + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(27)), "12:34:56 PM"); + + // not possible to use these three + // EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(32)), ""); + // EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(64)), ""); + // EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(128)), ""); + + EXPECT_EQ(dateTime1.GetAsLocalizedTime(TIME_FORMAT(256)), "34"); + + + // 24 hour clock must be set before time format + g_langInfo.Set24HourClock(true); + g_langInfo.SetTimeFormat("h:m:s"); + + g_langInfo.SetShortDateFormat("YYYY-M-D"); + g_langInfo.SetLongDateFormat("DDDD, MMMM D, YYYY"); + + CDateTime dateTime2; + dateTime2.SetDateTime(2020, 2, 3, 4, 5, 6); + + // std::cout << "GetAsLocalizedDate: " << dateTime2.GetAsLocalizedDate(false) << std::endl; + // std::cout << "GetAsLocalizedDate: " << dateTime2.GetAsLocalizedDate(true) << std::endl; + // std::cout << "GetAsLocalizedDate: " << dateTime2.GetAsLocalizedDate(std::string("dd-mm-yyyy")) << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime2.GetAsLocalizedTime("hh-mm-ss", true) << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime2.GetAsLocalizedTime("hh-mm-ss", false) + // << std::endl; + // std::cout << "GetAsLocalizedDateTime: " << dateTime2.GetAsLocalizedDateTime(false, false) + // << std::endl; + // std::cout << "GetAsLocalizedDateTime: " << dateTime2.GetAsLocalizedDateTime(true, true) + // << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(0), false) + // << std::endl; + // std::cout << "GetAsLocalizedTime: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(0), true) + // << std::endl; + + // std::cout << "1: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(1)) << std::endl; + // std::cout << "2: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(2)) << std::endl; + // std::cout << "3: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(3)) << std::endl; + // std::cout << "4: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(4)) << std::endl; + // std::cout << "5: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(5)) << std::endl; + // std::cout << "6: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(6)) << std::endl; + // std::cout << "7: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(7)) << std::endl; + // std::cout << "8: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(8)) << std::endl; + // std::cout << "14: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(14)) << std::endl; + // std::cout << "15: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(15)) << std::endl; + // std::cout << "16: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(16)) << std::endl; + // std::cout << "19: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(19)) << std::endl; + // std::cout << "27: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(27)) << std::endl; + // std::cout << "32: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(32)) << std::endl; + // std::cout << "64: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(64)) << std::endl; + // std::cout << "128: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(128)) << std::endl; + // std::cout << "256: " << dateTime2.GetAsLocalizedTime(TIME_FORMAT(256)) << std::endl; + + EXPECT_EQ(dateTime2.GetAsLocalizedDate(false), "2020-2-3"); + EXPECT_EQ(dateTime2.GetAsLocalizedDate(true), "Monday, February 3, 2020"); + EXPECT_EQ(dateTime2.GetAsLocalizedDate(std::string("dd-mm-yyyy")), + "03-02-2020"); // need to force overload function + EXPECT_EQ(dateTime2.GetAsLocalizedTime("hh-mm-ss", true), "04-05-06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime("hh-mm-ss", false), "04-05"); + EXPECT_EQ(dateTime2.GetAsLocalizedDateTime(false, false), "2020-2-3 4:5"); + EXPECT_EQ(dateTime2.GetAsLocalizedDateTime(true, true), "Monday, February 3, 2020 4:5:6"); + + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(0), false), "4:5"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(0), true), "4:5:6"); + + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(1)), "06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(2)), "05"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(3)), "05:06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(4)), "04"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(5)), "04:06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(6)), "04:05"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(7)), "04:05:06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(8)), ""); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(14)), "04:05"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(15)), "04:05:06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(16)), "4"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(19)), "4:05:06"); + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(27)), "4:05:06 AM"); + + // not possible to use these three + // EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(32)), ""); + // EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(64)), ""); + // EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(128)), ""); + + EXPECT_EQ(dateTime2.GetAsLocalizedTime(TIME_FORMAT(256)), "5"); +} + +TEST_F(TestDateTime, GetAsSystemTime) +{ + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + KODI::TIME::SystemTime systemTime; + dateTime.GetAsSystemTime(systemTime); + + EXPECT_TRUE(dateTime == systemTime); +} + +TEST_F(TestDateTime, GetAsTime) +{ + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + time_t time; + dateTime.GetAsTime(time); + + EXPECT_TRUE(dateTime == time); +} + +TEST_F(TestDateTime, GetAsTm) +{ + { + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + tm time; + dateTime.GetAsTm(time); + EXPECT_TRUE(dateTime == time); + } + + // same test but opposite daylight saving + { + CDateTime dateTime; + dateTime.SetDateTime(1991, 01, 14, 12, 34, 56); + + tm time; + dateTime.GetAsTm(time); + EXPECT_TRUE(dateTime == time); + } +} + +// Disabled pending std::chrono and std::date changes. +TEST_F(TestDateTime, DISABLED_GetAsTimeStamp) +{ + CDateTimeSpan bias = CDateTime::GetTimezoneBias(); + + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + KODI::TIME::FileTime fileTime; + dateTime.GetAsTimeStamp(fileTime); + dateTime += bias; + + EXPECT_TRUE(dateTime == fileTime); +} + +TEST_F(TestDateTime, GetAsUTCDateTime) +{ + CDateTimeSpan bias = CDateTime::GetTimezoneBias(); + + CDateTime dateTime1; + dateTime1.SetDateTime(1991, 05, 14, 12, 34, 56); + + CDateTime dateTime2; + dateTime2 = dateTime1.GetAsUTCDateTime(); + dateTime2 -= bias; + + EXPECT_EQ(dateTime2.GetYear(), 1991); + EXPECT_EQ(dateTime2.GetMonth(), 5); + EXPECT_EQ(dateTime2.GetDay(), 14); + EXPECT_EQ(dateTime2.GetHour(), 12); + EXPECT_EQ(dateTime2.GetMinute(), 34); + EXPECT_EQ(dateTime2.GetSecond(), 56); +} + +// disabled on osx and freebsd as their mktime functions +// don't work for dates before 1900 +#if defined(TARGET_DARWIN_OSX) || defined(TARGET_FREEBSD) +TEST_F(TestDateTime, DISABLED_Reset) +#else +TEST_F(TestDateTime, Reset) +#endif +{ + CDateTime dateTime; + dateTime.SetDateTime(1991, 05, 14, 12, 34, 56); + + dateTime.Reset(); + + EXPECT_EQ(dateTime.GetYear(), 1601); + EXPECT_EQ(dateTime.GetMonth(), 1); + EXPECT_EQ(dateTime.GetDay(), 1); + EXPECT_EQ(dateTime.GetHour(), 0); + EXPECT_EQ(dateTime.GetMinute(), 0); + EXPECT_EQ(dateTime.GetSecond(), 0); +} diff --git a/xbmc/test/TestDateTimeSpan.cpp b/xbmc/test/TestDateTimeSpan.cpp new file mode 100644 index 0000000..2ebdc59 --- /dev/null +++ b/xbmc/test/TestDateTimeSpan.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "XBDateTime.h" + +#include <gtest/gtest.h> + +class TestDateTimeSpan : public testing::Test +{ +protected: + TestDateTimeSpan() = default; + ~TestDateTimeSpan() override = default; +}; + +TEST_F(TestDateTimeSpan, Operators) +{ + CDateTimeSpan timeSpan1(1, 1, 1, 1); + CDateTimeSpan timeSpan2(2, 2, 2, 2); + + EXPECT_FALSE(timeSpan1 > timeSpan2); + EXPECT_TRUE(timeSpan1 < timeSpan2); + + CDateTimeSpan timeSpan3(timeSpan1); + EXPECT_TRUE(timeSpan1 == timeSpan3); + + EXPECT_TRUE((timeSpan1 + timeSpan3) == timeSpan2); + EXPECT_TRUE((timeSpan2 - timeSpan3) == timeSpan1); + + timeSpan1 += timeSpan3; + EXPECT_TRUE(timeSpan1 == timeSpan2); + + timeSpan1 -= timeSpan3; + EXPECT_TRUE(timeSpan1 == timeSpan3); +} + +TEST_F(TestDateTimeSpan, SetDateTimeSpan) +{ + CDateTimeSpan timeSpan; + int days = 1; + int hours = 2; + int minutes = 3; + int seconds = 4; + + int secondsTotal = (days * 24 * 60 * 60) + (hours * 60 * 60) + (minutes * 60) + seconds; + + timeSpan.SetDateTimeSpan(days, hours, minutes, seconds); + EXPECT_EQ(timeSpan.GetDays(), days); + EXPECT_EQ(timeSpan.GetHours(), hours); + EXPECT_EQ(timeSpan.GetMinutes(), minutes); + EXPECT_EQ(timeSpan.GetSeconds(), seconds); + EXPECT_EQ(timeSpan.GetSecondsTotal(), secondsTotal); +} + +TEST_F(TestDateTimeSpan, SetFromPeriod) +{ + CDateTimeSpan timeSpan; + + timeSpan.SetFromPeriod("3"); + EXPECT_EQ(timeSpan.GetDays(), 3); + + timeSpan.SetFromPeriod("3weeks"); + EXPECT_EQ(timeSpan.GetDays(), 21); + + timeSpan.SetFromPeriod("3months"); + EXPECT_EQ(timeSpan.GetDays(), 93); +} + +TEST_F(TestDateTimeSpan, SetFromTimeString) +{ + CDateTimeSpan timeSpan; + + timeSpan.SetFromTimeString("12:34"); + EXPECT_EQ(timeSpan.GetHours(), 12); + EXPECT_EQ(timeSpan.GetMinutes(), 34); +} diff --git a/xbmc/test/TestFileItem.cpp b/xbmc/test/TestFileItem.cpp new file mode 100644 index 0000000..e78ba27 --- /dev/null +++ b/xbmc/test/TestFileItem.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "FileItem.h" +#include "ServiceBroker.h" +#include "URL.h" +#include "settings/AdvancedSettings.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#include "settings/lib/SettingsManager.h" + +#include <gtest/gtest.h> + +using ::testing::Test; +using ::testing::WithParamInterface; +using ::testing::ValuesIn; + +struct TestFileData +{ + const char *file; + bool use_folder; + const char *base; +}; + +class AdvancedSettingsResetBase : public Test +{ +public: + AdvancedSettingsResetBase(); +}; + +AdvancedSettingsResetBase::AdvancedSettingsResetBase() +{ + // Force all advanced settings to be reset to defaults + const auto settings = CServiceBroker::GetSettingsComponent(); + CSettingsManager* settingsMgr = settings->GetSettings()->GetSettingsManager(); + settings->GetAdvancedSettings()->Uninitialize(*settingsMgr); + settings->GetAdvancedSettings()->Initialize(*settingsMgr); +} + +class TestFileItemSpecifiedArtJpg : public AdvancedSettingsResetBase, + public WithParamInterface<TestFileData> +{ +}; + + +TEST_P(TestFileItemSpecifiedArtJpg, GetLocalArt) +{ + CFileItem item; + item.SetPath(GetParam().file); + std::string path = CURL(item.GetLocalArt("art.jpg", GetParam().use_folder)).Get(); + std::string compare = CURL(GetParam().base).Get(); + EXPECT_EQ(compare, path); +} + +const TestFileData MovieFiles[] = {{ "c:\\dir\\filename.avi", false, "c:\\dir\\filename-art.jpg" }, + { "c:\\dir\\filename.avi", true, "c:\\dir\\art.jpg" }, + { "/dir/filename.avi", false, "/dir/filename-art.jpg" }, + { "/dir/filename.avi", true, "/dir/art.jpg" }, + { "smb://somepath/file.avi", false, "smb://somepath/file-art.jpg" }, + { "smb://somepath/file.avi", true, "smb://somepath/art.jpg" }, + { "stack:///path/to/movie-cd1.avi , /path/to/movie-cd2.avi", false, "/path/to/movie-art.jpg" }, + { "stack:///path/to/movie-cd1.avi , /path/to/movie-cd2.avi", true, "/path/to/art.jpg" }, + { "stack:///path/to/movie_name/cd1/some_file1.avi , /path/to/movie_name/cd2/some_file2.avi", true, "/path/to/movie_name/art.jpg" }, + { "/home/user/TV Shows/Dexter/S1/1x01.avi", false, "/home/user/TV Shows/Dexter/S1/1x01-art.jpg" }, + { "/home/user/TV Shows/Dexter/S1/1x01.avi", true, "/home/user/TV Shows/Dexter/S1/art.jpg" }, + { "zip://g%3a%5cmultimedia%5cmovies%5cSphere%2ezip/Sphere.avi", false, "g:\\multimedia\\movies\\Sphere-art.jpg" }, + { "zip://g%3a%5cmultimedia%5cmovies%5cSphere%2ezip/Sphere.avi", true, "g:\\multimedia\\movies\\art.jpg" }, + { "/home/user/movies/movie_name/video_ts/VIDEO_TS.IFO", false, "/home/user/movies/movie_name/art.jpg" }, + { "/home/user/movies/movie_name/video_ts/VIDEO_TS.IFO", true, "/home/user/movies/movie_name/art.jpg" }, + { "/home/user/movies/movie_name/BDMV/index.bdmv", false, "/home/user/movies/movie_name/art.jpg" }, + { "/home/user/movies/movie_name/BDMV/index.bdmv", true, "/home/user/movies/movie_name/art.jpg" }}; + +INSTANTIATE_TEST_SUITE_P(MovieFiles, TestFileItemSpecifiedArtJpg, ValuesIn(MovieFiles)); + +class TestFileItemFallbackArt : public AdvancedSettingsResetBase, + public WithParamInterface<TestFileData> +{ +}; + +TEST_P(TestFileItemFallbackArt, GetLocalArt) +{ + CFileItem item; + item.SetPath(GetParam().file); + std::string path = CURL(item.GetLocalArt("", GetParam().use_folder)).Get(); + std::string compare = CURL(GetParam().base).Get(); + EXPECT_EQ(compare, path); +} + +const TestFileData NoArtFiles[] = {{ "c:\\dir\\filename.avi", false, "c:\\dir\\filename.tbn" }, + { "/dir/filename.avi", false, "/dir/filename.tbn" }, + { "smb://somepath/file.avi", false, "smb://somepath/file.tbn" }, + { "/home/user/TV Shows/Dexter/S1/1x01.avi", false, "/home/user/TV Shows/Dexter/S1/1x01.tbn" }, + { "zip://g%3a%5cmultimedia%5cmovies%5cSphere%2ezip/Sphere.avi", false, "g:\\multimedia\\movies\\Sphere.tbn" }}; + +INSTANTIATE_TEST_SUITE_P(NoArt, TestFileItemFallbackArt, ValuesIn(NoArtFiles)); + +class TestFileItemBasePath : public AdvancedSettingsResetBase, + public WithParamInterface<TestFileData> +{ +}; + +TEST_P(TestFileItemBasePath, GetBaseMoviePath) +{ + CFileItem item; + item.SetPath(GetParam().file); + std::string path = CURL(item.GetBaseMoviePath(GetParam().use_folder)).Get(); + std::string compare = CURL(GetParam().base).Get(); + EXPECT_EQ(compare, path); +} + +const TestFileData BaseMovies[] = {{ "c:\\dir\\filename.avi", false, "c:\\dir\\filename.avi" }, + { "c:\\dir\\filename.avi", true, "c:\\dir\\" }, + { "/dir/filename.avi", false, "/dir/filename.avi" }, + { "/dir/filename.avi", true, "/dir/" }, + { "smb://somepath/file.avi", false, "smb://somepath/file.avi" }, + { "smb://somepath/file.avi", true, "smb://somepath/" }, + { "stack:///path/to/movie_name/cd1/some_file1.avi , /path/to/movie_name/cd2/some_file2.avi", false, "stack:///path/to/movie_name/cd1/some_file1.avi , /path/to/movie_name/cd2/some_file2.avi" }, + { "stack:///path/to/movie_name/cd1/some_file1.avi , /path/to/movie_name/cd2/some_file2.avi", true, "/path/to/movie_name/" }, + { "/home/user/TV Shows/Dexter/S1/1x01.avi", false, "/home/user/TV Shows/Dexter/S1/1x01.avi" }, + { "/home/user/TV Shows/Dexter/S1/1x01.avi", true, "/home/user/TV Shows/Dexter/S1/" }, + { "zip://g%3a%5cmultimedia%5cmovies%5cSphere%2ezip/Sphere.avi", true, "g:\\multimedia\\movies\\" }, + { "/home/user/movies/movie_name/video_ts/VIDEO_TS.IFO", false, "/home/user/movies/movie_name/" }, + { "/home/user/movies/movie_name/video_ts/VIDEO_TS.IFO", true, "/home/user/movies/movie_name/" }, + { "/home/user/movies/movie_name/BDMV/index.bdmv", false, "/home/user/movies/movie_name/" }, + { "/home/user/movies/movie_name/BDMV/index.bdmv", true, "/home/user/movies/movie_name/" }}; + +INSTANTIATE_TEST_SUITE_P(BaseNameMovies, TestFileItemBasePath, ValuesIn(BaseMovies)); diff --git a/xbmc/test/TestTextureUtils.cpp b/xbmc/test/TestTextureUtils.cpp new file mode 100644 index 0000000..a925e38 --- /dev/null +++ b/xbmc/test/TestTextureUtils.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "TextureDatabase.h" +#include "URL.h" + +#include <gtest/gtest.h> + +using ::testing::ValuesIn; + +namespace +{ +typedef struct +{ + const char *in; + const char *type; + const char *options; + const char *out; +} TestFiles; + +const TestFiles test_files[] = {{ "/path/to/image/file.jpg", "", "", "image://%2fpath%2fto%2fimage%2ffile.jpg/" }, + { "/path/to/image/file.jpg", "", "size=thumb", "image://%2fpath%2fto%2fimage%2ffile.jpg/transform?size=thumb" }, + { "/path/to/video/file.mkv", "video", "", "image://video@%2fpath%2fto%2fvideo%2ffile.mkv/" }, + { "/path/to/music/file.mp3", "music", "", "image://music@%2fpath%2fto%2fmusic%2ffile.mp3/" }, + { "image://%2fpath%2fto%2fimage%2ffile.jpg/", "", "", "image://%2fpath%2fto%2fimage%2ffile.jpg/" }, + { "image://%2fpath%2fto%2fimage%2ffile.jpg/transform?size=thumb", "", "size=thumb", "image://%2fpath%2fto%2fimage%2ffile.jpg/transform?size=thumb" }}; + + +class TestTextureUtils : + public ::testing::TestWithParam<TestFiles> +{ +}; + +TEST_P(TestTextureUtils, GetWrappedImageURL) +{ + const TestFiles &testFiles(GetParam()); + + std::string expected = testFiles.out; + std::string out = CTextureUtils::GetWrappedImageURL(testFiles.in, + testFiles.type, + testFiles.options); + EXPECT_EQ(expected, out); +} + +INSTANTIATE_TEST_SUITE_P(SampleFiles, TestTextureUtils, ValuesIn(test_files)); +} diff --git a/xbmc/test/TestURL.cpp b/xbmc/test/TestURL.cpp new file mode 100644 index 0000000..e74d3be --- /dev/null +++ b/xbmc/test/TestURL.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "URL.h" + +#include <gtest/gtest.h> + +using ::testing::Test; +using ::testing::WithParamInterface; +using ::testing::ValuesIn; + +struct TestURLGetWithoutUserDetailsData +{ + std::string input; + std::string expected; + bool redact; +}; + +std::ostream& operator<<(std::ostream& os, + const TestURLGetWithoutUserDetailsData& rhs) +{ + return os << "(Input: " << rhs.input << + "; Redact: " << (rhs.redact?"true":"false") << + "; Expected: " << rhs.expected << ")"; +} + +class TestURLGetWithoutUserDetails : public Test, + public WithParamInterface<TestURLGetWithoutUserDetailsData> +{ +}; + +TEST_P(TestURLGetWithoutUserDetails, GetWithoutUserDetails) +{ + CURL input(GetParam().input); + std::string result = input.GetWithoutUserDetails(GetParam().redact); + EXPECT_EQ(result, GetParam().expected); +} + +const TestURLGetWithoutUserDetailsData values[] = { + { std::string("smb://example.com/example"), std::string("smb://example.com/example"), false }, + { std::string("smb://example.com/example"), std::string("smb://example.com/example"), true }, + { std::string("smb://god:universe@example.com/example"), std::string("smb://example.com/example"), false }, + { std::string("smb://god@example.com/example"), std::string("smb://USERNAME@example.com/example"), true }, + { std::string("smb://god:universe@example.com/example"), std::string("smb://USERNAME:PASSWORD@example.com/example"), true }, + { std::string("http://god:universe@example.com:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@example.com:8448/example|auth=digest"), true }, + { std::string("smb://fd00::1/example"), std::string("smb://fd00::1/example"), false }, + { std::string("smb://fd00::1/example"), std::string("smb://fd00::1/example"), true }, + { std::string("smb://[fd00::1]:8080/example"), std::string("smb://[fd00::1]:8080/example"), false }, + { std::string("smb://[fd00::1]:8080/example"), std::string("smb://[fd00::1]:8080/example"), true }, + { std::string("smb://god:universe@[fd00::1]:8080/example"), std::string("smb://[fd00::1]:8080/example"), false }, + { std::string("smb://god@[fd00::1]:8080/example"), std::string("smb://USERNAME@[fd00::1]:8080/example"), true }, + { std::string("smb://god:universe@fd00::1/example"), std::string("smb://USERNAME:PASSWORD@fd00::1/example"), true }, + { std::string("http://god:universe@[fd00::1]:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@[fd00::1]:8448/example|auth=digest"), true }, + { std::string("smb://00ff:1:0000:abde::/example"), std::string("smb://00ff:1:0000:abde::/example"), true }, + { std::string("smb://god:universe@[00ff:1:0000:abde::]:8080/example"), std::string("smb://[00ff:1:0000:abde::]:8080/example"), false }, + { std::string("smb://god@[00ff:1:0000:abde::]:8080/example"), std::string("smb://USERNAME@[00ff:1:0000:abde::]:8080/example"), true }, + { std::string("smb://god:universe@00ff:1:0000:abde::/example"), std::string("smb://USERNAME:PASSWORD@00ff:1:0000:abde::/example"), true }, + { std::string("http://god:universe@[00ff:1:0000:abde::]:8448/example|auth=digest"), std::string("http://USERNAME:PASSWORD@[00ff:1:0000:abde::]:8448/example|auth=digest"), true }, + { std::string("smb://milkyway;god:universe@example.com/example"), std::string("smb://DOMAIN;USERNAME:PASSWORD@example.com/example"), true }, + { std::string("smb://milkyway;god@example.com/example"), std::string("smb://DOMAIN;USERNAME@example.com/example"), true }, + { std::string("smb://milkyway;@example.com/example"), std::string("smb://example.com/example"), true }, + { std::string("smb://milkyway;god:universe@example.com/example"), std::string("smb://example.com/example"), false }, + { std::string("smb://milkyway;god@example.com/example"), std::string("smb://example.com/example"), false }, + { std::string("smb://milkyway;@example.com/example"), std::string("smb://example.com/example"), false }, +}; + +INSTANTIATE_TEST_SUITE_P(URL, TestURLGetWithoutUserDetails, ValuesIn(values)); diff --git a/xbmc/test/TestUtil.cpp b/xbmc/test/TestUtil.cpp new file mode 100644 index 0000000..827c310 --- /dev/null +++ b/xbmc/test/TestUtil.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "Util.h" + +#include <gtest/gtest.h> + +TEST(TestUtil, GetQualifiedFilename) +{ + std::string file = "../foo"; + CUtil::GetQualifiedFilename("smb://", file); + EXPECT_EQ(file, "foo"); + file = "C:\\foo\\bar"; + CUtil::GetQualifiedFilename("smb://", file); + EXPECT_EQ(file, "C:\\foo\\bar"); + file = "../foo/./bar"; + CUtil::GetQualifiedFilename("smb://my/path", file); + EXPECT_EQ(file, "smb://my/foo/bar"); + file = "smb://foo/bar/"; + CUtil::GetQualifiedFilename("upnp://", file); + EXPECT_EQ(file, "smb://foo/bar/"); +} + +TEST(TestUtil, MakeLegalPath) +{ + std::string path; +#ifdef TARGET_WINDOWS + path = "C:\\foo\\bar"; + EXPECT_EQ(CUtil::MakeLegalPath(path), "C:\\foo\\bar"); + path = "C:\\foo:\\bar\\"; + EXPECT_EQ(CUtil::MakeLegalPath(path), "C:\\foo_\\bar\\"); +#else + path = "/foo/bar/"; + EXPECT_EQ(CUtil::MakeLegalPath(path),"/foo/bar/"); + path = "/foo?/bar"; + EXPECT_EQ(CUtil::MakeLegalPath(path),"/foo_/bar"); +#endif + path = "smb://foo/bar"; + EXPECT_EQ(CUtil::MakeLegalPath(path), "smb://foo/bar"); + path = "smb://foo/bar?/"; + EXPECT_EQ(CUtil::MakeLegalPath(path), "smb://foo/bar_/"); +} + +TEST(TestUtil, MakeShortenPath) +{ + std::string result; + EXPECT_EQ(true, CUtil::MakeShortenPath("smb://test/string/is/long/and/very/much/so", result, 10)); + EXPECT_EQ("smb:/../so", result); + + EXPECT_EQ(true, CUtil::MakeShortenPath("smb://test/string/is/long/and/very/much/so", result, 30)); + EXPECT_EQ("smb://../../../../../../../so", result); + + EXPECT_EQ(true, CUtil::MakeShortenPath("smb://test//string/is/long/and/very//much/so", result, 30)); + EXPECT_EQ("smb:/../../../../../so", result); + + EXPECT_EQ(true, CUtil::MakeShortenPath("//test//string/is/long/and/very//much/so", result, 30)); + EXPECT_EQ("/../../../../../so", result); +} + +TEST(TestUtil, ValidatePath) +{ + std::string path; +#ifdef TARGET_WINDOWS + path = "C:/foo/bar/"; + EXPECT_EQ(CUtil::ValidatePath(path), "C:\\foo\\bar\\"); + path = "C:\\\\foo\\\\bar\\"; + EXPECT_EQ(CUtil::ValidatePath(path, true), "C:\\foo\\bar\\"); + path = "\\\\foo\\\\bar\\"; + EXPECT_EQ(CUtil::ValidatePath(path, true), "\\\\foo\\bar\\"); +#else + path = "\\foo\\bar\\"; + EXPECT_EQ(CUtil::ValidatePath(path), "/foo/bar/"); + path = "/foo//bar/"; + EXPECT_EQ(CUtil::ValidatePath(path, true), "/foo/bar/"); +#endif + path = "smb://foo/bar/"; + EXPECT_EQ(CUtil::ValidatePath(path), "smb://foo/bar/"); + path = "smb://foo//bar/"; + EXPECT_EQ(CUtil::ValidatePath(path, true), "smb://foo/bar/"); + path = "smb:\\\\foo\\\\bar\\"; + EXPECT_EQ(CUtil::ValidatePath(path, true), "smb://foo/bar/"); +} diff --git a/xbmc/test/TestUtils.cpp b/xbmc/test/TestUtils.cpp new file mode 100644 index 0000000..1289c89 --- /dev/null +++ b/xbmc/test/TestUtils.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "TestUtils.h" +#include "Util.h" +#include "filesystem/File.h" +#include "filesystem/SpecialProtocol.h" +#include "platform/Filesystem.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" + +#ifdef TARGET_WINDOWS +#include <windows.h> +#else +#include <cstdlib> +#include <climits> +#include <ctime> +#endif + +#include <system_error> + +namespace fs = KODI::PLATFORM::FILESYSTEM; + +class CTempFile : public XFILE::CFile +{ +public: + CTempFile() = default; + ~CTempFile() + { + Delete(); + } + bool Create(const std::string &suffix) + { + std::error_code ec; + m_ptempFilePath = fs::temp_file_path(suffix, ec); + if (ec) + return false; + + if (m_ptempFilePath.empty()) + return false; + + OpenForWrite(m_ptempFilePath, true); + return true; + } + bool Delete() + { + Close(); + return CFile::Delete(m_ptempFilePath); + }; + std::string getTempFilePath() const + { + return m_ptempFilePath; + } + std::string getTempFileDirectory() const + { + return URIUtils::GetDirectory(m_ptempFilePath); + } +private: + std::string m_ptempFilePath; +}; + +CXBMCTestUtils::CXBMCTestUtils() +{ + probability = 0.01; +} + +CXBMCTestUtils &CXBMCTestUtils::Instance() +{ + static CXBMCTestUtils instance; + return instance; +} + +std::string CXBMCTestUtils::ReferenceFilePath(const std::string& path) +{ + return CSpecialProtocol::TranslatePath(URIUtils::AddFileToFolder("special://xbmc", path)); +} + +bool CXBMCTestUtils::SetReferenceFileBasePath() +{ + std::string xbmcPath = CUtil::GetHomePath(); + if (xbmcPath.empty()) + return false; + + /* Set xbmc, xbmcbin and home path */ + CSpecialProtocol::SetXBMCPath(xbmcPath); + CSpecialProtocol::SetXBMCBinPath(xbmcPath); + CSpecialProtocol::SetHomePath(URIUtils::AddFileToFolder(xbmcPath, "portable_data")); + + return true; +} + +XFILE::CFile *CXBMCTestUtils::CreateTempFile(std::string const& suffix) +{ + CTempFile *f = new CTempFile(); + if (f->Create(suffix)) + return f; + delete f; + return NULL; +} + +bool CXBMCTestUtils::DeleteTempFile(XFILE::CFile *tempfile) +{ + if (!tempfile) + return true; + CTempFile *f = static_cast<CTempFile*>(tempfile); + bool retval = f->Delete(); + delete f; + return retval; +} + +std::string CXBMCTestUtils::TempFilePath(XFILE::CFile const* const tempfile) +{ + if (!tempfile) + return ""; + CTempFile const* const f = static_cast<CTempFile const*>(tempfile); + return f->getTempFilePath(); +} + +std::string CXBMCTestUtils::TempFileDirectory(XFILE::CFile const* const tempfile) +{ + if (!tempfile) + return ""; + CTempFile const* const f = static_cast<CTempFile const*>(tempfile); + return f->getTempFileDirectory(); +} + +XFILE::CFile *CXBMCTestUtils::CreateCorruptedFile(std::string const& strFileName, + std::string const& suffix) +{ + XFILE::CFile inputfile, *tmpfile = CreateTempFile(suffix); + unsigned char buf[20], tmpchar; + ssize_t size, i; + + if (tmpfile && inputfile.Open(strFileName)) + { + srand(time(NULL)); + while ((size = inputfile.Read(buf, sizeof(buf))) > 0) + { + for (i = 0; i < size; i++) + { + if ((rand() % RAND_MAX) < (probability * RAND_MAX)) + { + tmpchar = buf[i]; + do + { + buf[i] = (rand() % 256); + } while (buf[i] == tmpchar); + } + } + if (tmpfile->Write(buf, size) < 0) + { + inputfile.Close(); + tmpfile->Close(); + DeleteTempFile(tmpfile); + return NULL; + } + } + inputfile.Close(); + tmpfile->Close(); + return tmpfile; + } + delete tmpfile; + return NULL; +} + + +std::vector<std::string> &CXBMCTestUtils::getTestFileFactoryReadUrls() +{ + return TestFileFactoryReadUrls; +} + +std::vector<std::string> &CXBMCTestUtils::getTestFileFactoryWriteUrls() +{ + return TestFileFactoryWriteUrls; +} + +std::string &CXBMCTestUtils::getTestFileFactoryWriteInputFile() +{ + return TestFileFactoryWriteInputFile; +} + +void CXBMCTestUtils::setTestFileFactoryWriteInputFile(std::string const& file) +{ + TestFileFactoryWriteInputFile = file; +} + +std::vector<std::string> &CXBMCTestUtils::getAdvancedSettingsFiles() +{ + return AdvancedSettingsFiles; +} + +std::vector<std::string> &CXBMCTestUtils::getGUISettingsFiles() +{ + return GUISettingsFiles; +} + +static const char usage[] = +"Kodi Test Suite\n" +"Usage: kodi-test [options]\n" +"\n" +"The following options are recognized by the kodi-test program.\n" +"\n" +" --add-testfilefactory-readurl [URL]\n" +" Add a url to be used int the TestFileFactory read tests.\n" +"\n" +" --add-testfilefactory-readurls [URLS]\n" +" Add multiple urls from a ',' delimited string of urls to be used\n" +" in the TestFileFactory read tests.\n" +"\n" +" --add-testfilefactory-writeurl [URL]\n" +" Add a url to be used int the TestFileFactory write tests.\n" +"\n" +" --add-testfilefactory-writeurls [URLS]\n" +" Add multiple urls from a ',' delimited string of urls to be used\n" +" in the TestFileFactory write tests.\n" +"\n" +" --set-testfilefactory-writeinputfile [FILE]\n" +" Set the path to the input file used in the TestFileFactory write tests.\n" +"\n" +" --add-advancedsettings-file [FILE]\n" +" Add an advanced settings file to be loaded in test cases that use them.\n" +"\n" +" --add-advancedsettings-files [FILES]\n" +" Add multiple advanced settings files from a ',' delimited string of\n" +" files to be loaded in test cases that use them.\n" +"\n" +" --add-guisettings-file [FILE]\n" +" Add a GUI settings file to be loaded in test cases that use them.\n" +"\n" +" --add-guisettings-files [FILES]\n" +" Add multiple GUI settings files from a ',' delimited string of\n" +" files to be loaded in test cases that use them.\n" +"\n" +" --set-probability [PROBABILITY]\n" +" Set the probability variable used by the file corrupting functions.\n" +" The variable should be a double type from 0.0 to 1.0. Values given\n" +" less than 0.0 are treated as 0.0. Values greater than 1.0 are treated\n" +" as 1.0. The default probability is 0.01.\n" +; + +void CXBMCTestUtils::ParseArgs(int argc, char **argv) +{ + int i; + std::string arg; + for (i = 1; i < argc; i++) + { + arg = argv[i]; + if (arg == "--add-testfilefactory-readurl") + { + TestFileFactoryReadUrls.emplace_back(argv[++i]); + } + else if (arg == "--add-testfilefactory-readurls") + { + arg = argv[++i]; + std::vector<std::string> urls = StringUtils::Split(arg, ","); + for (const auto& it : urls) + TestFileFactoryReadUrls.push_back(it); + } + else if (arg == "--add-testfilefactory-writeurl") + { + TestFileFactoryWriteUrls.emplace_back(argv[++i]); + } + else if (arg == "--add-testfilefactory-writeurls") + { + arg = argv[++i]; + std::vector<std::string> urls = StringUtils::Split(arg, ","); + for (const auto& it : urls) + TestFileFactoryWriteUrls.push_back(it); + } + else if (arg == "--set-testfilefactory-writeinputfile") + { + TestFileFactoryWriteInputFile = argv[++i]; + } + else if (arg == "--add-advancedsettings-file") + { + AdvancedSettingsFiles.emplace_back(argv[++i]); + } + else if (arg == "--add-advancedsettings-files") + { + arg = argv[++i]; + std::vector<std::string> urls = StringUtils::Split(arg, ","); + for (const auto& it : urls) + AdvancedSettingsFiles.push_back(it); + } + else if (arg == "--add-guisettings-file") + { + GUISettingsFiles.emplace_back(argv[++i]); + } + else if (arg == "--add-guisettings-files") + { + arg = argv[++i]; + std::vector<std::string> urls = StringUtils::Split(arg, ","); + for (const auto& it : urls) + GUISettingsFiles.push_back(it); + } + else if (arg == "--set-probability") + { + probability = atof(argv[++i]); + if (probability < 0.0) + probability = 0.0; + else if (probability > 1.0) + probability = 1.0; + } + else + { + std::cerr << usage; + exit(EXIT_FAILURE); + } + } +} + +std::string CXBMCTestUtils::getNewLineCharacters() const +{ +#ifdef TARGET_WINDOWS + return "\r\n"; +#else + return "\n"; +#endif +} diff --git a/xbmc/test/TestUtils.h b/xbmc/test/TestUtils.h new file mode 100644 index 0000000..b0dbcf6 --- /dev/null +++ b/xbmc/test/TestUtils.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include <string> +#include <vector> + +namespace XFILE +{ + class CFile; +} + +class CXBMCTestUtils +{ +public: + static CXBMCTestUtils &Instance(); + + /* ReferenceFilePath() is used to prepend a path with the location to the + * xbmc-test binary. It's assumed the test suite program will only be run + * with xbmc-test residing in the source tree. + */ + std::string ReferenceFilePath(const std::string& path); + + /* Function to set the reference file base path. */ + bool SetReferenceFileBasePath(); + + /* Function used in creating a temporary file. It accepts a parameter + * 'suffix' to append to the end of the tempfile path. The temporary + * file is return as a XFILE::CFile object. + */ + XFILE::CFile *CreateTempFile(std::string const& suffix); + + /* Function used to close and delete a temporary file previously created + * using CreateTempFile(). + */ + bool DeleteTempFile(XFILE::CFile *tempfile); + + /* Function to get path of a tempfile */ + std::string TempFilePath(XFILE::CFile const* const tempfile); + + /* Get the containing directory of a tempfile */ + std::string TempFileDirectory(XFILE::CFile const* const tempfile); + + /* Functions to get variables used in the TestFileFactory tests. */ + std::vector<std::string> &getTestFileFactoryReadUrls(); + + /* Function to get variables used in the TestFileFactory tests. */ + std::vector<std::string> &getTestFileFactoryWriteUrls(); + + /* Function to get the input file used in the TestFileFactory.Write tests. */ + std::string &getTestFileFactoryWriteInputFile(); + + /* Function to set the input file used in the TestFileFactory.Write tests */ + void setTestFileFactoryWriteInputFile(std::string const& file); + + /* Function to get advanced settings files. */ + std::vector<std::string> &getAdvancedSettingsFiles(); + + /* Function to get GUI settings files. */ + std::vector<std::string> &getGUISettingsFiles(); + + /* Function used in creating a corrupted file. The parameters are a URL + * to the original file to be corrupted and a suffix to append to the + * path of the newly created file. This will return a XFILE::CFile + * object which is itself a tempfile object which can be used with the + * tempfile functions of this utility class. + */ + XFILE::CFile *CreateCorruptedFile(std::string const& strFileName, + std::string const& suffix); + + /* Function to parse command line options */ + void ParseArgs(int argc, char **argv); + + /* Function to return the newline characters for this platform */ + std::string getNewLineCharacters() const; +private: + CXBMCTestUtils(); + CXBMCTestUtils(CXBMCTestUtils const&) = delete; + CXBMCTestUtils& operator=(CXBMCTestUtils const&) = delete; + + std::vector<std::string> TestFileFactoryReadUrls; + std::vector<std::string> TestFileFactoryWriteUrls; + std::string TestFileFactoryWriteInputFile; + + std::vector<std::string> AdvancedSettingsFiles; + std::vector<std::string> GUISettingsFiles; + + double probability; +}; + +#define XBMC_REF_FILE_PATH(s) CXBMCTestUtils::Instance().ReferenceFilePath(s) +#define XBMC_CREATETEMPFILE(a) CXBMCTestUtils::Instance().CreateTempFile(a) +#define XBMC_DELETETEMPFILE(a) CXBMCTestUtils::Instance().DeleteTempFile(a) +#define XBMC_TEMPFILEPATH(a) CXBMCTestUtils::Instance().TempFilePath(a) +#define XBMC_CREATECORRUPTEDFILE(a, b) \ + CXBMCTestUtils::Instance().CreateCorruptedFile(a, b) diff --git a/xbmc/test/xbmc-test.cpp b/xbmc/test/xbmc-test.cpp new file mode 100644 index 0000000..faafd5a --- /dev/null +++ b/xbmc/test/xbmc-test.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "TestBasicEnvironment.h" +#include "TestUtils.h" +#include "commons/ilog.h" +#include "threads/Thread.h" + +#include <cstdio> +#include <cstdlib> + +#include <gtest/gtest.h> + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + CXBMCTestUtils::Instance().ParseArgs(argc, argv); + + if (!testing::AddGlobalTestEnvironment(new TestBasicEnvironment())) + { + fprintf(stderr, "Unable to add basic test environment.\n"); + exit(EXIT_FAILURE); + } + int ret = RUN_ALL_TESTS(); + + return ret; +} |