summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/test
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
committermanuel <manuel@mausz.at>2020-10-19 00:52:24 +0200
commitbe933ef2241d79558f91796cc5b3a161f72ebf9c (patch)
treefe3ab2f130e20c99001f2d7a81d610c78c96a3f4 /xbmc/utils/test
parent5f8335c1e49ce108ef3481863833c98efa00411b (diff)
downloadkodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.gz
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.tar.bz2
kodi-pvr-build-be933ef2241d79558f91796cc5b3a161f72ebf9c.zip
sync with upstream
Diffstat (limited to 'xbmc/utils/test')
-rw-r--r--xbmc/utils/test/CMakeLists.txt53
-rw-r--r--xbmc/utils/test/CXBMCTinyXML-test.xml6
-rw-r--r--xbmc/utils/test/TestAlarmClock.cpp25
-rw-r--r--xbmc/utils/test/TestAliasShortcutUtils.cpp91
-rw-r--r--xbmc/utils/test/TestArchive.cpp411
-rw-r--r--xbmc/utils/test/TestBase64.cpp77
-rw-r--r--xbmc/utils/test/TestBitstreamStats.cpp58
-rw-r--r--xbmc/utils/test/TestCPUInfo.cpp72
-rw-r--r--xbmc/utils/test/TestCharsetConverter.cpp401
-rw-r--r--xbmc/utils/test/TestCrc32.cpp50
-rw-r--r--xbmc/utils/test/TestCryptThreading.cpp79
-rw-r--r--xbmc/utils/test/TestDatabaseUtils.cpp1376
-rw-r--r--xbmc/utils/test/TestDigest.cpp99
-rw-r--r--xbmc/utils/test/TestEndianSwap.cpp133
-rw-r--r--xbmc/utils/test/TestFileOperationJob.cpp288
-rw-r--r--xbmc/utils/test/TestFileUtils.cpp41
-rw-r--r--xbmc/utils/test/TestGlobalsHandling.cpp25
-rw-r--r--xbmc/utils/test/TestGlobalsHandlingPattern1.h40
-rw-r--r--xbmc/utils/test/TestHTMLUtil.cpp36
-rw-r--r--xbmc/utils/test/TestHttpHeader.cpp505
-rw-r--r--xbmc/utils/test/TestHttpParser.cpp49
-rw-r--r--xbmc/utils/test/TestHttpRangeUtils.cpp887
-rw-r--r--xbmc/utils/test/TestHttpResponse.cpp43
-rw-r--r--xbmc/utils/test/TestJSONVariantParser.cpp189
-rw-r--r--xbmc/utils/test/TestJSONVariantWriter.cpp151
-rw-r--r--xbmc/utils/test/TestJobManager.cpp215
-rw-r--r--xbmc/utils/test/TestLabelFormatter.cpp69
-rw-r--r--xbmc/utils/test/TestLangCodeExpander.cpp29
-rw-r--r--xbmc/utils/test/TestLocale.cpp272
-rw-r--r--xbmc/utils/test/TestMathUtils.cpp59
-rw-r--r--xbmc/utils/test/TestMime.cpp29
-rw-r--r--xbmc/utils/test/TestPOUtils.cpp47
-rw-r--r--xbmc/utils/test/TestRegExp.cpp169
-rw-r--r--xbmc/utils/test/TestRingBuffer.cpp33
-rw-r--r--xbmc/utils/test/TestScraperParser.cpp26
-rw-r--r--xbmc/utils/test/TestScraperUrl.cpp34
-rw-r--r--xbmc/utils/test/TestSortUtils.cpp123
-rw-r--r--xbmc/utils/test/TestStopwatch.cpp64
-rw-r--r--xbmc/utils/test/TestStreamDetails.cpp76
-rw-r--r--xbmc/utils/test/TestStreamUtils.cpp23
-rw-r--r--xbmc/utils/test/TestStringUtils.cpp605
-rw-r--r--xbmc/utils/test/TestSystemInfo.cpp326
-rw-r--r--xbmc/utils/test/TestURIUtils.cpp585
-rw-r--r--xbmc/utils/test/TestUrlOptions.cpp193
-rw-r--r--xbmc/utils/test/TestVariant.cpp334
-rw-r--r--xbmc/utils/test/TestXBMCTinyXML.cpp58
-rw-r--r--xbmc/utils/test/TestXMLUtils.cpp356
-rw-r--r--xbmc/utils/test/Testlog.cpp102
-rw-r--r--xbmc/utils/test/Testrfft.cpp41
-rw-r--r--xbmc/utils/test/data/language/Spanish/strings.po26
50 files changed, 9079 insertions, 0 deletions
diff --git a/xbmc/utils/test/CMakeLists.txt b/xbmc/utils/test/CMakeLists.txt
new file mode 100644
index 0000000..e953af6
--- /dev/null
+++ b/xbmc/utils/test/CMakeLists.txt
@@ -0,0 +1,53 @@
1set(SOURCES TestAlarmClock.cpp
2 TestAliasShortcutUtils.cpp
3 TestArchive.cpp
4 TestBase64.cpp
5 TestBitstreamStats.cpp
6 TestCharsetConverter.cpp
7 TestCPUInfo.cpp
8 TestCrc32.cpp
9 TestDatabaseUtils.cpp
10 TestDigest.cpp
11 TestEndianSwap.cpp
12 TestFileOperationJob.cpp
13 TestFileUtils.cpp
14 TestGlobalsHandling.cpp
15 TestHTMLUtil.cpp
16 TestHttpHeader.cpp
17 TestHttpParser.cpp
18 TestHttpRangeUtils.cpp
19 TestHttpResponse.cpp
20 TestJobManager.cpp
21 TestJSONVariantParser.cpp
22 TestJSONVariantWriter.cpp
23 TestLabelFormatter.cpp
24 TestLangCodeExpander.cpp
25 TestLocale.cpp
26 Testlog.cpp
27 TestMathUtils.cpp
28 TestMime.cpp
29 TestPOUtils.cpp
30 TestRegExp.cpp
31 Testrfft.cpp
32 TestRingBuffer.cpp
33 TestScraperParser.cpp
34 TestScraperUrl.cpp
35 TestSortUtils.cpp
36 TestStopwatch.cpp
37 TestStreamDetails.cpp
38 TestStreamUtils.cpp
39 TestStringUtils.cpp
40 TestSystemInfo.cpp
41 TestURIUtils.cpp
42 TestUrlOptions.cpp
43 TestVariant.cpp
44 TestXBMCTinyXML.cpp
45 TestXMLUtils.cpp)
46
47set(HEADERS TestGlobalsHandlingPattern1.h)
48
49if(NOT CORE_SYSTEM_NAME STREQUAL windows AND NOT CORE_SYSTEM_NAME STREQUAL windowsstore)
50 list(APPEND SOURCES TestCryptThreading.cpp)
51endif()
52
53core_add_test_library(utils_test)
diff --git a/xbmc/utils/test/CXBMCTinyXML-test.xml b/xbmc/utils/test/CXBMCTinyXML-test.xml
new file mode 100644
index 0000000..9444dc8
--- /dev/null
+++ b/xbmc/utils/test/CXBMCTinyXML-test.xml
@@ -0,0 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<details>
3 <url function="ParseTMDBRating" cache="tmdb-en-12244.json">
4 http://api.themoviedb.org/3/movie/12244?api_key=57983e31fb435df4df77afb854740ea9&language=en&#x3f;&#x003F;&#0063;
5 </url>
6</details>
diff --git a/xbmc/utils/test/TestAlarmClock.cpp b/xbmc/utils/test/TestAlarmClock.cpp
new file mode 100644
index 0000000..75ea84a
--- /dev/null
+++ b/xbmc/utils/test/TestAlarmClock.cpp
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/AlarmClock.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestAlarmClock, General)
14{
15 CAlarmClock a;
16 EXPECT_FALSE(a.IsRunning());
17 EXPECT_FALSE(a.HasAlarm("test"));
18 a.Start("test", 100.f, "test");
19 EXPECT_TRUE(a.IsRunning());
20 EXPECT_TRUE(a.HasAlarm("test"));
21 EXPECT_FALSE(a.HasAlarm("test2"));
22 EXPECT_NE(0.f, a.GetRemaining("test"));
23 EXPECT_EQ(0.f, a.GetRemaining("test2"));
24 a.Stop("test");
25}
diff --git a/xbmc/utils/test/TestAliasShortcutUtils.cpp b/xbmc/utils/test/TestAliasShortcutUtils.cpp
new file mode 100644
index 0000000..d36fd41
--- /dev/null
+++ b/xbmc/utils/test/TestAliasShortcutUtils.cpp
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/AliasShortcutUtils.h"
10#include "filesystem/File.h"
11#include "test/TestUtils.h"
12
13#if defined(TARGET_DARWIN_OSX)
14#include "platform/darwin/DarwinUtils.h"
15#endif
16#include <gtest/gtest.h>
17
18TEST(TestAliasShortcutUtils, IsAliasShortcut)
19{
20 XFILE::CFile *tmpFile = XBMC_CREATETEMPFILE("noaliastest");
21 std::string noalias = XBMC_TEMPFILEPATH(tmpFile);
22
23#if defined(TARGET_DARWIN_OSX)
24 XFILE::CFile *aliasDestFile = XBMC_CREATETEMPFILE("aliastest");
25 std::string alias = XBMC_TEMPFILEPATH(aliasDestFile);
26
27 //we only need the path here so delete the alias file
28 //which will be recreated as shortcut later:
29 XBMC_DELETETEMPFILE(aliasDestFile);
30
31 // create alias from a pointing to /Volumes
32 CDarwinUtils::CreateAliasShortcut(alias, "/Volumes");
33 EXPECT_TRUE(IsAliasShortcut(alias, true));
34 XFILE::CFile::Delete(alias);
35
36 // volumes is not a shortcut but a dir
37 EXPECT_FALSE(IsAliasShortcut("/Volumes", true));
38#endif
39
40 // a regular file is not a shortcut
41 EXPECT_FALSE(IsAliasShortcut(noalias, false));
42 XBMC_DELETETEMPFILE(tmpFile);
43
44 // empty string is not an alias
45 std::string emptyString;
46 EXPECT_FALSE(IsAliasShortcut(emptyString, false));
47
48 // non-existent file is no alias
49 std::string nonExistingFile="/IDontExistsNormally/somefile.txt";
50 EXPECT_FALSE(IsAliasShortcut(nonExistingFile, false));
51}
52
53TEST(TestAliasShortcutUtils, TranslateAliasShortcut)
54{
55 XFILE::CFile *tmpFile = XBMC_CREATETEMPFILE("noaliastest");
56 std::string noalias = XBMC_TEMPFILEPATH(tmpFile);
57 std::string noaliastemp = noalias;
58
59#if defined(TARGET_DARWIN_OSX)
60 XFILE::CFile *aliasDestFile = XBMC_CREATETEMPFILE("aliastest");
61 std::string alias = XBMC_TEMPFILEPATH(aliasDestFile);
62
63 //we only need the path here so delete the alias file
64 //which will be recreated as shortcut later:
65 XBMC_DELETETEMPFILE(aliasDestFile);
66
67 // create alias from a pointing to /Volumes
68 CDarwinUtils::CreateAliasShortcut(alias, "/Volumes");
69
70 // resolve the shortcut
71 TranslateAliasShortcut(alias);
72 EXPECT_STREQ("/Volumes", alias.c_str());
73 XFILE::CFile::Delete(alias);
74#endif
75
76 // translating a non-shortcut url should result in no change...
77 TranslateAliasShortcut(noaliastemp);
78 EXPECT_STREQ(noaliastemp.c_str(), noalias.c_str());
79 XBMC_DELETETEMPFILE(tmpFile);
80
81 //translate empty should stay empty
82 std::string emptyString;
83 TranslateAliasShortcut(emptyString);
84 EXPECT_STREQ("", emptyString.c_str());
85
86 // translate non-existent file should result in no change...
87 std::string nonExistingFile="/IDontExistsNormally/somefile.txt";
88 std::string resolvedNonExistingFile=nonExistingFile;
89 TranslateAliasShortcut(resolvedNonExistingFile);
90 EXPECT_STREQ(resolvedNonExistingFile.c_str(), nonExistingFile.c_str());
91}
diff --git a/xbmc/utils/test/TestArchive.cpp b/xbmc/utils/test/TestArchive.cpp
new file mode 100644
index 0000000..65023fd
--- /dev/null
+++ b/xbmc/utils/test/TestArchive.cpp
@@ -0,0 +1,411 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#if defined(TARGET_WINDOWS)
10# include <windows.h>
11#endif
12
13#include "utils/Archive.h"
14#include "utils/Variant.h"
15#include "filesystem/File.h"
16
17#include "test/TestUtils.h"
18
19#include <gtest/gtest.h>
20
21class TestArchive : public testing::Test
22{
23protected:
24 TestArchive()
25 {
26 file = XBMC_CREATETEMPFILE(".ar");
27 }
28 ~TestArchive() override
29 {
30 EXPECT_TRUE(XBMC_DELETETEMPFILE(file));
31 }
32 XFILE::CFile *file;
33};
34
35TEST_F(TestArchive, IsStoring)
36{
37 ASSERT_NE(nullptr, file);
38 CArchive arstore(file, CArchive::store);
39 EXPECT_TRUE(arstore.IsStoring());
40 EXPECT_FALSE(arstore.IsLoading());
41 arstore.Close();
42}
43
44TEST_F(TestArchive, IsLoading)
45{
46 ASSERT_NE(nullptr, file);
47 CArchive arload(file, CArchive::load);
48 EXPECT_TRUE(arload.IsLoading());
49 EXPECT_FALSE(arload.IsStoring());
50 arload.Close();
51}
52
53TEST_F(TestArchive, FloatArchive)
54{
55 ASSERT_NE(nullptr, file);
56 float float_ref = 1, float_var = 0;
57
58 CArchive arstore(file, CArchive::store);
59 arstore << float_ref;
60 arstore.Close();
61
62 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
63 CArchive arload(file, CArchive::load);
64 arload >> float_var;
65 arload.Close();
66
67 EXPECT_EQ(float_ref, float_var);
68}
69
70TEST_F(TestArchive, DoubleArchive)
71{
72 ASSERT_NE(nullptr, file);
73 double double_ref = 2, double_var = 0;
74
75 CArchive arstore(file, CArchive::store);
76 arstore << double_ref;
77 arstore.Close();
78
79 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
80 CArchive arload(file, CArchive::load);
81 arload >> double_var;
82 arload.Close();
83
84 EXPECT_EQ(double_ref, double_var);
85}
86
87TEST_F(TestArchive, IntegerArchive)
88{
89 ASSERT_NE(nullptr, file);
90 int int_ref = 3, int_var = 0;
91
92 CArchive arstore(file, CArchive::store);
93 arstore << int_ref;
94 arstore.Close();
95
96 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
97 CArchive arload(file, CArchive::load);
98 arload >> int_var;
99 arload.Close();
100
101 EXPECT_EQ(int_ref, int_var);
102}
103
104TEST_F(TestArchive, UnsignedIntegerArchive)
105{
106 ASSERT_NE(nullptr, file);
107 unsigned int unsigned_int_ref = 4, unsigned_int_var = 0;
108
109 CArchive arstore(file, CArchive::store);
110 arstore << unsigned_int_ref;
111 arstore.Close();
112
113 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
114 CArchive arload(file, CArchive::load);
115 arload >> unsigned_int_var;
116 arload.Close();
117
118 EXPECT_EQ(unsigned_int_ref, unsigned_int_var);
119}
120
121TEST_F(TestArchive, Int64tArchive)
122{
123 ASSERT_NE(nullptr, file);
124 int64_t int64_t_ref = 5, int64_t_var = 0;
125
126 CArchive arstore(file, CArchive::store);
127 arstore << int64_t_ref;
128 arstore.Close();
129
130 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
131 CArchive arload(file, CArchive::load);
132 arload >> int64_t_var;
133 arload.Close();
134
135 EXPECT_EQ(int64_t_ref, int64_t_var);
136}
137
138TEST_F(TestArchive, UInt64tArchive)
139{
140 ASSERT_NE(nullptr, file);
141 uint64_t uint64_t_ref = 6, uint64_t_var = 0;
142
143 CArchive arstore(file, CArchive::store);
144 arstore << uint64_t_ref;
145 arstore.Close();
146
147 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
148 CArchive arload(file, CArchive::load);
149 arload >> uint64_t_var;
150 arload.Close();
151
152 EXPECT_EQ(uint64_t_ref, uint64_t_var);
153}
154
155TEST_F(TestArchive, BoolArchive)
156{
157 ASSERT_NE(nullptr, file);
158 bool bool_ref = true, bool_var = false;
159
160 CArchive arstore(file, CArchive::store);
161 arstore << bool_ref;
162 arstore.Close();
163
164 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
165 CArchive arload(file, CArchive::load);
166 arload >> bool_var;
167 arload.Close();
168
169 EXPECT_EQ(bool_ref, bool_var);
170}
171
172TEST_F(TestArchive, CharArchive)
173{
174 ASSERT_NE(nullptr, file);
175 char char_ref = 'A', char_var = '\0';
176
177 CArchive arstore(file, CArchive::store);
178 arstore << char_ref;
179 arstore.Close();
180
181 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
182 CArchive arload(file, CArchive::load);
183 arload >> char_var;
184 arload.Close();
185
186 EXPECT_EQ(char_ref, char_var);
187}
188
189TEST_F(TestArchive, WStringArchive)
190{
191 ASSERT_NE(nullptr, file);
192 std::wstring wstring_ref = L"test wstring", wstring_var;
193
194 CArchive arstore(file, CArchive::store);
195 arstore << wstring_ref;
196 arstore.Close();
197
198 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
199 CArchive arload(file, CArchive::load);
200 arload >> wstring_var;
201 arload.Close();
202
203 EXPECT_STREQ(wstring_ref.c_str(), wstring_var.c_str());
204}
205
206TEST_F(TestArchive, StringArchive)
207{
208 ASSERT_NE(nullptr, file);
209 std::string string_ref = "test string", string_var;
210
211 CArchive arstore(file, CArchive::store);
212 arstore << string_ref;
213 arstore.Close();
214
215 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
216 CArchive arload(file, CArchive::load);
217 arload >> string_var;
218 arload.Close();
219
220 EXPECT_STREQ(string_ref.c_str(), string_var.c_str());
221}
222
223TEST_F(TestArchive, SystemTimeArchive)
224{
225 ASSERT_NE(nullptr, file);
226 KODI::TIME::SystemTime SystemTime_ref = {1, 2, 3, 4, 5, 6, 7, 8};
227 KODI::TIME::SystemTime SystemTime_var = {0, 0, 0, 0, 0, 0, 0, 0};
228
229 CArchive arstore(file, CArchive::store);
230 arstore << SystemTime_ref;
231 arstore.Close();
232
233 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
234 CArchive arload(file, CArchive::load);
235 arload >> SystemTime_var;
236 arload.Close();
237
238 EXPECT_TRUE(!memcmp(&SystemTime_ref, &SystemTime_var, sizeof(KODI::TIME::SystemTime)));
239}
240
241TEST_F(TestArchive, CVariantArchive)
242{
243 ASSERT_NE(nullptr, file);
244 CVariant CVariant_ref((int)1), CVariant_var;
245
246 CArchive arstore(file, CArchive::store);
247 arstore << CVariant_ref;
248 arstore.Close();
249
250 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
251 CArchive arload(file, CArchive::load);
252 arload >> CVariant_var;
253 arload.Close();
254
255 EXPECT_TRUE(CVariant_var.isInteger());
256 EXPECT_EQ(1, CVariant_var.asInteger());
257}
258
259TEST_F(TestArchive, CVariantArchiveString)
260{
261 ASSERT_NE(nullptr, file);
262 CVariant CVariant_ref("teststring"), CVariant_var;
263
264 CArchive arstore(file, CArchive::store);
265 arstore << CVariant_ref;
266 arstore.Close();
267
268 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
269 CArchive arload(file, CArchive::load);
270 arload >> CVariant_var;
271 arload.Close();
272
273 EXPECT_TRUE(CVariant_var.isString());
274 EXPECT_STREQ("teststring", CVariant_var.asString().c_str());
275}
276
277TEST_F(TestArchive, StringVectorArchive)
278{
279 ASSERT_NE(nullptr, file);
280 std::vector<std::string> strArray_ref, strArray_var;
281 strArray_ref.emplace_back("test strArray_ref 0");
282 strArray_ref.emplace_back("test strArray_ref 1");
283 strArray_ref.emplace_back("test strArray_ref 2");
284 strArray_ref.emplace_back("test strArray_ref 3");
285
286 CArchive arstore(file, CArchive::store);
287 arstore << strArray_ref;
288 arstore.Close();
289
290 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
291 CArchive arload(file, CArchive::load);
292 arload >> strArray_var;
293 arload.Close();
294
295 EXPECT_STREQ("test strArray_ref 0", strArray_var.at(0).c_str());
296 EXPECT_STREQ("test strArray_ref 1", strArray_var.at(1).c_str());
297 EXPECT_STREQ("test strArray_ref 2", strArray_var.at(2).c_str());
298 EXPECT_STREQ("test strArray_ref 3", strArray_var.at(3).c_str());
299}
300
301TEST_F(TestArchive, IntegerVectorArchive)
302{
303 ASSERT_NE(nullptr, file);
304 std::vector<int> iArray_ref, iArray_var;
305 iArray_ref.push_back(0);
306 iArray_ref.push_back(1);
307 iArray_ref.push_back(2);
308 iArray_ref.push_back(3);
309
310 CArchive arstore(file, CArchive::store);
311 arstore << iArray_ref;
312 arstore.Close();
313
314 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
315 CArchive arload(file, CArchive::load);
316 arload >> iArray_var;
317 arload.Close();
318
319 EXPECT_EQ(0, iArray_var.at(0));
320 EXPECT_EQ(1, iArray_var.at(1));
321 EXPECT_EQ(2, iArray_var.at(2));
322 EXPECT_EQ(3, iArray_var.at(3));
323}
324
325TEST_F(TestArchive, MultiTypeArchive)
326{
327 ASSERT_NE(nullptr, file);
328 float float_ref = 1, float_var = 0;
329 double double_ref = 2, double_var = 0;
330 int int_ref = 3, int_var = 0;
331 unsigned int unsigned_int_ref = 4, unsigned_int_var = 0;
332 int64_t int64_t_ref = 5, int64_t_var = 0;
333 uint64_t uint64_t_ref = 6, uint64_t_var = 0;
334 bool bool_ref = true, bool_var = false;
335 char char_ref = 'A', char_var = '\0';
336 std::string string_ref = "test string", string_var;
337 std::wstring wstring_ref = L"test wstring", wstring_var;
338 KODI::TIME::SystemTime SystemTime_ref = {1, 2, 3, 4, 5, 6, 7, 8};
339 KODI::TIME::SystemTime SystemTime_var = {0, 0, 0, 0, 0, 0, 0, 0};
340 CVariant CVariant_ref((int)1), CVariant_var;
341 std::vector<std::string> strArray_ref, strArray_var;
342 strArray_ref.emplace_back("test strArray_ref 0");
343 strArray_ref.emplace_back("test strArray_ref 1");
344 strArray_ref.emplace_back("test strArray_ref 2");
345 strArray_ref.emplace_back("test strArray_ref 3");
346 std::vector<int> iArray_ref, iArray_var;
347 iArray_ref.push_back(0);
348 iArray_ref.push_back(1);
349 iArray_ref.push_back(2);
350 iArray_ref.push_back(3);
351
352 CArchive arstore(file, CArchive::store);
353 EXPECT_TRUE(arstore.IsStoring());
354 EXPECT_FALSE(arstore.IsLoading());
355 arstore << float_ref;
356 arstore << double_ref;
357 arstore << int_ref;
358 arstore << unsigned_int_ref;
359 arstore << int64_t_ref;
360 arstore << uint64_t_ref;
361 arstore << bool_ref;
362 arstore << char_ref;
363 arstore << string_ref;
364 arstore << wstring_ref;
365 arstore << SystemTime_ref;
366 arstore << CVariant_ref;
367 arstore << strArray_ref;
368 arstore << iArray_ref;
369 arstore.Close();
370
371 ASSERT_EQ(0, file->Seek(0, SEEK_SET));
372 CArchive arload(file, CArchive::load);
373 EXPECT_TRUE(arload.IsLoading());
374 EXPECT_FALSE(arload.IsStoring());
375 arload >> float_var;
376 arload >> double_var;
377 arload >> int_var;
378 arload >> unsigned_int_var;
379 arload >> int64_t_var;
380 arload >> uint64_t_var;
381 arload >> bool_var;
382 arload >> char_var;
383 arload >> string_var;
384 arload >> wstring_var;
385 arload >> SystemTime_var;
386 arload >> CVariant_var;
387 arload >> strArray_var;
388 arload >> iArray_var;
389 arload.Close();
390
391 EXPECT_EQ(float_ref, float_var);
392 EXPECT_EQ(double_ref, double_var);
393 EXPECT_EQ(int_ref, int_var);
394 EXPECT_EQ(unsigned_int_ref, unsigned_int_var);
395 EXPECT_EQ(int64_t_ref, int64_t_var);
396 EXPECT_EQ(uint64_t_ref, uint64_t_var);
397 EXPECT_EQ(bool_ref, bool_var);
398 EXPECT_EQ(char_ref, char_var);
399 EXPECT_STREQ(string_ref.c_str(), string_var.c_str());
400 EXPECT_STREQ(wstring_ref.c_str(), wstring_var.c_str());
401 EXPECT_TRUE(!memcmp(&SystemTime_ref, &SystemTime_var, sizeof(KODI::TIME::SystemTime)));
402 EXPECT_TRUE(CVariant_var.isInteger());
403 EXPECT_STREQ("test strArray_ref 0", strArray_var.at(0).c_str());
404 EXPECT_STREQ("test strArray_ref 1", strArray_var.at(1).c_str());
405 EXPECT_STREQ("test strArray_ref 2", strArray_var.at(2).c_str());
406 EXPECT_STREQ("test strArray_ref 3", strArray_var.at(3).c_str());
407 EXPECT_EQ(0, iArray_var.at(0));
408 EXPECT_EQ(1, iArray_var.at(1));
409 EXPECT_EQ(2, iArray_var.at(2));
410 EXPECT_EQ(3, iArray_var.at(3));
411}
diff --git a/xbmc/utils/test/TestBase64.cpp b/xbmc/utils/test/TestBase64.cpp
new file mode 100644
index 0000000..8416378
--- /dev/null
+++ b/xbmc/utils/test/TestBase64.cpp
@@ -0,0 +1,77 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/Base64.h"
10
11#include <gtest/gtest.h>
12
13static const char refdata[] = "\x01\x02\x03\x04\x05\x06\x07\x08"
14 "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
15 "\x11\x12\x13\x14\x15\x16\x17\x18"
16 "\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
17 "\x21\x22\x23\x24\x25\x26\x27\x28"
18 "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30";
19
20static const char refbase64data[] = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcY"
21 "GRobHB0eHyAhIiMkJSYnKCkqKywtLi8w";
22
23TEST(TestBase64, Encode_1)
24{
25 std::string a;
26 Base64::Encode(refdata, sizeof(refdata) - 1, a);
27 EXPECT_STREQ(refbase64data, a.c_str());
28}
29
30TEST(TestBase64, Encode_2)
31{
32 std::string a;
33 a = Base64::Encode(refdata, sizeof(refdata) - 1);
34 EXPECT_STREQ(refbase64data, a.c_str());
35}
36
37TEST(TestBase64, Encode_3)
38{
39 std::string a;
40 Base64::Encode(refdata, a);
41 EXPECT_STREQ(refbase64data, a.c_str());
42}
43
44TEST(TestBase64, Encode_4)
45{
46 std::string a;
47 a = Base64::Encode(refdata);
48 EXPECT_STREQ(refbase64data, a.c_str());
49}
50
51TEST(TestBase64, Decode_1)
52{
53 std::string a;
54 Base64::Decode(refbase64data, sizeof(refbase64data) - 1, a);
55 EXPECT_STREQ(refdata, a.c_str());
56}
57
58TEST(TestBase64, Decode_2)
59{
60 std::string a;
61 a = Base64::Decode(refbase64data, sizeof(refbase64data) - 1);
62 EXPECT_STREQ(refdata, a.c_str());
63}
64
65TEST(TestBase64, Decode_3)
66{
67 std::string a;
68 Base64::Decode(refbase64data, a);
69 EXPECT_STREQ(refdata, a.c_str());
70}
71
72TEST(TestBase64, Decode_4)
73{
74 std::string a;
75 a = Base64::Decode(refbase64data);
76 EXPECT_STREQ(refdata, a.c_str());
77}
diff --git a/xbmc/utils/test/TestBitstreamStats.cpp b/xbmc/utils/test/TestBitstreamStats.cpp
new file mode 100644
index 0000000..69e4c88
--- /dev/null
+++ b/xbmc/utils/test/TestBitstreamStats.cpp
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "threads/Thread.h"
10#include "utils/BitstreamStats.h"
11
12#include <gtest/gtest.h>
13
14#define BITS (256 * 8)
15#define BYTES (256)
16
17class CTestBitstreamStatsThread : public CThread
18{
19public:
20 CTestBitstreamStatsThread() :
21 CThread("TestBitstreamStats"){}
22
23};
24
25TEST(TestBitstreamStats, General)
26{
27 int i;
28 BitstreamStats a;
29 CTestBitstreamStatsThread t;
30
31 i = 0;
32 a.Start();
33 EXPECT_EQ(0.0, a.GetBitrate());
34 EXPECT_EQ(0.0, a.GetMaxBitrate());
35 EXPECT_EQ(-1.0, a.GetMinBitrate());
36 while (i <= BITS)
37 {
38 a.AddSampleBits(1);
39 i++;
40 t.Sleep(1);
41 }
42 a.CalculateBitrate();
43 EXPECT_GT(a.GetBitrate(), 0.0);
44 EXPECT_GT(a.GetMaxBitrate(), 0.0);
45 EXPECT_GT(a.GetMinBitrate(), 0.0);
46
47 i = 0;
48 while (i <= BYTES)
49 {
50 a.AddSampleBytes(1);
51 t.Sleep(2);
52 i++;
53 }
54 a.CalculateBitrate();
55 EXPECT_GT(a.GetBitrate(), 0.0);
56 EXPECT_GT(a.GetMaxBitrate(), 0.0);
57 EXPECT_LE(a.GetMinBitrate(), a.GetMaxBitrate());
58}
diff --git a/xbmc/utils/test/TestCPUInfo.cpp b/xbmc/utils/test/TestCPUInfo.cpp
new file mode 100644
index 0000000..bd9572a
--- /dev/null
+++ b/xbmc/utils/test/TestCPUInfo.cpp
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#if defined(TARGET_WINDOWS)
10# include <windows.h>
11#endif
12
13#include "ServiceBroker.h"
14#include "settings/AdvancedSettings.h"
15#include "settings/SettingsComponent.h"
16#include "utils/CPUInfo.h"
17#include "utils/Temperature.h"
18#include "utils/XTimeUtils.h"
19
20#include <gtest/gtest.h>
21
22struct TestCPUInfo : public ::testing::Test
23{
24 TestCPUInfo() { CServiceBroker::RegisterCPUInfo(CCPUInfo::GetCPUInfo()); }
25
26 ~TestCPUInfo() { CServiceBroker::UnregisterCPUInfo(); }
27};
28
29TEST_F(TestCPUInfo, GetUsedPercentage)
30{
31 EXPECT_GE(CServiceBroker::GetCPUInfo()->GetUsedPercentage(), 0);
32}
33
34TEST_F(TestCPUInfo, GetCPUCount)
35{
36 EXPECT_GT(CServiceBroker::GetCPUInfo()->GetCPUCount(), 0);
37}
38
39TEST_F(TestCPUInfo, GetCPUFrequency)
40{
41 EXPECT_GE(CServiceBroker::GetCPUInfo()->GetCPUFrequency(), 0.f);
42}
43
44#if defined(TARGET_WINDOWS)
45TEST_F(TestCPUInfo, DISABLED_GetTemperature)
46#else
47TEST_F(TestCPUInfo, GetTemperature)
48#endif
49{
50 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_cpuTempCmd = "echo '50 c'";
51 CTemperature t;
52 EXPECT_TRUE(CServiceBroker::GetCPUInfo()->GetTemperature(t));
53 EXPECT_TRUE(t.IsValid());
54}
55
56TEST_F(TestCPUInfo, CoreInfo)
57{
58 ASSERT_TRUE(CServiceBroker::GetCPUInfo()->HasCoreId(0));
59 const CoreInfo c = CServiceBroker::GetCPUInfo()->GetCoreInfo(0);
60 EXPECT_TRUE(c.m_id == 0);
61}
62
63TEST_F(TestCPUInfo, GetCoresUsageString)
64{
65 EXPECT_STRNE("", CServiceBroker::GetCPUInfo()->GetCoresUsageString().c_str());
66}
67
68TEST_F(TestCPUInfo, GetCPUFeatures)
69{
70 unsigned int a = CServiceBroker::GetCPUInfo()->GetCPUFeatures();
71 (void)a;
72}
diff --git a/xbmc/utils/test/TestCharsetConverter.cpp b/xbmc/utils/test/TestCharsetConverter.cpp
new file mode 100644
index 0000000..f8736b7
--- /dev/null
+++ b/xbmc/utils/test/TestCharsetConverter.cpp
@@ -0,0 +1,401 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "ServiceBroker.h"
10#include "settings/Settings.h"
11#include "settings/SettingsComponent.h"
12#include "utils/CharsetConverter.h"
13#include "utils/Utf8Utils.h"
14
15#include <gtest/gtest.h>
16
17#if 0
18static const uint16_t refutf16LE1[] = { 0xff54, 0xff45, 0xff53, 0xff54,
19 0xff3f, 0xff55, 0xff54, 0xff46,
20 0xff11, 0xff16, 0xff2c, 0xff25,
21 0xff54, 0xff4f, 0xff57, 0x0 };
22
23static const uint16_t refutf16LE2[] = { 0xff54, 0xff45, 0xff53, 0xff54,
24 0xff3f, 0xff55, 0xff54, 0xff46,
25 0xff18, 0xff34, 0xff4f, 0xff1a,
26 0xff3f, 0xff43, 0xff48, 0xff41,
27 0xff52, 0xff53, 0xff45, 0xff54,
28 0xff3f, 0xff35, 0xff34, 0xff26,
29 0xff0d, 0xff11, 0xff16, 0xff2c,
30 0xff25, 0xff0c, 0xff3f, 0xff23,
31 0xff33, 0xff54, 0xff44, 0xff33,
32 0xff54, 0xff52, 0xff49, 0xff4e,
33 0xff47, 0xff11, 0xff16, 0x0 };
34#endif
35
36static const char refutf16LE3[] = "T\377E\377S\377T\377?\377S\377T\377"
37 "R\377I\377N\377G\377#\377H\377A\377"
38 "R\377S\377E\377T\377\064\377O\377\065"
39 "\377T\377F\377\030\377";
40
41#if 0
42static const uint16_t refutf16LE4[] = { 0xff54, 0xff45, 0xff53, 0xff54,
43 0xff3f, 0xff55, 0xff54, 0xff46,
44 0xff11, 0xff16, 0xff2c, 0xff25,
45 0xff54, 0xff4f, 0xff35, 0xff34,
46 0xff26, 0xff18, 0x0 };
47
48static const uint32_t refutf32LE1[] = { 0xff54, 0xff45, 0xff53, 0xff54,
49 0xff3f, 0xff55, 0xff54, 0xff46,
50 0xff18, 0xff34, 0xff4f, 0xff1a,
51 0xff3f, 0xff43, 0xff48, 0xff41,
52 0xff52, 0xff53, 0xff45, 0xff54,
53 0xff3f, 0xff35, 0xff34, 0xff26,
54 0xff0d, 0xff13, 0xff12, 0xff2c,
55 0xff25, 0xff0c, 0xff3f, 0xff23,
56 0xff33, 0xff54, 0xff44, 0xff33,
57 0xff54, 0xff52, 0xff49, 0xff4e,
58 0xff47, 0xff13, 0xff12, 0xff3f,
59#ifdef TARGET_DARWIN
60 0x0 };
61#else
62 0x1f42d, 0x1f42e, 0x0 };
63#endif
64
65static const uint16_t refutf16BE[] = { 0x54ff, 0x45ff, 0x53ff, 0x54ff,
66 0x3fff, 0x55ff, 0x54ff, 0x46ff,
67 0x11ff, 0x16ff, 0x22ff, 0x25ff,
68 0x54ff, 0x4fff, 0x35ff, 0x34ff,
69 0x26ff, 0x18ff, 0x0};
70
71static const uint16_t refucs2[] = { 0xff54, 0xff45, 0xff53, 0xff54,
72 0xff3f, 0xff55, 0xff43, 0xff53,
73 0xff12, 0xff54, 0xff4f, 0xff35,
74 0xff34, 0xff26, 0xff18, 0x0 };
75#endif
76
77class TestCharsetConverter : public testing::Test
78{
79protected:
80 TestCharsetConverter()
81 {
82 /* Add default settings for locale.
83 * Settings here are taken from CGUISettings::Initialize()
84 */
85 /*
86 //! @todo implement
87 CSettingsCategory *loc = CServiceBroker::GetSettingsComponent()->GetSettings()->AddCategory(7, "locale", 14090);
88 CServiceBroker::GetSettingsComponent()->GetSettings()->AddString(loc, CSettings::SETTING_LOCALE_LANGUAGE,248,"english",
89 SPIN_CONTROL_TEXT);
90 CServiceBroker::GetSettingsComponent()->GetSettings()->AddString(loc, CSettings::SETTING_LOCALE_COUNTRY, 20026, "USA",
91 SPIN_CONTROL_TEXT);
92 CServiceBroker::GetSettingsComponent()->GetSettings()->AddString(loc, CSettings::SETTING_LOCALE_CHARSET, 14091, "DEFAULT",
93 SPIN_CONTROL_TEXT); // charset is set by the
94 // language file
95
96 // Add default settings for subtitles
97 CSettingsCategory *sub = CServiceBroker::GetSettingsComponent()->GetSettings()->AddCategory(5, "subtitles", 287);
98 CServiceBroker::GetSettingsComponent()->GetSettings()->AddString(sub, CSettings::SETTING_SUBTITLES_CHARSET, 735, "DEFAULT",
99 SPIN_CONTROL_TEXT);
100 */
101 g_charsetConverter.reset();
102 g_charsetConverter.clear();
103 }
104
105 ~TestCharsetConverter() override
106 {
107 CServiceBroker::GetSettingsComponent()->GetSettings()->Unload();
108 }
109
110 std::string refstra1, refstra2, varstra1;
111 std::wstring refstrw1, varstrw1;
112 std::string refstr1;
113};
114
115TEST_F(TestCharsetConverter, utf8ToW)
116{
117 refstra1 = "test utf8ToW";
118 refstrw1 = L"test utf8ToW";
119 varstrw1.clear();
120 g_charsetConverter.utf8ToW(refstra1, varstrw1, true, false, false);
121 EXPECT_STREQ(refstrw1.c_str(), varstrw1.c_str());
122}
123
124
125//TEST_F(TestCharsetConverter, utf16LEtoW)
126//{
127// refstrw1 = L"test_utf16LEtow";
128// //! @todo Should be able to use '=' operator instead of assign()
129// std::wstring refstr16_1;
130// refstr16_1.assign(refutf16LE1);
131// varstrw1.clear();
132// g_charsetConverter.utf16LEtoW(refstr16_1, varstrw1);
133// EXPECT_STREQ(refstrw1.c_str(), varstrw1.c_str());
134//}
135
136TEST_F(TestCharsetConverter, subtitleCharsetToUtf8)
137{
138 refstra1 = "test subtitleCharsetToW";
139 varstra1.clear();
140 g_charsetConverter.subtitleCharsetToUtf8(refstra1, varstra1);
141
142 /* Assign refstra1 to refstrw1 so that we can compare */
143 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
144}
145
146TEST_F(TestCharsetConverter, utf8ToStringCharset_1)
147{
148 refstra1 = "test utf8ToStringCharset";
149 varstra1.clear();
150 g_charsetConverter.utf8ToStringCharset(refstra1, varstra1);
151 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
152}
153
154TEST_F(TestCharsetConverter, utf8ToStringCharset_2)
155{
156 refstra1 = "test utf8ToStringCharset";
157 varstra1 = "test utf8ToStringCharset";
158 g_charsetConverter.utf8ToStringCharset(varstra1);
159 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
160}
161
162TEST_F(TestCharsetConverter, utf8ToSystem)
163{
164 refstra1 = "test utf8ToSystem";
165 varstra1 = "test utf8ToSystem";
166 g_charsetConverter.utf8ToSystem(varstra1);
167 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
168}
169
170TEST_F(TestCharsetConverter, utf8To_ASCII)
171{
172 refstra1 = "test utf8To: charset ASCII, std::string";
173 varstra1.clear();
174 g_charsetConverter.utf8To("ASCII", refstra1, varstra1);
175 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
176}
177
178/*
179TEST_F(TestCharsetConverter, utf8To_UTF16LE)
180{
181 refstra1 = "test_utf8To:_charset_UTF-16LE,_"
182 "CStdString16";
183 refstr16_1.assign(refutf16LE2);
184 varstr16_1.clear();
185 g_charsetConverter.utf8To("UTF-16LE", refstra1, varstr16_1);
186 EXPECT_TRUE(!memcmp(refstr16_1.c_str(), varstr16_1.c_str(),
187 refstr16_1.length() * sizeof(uint16_t)));
188}
189*/
190
191//TEST_F(TestCharsetConverter, utf8To_UTF32LE)
192//{
193// refstra1 = "test_utf8To:_charset_UTF-32LE,_"
194//#ifdef TARGET_DARWIN
195///* OSX has its own 'special' utf-8 charset which we use (see UTF8_SOURCE in CharsetConverter.cpp)
196// which is basically NFD (decomposed) utf-8. The trouble is, it fails on the COW FACE and MOUSE FACE
197// characters for some reason (possibly anything over 0x100000, or maybe there's a decomposed form of these
198// that I couldn't find???) If UTF8_SOURCE is switched to UTF-8 then this test would pass as-is, but then
199// some filenames stored in utf8-mac wouldn't display correctly in the UI. */
200// "CStdString32_";
201//#else
202// "CStdString32_🐭🐮";
203//#endif
204// refstr32_1.assign(refutf32LE1);
205// varstr32_1.clear();
206// g_charsetConverter.utf8To("UTF-32LE", refstra1, varstr32_1);
207// EXPECT_TRUE(!memcmp(refstr32_1.c_str(), varstr32_1.c_str(),
208// sizeof(refutf32LE1)));
209//}
210
211TEST_F(TestCharsetConverter, stringCharsetToUtf8)
212{
213 refstra1 = "test_stringCharsetToUtf8";
214 varstra1.clear();
215 g_charsetConverter.ToUtf8("UTF-16LE", refutf16LE3, varstra1);
216 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
217}
218
219TEST_F(TestCharsetConverter, isValidUtf8_1)
220{
221 varstra1.clear();
222 g_charsetConverter.ToUtf8("UTF-16LE", refutf16LE3, varstra1);
223 EXPECT_TRUE(CUtf8Utils::isValidUtf8(varstra1.c_str()));
224}
225
226TEST_F(TestCharsetConverter, isValidUtf8_2)
227{
228 refstr1 = refutf16LE3;
229 EXPECT_FALSE(CUtf8Utils::isValidUtf8(refstr1));
230}
231
232TEST_F(TestCharsetConverter, isValidUtf8_3)
233{
234 varstra1.clear();
235 g_charsetConverter.ToUtf8("UTF-16LE", refutf16LE3, varstra1);
236 EXPECT_TRUE(CUtf8Utils::isValidUtf8(varstra1.c_str()));
237}
238
239TEST_F(TestCharsetConverter, isValidUtf8_4)
240{
241 EXPECT_FALSE(CUtf8Utils::isValidUtf8(refutf16LE3));
242}
243
244//! @todo Resolve correct input/output for this function
245// TEST_F(TestCharsetConverter, ucs2CharsetToStringCharset)
246// {
247// void ucs2CharsetToStringCharset(const std::wstring& strSource,
248// std::string& strDest, bool swap = false);
249// }
250
251TEST_F(TestCharsetConverter, wToUTF8)
252{
253 refstrw1 = L"test_wToUTF8";
254 refstra1 = u8"test_wToUTF8";
255 varstra1.clear();
256 g_charsetConverter.wToUTF8(refstrw1, varstra1);
257 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
258}
259
260//TEST_F(TestCharsetConverter, utf16BEtoUTF8)
261//{
262// refstr16_1.assign(refutf16BE);
263// refstra1 = "test_utf16BEtoUTF8";
264// varstra1.clear();
265// g_charsetConverter.utf16BEtoUTF8(refstr16_1, varstra1);
266// EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
267//}
268
269//TEST_F(TestCharsetConverter, utf16LEtoUTF8)
270//{
271// refstr16_1.assign(refutf16LE4);
272// refstra1 = "test_utf16LEtoUTF8";
273// varstra1.clear();
274// g_charsetConverter.utf16LEtoUTF8(refstr16_1, varstra1);
275// EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
276//}
277
278//TEST_F(TestCharsetConverter, ucs2ToUTF8)
279//{
280// refstr16_1.assign(refucs2);
281// refstra1 = "test_ucs2toUTF8";
282// varstra1.clear();
283// g_charsetConverter.ucs2ToUTF8(refstr16_1, varstra1);
284// EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
285//}
286
287TEST_F(TestCharsetConverter, utf8logicalToVisualBiDi)
288{
289 refstra1 = "test_utf8logicalToVisualBiDi";
290 refstra2 = "test_utf8logicalToVisualBiDi";
291 varstra1.clear();
292 g_charsetConverter.utf8logicalToVisualBiDi(refstra1, varstra1);
293 EXPECT_STREQ(refstra2.c_str(), varstra1.c_str());
294}
295
296//! @todo Resolve correct input/output for this function
297// TEST_F(TestCharsetConverter, utf32ToStringCharset)
298// {
299// void utf32ToStringCharset(const unsigned long* strSource, std::string& strDest);
300// }
301
302TEST_F(TestCharsetConverter, getCharsetLabels)
303{
304 std::vector<std::string> reflabels;
305 reflabels.emplace_back("Western Europe (ISO)");
306 reflabels.emplace_back("Central Europe (ISO)");
307 reflabels.emplace_back("South Europe (ISO)");
308 reflabels.emplace_back("Baltic (ISO)");
309 reflabels.emplace_back("Cyrillic (ISO)");
310 reflabels.emplace_back("Arabic (ISO)");
311 reflabels.emplace_back("Greek (ISO)");
312 reflabels.emplace_back("Hebrew (ISO)");
313 reflabels.emplace_back("Turkish (ISO)");
314 reflabels.emplace_back("Central Europe (Windows)");
315 reflabels.emplace_back("Cyrillic (Windows)");
316 reflabels.emplace_back("Western Europe (Windows)");
317 reflabels.emplace_back("Greek (Windows)");
318 reflabels.emplace_back("Turkish (Windows)");
319 reflabels.emplace_back("Hebrew (Windows)");
320 reflabels.emplace_back("Arabic (Windows)");
321 reflabels.emplace_back("Baltic (Windows)");
322 reflabels.emplace_back("Vietnamese (Windows)");
323 reflabels.emplace_back("Thai (Windows)");
324 reflabels.emplace_back("Chinese Traditional (Big5)");
325 reflabels.emplace_back("Chinese Simplified (GBK)");
326 reflabels.emplace_back("Japanese (Shift-JIS)");
327 reflabels.emplace_back("Korean");
328 reflabels.emplace_back("Hong Kong (Big5-HKSCS)");
329
330 std::vector<std::string> varlabels = g_charsetConverter.getCharsetLabels();
331 ASSERT_EQ(reflabels.size(), varlabels.size());
332
333 size_t pos = 0;
334 for (const auto& it : varlabels)
335 {
336 EXPECT_STREQ((reflabels.at(pos++)).c_str(), it.c_str());
337 }
338}
339
340TEST_F(TestCharsetConverter, getCharsetLabelByName)
341{
342 std::string varstr =
343 g_charsetConverter.getCharsetLabelByName("ISO-8859-1");
344 EXPECT_STREQ("Western Europe (ISO)", varstr.c_str());
345 varstr.clear();
346 varstr = g_charsetConverter.getCharsetLabelByName("Bogus");
347 EXPECT_STREQ("", varstr.c_str());
348}
349
350TEST_F(TestCharsetConverter, getCharsetNameByLabel)
351{
352 std::string varstr =
353 g_charsetConverter.getCharsetNameByLabel("Western Europe (ISO)");
354 EXPECT_STREQ("ISO-8859-1", varstr.c_str());
355 varstr.clear();
356 varstr = g_charsetConverter.getCharsetNameByLabel("Bogus");
357 EXPECT_STREQ("", varstr.c_str());
358}
359
360TEST_F(TestCharsetConverter, unknownToUTF8_1)
361{
362 refstra1 = "test_unknownToUTF8";
363 varstra1 = "test_unknownToUTF8";
364 g_charsetConverter.unknownToUTF8(varstra1);
365 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
366}
367
368TEST_F(TestCharsetConverter, unknownToUTF8_2)
369{
370 refstra1 = "test_unknownToUTF8";
371 varstra1.clear();
372 g_charsetConverter.unknownToUTF8(refstra1, varstra1);
373 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
374}
375
376TEST_F(TestCharsetConverter, toW)
377{
378 refstra1 = "test_toW:_charset_UTF-16LE";
379 refstrw1 = L"\xBDEF\xEF94\x85BD\xBDEF\xEF93\x94BD\xBCEF\xEFBF"
380 L"\x94BD\xBDEF\xEF8F\xB7BC\xBCEF\xEF9A\xBFBC\xBDEF"
381 L"\xEF83\x88BD\xBDEF\xEF81\x92BD\xBDEF\xEF93\x85BD"
382 L"\xBDEF\xEF94\xBFBC\xBCEF\xEFB5\xB4BC\xBCEF\xEFA6"
383 L"\x8DBC\xBCEF\xEF91\x96BC\xBCEF\xEFAC\xA5BC";
384 varstrw1.clear();
385 g_charsetConverter.toW(refstra1, varstrw1, "UTF-16LE");
386 EXPECT_STREQ(refstrw1.c_str(), varstrw1.c_str());
387}
388
389TEST_F(TestCharsetConverter, fromW)
390{
391 refstrw1 = L"\xBDEF\xEF94\x85BD\xBDEF\xEF93\x94BD\xBCEF\xEFBF"
392 L"\x86BD\xBDEF\xEF92\x8FBD\xBDEF\xEF8D\xB7BC\xBCEF"
393 L"\xEF9A\xBFBC\xBDEF\xEF83\x88BD\xBDEF\xEF81\x92BD"
394 L"\xBDEF\xEF93\x85BD\xBDEF\xEF94\xBFBC\xBCEF\xEFB5"
395 L"\xB4BC\xBCEF\xEFA6\x8DBC\xBCEF\xEF91\x96BC\xBCEF"
396 L"\xEFAC\xA5BC";
397 refstra1 = "test_fromW:_charset_UTF-16LE";
398 varstra1.clear();
399 g_charsetConverter.fromW(refstrw1, varstra1, "UTF-16LE");
400 EXPECT_STREQ(refstra1.c_str(), varstra1.c_str());
401}
diff --git a/xbmc/utils/test/TestCrc32.cpp b/xbmc/utils/test/TestCrc32.cpp
new file mode 100644
index 0000000..99a2dd5
--- /dev/null
+++ b/xbmc/utils/test/TestCrc32.cpp
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/Crc32.h"
10
11#include <gtest/gtest.h>
12
13static const char refdata[] = "abcdefghijklmnopqrstuvwxyz"
14 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
15 "01234567890!@#$%^&*()";
16
17TEST(TestCrc32, Compute_1)
18{
19 Crc32 a;
20 uint32_t varcrc;
21 a.Compute(refdata, sizeof(refdata) - 1);
22 varcrc = a;
23 EXPECT_EQ(0xa4eb60e3, varcrc);
24}
25
26TEST(TestCrc32, Compute_2)
27{
28 uint32_t varcrc;
29 std::string s = refdata;
30 varcrc = Crc32::Compute(s);
31 EXPECT_EQ(0xa4eb60e3, varcrc);
32}
33
34TEST(TestCrc32, ComputeFromLowerCase)
35{
36 std::string s = refdata;
37 uint32_t varcrc = Crc32::ComputeFromLowerCase(s);
38 EXPECT_EQ((uint32_t)0x7f045b3e, varcrc);
39}
40
41TEST(TestCrc32, Reset)
42{
43 Crc32 a;
44 uint32_t varcrc;
45 std::string s = refdata;
46 a.Compute(s.c_str(), s.length());
47 a.Reset();
48 varcrc = a;
49 EXPECT_EQ(0xffffffff, varcrc);
50}
diff --git a/xbmc/utils/test/TestCryptThreading.cpp b/xbmc/utils/test/TestCryptThreading.cpp
new file mode 100644
index 0000000..949bd6f
--- /dev/null
+++ b/xbmc/utils/test/TestCryptThreading.cpp
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/CryptThreading.h"
10#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
11#include "threads/SingleLock.h"
12
13#include <atomic>
14#include <set>
15#include <thread>
16#include <vector>
17
18#include <gtest/gtest.h>
19
20TEST(TestCryptThreadingInitializer, General)
21{
22 std::cout << "g_cryptThreadingInitializer address: " <<
23 testing::PrintToString(&g_cryptThreadingInitializer) << "\n";
24}
25
26#define PVTID_NUM_THREADS 10
27
28TEST(TestCryptThreadingInitializer, ProducesValidThreadIds)
29{
30 std::thread testThreads[PVTID_NUM_THREADS];
31
32 std::vector<unsigned long> gatheredIds;
33 CCriticalSection gatheredIdsMutex;
34
35 std::atomic<unsigned long> threadsWaiting{0};
36 std::atomic<bool> gate{false};
37
38 for (int i = 0; i < PVTID_NUM_THREADS; i++)
39 {
40 testThreads[i] = std::thread([&gatheredIds, &gatheredIdsMutex, &threadsWaiting, &gate]() {
41 threadsWaiting++;
42
43 while (!gate);
44
45 unsigned long myTid = g_cryptThreadingInitializer.GetCurrentCryptThreadId();
46
47 {
48 CSingleLock gatheredIdsLock(gatheredIdsMutex);
49 gatheredIds.push_back(myTid);
50 }
51 });
52 }
53
54 gate = true;
55
56 for (int i = 0; i < PVTID_NUM_THREADS; i++)
57 // This is somewhat dangerous but C++ doesn't have a join with timeout or a way to check
58 // if a thread is still running.
59 testThreads[i].join();
60
61 // Verify that all of the thread id's are unique, and that there are 10 of them, and that none
62 // of them is zero
63 std::set<unsigned long> checkIds;
64 for (std::vector<unsigned long>::const_iterator i = gatheredIds.begin(); i != gatheredIds.end(); ++i)
65 {
66 unsigned long curId = *i;
67 // Thread ID isn't zero (since the sequence is pre-incremented and starts at 0)
68 ASSERT_TRUE(curId != 0);
69
70 // Make sure the ID isn't duplicated
71 ASSERT_TRUE(checkIds.find(curId) == checkIds.end());
72 checkIds.insert(curId);
73 }
74
75 // Make sure there's exactly PVTID_NUM_THREADS of them
76 ASSERT_EQ(PVTID_NUM_THREADS, gatheredIds.size());
77 ASSERT_EQ(PVTID_NUM_THREADS, checkIds.size());
78}
79#endif
diff --git a/xbmc/utils/test/TestDatabaseUtils.cpp b/xbmc/utils/test/TestDatabaseUtils.cpp
new file mode 100644
index 0000000..41e20bd
--- /dev/null
+++ b/xbmc/utils/test/TestDatabaseUtils.cpp
@@ -0,0 +1,1376 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "dbwrappers/qry_dat.h"
10#include "music/MusicDatabase.h"
11#include "utils/DatabaseUtils.h"
12#include "utils/StringUtils.h"
13#include "utils/Variant.h"
14#include "video/VideoDatabase.h"
15
16#include <gtest/gtest.h>
17
18class TestDatabaseUtilsHelper
19{
20public:
21 TestDatabaseUtilsHelper()
22 {
23 album_idAlbum = CMusicDatabase::album_idAlbum;
24 album_strAlbum = CMusicDatabase::album_strAlbum;
25 album_strArtists = CMusicDatabase::album_strArtists;
26 album_strGenres = CMusicDatabase::album_strGenres;
27 album_strMoods = CMusicDatabase::album_strMoods;
28 album_strReleaseDate = CMusicDatabase::album_strReleaseDate;
29 album_strOrigReleaseDate = CMusicDatabase::album_strOrigReleaseDate;
30 album_strStyles = CMusicDatabase::album_strStyles;
31 album_strThemes = CMusicDatabase::album_strThemes;
32 album_strReview = CMusicDatabase::album_strReview;
33 album_strLabel = CMusicDatabase::album_strLabel;
34 album_strType = CMusicDatabase::album_strType;
35 album_fRating = CMusicDatabase::album_fRating;
36 album_iVotes = CMusicDatabase::album_iVotes;
37 album_iUserrating = CMusicDatabase::album_iUserrating;
38 album_dtDateAdded = CMusicDatabase::album_dateAdded;
39
40 song_idSong = CMusicDatabase::song_idSong;
41 song_strTitle = CMusicDatabase::song_strTitle;
42 song_iTrack = CMusicDatabase::song_iTrack;
43 song_iDuration = CMusicDatabase::song_iDuration;
44 song_strReleaseDate = CMusicDatabase::song_strReleaseDate;
45 song_strOrigReleaseDate = CMusicDatabase::song_strOrigReleaseDate;
46 song_strFileName = CMusicDatabase::song_strFileName;
47 song_iTimesPlayed = CMusicDatabase::song_iTimesPlayed;
48 song_iStartOffset = CMusicDatabase::song_iStartOffset;
49 song_iEndOffset = CMusicDatabase::song_iEndOffset;
50 song_lastplayed = CMusicDatabase::song_lastplayed;
51 song_rating = CMusicDatabase::song_rating;
52 song_votes = CMusicDatabase::song_votes;
53 song_userrating = CMusicDatabase::song_userrating;
54 song_comment = CMusicDatabase::song_comment;
55 song_strAlbum = CMusicDatabase::song_strAlbum;
56 song_strPath = CMusicDatabase::song_strPath;
57 song_strGenres = CMusicDatabase::song_strGenres;
58 song_strArtists = CMusicDatabase::song_strArtists;
59 }
60
61 int album_idAlbum;
62 int album_strAlbum;
63 int album_strArtists;
64 int album_strGenres;
65 int album_strMoods;
66 int album_strReleaseDate;
67 int album_strOrigReleaseDate;
68 int album_strStyles;
69 int album_strThemes;
70 int album_strReview;
71 int album_strLabel;
72 int album_strType;
73 int album_fRating;
74 int album_iVotes;
75 int album_iUserrating;
76 int album_dtDateAdded;
77
78 int song_idSong;
79 int song_strTitle;
80 int song_iTrack;
81 int song_iDuration;
82 int song_strReleaseDate;
83 int song_strOrigReleaseDate;
84 int song_strFileName;
85 int song_iTimesPlayed;
86 int song_iStartOffset;
87 int song_iEndOffset;
88 int song_lastplayed;
89 int song_rating;
90 int song_votes;
91 int song_userrating;
92 int song_comment;
93 int song_strAlbum;
94 int song_strPath;
95 int song_strGenres;
96 int song_strArtists;
97};
98
99TEST(TestDatabaseUtils, GetField_None)
100{
101 std::string refstr, varstr;
102
103 refstr = "";
104 varstr = DatabaseUtils::GetField(FieldNone, MediaTypeNone,
105 DatabaseQueryPartSelect);
106 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
107
108 varstr = DatabaseUtils::GetField(FieldNone, MediaTypeMovie,
109 DatabaseQueryPartSelect);
110 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
111}
112
113TEST(TestDatabaseUtils, GetField_MediaTypeAlbum)
114{
115 std::string refstr, varstr;
116
117 refstr = "albumview.idAlbum";
118 varstr = DatabaseUtils::GetField(FieldId, MediaTypeAlbum,
119 DatabaseQueryPartSelect);
120 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
121
122 refstr = "albumview.strAlbum";
123 varstr = DatabaseUtils::GetField(FieldAlbum, MediaTypeAlbum,
124 DatabaseQueryPartSelect);
125 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
126
127 refstr = "albumview.strArtists";
128 varstr = DatabaseUtils::GetField(FieldArtist, MediaTypeAlbum,
129 DatabaseQueryPartSelect);
130 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
131
132 refstr = "albumview.strArtists";
133 varstr = DatabaseUtils::GetField(FieldAlbumArtist, MediaTypeAlbum,
134 DatabaseQueryPartSelect);
135 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
136
137 refstr = "albumview.strGenres";
138 varstr = DatabaseUtils::GetField(FieldGenre, MediaTypeAlbum,
139 DatabaseQueryPartSelect);
140 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
141
142 refstr = "albumview.strReleaseDate";
143 varstr = DatabaseUtils::GetField(FieldYear, MediaTypeAlbum,
144 DatabaseQueryPartSelect);
145 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
146
147refstr = "albumview.strOrigReleaseDate";
148 varstr = DatabaseUtils::GetField(FieldOrigYear, MediaTypeAlbum,
149 DatabaseQueryPartSelect);
150 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
151
152 refstr = "albumview.strMoods";
153 varstr = DatabaseUtils::GetField(FieldMoods, MediaTypeAlbum,
154 DatabaseQueryPartSelect);
155 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
156
157 refstr = "albumview.strStyles";
158 varstr = DatabaseUtils::GetField(FieldStyles, MediaTypeAlbum,
159 DatabaseQueryPartSelect);
160 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
161
162 refstr = "albumview.strThemes";
163 varstr = DatabaseUtils::GetField(FieldThemes, MediaTypeAlbum,
164 DatabaseQueryPartSelect);
165 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
166
167 refstr = "albumview.strReview";
168 varstr = DatabaseUtils::GetField(FieldReview, MediaTypeAlbum,
169 DatabaseQueryPartSelect);
170 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
171
172 refstr = "albumview.strLabel";
173 varstr = DatabaseUtils::GetField(FieldMusicLabel, MediaTypeAlbum,
174 DatabaseQueryPartSelect);
175 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
176
177 refstr = "albumview.strType";
178 varstr = DatabaseUtils::GetField(FieldAlbumType, MediaTypeAlbum,
179 DatabaseQueryPartSelect);
180 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
181
182 refstr = "albumview.fRating";
183 varstr = DatabaseUtils::GetField(FieldRating, MediaTypeAlbum,
184 DatabaseQueryPartSelect);
185 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
186
187 refstr = "albumview.iVotes";
188 varstr = DatabaseUtils::GetField(FieldVotes, MediaTypeAlbum,
189 DatabaseQueryPartSelect);
190 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
191
192 refstr = "albumview.iUserrating";
193 varstr = DatabaseUtils::GetField(FieldUserRating, MediaTypeAlbum,
194 DatabaseQueryPartSelect);
195 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
196
197 refstr = "albumview.dateAdded";
198 varstr = DatabaseUtils::GetField(FieldDateAdded, MediaTypeAlbum,
199 DatabaseQueryPartSelect);
200 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
201
202 refstr = "";
203 varstr = DatabaseUtils::GetField(FieldNone, MediaTypeAlbum,
204 DatabaseQueryPartSelect);
205 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
206
207 refstr = "albumview.strAlbum";
208 varstr = DatabaseUtils::GetField(FieldAlbum, MediaTypeAlbum,
209 DatabaseQueryPartWhere);
210 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
211
212 varstr = DatabaseUtils::GetField(FieldAlbum, MediaTypeAlbum,
213 DatabaseQueryPartOrderBy);
214 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
215}
216
217TEST(TestDatabaseUtils, GetField_MediaTypeSong)
218{
219 std::string refstr, varstr;
220
221 refstr = "songview.idSong";
222 varstr = DatabaseUtils::GetField(FieldId, MediaTypeSong,
223 DatabaseQueryPartSelect);
224 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
225
226 refstr = "songview.strTitle";
227 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeSong,
228 DatabaseQueryPartSelect);
229 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
230
231 refstr = "songview.iTrack";
232 varstr = DatabaseUtils::GetField(FieldTrackNumber, MediaTypeSong,
233 DatabaseQueryPartSelect);
234 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
235
236 refstr = "songview.iDuration";
237 varstr = DatabaseUtils::GetField(FieldTime, MediaTypeSong,
238 DatabaseQueryPartSelect);
239 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
240
241 refstr = "songview.strFilename";
242 varstr = DatabaseUtils::GetField(FieldFilename, MediaTypeSong,
243 DatabaseQueryPartSelect);
244 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
245
246 refstr = "songview.iTimesPlayed";
247 varstr = DatabaseUtils::GetField(FieldPlaycount, MediaTypeSong,
248 DatabaseQueryPartSelect);
249 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
250
251 refstr = "songview.iStartOffset";
252 varstr = DatabaseUtils::GetField(FieldStartOffset, MediaTypeSong,
253 DatabaseQueryPartSelect);
254 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
255
256 refstr = "songview.iEndOffset";
257 varstr = DatabaseUtils::GetField(FieldEndOffset, MediaTypeSong,
258 DatabaseQueryPartSelect);
259 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
260
261 refstr = "songview.lastPlayed";
262 varstr = DatabaseUtils::GetField(FieldLastPlayed, MediaTypeSong,
263 DatabaseQueryPartSelect);
264 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
265
266 refstr = "songview.rating";
267 varstr = DatabaseUtils::GetField(FieldRating, MediaTypeSong,
268 DatabaseQueryPartSelect);
269 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
270
271 refstr = "songview.votes";
272 varstr = DatabaseUtils::GetField(FieldVotes, MediaTypeSong,
273 DatabaseQueryPartSelect);
274 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
275
276 refstr = "songview.userrating";
277 varstr = DatabaseUtils::GetField(FieldUserRating, MediaTypeSong,
278 DatabaseQueryPartSelect);
279 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
280
281 refstr = "songview.comment";
282 varstr = DatabaseUtils::GetField(FieldComment, MediaTypeSong,
283 DatabaseQueryPartSelect);
284 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
285
286 refstr = "songview.strReleaseDate";
287 varstr = DatabaseUtils::GetField(FieldYear, MediaTypeSong,
288 DatabaseQueryPartSelect);
289 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
290
291 refstr = "songview.strOrigReleaseDate";
292 varstr = DatabaseUtils::GetField(FieldOrigYear, MediaTypeSong,
293 DatabaseQueryPartSelect);
294 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
295
296 refstr = "songview.strAlbum";
297 varstr = DatabaseUtils::GetField(FieldAlbum, MediaTypeSong,
298 DatabaseQueryPartSelect);
299 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
300
301 refstr = "songview.strPath";
302 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeSong,
303 DatabaseQueryPartSelect);
304 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
305
306 refstr = "songview.strArtists";
307 varstr = DatabaseUtils::GetField(FieldArtist, MediaTypeSong,
308 DatabaseQueryPartSelect);
309 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
310
311 refstr = "songview.strArtists";
312 varstr = DatabaseUtils::GetField(FieldAlbumArtist, MediaTypeSong,
313 DatabaseQueryPartSelect);
314 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
315
316 refstr = "songview.strGenres";
317 varstr = DatabaseUtils::GetField(FieldGenre, MediaTypeSong,
318 DatabaseQueryPartSelect);
319 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
320
321 refstr = "songview.dateAdded";
322 varstr = DatabaseUtils::GetField(FieldDateAdded, MediaTypeSong,
323 DatabaseQueryPartSelect);
324 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
325
326 refstr = "songview.strPath";
327 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeSong,
328 DatabaseQueryPartWhere);
329 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
330
331 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeSong,
332 DatabaseQueryPartOrderBy);
333 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
334}
335
336TEST(TestDatabaseUtils, GetField_MediaTypeMusicVideo)
337{
338 std::string refstr, varstr;
339
340 refstr = "musicvideo_view.idMVideo";
341 varstr = DatabaseUtils::GetField(FieldId, MediaTypeMusicVideo,
342 DatabaseQueryPartSelect);
343 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
344
345 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_TITLE);
346 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeMusicVideo,
347 DatabaseQueryPartSelect);
348 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
349
350 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_RUNTIME);
351 varstr = DatabaseUtils::GetField(FieldTime, MediaTypeMusicVideo,
352 DatabaseQueryPartSelect);
353 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
354
355 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_DIRECTOR);
356 varstr = DatabaseUtils::GetField(FieldDirector, MediaTypeMusicVideo,
357 DatabaseQueryPartSelect);
358 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
359
360 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_STUDIOS);
361 varstr = DatabaseUtils::GetField(FieldStudio, MediaTypeMusicVideo,
362 DatabaseQueryPartSelect);
363 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
364
365 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_PLOT);
366 varstr = DatabaseUtils::GetField(FieldPlot, MediaTypeMusicVideo,
367 DatabaseQueryPartSelect);
368 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
369
370 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_ALBUM);
371 varstr = DatabaseUtils::GetField(FieldAlbum, MediaTypeMusicVideo,
372 DatabaseQueryPartSelect);
373 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
374
375 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_ARTIST);
376 varstr = DatabaseUtils::GetField(FieldArtist, MediaTypeMusicVideo,
377 DatabaseQueryPartSelect);
378 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
379
380 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_GENRE);
381 varstr = DatabaseUtils::GetField(FieldGenre, MediaTypeMusicVideo,
382 DatabaseQueryPartSelect);
383 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
384
385 refstr = StringUtils::Format("musicvideo_view.c%02d",VIDEODB_ID_MUSICVIDEO_TRACK);
386 varstr = DatabaseUtils::GetField(FieldTrackNumber, MediaTypeMusicVideo,
387 DatabaseQueryPartSelect);
388 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
389
390 refstr = "musicvideo_view.strFilename";
391 varstr = DatabaseUtils::GetField(FieldFilename, MediaTypeMusicVideo,
392 DatabaseQueryPartSelect);
393 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
394
395 refstr = "musicvideo_view.strPath";
396 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeMusicVideo,
397 DatabaseQueryPartSelect);
398 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
399
400 refstr = "musicvideo_view.playCount";
401 varstr = DatabaseUtils::GetField(FieldPlaycount, MediaTypeMusicVideo,
402 DatabaseQueryPartSelect);
403 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
404
405 refstr = "musicvideo_view.lastPlayed";
406 varstr = DatabaseUtils::GetField(FieldLastPlayed, MediaTypeMusicVideo,
407 DatabaseQueryPartSelect);
408 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
409
410 refstr = "musicvideo_view.dateAdded";
411 varstr = DatabaseUtils::GetField(FieldDateAdded, MediaTypeMusicVideo,
412 DatabaseQueryPartSelect);
413 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
414
415 refstr = "";
416 varstr = DatabaseUtils::GetField(FieldVideoResolution, MediaTypeMusicVideo,
417 DatabaseQueryPartSelect);
418 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
419
420 refstr = "musicvideo_view.strPath";
421 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeMusicVideo,
422 DatabaseQueryPartWhere);
423 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
424
425 refstr = "musicvideo_view.strPath";
426 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeMusicVideo,
427 DatabaseQueryPartOrderBy);
428 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
429
430 refstr = "musicvideo_view.userrating";
431 varstr = DatabaseUtils::GetField(FieldUserRating, MediaTypeMusicVideo,
432 DatabaseQueryPartSelect);
433 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
434}
435
436TEST(TestDatabaseUtils, GetField_MediaTypeMovie)
437{
438 std::string refstr, varstr;
439
440 refstr = "movie_view.idMovie";
441 varstr = DatabaseUtils::GetField(FieldId, MediaTypeMovie,
442 DatabaseQueryPartSelect);
443 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
444
445 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_TITLE);
446 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeMovie,
447 DatabaseQueryPartSelect);
448 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
449
450 refstr = StringUtils::Format("CASE WHEN length(movie_view.c%02d) > 0 THEN movie_view.c%02d "
451 "ELSE movie_view.c%02d END", VIDEODB_ID_SORTTITLE,
452 VIDEODB_ID_SORTTITLE, VIDEODB_ID_TITLE);
453 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeMovie,
454 DatabaseQueryPartOrderBy);
455 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
456
457 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_PLOT);
458 varstr = DatabaseUtils::GetField(FieldPlot, MediaTypeMovie,
459 DatabaseQueryPartSelect);
460 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
461
462 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_PLOTOUTLINE);
463 varstr = DatabaseUtils::GetField(FieldPlotOutline, MediaTypeMovie,
464 DatabaseQueryPartSelect);
465 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
466
467 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_TAGLINE);
468 varstr = DatabaseUtils::GetField(FieldTagline, MediaTypeMovie,
469 DatabaseQueryPartSelect);
470 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
471
472 refstr = "movie_view.votes";
473 varstr = DatabaseUtils::GetField(FieldVotes, MediaTypeMovie,
474 DatabaseQueryPartSelect);
475 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
476
477 refstr = "movie_view.rating";
478 varstr = DatabaseUtils::GetField(FieldRating, MediaTypeMovie,
479 DatabaseQueryPartSelect);
480 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
481
482 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_CREDITS);
483 varstr = DatabaseUtils::GetField(FieldWriter, MediaTypeMovie,
484 DatabaseQueryPartSelect);
485 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
486
487 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_SORTTITLE);
488 varstr = DatabaseUtils::GetField(FieldSortTitle, MediaTypeMovie,
489 DatabaseQueryPartSelect);
490 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
491
492 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_RUNTIME);
493 varstr = DatabaseUtils::GetField(FieldTime, MediaTypeMovie,
494 DatabaseQueryPartSelect);
495 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
496
497 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_MPAA);
498 varstr = DatabaseUtils::GetField(FieldMPAA, MediaTypeMovie,
499 DatabaseQueryPartSelect);
500 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
501
502 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_TOP250);
503 varstr = DatabaseUtils::GetField(FieldTop250, MediaTypeMovie,
504 DatabaseQueryPartSelect);
505 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
506
507 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_GENRE);
508 varstr = DatabaseUtils::GetField(FieldGenre, MediaTypeMovie,
509 DatabaseQueryPartSelect);
510 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
511
512 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_DIRECTOR);
513 varstr = DatabaseUtils::GetField(FieldDirector, MediaTypeMovie,
514 DatabaseQueryPartSelect);
515 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
516
517 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_STUDIOS);
518 varstr = DatabaseUtils::GetField(FieldStudio, MediaTypeMovie,
519 DatabaseQueryPartSelect);
520 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
521
522 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_TRAILER);
523 varstr = DatabaseUtils::GetField(FieldTrailer, MediaTypeMovie,
524 DatabaseQueryPartSelect);
525 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
526
527 refstr = StringUtils::Format("movie_view.c%02d", VIDEODB_ID_COUNTRY);
528 varstr = DatabaseUtils::GetField(FieldCountry, MediaTypeMovie,
529 DatabaseQueryPartSelect);
530 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
531
532 refstr = "movie_view.strFilename";
533 varstr = DatabaseUtils::GetField(FieldFilename, MediaTypeMovie,
534 DatabaseQueryPartSelect);
535 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
536
537 refstr = "movie_view.strPath";
538 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeMovie,
539 DatabaseQueryPartSelect);
540 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
541
542 refstr = "movie_view.playCount";
543 varstr = DatabaseUtils::GetField(FieldPlaycount, MediaTypeMovie,
544 DatabaseQueryPartSelect);
545 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
546
547 refstr = "movie_view.lastPlayed";
548 varstr = DatabaseUtils::GetField(FieldLastPlayed, MediaTypeMovie,
549 DatabaseQueryPartSelect);
550 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
551
552 refstr = "movie_view.dateAdded";
553 varstr = DatabaseUtils::GetField(FieldDateAdded, MediaTypeMovie,
554 DatabaseQueryPartSelect);
555 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
556
557 refstr = "movie_view.userrating";
558 varstr = DatabaseUtils::GetField(FieldUserRating, MediaTypeMovie,
559 DatabaseQueryPartSelect);
560 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
561
562 refstr = "";
563 varstr = DatabaseUtils::GetField(FieldRandom, MediaTypeMovie,
564 DatabaseQueryPartSelect);
565 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
566}
567
568TEST(TestDatabaseUtils, GetField_MediaTypeTvShow)
569{
570 std::string refstr, varstr;
571
572 refstr = "tvshow_view.idShow";
573 varstr = DatabaseUtils::GetField(FieldId, MediaTypeTvShow,
574 DatabaseQueryPartSelect);
575 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
576
577 refstr = StringUtils::Format("CASE WHEN length(tvshow_view.c%02d) > 0 THEN tvshow_view.c%02d "
578 "ELSE tvshow_view.c%02d END", VIDEODB_ID_TV_SORTTITLE,
579 VIDEODB_ID_TV_SORTTITLE, VIDEODB_ID_TV_TITLE);
580 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeTvShow,
581 DatabaseQueryPartOrderBy);
582 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
583
584 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_TITLE);
585 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeTvShow,
586 DatabaseQueryPartSelect);
587 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
588
589 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_PLOT);
590 varstr = DatabaseUtils::GetField(FieldPlot, MediaTypeTvShow,
591 DatabaseQueryPartSelect);
592 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
593
594 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_STATUS);
595 varstr = DatabaseUtils::GetField(FieldTvShowStatus, MediaTypeTvShow,
596 DatabaseQueryPartSelect);
597 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
598
599 refstr = "tvshow_view.votes";
600 varstr = DatabaseUtils::GetField(FieldVotes, MediaTypeTvShow,
601 DatabaseQueryPartSelect);
602 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
603
604 refstr = "tvshow_view.rating";
605 varstr = DatabaseUtils::GetField(FieldRating, MediaTypeTvShow,
606 DatabaseQueryPartSelect);
607 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
608
609 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_PREMIERED);
610 varstr = DatabaseUtils::GetField(FieldYear, MediaTypeTvShow,
611 DatabaseQueryPartSelect);
612 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
613
614 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_GENRE);
615 varstr = DatabaseUtils::GetField(FieldGenre, MediaTypeTvShow,
616 DatabaseQueryPartSelect);
617 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
618
619 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_MPAA);
620 varstr = DatabaseUtils::GetField(FieldMPAA, MediaTypeTvShow,
621 DatabaseQueryPartSelect);
622 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
623
624 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_STUDIOS);
625 varstr = DatabaseUtils::GetField(FieldStudio, MediaTypeTvShow,
626 DatabaseQueryPartSelect);
627 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
628
629 refstr = StringUtils::Format("tvshow_view.c%02d", VIDEODB_ID_TV_SORTTITLE);
630 varstr = DatabaseUtils::GetField(FieldSortTitle, MediaTypeTvShow,
631 DatabaseQueryPartSelect);
632 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
633
634 refstr = "tvshow_view.strPath";
635 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeTvShow,
636 DatabaseQueryPartSelect);
637 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
638
639 refstr = "tvshow_view.dateAdded";
640 varstr = DatabaseUtils::GetField(FieldDateAdded, MediaTypeTvShow,
641 DatabaseQueryPartSelect);
642 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
643
644 refstr = "tvshow_view.totalSeasons";
645 varstr = DatabaseUtils::GetField(FieldSeason, MediaTypeTvShow,
646 DatabaseQueryPartSelect);
647 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
648
649 refstr = "tvshow_view.totalCount";
650 varstr = DatabaseUtils::GetField(FieldNumberOfEpisodes, MediaTypeTvShow,
651 DatabaseQueryPartSelect);
652 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
653
654 refstr = "tvshow_view.watchedcount";
655 varstr = DatabaseUtils::GetField(FieldNumberOfWatchedEpisodes,
656 MediaTypeTvShow, DatabaseQueryPartSelect);
657 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
658
659 refstr = "tvshow_view.userrating";
660 varstr = DatabaseUtils::GetField(FieldUserRating, MediaTypeTvShow,
661 DatabaseQueryPartSelect);
662 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
663
664 refstr = "";
665 varstr = DatabaseUtils::GetField(FieldRandom, MediaTypeTvShow,
666 DatabaseQueryPartSelect);
667 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
668}
669
670TEST(TestDatabaseUtils, GetField_MediaTypeEpisode)
671{
672 std::string refstr, varstr;
673
674 refstr = "episode_view.idEpisode";
675 varstr = DatabaseUtils::GetField(FieldId, MediaTypeEpisode,
676 DatabaseQueryPartSelect);
677 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
678
679 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_TITLE);
680 varstr = DatabaseUtils::GetField(FieldTitle, MediaTypeEpisode,
681 DatabaseQueryPartSelect);
682 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
683
684 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_PLOT);
685 varstr = DatabaseUtils::GetField(FieldPlot, MediaTypeEpisode,
686 DatabaseQueryPartSelect);
687 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
688
689 refstr = "episode_view.votes";
690 varstr = DatabaseUtils::GetField(FieldVotes, MediaTypeEpisode,
691 DatabaseQueryPartSelect);
692 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
693
694 refstr = "episode_view.rating";
695 varstr = DatabaseUtils::GetField(FieldRating, MediaTypeEpisode,
696 DatabaseQueryPartSelect);
697 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
698
699 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_CREDITS);
700 varstr = DatabaseUtils::GetField(FieldWriter, MediaTypeEpisode,
701 DatabaseQueryPartSelect);
702 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
703
704 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_AIRED);
705 varstr = DatabaseUtils::GetField(FieldAirDate, MediaTypeEpisode,
706 DatabaseQueryPartSelect);
707 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
708
709 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_RUNTIME);
710 varstr = DatabaseUtils::GetField(FieldTime, MediaTypeEpisode,
711 DatabaseQueryPartSelect);
712 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
713
714 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_DIRECTOR);
715 varstr = DatabaseUtils::GetField(FieldDirector, MediaTypeEpisode,
716 DatabaseQueryPartSelect);
717 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
718
719 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_SEASON);
720 varstr = DatabaseUtils::GetField(FieldSeason, MediaTypeEpisode,
721 DatabaseQueryPartSelect);
722 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
723
724 refstr = StringUtils::Format("episode_view.c%02d", VIDEODB_ID_EPISODE_EPISODE);
725 varstr = DatabaseUtils::GetField(FieldEpisodeNumber, MediaTypeEpisode,
726 DatabaseQueryPartSelect);
727 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
728
729 refstr = "episode_view.strFilename";
730 varstr = DatabaseUtils::GetField(FieldFilename, MediaTypeEpisode,
731 DatabaseQueryPartSelect);
732 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
733
734 refstr = "episode_view.strPath";
735 varstr = DatabaseUtils::GetField(FieldPath, MediaTypeEpisode,
736 DatabaseQueryPartSelect);
737 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
738
739 refstr = "episode_view.playCount";
740 varstr = DatabaseUtils::GetField(FieldPlaycount, MediaTypeEpisode,
741 DatabaseQueryPartSelect);
742 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
743
744 refstr = "episode_view.lastPlayed";
745 varstr = DatabaseUtils::GetField(FieldLastPlayed, MediaTypeEpisode,
746 DatabaseQueryPartSelect);
747 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
748
749 refstr = "episode_view.dateAdded";
750 varstr = DatabaseUtils::GetField(FieldDateAdded, MediaTypeEpisode,
751 DatabaseQueryPartSelect);
752 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
753
754 refstr = "episode_view.strTitle";
755 varstr = DatabaseUtils::GetField(FieldTvShowTitle, MediaTypeEpisode,
756 DatabaseQueryPartSelect);
757 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
758
759 refstr = "episode_view.premiered";
760 varstr = DatabaseUtils::GetField(FieldYear, MediaTypeEpisode,
761 DatabaseQueryPartSelect);
762 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
763
764 refstr = "episode_view.mpaa";
765 varstr = DatabaseUtils::GetField(FieldMPAA, MediaTypeEpisode,
766 DatabaseQueryPartSelect);
767 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
768
769 refstr = "episode_view.strStudio";
770 varstr = DatabaseUtils::GetField(FieldStudio, MediaTypeEpisode,
771 DatabaseQueryPartSelect);
772 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
773
774 refstr = "episode_view.userrating";
775 varstr = DatabaseUtils::GetField(FieldUserRating, MediaTypeEpisode,
776 DatabaseQueryPartSelect);
777 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
778
779 refstr = "";
780 varstr = DatabaseUtils::GetField(FieldRandom, MediaTypeEpisode,
781 DatabaseQueryPartSelect);
782 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
783}
784
785TEST(TestDatabaseUtils, GetField_FieldRandom)
786{
787 std::string refstr, varstr;
788
789 refstr = "";
790 varstr = DatabaseUtils::GetField(FieldRandom, MediaTypeEpisode,
791 DatabaseQueryPartSelect);
792 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
793
794 refstr = "";
795 varstr = DatabaseUtils::GetField(FieldRandom, MediaTypeEpisode,
796 DatabaseQueryPartWhere);
797 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
798
799 refstr = "RANDOM()";
800 varstr = DatabaseUtils::GetField(FieldRandom, MediaTypeEpisode,
801 DatabaseQueryPartOrderBy);
802 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
803}
804
805TEST(TestDatabaseUtils, GetFieldIndex_None)
806{
807 int refindex, varindex;
808
809 refindex = -1;
810 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeNone);
811 EXPECT_EQ(refindex, varindex);
812
813 varindex = DatabaseUtils::GetFieldIndex(FieldNone, MediaTypeAlbum);
814 EXPECT_EQ(refindex, varindex);
815}
816
817//! @todo Should enums in CMusicDatabase be made public instead?
818TEST(TestDatabaseUtils, GetFieldIndex_MediaTypeAlbum)
819{
820 int refindex, varindex;
821 TestDatabaseUtilsHelper a;
822
823 refindex = a.album_idAlbum;
824 varindex = DatabaseUtils::GetFieldIndex(FieldId, MediaTypeAlbum);
825 EXPECT_EQ(refindex, varindex);
826
827 refindex = a.album_strAlbum;
828 varindex = DatabaseUtils::GetFieldIndex(FieldAlbum, MediaTypeAlbum);
829 EXPECT_EQ(refindex, varindex);
830
831 refindex = a.album_strArtists;
832 varindex = DatabaseUtils::GetFieldIndex(FieldArtist, MediaTypeAlbum);
833 EXPECT_EQ(refindex, varindex);
834
835 refindex = a.album_strArtists;
836 varindex = DatabaseUtils::GetFieldIndex(FieldAlbumArtist, MediaTypeAlbum);
837 EXPECT_EQ(refindex, varindex);
838
839 refindex = a.album_strGenres;
840 varindex = DatabaseUtils::GetFieldIndex(FieldGenre, MediaTypeAlbum);
841 EXPECT_EQ(refindex, varindex);
842
843 refindex = a.album_strReleaseDate;
844 varindex = DatabaseUtils::GetFieldIndex(FieldYear, MediaTypeAlbum);
845 EXPECT_EQ(refindex, varindex);
846
847 refindex = a.album_strOrigReleaseDate;
848 varindex = DatabaseUtils::GetFieldIndex(FieldOrigYear, MediaTypeAlbum);
849 EXPECT_EQ(refindex, varindex);
850
851 refindex = a.album_strMoods;
852 varindex = DatabaseUtils::GetFieldIndex(FieldMoods, MediaTypeAlbum);
853 EXPECT_EQ(refindex, varindex);
854
855 refindex = a.album_strStyles;
856 varindex = DatabaseUtils::GetFieldIndex(FieldStyles, MediaTypeAlbum);
857 EXPECT_EQ(refindex, varindex);
858
859 refindex = a.album_strThemes;
860 varindex = DatabaseUtils::GetFieldIndex(FieldThemes, MediaTypeAlbum);
861 EXPECT_EQ(refindex, varindex);
862
863 refindex = a.album_strReview;
864 varindex = DatabaseUtils::GetFieldIndex(FieldReview, MediaTypeAlbum);
865 EXPECT_EQ(refindex, varindex);
866
867 refindex = a.album_strLabel;
868 varindex = DatabaseUtils::GetFieldIndex(FieldMusicLabel, MediaTypeAlbum);
869 EXPECT_EQ(refindex, varindex);
870
871 refindex = a.album_strType;
872 varindex = DatabaseUtils::GetFieldIndex(FieldAlbumType, MediaTypeAlbum);
873 EXPECT_EQ(refindex, varindex);
874
875 refindex = a.album_fRating;
876 varindex = DatabaseUtils::GetFieldIndex(FieldRating, MediaTypeAlbum);
877 EXPECT_EQ(refindex, varindex);
878
879 refindex = a.album_dtDateAdded;
880 varindex = DatabaseUtils::GetFieldIndex(FieldDateAdded, MediaTypeAlbum);
881 EXPECT_EQ(refindex, varindex);
882
883 refindex = -1;
884 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeAlbum);
885 EXPECT_EQ(refindex, varindex);
886}
887
888TEST(TestDatabaseUtils, GetFieldIndex_MediaTypeSong)
889{
890 int refindex, varindex;
891 TestDatabaseUtilsHelper a;
892
893 refindex = a.song_idSong;
894 varindex = DatabaseUtils::GetFieldIndex(FieldId, MediaTypeSong);
895 EXPECT_EQ(refindex, varindex);
896
897 refindex = a.song_strTitle;
898 varindex = DatabaseUtils::GetFieldIndex(FieldTitle, MediaTypeSong);
899 EXPECT_EQ(refindex, varindex);
900
901 refindex = a.song_iTrack;
902 varindex = DatabaseUtils::GetFieldIndex(FieldTrackNumber, MediaTypeSong);
903 EXPECT_EQ(refindex, varindex);
904
905 refindex = a.song_iDuration;
906 varindex = DatabaseUtils::GetFieldIndex(FieldTime, MediaTypeSong);
907 EXPECT_EQ(refindex, varindex);
908
909 refindex = a.song_strReleaseDate;
910 varindex = DatabaseUtils::GetFieldIndex(FieldYear, MediaTypeSong);
911 EXPECT_EQ(refindex, varindex);
912
913 refindex = a.song_strFileName;
914 varindex = DatabaseUtils::GetFieldIndex(FieldFilename, MediaTypeSong);
915 EXPECT_EQ(refindex, varindex);
916
917 refindex = a.song_iTimesPlayed;
918 varindex = DatabaseUtils::GetFieldIndex(FieldPlaycount, MediaTypeSong);
919 EXPECT_EQ(refindex, varindex);
920
921 refindex = a.song_iStartOffset;
922 varindex = DatabaseUtils::GetFieldIndex(FieldStartOffset, MediaTypeSong);
923 EXPECT_EQ(refindex, varindex);
924
925 refindex = a.song_iEndOffset;
926 varindex = DatabaseUtils::GetFieldIndex(FieldEndOffset, MediaTypeSong);
927 EXPECT_EQ(refindex, varindex);
928
929 refindex = a.song_lastplayed;
930 varindex = DatabaseUtils::GetFieldIndex(FieldLastPlayed, MediaTypeSong);
931 EXPECT_EQ(refindex, varindex);
932
933 refindex = a.song_rating;
934 varindex = DatabaseUtils::GetFieldIndex(FieldRating, MediaTypeSong);
935 EXPECT_EQ(refindex, varindex);
936
937 refindex = a.song_votes;
938 varindex = DatabaseUtils::GetFieldIndex(FieldVotes, MediaTypeSong);
939 EXPECT_EQ(refindex, varindex);
940
941 refindex = a.song_userrating;
942 varindex = DatabaseUtils::GetFieldIndex(FieldUserRating, MediaTypeSong);
943 EXPECT_EQ(refindex, varindex);
944
945 refindex = a.song_comment;
946 varindex = DatabaseUtils::GetFieldIndex(FieldComment, MediaTypeSong);
947 EXPECT_EQ(refindex, varindex);
948
949 refindex = a.song_strAlbum;
950 varindex = DatabaseUtils::GetFieldIndex(FieldAlbum, MediaTypeSong);
951 EXPECT_EQ(refindex, varindex);
952
953 refindex = a.song_strPath;
954 varindex = DatabaseUtils::GetFieldIndex(FieldPath, MediaTypeSong);
955 EXPECT_EQ(refindex, varindex);
956
957 refindex = a.song_strArtists;
958 varindex = DatabaseUtils::GetFieldIndex(FieldArtist, MediaTypeSong);
959 EXPECT_EQ(refindex, varindex);
960
961 refindex = a.song_strGenres;
962 varindex = DatabaseUtils::GetFieldIndex(FieldGenre, MediaTypeSong);
963 EXPECT_EQ(refindex, varindex);
964
965 refindex = -1;
966 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeSong);
967 EXPECT_EQ(refindex, varindex);
968}
969
970TEST(TestDatabaseUtils, GetFieldIndex_MediaTypeMusicVideo)
971{
972 int refindex, varindex;
973
974 refindex = 0;
975 varindex = DatabaseUtils::GetFieldIndex(FieldId, MediaTypeMusicVideo);
976 EXPECT_EQ(refindex, varindex);
977
978 refindex = VIDEODB_ID_MUSICVIDEO_TITLE + 2;
979 varindex = DatabaseUtils::GetFieldIndex(FieldTitle, MediaTypeMusicVideo);
980 EXPECT_EQ(refindex, varindex);
981
982 refindex = VIDEODB_ID_MUSICVIDEO_RUNTIME + 2;
983 varindex = DatabaseUtils::GetFieldIndex(FieldTime, MediaTypeMusicVideo);
984 EXPECT_EQ(refindex, varindex);
985
986 refindex = VIDEODB_ID_MUSICVIDEO_DIRECTOR + 2;
987 varindex = DatabaseUtils::GetFieldIndex(FieldDirector, MediaTypeMusicVideo);
988 EXPECT_EQ(refindex, varindex);
989
990 refindex = VIDEODB_ID_MUSICVIDEO_STUDIOS + 2;
991 varindex = DatabaseUtils::GetFieldIndex(FieldStudio, MediaTypeMusicVideo);
992 EXPECT_EQ(refindex, varindex);
993
994 refindex = VIDEODB_ID_MUSICVIDEO_PLOT + 2;
995 varindex = DatabaseUtils::GetFieldIndex(FieldPlot, MediaTypeMusicVideo);
996 EXPECT_EQ(refindex, varindex);
997
998 refindex = VIDEODB_ID_MUSICVIDEO_ALBUM + 2;
999 varindex = DatabaseUtils::GetFieldIndex(FieldAlbum, MediaTypeMusicVideo);
1000 EXPECT_EQ(refindex, varindex);
1001
1002 refindex = VIDEODB_ID_MUSICVIDEO_ARTIST + 2;
1003 varindex = DatabaseUtils::GetFieldIndex(FieldArtist, MediaTypeMusicVideo);
1004 EXPECT_EQ(refindex, varindex);
1005
1006 refindex = VIDEODB_ID_MUSICVIDEO_GENRE + 2;
1007 varindex = DatabaseUtils::GetFieldIndex(FieldGenre, MediaTypeMusicVideo);
1008 EXPECT_EQ(refindex, varindex);
1009
1010 refindex = VIDEODB_ID_MUSICVIDEO_TRACK + 2;
1011 varindex = DatabaseUtils::GetFieldIndex(FieldTrackNumber, MediaTypeMusicVideo);
1012 EXPECT_EQ(refindex, varindex);
1013
1014 refindex = VIDEODB_DETAILS_MUSICVIDEO_FILE;
1015 varindex = DatabaseUtils::GetFieldIndex(FieldFilename, MediaTypeMusicVideo);
1016 EXPECT_EQ(refindex, varindex);
1017
1018 refindex = VIDEODB_DETAILS_MUSICVIDEO_PATH;
1019 varindex = DatabaseUtils::GetFieldIndex(FieldPath, MediaTypeMusicVideo);
1020 EXPECT_EQ(refindex, varindex);
1021
1022 refindex = VIDEODB_DETAILS_MUSICVIDEO_PLAYCOUNT;
1023 varindex = DatabaseUtils::GetFieldIndex(FieldPlaycount, MediaTypeMusicVideo);
1024 EXPECT_EQ(refindex, varindex);
1025
1026 refindex = VIDEODB_DETAILS_MUSICVIDEO_LASTPLAYED;
1027 varindex = DatabaseUtils::GetFieldIndex(FieldLastPlayed, MediaTypeMusicVideo);
1028 EXPECT_EQ(refindex, varindex);
1029
1030 refindex = VIDEODB_DETAILS_MUSICVIDEO_DATEADDED;
1031 varindex = DatabaseUtils::GetFieldIndex(FieldDateAdded, MediaTypeMusicVideo);
1032 EXPECT_EQ(refindex, varindex);
1033
1034 refindex = VIDEODB_DETAILS_MUSICVIDEO_USER_RATING;
1035 varindex = DatabaseUtils::GetFieldIndex(FieldUserRating, MediaTypeMusicVideo);
1036 EXPECT_EQ(refindex, varindex);
1037
1038 refindex = VIDEODB_DETAILS_MUSICVIDEO_PREMIERED;
1039 varindex = DatabaseUtils::GetFieldIndex(FieldYear, MediaTypeMusicVideo);
1040 EXPECT_EQ(refindex, varindex);
1041
1042 refindex = -1;
1043 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeMusicVideo);
1044 EXPECT_EQ(refindex, varindex);
1045}
1046
1047TEST(TestDatabaseUtils, GetFieldIndex_MediaTypeMovie)
1048{
1049 int refindex, varindex;
1050
1051 refindex = 0;
1052 varindex = DatabaseUtils::GetFieldIndex(FieldId, MediaTypeMovie);
1053 EXPECT_EQ(refindex, varindex);
1054
1055 refindex = VIDEODB_ID_TITLE + 2;
1056 varindex = DatabaseUtils::GetFieldIndex(FieldTitle, MediaTypeMovie);
1057 EXPECT_EQ(refindex, varindex);
1058
1059 refindex = VIDEODB_ID_SORTTITLE + 2;
1060 varindex = DatabaseUtils::GetFieldIndex(FieldSortTitle, MediaTypeMovie);
1061 EXPECT_EQ(refindex, varindex);
1062
1063 refindex = VIDEODB_ID_PLOT + 2;
1064 varindex = DatabaseUtils::GetFieldIndex(FieldPlot, MediaTypeMovie);
1065 EXPECT_EQ(refindex, varindex);
1066
1067 refindex = VIDEODB_ID_PLOTOUTLINE + 2;
1068 varindex = DatabaseUtils::GetFieldIndex(FieldPlotOutline, MediaTypeMovie);
1069 EXPECT_EQ(refindex, varindex);
1070
1071 refindex = VIDEODB_ID_TAGLINE + 2;
1072 varindex = DatabaseUtils::GetFieldIndex(FieldTagline, MediaTypeMovie);
1073 EXPECT_EQ(refindex, varindex);
1074
1075 refindex = VIDEODB_ID_CREDITS + 2;
1076 varindex = DatabaseUtils::GetFieldIndex(FieldWriter, MediaTypeMovie);
1077 EXPECT_EQ(refindex, varindex);
1078
1079 refindex = VIDEODB_ID_RUNTIME + 2;
1080 varindex = DatabaseUtils::GetFieldIndex(FieldTime, MediaTypeMovie);
1081 EXPECT_EQ(refindex, varindex);
1082
1083 refindex = VIDEODB_ID_MPAA + 2;
1084 varindex = DatabaseUtils::GetFieldIndex(FieldMPAA, MediaTypeMovie);
1085 EXPECT_EQ(refindex, varindex);
1086
1087 refindex = VIDEODB_ID_TOP250 + 2;
1088 varindex = DatabaseUtils::GetFieldIndex(FieldTop250, MediaTypeMovie);
1089 EXPECT_EQ(refindex, varindex);
1090
1091 refindex = VIDEODB_ID_GENRE + 2;
1092 varindex = DatabaseUtils::GetFieldIndex(FieldGenre, MediaTypeMovie);
1093 EXPECT_EQ(refindex, varindex);
1094
1095 refindex = VIDEODB_ID_DIRECTOR + 2;
1096 varindex = DatabaseUtils::GetFieldIndex(FieldDirector, MediaTypeMovie);
1097 EXPECT_EQ(refindex, varindex);
1098
1099 refindex = VIDEODB_ID_STUDIOS + 2;
1100 varindex = DatabaseUtils::GetFieldIndex(FieldStudio, MediaTypeMovie);
1101 EXPECT_EQ(refindex, varindex);
1102
1103 refindex = VIDEODB_ID_TRAILER + 2;
1104 varindex = DatabaseUtils::GetFieldIndex(FieldTrailer, MediaTypeMovie);
1105 EXPECT_EQ(refindex, varindex);
1106
1107 refindex = VIDEODB_ID_COUNTRY + 2;
1108 varindex = DatabaseUtils::GetFieldIndex(FieldCountry, MediaTypeMovie);
1109 EXPECT_EQ(refindex, varindex);
1110
1111 refindex = VIDEODB_DETAILS_MOVIE_FILE + 2;
1112 varindex = DatabaseUtils::GetFieldIndex(FieldFilename, MediaTypeMovie);
1113 EXPECT_EQ(refindex, varindex);
1114
1115 refindex = VIDEODB_DETAILS_MOVIE_PATH;
1116 varindex = DatabaseUtils::GetFieldIndex(FieldPath, MediaTypeMovie);
1117 EXPECT_EQ(refindex, varindex);
1118
1119 refindex = VIDEODB_DETAILS_MOVIE_PLAYCOUNT;
1120 varindex = DatabaseUtils::GetFieldIndex(FieldPlaycount, MediaTypeMovie);
1121 EXPECT_EQ(refindex, varindex);
1122
1123 refindex = VIDEODB_DETAILS_MOVIE_LASTPLAYED;
1124 varindex = DatabaseUtils::GetFieldIndex(FieldLastPlayed, MediaTypeMovie);
1125 EXPECT_EQ(refindex, varindex);
1126
1127 refindex = VIDEODB_DETAILS_MOVIE_DATEADDED;
1128 varindex = DatabaseUtils::GetFieldIndex(FieldDateAdded, MediaTypeMovie);
1129 EXPECT_EQ(refindex, varindex);
1130
1131 refindex = VIDEODB_DETAILS_MOVIE_USER_RATING;
1132 varindex = DatabaseUtils::GetFieldIndex(FieldUserRating, MediaTypeMovie);
1133 EXPECT_EQ(refindex, varindex);
1134
1135 refindex = VIDEODB_DETAILS_MOVIE_VOTES;
1136 varindex = DatabaseUtils::GetFieldIndex(FieldVotes, MediaTypeMovie);
1137 EXPECT_EQ(refindex, varindex);
1138
1139 refindex = VIDEODB_DETAILS_MOVIE_RATING;
1140 varindex = DatabaseUtils::GetFieldIndex(FieldRating, MediaTypeMovie);
1141 EXPECT_EQ(refindex, varindex);
1142
1143 refindex = VIDEODB_DETAILS_MOVIE_PREMIERED;
1144 varindex = DatabaseUtils::GetFieldIndex(FieldYear, MediaTypeMovie);
1145 EXPECT_EQ(refindex, varindex);
1146
1147 refindex = -1;
1148 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeMovie);
1149 EXPECT_EQ(refindex, varindex);
1150}
1151
1152TEST(TestDatabaseUtils, GetFieldIndex_MediaTypeTvShow)
1153{
1154 int refindex, varindex;
1155
1156 refindex = 0;
1157 varindex = DatabaseUtils::GetFieldIndex(FieldId, MediaTypeTvShow);
1158 EXPECT_EQ(refindex, varindex);
1159
1160 refindex = VIDEODB_ID_TV_TITLE + 1;
1161 varindex = DatabaseUtils::GetFieldIndex(FieldTitle, MediaTypeTvShow);
1162 EXPECT_EQ(refindex, varindex);
1163
1164 refindex = VIDEODB_ID_TV_SORTTITLE + 1;
1165 varindex = DatabaseUtils::GetFieldIndex(FieldSortTitle, MediaTypeTvShow);
1166 EXPECT_EQ(refindex, varindex);
1167
1168 refindex = VIDEODB_ID_TV_PLOT + 1;
1169 varindex = DatabaseUtils::GetFieldIndex(FieldPlot, MediaTypeTvShow);
1170 EXPECT_EQ(refindex, varindex);
1171
1172 refindex = VIDEODB_ID_TV_STATUS + 1;
1173 varindex = DatabaseUtils::GetFieldIndex(FieldTvShowStatus, MediaTypeTvShow);
1174 EXPECT_EQ(refindex, varindex);
1175
1176 refindex = VIDEODB_ID_TV_PREMIERED + 1;
1177 varindex = DatabaseUtils::GetFieldIndex(FieldYear, MediaTypeTvShow);
1178 EXPECT_EQ(refindex, varindex);
1179
1180 refindex = VIDEODB_ID_TV_GENRE + 1;
1181 varindex = DatabaseUtils::GetFieldIndex(FieldGenre, MediaTypeTvShow);
1182 EXPECT_EQ(refindex, varindex);
1183
1184 refindex = VIDEODB_ID_TV_MPAA + 1;
1185 varindex = DatabaseUtils::GetFieldIndex(FieldMPAA, MediaTypeTvShow);
1186 EXPECT_EQ(refindex, varindex);
1187
1188 refindex = VIDEODB_ID_TV_STUDIOS + 1;
1189 varindex = DatabaseUtils::GetFieldIndex(FieldStudio, MediaTypeTvShow);
1190 EXPECT_EQ(refindex, varindex);
1191
1192 refindex = VIDEODB_DETAILS_TVSHOW_PATH;
1193 varindex = DatabaseUtils::GetFieldIndex(FieldPath, MediaTypeTvShow);
1194 EXPECT_EQ(refindex, varindex);
1195
1196 refindex = VIDEODB_DETAILS_TVSHOW_DATEADDED;
1197 varindex = DatabaseUtils::GetFieldIndex(FieldDateAdded, MediaTypeTvShow);
1198 EXPECT_EQ(refindex, varindex);
1199
1200 refindex = VIDEODB_DETAILS_TVSHOW_NUM_EPISODES;
1201 varindex = DatabaseUtils::GetFieldIndex(FieldNumberOfEpisodes, MediaTypeTvShow);
1202 EXPECT_EQ(refindex, varindex);
1203
1204 refindex = VIDEODB_DETAILS_TVSHOW_NUM_WATCHED;
1205 varindex = DatabaseUtils::GetFieldIndex(FieldNumberOfWatchedEpisodes, MediaTypeTvShow);
1206 EXPECT_EQ(refindex, varindex);
1207
1208 refindex = VIDEODB_DETAILS_TVSHOW_NUM_SEASONS;
1209 varindex = DatabaseUtils::GetFieldIndex(FieldSeason, MediaTypeTvShow);
1210 EXPECT_EQ(refindex, varindex);
1211
1212 refindex = VIDEODB_DETAILS_TVSHOW_USER_RATING;
1213 varindex = DatabaseUtils::GetFieldIndex(FieldUserRating, MediaTypeTvShow);
1214 EXPECT_EQ(refindex, varindex);
1215
1216 refindex = VIDEODB_DETAILS_TVSHOW_VOTES;
1217 varindex = DatabaseUtils::GetFieldIndex(FieldVotes, MediaTypeTvShow);
1218 EXPECT_EQ(refindex, varindex);
1219
1220 refindex = VIDEODB_DETAILS_TVSHOW_RATING;
1221 varindex = DatabaseUtils::GetFieldIndex(FieldRating, MediaTypeTvShow);
1222 EXPECT_EQ(refindex, varindex);
1223
1224 refindex = -1;
1225 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeTvShow);
1226 EXPECT_EQ(refindex, varindex);
1227}
1228
1229TEST(TestDatabaseUtils, GetFieldIndex_MediaTypeEpisode)
1230{
1231 int refindex, varindex;
1232
1233 refindex = 0;
1234 varindex = DatabaseUtils::GetFieldIndex(FieldId, MediaTypeEpisode);
1235 EXPECT_EQ(refindex, varindex);
1236
1237 refindex = VIDEODB_ID_EPISODE_TITLE + 2;
1238 varindex = DatabaseUtils::GetFieldIndex(FieldTitle, MediaTypeEpisode);
1239 EXPECT_EQ(refindex, varindex);
1240
1241 refindex = VIDEODB_ID_EPISODE_PLOT + 2;
1242 varindex = DatabaseUtils::GetFieldIndex(FieldPlot, MediaTypeEpisode);
1243 EXPECT_EQ(refindex, varindex);
1244
1245 refindex = VIDEODB_ID_EPISODE_CREDITS + 2;
1246 varindex = DatabaseUtils::GetFieldIndex(FieldWriter, MediaTypeEpisode);
1247 EXPECT_EQ(refindex, varindex);
1248
1249 refindex = VIDEODB_ID_EPISODE_AIRED + 2;
1250 varindex = DatabaseUtils::GetFieldIndex(FieldAirDate, MediaTypeEpisode);
1251 EXPECT_EQ(refindex, varindex);
1252
1253 refindex = VIDEODB_ID_EPISODE_RUNTIME + 2;
1254 varindex = DatabaseUtils::GetFieldIndex(FieldTime, MediaTypeEpisode);
1255 EXPECT_EQ(refindex, varindex);
1256
1257 refindex = VIDEODB_ID_EPISODE_DIRECTOR + 2;
1258 varindex = DatabaseUtils::GetFieldIndex(FieldDirector, MediaTypeEpisode);
1259 EXPECT_EQ(refindex, varindex);
1260
1261 refindex = VIDEODB_ID_EPISODE_SEASON + 2;
1262 varindex = DatabaseUtils::GetFieldIndex(FieldSeason, MediaTypeEpisode);
1263 EXPECT_EQ(refindex, varindex);
1264
1265 refindex = VIDEODB_ID_EPISODE_EPISODE + 2;
1266 varindex = DatabaseUtils::GetFieldIndex(FieldEpisodeNumber, MediaTypeEpisode);
1267 EXPECT_EQ(refindex, varindex);
1268
1269 refindex = VIDEODB_DETAILS_EPISODE_FILE;
1270 varindex = DatabaseUtils::GetFieldIndex(FieldFilename, MediaTypeEpisode);
1271 EXPECT_EQ(refindex, varindex);
1272
1273 refindex = VIDEODB_DETAILS_EPISODE_PATH;
1274 varindex = DatabaseUtils::GetFieldIndex(FieldPath, MediaTypeEpisode);
1275 EXPECT_EQ(refindex, varindex);
1276
1277 refindex = VIDEODB_DETAILS_EPISODE_PLAYCOUNT;
1278 varindex = DatabaseUtils::GetFieldIndex(FieldPlaycount, MediaTypeEpisode);
1279 EXPECT_EQ(refindex, varindex);
1280
1281 refindex = VIDEODB_DETAILS_EPISODE_LASTPLAYED;
1282 varindex = DatabaseUtils::GetFieldIndex(FieldLastPlayed, MediaTypeEpisode);
1283 EXPECT_EQ(refindex, varindex);
1284
1285 refindex = VIDEODB_DETAILS_EPISODE_DATEADDED;
1286 varindex = DatabaseUtils::GetFieldIndex(FieldDateAdded, MediaTypeEpisode);
1287 EXPECT_EQ(refindex, varindex);
1288
1289 refindex = VIDEODB_DETAILS_EPISODE_TVSHOW_NAME;
1290 varindex = DatabaseUtils::GetFieldIndex(FieldTvShowTitle, MediaTypeEpisode);
1291 EXPECT_EQ(refindex, varindex);
1292
1293 refindex = VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO;
1294 varindex = DatabaseUtils::GetFieldIndex(FieldStudio, MediaTypeEpisode);
1295 EXPECT_EQ(refindex, varindex);
1296
1297 refindex = VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED;
1298 varindex = DatabaseUtils::GetFieldIndex(FieldYear, MediaTypeEpisode);
1299 EXPECT_EQ(refindex, varindex);
1300
1301 refindex = VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA;
1302 varindex = DatabaseUtils::GetFieldIndex(FieldMPAA, MediaTypeEpisode);
1303 EXPECT_EQ(refindex, varindex);
1304
1305 refindex = VIDEODB_DETAILS_EPISODE_USER_RATING;
1306 varindex = DatabaseUtils::GetFieldIndex(FieldUserRating, MediaTypeEpisode);
1307 EXPECT_EQ(refindex, varindex);
1308
1309 refindex = VIDEODB_DETAILS_EPISODE_VOTES;
1310 varindex = DatabaseUtils::GetFieldIndex(FieldVotes, MediaTypeEpisode);
1311 EXPECT_EQ(refindex, varindex);
1312
1313 refindex = VIDEODB_DETAILS_EPISODE_RATING;
1314 varindex = DatabaseUtils::GetFieldIndex(FieldRating, MediaTypeEpisode);
1315 EXPECT_EQ(refindex, varindex);
1316
1317 refindex = -1;
1318 varindex = DatabaseUtils::GetFieldIndex(FieldRandom, MediaTypeEpisode);
1319 EXPECT_EQ(refindex, varindex);
1320}
1321
1322TEST(TestDatabaseUtils, GetSelectFields)
1323{
1324 Fields fields;
1325 FieldList fieldlist;
1326
1327 EXPECT_FALSE(DatabaseUtils::GetSelectFields(fields, MediaTypeAlbum,
1328 fieldlist));
1329
1330 fields.insert(FieldId);
1331 fields.insert(FieldGenre);
1332 fields.insert(FieldAlbum);
1333 fields.insert(FieldArtist);
1334 fields.insert(FieldTitle);
1335 EXPECT_FALSE(DatabaseUtils::GetSelectFields(fields, MediaTypeNone,
1336 fieldlist));
1337 EXPECT_TRUE(DatabaseUtils::GetSelectFields(fields, MediaTypeAlbum,
1338 fieldlist));
1339 EXPECT_FALSE(fieldlist.empty());
1340}
1341
1342TEST(TestDatabaseUtils, GetFieldValue)
1343{
1344 CVariant v_null, v_string;
1345 dbiplus::field_value f_null, f_string("test");
1346
1347 f_null.set_isNull();
1348 EXPECT_TRUE(DatabaseUtils::GetFieldValue(f_null, v_null));
1349 EXPECT_TRUE(v_null.isNull());
1350
1351 EXPECT_TRUE(DatabaseUtils::GetFieldValue(f_string, v_string));
1352 EXPECT_FALSE(v_string.isNull());
1353 EXPECT_TRUE(v_string.isString());
1354}
1355
1356//! @todo Need some way to test this function
1357// TEST(TestDatabaseUtils, GetDatabaseResults)
1358// {
1359// static bool GetDatabaseResults(MediaType mediaType, const FieldList &fields,
1360// const std::unique_ptr<dbiplus::Dataset> &dataset,
1361// DatabaseResults &results);
1362// }
1363
1364TEST(TestDatabaseUtils, BuildLimitClause)
1365{
1366 std::string a = DatabaseUtils::BuildLimitClause(100);
1367 EXPECT_STREQ(" LIMIT 100", a.c_str());
1368}
1369
1370// class DatabaseUtils
1371// {
1372// public:
1373//
1374//
1375// static std::string BuildLimitClause(int end, int start = 0);
1376// };
diff --git a/xbmc/utils/test/TestDigest.cpp b/xbmc/utils/test/TestDigest.cpp
new file mode 100644
index 0000000..96d0529
--- /dev/null
+++ b/xbmc/utils/test/TestDigest.cpp
@@ -0,0 +1,99 @@
1/*
2 * Copyright (C) 2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/Digest.h"
10
11#include <gtest/gtest.h>
12
13using KODI::UTILITY::CDigest;
14using KODI::UTILITY::TypedDigest;
15
16TEST(TestDigest, Digest_Empty)
17{
18 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::MD5, "").c_str(), "d41d8cd98f00b204e9800998ecf8427e");
19 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::MD5, nullptr, 0).c_str(), "d41d8cd98f00b204e9800998ecf8427e");
20 {
21 CDigest digest{CDigest::Type::MD5};
22 EXPECT_STREQ(digest.Finalize().c_str(), "d41d8cd98f00b204e9800998ecf8427e");
23 }
24 {
25 CDigest digest{CDigest::Type::MD5};
26 digest.Update("");
27 digest.Update(nullptr, 0);
28 EXPECT_STREQ(digest.Finalize().c_str(), "d41d8cd98f00b204e9800998ecf8427e");
29 }
30}
31
32TEST(TestDigest, Digest_Basic)
33{
34 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::MD5, "asdf").c_str(), "912ec803b2ce49e4a541068d495ab570");
35 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::MD5, "asdf", 4).c_str(), "912ec803b2ce49e4a541068d495ab570");
36 {
37 CDigest digest{CDigest::Type::MD5};
38 digest.Update("as");
39 digest.Update("df", 2);
40 EXPECT_STREQ(digest.Finalize().c_str(), "912ec803b2ce49e4a541068d495ab570");
41 }
42}
43
44TEST(TestDigest, Digest_SHA1)
45{
46 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::SHA1, "").c_str(), "da39a3ee5e6b4b0d3255bfef95601890afd80709");
47 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::SHA1, "asdf").c_str(), "3da541559918a808c2402bba5012f6c60b27661c");
48}
49
50TEST(TestDigest, Digest_SHA256)
51{
52 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::SHA256, "").c_str(), "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
53 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::SHA256, "asdf").c_str(), "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b");
54}
55
56TEST(TestDigest, Digest_SHA512)
57{
58 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::SHA512, "").c_str(), "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e");
59 EXPECT_STREQ(CDigest::Calculate(CDigest::Type::SHA512, "asdf").c_str(), "401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429080fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1");
60}
61
62TEST(TestDigest, TypedDigest_Empty)
63{
64 TypedDigest t1, t2;
65 EXPECT_EQ(t1, t2);
66 EXPECT_EQ(t1.type, CDigest::Type::INVALID);
67 EXPECT_EQ(t1.value, "");
68 EXPECT_TRUE(t1.Empty());
69 t1.type = CDigest::Type::SHA1;
70 EXPECT_TRUE(t1.Empty());
71}
72
73TEST(TestDigest, TypedDigest_SameType)
74{
75 TypedDigest t1{CDigest::Type::SHA1, "da39a3ee5e6b4b0d3255bfef95601890afd80709"};
76 TypedDigest t2{CDigest::Type::SHA1, "da39a3ee5e6b4b0d3255bfef95601890afd80708"};
77 EXPECT_NE(t1, t2);
78 EXPECT_FALSE(t1.Empty());
79}
80
81TEST(TestDigest, TypedDigest_CompareCase)
82{
83 TypedDigest t1{CDigest::Type::SHA1, "da39a3ee5e6b4b0d3255bfef95601890afd80708"};
84 TypedDigest t2{CDigest::Type::SHA1, "da39A3EE5e6b4b0d3255bfef95601890afd80708"};
85 EXPECT_EQ(t1, t2);
86}
87
88TEST(TestDigest, TypedDigest_DifferingType)
89{
90 TypedDigest t1{CDigest::Type::SHA1, "da39a3ee5e6b4b0d3255bfef95601890afd80709"};
91 TypedDigest t2{CDigest::Type::SHA256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"};
92 // Silence "unused expression" warning
93 bool a;
94 EXPECT_THROW(a = (t1 == t2), std::logic_error);
95 // Silence "unused variable" warning
96 (void)a;
97 EXPECT_THROW(a = (t1 != t2), std::logic_error);
98 (void)a;
99}
diff --git a/xbmc/utils/test/TestEndianSwap.cpp b/xbmc/utils/test/TestEndianSwap.cpp
new file mode 100644
index 0000000..70d3cf0
--- /dev/null
+++ b/xbmc/utils/test/TestEndianSwap.cpp
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/EndianSwap.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestEndianSwap, Endian_Swap16)
14{
15 uint16_t ref, var;
16 ref = 0x00FF;
17 var = Endian_Swap16(0xFF00);
18 EXPECT_EQ(ref, var);
19}
20
21TEST(TestEndianSwap, Endian_Swap32)
22{
23 uint32_t ref, var;
24 ref = 0x00FF00FF;
25 var = Endian_Swap32(0xFF00FF00);
26 EXPECT_EQ(ref, var);
27}
28
29TEST(TestEndianSwap, Endian_Swap64)
30{
31 uint64_t ref, var;
32 ref = UINT64_C(0x00FF00FF00FF00FF);
33 var = Endian_Swap64(UINT64_C(0xFF00FF00FF00FF00));
34 EXPECT_EQ(ref, var);
35}
36
37#ifndef WORDS_BIGENDIAN
38TEST(TestEndianSwap, Endian_SwapLE16)
39{
40 uint16_t ref, var;
41 ref = 0x00FF;
42 var = Endian_SwapLE16(0x00FF);
43 EXPECT_EQ(ref, var);
44}
45
46TEST(TestEndianSwap, Endian_SwapLE32)
47{
48 uint32_t ref, var;
49 ref = 0x00FF00FF;
50 var = Endian_SwapLE32(0x00FF00FF);
51 EXPECT_EQ(ref, var);
52}
53
54TEST(TestEndianSwap, Endian_SwapLE64)
55{
56 uint64_t ref, var;
57 ref = UINT64_C(0x00FF00FF00FF00FF);
58 var = Endian_SwapLE64(UINT64_C(0x00FF00FF00FF00FF));
59 EXPECT_EQ(ref, var);
60}
61
62TEST(TestEndianSwap, Endian_SwapBE16)
63{
64 uint16_t ref, var;
65 ref = 0x00FF;
66 var = Endian_SwapBE16(0xFF00);
67 EXPECT_EQ(ref, var);
68}
69
70TEST(TestEndianSwap, Endian_SwapBE32)
71{
72 uint32_t ref, var;
73 ref = 0x00FF00FF;
74 var = Endian_SwapBE32(0xFF00FF00);
75 EXPECT_EQ(ref, var);
76}
77
78TEST(TestEndianSwap, Endian_SwapBE64)
79{
80 uint64_t ref, var;
81 ref = UINT64_C(0x00FF00FF00FF00FF);
82 var = Endian_SwapBE64(UINT64_C(0xFF00FF00FF00FF00));
83 EXPECT_EQ(ref, var);
84}
85#else
86TEST(TestEndianSwap, Endian_SwapLE16)
87{
88 uint16_t ref, var;
89 ref = 0x00FF;
90 var = Endian_SwapLE16(0xFF00);
91 EXPECT_EQ(ref, var);
92}
93
94TEST(TestEndianSwap, Endian_SwapLE32)
95{
96 uint32_t ref, var;
97 ref = 0x00FF00FF;
98 var = Endian_SwapLE32(0xFF00FF00);
99 EXPECT_EQ(ref, var);
100}
101
102TEST(TestEndianSwap, Endian_SwapLE64)
103{
104 uint64_t ref, var;
105 ref = UINT64_C(0x00FF00FF00FF00FF);
106 var = Endian_SwapLE64(UINT64_C(0xFF00FF00FF00FF00));
107 EXPECT_EQ(ref, var);
108}
109
110TEST(TestEndianSwap, Endian_SwapBE16)
111{
112 uint16_t ref, var;
113 ref = 0x00FF;
114 var = Endian_SwapBE16(0x00FF);
115 EXPECT_EQ(ref, var);
116}
117
118TEST(TestEndianSwap, Endian_SwapBE32)
119{
120 uint32_t ref, var;
121 ref = 0x00FF00FF;
122 var = Endian_SwapBE32(0x00FF00FF);
123 EXPECT_EQ(ref, var);
124}
125
126TEST(TestEndianSwap, Endian_SwapBE64)
127{
128 uint64_t ref, var;
129 ref = UINT64_C(0x00FF00FF00FF00FF);
130 var = Endian_SwapBE64(UINT64_C(0x00FF00FF00FF00FF));
131 EXPECT_EQ(ref, var);
132}
133#endif
diff --git a/xbmc/utils/test/TestFileOperationJob.cpp b/xbmc/utils/test/TestFileOperationJob.cpp
new file mode 100644
index 0000000..cab4125
--- /dev/null
+++ b/xbmc/utils/test/TestFileOperationJob.cpp
@@ -0,0 +1,288 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "filesystem/Directory.h"
10#include "filesystem/File.h"
11#include "test/TestUtils.h"
12#include "utils/FileOperationJob.h"
13#include "utils/URIUtils.h"
14
15#include <gtest/gtest.h>
16
17TEST(TestFileOperationJob, ActionCopy)
18{
19 XFILE::CFile *tmpfile;
20 std::string tmpfilepath, destfile;
21 CFileItemList items;
22 CFileOperationJob job;
23
24 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
25 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
26 tmpfile->Close();
27
28 CFileItemPtr item(new CFileItem(tmpfilepath));
29 item->SetPath(tmpfilepath);
30 item->m_bIsFolder = false;
31 item->Select(true);
32 items.Add(item);
33
34 std::string destpath = URIUtils::GetDirectory(tmpfilepath);
35 destpath = URIUtils::AddFileToFolder(destpath, "copy");
36 destfile = URIUtils::AddFileToFolder(destpath, URIUtils::GetFileName(tmpfilepath));
37 ASSERT_FALSE(XFILE::CFile::Exists(destfile));
38
39 job.SetFileOperation(CFileOperationJob::ActionCopy, items, destpath);
40 EXPECT_EQ(CFileOperationJob::ActionCopy, job.GetAction());
41
42 EXPECT_TRUE(job.DoWork());
43 EXPECT_TRUE(XFILE::CFile::Exists(tmpfilepath));
44 EXPECT_TRUE(XFILE::CFile::Exists(destfile));
45
46 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
47 EXPECT_TRUE(XFILE::CFile::Delete(destfile));
48 EXPECT_TRUE(XFILE::CDirectory::Remove(destpath));
49}
50
51TEST(TestFileOperationJob, ActionMove)
52{
53 XFILE::CFile *tmpfile;
54 std::string tmpfilepath, destfile;
55 CFileItemList items;
56 CFileOperationJob job;
57
58 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
59 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
60 tmpfile->Close();
61
62 CFileItemPtr item(new CFileItem(tmpfilepath));
63 item->SetPath(tmpfilepath);
64 item->m_bIsFolder = false;
65 item->Select(true);
66 items.Add(item);
67
68 std::string destpath = URIUtils::GetDirectory(tmpfilepath);
69 destpath = URIUtils::AddFileToFolder(destpath, "move");
70 destfile = URIUtils::AddFileToFolder(destpath, URIUtils::GetFileName(tmpfilepath));
71 ASSERT_FALSE(XFILE::CFile::Exists(destfile));
72 ASSERT_TRUE(XFILE::CDirectory::Create(destpath));
73
74 job.SetFileOperation(CFileOperationJob::ActionMove, items, destpath);
75 EXPECT_EQ(CFileOperationJob::ActionMove, job.GetAction());
76
77 EXPECT_TRUE(job.DoWork());
78 EXPECT_FALSE(XFILE::CFile::Exists(tmpfilepath));
79 EXPECT_TRUE(XFILE::CFile::Exists(destfile));
80
81 EXPECT_TRUE(XFILE::CFile::Delete(destfile));
82 EXPECT_TRUE(XFILE::CDirectory::Remove(destpath));
83}
84
85TEST(TestFileOperationJob, ActionDelete)
86{
87 XFILE::CFile *tmpfile;
88 std::string tmpfilepath, destfile;
89 CFileItemList items;
90 CFileOperationJob job;
91
92 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
93 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
94 tmpfile->Close();
95
96 CFileItemPtr item(new CFileItem(tmpfilepath));
97 item->SetPath(tmpfilepath);
98 item->m_bIsFolder = false;
99 item->Select(true);
100 items.Add(item);
101
102 std::string destpath = URIUtils::GetDirectory(tmpfilepath);
103 destpath = URIUtils::AddFileToFolder(destpath, "delete");
104 destfile = URIUtils::AddFileToFolder(destpath, URIUtils::GetFileName(tmpfilepath));
105 ASSERT_FALSE(XFILE::CFile::Exists(destfile));
106
107 job.SetFileOperation(CFileOperationJob::ActionCopy, items, destpath);
108 EXPECT_EQ(CFileOperationJob::ActionCopy, job.GetAction());
109
110 EXPECT_TRUE(job.DoWork());
111 EXPECT_TRUE(XFILE::CFile::Exists(tmpfilepath));
112 EXPECT_TRUE(XFILE::CFile::Exists(destfile));
113
114 job.SetFileOperation(CFileOperationJob::ActionDelete, items, "");
115 EXPECT_EQ(CFileOperationJob::ActionDelete, job.GetAction());
116
117 EXPECT_TRUE(job.DoWork());
118 EXPECT_FALSE(XFILE::CFile::Exists(tmpfilepath));
119
120 items.Clear();
121 CFileItemPtr item2(new CFileItem(destfile));
122 item2->SetPath(destfile);
123 item2->m_bIsFolder = false;
124 item2->Select(true);
125 items.Add(item2);
126
127 job.SetFileOperation(CFileOperationJob::ActionDelete, items, "");
128 EXPECT_EQ(CFileOperationJob::ActionDelete, job.GetAction());
129
130 EXPECT_TRUE(job.DoWork());
131 EXPECT_FALSE(XFILE::CFile::Exists(destfile));
132 EXPECT_TRUE(XFILE::CDirectory::Remove(destpath));
133}
134
135TEST(TestFileOperationJob, ActionReplace)
136{
137 XFILE::CFile *tmpfile;
138 std::string tmpfilepath, destfile;
139 CFileItemList items;
140 CFileOperationJob job;
141
142 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
143 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
144 tmpfile->Close();
145
146 CFileItemPtr item(new CFileItem(tmpfilepath));
147 item->SetPath(tmpfilepath);
148 item->m_bIsFolder = false;
149 item->Select(true);
150 items.Add(item);
151
152 std::string destpath = URIUtils::GetDirectory(tmpfilepath);
153 destpath = URIUtils::AddFileToFolder(destpath, "replace");
154 destfile = URIUtils::AddFileToFolder(destpath, URIUtils::GetFileName(tmpfilepath));
155 ASSERT_FALSE(XFILE::CFile::Exists(destfile));
156
157 job.SetFileOperation(CFileOperationJob::ActionCopy, items, destpath);
158 EXPECT_EQ(CFileOperationJob::ActionCopy, job.GetAction());
159
160 EXPECT_TRUE(job.DoWork());
161 EXPECT_TRUE(XFILE::CFile::Exists(tmpfilepath));
162 EXPECT_TRUE(XFILE::CFile::Exists(destfile));
163
164 job.SetFileOperation(CFileOperationJob::ActionReplace, items, destpath);
165 EXPECT_EQ(CFileOperationJob::ActionReplace, job.GetAction());
166
167 EXPECT_TRUE(job.DoWork());
168 EXPECT_TRUE(XFILE::CFile::Exists(destfile));
169
170 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
171 EXPECT_TRUE(XFILE::CFile::Delete(destfile));
172 EXPECT_TRUE(XFILE::CDirectory::Remove(destpath));
173}
174
175TEST(TestFileOperationJob, ActionCreateFolder)
176{
177 XFILE::CFile *tmpfile;
178 std::string tmpfilepath, destpath;
179 CFileItemList items;
180 CFileOperationJob job;
181
182 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
183 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
184
185 std::string tmpfiledirectory =
186 CXBMCTestUtils::Instance().TempFileDirectory(tmpfile);
187
188 tmpfile->Close();
189
190 destpath = tmpfilepath;
191 destpath += ".createfolder";
192 ASSERT_FALSE(XFILE::CFile::Exists(destpath));
193
194 CFileItemPtr item(new CFileItem(destpath));
195 item->SetPath(destpath);
196 item->m_bIsFolder = true;
197 item->Select(true);
198 items.Add(item);
199
200 job.SetFileOperation(CFileOperationJob::ActionCreateFolder, items, tmpfiledirectory);
201 EXPECT_EQ(CFileOperationJob::ActionCreateFolder, job.GetAction());
202
203 EXPECT_TRUE(job.DoWork());
204 EXPECT_TRUE(XFILE::CDirectory::Exists(destpath));
205
206 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
207 EXPECT_TRUE(XFILE::CDirectory::Remove(destpath));
208}
209
210// This test will fail until ActionDeleteFolder has a proper implementation
211TEST(TestFileOperationJob, ActionDeleteFolder)
212{
213 XFILE::CFile *tmpfile;
214 std::string tmpfilepath, destpath;
215 CFileItemList items;
216 CFileOperationJob job;
217
218 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
219 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
220
221 std::string tmpfiledirectory =
222 CXBMCTestUtils::Instance().TempFileDirectory(tmpfile);
223
224 tmpfile->Close();
225
226 destpath = tmpfilepath;
227 destpath += ".deletefolder";
228 ASSERT_FALSE(XFILE::CFile::Exists(destpath));
229
230 CFileItemPtr item(new CFileItem(destpath));
231 item->SetPath(destpath);
232 item->m_bIsFolder = true;
233 item->Select(true);
234 items.Add(item);
235
236 job.SetFileOperation(CFileOperationJob::ActionCreateFolder, items, tmpfiledirectory);
237 EXPECT_EQ(CFileOperationJob::ActionCreateFolder, job.GetAction());
238
239 EXPECT_TRUE(job.DoWork());
240 EXPECT_TRUE(XFILE::CDirectory::Exists(destpath));
241
242 job.SetFileOperation(CFileOperationJob::ActionDeleteFolder, items, tmpfiledirectory);
243 EXPECT_EQ(CFileOperationJob::ActionDeleteFolder, job.GetAction());
244
245 EXPECT_TRUE(job.DoWork());
246 EXPECT_FALSE(XFILE::CDirectory::Exists(destpath));
247
248 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
249}
250
251TEST(TestFileOperationJob, GetFunctions)
252{
253 XFILE::CFile *tmpfile;
254 std::string tmpfilepath, destfile;
255 CFileItemList items;
256 CFileOperationJob job;
257
258 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
259 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
260 tmpfile->Close();
261
262 CFileItemPtr item(new CFileItem(tmpfilepath));
263 item->SetPath(tmpfilepath);
264 item->m_bIsFolder = false;
265 item->Select(true);
266 items.Add(item);
267
268 std::string destpath = URIUtils::GetDirectory(tmpfilepath);
269 destpath = URIUtils::AddFileToFolder(destpath, "getfunctions");
270 destfile = URIUtils::AddFileToFolder(destpath, URIUtils::GetFileName(tmpfilepath));
271 ASSERT_FALSE(XFILE::CFile::Exists(destfile));
272
273 job.SetFileOperation(CFileOperationJob::ActionCopy, items, destpath);
274 EXPECT_EQ(CFileOperationJob::ActionCopy, job.GetAction());
275
276 EXPECT_TRUE(job.DoWork());
277 EXPECT_TRUE(XFILE::CFile::Exists(tmpfilepath));
278 EXPECT_TRUE(XFILE::CFile::Exists(destfile));
279
280 std::cout << "GetAverageSpeed(): " << job.GetAverageSpeed() << std::endl;
281 std::cout << "GetCurrentOperation(): " << job.GetCurrentOperation() << std::endl;
282 std::cout << "GetCurrentFile(): " << job.GetCurrentFile() << std::endl;
283 EXPECT_FALSE(job.GetItems().IsEmpty());
284
285 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
286 EXPECT_TRUE(XFILE::CFile::Delete(destfile));
287 EXPECT_TRUE(XFILE::CDirectory::Remove(destpath));
288}
diff --git a/xbmc/utils/test/TestFileUtils.cpp b/xbmc/utils/test/TestFileUtils.cpp
new file mode 100644
index 0000000..720e82d
--- /dev/null
+++ b/xbmc/utils/test/TestFileUtils.cpp
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "filesystem/File.h"
10#include "test/TestUtils.h"
11#include "utils/FileUtils.h"
12
13#include <gtest/gtest.h>
14
15TEST(TestFileUtils, DeleteItem_CFileItemPtr)
16{
17 XFILE::CFile *tmpfile;
18 std::string tmpfilepath;
19
20 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
21 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
22
23 CFileItemPtr item(new CFileItem(tmpfilepath));
24 item->SetPath(tmpfilepath);
25 item->m_bIsFolder = false;
26 item->Select(true);
27 tmpfile->Close(); //Close tmpfile before we try to delete it
28 EXPECT_TRUE(CFileUtils::DeleteItem(item));
29}
30
31TEST(TestFileUtils, DeleteItemString)
32{
33 XFILE::CFile *tmpfile;
34
35 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
36 tmpfile->Close(); //Close tmpfile before we try to delete it
37 EXPECT_TRUE(CFileUtils::DeleteItem(XBMC_TEMPFILEPATH(tmpfile)));
38}
39
40/* Executing RenameFile() requires input from the user */
41// static bool RenameFile(const std::string &strFile);
diff --git a/xbmc/utils/test/TestGlobalsHandling.cpp b/xbmc/utils/test/TestGlobalsHandling.cpp
new file mode 100644
index 0000000..5b8d26a
--- /dev/null
+++ b/xbmc/utils/test/TestGlobalsHandling.cpp
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/test/TestGlobalsHandlingPattern1.h"
10
11#include <gtest/gtest.h>
12
13using namespace xbmcutil;
14using namespace test;
15
16bool TestGlobalPattern1::ctorCalled = false;
17bool TestGlobalPattern1::dtorCalled = false;
18
19TEST(TestGlobal, Pattern1)
20{
21 EXPECT_TRUE(TestGlobalPattern1::ctorCalled);
22 {
23 std::shared_ptr<TestGlobalPattern1> ptr = g_testGlobalPattern1Ref;
24 }
25}
diff --git a/xbmc/utils/test/TestGlobalsHandlingPattern1.h b/xbmc/utils/test/TestGlobalsHandlingPattern1.h
new file mode 100644
index 0000000..92088b8
--- /dev/null
+++ b/xbmc/utils/test/TestGlobalsHandlingPattern1.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#pragma once
10
11#include "utils/GlobalsHandling.h"
12
13#include <iostream>
14
15namespace xbmcutil
16{
17 namespace test
18 {
19 class TestGlobalPattern1
20 {
21 public:
22 static bool ctorCalled;
23 static bool dtorCalled;
24
25 int somethingToAccess = 0;
26
27 TestGlobalPattern1() { ctorCalled = true; }
28 ~TestGlobalPattern1()
29 {
30 std::cout << "Clean shutdown of TestGlobalPattern1" << std::endl << std::flush;
31 dtorCalled = true;
32 }
33
34 void beHappy() { if (somethingToAccess) throw somethingToAccess; }
35 };
36 }
37}
38
39XBMC_GLOBAL_REF(xbmcutil::test::TestGlobalPattern1,g_testGlobalPattern1);
40#define g_testGlobalPattern1 XBMC_GLOBAL_USE(xbmcutil::test::TestGlobalPattern1)
diff --git a/xbmc/utils/test/TestHTMLUtil.cpp b/xbmc/utils/test/TestHTMLUtil.cpp
new file mode 100644
index 0000000..7d0e515
--- /dev/null
+++ b/xbmc/utils/test/TestHTMLUtil.cpp
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/HTMLUtil.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestHTMLUtil, RemoveTags)
14{
15 std::string str;
16 str = "<!DOCTYPE html>\n"
17 "<html>\n"
18 " <head class=\"someclass\">\n"
19 " <body>\n"
20 " <p>blah blah blah</p>\n"
21 " </body>\n"
22 " </head>\n"
23 "</html>\n";
24 HTML::CHTMLUtil::RemoveTags(str);
25 EXPECT_STREQ("\n\n \n \n blah blah blah\n \n \n\n",
26 str.c_str());
27}
28
29TEST(TestHTMLUtil, ConvertHTMLToW)
30{
31 std::wstring inw, refstrw, varstrw;
32 inw = L"&aring;&amp;&euro;";
33 refstrw = L"\u00e5&\u20ac";
34 HTML::CHTMLUtil::ConvertHTMLToW(inw, varstrw);
35 EXPECT_STREQ(refstrw.c_str(), varstrw.c_str());
36}
diff --git a/xbmc/utils/test/TestHttpHeader.cpp b/xbmc/utils/test/TestHttpHeader.cpp
new file mode 100644
index 0000000..1aeecc7
--- /dev/null
+++ b/xbmc/utils/test/TestHttpHeader.cpp
@@ -0,0 +1,505 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/HttpHeader.h"
10
11#include <string.h>
12
13#include <gtest/gtest.h>
14
15#define CHECK_CNT_TYPE_NAME "Content-Type"
16#define CHECK_CONTENT_TYPE_HTML "text/html"
17#define CHECK_CONTENT_TYPE_HTML_CHRS "text/html; charset=WINDOWS-1251"
18#define CHECK_CONTENT_TYPE_XML_CHRS "text/xml; charset=uTf-8"
19#define CHECK_CONTENT_TYPE_TEXT "text/plain"
20#define CHECK_DATE_NAME "Date"
21#define CHECK_DATE_VALUE1 "Thu, 09 Jan 2014 17:58:30 GMT"
22#define CHECK_DATE_VALUE2 "Thu, 09 Jan 2014 20:21:20 GMT"
23#define CHECK_DATE_VALUE3 "Thu, 09 Jan 2014 20:25:02 GMT"
24#define CHECK_PROT_LINE_200 "HTTP/1.1 200 OK"
25#define CHECK_PROT_LINE_301 "HTTP/1.1 301 Moved Permanently"
26
27#define CHECK_HEADER_SMPL CHECK_PROT_LINE_200 "\r\n" \
28 CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n" \
29 "\r\n"
30
31#define CHECK_HEADER_L1 CHECK_PROT_LINE_200 "\r\n" \
32 "Server: nginx/1.4.4\r\n" \
33 CHECK_DATE_NAME ": " CHECK_DATE_VALUE1 "\r\n" \
34 CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML_CHRS "\r\n" \
35 "Transfer-Encoding: chunked\r\n" \
36 "Connection: close\r\n" \
37 "Set-Cookie: PHPSESSID=90857d437518db8f0944ca012761048a; path=/; domain=example.com\r\n" \
38 "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" \
39 "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" \
40 "Pragma: no-cache\r\n" \
41 "Set-Cookie: user_country=ot; expires=Thu, 09-Jan-2014 18:58:30 GMT; path=/; domain=.example.com\r\n" \
42 "\r\n"
43
44#define CHECK_HEADER_R CHECK_PROT_LINE_301 "\r\n" \
45 "Server: nginx/1.4.4\r\n" \
46 CHECK_DATE_NAME ": " CHECK_DATE_VALUE2 "\r\n" \
47 CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n" \
48 "Content-Length: 150\r\n" \
49 "Connection: close\r\n" \
50 "Location: http://www.Example.Com\r\n" \
51 "\r\n"
52
53#define CHECK_HEADER_L2 CHECK_PROT_LINE_200 "\r\n" \
54 CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\n" \
55 "Server: Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e\r\n" \
56 "Last-Modified: Thu, 09 Jan 2014 20:10:28 GMT\r\n" \
57 "ETag: \"9a97-4ef8f335ebd10\"\r\n" \
58 "Accept-Ranges: bytes\r\n" \
59 "Content-Length: 33355\r\n" \
60 "Vary: Accept-Encoding\r\n" \
61 "Cache-Control: max-age=3600\r\n" \
62 "Expires: Thu, 09 Jan 2014 21:25:02 GMT\r\n" \
63 "Connection: close\r\n" \
64 CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_XML_CHRS "\r\n" \
65 "\r\n"
66
67// local helper function: replace substrings
68std::string strReplace(const std::string& str, const std::string& from, const std::string& to)
69{
70 std::string result;
71 size_t prevPos = 0;
72 size_t pos;
73 const size_t len = str.length();
74
75 do
76 {
77 pos = str.find(from, prevPos);
78 result.append(str, prevPos, pos - prevPos);
79 if (pos >= len)
80 break;
81 result.append(to);
82 prevPos = pos + from.length();
83 } while (true);
84
85 return result;
86}
87
88TEST(TestHttpHeader, General)
89{
90 /* check freshly created object */
91 CHttpHeader testHdr;
92 EXPECT_TRUE(testHdr.GetHeader().empty()) << "Newly created object is not empty";
93 EXPECT_TRUE(testHdr.GetProtoLine().empty()) << "Newly created object has non-empty protocol line";
94 EXPECT_TRUE(testHdr.GetMimeType().empty()) << "Newly created object has non-empty MIME-type";
95 EXPECT_TRUE(testHdr.GetCharset().empty()) << "Newly created object has non-empty charset";
96 EXPECT_TRUE(testHdr.GetValue("foo").empty()) << "Newly created object has some parameter";
97 EXPECT_TRUE(testHdr.GetValues("bar").empty()) << "Newly created object has some parameters";
98 EXPECT_FALSE(testHdr.IsHeaderDone()) << "Newly created object has \"parsing finished\" state";
99
100 /* check general functions in simple case */
101 testHdr.Parse(CHECK_HEADER_SMPL);
102 EXPECT_FALSE(testHdr.GetHeader().empty()) << "Parsed header is empty";
103 EXPECT_FALSE(testHdr.GetProtoLine().empty()) << "Parsed header has empty protocol line";
104 EXPECT_FALSE(testHdr.GetMimeType().empty()) << "Parsed header has empty MIME-type";
105 EXPECT_FALSE(testHdr.GetValue(CHECK_CNT_TYPE_NAME).empty()) << "Parsed header has empty \"" CHECK_CNT_TYPE_NAME "\" parameter";
106 EXPECT_FALSE(testHdr.GetValues(CHECK_CNT_TYPE_NAME).empty()) << "Parsed header has no \"" CHECK_CNT_TYPE_NAME "\" parameters";
107 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Parsed header has \"parsing not finished\" state";
108
109 /* check clearing of object */
110 testHdr.Clear();
111 EXPECT_TRUE(testHdr.GetHeader().empty()) << "Cleared object is not empty";
112 EXPECT_TRUE(testHdr.GetProtoLine().empty()) << "Cleared object has non-empty protocol line";
113 EXPECT_TRUE(testHdr.GetMimeType().empty()) << "Cleared object has non-empty MIME-type";
114 EXPECT_TRUE(testHdr.GetCharset().empty()) << "Cleared object has non-empty charset";
115 EXPECT_TRUE(testHdr.GetValue(CHECK_CNT_TYPE_NAME).empty()) << "Cleared object has some parameter";
116 EXPECT_TRUE(testHdr.GetValues(CHECK_CNT_TYPE_NAME).empty()) << "Cleared object has some parameters";
117 EXPECT_FALSE(testHdr.IsHeaderDone()) << "Cleared object has \"parsing finished\" state";
118
119 /* check general functions after object clearing */
120 testHdr.Parse(CHECK_HEADER_R);
121 EXPECT_FALSE(testHdr.GetHeader().empty()) << "Parsed header is empty";
122 EXPECT_FALSE(testHdr.GetProtoLine().empty()) << "Parsed header has empty protocol line";
123 EXPECT_FALSE(testHdr.GetMimeType().empty()) << "Parsed header has empty MIME-type";
124 EXPECT_FALSE(testHdr.GetValue(CHECK_CNT_TYPE_NAME).empty()) << "Parsed header has empty \"" CHECK_CNT_TYPE_NAME "\" parameter";
125 EXPECT_FALSE(testHdr.GetValues(CHECK_CNT_TYPE_NAME).empty()) << "Parsed header has no \"" CHECK_CNT_TYPE_NAME "\" parameters";
126 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Parsed header has \"parsing not finished\" state";
127}
128
129TEST(TestHttpHeader, Parse)
130{
131 CHttpHeader testHdr;
132
133 /* check parsing line-by-line */
134 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
135 EXPECT_FALSE(testHdr.IsHeaderDone()) << "Not completed header has \"parsing finished\" state";
136 testHdr.Parse(CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n");
137 EXPECT_FALSE(testHdr.IsHeaderDone()) << "Not completed header has \"parsing finished\" state";
138 testHdr.Parse("\r\n");
139 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
140 EXPECT_STREQ(CHECK_PROT_LINE_200, testHdr.GetProtoLine().c_str()) << "Wrong protocol line";
141 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
142
143 /* check autoclearing when new header is parsed */
144 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
145 EXPECT_FALSE(testHdr.IsHeaderDone()) << "Not completed header has \"parsing finished\" state";
146 EXPECT_TRUE(testHdr.GetValues(CHECK_CNT_TYPE_NAME).empty()) << "Cleared header has some parameters";
147 testHdr.Clear();
148 EXPECT_TRUE(testHdr.GetHeader().empty()) << "Cleared object is not empty";
149
150 /* general check parsing */
151 testHdr.Parse(CHECK_HEADER_SMPL);
152 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
153 EXPECT_STRCASEEQ(CHECK_HEADER_SMPL, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
154 testHdr.Parse(CHECK_HEADER_L1);
155 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
156 EXPECT_STRCASEEQ(CHECK_HEADER_L1, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
157 EXPECT_STREQ("Thu, 09 Jan 2014 17:58:30 GMT", testHdr.GetValue("Date").c_str()); // case-sensitive match of value
158 testHdr.Parse(CHECK_HEADER_L2);
159 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
160 EXPECT_STRCASEEQ(CHECK_HEADER_L2, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
161 EXPECT_STREQ("Thu, 09 Jan 2014 20:10:28 GMT", testHdr.GetValue("Last-Modified").c_str()); // case-sensitive match of value
162 testHdr.Parse(CHECK_HEADER_R);
163 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
164 EXPECT_STRCASEEQ(CHECK_HEADER_R, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
165 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("Location").c_str()); // case-sensitive match of value
166
167 /* check support for '\n' line endings */
168 testHdr.Parse(strReplace(CHECK_HEADER_SMPL, "\r\n", "\n"));
169 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
170 EXPECT_STRCASEEQ(CHECK_HEADER_SMPL, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
171 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
172 testHdr.Parse(strReplace(CHECK_HEADER_L1, "\r\n", "\n"));
173 EXPECT_STRCASEEQ(CHECK_HEADER_L1, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
174 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
175 testHdr.Parse(strReplace(CHECK_HEADER_L2, "\r\n", "\n"));
176 EXPECT_STRCASEEQ(CHECK_HEADER_L2, testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
177 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
178 testHdr.Parse(CHECK_PROT_LINE_200 "\n" CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n"); // mixed "\n" and "\r\n"
179 testHdr.Parse("\n");
180 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
181 EXPECT_STRCASEEQ(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n\r\n", testHdr.GetHeader().c_str()) << "Parsed header mismatch the original header";
182 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
183
184 /* check trimming of whitespaces for parameter name and value */
185 testHdr.Clear();
186 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML "\r\n\r\n");
187 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
188 testHdr.Clear();
189 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_HTML " \r\n\r\n");
190 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
191 testHdr.Clear();
192 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME ":" CHECK_CONTENT_TYPE_HTML " \r\n\r\n");
193 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
194 testHdr.Clear();
195 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME ":\t" CHECK_CONTENT_TYPE_HTML " \t \r\n\r\n");
196 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
197 testHdr.Clear();
198 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME ":\t " CHECK_CONTENT_TYPE_HTML " \t \r\n\r\n");
199 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
200 testHdr.Clear();
201 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME "\t:" CHECK_CONTENT_TYPE_HTML " \t \r\n\r\n");
202 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
203 testHdr.Clear();
204 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_CNT_TYPE_NAME " \t : " CHECK_CONTENT_TYPE_HTML " \t \r\n\r\n");
205 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong value of parameter \"" CHECK_CNT_TYPE_NAME "\"";
206}
207
208TEST(TestHttpHeader, Parse_Multiline)
209{
210 CHttpHeader testHdr;
211
212 /* Check multiline parameter parsing line-by-line */
213 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
214 testHdr.Parse(CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\n");
215 testHdr.Parse("X-Comment: This\r\n"); // between singleline parameters
216 testHdr.Parse(" is\r\n");
217 testHdr.Parse(" multi\r\n");
218 testHdr.Parse(" line\r\n");
219 testHdr.Parse(" value\r\n");
220 testHdr.Parse(CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_TEXT "\r\n");
221 testHdr.Parse("\r\n");
222 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
223 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
224
225 testHdr.Clear();
226 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
227 testHdr.Parse("X-Comment: This\r\n"); // first parameter
228 testHdr.Parse(" is\r\n");
229 testHdr.Parse(" multi\r\n");
230 testHdr.Parse(" line\r\n");
231 testHdr.Parse(" value\r\n");
232 testHdr.Parse(CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_TEXT "\r\n");
233 testHdr.Parse("\r\n");
234 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
235 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
236
237 testHdr.Clear();
238 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
239 testHdr.Parse(CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\n");
240 testHdr.Parse("X-Comment: This\r\n"); // last parameter
241 testHdr.Parse(" is\r\n");
242 testHdr.Parse(" multi\r\n");
243 testHdr.Parse(" line\r\n");
244 testHdr.Parse(" value\r\n");
245 testHdr.Parse("\r\n");
246 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
247 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
248
249 testHdr.Clear();
250 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
251 testHdr.Parse("X-Comment: This\r\n"); // the only parameter
252 testHdr.Parse(" is\r\n");
253 testHdr.Parse(" multi\r\n");
254 testHdr.Parse(" line\r\n");
255 testHdr.Parse(" value\r\n");
256 testHdr.Parse("\r\n");
257 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
258 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
259
260 testHdr.Clear();
261 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
262 testHdr.Parse("X-Comment: This\n"); // the only parameter with mixed ending style
263 testHdr.Parse(" is\r\n");
264 testHdr.Parse(" multi\n");
265 testHdr.Parse(" line\r\n");
266 testHdr.Parse(" value\n");
267 testHdr.Parse("\r\n");
268 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
269 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
270
271 /* Check multiline parameter parsing as one line */
272 testHdr.Clear();
273 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\nX-Comment: This\r\n is\r\n multi\r\n line\r\n value\r\n" \
274 CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_TEXT "\r\n\r\n"); // between singleline parameters
275 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
276 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
277
278 testHdr.Clear();
279 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nX-Comment: This\r\n is\r\n multi\r\n line\r\n value\r\n" \
280 CHECK_CNT_TYPE_NAME ": " CHECK_CONTENT_TYPE_TEXT "\r\n\r\n"); // first parameter
281 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
282 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
283
284 testHdr.Clear();
285 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n" CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\nX-Comment: This\r\n is\r\n multi\r\n line\r\n value\r\n\r\n"); // last parameter
286 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
287 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
288
289 testHdr.Clear();
290 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nX-Comment: This\r\n is\r\n multi\r\n line\r\n value\r\n\r\n"); // the only parameter
291 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
292 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
293
294 testHdr.Clear();
295 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nX-Comment: This\n is\r\n multi\r\n line\n value\r\n\n"); // the only parameter with mixed ending style
296 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
297 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
298
299 /* Check multiline parameter parsing as mixed one/many lines */
300 testHdr.Clear();
301 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nX-Comment: This\n is\r\n multi\r\n");
302 testHdr.Parse(" line\n value\r\n\n"); // the only parameter with mixed ending style
303 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
304 EXPECT_STREQ("This is multi line value", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
305
306 /* Check parsing of multiline parameter with ':' in value */
307 testHdr.Clear();
308 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nX-Comment: This\r\n is:\r\n mul:ti\r\n");
309 testHdr.Parse(" :line\r\n valu:e\r\n\n"); // the only parameter
310 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
311 EXPECT_STREQ("This is: mul:ti :line valu:e", testHdr.GetValue("X-Comment").c_str()) << "Wrong multiline value";
312
313 /* Check multiline parameter parsing with trimming */
314 testHdr.Clear();
315 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
316 testHdr.Parse(CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\n");
317 testHdr.Parse("Server: Apache/2.4.7 (Unix)\r\n"); // last parameter, line-by-line parsing
318 testHdr.Parse(" mod_wsgi/3.4 \r\n");
319 testHdr.Parse("\tPython/2.7.5\r\n");
320 testHdr.Parse("\t \t \tOpenSSL/1.0.1e\r\n");
321 testHdr.Parse("\r\n");
322 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
323 EXPECT_GE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 \tPython/2.7.5\t \t \tOpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is greater than length of original string";
324 EXPECT_LE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is less than length of trimmed original string";
325 EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplace(strReplace(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces";
326
327 testHdr.Clear();
328 testHdr.Parse(CHECK_PROT_LINE_200 "\r\n");
329 testHdr.Parse(CHECK_DATE_NAME ": " CHECK_DATE_VALUE3 "\r\n");
330 testHdr.Parse("Server: Apache/2.4.7 (Unix)\r\n mod_wsgi/3.4 \n"); // last parameter, mixed line-by-line/one line parsing, mixed line ending
331 testHdr.Parse("\tPython/2.7.5\n\t \t \tOpenSSL/1.0.1e\r\n");
332 testHdr.Parse("\r\n");
333 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
334 EXPECT_GE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 \tPython/2.7.5\t \t \tOpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is greater than length of original string";
335 EXPECT_LE(strlen("Apache/2.4.7 (Unix) mod_wsgi/3.4 Python/2.7.5 OpenSSL/1.0.1e"), testHdr.GetValue("Server").length()) << "Length of miltiline value is less than length of trimmed original string";
336 EXPECT_STREQ("Apache/2.4.7(Unix)mod_wsgi/3.4Python/2.7.5OpenSSL/1.0.1e", strReplace(strReplace(testHdr.GetValue("Server"), " ", ""), "\t", "").c_str()) << "Multiline value with removed whitespaces does not match original string with removed whitespaces";
337}
338
339TEST(TestHttpHeader, GetValue)
340{
341 CHttpHeader testHdr;
342
343 /* Check that all parameters values can be retrieved */
344 testHdr.Parse(CHECK_HEADER_R);
345 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
346 EXPECT_STREQ("nginx/1.4.4", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
347 EXPECT_STREQ(CHECK_DATE_VALUE2, testHdr.GetValue(CHECK_DATE_NAME).c_str()) << "Wrong parameter value";
348 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong parameter value";
349 EXPECT_STREQ("150", testHdr.GetValue("Content-Length").c_str()) << "Wrong parameter value";
350 EXPECT_STREQ("close", testHdr.GetValue("Connection").c_str()) << "Wrong parameter value";
351 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("Location").c_str()) << "Wrong parameter value";
352 EXPECT_TRUE(testHdr.GetValue("foo").empty()) << "Some value is returned for non-existed parameter";
353
354 /* Check that all parameters values can be retrieved in random order */
355 testHdr.Parse(CHECK_HEADER_R);
356 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Completed header has \"parsing not finished\" state";
357 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("Location").c_str()) << "Wrong parameter value";
358 EXPECT_STREQ(CHECK_CONTENT_TYPE_HTML, testHdr.GetValue(CHECK_CNT_TYPE_NAME).c_str()) << "Wrong parameter value";
359 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("Location").c_str()) << "Wrong parameter value";
360 EXPECT_STREQ("close", testHdr.GetValue("Connection").c_str()) << "Wrong parameter value";
361 EXPECT_STREQ("nginx/1.4.4", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
362 EXPECT_STREQ("150", testHdr.GetValue("Content-Length").c_str()) << "Wrong parameter value";
363 EXPECT_STREQ(CHECK_DATE_VALUE2, testHdr.GetValue(CHECK_DATE_NAME).c_str()) << "Wrong parameter value";
364 EXPECT_STREQ("nginx/1.4.4", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
365 EXPECT_TRUE(testHdr.GetValue("foo").empty()) << "Some value is returned for non-existed parameter";
366
367 /* Check that parameters name is case-insensitive and value is case-sensitive*/
368 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("location").c_str()) << "Wrong parameter value for lowercase name";
369 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("LOCATION").c_str()) << "Wrong parameter value for UPPERCASE name";
370 EXPECT_STREQ("http://www.Example.Com", testHdr.GetValue("LoCAtIOn").c_str()) << "Wrong parameter value for MiXEdcASe name";
371
372 /* Check value of last added parameter with the same name is returned */
373 testHdr.Parse(CHECK_HEADER_L1);
374 EXPECT_STREQ("close", testHdr.GetValue("Connection").c_str()) << "Wrong parameter value";
375 EXPECT_STREQ("user_country=ot; expires=Thu, 09-Jan-2014 18:58:30 GMT; path=/; domain=.example.com", testHdr.GetValue("Set-Cookie").c_str()) << "Wrong parameter value";
376 EXPECT_STREQ("user_country=ot; expires=Thu, 09-Jan-2014 18:58:30 GMT; path=/; domain=.example.com", testHdr.GetValue("set-cookie").c_str()) << "Wrong parameter value for lowercase name";
377}
378
379TEST(TestHttpHeader, GetValues)
380{
381 CHttpHeader testHdr;
382
383 /* Check that all parameter values can be retrieved and order of values is correct */
384 testHdr.Parse(CHECK_HEADER_L1);
385 EXPECT_EQ(1U, testHdr.GetValues("Server").size()) << "Wrong number of values for parameter \"Server\"";
386 EXPECT_STREQ("nginx/1.4.4", testHdr.GetValues("Server")[0].c_str()) << "Wrong parameter value";
387 EXPECT_EQ(2U, testHdr.GetValues("Set-Cookie").size()) << "Wrong number of values for parameter \"Set-Cookie\"";
388 EXPECT_STREQ("PHPSESSID=90857d437518db8f0944ca012761048a; path=/; domain=example.com", testHdr.GetValues("Set-Cookie")[0].c_str()) << "Wrong parameter value";
389 EXPECT_STREQ("user_country=ot; expires=Thu, 09-Jan-2014 18:58:30 GMT; path=/; domain=.example.com", testHdr.GetValues("Set-Cookie")[1].c_str()) << "Wrong parameter value";
390 EXPECT_TRUE(testHdr.GetValues("foo").empty()) << "Some values are returned for non-existed parameter";
391}
392
393TEST(TestHttpHeader, AddParam)
394{
395 CHttpHeader testHdr;
396
397 /* General functionality */
398 testHdr.AddParam("server", "Microsoft-IIS/8.0");
399 EXPECT_STREQ("Microsoft-IIS/8.0", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
400
401 /* Interfere with parsing */
402 EXPECT_FALSE(testHdr.IsHeaderDone()) << "\"AddParam\" set \"parsing finished\" state";
403 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nServer: nginx/1.4.4\r\n\r\n");
404 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Parsed header has \"parsing not finished\" state";
405 EXPECT_STREQ("nginx/1.4.4", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
406 testHdr.AddParam("server", "Apache/2.4.7");
407 EXPECT_STREQ("Apache/2.4.7", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
408 EXPECT_EQ(3U, testHdr.GetValues("Server").size()) << "Wrong number of values for parameter \"Server\"";
409
410 /* Multiple values */
411 testHdr.AddParam("X-foo", "bar1");
412 testHdr.AddParam("x-foo", "bar2");
413 testHdr.AddParam("x-fOO", "bar3");
414 EXPECT_EQ(3U, testHdr.GetValues("X-FOO").size()) << "Wrong number of values for parameter \"X-foo\"";
415 EXPECT_STREQ("bar1", testHdr.GetValues("X-FOo")[0].c_str()) << "Wrong parameter value";
416 EXPECT_STREQ("bar2", testHdr.GetValues("X-fOo")[1].c_str()) << "Wrong parameter value";
417 EXPECT_STREQ("bar3", testHdr.GetValues("x-fOo")[2].c_str()) << "Wrong parameter value";
418 EXPECT_STREQ("bar3", testHdr.GetValue("x-foo").c_str()) << "Wrong parameter value";
419
420 /* Overwrite value */
421 EXPECT_TRUE(testHdr.IsHeaderDone()) << "Parsed header has \"parsing not finished\" state";
422 testHdr.AddParam("x-fOO", "superbar", true);
423 EXPECT_EQ(1U, testHdr.GetValues("X-FoO").size()) << "Wrong number of values for parameter \"X-foo\"";
424 EXPECT_STREQ("superbar", testHdr.GetValue("x-foo").c_str()) << "Wrong parameter value";
425
426 /* Check name trimming */
427 testHdr.AddParam("\tx-fOO\t ", "bar");
428 EXPECT_EQ(2U, testHdr.GetValues("X-FoO").size()) << "Wrong number of values for parameter \"X-foo\"";
429 EXPECT_STREQ("bar", testHdr.GetValue("x-foo").c_str()) << "Wrong parameter value";
430 testHdr.AddParam(" SerVer \t ", "fakeSrv", true);
431 EXPECT_EQ(1U, testHdr.GetValues("serveR").size()) << "Wrong number of values for parameter \"Server\"";
432 EXPECT_STREQ("fakeSrv", testHdr.GetValue("Server").c_str()) << "Wrong parameter value";
433
434 /* Check value trimming */
435 testHdr.AddParam("X-TestParam", " testValue1");
436 EXPECT_STREQ("testValue1", testHdr.GetValue("X-TestParam").c_str()) << "Wrong parameter value";
437 testHdr.AddParam("X-TestParam", "\ttestValue2 and more \t ");
438 EXPECT_STREQ("testValue2 and more", testHdr.GetValue("X-TestParam").c_str()) << "Wrong parameter value";
439
440 /* Empty name or value */
441 testHdr.Clear();
442 testHdr.AddParam("X-TestParam", " ");
443 EXPECT_TRUE(testHdr.GetHeader().empty()) << "Parameter with empty value was added";
444 testHdr.AddParam("\t\t", "value");
445 EXPECT_TRUE(testHdr.GetHeader().empty());
446 testHdr.AddParam(" ", "\t");
447 EXPECT_TRUE(testHdr.GetHeader().empty());
448}
449
450TEST(TestHttpHeader, GetMimeType)
451{
452 CHttpHeader testHdr;
453
454 /* General functionality */
455 EXPECT_TRUE(testHdr.GetMimeType().empty()) << "Newly created object has non-empty MIME-type";
456 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nServer: nginx/1.4.4\r\n\r\n");
457 EXPECT_TRUE(testHdr.GetMimeType().empty()) << "Non-empty MIME-type for header without MIME-type";
458 testHdr.Parse(CHECK_HEADER_SMPL);
459 EXPECT_STREQ("text/html", testHdr.GetMimeType().c_str()) << "Wrong MIME-type";
460 testHdr.Parse(CHECK_HEADER_L1);
461 EXPECT_STREQ("text/html", testHdr.GetMimeType().c_str()) << "Wrong MIME-type";
462 testHdr.Parse(CHECK_HEADER_L2);
463 EXPECT_STREQ("text/xml", testHdr.GetMimeType().c_str()) << "Wrong MIME-type";
464 testHdr.Parse(CHECK_HEADER_R);
465 EXPECT_STREQ("text/html", testHdr.GetMimeType().c_str()) << "Wrong MIME-type";
466
467 /* Overwrite by AddParam */
468 testHdr.AddParam(CHECK_CNT_TYPE_NAME, CHECK_CONTENT_TYPE_TEXT);
469 EXPECT_STREQ(CHECK_CONTENT_TYPE_TEXT, testHdr.GetMimeType().c_str()) << "MIME-type was not overwritten by \"AddParam\"";
470
471 /* Correct trimming */
472 testHdr.AddParam(CHECK_CNT_TYPE_NAME, " " CHECK_CONTENT_TYPE_TEXT " \t ;foo=bar");
473 EXPECT_STREQ(CHECK_CONTENT_TYPE_TEXT, testHdr.GetMimeType().c_str()) << "MIME-type is not trimmed correctly";
474}
475
476
477TEST(TestHttpHeader, GetCharset)
478{
479 CHttpHeader testHdr;
480
481 /* General functionality */
482 EXPECT_TRUE(testHdr.GetCharset().empty()) << "Newly created object has non-empty charset";
483 testHdr.Parse(CHECK_PROT_LINE_200 "\r\nServer: nginx/1.4.4\r\n\r\n");
484 EXPECT_TRUE(testHdr.GetCharset().empty()) << "Non-empty charset for header without charset";
485 testHdr.Parse(CHECK_HEADER_SMPL);
486 EXPECT_TRUE(testHdr.GetCharset().empty()) << "Non-empty charset for header without charset";
487 testHdr.Parse(CHECK_HEADER_L1);
488 EXPECT_STREQ("WINDOWS-1251", testHdr.GetCharset().c_str()) << "Wrong charset value";
489 testHdr.Parse(CHECK_HEADER_L2);
490 EXPECT_STREQ("UTF-8", testHdr.GetCharset().c_str()) << "Wrong charset value";
491
492 /* Overwrite by AddParam */
493 testHdr.AddParam(CHECK_CNT_TYPE_NAME, CHECK_CONTENT_TYPE_TEXT "; charset=WINDOWS-1252");
494 EXPECT_STREQ("WINDOWS-1252", testHdr.GetCharset().c_str()) << "Charset was not overwritten by \"AddParam\"";
495
496 /* Correct trimming */
497 testHdr.AddParam(CHECK_CNT_TYPE_NAME, "text/plain;charset=WINDOWS-1251");
498 EXPECT_STREQ("WINDOWS-1251", testHdr.GetCharset().c_str()) << "Wrong charset value";
499 testHdr.AddParam(CHECK_CNT_TYPE_NAME, "text/plain ;\tcharset=US-AScII\t");
500 EXPECT_STREQ("US-ASCII", testHdr.GetCharset().c_str()) << "Wrong charset value";
501 testHdr.AddParam(CHECK_CNT_TYPE_NAME, "text/html ; \tcharset=\"uTF-8\"\t");
502 EXPECT_STREQ("UTF-8", testHdr.GetCharset().c_str()) << "Wrong charset value";
503 testHdr.AddParam(CHECK_CNT_TYPE_NAME, " \ttext/xml\t;\tcharset=uTF-16 ");
504 EXPECT_STREQ("UTF-16", testHdr.GetCharset().c_str()) << "Wrong charset value";
505}
diff --git a/xbmc/utils/test/TestHttpParser.cpp b/xbmc/utils/test/TestHttpParser.cpp
new file mode 100644
index 0000000..1eb2932
--- /dev/null
+++ b/xbmc/utils/test/TestHttpParser.cpp
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/HttpParser.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestHttpParser, General)
14{
15 HttpParser a;
16 std::string str = "POST /path/script.cgi HTTP/1.0\r\n"
17 "From: amejia@xbmc.org\r\n"
18 "User-Agent: XBMC/snapshot (compatible; MSIE 5.5; Windows NT"
19 " 4.0)\r\n"
20 "Content-Type: application/x-www-form-urlencoded\r\n"
21 "Content-Length: 35\r\n"
22 "\r\n"
23 "home=amejia&favorite+flavor=orange\r\n";
24 std::string refstr, varstr;
25
26 EXPECT_EQ(a.Done, a.addBytes(str.c_str(), str.length()));
27
28 refstr = "POST";
29 varstr = a.getMethod();
30 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
31
32 refstr = "/path/script.cgi";
33 varstr = a.getUri();
34 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
35
36 refstr = "";
37 varstr = a.getQueryString();
38 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
39
40 refstr = "home=amejia&favorite+flavor=orange\r\n";
41 varstr = a.getBody();
42 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
43
44 refstr = "application/x-www-form-urlencoded";
45 varstr = a.getValue("content-type");
46 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
47
48 EXPECT_EQ((unsigned)35, a.getContentLength());
49}
diff --git a/xbmc/utils/test/TestHttpRangeUtils.cpp b/xbmc/utils/test/TestHttpRangeUtils.cpp
new file mode 100644
index 0000000..f988f10
--- /dev/null
+++ b/xbmc/utils/test/TestHttpRangeUtils.cpp
@@ -0,0 +1,887 @@
1/*
2 * Copyright (C) 2015-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/HttpRangeUtils.h"
10
11#include <gtest/gtest.h>
12
13#define RANGES_START "bytes="
14
15static const uint64_t DefaultFirstPosition = 1;
16static const uint64_t DefaultLastPosition = 0;
17static const uint64_t DefaultLength = 0;
18static const void* DefaultData = NULL;
19
20TEST(TestHttpRange, FirstPosition)
21{
22 const uint64_t expectedFirstPosition = 25;
23
24 CHttpRange range;
25 EXPECT_EQ(DefaultFirstPosition, range.GetFirstPosition());
26
27 range.SetFirstPosition(expectedFirstPosition);
28 EXPECT_EQ(expectedFirstPosition, range.GetFirstPosition());
29}
30
31TEST(TestHttpRange, LastPosition)
32{
33 const uint64_t expectedLastPosition = 25;
34
35 CHttpRange range;
36 EXPECT_EQ(DefaultLastPosition, range.GetLastPosition());
37
38 range.SetLastPosition(expectedLastPosition);
39 EXPECT_EQ(expectedLastPosition, range.GetLastPosition());
40}
41
42TEST(TestHttpRange, Length)
43{
44 const uint64_t expectedFirstPosition = 10;
45 const uint64_t expectedLastPosition = 25;
46 const uint64_t expectedLength = expectedLastPosition - expectedFirstPosition + 1;
47
48 CHttpRange range;
49 EXPECT_EQ(DefaultLength, range.GetLength());
50
51 range.SetFirstPosition(expectedFirstPosition);
52 range.SetLastPosition(expectedLastPosition);
53 EXPECT_EQ(expectedLength, range.GetLength());
54
55 CHttpRange range_length;
56 range.SetFirstPosition(expectedFirstPosition);
57 range.SetLength(expectedLength);
58 EXPECT_EQ(expectedLastPosition, range.GetLastPosition());
59 EXPECT_EQ(expectedLength, range.GetLength());
60}
61
62TEST(TestHttpRange, IsValid)
63{
64 const uint64_t validFirstPosition = 10;
65 const uint64_t validLastPosition = 25;
66 const uint64_t invalidLastPosition = 5;
67
68 CHttpRange range;
69 EXPECT_FALSE(range.IsValid());
70
71 range.SetFirstPosition(validFirstPosition);
72 EXPECT_FALSE(range.IsValid());
73
74 range.SetLastPosition(invalidLastPosition);
75 EXPECT_FALSE(range.IsValid());
76
77 range.SetLastPosition(validLastPosition);
78 EXPECT_TRUE(range.IsValid());
79}
80
81TEST(TestHttpRange, Ctor)
82{
83 const uint64_t validFirstPosition = 10;
84 const uint64_t validLastPosition = 25;
85 const uint64_t invalidLastPosition = 5;
86 const uint64_t validLength = validLastPosition - validFirstPosition + 1;
87
88 CHttpRange range_invalid(validFirstPosition, invalidLastPosition);
89 EXPECT_EQ(validFirstPosition, range_invalid.GetFirstPosition());
90 EXPECT_EQ(invalidLastPosition, range_invalid.GetLastPosition());
91 EXPECT_EQ(DefaultLength, range_invalid.GetLength());
92 EXPECT_FALSE(range_invalid.IsValid());
93
94 CHttpRange range_valid(validFirstPosition, validLastPosition);
95 EXPECT_EQ(validFirstPosition, range_valid.GetFirstPosition());
96 EXPECT_EQ(validLastPosition, range_valid.GetLastPosition());
97 EXPECT_EQ(validLength, range_valid.GetLength());
98 EXPECT_TRUE(range_valid.IsValid());
99}
100
101TEST(TestHttpResponseRange, SetData)
102{
103 const uint64_t validFirstPosition = 1;
104 const uint64_t validLastPosition = 2;
105 const uint64_t validLength = validLastPosition - validFirstPosition + 1;
106 const char* validData = "test";
107 const void* invalidData = DefaultData;
108 const size_t validDataLength = strlen(validData);
109 const size_t invalidDataLength = 1;
110
111 CHttpResponseRange range;
112 EXPECT_EQ(DefaultData, range.GetData());
113 EXPECT_FALSE(range.IsValid());
114
115 range.SetData(invalidData);
116 EXPECT_EQ(invalidData, range.GetData());
117 EXPECT_FALSE(range.IsValid());
118
119 range.SetData(validData);
120 EXPECT_EQ(validData, range.GetData());
121 EXPECT_FALSE(range.IsValid());
122
123 range.SetData(invalidData, 0);
124 EXPECT_EQ(validData, range.GetData());
125 EXPECT_FALSE(range.IsValid());
126
127 range.SetData(invalidData, invalidDataLength);
128 EXPECT_EQ(invalidData, range.GetData());
129 EXPECT_FALSE(range.IsValid());
130
131 range.SetData(validData, validDataLength);
132 EXPECT_EQ(validData, range.GetData());
133 EXPECT_EQ(0U, range.GetFirstPosition());
134 EXPECT_EQ(validDataLength - 1, range.GetLastPosition());
135 EXPECT_EQ(validDataLength, range.GetLength());
136 EXPECT_TRUE(range.IsValid());
137
138 range.SetData(invalidData, 0, 0);
139 EXPECT_EQ(invalidData, range.GetData());
140 EXPECT_FALSE(range.IsValid());
141
142 range.SetData(validData, validFirstPosition, validLastPosition);
143 EXPECT_EQ(validData, range.GetData());
144 EXPECT_EQ(validFirstPosition, range.GetFirstPosition());
145 EXPECT_EQ(validLastPosition, range.GetLastPosition());
146 EXPECT_EQ(validLength, range.GetLength());
147 EXPECT_TRUE(range.IsValid());
148}
149
150TEST(TestHttpRanges, Ctor)
151{
152 CHttpRange range;
153 uint64_t position;
154
155 CHttpRanges ranges_empty;
156
157 EXPECT_EQ(0U, ranges_empty.Size());
158 EXPECT_TRUE(ranges_empty.Get().empty());
159
160 EXPECT_FALSE(ranges_empty.Get(0, range));
161 EXPECT_FALSE(ranges_empty.GetFirst(range));
162 EXPECT_FALSE(ranges_empty.GetLast(range));
163
164 EXPECT_FALSE(ranges_empty.GetFirstPosition(position));
165 EXPECT_FALSE(ranges_empty.GetLastPosition(position));
166 EXPECT_EQ(0U, ranges_empty.GetLength());
167 EXPECT_FALSE(ranges_empty.GetTotalRange(range));
168}
169
170TEST(TestHttpRanges, GetAll)
171{
172 CHttpRange range_0(0, 2);
173 CHttpRange range_1(4, 6);
174 CHttpRange range_2(8, 10);
175
176 HttpRanges ranges_raw;
177 ranges_raw.push_back(range_0);
178 ranges_raw.push_back(range_1);
179 ranges_raw.push_back(range_2);
180
181 CHttpRanges ranges(ranges_raw);
182
183 const HttpRanges& ranges_raw_get = ranges.Get();
184 ASSERT_EQ(ranges_raw.size(), ranges_raw_get.size());
185
186 for (size_t i = 0; i < ranges_raw.size(); ++i)
187 EXPECT_EQ(ranges_raw.at(i), ranges_raw_get.at(i));
188}
189
190TEST(TestHttpRanges, GetIndex)
191{
192 CHttpRange range_0(0, 2);
193 CHttpRange range_1(4, 6);
194 CHttpRange range_2(8, 10);
195
196 HttpRanges ranges_raw;
197 ranges_raw.push_back(range_0);
198 ranges_raw.push_back(range_1);
199 ranges_raw.push_back(range_2);
200
201 CHttpRanges ranges(ranges_raw);
202
203 CHttpRange range;
204 EXPECT_TRUE(ranges.Get(0, range));
205 EXPECT_EQ(range_0, range);
206
207 EXPECT_TRUE(ranges.Get(1, range));
208 EXPECT_EQ(range_1, range);
209
210 EXPECT_TRUE(ranges.Get(2, range));
211 EXPECT_EQ(range_2, range);
212
213 EXPECT_FALSE(ranges.Get(3, range));
214}
215
216TEST(TestHttpRanges, GetFirst)
217{
218 CHttpRange range_0(0, 2);
219 CHttpRange range_1(4, 6);
220 CHttpRange range_2(8, 10);
221
222 HttpRanges ranges_raw;
223 ranges_raw.push_back(range_0);
224 ranges_raw.push_back(range_1);
225 ranges_raw.push_back(range_2);
226
227 CHttpRanges ranges(ranges_raw);
228
229 CHttpRange range;
230 EXPECT_TRUE(ranges.GetFirst(range));
231 EXPECT_EQ(range_0, range);
232}
233
234TEST(TestHttpRanges, GetLast)
235{
236 CHttpRange range_0(0, 2);
237 CHttpRange range_1(4, 6);
238 CHttpRange range_2(8, 10);
239
240 HttpRanges ranges_raw;
241 ranges_raw.push_back(range_0);
242 ranges_raw.push_back(range_1);
243 ranges_raw.push_back(range_2);
244
245 CHttpRanges ranges(ranges_raw);
246
247 CHttpRange range;
248 EXPECT_TRUE(ranges.GetLast(range));
249 EXPECT_EQ(range_2, range);
250}
251
252TEST(TestHttpRanges, Size)
253{
254 CHttpRange range_0(0, 2);
255 CHttpRange range_1(4, 6);
256 CHttpRange range_2(8, 10);
257
258 HttpRanges ranges_raw;
259 ranges_raw.push_back(range_0);
260 ranges_raw.push_back(range_1);
261 ranges_raw.push_back(range_2);
262
263 CHttpRanges ranges_empty;
264 EXPECT_EQ(0U, ranges_empty.Size());
265
266 CHttpRanges ranges(ranges_raw);
267 EXPECT_EQ(ranges_raw.size(), ranges.Size());
268}
269
270TEST(TestHttpRanges, GetFirstPosition)
271{
272 CHttpRange range_0(0, 2);
273 CHttpRange range_1(4, 6);
274 CHttpRange range_2(8, 10);
275
276 HttpRanges ranges_raw;
277 ranges_raw.push_back(range_0);
278 ranges_raw.push_back(range_1);
279 ranges_raw.push_back(range_2);
280
281 CHttpRanges ranges(ranges_raw);
282
283 uint64_t position;
284 EXPECT_TRUE(ranges.GetFirstPosition(position));
285 EXPECT_EQ(range_0.GetFirstPosition(), position);
286}
287
288TEST(TestHttpRanges, GetLastPosition)
289{
290 CHttpRange range_0(0, 2);
291 CHttpRange range_1(4, 6);
292 CHttpRange range_2(8, 10);
293
294 HttpRanges ranges_raw;
295 ranges_raw.push_back(range_0);
296 ranges_raw.push_back(range_1);
297 ranges_raw.push_back(range_2);
298
299 CHttpRanges ranges(ranges_raw);
300
301 uint64_t position;
302 EXPECT_TRUE(ranges.GetLastPosition(position));
303 EXPECT_EQ(range_2.GetLastPosition(), position);
304}
305
306TEST(TestHttpRanges, GetLength)
307{
308 CHttpRange range_0(0, 2);
309 CHttpRange range_1(4, 6);
310 CHttpRange range_2(8, 10);
311 const uint64_t expectedLength = range_0.GetLength() + range_1.GetLength() + range_2.GetLength();
312
313 HttpRanges ranges_raw;
314 ranges_raw.push_back(range_0);
315 ranges_raw.push_back(range_1);
316 ranges_raw.push_back(range_2);
317
318 CHttpRanges ranges(ranges_raw);
319
320 EXPECT_EQ(expectedLength, ranges.GetLength());
321}
322
323TEST(TestHttpRanges, GetTotalRange)
324{
325 CHttpRange range_0(0, 2);
326 CHttpRange range_1(4, 6);
327 CHttpRange range_2(8, 10);
328 CHttpRange range_total_expected(range_0.GetFirstPosition(), range_2.GetLastPosition());
329
330 HttpRanges ranges_raw;
331 ranges_raw.push_back(range_0);
332 ranges_raw.push_back(range_1);
333 ranges_raw.push_back(range_2);
334
335 CHttpRanges ranges(ranges_raw);
336
337 CHttpRange range_total;
338 EXPECT_TRUE(ranges.GetTotalRange(range_total));
339 EXPECT_EQ(range_total_expected, range_total);
340}
341
342TEST(TestHttpRanges, Add)
343{
344 CHttpRange range_0(0, 2);
345 CHttpRange range_1(4, 6);
346 CHttpRange range_2(8, 10);
347
348 CHttpRanges ranges;
349 CHttpRange range;
350
351 ranges.Add(range_0);
352 EXPECT_EQ(1U, ranges.Size());
353 EXPECT_TRUE(ranges.GetFirst(range));
354 EXPECT_EQ(range_0, range);
355 EXPECT_TRUE(ranges.GetLast(range));
356 EXPECT_EQ(range_0, range);
357
358 ranges.Add(range_1);
359 EXPECT_EQ(2U, ranges.Size());
360 EXPECT_TRUE(ranges.GetFirst(range));
361 EXPECT_EQ(range_0, range);
362 EXPECT_TRUE(ranges.GetLast(range));
363 EXPECT_EQ(range_1, range);
364
365 ranges.Add(range_2);
366 EXPECT_EQ(3U, ranges.Size());
367 EXPECT_TRUE(ranges.GetFirst(range));
368 EXPECT_EQ(range_0, range);
369 EXPECT_TRUE(ranges.GetLast(range));
370 EXPECT_EQ(range_2, range);
371}
372
373TEST(TestHttpRanges, Remove)
374{
375 CHttpRange range_0(0, 2);
376 CHttpRange range_1(4, 6);
377 CHttpRange range_2(8, 10);
378
379 HttpRanges ranges_raw;
380 ranges_raw.push_back(range_0);
381 ranges_raw.push_back(range_1);
382 ranges_raw.push_back(range_2);
383
384 CHttpRanges ranges(ranges_raw);
385
386 CHttpRange range;
387 EXPECT_EQ(3U, ranges.Size());
388 EXPECT_TRUE(ranges.Get(0, range));
389 EXPECT_EQ(range_0, range);
390 EXPECT_TRUE(ranges.Get(1, range));
391 EXPECT_EQ(range_1, range);
392 EXPECT_TRUE(ranges.Get(2, range));
393 EXPECT_EQ(range_2, range);
394
395 // remove non-existing range
396 ranges.Remove(ranges.Size());
397 EXPECT_EQ(3U, ranges.Size());
398 EXPECT_TRUE(ranges.Get(0, range));
399 EXPECT_EQ(range_0, range);
400 EXPECT_TRUE(ranges.Get(1, range));
401 EXPECT_EQ(range_1, range);
402 EXPECT_TRUE(ranges.Get(2, range));
403 EXPECT_EQ(range_2, range);
404
405 // remove first range
406 ranges.Remove(0);
407 EXPECT_EQ(2U, ranges.Size());
408 EXPECT_TRUE(ranges.Get(0, range));
409 EXPECT_EQ(range_1, range);
410 EXPECT_TRUE(ranges.Get(1, range));
411 EXPECT_EQ(range_2, range);
412
413 // remove last range
414 ranges.Remove(1);
415 EXPECT_EQ(1U, ranges.Size());
416 EXPECT_TRUE(ranges.Get(0, range));
417 EXPECT_EQ(range_1, range);
418
419 // remove remaining range
420 ranges.Remove(0);
421 EXPECT_EQ(0U, ranges.Size());
422}
423
424TEST(TestHttpRanges, Clear)
425{
426 CHttpRange range_0(0, 2);
427 CHttpRange range_1(4, 6);
428 CHttpRange range_2(8, 10);
429
430 HttpRanges ranges_raw;
431 ranges_raw.push_back(range_0);
432 ranges_raw.push_back(range_1);
433 ranges_raw.push_back(range_2);
434
435 CHttpRanges ranges(ranges_raw);
436
437 CHttpRange range;
438 EXPECT_EQ(3U, ranges.Size());
439 EXPECT_TRUE(ranges.Get(0, range));
440 EXPECT_EQ(range_0, range);
441 EXPECT_TRUE(ranges.Get(1, range));
442 EXPECT_EQ(range_1, range);
443 EXPECT_TRUE(ranges.Get(2, range));
444 EXPECT_EQ(range_2, range);
445
446 ranges.Clear();
447 EXPECT_EQ(0U, ranges.Size());
448}
449
450TEST(TestHttpRanges, ParseInvalid)
451{
452 CHttpRanges ranges;
453
454 // combinations of invalid string and invalid total length
455 EXPECT_FALSE(ranges.Parse(""));
456 EXPECT_FALSE(ranges.Parse("", 0));
457 EXPECT_FALSE(ranges.Parse("", 1));
458 EXPECT_FALSE(ranges.Parse("test", 0));
459 EXPECT_FALSE(ranges.Parse(RANGES_START, 0));
460
461 // empty range definition
462 EXPECT_FALSE(ranges.Parse(RANGES_START));
463 EXPECT_FALSE(ranges.Parse(RANGES_START "-"));
464
465 // bad characters in range definition
466 EXPECT_FALSE(ranges.Parse(RANGES_START "a"));
467 EXPECT_FALSE(ranges.Parse(RANGES_START "1a"));
468 EXPECT_FALSE(ranges.Parse(RANGES_START "1-a"));
469 EXPECT_FALSE(ranges.Parse(RANGES_START "a-a"));
470 EXPECT_FALSE(ranges.Parse(RANGES_START "a-1"));
471 EXPECT_FALSE(ranges.Parse(RANGES_START "--"));
472 EXPECT_FALSE(ranges.Parse(RANGES_START "1--"));
473 EXPECT_FALSE(ranges.Parse(RANGES_START "1--2"));
474 EXPECT_FALSE(ranges.Parse(RANGES_START "--2"));
475
476 // combination of valid and empty range definitions
477 EXPECT_FALSE(ranges.Parse(RANGES_START "0-1,"));
478 EXPECT_FALSE(ranges.Parse(RANGES_START ",0-1"));
479
480 // too big start position
481 EXPECT_FALSE(ranges.Parse(RANGES_START "10-11", 5));
482
483 // end position smaller than start position
484 EXPECT_FALSE(ranges.Parse(RANGES_START "1-0"));
485}
486
487TEST(TestHttpRanges, ParseStartOnly)
488{
489 const uint64_t totalLength = 5;
490 const CHttpRange range0_(0, totalLength - 1);
491 const CHttpRange range2_(2, totalLength - 1);
492
493 CHttpRange range;
494
495 CHttpRanges ranges_all;
496 EXPECT_TRUE(ranges_all.Parse(RANGES_START "0-", totalLength));
497 EXPECT_EQ(1U, ranges_all.Size());
498 EXPECT_TRUE(ranges_all.Get(0, range));
499 EXPECT_EQ(range0_, range);
500
501 CHttpRanges ranges_some;
502 EXPECT_TRUE(ranges_some.Parse(RANGES_START "2-", totalLength));
503 EXPECT_EQ(1U, ranges_some.Size());
504 EXPECT_TRUE(ranges_some.Get(0, range));
505 EXPECT_EQ(range2_, range);
506}
507
508TEST(TestHttpRanges, ParseFromEnd)
509{
510 const uint64_t totalLength = 5;
511 const CHttpRange range_1(totalLength - 1, totalLength - 1);
512 const CHttpRange range_3(totalLength - 3, totalLength - 1);
513
514 CHttpRange range;
515
516 CHttpRanges ranges_1;
517 EXPECT_TRUE(ranges_1.Parse(RANGES_START "-1", totalLength));
518 EXPECT_EQ(1U, ranges_1.Size());
519 EXPECT_TRUE(ranges_1.Get(0, range));
520 EXPECT_EQ(range_1, range);
521
522 CHttpRanges ranges_3;
523 EXPECT_TRUE(ranges_3.Parse(RANGES_START "-3", totalLength));
524 EXPECT_EQ(1U, ranges_3.Size());
525 EXPECT_TRUE(ranges_3.Get(0, range));
526 EXPECT_EQ(range_3, range);
527}
528
529TEST(TestHttpRanges, ParseSingle)
530{
531 const uint64_t totalLength = 5;
532 const CHttpRange range0_0(0, 0);
533 const CHttpRange range0_1(0, 1);
534 const CHttpRange range0_5(0, totalLength - 1);
535 const CHttpRange range1_1(1, 1);
536 const CHttpRange range1_3(1, 3);
537 const CHttpRange range3_4(3, 4);
538 const CHttpRange range4_4(4, 4);
539
540 CHttpRange range;
541
542 CHttpRanges ranges;
543 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0", totalLength));
544 EXPECT_EQ(1U, ranges.Size());
545 EXPECT_TRUE(ranges.Get(0, range));
546 EXPECT_EQ(range0_0, range);
547
548 EXPECT_TRUE(ranges.Parse(RANGES_START "0-1", totalLength));
549 EXPECT_EQ(1U, ranges.Size());
550 EXPECT_TRUE(ranges.Get(0, range));
551 EXPECT_EQ(range0_1, range);
552
553 EXPECT_TRUE(ranges.Parse(RANGES_START "0-5", totalLength));
554 EXPECT_EQ(1U, ranges.Size());
555 EXPECT_TRUE(ranges.Get(0, range));
556 EXPECT_EQ(range0_5, range);
557
558 EXPECT_TRUE(ranges.Parse(RANGES_START "1-1", totalLength));
559 EXPECT_EQ(1U, ranges.Size());
560 EXPECT_TRUE(ranges.Get(0, range));
561 EXPECT_EQ(range1_1, range);
562
563 EXPECT_TRUE(ranges.Parse(RANGES_START "1-3", totalLength));
564 EXPECT_EQ(1U, ranges.Size());
565 EXPECT_TRUE(ranges.Get(0, range));
566 EXPECT_EQ(range1_3, range);
567
568 EXPECT_TRUE(ranges.Parse(RANGES_START "3-4", totalLength));
569 EXPECT_EQ(1U, ranges.Size());
570 EXPECT_TRUE(ranges.Get(0, range));
571 EXPECT_EQ(range3_4, range);
572
573 EXPECT_TRUE(ranges.Parse(RANGES_START "4-4", totalLength));
574 EXPECT_EQ(1U, ranges.Size());
575 EXPECT_TRUE(ranges.Get(0, range));
576 EXPECT_EQ(range4_4, range);
577}
578
579TEST(TestHttpRanges, ParseMulti)
580{
581 const uint64_t totalLength = 6;
582 const CHttpRange range0_0(0, 0);
583 const CHttpRange range0_1(0, 1);
584 const CHttpRange range1_3(1, 3);
585 const CHttpRange range2_2(2, 2);
586 const CHttpRange range4_5(4, 5);
587 const CHttpRange range5_5(5, 5);
588
589 CHttpRange range;
590
591 CHttpRanges ranges;
592 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,2-2", totalLength));
593 EXPECT_EQ(2U, ranges.Size());
594 EXPECT_TRUE(ranges.Get(0, range));
595 EXPECT_EQ(range0_0, range);
596 EXPECT_TRUE(ranges.Get(1, range));
597 EXPECT_EQ(range2_2, range);
598
599 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,2-2,4-5", totalLength));
600 EXPECT_EQ(3U, ranges.Size());
601 EXPECT_TRUE(ranges.Get(0, range));
602 EXPECT_EQ(range0_0, range);
603 EXPECT_TRUE(ranges.Get(1, range));
604 EXPECT_EQ(range2_2, range);
605 EXPECT_TRUE(ranges.Get(2, range));
606 EXPECT_EQ(range4_5, range);
607
608 EXPECT_TRUE(ranges.Parse(RANGES_START "0-1,5-5", totalLength));
609 EXPECT_EQ(2U, ranges.Size());
610 EXPECT_TRUE(ranges.Get(0, range));
611 EXPECT_EQ(range0_1, range);
612 EXPECT_TRUE(ranges.Get(1, range));
613 EXPECT_EQ(range5_5, range);
614
615 EXPECT_TRUE(ranges.Parse(RANGES_START "1-3,5-5", totalLength));
616 EXPECT_EQ(2U, ranges.Size());
617 EXPECT_TRUE(ranges.Get(0, range));
618 EXPECT_EQ(range1_3, range);
619 EXPECT_TRUE(ranges.Get(1, range));
620 EXPECT_EQ(range5_5, range);
621}
622
623TEST(TestHttpRanges, ParseOrderedNotOverlapping)
624{
625 const uint64_t totalLength = 5;
626 const CHttpRange range0_0(0, 0);
627 const CHttpRange range0_1(0, 1);
628 const CHttpRange range2_2(2, 2);
629 const CHttpRange range2_(2, totalLength - 1);
630 const CHttpRange range_1(totalLength - 1, totalLength - 1);
631
632 CHttpRange range;
633
634 CHttpRanges ranges;
635 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,-1", totalLength));
636 EXPECT_EQ(2U, ranges.Size());
637 EXPECT_TRUE(ranges.Get(0, range));
638 EXPECT_EQ(range0_0, range);
639 EXPECT_TRUE(ranges.Get(1, range));
640 EXPECT_EQ(range_1, range);
641
642 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,2-2,-1", totalLength));
643 EXPECT_EQ(3U, ranges.Size());
644 EXPECT_TRUE(ranges.Get(0, range));
645 EXPECT_EQ(range0_0, range);
646 EXPECT_TRUE(ranges.Get(1, range));
647 EXPECT_EQ(range2_2, range);
648 EXPECT_TRUE(ranges.Get(2, range));
649 EXPECT_EQ(range_1, range);
650
651 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,2-", totalLength));
652 EXPECT_EQ(2U, ranges.Size());
653 EXPECT_TRUE(ranges.Get(0, range));
654 EXPECT_EQ(range0_0, range);
655 EXPECT_TRUE(ranges.Get(1, range));
656 EXPECT_EQ(range2_, range);
657}
658
659TEST(TestHttpRanges, ParseOrderedBackToBack)
660{
661 const uint64_t totalLength = 5;
662 const CHttpRange range0_1(0, 1);
663 const CHttpRange range0_2(0, 2);
664 const CHttpRange range1_2(1, 2);
665 const CHttpRange range0_3(0, 3);
666 const CHttpRange range4_4(4, 4);
667 const CHttpRange range0_4(0, 4);
668 const CHttpRange range3_4(3, 4);
669
670 CHttpRange range;
671
672 CHttpRanges ranges;
673 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,1-1", totalLength));
674 EXPECT_EQ(1U, ranges.Size());
675 EXPECT_TRUE(ranges.Get(0, range));
676 EXPECT_EQ(range0_1, range);
677
678 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,1-1,2-2", totalLength));
679 EXPECT_EQ(1U, ranges.Size());
680 EXPECT_TRUE(ranges.Get(0, range));
681 EXPECT_EQ(range0_2, range);
682
683 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,1-1,2-2,3-3", totalLength));
684 EXPECT_EQ(1U, ranges.Size());
685 EXPECT_TRUE(ranges.Get(0, range));
686 EXPECT_EQ(range0_3, range);
687
688 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,1-1,2-2,3-3,4-4", totalLength));
689 EXPECT_EQ(1U, ranges.Size());
690 EXPECT_TRUE(ranges.Get(0, range));
691 EXPECT_EQ(range0_4, range);
692
693 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,1-1,3-3,4-4", totalLength));
694 EXPECT_EQ(2U, ranges.Size());
695 EXPECT_TRUE(ranges.Get(0, range));
696 EXPECT_EQ(range0_1, range);
697 EXPECT_TRUE(ranges.Get(1, range));
698 EXPECT_EQ(range3_4, range);
699
700 EXPECT_TRUE(ranges.Parse(RANGES_START "1-1,2-2,4-4", totalLength));
701 EXPECT_EQ(2U, ranges.Size());
702 EXPECT_TRUE(ranges.Get(0, range));
703 EXPECT_EQ(range1_2, range);
704 EXPECT_TRUE(ranges.Get(1, range));
705 EXPECT_EQ(range4_4, range);
706}
707
708TEST(TestHttpRanges, ParseOrderedOverlapping)
709{
710 const uint64_t totalLength = 5;
711 const CHttpRange range0_0(0, 0);
712 const CHttpRange range0_1(0, 1);
713 const CHttpRange range0_2(0, 2);
714 const CHttpRange range0_3(0, 3);
715 const CHttpRange range0_4(0, 4);
716 const CHttpRange range2_4(2, 4);
717
718 CHttpRange range;
719
720 CHttpRanges ranges;
721 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,0-1", totalLength));
722 EXPECT_EQ(1U, ranges.Size());
723 EXPECT_TRUE(ranges.Get(0, range));
724 EXPECT_EQ(range0_1, range);
725
726 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,0-1,0-2", totalLength));
727 EXPECT_EQ(1U, ranges.Size());
728 EXPECT_TRUE(ranges.Get(0, range));
729 EXPECT_EQ(range0_2, range);
730
731 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,0-1,1-2", totalLength));
732 EXPECT_EQ(1U, ranges.Size());
733 EXPECT_TRUE(ranges.Get(0, range));
734 EXPECT_EQ(range0_2, range);
735
736 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,0-2,1-3", totalLength));
737 EXPECT_EQ(1U, ranges.Size());
738 EXPECT_TRUE(ranges.Get(0, range));
739 EXPECT_EQ(range0_3, range);
740
741 EXPECT_TRUE(ranges.Parse(RANGES_START "0-1,1-2,2-3,3-4", totalLength));
742 EXPECT_EQ(1U, ranges.Size());
743 EXPECT_TRUE(ranges.Get(0, range));
744 EXPECT_EQ(range0_4, range);
745
746 EXPECT_TRUE(ranges.Parse(RANGES_START "0-0,2-3,2-4,4-4", totalLength));
747 EXPECT_EQ(2U, ranges.Size());
748 EXPECT_TRUE(ranges.Get(0, range));
749 EXPECT_EQ(range0_0, range);
750 EXPECT_TRUE(ranges.Get(1, range));
751 EXPECT_EQ(range2_4, range);
752}
753
754TEST(TestHttpRanges, ParseUnorderedNotOverlapping)
755{
756 const uint64_t totalLength = 5;
757 const CHttpRange range0_0(0, 0);
758 const CHttpRange range0_1(0, 1);
759 const CHttpRange range2_2(2, 2);
760 const CHttpRange range2_(2, totalLength - 1);
761 const CHttpRange range_1(totalLength - 1, totalLength - 1);
762
763 CHttpRange range;
764
765 CHttpRanges ranges;
766 EXPECT_TRUE(ranges.Parse(RANGES_START "-1,0-0", totalLength));
767 EXPECT_EQ(2U, ranges.Size());
768 EXPECT_TRUE(ranges.Get(0, range));
769 EXPECT_EQ(range0_0, range);
770 EXPECT_TRUE(ranges.Get(1, range));
771 EXPECT_EQ(range_1, range);
772
773 EXPECT_TRUE(ranges.Parse(RANGES_START "2-2,-1,0-0", totalLength));
774 EXPECT_EQ(3U, ranges.Size());
775 EXPECT_TRUE(ranges.Get(0, range));
776 EXPECT_EQ(range0_0, range);
777 EXPECT_TRUE(ranges.Get(1, range));
778 EXPECT_EQ(range2_2, range);
779 EXPECT_TRUE(ranges.Get(2, range));
780 EXPECT_EQ(range_1, range);
781
782 EXPECT_TRUE(ranges.Parse(RANGES_START "2-,0-0", totalLength));
783 EXPECT_EQ(2U, ranges.Size());
784 EXPECT_TRUE(ranges.Get(0, range));
785 EXPECT_EQ(range0_0, range);
786 EXPECT_TRUE(ranges.Get(1, range));
787 EXPECT_EQ(range2_, range);
788}
789
790TEST(TestHttpRanges, ParseUnorderedBackToBack)
791{
792 const uint64_t totalLength = 5;
793 const CHttpRange range0_0(0, 0);
794 const CHttpRange range1_1(1, 1);
795 const CHttpRange range0_1(0, 1);
796 const CHttpRange range2_2(2, 2);
797 const CHttpRange range0_2(0, 2);
798 const CHttpRange range1_2(1, 2);
799 const CHttpRange range3_3(3, 3);
800 const CHttpRange range0_3(0, 3);
801 const CHttpRange range4_4(4, 4);
802 const CHttpRange range0_4(0, 4);
803 const CHttpRange range3_4(3, 4);
804
805 CHttpRange range;
806
807 CHttpRanges ranges;
808 EXPECT_TRUE(ranges.Parse(RANGES_START "1-1,0-0", totalLength));
809 EXPECT_EQ(1U, ranges.Size());
810 EXPECT_TRUE(ranges.Get(0, range));
811 EXPECT_EQ(range0_1, range);
812
813 EXPECT_TRUE(ranges.Parse(RANGES_START "1-1,0-0,2-2", totalLength));
814 EXPECT_EQ(1U, ranges.Size());
815 EXPECT_TRUE(ranges.Get(0, range));
816 EXPECT_EQ(range0_2, range);
817
818 EXPECT_TRUE(ranges.Parse(RANGES_START "2-2,1-1,3-3,0-0", totalLength));
819 EXPECT_EQ(1U, ranges.Size());
820 EXPECT_TRUE(ranges.Get(0, range));
821 EXPECT_EQ(range0_3, range);
822
823 EXPECT_TRUE(ranges.Parse(RANGES_START "4-4,1-1,0-0,2-2,3-3", totalLength));
824 EXPECT_EQ(1U, ranges.Size());
825 EXPECT_TRUE(ranges.Get(0, range));
826 EXPECT_EQ(range0_4, range);
827
828 EXPECT_TRUE(ranges.Parse(RANGES_START "3-3,0-0,4-4,1-1", totalLength));
829 EXPECT_EQ(2U, ranges.Size());
830 EXPECT_TRUE(ranges.Get(0, range));
831 EXPECT_EQ(range0_1, range);
832 EXPECT_TRUE(ranges.Get(1, range));
833 EXPECT_EQ(range3_4, range);
834
835 EXPECT_TRUE(ranges.Parse(RANGES_START "4-4,1-1,2-2", totalLength));
836 EXPECT_EQ(2U, ranges.Size());
837 EXPECT_TRUE(ranges.Get(0, range));
838 EXPECT_EQ(range1_2, range);
839 EXPECT_TRUE(ranges.Get(1, range));
840 EXPECT_EQ(range4_4, range);
841}
842
843TEST(TestHttpRanges, ParseUnorderedOverlapping)
844{
845 const uint64_t totalLength = 5;
846 const CHttpRange range0_0(0, 0);
847 const CHttpRange range0_1(0, 1);
848 const CHttpRange range0_2(0, 2);
849 const CHttpRange range0_3(0, 3);
850 const CHttpRange range0_4(0, 4);
851 const CHttpRange range2_4(2, 4);
852
853 CHttpRange range;
854
855 CHttpRanges ranges;
856 EXPECT_TRUE(ranges.Parse(RANGES_START "0-1,0-0", totalLength));
857 EXPECT_EQ(1U, ranges.Size());
858 EXPECT_TRUE(ranges.Get(0, range));
859 EXPECT_EQ(range0_1, range);
860
861 EXPECT_TRUE(ranges.Parse(RANGES_START "0-2,0-0,0-1", totalLength));
862 EXPECT_EQ(1U, ranges.Size());
863 EXPECT_TRUE(ranges.Get(0, range));
864 EXPECT_EQ(range0_2, range);
865
866 EXPECT_TRUE(ranges.Parse(RANGES_START "0-1,1-2,0-0", totalLength));
867 EXPECT_EQ(1U, ranges.Size());
868 EXPECT_TRUE(ranges.Get(0, range));
869 EXPECT_EQ(range0_2, range);
870
871 EXPECT_TRUE(ranges.Parse(RANGES_START "0-2,0-0,1-3", totalLength));
872 EXPECT_EQ(1U, ranges.Size());
873 EXPECT_TRUE(ranges.Get(0, range));
874 EXPECT_EQ(range0_3, range);
875
876 EXPECT_TRUE(ranges.Parse(RANGES_START "2-3,1-2,0-1,3-4", totalLength));
877 EXPECT_EQ(1U, ranges.Size());
878 EXPECT_TRUE(ranges.Get(0, range));
879 EXPECT_EQ(range0_4, range);
880
881 EXPECT_TRUE(ranges.Parse(RANGES_START "4-4,0-0,2-4,2-3", totalLength));
882 EXPECT_EQ(2U, ranges.Size());
883 EXPECT_TRUE(ranges.Get(0, range));
884 EXPECT_EQ(range0_0, range);
885 EXPECT_TRUE(ranges.Get(1, range));
886 EXPECT_EQ(range2_4, range);
887}
diff --git a/xbmc/utils/test/TestHttpResponse.cpp b/xbmc/utils/test/TestHttpResponse.cpp
new file mode 100644
index 0000000..1f66285
--- /dev/null
+++ b/xbmc/utils/test/TestHttpResponse.cpp
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/HttpResponse.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestHttpResponse, General)
14{
15 CHttpResponse a(HTTP::POST, HTTP::OK);
16 std::string response, content, refstr;
17
18 a.AddHeader("date", "Sun, 01 Jul 2012 00:00:00 -0400");
19 a.AddHeader("content-type", "text/html");
20 content = "<html>\r\n"
21 " <body>\r\n"
22 " <h1>XBMC TestHttpResponse Page</h1>\r\n"
23 " <p>blah blah blah</p>\r\n"
24 " </body>\r\n"
25 "</html>\r\n";
26 a.SetContent(content.c_str(), content.length());
27
28 response = a.Create();;
29 EXPECT_EQ((unsigned int)210, response.size());
30
31 refstr = "HTTP/1.1 200 OK\r\n"
32 "date: Sun, 01 Jul 2012 00:00:00 -0400\r\n"
33 "content-type: text/html\r\n"
34 "Content-Length: 106\r\n"
35 "\r\n"
36 "<html>\r\n"
37 " <body>\r\n"
38 " <h1>XBMC TestHttpResponse Page</h1>\r\n"
39 " <p>blah blah blah</p>\r\n"
40 " </body>\r\n"
41 "</html>\r\n";
42 EXPECT_STREQ(refstr.c_str(), response.c_str());
43}
diff --git a/xbmc/utils/test/TestJSONVariantParser.cpp b/xbmc/utils/test/TestJSONVariantParser.cpp
new file mode 100644
index 0000000..b8556b0
--- /dev/null
+++ b/xbmc/utils/test/TestJSONVariantParser.cpp
@@ -0,0 +1,189 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/JSONVariantParser.h"
10#include "utils/Variant.h"
11
12#include <gtest/gtest.h>
13
14TEST(TestJSONVariantParser, CannotParseNullptr)
15{
16 CVariant variant;
17 ASSERT_FALSE(CJSONVariantParser::Parse(nullptr, variant));
18}
19
20TEST(TestJSONVariantParser, CannotParseEmptyString)
21{
22 CVariant variant;
23 ASSERT_FALSE(CJSONVariantParser::Parse("", variant));
24 ASSERT_FALSE(CJSONVariantParser::Parse(std::string(), variant));
25}
26
27TEST(TestJSONVariantParser, CannotParseInvalidJson)
28{
29 CVariant variant;
30 ASSERT_FALSE(CJSONVariantParser::Parse("{", variant));
31 ASSERT_FALSE(CJSONVariantParser::Parse("}", variant));
32 ASSERT_FALSE(CJSONVariantParser::Parse("[", variant));
33 ASSERT_FALSE(CJSONVariantParser::Parse("]", variant));
34 ASSERT_FALSE(CJSONVariantParser::Parse("foo", variant));
35}
36
37TEST(TestJSONVariantParser, CanParseNull)
38{
39 CVariant variant;
40 ASSERT_TRUE(CJSONVariantParser::Parse("null", variant));
41 ASSERT_TRUE(variant.isNull());
42}
43
44TEST(TestJSONVariantParser, CanParseBoolean)
45{
46 CVariant variant;
47 ASSERT_TRUE(CJSONVariantParser::Parse("true", variant));
48 ASSERT_TRUE(variant.isBoolean());
49 ASSERT_TRUE(variant.asBoolean());
50
51 ASSERT_TRUE(CJSONVariantParser::Parse("false", variant));
52 ASSERT_TRUE(variant.isBoolean());
53 ASSERT_FALSE(variant.asBoolean());
54}
55
56TEST(TestJSONVariantParser, CanParseSignedInteger)
57{
58 CVariant variant;
59 ASSERT_TRUE(CJSONVariantParser::Parse("-1", variant));
60 ASSERT_TRUE(variant.isInteger());
61 ASSERT_EQ(-1, variant.asInteger());
62}
63
64TEST(TestJSONVariantParser, CanParseUnsignedInteger)
65{
66 CVariant variant;
67 ASSERT_TRUE(CJSONVariantParser::Parse("0", variant));
68 ASSERT_TRUE(variant.isUnsignedInteger());
69 ASSERT_EQ(0U, variant.asUnsignedInteger());
70
71 ASSERT_TRUE(CJSONVariantParser::Parse("1", variant));
72 ASSERT_TRUE(variant.isUnsignedInteger());
73 ASSERT_EQ(1U, variant.asUnsignedInteger());
74}
75
76TEST(TestJSONVariantParser, CanParseSignedInteger64)
77{
78 CVariant variant;
79 ASSERT_TRUE(CJSONVariantParser::Parse("-4294967296", variant));
80 ASSERT_TRUE(variant.isInteger());
81 ASSERT_EQ(-4294967296, variant.asInteger());
82}
83
84TEST(TestJSONVariantParser, CanParseUnsignedInteger64)
85{
86 CVariant variant;
87 ASSERT_TRUE(CJSONVariantParser::Parse("4294967296", variant));
88 ASSERT_TRUE(variant.isUnsignedInteger());
89 ASSERT_EQ(4294967296U, variant.asUnsignedInteger());
90}
91
92TEST(TestJSONVariantParser, CanParseDouble)
93{
94 CVariant variant;
95 ASSERT_TRUE(CJSONVariantParser::Parse("0.0", variant));
96 ASSERT_TRUE(variant.isDouble());
97 ASSERT_EQ(0.0, variant.asDouble());
98
99 ASSERT_TRUE(CJSONVariantParser::Parse("1.0", variant));
100 ASSERT_TRUE(variant.isDouble());
101 ASSERT_EQ(1.0, variant.asDouble());
102
103 ASSERT_TRUE(CJSONVariantParser::Parse("-1.0", variant));
104 ASSERT_TRUE(variant.isDouble());
105 ASSERT_EQ(-1.0, variant.asDouble());
106}
107
108TEST(TestJSONVariantParser, CanParseString)
109{
110 CVariant variant;
111 ASSERT_TRUE(CJSONVariantParser::Parse("\"\"", variant));
112 ASSERT_TRUE(variant.isString());
113 ASSERT_TRUE(variant.empty());
114
115 ASSERT_TRUE(CJSONVariantParser::Parse("\"foo\"", variant));
116 ASSERT_TRUE(variant.isString());
117 ASSERT_STREQ("foo", variant.asString().c_str());
118
119 ASSERT_TRUE(CJSONVariantParser::Parse("\"foo bar\"", variant));
120 ASSERT_TRUE(variant.isString());
121 ASSERT_STREQ("foo bar", variant.asString().c_str());
122}
123
124TEST(TestJSONVariantParser, CanParseObject)
125{
126 CVariant variant;
127 ASSERT_TRUE(CJSONVariantParser::Parse("{}", variant));
128 ASSERT_TRUE(variant.isObject());
129 ASSERT_TRUE(variant.empty());
130
131 variant.clear();
132 ASSERT_TRUE(CJSONVariantParser::Parse("{ \"foo\": \"bar\" }", variant));
133 ASSERT_TRUE(variant.isObject());
134 ASSERT_TRUE(variant.isMember("foo"));
135 ASSERT_TRUE(variant["foo"].isString());
136 ASSERT_STREQ("bar", variant["foo"].asString().c_str());
137
138 variant.clear();
139 ASSERT_TRUE(CJSONVariantParser::Parse("{ \"foo\": \"bar\", \"bar\": true }", variant));
140 ASSERT_TRUE(variant.isObject());
141 ASSERT_TRUE(variant.isMember("foo"));
142 ASSERT_TRUE(variant["foo"].isString());
143 ASSERT_STREQ("bar", variant["foo"].asString().c_str());
144 ASSERT_TRUE(variant.isMember("bar"));
145 ASSERT_TRUE(variant["bar"].isBoolean());
146 ASSERT_TRUE(variant["bar"].asBoolean());
147
148 variant.clear();
149 ASSERT_TRUE(CJSONVariantParser::Parse("{ \"foo\": { \"sub-foo\": \"bar\" } }", variant));
150 ASSERT_TRUE(variant.isObject());
151 ASSERT_TRUE(variant.isMember("foo"));
152 ASSERT_TRUE(variant["foo"].isObject());
153 ASSERT_TRUE(variant["foo"].isMember("sub-foo"));
154 ASSERT_TRUE(variant["foo"]["sub-foo"].isString());
155 ASSERT_STREQ("bar", variant["foo"]["sub-foo"].asString().c_str());
156}
157
158TEST(TestJSONVariantParser, CanParseArray)
159{
160 CVariant variant;
161 ASSERT_TRUE(CJSONVariantParser::Parse("[]", variant));
162 ASSERT_TRUE(variant.isArray());
163 ASSERT_TRUE(variant.empty());
164
165 variant.clear();
166 ASSERT_TRUE(CJSONVariantParser::Parse("[ true ]", variant));
167 ASSERT_TRUE(variant.isArray());
168 ASSERT_EQ(1U, variant.size());
169 ASSERT_TRUE(variant[0].isBoolean());
170 ASSERT_TRUE(variant[0].asBoolean());
171
172 variant.clear();
173 ASSERT_TRUE(CJSONVariantParser::Parse("[ true, \"foo\" ]", variant));
174 ASSERT_TRUE(variant.isArray());
175 ASSERT_EQ(2U, variant.size());
176 ASSERT_TRUE(variant[0].isBoolean());
177 ASSERT_TRUE(variant[0].asBoolean());
178 ASSERT_TRUE(variant[1].isString());
179 ASSERT_STREQ("foo", variant[1].asString().c_str());
180
181 variant.clear();
182 ASSERT_TRUE(CJSONVariantParser::Parse("[ { \"foo\": \"bar\" } ]", variant));
183 ASSERT_TRUE(variant.isArray());
184 ASSERT_EQ(1U, variant.size());
185 ASSERT_TRUE(variant[0].isObject());
186 ASSERT_TRUE(variant[0].isMember("foo"));
187 ASSERT_TRUE(variant[0]["foo"].isString());
188 ASSERT_STREQ("bar", variant[0]["foo"].asString().c_str());
189}
diff --git a/xbmc/utils/test/TestJSONVariantWriter.cpp b/xbmc/utils/test/TestJSONVariantWriter.cpp
new file mode 100644
index 0000000..0772a4d
--- /dev/null
+++ b/xbmc/utils/test/TestJSONVariantWriter.cpp
@@ -0,0 +1,151 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/JSONVariantWriter.h"
10#include "utils/Variant.h"
11
12#include <gtest/gtest.h>
13
14TEST(TestJSONVariantWriter, CanWriteNull)
15{
16 CVariant variant;
17 std::string str;
18
19 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
20 ASSERT_STREQ("null", str.c_str());
21}
22
23TEST(TestJSONVariantWriter, CanWriteBoolean)
24{
25 CVariant variant(true);
26 std::string str;
27 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
28 ASSERT_STREQ("true", str.c_str());
29
30 variant = false;
31 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
32 ASSERT_STREQ("false", str.c_str());
33}
34
35TEST(TestJSONVariantWriter, CanWriteSignedInteger)
36{
37 CVariant variant(-1);
38 std::string str;
39 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
40 ASSERT_STREQ("-1", str.c_str());
41}
42
43TEST(TestJSONVariantWriter, CanWriteUnsignedInteger)
44{
45 CVariant variant(0);
46 std::string str;
47 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
48 ASSERT_STREQ("0", str.c_str());
49
50 variant = 1;
51 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
52 ASSERT_STREQ("1", str.c_str());
53}
54
55TEST(TestJSONVariantWriter, CanWriteSignedInteger64)
56{
57 CVariant variant(static_cast<int64_t>(-4294967296LL));
58 std::string str;
59 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
60 ASSERT_STREQ("-4294967296", str.c_str());
61}
62
63TEST(TestJSONVariantWriter, CanWriteUnsignedInteger64)
64{
65 CVariant variant(static_cast<int64_t>(4294967296LL));
66 std::string str;
67 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
68 ASSERT_STREQ("4294967296", str.c_str());
69}
70
71TEST(TestJSONVariantWriter, CanWriteDouble)
72{
73 CVariant variant(0.0);
74 std::string str;
75 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
76 ASSERT_STREQ("0.0", str.c_str());
77
78 variant = 1.0;
79 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
80 ASSERT_STREQ("1.0", str.c_str());
81
82 variant = -1.0;
83 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
84 ASSERT_STREQ("-1.0", str.c_str());
85}
86
87TEST(TestJSONVariantWriter, CanWriteString)
88{
89 CVariant variant("");
90 std::string str;
91 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
92 ASSERT_STREQ("\"\"", str.c_str());
93
94 variant = "foo";
95 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
96 ASSERT_STREQ("\"foo\"", str.c_str());
97
98 variant = "foo bar";
99 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
100 ASSERT_STREQ("\"foo bar\"", str.c_str());
101}
102
103TEST(TestJSONVariantWriter, CanWriteObject)
104{
105 CVariant variant(CVariant::VariantTypeObject);
106 std::string str;
107 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
108 ASSERT_STREQ("{}", str.c_str());
109
110 variant.clear();
111 variant["foo"] = "bar";
112 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
113 ASSERT_STREQ("{\n\t\"foo\": \"bar\"\n}", str.c_str());
114
115 variant.clear();
116 variant["foo"] = "bar";
117 variant["bar"] = true;
118 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
119 ASSERT_STREQ("{\n\t\"bar\": true,\n\t\"foo\": \"bar\"\n}", str.c_str());
120
121 variant.clear();
122 variant["foo"]["sub-foo"] = "bar";
123 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
124 ASSERT_STREQ("{\n\t\"foo\": {\n\t\t\"sub-foo\": \"bar\"\n\t}\n}", str.c_str());
125}
126
127TEST(TestJSONVariantWriter, CanWriteArray)
128{
129 CVariant variant(CVariant::VariantTypeArray);
130 std::string str;
131 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
132 ASSERT_STREQ("[]", str.c_str());
133
134 variant.clear();
135 variant.push_back(true);
136 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
137 ASSERT_STREQ("[\n\ttrue\n]", str.c_str());
138
139 variant.clear();
140 variant.push_back(true);
141 variant.push_back("foo");
142 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
143 ASSERT_STREQ("[\n\ttrue,\n\t\"foo\"\n]", str.c_str());
144
145 variant.clear();
146 CVariant obj(CVariant::VariantTypeObject);
147 obj["foo"] = "bar";
148 variant.push_back(obj);
149 ASSERT_TRUE(CJSONVariantWriter::Write(variant, str, false));
150 ASSERT_STREQ("[\n\t{\n\t\t\"foo\": \"bar\"\n\t}\n]", str.c_str());
151}
diff --git a/xbmc/utils/test/TestJobManager.cpp b/xbmc/utils/test/TestJobManager.cpp
new file mode 100644
index 0000000..40165e9
--- /dev/null
+++ b/xbmc/utils/test/TestJobManager.cpp
@@ -0,0 +1,215 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "test/MtTestUtils.h"
10#include "utils/Job.h"
11#include "utils/JobManager.h"
12#include "utils/XTimeUtils.h"
13
14#include <atomic>
15
16#include <gtest/gtest.h>
17
18using namespace ConditionPoll;
19
20struct Flags
21{
22 std::atomic<bool> lingerAtWork{true};
23 std::atomic<bool> started{false};
24 std::atomic<bool> finished{false};
25 std::atomic<bool> wasCanceled{false};
26};
27
28class DummyJob : public CJob
29{
30 Flags* m_flags;
31public:
32 inline DummyJob(Flags* flags) : m_flags(flags)
33 {
34 }
35
36 bool DoWork() override
37 {
38 m_flags->started = true;
39 while (m_flags->lingerAtWork)
40 std::this_thread::yield();
41
42 if (ShouldCancel(0,0))
43 m_flags->wasCanceled = true;
44
45 m_flags->finished = true;
46 return true;
47 }
48};
49
50class ReallyDumbJob : public CJob
51{
52 Flags* m_flags;
53public:
54 inline ReallyDumbJob(Flags* flags) : m_flags(flags) {}
55
56 bool DoWork() override
57 {
58 m_flags->finished = true;
59 return true;
60 }
61};
62
63class TestJobManager : public testing::Test
64{
65protected:
66 TestJobManager() = default;
67
68 ~TestJobManager() override
69 {
70 /* Always cancel jobs test completion */
71 CJobManager::GetInstance().CancelJobs();
72 CJobManager::GetInstance().Restart();
73 }
74};
75
76TEST_F(TestJobManager, AddJob)
77{
78 Flags* flags = new Flags();
79 ReallyDumbJob* job = new ReallyDumbJob(flags);
80 CJobManager::GetInstance().AddJob(job, NULL);
81 ASSERT_TRUE(poll([flags]() -> bool { return flags->finished; }));
82 delete flags;
83}
84
85TEST_F(TestJobManager, CancelJob)
86{
87 unsigned int id;
88 Flags* flags = new Flags();
89 DummyJob* job = new DummyJob(flags);
90 id = CJobManager::GetInstance().AddJob(job, NULL);
91
92 // wait for the worker thread to be entered
93 ASSERT_TRUE(poll([flags]() -> bool { return flags->started; }));
94
95 // cancel the job
96 CJobManager::GetInstance().CancelJob(id);
97
98 // let the worker thread continue
99 flags->lingerAtWork = false;
100
101 // make sure the job finished.
102 ASSERT_TRUE(poll([flags]() -> bool { return flags->finished; }));
103
104 // ... and that it was canceled.
105 EXPECT_TRUE(flags->wasCanceled);
106 delete flags;
107}
108
109namespace
110{
111struct JobControlPackage
112{
113 JobControlPackage()
114 {
115 // We're not ready to wait yet
116 jobCreatedMutex.lock();
117 }
118
119 ~JobControlPackage()
120 {
121 jobCreatedMutex.unlock();
122 }
123
124 bool ready = false;
125 XbmcThreads::ConditionVariable jobCreatedCond;
126 CCriticalSection jobCreatedMutex;
127};
128
129class BroadcastingJob :
130 public CJob
131{
132public:
133
134 BroadcastingJob(JobControlPackage &package) :
135 m_package(package),
136 m_finish(false)
137 {
138 }
139
140 void FinishAndStopBlocking()
141 {
142 CSingleLock lock(m_blockMutex);
143
144 m_finish = true;
145 m_block.notifyAll();
146 }
147
148 const char * GetType() const override
149 {
150 return "BroadcastingJob";
151 }
152
153 bool DoWork() override
154 {
155 {
156 CSingleLock lock(m_package.jobCreatedMutex);
157
158 m_package.ready = true;
159 m_package.jobCreatedCond.notifyAll();
160 }
161
162 CSingleLock blockLock(m_blockMutex);
163
164 // Block until we're told to go away
165 while (!m_finish)
166 m_block.wait(m_blockMutex);
167 return true;
168 }
169
170private:
171
172 JobControlPackage &m_package;
173
174 XbmcThreads::ConditionVariable m_block;
175 CCriticalSection m_blockMutex;
176 bool m_finish;
177};
178
179BroadcastingJob *
180WaitForJobToStartProcessing(CJob::PRIORITY priority, JobControlPackage &package)
181{
182 BroadcastingJob* job = new BroadcastingJob(package);
183 CJobManager::GetInstance().AddJob(job, NULL, priority);
184
185 // We're now ready to wait, wait and then unblock once ready
186 while (!package.ready)
187 package.jobCreatedCond.wait(package.jobCreatedMutex);
188
189 return job;
190}
191}
192
193TEST_F(TestJobManager, PauseLowPriorityJob)
194{
195 JobControlPackage package;
196 BroadcastingJob *job (WaitForJobToStartProcessing(CJob::PRIORITY_LOW_PAUSABLE, package));
197
198 EXPECT_TRUE(CJobManager::GetInstance().IsProcessing(CJob::PRIORITY_LOW_PAUSABLE));
199 CJobManager::GetInstance().PauseJobs();
200 EXPECT_FALSE(CJobManager::GetInstance().IsProcessing(CJob::PRIORITY_LOW_PAUSABLE));
201 CJobManager::GetInstance().UnPauseJobs();
202 EXPECT_TRUE(CJobManager::GetInstance().IsProcessing(CJob::PRIORITY_LOW_PAUSABLE));
203
204 job->FinishAndStopBlocking();
205}
206
207TEST_F(TestJobManager, IsProcessing)
208{
209 JobControlPackage package;
210 BroadcastingJob *job (WaitForJobToStartProcessing(CJob::PRIORITY_LOW_PAUSABLE, package));
211
212 EXPECT_EQ(0, CJobManager::GetInstance().IsProcessing(""));
213
214 job->FinishAndStopBlocking();
215}
diff --git a/xbmc/utils/test/TestLabelFormatter.cpp b/xbmc/utils/test/TestLabelFormatter.cpp
new file mode 100644
index 0000000..0989fec
--- /dev/null
+++ b/xbmc/utils/test/TestLabelFormatter.cpp
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "FileItem.h"
10#include "ServiceBroker.h"
11#include "filesystem/File.h"
12#include "settings/Settings.h"
13#include "settings/SettingsComponent.h"
14#include "test/TestUtils.h"
15#include "utils/LabelFormatter.h"
16
17#include <gtest/gtest.h>
18
19/* Set default settings used by CLabelFormatter. */
20class TestLabelFormatter : public testing::Test
21{
22protected:
23 TestLabelFormatter() = default;
24
25 ~TestLabelFormatter() override
26 {
27 CServiceBroker::GetSettingsComponent()->GetSettings()->Unload();
28 }
29};
30
31TEST_F(TestLabelFormatter, FormatLabel)
32{
33 XFILE::CFile *tmpfile;
34 std::string tmpfilepath, destpath;
35 LABEL_MASKS labelMasks;
36 CLabelFormatter formatter("", labelMasks.m_strLabel2File);
37
38 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
39 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
40
41 CFileItemPtr item(new CFileItem(tmpfilepath));
42 item->SetPath(tmpfilepath);
43 item->m_bIsFolder = false;
44 item->Select(true);
45
46 formatter.FormatLabel(item.get());
47
48 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
49}
50
51TEST_F(TestLabelFormatter, FormatLabel2)
52{
53 XFILE::CFile *tmpfile;
54 std::string tmpfilepath, destpath;
55 LABEL_MASKS labelMasks;
56 CLabelFormatter formatter("", labelMasks.m_strLabel2File);
57
58 ASSERT_NE(nullptr, (tmpfile = XBMC_CREATETEMPFILE("")));
59 tmpfilepath = XBMC_TEMPFILEPATH(tmpfile);
60
61 CFileItemPtr item(new CFileItem(tmpfilepath));
62 item->SetPath(tmpfilepath);
63 item->m_bIsFolder = false;
64 item->Select(true);
65
66 formatter.FormatLabel2(item.get());
67
68 EXPECT_TRUE(XBMC_DELETETEMPFILE(tmpfile));
69}
diff --git a/xbmc/utils/test/TestLangCodeExpander.cpp b/xbmc/utils/test/TestLangCodeExpander.cpp
new file mode 100644
index 0000000..7a6dde1
--- /dev/null
+++ b/xbmc/utils/test/TestLangCodeExpander.cpp
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/LangCodeExpander.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestLangCodeExpander, ConvertISO6391ToISO6392B)
14{
15 std::string refstr, varstr;
16
17 refstr = "eng";
18 g_LangCodeExpander.ConvertISO6391ToISO6392B("en", varstr);
19 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
20}
21
22TEST(TestLangCodeExpander, ConvertToISO6392B)
23{
24 std::string refstr, varstr;
25
26 refstr = "eng";
27 g_LangCodeExpander.ConvertToISO6392B("en", varstr);
28 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
29}
diff --git a/xbmc/utils/test/TestLocale.cpp b/xbmc/utils/test/TestLocale.cpp
new file mode 100644
index 0000000..f5193ed
--- /dev/null
+++ b/xbmc/utils/test/TestLocale.cpp
@@ -0,0 +1,272 @@
1/*
2 * Copyright (C) 2015-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/Locale.h"
10#include "utils/StringUtils.h"
11
12#include <gtest/gtest.h>
13
14static const std::string TerritorySeparator = "_";
15static const std::string CodesetSeparator = ".";
16static const std::string ModifierSeparator = "@";
17
18static const std::string LanguageCodeEnglish = "en";
19static const std::string TerritoryCodeBritain = "GB";
20static const std::string CodesetUtf8 = "UTF-8";
21static const std::string ModifierLatin = "latin";
22
23TEST(TestLocale, DefaultLocale)
24{
25 CLocale locale;
26 ASSERT_FALSE(locale.IsValid());
27 ASSERT_STREQ("", locale.GetLanguageCode().c_str());
28 ASSERT_STREQ("", locale.GetTerritoryCode().c_str());
29 ASSERT_STREQ("", locale.GetCodeset().c_str());
30 ASSERT_STREQ("", locale.GetModifier().c_str());
31 ASSERT_STREQ("", locale.ToString().c_str());
32}
33
34TEST(TestLocale, LanguageLocale)
35{
36 CLocale locale(LanguageCodeEnglish);
37 ASSERT_TRUE(locale.IsValid());
38 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
39 ASSERT_STREQ("", locale.GetTerritoryCode().c_str());
40 ASSERT_STREQ("", locale.GetCodeset().c_str());
41 ASSERT_STREQ("", locale.GetModifier().c_str());
42 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToString().c_str());
43 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToStringLC().c_str());
44 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToShortString().c_str());
45 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToShortStringLC().c_str());
46}
47
48TEST(TestLocale, LanguageTerritoryLocale)
49{
50 const std::string strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
51 std::string strLocaleLC = strLocale;
52 StringUtils::ToLower(strLocaleLC);
53
54 CLocale locale(LanguageCodeEnglish, TerritoryCodeBritain);
55 ASSERT_TRUE(locale.IsValid());
56 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
57 ASSERT_STREQ(TerritoryCodeBritain.c_str(), locale.GetTerritoryCode().c_str());
58 ASSERT_STREQ("", locale.GetCodeset().c_str());
59 ASSERT_STREQ("", locale.GetModifier().c_str());
60 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
61 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
62 ASSERT_STREQ(strLocale.c_str(), locale.ToShortString().c_str());
63 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToShortStringLC().c_str());
64}
65
66TEST(TestLocale, LanguageCodesetLocale)
67{
68 const std::string strLocale = LanguageCodeEnglish + CodesetSeparator + CodesetUtf8;
69 std::string strLocaleLC = strLocale;
70 StringUtils::ToLower(strLocaleLC);
71
72 CLocale locale(LanguageCodeEnglish, "", CodesetUtf8);
73 ASSERT_TRUE(locale.IsValid());
74 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
75 ASSERT_STREQ("", locale.GetTerritoryCode().c_str());
76 ASSERT_STREQ(CodesetUtf8.c_str(), locale.GetCodeset().c_str());
77 ASSERT_STREQ("", locale.GetModifier().c_str());
78 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
79 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
80 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToShortString().c_str());
81 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToShortStringLC().c_str());
82}
83
84TEST(TestLocale, LanguageModifierLocale)
85{
86 const std::string strLocale = LanguageCodeEnglish + ModifierSeparator + ModifierLatin;
87 std::string strLocaleLC = strLocale;
88 StringUtils::ToLower(strLocaleLC);
89
90 CLocale locale(LanguageCodeEnglish, "", "", ModifierLatin);
91 ASSERT_TRUE(locale.IsValid());
92 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
93 ASSERT_STREQ("", locale.GetTerritoryCode().c_str());
94 ASSERT_STREQ("", locale.GetCodeset().c_str());
95 ASSERT_STREQ(ModifierLatin.c_str(), locale.GetModifier().c_str());
96 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
97 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
98 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToShortString().c_str());
99 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.ToShortStringLC().c_str());
100}
101
102TEST(TestLocale, LanguageTerritoryCodesetLocale)
103{
104 const std::string strLocaleShort = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
105 std::string strLocaleShortLC = strLocaleShort;
106 StringUtils::ToLower(strLocaleShortLC);
107 const std::string strLocale = strLocaleShort + CodesetSeparator + CodesetUtf8;
108 std::string strLocaleLC = strLocale;
109 StringUtils::ToLower(strLocaleLC);
110
111 CLocale locale(LanguageCodeEnglish, TerritoryCodeBritain, CodesetUtf8);
112 ASSERT_TRUE(locale.IsValid());
113 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
114 ASSERT_STREQ(TerritoryCodeBritain.c_str(), locale.GetTerritoryCode().c_str());
115 ASSERT_STREQ(CodesetUtf8.c_str(), locale.GetCodeset().c_str());
116 ASSERT_STREQ("", locale.GetModifier().c_str());
117 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
118 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
119 ASSERT_STREQ(strLocaleShort.c_str(), locale.ToShortString().c_str());
120 ASSERT_STREQ(strLocaleShortLC.c_str(), locale.ToShortStringLC().c_str());
121}
122
123TEST(TestLocale, LanguageTerritoryModifierLocale)
124{
125 const std::string strLocaleShort = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
126 std::string strLocaleShortLC = strLocaleShort;
127 StringUtils::ToLower(strLocaleShortLC);
128 const std::string strLocale = strLocaleShort + ModifierSeparator + ModifierLatin;
129 std::string strLocaleLC = strLocale;
130 StringUtils::ToLower(strLocaleLC);
131
132 CLocale locale(LanguageCodeEnglish, TerritoryCodeBritain, "", ModifierLatin);
133 ASSERT_TRUE(locale.IsValid());
134 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
135 ASSERT_STREQ(TerritoryCodeBritain.c_str(), locale.GetTerritoryCode().c_str());
136 ASSERT_STREQ("", locale.GetCodeset().c_str());
137 ASSERT_STREQ(ModifierLatin.c_str(), locale.GetModifier().c_str());
138 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
139 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
140 ASSERT_STREQ(strLocaleShort.c_str(), locale.ToShortString().c_str());
141 ASSERT_STREQ(strLocaleShortLC.c_str(), locale.ToShortStringLC().c_str());
142}
143
144TEST(TestLocale, LanguageTerritoryCodesetModifierLocale)
145{
146 const std::string strLocaleShort = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
147 std::string strLocaleShortLC = strLocaleShort;
148 StringUtils::ToLower(strLocaleShortLC);
149 const std::string strLocale = strLocaleShort + CodesetSeparator + CodesetUtf8 + ModifierSeparator + ModifierLatin;
150 std::string strLocaleLC = strLocale;
151 StringUtils::ToLower(strLocaleLC);
152
153 CLocale locale(LanguageCodeEnglish, TerritoryCodeBritain, CodesetUtf8, ModifierLatin);
154 ASSERT_TRUE(locale.IsValid());
155 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
156 ASSERT_STREQ(TerritoryCodeBritain.c_str(), locale.GetTerritoryCode().c_str());
157 ASSERT_STREQ(CodesetUtf8.c_str(), locale.GetCodeset().c_str());
158 ASSERT_STREQ(ModifierLatin.c_str(), locale.GetModifier().c_str());
159 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
160 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
161 ASSERT_STREQ(strLocaleShort.c_str(), locale.ToShortString().c_str());
162 ASSERT_STREQ(strLocaleShortLC.c_str(), locale.ToShortStringLC().c_str());
163}
164
165TEST(TestLocale, FullStringLocale)
166{
167 const std::string strLocaleShort = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
168 std::string strLocaleShortLC = strLocaleShort;
169 StringUtils::ToLower(strLocaleShortLC);
170 const std::string strLocale = strLocaleShort + CodesetSeparator + CodesetUtf8 + ModifierSeparator + ModifierLatin;
171 std::string strLocaleLC = strLocale;
172 StringUtils::ToLower(strLocaleLC);
173
174 CLocale locale(strLocale);
175 ASSERT_TRUE(locale.IsValid());
176 ASSERT_STREQ(LanguageCodeEnglish.c_str(), locale.GetLanguageCode().c_str());
177 ASSERT_STREQ(TerritoryCodeBritain.c_str(), locale.GetTerritoryCode().c_str());
178 ASSERT_STREQ(CodesetUtf8.c_str(), locale.GetCodeset().c_str());
179 ASSERT_STREQ(ModifierLatin.c_str(), locale.GetModifier().c_str());
180 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
181 ASSERT_STREQ(strLocaleLC.c_str(), locale.ToStringLC().c_str());
182 ASSERT_STREQ(strLocaleShort.c_str(), locale.ToShortString().c_str());
183 ASSERT_STREQ(strLocaleShortLC.c_str(), locale.ToShortStringLC().c_str());
184}
185
186TEST(TestLocale, FromString)
187{
188 std::string strLocale = "";
189 CLocale locale = CLocale::FromString(strLocale);
190 ASSERT_FALSE(locale.IsValid());
191 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
192
193 strLocale = LanguageCodeEnglish;
194 locale = CLocale::FromString(strLocale);
195 ASSERT_TRUE(locale.IsValid());
196 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
197
198 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
199 locale = CLocale::FromString(strLocale);
200 ASSERT_TRUE(locale.IsValid());
201 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
202
203 strLocale = LanguageCodeEnglish + CodesetSeparator + CodesetUtf8;
204 locale = CLocale::FromString(strLocale);
205 ASSERT_TRUE(locale.IsValid());
206 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
207
208 strLocale = LanguageCodeEnglish + ModifierSeparator + ModifierLatin;
209 locale = CLocale::FromString(strLocale);
210 ASSERT_TRUE(locale.IsValid());
211 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
212
213 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain + CodesetSeparator + CodesetUtf8;
214 locale = CLocale::FromString(strLocale);
215 ASSERT_TRUE(locale.IsValid());
216 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
217
218 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain + ModifierSeparator + ModifierLatin;
219 locale = CLocale::FromString(strLocale);
220 ASSERT_TRUE(locale.IsValid());
221 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
222
223 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain + CodesetSeparator + CodesetUtf8 + ModifierSeparator + ModifierLatin;
224 locale = CLocale::FromString(strLocale);
225 ASSERT_TRUE(locale.IsValid());
226 ASSERT_STREQ(strLocale.c_str(), locale.ToString().c_str());
227}
228
229TEST(TestLocale, EmptyLocale)
230{
231 ASSERT_FALSE(CLocale::Empty.IsValid());
232 ASSERT_STREQ("", CLocale::Empty.GetLanguageCode().c_str());
233 ASSERT_STREQ("", CLocale::Empty.GetTerritoryCode().c_str());
234 ASSERT_STREQ("", CLocale::Empty.GetCodeset().c_str());
235 ASSERT_STREQ("", CLocale::Empty.GetModifier().c_str());
236 ASSERT_STREQ("", CLocale::Empty.ToString().c_str());
237}
238
239TEST(TestLocale, Equals)
240{
241 std::string strLocale = "";
242 CLocale locale;
243 ASSERT_TRUE(locale.Equals(strLocale));
244
245 locale = CLocale(LanguageCodeEnglish);
246 strLocale = LanguageCodeEnglish;
247 ASSERT_TRUE(locale.Equals(strLocale));
248
249 locale = CLocale(LanguageCodeEnglish, TerritoryCodeBritain);
250 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain;
251 ASSERT_TRUE(locale.Equals(strLocale));
252
253 locale = CLocale(LanguageCodeEnglish, "", CodesetUtf8);
254 strLocale = LanguageCodeEnglish + CodesetSeparator + CodesetUtf8;
255 ASSERT_TRUE(locale.Equals(strLocale));
256
257 locale = CLocale(LanguageCodeEnglish, "", "", ModifierLatin);
258 strLocale = LanguageCodeEnglish + ModifierSeparator + ModifierLatin;
259 ASSERT_TRUE(locale.Equals(strLocale));
260
261 locale = CLocale(LanguageCodeEnglish, TerritoryCodeBritain, CodesetUtf8);
262 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain + CodesetSeparator + CodesetUtf8;
263 ASSERT_TRUE(locale.Equals(strLocale));
264
265 locale = CLocale(LanguageCodeEnglish, TerritoryCodeBritain, "", ModifierLatin);
266 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain + ModifierSeparator + ModifierLatin;
267 ASSERT_TRUE(locale.Equals(strLocale));
268
269 locale = CLocale(LanguageCodeEnglish, TerritoryCodeBritain, CodesetUtf8, ModifierLatin);
270 strLocale = LanguageCodeEnglish + TerritorySeparator + TerritoryCodeBritain + CodesetSeparator + CodesetUtf8 + ModifierSeparator + ModifierLatin;
271 ASSERT_TRUE(locale.Equals(strLocale));
272}
diff --git a/xbmc/utils/test/TestMathUtils.cpp b/xbmc/utils/test/TestMathUtils.cpp
new file mode 100644
index 0000000..d60cc3f
--- /dev/null
+++ b/xbmc/utils/test/TestMathUtils.cpp
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/MathUtils.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestMathUtils, round_int)
14{
15 int refval, varval, i;
16
17 for (i = -8; i < 8; ++i)
18 {
19 double d = 0.25*i;
20 refval = (i < 0) ? (i - 1) / 4 : (i + 2) / 4;
21 varval = MathUtils::round_int(d);
22 EXPECT_EQ(refval, varval);
23 }
24}
25
26TEST(TestMathUtils, truncate_int)
27{
28 int refval, varval, i;
29
30 for (i = -8; i < 8; ++i)
31 {
32 double d = 0.25*i;
33 refval = i / 4;
34 varval = MathUtils::truncate_int(d);
35 EXPECT_EQ(refval, varval);
36 }
37}
38
39TEST(TestMathUtils, abs)
40{
41 int64_t refval, varval;
42
43 refval = 5;
44 varval = MathUtils::abs(-5);
45 EXPECT_EQ(refval, varval);
46}
47
48TEST(TestMathUtils, bitcount)
49{
50 unsigned refval, varval;
51
52 refval = 10;
53 varval = MathUtils::bitcount(0x03FF);
54 EXPECT_EQ(refval, varval);
55
56 refval = 8;
57 varval = MathUtils::bitcount(0x2AD5);
58 EXPECT_EQ(refval, varval);
59}
diff --git a/xbmc/utils/test/TestMime.cpp b/xbmc/utils/test/TestMime.cpp
new file mode 100644
index 0000000..7ef82c3
--- /dev/null
+++ b/xbmc/utils/test/TestMime.cpp
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "FileItem.h"
10#include "utils/Mime.h"
11
12#include <gtest/gtest.h>
13
14TEST(TestMime, GetMimeType_string)
15{
16 EXPECT_STREQ("video/avi", CMime::GetMimeType("avi").c_str());
17 EXPECT_STRNE("video/x-msvideo", CMime::GetMimeType("avi").c_str());
18 EXPECT_STRNE("video/avi", CMime::GetMimeType("xvid").c_str());
19}
20
21TEST(TestMime, GetMimeType_CFileItem)
22{
23 std::string refstr, varstr;
24 CFileItem item("testfile.mp4", false);
25
26 refstr = "video/mp4";
27 varstr = CMime::GetMimeType(item);
28 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
29}
diff --git a/xbmc/utils/test/TestPOUtils.cpp b/xbmc/utils/test/TestPOUtils.cpp
new file mode 100644
index 0000000..5808c31
--- /dev/null
+++ b/xbmc/utils/test/TestPOUtils.cpp
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "test/TestUtils.h"
10#include "utils/POUtils.h"
11
12#include <gtest/gtest.h>
13
14
15TEST(TestPOUtils, General)
16{
17 CPODocument a;
18
19 EXPECT_TRUE(a.LoadFile(XBMC_REF_FILE_PATH("xbmc/utils/test/data/language/Spanish/strings.po")));
20
21 EXPECT_TRUE(a.GetNextEntry());
22 EXPECT_EQ(ID_FOUND, a.GetEntryType());
23 EXPECT_EQ((uint32_t)0, a.GetEntryID());
24 a.ParseEntry(false);
25 EXPECT_STREQ("", a.GetMsgctxt().c_str());
26 EXPECT_STREQ("Programs", a.GetMsgid().c_str());
27 EXPECT_STREQ("Programas", a.GetMsgstr().c_str());
28 EXPECT_STREQ("", a.GetPlurMsgstr(0).c_str());
29
30 EXPECT_TRUE(a.GetNextEntry());
31 EXPECT_EQ(ID_FOUND, a.GetEntryType());
32 EXPECT_EQ((uint32_t)1, a.GetEntryID());
33 a.ParseEntry(false);
34 EXPECT_STREQ("", a.GetMsgctxt().c_str());
35 EXPECT_STREQ("Pictures", a.GetMsgid().c_str());
36 EXPECT_STREQ("Imágenes", a.GetMsgstr().c_str());
37 EXPECT_STREQ("", a.GetPlurMsgstr(0).c_str());
38
39 EXPECT_TRUE(a.GetNextEntry());
40 EXPECT_EQ(ID_FOUND, a.GetEntryType());
41 EXPECT_EQ((uint32_t)2, a.GetEntryID());
42 a.ParseEntry(false);
43 EXPECT_STREQ("", a.GetMsgctxt().c_str());
44 EXPECT_STREQ("Music", a.GetMsgid().c_str());
45 EXPECT_STREQ("Música", a.GetMsgstr().c_str());
46 EXPECT_STREQ("", a.GetPlurMsgstr(0).c_str());
47}
diff --git a/xbmc/utils/test/TestRegExp.cpp b/xbmc/utils/test/TestRegExp.cpp
new file mode 100644
index 0000000..3a3df8f
--- /dev/null
+++ b/xbmc/utils/test/TestRegExp.cpp
@@ -0,0 +1,169 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9/** @todo gtest/gtest.h needs to come in before utils/RegExp.h.
10 * Investigate why.
11 */
12#include "CompileInfo.h"
13#include "ServiceBroker.h"
14#include "filesystem/File.h"
15#include "filesystem/SpecialProtocol.h"
16#include "utils/RegExp.h"
17#include "utils/StringUtils.h"
18#include "utils/log.h"
19
20#include <gtest/gtest.h>
21
22TEST(TestRegExp, RegFind)
23{
24 CRegExp regex;
25
26 EXPECT_TRUE(regex.RegComp("^Test.*"));
27 EXPECT_EQ(0, regex.RegFind("Test string."));
28
29 EXPECT_TRUE(regex.RegComp("^string.*"));
30 EXPECT_EQ(-1, regex.RegFind("Test string."));
31}
32
33TEST(TestRegExp, GetReplaceString)
34{
35 CRegExp regex;
36
37 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
38 EXPECT_EQ(0, regex.RegFind("Test string."));
39 EXPECT_STREQ("string", regex.GetReplaceString("\\2").c_str());
40}
41
42TEST(TestRegExp, GetFindLen)
43{
44 CRegExp regex;
45
46 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
47 EXPECT_EQ(0, regex.RegFind("Test string."));
48 EXPECT_EQ(12, regex.GetFindLen());
49}
50
51TEST(TestRegExp, GetSubCount)
52{
53 CRegExp regex;
54
55 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
56 EXPECT_EQ(0, regex.RegFind("Test string."));
57 EXPECT_EQ(2, regex.GetSubCount());
58}
59
60TEST(TestRegExp, GetSubStart)
61{
62 CRegExp regex;
63
64 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
65 EXPECT_EQ(0, regex.RegFind("Test string."));
66 EXPECT_EQ(0, regex.GetSubStart(0));
67 EXPECT_EQ(0, regex.GetSubStart(1));
68 EXPECT_EQ(5, regex.GetSubStart(2));
69}
70
71TEST(TestRegExp, GetCaptureTotal)
72{
73 CRegExp regex;
74
75 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
76 EXPECT_EQ(0, regex.RegFind("Test string."));
77 EXPECT_EQ(2, regex.GetCaptureTotal());
78}
79
80TEST(TestRegExp, GetMatch)
81{
82 CRegExp regex;
83
84 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
85 EXPECT_EQ(0, regex.RegFind("Test string."));
86 EXPECT_STREQ("Test string.", regex.GetMatch(0).c_str());
87 EXPECT_STREQ("Test", regex.GetMatch(1).c_str());
88 EXPECT_STREQ("string", regex.GetMatch(2).c_str());
89}
90
91TEST(TestRegExp, GetPattern)
92{
93 CRegExp regex;
94
95 EXPECT_TRUE(regex.RegComp("^(Test)\\s*(.*)\\."));
96 EXPECT_STREQ("^(Test)\\s*(.*)\\.", regex.GetPattern().c_str());
97}
98
99TEST(TestRegExp, GetNamedSubPattern)
100{
101 CRegExp regex;
102 std::string match;
103
104 EXPECT_TRUE(regex.RegComp("^(?<first>Test)\\s*(?<second>.*)\\."));
105 EXPECT_EQ(0, regex.RegFind("Test string."));
106 EXPECT_TRUE(regex.GetNamedSubPattern("first", match));
107 EXPECT_STREQ("Test", match.c_str());
108 EXPECT_TRUE(regex.GetNamedSubPattern("second", match));
109 EXPECT_STREQ("string", match.c_str());
110}
111
112TEST(TestRegExp, operatorEqual)
113{
114 CRegExp regex, regexcopy;
115 std::string match;
116
117 EXPECT_TRUE(regex.RegComp("^(?<first>Test)\\s*(?<second>.*)\\."));
118 regexcopy = regex;
119 EXPECT_EQ(0, regexcopy.RegFind("Test string."));
120 EXPECT_TRUE(regexcopy.GetNamedSubPattern("first", match));
121 EXPECT_STREQ("Test", match.c_str());
122 EXPECT_TRUE(regexcopy.GetNamedSubPattern("second", match));
123 EXPECT_STREQ("string", match.c_str());
124}
125
126class TestRegExpLog : public testing::Test
127{
128protected:
129 TestRegExpLog() = default;
130 ~TestRegExpLog() override { CServiceBroker::GetLogging().Uninitialize(); }
131};
132
133TEST_F(TestRegExpLog, DumpOvector)
134{
135 CRegExp regex;
136 std::string logfile, logstring;
137 char buf[100];
138 ssize_t bytesread;
139 XFILE::CFile file;
140
141 std::string appName = CCompileInfo::GetAppName();
142 StringUtils::ToLower(appName);
143 logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log";
144 CServiceBroker::GetLogging().Initialize(
145 CSpecialProtocol::TranslatePath("special://temp/").c_str());
146 EXPECT_TRUE(XFILE::CFile::Exists(logfile));
147
148 EXPECT_TRUE(regex.RegComp("^(?<first>Test)\\s*(?<second>.*)\\."));
149 EXPECT_EQ(0, regex.RegFind("Test string."));
150 regex.DumpOvector(LOGDEBUG);
151 CServiceBroker::GetLogging().Uninitialize();
152
153 EXPECT_TRUE(file.Open(logfile));
154 while ((bytesread = file.Read(buf, sizeof(buf) - 1)) > 0)
155 {
156 buf[bytesread] = '\0';
157 logstring.append(buf);
158 }
159 file.Close();
160 EXPECT_FALSE(logstring.empty());
161
162 EXPECT_STREQ("\xEF\xBB\xBF", logstring.substr(0, 3).c_str());
163
164 EXPECT_TRUE(regex.RegComp(".*DEBUG <general>: regexp ovector=\\{\\[0,12\\],\\[0,4\\],"
165 "\\[5,11\\]\\}.*"));
166 EXPECT_GE(regex.RegFind(logstring), 0);
167
168 EXPECT_TRUE(XFILE::CFile::Delete(logfile));
169}
diff --git a/xbmc/utils/test/TestRingBuffer.cpp b/xbmc/utils/test/TestRingBuffer.cpp
new file mode 100644
index 0000000..e2fd2d5
--- /dev/null
+++ b/xbmc/utils/test/TestRingBuffer.cpp
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/RingBuffer.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestRingBuffer, General)
14{
15 CRingBuffer a;
16 char data[20];
17 unsigned int i;
18
19 EXPECT_TRUE(a.Create(20));
20 EXPECT_EQ((unsigned int)20, a.getSize());
21 memset(data, 0, sizeof(data));
22 for (i = 0; i < a.getSize(); i++)
23 EXPECT_TRUE(a.WriteData(data, 1));
24 a.Clear();
25
26 memcpy(data, "0123456789", sizeof("0123456789"));
27 EXPECT_TRUE(a.WriteData(data, sizeof("0123456789")));
28 EXPECT_STREQ("0123456789", a.getBuffer());
29
30 memset(data, 0, sizeof(data));
31 EXPECT_TRUE(a.ReadData(data, 5));
32 EXPECT_STREQ("01234", data);
33}
diff --git a/xbmc/utils/test/TestScraperParser.cpp b/xbmc/utils/test/TestScraperParser.cpp
new file mode 100644
index 0000000..50744b4
--- /dev/null
+++ b/xbmc/utils/test/TestScraperParser.cpp
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "test/TestUtils.h"
10#include "utils/ScraperParser.h"
11
12#include <gtest/gtest.h>
13
14TEST(TestScraperParser, General)
15{
16 CScraperParser a;
17
18 a.Clear();
19 EXPECT_TRUE(
20 a.Load(XBMC_REF_FILE_PATH("/addons/metadata.themoviedb.org/tmdb.xml")));
21
22 EXPECT_STREQ(
23 XBMC_REF_FILE_PATH("/addons/metadata.themoviedb.org/tmdb.xml").c_str(),
24 a.GetFilename().c_str());
25 EXPECT_STREQ("UTF-8", a.GetSearchStringEncoding().c_str());
26}
diff --git a/xbmc/utils/test/TestScraperUrl.cpp b/xbmc/utils/test/TestScraperUrl.cpp
new file mode 100644
index 0000000..1feb181
--- /dev/null
+++ b/xbmc/utils/test/TestScraperUrl.cpp
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/ScraperUrl.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestScraperUrl, General)
14{
15 CScraperUrl a;
16 std::string xmlstring;
17
18 xmlstring = "<data spoof=\"blah\" gzip=\"yes\">\n"
19 " <someurl>\n"
20 " </someurl>\n"
21 " <someotherurl>\n"
22 " </someotherurl>\n"
23 "</data>\n";
24 EXPECT_TRUE(a.ParseFromData(xmlstring));
25
26 const auto url = a.GetFirstUrlByType();
27 EXPECT_STREQ("blah", url.m_spoof.c_str());
28 EXPECT_STREQ("someurl", url.m_url.c_str());
29 EXPECT_STREQ("", url.m_cache.c_str());
30 EXPECT_EQ(CScraperUrl::UrlType::General, url.m_type);
31 EXPECT_FALSE(url.m_post);
32 EXPECT_TRUE(url.m_isgz);
33 EXPECT_EQ(-1, url.m_season);
34}
diff --git a/xbmc/utils/test/TestSortUtils.cpp b/xbmc/utils/test/TestSortUtils.cpp
new file mode 100644
index 0000000..dac3c62
--- /dev/null
+++ b/xbmc/utils/test/TestSortUtils.cpp
@@ -0,0 +1,123 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/SortUtils.h"
10#include "utils/Variant.h"
11
12#include <gtest/gtest.h>
13
14TEST(TestSortUtils, Sort_SortBy)
15{
16 SortItems items;
17
18 CVariant variant1("M Artist");
19 SortItemPtr item1(new SortItem());
20 (*item1)[FieldArtist] = variant1;
21 CVariant variant2("B Artist");
22 SortItemPtr item2(new SortItem());
23 (*item2)[FieldArtist] = variant2;
24 CVariant variant3("R Artist");
25 SortItemPtr item3(new SortItem());
26 (*item3)[FieldArtist] = variant3;
27 CVariant variant4("R Artist");
28 SortItemPtr item4(new SortItem());
29 (*item4)[FieldArtist] = variant4;
30 CVariant variant5("I Artist");
31 SortItemPtr item5(new SortItem());
32 (*item5)[FieldArtist] = variant5;
33 CVariant variant6("A Artist");
34 SortItemPtr item6(new SortItem());
35 (*item6)[FieldArtist] = variant6;
36 CVariant variant7("G Artist");
37 SortItemPtr item7(new SortItem());
38 (*item7)[FieldArtist] = variant7;
39
40 items.push_back(item1);
41 items.push_back(item2);
42 items.push_back(item3);
43 items.push_back(item4);
44 items.push_back(item5);
45 items.push_back(item6);
46 items.push_back(item7);
47
48 SortUtils::Sort(SortByArtist, SortOrderAscending, SortAttributeNone, items);
49
50 EXPECT_STREQ("A Artist", (*items.at(0))[FieldArtist].asString().c_str());
51 EXPECT_STREQ("B Artist", (*items.at(1))[FieldArtist].asString().c_str());
52 EXPECT_STREQ("G Artist", (*items.at(2))[FieldArtist].asString().c_str());
53 EXPECT_STREQ("I Artist", (*items.at(3))[FieldArtist].asString().c_str());
54 EXPECT_STREQ("M Artist", (*items.at(4))[FieldArtist].asString().c_str());
55 EXPECT_STREQ("R Artist", (*items.at(5))[FieldArtist].asString().c_str());
56 EXPECT_STREQ("R Artist", (*items.at(6))[FieldArtist].asString().c_str());
57}
58
59TEST(TestSortUtils, Sort_SortDescription)
60{
61 SortItems items;
62
63 CVariant variant1("M Artist");
64 SortItemPtr item1(new SortItem());
65 (*item1)[FieldArtist] = variant1;
66 CVariant variant2("B Artist");
67 SortItemPtr item2(new SortItem());
68 (*item2)[FieldArtist] = variant2;
69 CVariant variant3("R Artist");
70 SortItemPtr item3(new SortItem());
71 (*item3)[FieldArtist] = variant3;
72 CVariant variant4("R Artist");
73 SortItemPtr item4(new SortItem());
74 (*item4)[FieldArtist] = variant4;
75 CVariant variant5("I Artist");
76 SortItemPtr item5(new SortItem());
77 (*item5)[FieldArtist] = variant5;
78 CVariant variant6("A Artist");
79 SortItemPtr item6(new SortItem());
80 (*item6)[FieldArtist] = variant6;
81 CVariant variant7("G Artist");
82 SortItemPtr item7(new SortItem());
83 (*item7)[FieldArtist] = variant7;
84
85 items.push_back(item1);
86 items.push_back(item2);
87 items.push_back(item3);
88 items.push_back(item4);
89 items.push_back(item5);
90 items.push_back(item6);
91 items.push_back(item7);
92
93 SortDescription desc;
94 desc.sortBy = SortByArtist;
95 SortUtils::Sort(desc, items);
96
97 EXPECT_STREQ("A Artist", (*items.at(0))[FieldArtist].asString().c_str());
98 EXPECT_STREQ("B Artist", (*items.at(1))[FieldArtist].asString().c_str());
99 EXPECT_STREQ("G Artist", (*items.at(2))[FieldArtist].asString().c_str());
100 EXPECT_STREQ("I Artist", (*items.at(3))[FieldArtist].asString().c_str());
101 EXPECT_STREQ("M Artist", (*items.at(4))[FieldArtist].asString().c_str());
102 EXPECT_STREQ("R Artist", (*items.at(5))[FieldArtist].asString().c_str());
103 EXPECT_STREQ("R Artist", (*items.at(6))[FieldArtist].asString().c_str());
104}
105
106TEST(TestSortUtils, GetFieldsForSorting)
107{
108 Fields fields;
109
110 fields = SortUtils::GetFieldsForSorting(SortByArtist);
111 Fields::iterator it;
112 it = fields.find(FieldAlbum);
113 EXPECT_EQ(FieldAlbum, *it);
114 it = fields.find(FieldArtist);
115 EXPECT_EQ(FieldArtist, *it);
116 it = fields.find(FieldArtistSort);
117 EXPECT_EQ(FieldArtistSort, *it);
118 it = fields.find(FieldYear);
119 EXPECT_EQ(FieldYear, *it);
120 it = fields.find(FieldTrackNumber);
121 EXPECT_EQ(FieldTrackNumber, *it);
122 EXPECT_EQ((unsigned int)5, fields.size());
123}
diff --git a/xbmc/utils/test/TestStopwatch.cpp b/xbmc/utils/test/TestStopwatch.cpp
new file mode 100644
index 0000000..966afc5
--- /dev/null
+++ b/xbmc/utils/test/TestStopwatch.cpp
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "threads/Thread.h"
10#include "utils/Stopwatch.h"
11
12#include <gtest/gtest.h>
13
14class CTestStopWatchThread : public CThread
15{
16public:
17 CTestStopWatchThread() :
18 CThread("TestStopWatch"){}
19};
20
21TEST(TestStopWatch, Initialization)
22{
23 CStopWatch a;
24 EXPECT_FALSE(a.IsRunning());
25 EXPECT_EQ(0.0f, a.GetElapsedSeconds());
26 EXPECT_EQ(0.0f, a.GetElapsedMilliseconds());
27}
28
29TEST(TestStopWatch, Start)
30{
31 CStopWatch a;
32 a.Start();
33 EXPECT_TRUE(a.IsRunning());
34}
35
36TEST(TestStopWatch, Stop)
37{
38 CStopWatch a;
39 a.Start();
40 a.Stop();
41 EXPECT_FALSE(a.IsRunning());
42}
43
44TEST(TestStopWatch, ElapsedTime)
45{
46 CStopWatch a;
47 CTestStopWatchThread thread;
48 a.Start();
49 thread.Sleep(1);
50 EXPECT_GT(a.GetElapsedSeconds(), 0.0f);
51 EXPECT_GT(a.GetElapsedMilliseconds(), 0.0f);
52}
53
54TEST(TestStopWatch, Reset)
55{
56 CStopWatch a;
57 CTestStopWatchThread thread;
58 a.StartZero();
59 thread.Sleep(2);
60 EXPECT_GT(a.GetElapsedMilliseconds(), 1);
61 thread.Sleep(3);
62 a.Reset();
63 EXPECT_LT(a.GetElapsedMilliseconds(), 5);
64}
diff --git a/xbmc/utils/test/TestStreamDetails.cpp b/xbmc/utils/test/TestStreamDetails.cpp
new file mode 100644
index 0000000..7842eee
--- /dev/null
+++ b/xbmc/utils/test/TestStreamDetails.cpp
@@ -0,0 +1,76 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/StreamDetails.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestStreamDetails, General)
14{
15 CStreamDetails a;
16 CStreamDetailVideo *video = new CStreamDetailVideo();
17 CStreamDetailAudio *audio = new CStreamDetailAudio();
18 CStreamDetailSubtitle *subtitle = new CStreamDetailSubtitle();
19
20 video->m_iWidth = 1920;
21 video->m_iHeight = 1080;
22 video->m_fAspect = 2.39f;
23 video->m_iDuration = 30;
24 video->m_strCodec = "h264";
25 video->m_strStereoMode = "left_right";
26 video->m_strLanguage = "eng";
27
28 audio->m_iChannels = 2;
29 audio->m_strCodec = "aac";
30 audio->m_strLanguage = "eng";
31
32 subtitle->m_strLanguage = "eng";
33
34 a.AddStream(video);
35 a.AddStream(audio);
36
37 EXPECT_TRUE(a.HasItems());
38
39 EXPECT_EQ(1, a.GetStreamCount(CStreamDetail::VIDEO));
40 EXPECT_EQ(1, a.GetVideoStreamCount());
41 EXPECT_STREQ("", a.GetVideoCodec().c_str());
42 EXPECT_EQ(0.0f, a.GetVideoAspect());
43 EXPECT_EQ(0, a.GetVideoWidth());
44 EXPECT_EQ(0, a.GetVideoHeight());
45 EXPECT_EQ(0, a.GetVideoDuration());
46 EXPECT_STREQ("", a.GetStereoMode().c_str());
47
48 EXPECT_EQ(1, a.GetStreamCount(CStreamDetail::AUDIO));
49 EXPECT_EQ(1, a.GetAudioStreamCount());
50
51 EXPECT_EQ(0, a.GetStreamCount(CStreamDetail::SUBTITLE));
52 EXPECT_EQ(0, a.GetSubtitleStreamCount());
53
54 a.AddStream(subtitle);
55 EXPECT_EQ(1, a.GetStreamCount(CStreamDetail::SUBTITLE));
56 EXPECT_EQ(1, a.GetSubtitleStreamCount());
57
58 a.DetermineBestStreams();
59 EXPECT_STREQ("h264", a.GetVideoCodec().c_str());
60 EXPECT_EQ(2.39f, a.GetVideoAspect());
61 EXPECT_EQ(1920, a.GetVideoWidth());
62 EXPECT_EQ(1080, a.GetVideoHeight());
63 EXPECT_EQ(30, a.GetVideoDuration());
64 EXPECT_STREQ("left_right", a.GetStereoMode().c_str());
65}
66
67TEST(TestStreamDetails, VideoDimsToResolutionDescription)
68{
69 EXPECT_STREQ("1080",
70 CStreamDetails::VideoDimsToResolutionDescription(1920, 1080).c_str());
71}
72
73TEST(TestStreamDetails, VideoAspectToAspectDescription)
74{
75 EXPECT_STREQ("2.40", CStreamDetails::VideoAspectToAspectDescription(2.39f).c_str());
76}
diff --git a/xbmc/utils/test/TestStreamUtils.cpp b/xbmc/utils/test/TestStreamUtils.cpp
new file mode 100644
index 0000000..e23f958
--- /dev/null
+++ b/xbmc/utils/test/TestStreamUtils.cpp
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/StreamUtils.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestStreamUtils, General)
14{
15 EXPECT_EQ(0, StreamUtils::GetCodecPriority(""));
16 EXPECT_EQ(1, StreamUtils::GetCodecPriority("ac3"));
17 EXPECT_EQ(2, StreamUtils::GetCodecPriority("dca"));
18 EXPECT_EQ(3, StreamUtils::GetCodecPriority("eac3"));
19 EXPECT_EQ(4, StreamUtils::GetCodecPriority("dtshd_hra"));
20 EXPECT_EQ(5, StreamUtils::GetCodecPriority("dtshd_ma"));
21 EXPECT_EQ(6, StreamUtils::GetCodecPriority("truehd"));
22 EXPECT_EQ(7, StreamUtils::GetCodecPriority("flac"));
23}
diff --git a/xbmc/utils/test/TestStringUtils.cpp b/xbmc/utils/test/TestStringUtils.cpp
new file mode 100644
index 0000000..0a063cc
--- /dev/null
+++ b/xbmc/utils/test/TestStringUtils.cpp
@@ -0,0 +1,605 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/StringUtils.h"
10
11#include <algorithm>
12
13#include <gtest/gtest.h>
14enum class ECG
15{
16 A,
17 B
18};
19
20enum EG
21{
22 C,
23 D
24};
25
26namespace test_enum
27{
28enum class ECN
29{
30 A = 1,
31 B
32};
33enum EN
34{
35 C = 1,
36 D
37};
38}
39TEST(TestStringUtils, Format)
40{
41 std::string refstr = "test 25 2.7 ff FF";
42
43 std::string varstr =
44 StringUtils::Format("%s %d %.1f %x %02X", "test", 25, 2.743f, 0x00ff, 0x00ff);
45 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
46
47 varstr = StringUtils::Format("", "test", 25, 2.743f, 0x00ff, 0x00ff);
48 EXPECT_STREQ("", varstr.c_str());
49}
50
51TEST(TestStringUtils, FormatEnum)
52{
53 const char* zero = "0";
54 const char* one = "1";
55
56 std::string varstr = StringUtils::Format("{}", ECG::A);
57 EXPECT_STREQ(zero, varstr.c_str());
58
59 varstr = StringUtils::Format("{}", EG::C);
60 EXPECT_STREQ(zero, varstr.c_str());
61
62 varstr = StringUtils::Format("{}", test_enum::ECN::A);
63 EXPECT_STREQ(one, varstr.c_str());
64
65 varstr = StringUtils::Format("{}", test_enum::EN::C);
66 EXPECT_STREQ(one, varstr.c_str());
67}
68
69TEST(TestStringUtils, FormatEnumWidth)
70{
71 const char* one = "01";
72
73 std::string varstr = StringUtils::Format("{:02d}", ECG::B);
74 EXPECT_STREQ(one, varstr.c_str());
75
76 varstr = StringUtils::Format("%02d", EG::D);
77 EXPECT_STREQ(one, varstr.c_str());
78}
79
80TEST(TestStringUtils, ToUpper)
81{
82 std::string refstr = "TEST";
83
84 std::string varstr = "TeSt";
85 StringUtils::ToUpper(varstr);
86 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
87}
88
89TEST(TestStringUtils, ToLower)
90{
91 std::string refstr = "test";
92
93 std::string varstr = "TeSt";
94 StringUtils::ToLower(varstr);
95 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
96}
97
98TEST(TestStringUtils, ToCapitalize)
99{
100 std::string refstr = "Test";
101 std::string varstr = "test";
102 StringUtils::ToCapitalize(varstr);
103 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
104
105 refstr = "Just A Test";
106 varstr = "just a test";
107 StringUtils::ToCapitalize(varstr);
108 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
109
110 refstr = "Test -1;2:3, String For Case";
111 varstr = "test -1;2:3, string for Case";
112 StringUtils::ToCapitalize(varstr);
113 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
114
115 refstr = " JuST Another\t\tTEst:\nWoRKs ";
116 varstr = " juST another\t\ttEst:\nwoRKs ";
117 StringUtils::ToCapitalize(varstr);
118 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
119
120 refstr = "N.Y.P.D";
121 varstr = "n.y.p.d";
122 StringUtils::ToCapitalize(varstr);
123 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
124
125 refstr = "N-Y-P-D";
126 varstr = "n-y-p-d";
127 StringUtils::ToCapitalize(varstr);
128 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
129}
130
131TEST(TestStringUtils, EqualsNoCase)
132{
133 std::string refstr = "TeSt";
134
135 EXPECT_TRUE(StringUtils::EqualsNoCase(refstr, "TeSt"));
136 EXPECT_TRUE(StringUtils::EqualsNoCase(refstr, "tEsT"));
137}
138
139TEST(TestStringUtils, Left)
140{
141 std::string refstr, varstr;
142 std::string origstr = "test";
143
144 refstr = "";
145 varstr = StringUtils::Left(origstr, 0);
146 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
147
148 refstr = "te";
149 varstr = StringUtils::Left(origstr, 2);
150 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
151
152 refstr = "test";
153 varstr = StringUtils::Left(origstr, 10);
154 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
155}
156
157TEST(TestStringUtils, Mid)
158{
159 std::string refstr, varstr;
160 std::string origstr = "test";
161
162 refstr = "";
163 varstr = StringUtils::Mid(origstr, 0, 0);
164 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
165
166 refstr = "te";
167 varstr = StringUtils::Mid(origstr, 0, 2);
168 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
169
170 refstr = "test";
171 varstr = StringUtils::Mid(origstr, 0, 10);
172 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
173
174 refstr = "st";
175 varstr = StringUtils::Mid(origstr, 2);
176 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
177
178 refstr = "st";
179 varstr = StringUtils::Mid(origstr, 2, 2);
180 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
181
182 refstr = "es";
183 varstr = StringUtils::Mid(origstr, 1, 2);
184 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
185}
186
187TEST(TestStringUtils, Right)
188{
189 std::string refstr, varstr;
190 std::string origstr = "test";
191
192 refstr = "";
193 varstr = StringUtils::Right(origstr, 0);
194 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
195
196 refstr = "st";
197 varstr = StringUtils::Right(origstr, 2);
198 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
199
200 refstr = "test";
201 varstr = StringUtils::Right(origstr, 10);
202 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
203}
204
205TEST(TestStringUtils, Trim)
206{
207 std::string refstr = "test test";
208
209 std::string varstr = " test test ";
210 StringUtils::Trim(varstr);
211 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
212}
213
214TEST(TestStringUtils, TrimLeft)
215{
216 std::string refstr = "test test ";
217
218 std::string varstr = " test test ";
219 StringUtils::TrimLeft(varstr);
220 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
221}
222
223TEST(TestStringUtils, TrimRight)
224{
225 std::string refstr = " test test";
226
227 std::string varstr = " test test ";
228 StringUtils::TrimRight(varstr);
229 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
230}
231
232TEST(TestStringUtils, Replace)
233{
234 std::string refstr = "text text";
235
236 std::string varstr = "test test";
237 EXPECT_EQ(StringUtils::Replace(varstr, 's', 'x'), 2);
238 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
239
240 EXPECT_EQ(StringUtils::Replace(varstr, 's', 'x'), 0);
241 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
242
243 varstr = "test test";
244 EXPECT_EQ(StringUtils::Replace(varstr, "s", "x"), 2);
245 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
246
247 EXPECT_EQ(StringUtils::Replace(varstr, "s", "x"), 0);
248 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
249}
250
251TEST(TestStringUtils, StartsWith)
252{
253 std::string refstr = "test";
254
255 EXPECT_FALSE(StringUtils::StartsWithNoCase(refstr, "x"));
256
257 EXPECT_TRUE(StringUtils::StartsWith(refstr, "te"));
258 EXPECT_TRUE(StringUtils::StartsWith(refstr, "test"));
259 EXPECT_FALSE(StringUtils::StartsWith(refstr, "Te"));
260
261 EXPECT_TRUE(StringUtils::StartsWithNoCase(refstr, "Te"));
262 EXPECT_TRUE(StringUtils::StartsWithNoCase(refstr, "TesT"));
263}
264
265TEST(TestStringUtils, EndsWith)
266{
267 std::string refstr = "test";
268
269 EXPECT_FALSE(StringUtils::EndsWithNoCase(refstr, "x"));
270
271 EXPECT_TRUE(StringUtils::EndsWith(refstr, "st"));
272 EXPECT_TRUE(StringUtils::EndsWith(refstr, "test"));
273 EXPECT_FALSE(StringUtils::EndsWith(refstr, "sT"));
274
275 EXPECT_TRUE(StringUtils::EndsWithNoCase(refstr, "sT"));
276 EXPECT_TRUE(StringUtils::EndsWithNoCase(refstr, "TesT"));
277}
278
279TEST(TestStringUtils, Join)
280{
281 std::string refstr, varstr;
282 std::vector<std::string> strarray;
283
284 strarray.emplace_back("a");
285 strarray.emplace_back("b");
286 strarray.emplace_back("c");
287 strarray.emplace_back("de");
288 strarray.emplace_back(",");
289 strarray.emplace_back("fg");
290 strarray.emplace_back(",");
291 refstr = "a,b,c,de,,,fg,,";
292 varstr = StringUtils::Join(strarray, ",");
293 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
294}
295
296TEST(TestStringUtils, Split)
297{
298 std::vector<std::string> varresults;
299
300 // test overload with string as delimiter
301 varresults = StringUtils::Split("g,h,ij,k,lm,,n", ",");
302 EXPECT_STREQ("g", varresults.at(0).c_str());
303 EXPECT_STREQ("h", varresults.at(1).c_str());
304 EXPECT_STREQ("ij", varresults.at(2).c_str());
305 EXPECT_STREQ("k", varresults.at(3).c_str());
306 EXPECT_STREQ("lm", varresults.at(4).c_str());
307 EXPECT_STREQ("", varresults.at(5).c_str());
308 EXPECT_STREQ("n", varresults.at(6).c_str());
309
310 EXPECT_TRUE(StringUtils::Split("", "|").empty());
311
312 EXPECT_EQ(4U, StringUtils::Split("a bc d ef ghi ", " ", 4).size());
313 EXPECT_STREQ("d ef ghi ", StringUtils::Split("a bc d ef ghi ", " ", 4).at(3).c_str()) << "Last part must include rest of the input string";
314 EXPECT_EQ(7U, StringUtils::Split("a bc d ef ghi ", " ").size()) << "Result must be 7 strings including two empty strings";
315 EXPECT_STREQ("bc", StringUtils::Split("a bc d ef ghi ", " ").at(1).c_str());
316 EXPECT_STREQ("", StringUtils::Split("a bc d ef ghi ", " ").at(2).c_str());
317 EXPECT_STREQ("", StringUtils::Split("a bc d ef ghi ", " ").at(6).c_str());
318
319 EXPECT_EQ(2U, StringUtils::Split("a bc d ef ghi ", " ").size());
320 EXPECT_EQ(2U, StringUtils::Split("a bc d ef ghi ", " ", 10).size());
321 EXPECT_STREQ("a bc", StringUtils::Split("a bc d ef ghi ", " ", 10).at(0).c_str());
322
323 EXPECT_EQ(1U, StringUtils::Split("a bc d ef ghi ", " z").size());
324 EXPECT_STREQ("a bc d ef ghi ", StringUtils::Split("a bc d ef ghi ", " z").at(0).c_str());
325
326 EXPECT_EQ(1U, StringUtils::Split("a bc d ef ghi ", "").size());
327 EXPECT_STREQ("a bc d ef ghi ", StringUtils::Split("a bc d ef ghi ", "").at(0).c_str());
328
329 // test overload with char as delimiter
330 EXPECT_EQ(4U, StringUtils::Split("a bc d ef ghi ", ' ', 4).size());
331 EXPECT_STREQ("d ef ghi ", StringUtils::Split("a bc d ef ghi ", ' ', 4).at(3).c_str());
332 EXPECT_EQ(7U, StringUtils::Split("a bc d ef ghi ", ' ').size()) << "Result must be 7 strings including two empty strings";
333 EXPECT_STREQ("bc", StringUtils::Split("a bc d ef ghi ", ' ').at(1).c_str());
334 EXPECT_STREQ("", StringUtils::Split("a bc d ef ghi ", ' ').at(2).c_str());
335 EXPECT_STREQ("", StringUtils::Split("a bc d ef ghi ", ' ').at(6).c_str());
336
337 EXPECT_EQ(1U, StringUtils::Split("a bc d ef ghi ", 'z').size());
338 EXPECT_STREQ("a bc d ef ghi ", StringUtils::Split("a bc d ef ghi ", 'z').at(0).c_str());
339
340 EXPECT_EQ(1U, StringUtils::Split("a bc d ef ghi ", "").size());
341 EXPECT_STREQ("a bc d ef ghi ", StringUtils::Split("a bc d ef ghi ", 'z').at(0).c_str());
342}
343
344TEST(TestStringUtils, FindNumber)
345{
346 EXPECT_EQ(3, StringUtils::FindNumber("aabcaadeaa", "aa"));
347 EXPECT_EQ(1, StringUtils::FindNumber("aabcaadeaa", "b"));
348}
349
350TEST(TestStringUtils, AlphaNumericCompare)
351{
352 int64_t ref, var;
353
354 ref = 0;
355 var = StringUtils::AlphaNumericCompare(L"123abc", L"abc123");
356 EXPECT_LT(var, ref);
357}
358
359TEST(TestStringUtils, TimeStringToSeconds)
360{
361 EXPECT_EQ(77455, StringUtils::TimeStringToSeconds("21:30:55"));
362 EXPECT_EQ(7*60, StringUtils::TimeStringToSeconds("7 min"));
363 EXPECT_EQ(7*60, StringUtils::TimeStringToSeconds("7 min\t"));
364 EXPECT_EQ(154*60, StringUtils::TimeStringToSeconds(" 154 min"));
365 EXPECT_EQ(1*60+1, StringUtils::TimeStringToSeconds("1:01"));
366 EXPECT_EQ(4*60+3, StringUtils::TimeStringToSeconds("4:03"));
367 EXPECT_EQ(2*3600+4*60+3, StringUtils::TimeStringToSeconds("2:04:03"));
368 EXPECT_EQ(2*3600+4*60+3, StringUtils::TimeStringToSeconds(" 2:4:3"));
369 EXPECT_EQ(2*3600+4*60+3, StringUtils::TimeStringToSeconds(" \t\t 02:04:03 \n "));
370 EXPECT_EQ(1*3600+5*60+2, StringUtils::TimeStringToSeconds("01:05:02:04:03 \n "));
371 EXPECT_EQ(0, StringUtils::TimeStringToSeconds("blah"));
372 EXPECT_EQ(0, StringUtils::TimeStringToSeconds("ля-ля"));
373}
374
375TEST(TestStringUtils, RemoveCRLF)
376{
377 std::string refstr, varstr;
378
379 refstr = "test\r\nstring\nblah blah";
380 varstr = "test\r\nstring\nblah blah\n";
381 StringUtils::RemoveCRLF(varstr);
382 EXPECT_STREQ(refstr.c_str(), varstr.c_str());
383}
384
385TEST(TestStringUtils, utf8_strlen)
386{
387 size_t ref, var;
388
389 ref = 9;
390 var = StringUtils::utf8_strlen("test_UTF8");
391 EXPECT_EQ(ref, var);
392}
393
394TEST(TestStringUtils, SecondsToTimeString)
395{
396 std::string ref, var;
397
398 ref = "21:30:55";
399 var = StringUtils::SecondsToTimeString(77455);
400 EXPECT_STREQ(ref.c_str(), var.c_str());
401}
402
403TEST(TestStringUtils, IsNaturalNumber)
404{
405 EXPECT_TRUE(StringUtils::IsNaturalNumber("10"));
406 EXPECT_TRUE(StringUtils::IsNaturalNumber(" 10"));
407 EXPECT_TRUE(StringUtils::IsNaturalNumber("0"));
408 EXPECT_FALSE(StringUtils::IsNaturalNumber(" 1 0"));
409 EXPECT_FALSE(StringUtils::IsNaturalNumber("1.0"));
410 EXPECT_FALSE(StringUtils::IsNaturalNumber("1.1"));
411 EXPECT_FALSE(StringUtils::IsNaturalNumber("0x1"));
412 EXPECT_FALSE(StringUtils::IsNaturalNumber("blah"));
413 EXPECT_FALSE(StringUtils::IsNaturalNumber("120 h"));
414 EXPECT_FALSE(StringUtils::IsNaturalNumber(" "));
415 EXPECT_FALSE(StringUtils::IsNaturalNumber(""));
416}
417
418TEST(TestStringUtils, IsInteger)
419{
420 EXPECT_TRUE(StringUtils::IsInteger("10"));
421 EXPECT_TRUE(StringUtils::IsInteger(" -10"));
422 EXPECT_TRUE(StringUtils::IsInteger("0"));
423 EXPECT_FALSE(StringUtils::IsInteger(" 1 0"));
424 EXPECT_FALSE(StringUtils::IsInteger("1.0"));
425 EXPECT_FALSE(StringUtils::IsInteger("1.1"));
426 EXPECT_FALSE(StringUtils::IsInteger("0x1"));
427 EXPECT_FALSE(StringUtils::IsInteger("blah"));
428 EXPECT_FALSE(StringUtils::IsInteger("120 h"));
429 EXPECT_FALSE(StringUtils::IsInteger(" "));
430 EXPECT_FALSE(StringUtils::IsInteger(""));
431}
432
433TEST(TestStringUtils, SizeToString)
434{
435 std::string ref, var;
436
437 ref = "2.00 GB";
438 var = StringUtils::SizeToString(2147483647);
439 EXPECT_STREQ(ref.c_str(), var.c_str());
440}
441
442TEST(TestStringUtils, EmptyString)
443{
444 EXPECT_STREQ("", StringUtils::Empty.c_str());
445}
446
447TEST(TestStringUtils, FindWords)
448{
449 size_t ref, var;
450
451 ref = 5;
452 var = StringUtils::FindWords("test string", "string");
453 EXPECT_EQ(ref, var);
454 var = StringUtils::FindWords("12345string", "string");
455 EXPECT_EQ(ref, var);
456 var = StringUtils::FindWords("apple2012", "2012");
457 EXPECT_EQ(ref, var);
458 ref = -1;
459 var = StringUtils::FindWords("12345string", "ring");
460 EXPECT_EQ(ref, var);
461 var = StringUtils::FindWords("12345string", "345");
462 EXPECT_EQ(ref, var);
463 var = StringUtils::FindWords("apple2012", "e2012");
464 EXPECT_EQ(ref, var);
465 var = StringUtils::FindWords("apple2012", "12");
466 EXPECT_EQ(ref, var);
467}
468
469TEST(TestStringUtils, FindWords_NonAscii)
470{
471 size_t ref, var;
472
473 ref = 6;
474 var = StringUtils::FindWords("我的视频", "视频");
475 EXPECT_EQ(ref, var);
476 var = StringUtils::FindWords("我的视频", "视");
477 EXPECT_EQ(ref, var);
478 var = StringUtils::FindWords("Apple ple", "ple");
479 EXPECT_EQ(ref, var);
480 ref = 7;
481 var = StringUtils::FindWords("Äpfel.pfel", "pfel");
482 EXPECT_EQ(ref, var);
483}
484
485TEST(TestStringUtils, FindEndBracket)
486{
487 int ref, var;
488
489 ref = 11;
490 var = StringUtils::FindEndBracket("atest testbb test", 'a', 'b');
491 EXPECT_EQ(ref, var);
492}
493
494TEST(TestStringUtils, DateStringToYYYYMMDD)
495{
496 int ref, var;
497
498 ref = 20120706;
499 var = StringUtils::DateStringToYYYYMMDD("2012-07-06");
500 EXPECT_EQ(ref, var);
501}
502
503TEST(TestStringUtils, WordToDigits)
504{
505 std::string ref, var;
506
507 ref = "8378 787464";
508 var = "test string";
509 StringUtils::WordToDigits(var);
510 EXPECT_STREQ(ref.c_str(), var.c_str());
511}
512
513TEST(TestStringUtils, CreateUUID)
514{
515 std::cout << "CreateUUID(): " << StringUtils::CreateUUID() << std::endl;
516}
517
518TEST(TestStringUtils, ValidateUUID)
519{
520 EXPECT_TRUE(StringUtils::ValidateUUID(StringUtils::CreateUUID()));
521}
522
523TEST(TestStringUtils, CompareFuzzy)
524{
525 double ref, var;
526
527 ref = 6.25f;
528 var = StringUtils::CompareFuzzy("test string", "string test");
529 EXPECT_EQ(ref, var);
530}
531
532TEST(TestStringUtils, FindBestMatch)
533{
534 double refdouble, vardouble;
535 int refint, varint;
536 std::vector<std::string> strarray;
537
538 refint = 3;
539 refdouble = 0.5625f;
540 strarray.emplace_back("");
541 strarray.emplace_back("a");
542 strarray.emplace_back("e");
543 strarray.emplace_back("es");
544 strarray.emplace_back("t");
545 varint = StringUtils::FindBestMatch("test", strarray, vardouble);
546 EXPECT_EQ(refint, varint);
547 EXPECT_EQ(refdouble, vardouble);
548}
549
550TEST(TestStringUtils, Paramify)
551{
552 const char *input = "some, very \\ odd \"string\"";
553 const char *ref = "\"some, very \\\\ odd \\\"string\\\"\"";
554
555 std::string result = StringUtils::Paramify(input);
556 EXPECT_STREQ(ref, result.c_str());
557}
558
559TEST(TestStringUtils, sortstringbyname)
560{
561 std::vector<std::string> strarray;
562 strarray.emplace_back("B");
563 strarray.emplace_back("c");
564 strarray.emplace_back("a");
565 std::sort(strarray.begin(), strarray.end(), sortstringbyname());
566
567 EXPECT_STREQ("a", strarray[0].c_str());
568 EXPECT_STREQ("B", strarray[1].c_str());
569 EXPECT_STREQ("c", strarray[2].c_str());
570}
571
572TEST(TestStringUtils, FileSizeFormat)
573{
574 EXPECT_STREQ("0B", StringUtils::FormatFileSize(0).c_str());
575
576 EXPECT_STREQ("999B", StringUtils::FormatFileSize(999).c_str());
577 EXPECT_STREQ("0.98kB", StringUtils::FormatFileSize(1000).c_str());
578
579 EXPECT_STREQ("1.00kB", StringUtils::FormatFileSize(1024).c_str());
580 EXPECT_STREQ("9.99kB", StringUtils::FormatFileSize(10229).c_str());
581
582 EXPECT_STREQ("10.1kB", StringUtils::FormatFileSize(10387).c_str());
583 EXPECT_STREQ("99.9kB", StringUtils::FormatFileSize(102297).c_str());
584
585 EXPECT_STREQ("100kB", StringUtils::FormatFileSize(102400).c_str());
586 EXPECT_STREQ("999kB", StringUtils::FormatFileSize(1023431).c_str());
587
588 EXPECT_STREQ("0.98MB", StringUtils::FormatFileSize(1023897).c_str());
589 EXPECT_STREQ("0.98MB", StringUtils::FormatFileSize(1024000).c_str());
590
591 //Last unit should overflow the 3 digit limit
592 EXPECT_STREQ("5432PB", StringUtils::FormatFileSize(6115888293969133568).c_str());
593}
594
595TEST(TestStringUtils, ToHexadecimal)
596{
597 EXPECT_STREQ("", StringUtils::ToHexadecimal("").c_str());
598 EXPECT_STREQ("616263", StringUtils::ToHexadecimal("abc").c_str());
599 std::string a{"a\0b\n", 4};
600 EXPECT_STREQ("6100620a", StringUtils::ToHexadecimal(a).c_str());
601 std::string nul{"\0", 1};
602 EXPECT_STREQ("00", StringUtils::ToHexadecimal(nul).c_str());
603 std::string ff{"\xFF", 1};
604 EXPECT_STREQ("ff", StringUtils::ToHexadecimal(ff).c_str());
605}
diff --git a/xbmc/utils/test/TestSystemInfo.cpp b/xbmc/utils/test/TestSystemInfo.cpp
new file mode 100644
index 0000000..1f2b0a1
--- /dev/null
+++ b/xbmc/utils/test/TestSystemInfo.cpp
@@ -0,0 +1,326 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "GUIInfoManager.h"
10#include "ServiceBroker.h"
11#include "settings/Settings.h"
12#include "utils/CPUInfo.h"
13#include "utils/SystemInfo.h"
14#if defined(TARGET_WINDOWS)
15#include "platform/win32/CharsetConverter.h"
16#endif
17
18#include <gtest/gtest.h>
19
20class TestSystemInfo : public testing::Test
21{
22protected:
23 TestSystemInfo() { CServiceBroker::RegisterCPUInfo(CCPUInfo::GetCPUInfo()); }
24 ~TestSystemInfo() { CServiceBroker::UnregisterCPUInfo(); }
25};
26
27TEST_F(TestSystemInfo, Print_System_Info)
28{
29 std::cout << "'GetKernelName(false)': \"" << g_sysinfo.GetKernelName(true) << "\"\n";
30 std::cout << "'GetKernelVersion()': \"" << g_sysinfo.GetKernelVersion() << "\"\n";
31 std::cout << "'GetKernelVersionFull()': \"" << g_sysinfo.GetKernelVersionFull() << "\"\n";
32 std::cout << "'GetOsPrettyNameWithVersion()': \"" << g_sysinfo.GetOsPrettyNameWithVersion() << "\"\n";
33 std::cout << "'GetOsName(false)': \"" << g_sysinfo.GetOsName(false) << "\"\n";
34 std::cout << "'GetOsVersion()': \"" << g_sysinfo.GetOsVersion() << "\"\n";
35 std::cout << "'GetKernelCpuFamily()': \"" << g_sysinfo.GetKernelCpuFamily() << "\"\n";
36 std::cout << "'GetKernelBitness()': \"" << g_sysinfo.GetKernelBitness() << "\"\n";
37 std::cout << "'GetBuildTargetPlatformName()': \"" << g_sysinfo.GetBuildTargetPlatformName() << "\"\n";
38 std::cout << "'GetBuildTargetPlatformVersionDecoded()': \"" << g_sysinfo.GetBuildTargetPlatformVersionDecoded() << "\"\n";
39 std::cout << "'GetBuildTargetPlatformVersion()': \"" << g_sysinfo.GetBuildTargetPlatformVersion() << "\"\n";
40 std::cout << "'GetBuildTargetCpuFamily()': \"" << g_sysinfo.GetBuildTargetCpuFamily() << "\"\n";
41 std::cout << "'GetXbmcBitness()': \"" << g_sysinfo.GetXbmcBitness() << "\"\n";
42 std::cout << "'GetUsedCompilerNameAndVer()': \"" << g_sysinfo.GetUsedCompilerNameAndVer() << "\"\n";
43 std::cout << "'GetManufacturerName()': \"" << g_sysinfo.GetManufacturerName() << "\"\n";
44 std::cout << "'GetModelName()': \"" << g_sysinfo.GetModelName() << "\"\n";
45 std::cout << "'GetUserAgent()': \"" << g_sysinfo.GetUserAgent() << "\"\n";
46}
47
48TEST_F(TestSystemInfo, GetKernelName)
49{
50 EXPECT_FALSE(g_sysinfo.GetKernelName(true).empty()) << "'GetKernelName(true)' must not return empty kernel name";
51 EXPECT_FALSE(g_sysinfo.GetKernelName(false).empty()) << "'GetKernelName(false)' must not return empty kernel name";
52 EXPECT_STRCASENE("Unknown kernel", g_sysinfo.GetKernelName(true).c_str()) << "'GetKernelName(true)' must not return 'Unknown kernel'";
53 EXPECT_STRCASENE("Unknown kernel", g_sysinfo.GetKernelName(false).c_str()) << "'GetKernelName(false)' must not return 'Unknown kernel'";
54#ifndef TARGET_DARWIN
55 EXPECT_EQ(g_sysinfo.GetBuildTargetPlatformName(), g_sysinfo.GetKernelName(true)) << "'GetKernelName(true)' must match GetBuildTargetPlatformName()";
56 EXPECT_EQ(g_sysinfo.GetBuildTargetPlatformName(), g_sysinfo.GetKernelName(false)) << "'GetKernelName(false)' must match GetBuildTargetPlatformName()";
57#endif // !TARGET_DARWIN
58#if defined(TARGET_WINDOWS)
59 EXPECT_NE(std::string::npos, g_sysinfo.GetKernelName(true).find("Windows")) << "'GetKernelName(true)' must contain 'Windows'";
60 EXPECT_NE(std::string::npos, g_sysinfo.GetKernelName(false).find("Windows")) << "'GetKernelName(false)' must contain 'Windows'";
61#elif defined(TARGET_FREEBSD)
62 EXPECT_STREQ("FreeBSD", g_sysinfo.GetKernelName(true).c_str()) << "'GetKernelName(true)' must return 'FreeBSD'";
63 EXPECT_STREQ("FreeBSD", g_sysinfo.GetKernelName(false).c_str()) << "'GetKernelName(false)' must return 'FreeBSD'";
64#elif defined(TARGET_DARWIN)
65 EXPECT_STREQ("Darwin", g_sysinfo.GetKernelName(true).c_str()) << "'GetKernelName(true)' must return 'Darwin'";
66 EXPECT_STREQ("Darwin", g_sysinfo.GetKernelName(false).c_str()) << "'GetKernelName(false)' must return 'Darwin'";
67#elif defined(TARGET_LINUX)
68 EXPECT_STREQ("Linux", g_sysinfo.GetKernelName(true).c_str()) << "'GetKernelName(true)' must return 'Linux'";
69 EXPECT_STREQ("Linux", g_sysinfo.GetKernelName(false).c_str()) << "'GetKernelName(false)' must return 'Linux'";
70#endif
71}
72
73TEST_F(TestSystemInfo, GetKernelVersionFull)
74{
75 EXPECT_FALSE(g_sysinfo.GetKernelVersionFull().empty()) << "'GetKernelVersionFull()' must not return empty string";
76 EXPECT_STRNE("0.0.0", g_sysinfo.GetKernelVersionFull().c_str()) << "'GetKernelVersionFull()' must not return '0.0.0'";
77 EXPECT_STRNE("0.0", g_sysinfo.GetKernelVersionFull().c_str()) << "'GetKernelVersionFull()' must not return '0.0'";
78 EXPECT_EQ(0U, g_sysinfo.GetKernelVersionFull().find_first_of("0123456789")) << "'GetKernelVersionFull()' must not return version not starting from digit";
79}
80
81TEST_F(TestSystemInfo, GetKernelVersion)
82{
83 EXPECT_FALSE(g_sysinfo.GetKernelVersion().empty()) << "'GetKernelVersion()' must not return empty string";
84 EXPECT_STRNE("0.0.0", g_sysinfo.GetKernelVersion().c_str()) << "'GetKernelVersion()' must not return '0.0.0'";
85 EXPECT_STRNE("0.0", g_sysinfo.GetKernelVersion().c_str()) << "'GetKernelVersion()' must not return '0.0'";
86 EXPECT_EQ(0U, g_sysinfo.GetKernelVersion().find_first_of("0123456789")) << "'GetKernelVersion()' must not return version not starting from digit";
87 EXPECT_EQ(std::string::npos, g_sysinfo.GetKernelVersion().find_first_not_of("0123456789.")) << "'GetKernelVersion()' must not return version with not only digits and dots";
88}
89
90TEST_F(TestSystemInfo, GetOsName)
91{
92 EXPECT_FALSE(g_sysinfo.GetOsName(true).empty()) << "'GetOsName(true)' must not return empty OS name";
93 EXPECT_FALSE(g_sysinfo.GetOsName(false).empty()) << "'GetOsName(false)' must not return empty OS name";
94 EXPECT_STRCASENE("Unknown OS", g_sysinfo.GetOsName(true).c_str()) << "'GetOsName(true)' must not return 'Unknown OS'";
95 EXPECT_STRCASENE("Unknown OS", g_sysinfo.GetOsName(false).c_str()) << "'GetOsName(false)' must not return 'Unknown OS'";
96#if defined(TARGET_WINDOWS)
97 EXPECT_NE(std::string::npos, g_sysinfo.GetOsName(true).find("Windows")) << "'GetOsName(true)' must contain 'Windows'";
98 EXPECT_NE(std::string::npos, g_sysinfo.GetOsName(false).find("Windows")) << "'GetOsName(false)' must contain 'Windows'";
99#elif defined(TARGET_FREEBSD)
100 EXPECT_STREQ("FreeBSD", g_sysinfo.GetOsName(true).c_str()) << "'GetOsName(true)' must return 'FreeBSD'";
101 EXPECT_STREQ("FreeBSD", g_sysinfo.GetOsName(false).c_str()) << "'GetOsName(false)' must return 'FreeBSD'";
102#elif defined(TARGET_DARWIN_IOS)
103 EXPECT_STREQ("iOS", g_sysinfo.GetOsName(true).c_str()) << "'GetOsName(true)' must return 'iOS'";
104 EXPECT_STREQ("iOS", g_sysinfo.GetOsName(false).c_str()) << "'GetOsName(false)' must return 'iOS'";
105#elif defined(TARGET_DARWIN_TVOS)
106 EXPECT_STREQ("tvOS", g_sysinfo.GetOsName(true).c_str()) << "'GetOsName(true)' must return 'tvOS'";
107 EXPECT_STREQ("tvOS", g_sysinfo.GetOsName(false).c_str())
108 << "'GetOsName(false)' must return 'tvOS'";
109#elif defined(TARGET_DARWIN_OSX)
110 EXPECT_STREQ("OS X", g_sysinfo.GetOsName(true).c_str()) << "'GetOsName(true)' must return 'OS X'";
111 EXPECT_STREQ("OS X", g_sysinfo.GetOsName(false).c_str()) << "'GetOsName(false)' must return 'OS X'";
112#elif defined(TARGET_ANDROID)
113 EXPECT_STREQ("Android", g_sysinfo.GetOsName(true).c_str()) << "'GetOsName(true)' must return 'Android'";
114 EXPECT_STREQ("Android", g_sysinfo.GetOsName(false).c_str()) << "'GetOsName(false)' must return 'Android'";
115#endif
116#ifdef TARGET_DARWIN
117 EXPECT_EQ(g_sysinfo.GetBuildTargetPlatformName(), g_sysinfo.GetOsName(true)) << "'GetOsName(true)' must match GetBuildTargetPlatformName()";
118 EXPECT_EQ(g_sysinfo.GetBuildTargetPlatformName(), g_sysinfo.GetOsName(false)) << "'GetOsName(false)' must match GetBuildTargetPlatformName()";
119#endif // TARGET_DARWIN
120}
121
122TEST_F(TestSystemInfo, DISABLED_GetOsVersion)
123{
124 EXPECT_FALSE(g_sysinfo.GetOsVersion().empty()) << "'GetOsVersion()' must not return empty string";
125 EXPECT_STRNE("0.0.0", g_sysinfo.GetOsVersion().c_str()) << "'GetOsVersion()' must not return '0.0.0'";
126 EXPECT_STRNE("0.0", g_sysinfo.GetOsVersion().c_str()) << "'GetOsVersion()' must not return '0.0'";
127 EXPECT_EQ(0U, g_sysinfo.GetOsVersion().find_first_of("0123456789")) << "'GetOsVersion()' must not return version not starting from digit";
128 EXPECT_EQ(std::string::npos, g_sysinfo.GetOsVersion().find_first_not_of("0123456789.")) << "'GetOsVersion()' must not return version with not only digits and dots";
129}
130
131TEST_F(TestSystemInfo, GetOsPrettyNameWithVersion)
132{
133 EXPECT_FALSE(g_sysinfo.GetOsPrettyNameWithVersion().empty()) << "'GetOsPrettyNameWithVersion()' must not return empty string";
134 EXPECT_EQ(std::string::npos, g_sysinfo.GetOsPrettyNameWithVersion().find("Unknown")) << "'GetOsPrettyNameWithVersion()' must not contain 'Unknown'";
135 EXPECT_EQ(std::string::npos, g_sysinfo.GetOsPrettyNameWithVersion().find("unknown")) << "'GetOsPrettyNameWithVersion()' must not contain 'unknown'";
136#ifdef TARGET_WINDOWS
137 EXPECT_NE(std::string::npos, g_sysinfo.GetOsPrettyNameWithVersion().find("Windows")) << "'GetOsPrettyNameWithVersion()' must contain 'Windows'";
138#else // ! TARGET_WINDOWS
139 EXPECT_NE(std::string::npos, g_sysinfo.GetOsPrettyNameWithVersion().find(g_sysinfo.GetOsVersion())) << "'GetOsPrettyNameWithVersion()' must contain OS version";
140#endif // ! TARGET_WINDOWS
141}
142
143TEST_F(TestSystemInfo, GetManufacturerName)
144{
145 EXPECT_STRCASENE("unknown", g_sysinfo.GetManufacturerName().c_str()) << "'GetManufacturerName()' must return empty string instead of 'Unknown'";
146}
147
148TEST_F(TestSystemInfo, GetModelName)
149{
150 EXPECT_STRCASENE("unknown", g_sysinfo.GetModelName().c_str()) << "'GetModelName()' must return empty string instead of 'Unknown'";
151}
152
153#ifndef TARGET_WINDOWS
154TEST_F(TestSystemInfo, IsAeroDisabled)
155{
156 EXPECT_FALSE(g_sysinfo.IsAeroDisabled()) << "'IsAeroDisabled()' must return 'false'";
157}
158#endif // ! TARGET_WINDOWS
159
160TEST_F(TestSystemInfo, IsWindowsVersion)
161{
162 EXPECT_FALSE(g_sysinfo.IsWindowsVersion(CSysInfo::WindowsVersionUnknown)) << "'IsWindowsVersion()' must return 'false' for 'WindowsVersionUnknown'";
163#ifndef TARGET_WINDOWS
164 EXPECT_FALSE(g_sysinfo.IsWindowsVersion(CSysInfo::WindowsVersionWin7)) << "'IsWindowsVersion()' must return 'false'";
165#endif // ! TARGET_WINDOWS
166}
167
168TEST_F(TestSystemInfo, IsWindowsVersionAtLeast)
169{
170 EXPECT_FALSE(g_sysinfo.IsWindowsVersionAtLeast(CSysInfo::WindowsVersionUnknown)) << "'IsWindowsVersionAtLeast()' must return 'false' for 'WindowsVersionUnknown'";
171 EXPECT_FALSE(g_sysinfo.IsWindowsVersionAtLeast(CSysInfo::WindowsVersionFuture)) << "'IsWindowsVersionAtLeast()' must return 'false' for 'WindowsVersionFuture'";
172#ifndef TARGET_WINDOWS
173 EXPECT_FALSE(g_sysinfo.IsWindowsVersion(CSysInfo::WindowsVersionWin7)) << "'IsWindowsVersionAtLeast()' must return 'false'";
174#endif // ! TARGET_WINDOWS
175}
176
177TEST_F(TestSystemInfo, GetWindowsVersion)
178{
179#ifdef TARGET_WINDOWS
180 EXPECT_NE(CSysInfo::WindowsVersionUnknown, g_sysinfo.GetWindowsVersion()) << "'GetWindowsVersion()' must not return 'WindowsVersionUnknown'";
181 EXPECT_NE(CSysInfo::WindowsVersionFuture, g_sysinfo.GetWindowsVersion()) << "'GetWindowsVersion()' must not return 'WindowsVersionFuture'";
182#else // ! TARGET_WINDOWS
183 EXPECT_EQ(CSysInfo::WindowsVersionUnknown, g_sysinfo.GetWindowsVersion()) << "'GetWindowsVersion()' must return 'WindowsVersionUnknown'";
184#endif // ! TARGET_WINDOWS
185}
186
187TEST_F(TestSystemInfo, GetKernelBitness)
188{
189 EXPECT_TRUE(g_sysinfo.GetKernelBitness() == 32 || g_sysinfo.GetKernelBitness() == 64) << "'GetKernelBitness()' must return '32' or '64', but not '" << g_sysinfo.GetKernelBitness() << "'";
190 EXPECT_LE(g_sysinfo.GetXbmcBitness(), g_sysinfo.GetKernelBitness()) << "'GetKernelBitness()' must be greater or equal to 'GetXbmcBitness()'";
191}
192
193TEST_F(TestSystemInfo, GetKernelCpuFamily)
194{
195 EXPECT_STRNE("unknown CPU family", g_sysinfo.GetKernelCpuFamily().c_str()) << "'GetKernelCpuFamily()' must not return 'unknown CPU family'";
196#if defined(__thumb__) || defined(_M_ARMT) || defined(__arm__) || defined(_M_ARM) || defined (__aarch64__)
197 EXPECT_STREQ("ARM", g_sysinfo.GetKernelCpuFamily().c_str()) << "'GetKernelCpuFamily()' must return 'ARM'";
198#else // ! ARM
199 EXPECT_EQ(g_sysinfo.GetBuildTargetCpuFamily(), g_sysinfo.GetKernelCpuFamily()) << "'GetKernelCpuFamily()' must match 'GetBuildTargetCpuFamily()'";
200#endif // ! ARM
201}
202
203TEST_F(TestSystemInfo, GetXbmcBitness)
204{
205 EXPECT_TRUE(g_sysinfo.GetXbmcBitness() == 32 || g_sysinfo.GetXbmcBitness() == 64) << "'GetXbmcBitness()' must return '32' or '64', but not '" << g_sysinfo.GetXbmcBitness() << "'";
206 EXPECT_GE(g_sysinfo.GetKernelBitness(), g_sysinfo.GetXbmcBitness()) << "'GetXbmcBitness()' must be not greater than 'GetKernelBitness()'";
207}
208
209TEST_F(TestSystemInfo, GetUserAgent)
210{
211 EXPECT_STREQ(g_sysinfo.GetAppName().c_str(), g_sysinfo.GetUserAgent().substr(0, g_sysinfo.GetAppName().size()).c_str()) << "'GetUserAgent()' string must start with app name'";
212 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find('(')) << "'GetUserAgent()' must contain brackets around second parameter";
213 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(')')) << "'GetUserAgent()' must contain brackets around second parameter";
214 EXPECT_EQ(g_sysinfo.GetUserAgent().find(' '), g_sysinfo.GetUserAgent().find(" (")) << "Second parameter in 'GetUserAgent()' string must be in brackets";
215 EXPECT_EQ(g_sysinfo.GetUserAgent().find(" (") + 1, g_sysinfo.GetUserAgent().find('(')) << "'GetUserAgent()' string must not contain any opening brackets before second parameter";
216 EXPECT_GT(g_sysinfo.GetUserAgent().find(')'), g_sysinfo.GetUserAgent().find('(')) << "'GetUserAgent()' string must not contain any closing brackets before second parameter";
217 EXPECT_EQ(g_sysinfo.GetUserAgent().find(") "), g_sysinfo.GetUserAgent().find(')')) << "'GetUserAgent()' string must not contain any closing brackets before end of second parameter";
218#if defined(TARGET_WINDOWS)
219 EXPECT_EQ(g_sysinfo.GetUserAgent().find('('), g_sysinfo.GetUserAgent().find("(Windows")) << "Second parameter in 'GetUserAgent()' string must start from `Windows`";
220 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find("Windows")) << "'GetUserAgent()' must contain 'Windows'";
221#elif defined(TARGET_DARWIN_IOS)
222 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find("like Mac OS X")) << "'GetUserAgent()' must contain ' like Mac OS X'";
223 EXPECT_TRUE(g_sysinfo.GetUserAgent().find("CPU OS ") != std::string::npos || g_sysinfo.GetUserAgent().find("CPU iPhone OS ") != std::string::npos) << "'GetUserAgent()' must contain 'CPU OS ' or 'CPU iPhone OS '";
224#elif defined(TARGET_DARWIN_TVOS)
225 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find("like Mac OS X"))
226 << "'GetUserAgent()' must contain ' like Mac OS X'";
227 EXPECT_TRUE(g_sysinfo.GetUserAgent().find("CPU TVOS ") != std::string::npos)
228 << "'GetUserAgent()' must contain 'CPU TVOS '";
229#elif defined(TARGET_DARWIN_OSX)
230 EXPECT_EQ(g_sysinfo.GetUserAgent().find('('), g_sysinfo.GetUserAgent().find("(Macintosh; ")) << "Second parameter in 'GetUserAgent()' string must start from 'Macintosh; '";
231#elif defined(TARGET_ANDROID)
232 EXPECT_EQ(g_sysinfo.GetUserAgent().find('('), g_sysinfo.GetUserAgent().find("(Linux; Android ")) << "Second parameter in 'GetUserAgent()' string must start from 'Linux; Android '";
233#elif defined(TARGET_POSIX)
234 EXPECT_EQ(g_sysinfo.GetUserAgent().find('('), g_sysinfo.GetUserAgent().find("(X11; ")) << "Second parameter in 'GetUserAgent()' string must start from 'X11; '";
235#if defined(TARGET_FREEBSD)
236 EXPECT_EQ(g_sysinfo.GetUserAgent().find('('), g_sysinfo.GetUserAgent().find("(X11; FreeBSD ")) << "Second parameter in 'GetUserAgent()' string must start from 'X11; FreeBSD '";
237#elif defined(TARGET_LINUX)
238 EXPECT_EQ(g_sysinfo.GetUserAgent().find('('), g_sysinfo.GetUserAgent().find("(X11; Linux ")) << "Second parameter in 'GetUserAgent()' string must start from 'X11; Linux '";
239#endif // defined(TARGET_LINUX)
240#endif // defined(TARGET_POSIX)
241
242#ifdef TARGET_RASPBERRY_PI
243 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(" XBMC_HW_RaspberryPi/")) << "'GetUserAgent()' must contain ' XBMC_HW_RaspberryPi/'";
244#endif // TARGET_RASPBERRY_PI
245
246 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(" App_Bitness/")) << "'GetUserAgent()' must contain ' App_Bitness/'";
247 EXPECT_NE(std::string::npos, g_sysinfo.GetUserAgent().find(" Version/")) << "'GetUserAgent()' must contain ' Version/'";
248}
249
250TEST_F(TestSystemInfo, GetBuildTargetPlatformName)
251{
252 EXPECT_EQ(std::string::npos, g_sysinfo.GetBuildTargetPlatformName().find("Unknown")) << "'GetBuildTargetPlatformName()' must not contain 'Unknown', actual value: '" << g_sysinfo.GetBuildTargetPlatformName() << "'";
253 EXPECT_EQ(std::string::npos, g_sysinfo.GetBuildTargetPlatformName().find("unknown")) << "'GetBuildTargetPlatformName()' must not contain 'unknown', actual value: '" << g_sysinfo.GetBuildTargetPlatformName() << "'";
254}
255
256TEST_F(TestSystemInfo, GetBuildTargetPlatformVersion)
257{
258 EXPECT_EQ(std::string::npos, g_sysinfo.GetBuildTargetPlatformVersion().find("Unknown")) << "'GetBuildTargetPlatformVersion()' must not contain 'Unknown', actual value: '" << g_sysinfo.GetBuildTargetPlatformVersion() << "'";
259 EXPECT_EQ(std::string::npos, g_sysinfo.GetBuildTargetPlatformVersion().find("unknown")) << "'GetBuildTargetPlatformVersion()' must not contain 'unknown', actual value: '" << g_sysinfo.GetBuildTargetPlatformVersion() << "'";
260}
261
262TEST_F(TestSystemInfo, GetBuildTargetPlatformVersionDecoded)
263{
264 EXPECT_EQ(std::string::npos, g_sysinfo.GetBuildTargetPlatformVersionDecoded().find("Unknown")) << "'GetBuildTargetPlatformVersionDecoded()' must not contain 'Unknown', actual value: '" << g_sysinfo.GetBuildTargetPlatformVersion() << "'";
265 EXPECT_EQ(std::string::npos, g_sysinfo.GetBuildTargetPlatformVersionDecoded().find("unknown")) << "'GetBuildTargetPlatformVersionDecoded()' must not contain 'unknown', actual value: '" << g_sysinfo.GetBuildTargetPlatformVersion() << "'";
266#ifdef TARGET_ANDROID
267 EXPECT_STREQ("API level ", g_sysinfo.GetBuildTargetPlatformVersionDecoded().substr(0, 10).c_str()) << "'GetBuildTargetPlatformVersionDecoded()' must start from 'API level '";
268#else
269 EXPECT_STREQ("version ", g_sysinfo.GetBuildTargetPlatformVersionDecoded().substr(0, 8).c_str()) << "'GetBuildTargetPlatformVersionDecoded()' must start from 'version'";
270#endif
271}
272
273TEST_F(TestSystemInfo, GetBuildTargetCpuFamily)
274{
275 EXPECT_STRNE("unknown CPU family", g_sysinfo.GetBuildTargetCpuFamily().c_str()) << "'GetBuildTargetCpuFamily()' must not return 'unknown CPU family'";
276#if defined(__thumb__) || defined(_M_ARMT) || defined(__arm__) || defined(_M_ARM) || defined (__aarch64__)
277 EXPECT_STREQ("ARM", g_sysinfo.GetBuildTargetCpuFamily().substr(0, 3).c_str()) << "'GetKernelCpuFamily()' string must start from 'ARM'";
278#else // ! ARM
279 EXPECT_EQ(g_sysinfo.GetKernelCpuFamily(), g_sysinfo.GetBuildTargetCpuFamily()) << "'GetBuildTargetCpuFamily()' must match 'GetKernelCpuFamily()'";
280#endif // ! ARM
281}
282
283TEST_F(TestSystemInfo, GetUsedCompilerNameAndVer)
284{
285 EXPECT_STRNE("unknown compiler", g_sysinfo.GetUsedCompilerNameAndVer().c_str()) << "'GetUsedCompilerNameAndVer()' must not return 'unknown compiler'";
286}
287
288TEST_F(TestSystemInfo, GetDiskSpace)
289{
290 int iTotal, iTotalFree, iTotalUsed, iPercentFree, iPercentUsed;
291
292 iTotal = iTotalFree = iTotalUsed = iPercentFree = iPercentUsed = 0;
293 EXPECT_TRUE(g_sysinfo.GetDiskSpace("*", iTotal, iTotalFree, iTotalUsed, iPercentFree, iPercentUsed)) << "'GetDiskSpace()' return 'false' for disk '*'";
294 EXPECT_NE(0, iTotal) << "'GetDiskSpace()' return zero total space for disk '*'";
295 EXPECT_EQ(iTotal, iTotalFree + iTotalUsed) << "'GetDiskSpace()' return 'TotalFree + TotalUsed' not equal to 'Total' for disk '*'";
296 EXPECT_EQ(100, iPercentFree + iPercentUsed) << "'GetDiskSpace()' return 'PercentFree + PercentUsed' not equal to '100' for disk '*'";
297
298 iTotal = iTotalFree = iTotalUsed = iPercentFree = iPercentUsed = 0;
299 EXPECT_TRUE(g_sysinfo.GetDiskSpace("", iTotal, iTotalFree, iTotalUsed, iPercentFree, iPercentUsed)) << "'GetDiskSpace()' return 'false' for disk ''";
300 EXPECT_NE(0, iTotal) << "'GetDiskSpace()' return zero total space for disk ''";
301 EXPECT_EQ(iTotal, iTotalFree + iTotalUsed) << "'GetDiskSpace()' return 'TotalFree + TotalUsed' not equal to 'Total' for disk ''";
302 EXPECT_EQ(100, iPercentFree + iPercentUsed) << "'GetDiskSpace()' return 'PercentFree + PercentUsed' not equal to '100' for disk ''";
303
304#ifdef TARGET_WINDOWS
305 using KODI::PLATFORM::WINDOWS::FromW;
306 wchar_t sysDrive[300];
307 DWORD res = GetEnvironmentVariableW(L"SystemDrive", sysDrive, sizeof(sysDrive) / sizeof(wchar_t));
308 std::string sysDriveLtr;
309 if (res != 0 && res <= sizeof(sysDrive) / sizeof(wchar_t))
310 sysDriveLtr.assign(FromW(sysDrive), 0, 1);
311 else
312 sysDriveLtr = "C"; // fallback
313
314 iTotal = iTotalFree = iTotalUsed = iPercentFree = iPercentUsed = 0;
315 EXPECT_TRUE(g_sysinfo.GetDiskSpace(sysDriveLtr, iTotal, iTotalFree, iTotalUsed, iPercentFree, iPercentUsed)) << "'GetDiskSpace()' return 'false' for disk '" << sysDriveLtr << ":'";
316 EXPECT_NE(0, iTotal) << "'GetDiskSpace()' return zero total space for disk '" << sysDriveLtr << ":'";
317 EXPECT_EQ(iTotal, iTotalFree + iTotalUsed) << "'GetDiskSpace()' return 'TotalFree + TotalUsed' not equal to 'Total' for disk '" << sysDriveLtr << ":'";
318 EXPECT_EQ(100, iPercentFree + iPercentUsed) << "'GetDiskSpace()' return 'PercentFree + PercentUsed' not equal to '100' for disk '" << sysDriveLtr << ":'";
319#elif defined(TARGET_POSIX)
320 iTotal = iTotalFree = iTotalUsed = iPercentFree = iPercentUsed = 0;
321 EXPECT_TRUE(g_sysinfo.GetDiskSpace("/", iTotal, iTotalFree, iTotalUsed, iPercentFree, iPercentUsed)) << "'GetDiskSpace()' return 'false' for directory '/'";
322 EXPECT_NE(0, iTotal) << "'GetDiskSpace()' return zero total space for directory '/'";
323 EXPECT_EQ(iTotal, iTotalFree + iTotalUsed) << "'GetDiskSpace()' return 'TotalFree + TotalUsed' not equal to 'Total' for directory '/'";
324 EXPECT_EQ(100, iPercentFree + iPercentUsed) << "'GetDiskSpace()' return 'PercentFree + PercentUsed' not equal to '100' for directory '/'";
325#endif
326}
diff --git a/xbmc/utils/test/TestURIUtils.cpp b/xbmc/utils/test/TestURIUtils.cpp
new file mode 100644
index 0000000..7122fe9
--- /dev/null
+++ b/xbmc/utils/test/TestURIUtils.cpp
@@ -0,0 +1,585 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "ServiceBroker.h"
10#include "URL.h"
11#include "filesystem/MultiPathDirectory.h"
12#include "settings/AdvancedSettings.h"
13#include "settings/SettingsComponent.h"
14#include "utils/URIUtils.h"
15
16#include <utility>
17
18#include <gtest/gtest.h>
19
20using namespace XFILE;
21
22class TestURIUtils : public testing::Test
23{
24protected:
25 TestURIUtils() = default;
26 ~TestURIUtils() override
27 {
28 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_pathSubstitutions.clear();
29 }
30};
31
32TEST_F(TestURIUtils, PathHasParent)
33{
34 EXPECT_TRUE(URIUtils::PathHasParent("/path/to/movie.avi", "/path/to/"));
35 EXPECT_FALSE(URIUtils::PathHasParent("/path/to/movie.avi", "/path/2/"));
36}
37
38TEST_F(TestURIUtils, GetDirectory)
39{
40 EXPECT_STREQ("/path/to/", URIUtils::GetDirectory("/path/to/movie.avi").c_str());
41 EXPECT_STREQ("/path/to/", URIUtils::GetDirectory("/path/to/").c_str());
42 EXPECT_STREQ("/path/to/|option=foo", URIUtils::GetDirectory("/path/to/movie.avi|option=foo").c_str());
43 EXPECT_STREQ("/path/to/|option=foo", URIUtils::GetDirectory("/path/to/|option=foo").c_str());
44 EXPECT_STREQ("", URIUtils::GetDirectory("movie.avi").c_str());
45 EXPECT_STREQ("", URIUtils::GetDirectory("movie.avi|option=foo").c_str());
46 EXPECT_STREQ("", URIUtils::GetDirectory("").c_str());
47
48 // Make sure it works when assigning to the same str as the reference parameter
49 std::string var = "/path/to/movie.avi|option=foo";
50 var = URIUtils::GetDirectory(var);
51 EXPECT_STREQ("/path/to/|option=foo", var.c_str());
52}
53
54TEST_F(TestURIUtils, GetExtension)
55{
56 EXPECT_STREQ(".avi",
57 URIUtils::GetExtension("/path/to/movie.avi").c_str());
58}
59
60TEST_F(TestURIUtils, HasExtension)
61{
62 EXPECT_TRUE (URIUtils::HasExtension("/path/to/movie.AvI"));
63 EXPECT_FALSE(URIUtils::HasExtension("/path/to/movie"));
64 EXPECT_FALSE(URIUtils::HasExtension("/path/.to/movie"));
65 EXPECT_FALSE(URIUtils::HasExtension(""));
66
67 EXPECT_TRUE (URIUtils::HasExtension("/path/to/movie.AvI", ".avi"));
68 EXPECT_FALSE(URIUtils::HasExtension("/path/to/movie.AvI", ".mkv"));
69 EXPECT_FALSE(URIUtils::HasExtension("/path/.avi/movie", ".avi"));
70 EXPECT_FALSE(URIUtils::HasExtension("", ".avi"));
71
72 EXPECT_TRUE (URIUtils::HasExtension("/path/movie.AvI", ".avi|.mkv|.mp4"));
73 EXPECT_TRUE (URIUtils::HasExtension("/path/movie.AvI", ".mkv|.avi|.mp4"));
74 EXPECT_FALSE(URIUtils::HasExtension("/path/movie.AvI", ".mpg|.mkv|.mp4"));
75 EXPECT_FALSE(URIUtils::HasExtension("/path.mkv/movie.AvI", ".mpg|.mkv|.mp4"));
76 EXPECT_FALSE(URIUtils::HasExtension("", ".avi|.mkv|.mp4"));
77}
78
79TEST_F(TestURIUtils, GetFileName)
80{
81 EXPECT_STREQ("movie.avi",
82 URIUtils::GetFileName("/path/to/movie.avi").c_str());
83}
84
85TEST_F(TestURIUtils, RemoveExtension)
86{
87 std::string ref, var;
88
89 /* NOTE: CSettings need to be set to find other extensions. */
90 ref = "/path/to/file";
91 var = "/path/to/file.xml";
92 URIUtils::RemoveExtension(var);
93 EXPECT_STREQ(ref.c_str(), var.c_str());
94}
95
96TEST_F(TestURIUtils, ReplaceExtension)
97{
98 std::string ref, var;
99
100 ref = "/path/to/file.xsd";
101 var = URIUtils::ReplaceExtension("/path/to/file.xml", ".xsd");
102 EXPECT_STREQ(ref.c_str(), var.c_str());
103}
104
105TEST_F(TestURIUtils, Split)
106{
107 std::string refpath, reffile, varpath, varfile;
108
109 refpath = "/path/to/";
110 reffile = "movie.avi";
111 URIUtils::Split("/path/to/movie.avi", varpath, varfile);
112 EXPECT_STREQ(refpath.c_str(), varpath.c_str());
113 EXPECT_STREQ(reffile.c_str(), varfile.c_str());
114
115 std::string varpathOptional, varfileOptional;
116
117 refpath = "/path/to/";
118 reffile = "movie?movie.avi";
119 URIUtils::Split("/path/to/movie?movie.avi", varpathOptional, varfileOptional);
120 EXPECT_STREQ(refpath.c_str(), varpathOptional.c_str());
121 EXPECT_STREQ(reffile.c_str(), varfileOptional.c_str());
122
123 refpath = "file:///path/to/";
124 reffile = "movie.avi";
125 URIUtils::Split("file:///path/to/movie.avi?showinfo=true", varpathOptional, varfileOptional);
126 EXPECT_STREQ(refpath.c_str(), varpathOptional.c_str());
127 EXPECT_STREQ(reffile.c_str(), varfileOptional.c_str());
128}
129
130TEST_F(TestURIUtils, SplitPath)
131{
132 std::vector<std::string> strarray;
133
134 strarray = URIUtils::SplitPath("http://www.test.com/path/to/movie.avi");
135
136 EXPECT_STREQ("http://www.test.com/", strarray.at(0).c_str());
137 EXPECT_STREQ("path", strarray.at(1).c_str());
138 EXPECT_STREQ("to", strarray.at(2).c_str());
139 EXPECT_STREQ("movie.avi", strarray.at(3).c_str());
140}
141
142TEST_F(TestURIUtils, SplitPathLocal)
143{
144#ifndef TARGET_LINUX
145 const char *path = "C:\\path\\to\\movie.avi";
146#else
147 const char *path = "/path/to/movie.avi";
148#endif
149 std::vector<std::string> strarray;
150
151 strarray = URIUtils::SplitPath(path);
152
153#ifndef TARGET_LINUX
154 EXPECT_STREQ("C:", strarray.at(0).c_str());
155#else
156 EXPECT_STREQ("", strarray.at(0).c_str());
157#endif
158 EXPECT_STREQ("path", strarray.at(1).c_str());
159 EXPECT_STREQ("to", strarray.at(2).c_str());
160 EXPECT_STREQ("movie.avi", strarray.at(3).c_str());
161}
162
163TEST_F(TestURIUtils, GetCommonPath)
164{
165 std::string ref, var;
166
167 ref = "/path/";
168 var = "/path/2/movie.avi";
169 URIUtils::GetCommonPath(var, "/path/to/movie.avi");
170 EXPECT_STREQ(ref.c_str(), var.c_str());
171}
172
173TEST_F(TestURIUtils, GetParentPath)
174{
175 std::string ref, var;
176
177 ref = "/path/to/";
178 var = URIUtils::GetParentPath("/path/to/movie.avi");
179 EXPECT_STREQ(ref.c_str(), var.c_str());
180
181 var.clear();
182 EXPECT_TRUE(URIUtils::GetParentPath("/path/to/movie.avi", var));
183 EXPECT_STREQ(ref.c_str(), var.c_str());
184}
185
186TEST_F(TestURIUtils, SubstitutePath)
187{
188 std::string from, to, ref, var;
189
190 from = "C:\\My Videos";
191 to = "https://myserver/some%20other%20path";
192 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_pathSubstitutions.push_back(std::make_pair(from, to));
193
194 from = "/this/path1";
195 to = "/some/other/path2";
196 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_pathSubstitutions.push_back(std::make_pair(from, to));
197
198 from = "davs://otherserver/my%20music%20path";
199 to = "D:\\Local Music\\MP3 Collection";
200 CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_pathSubstitutions.push_back(std::make_pair(from, to));
201
202 ref = "https://myserver/some%20other%20path/sub%20dir/movie%20name.avi";
203 var = URIUtils::SubstitutePath("C:\\My Videos\\sub dir\\movie name.avi");
204 EXPECT_STREQ(ref.c_str(), var.c_str());
205
206 ref = "C:\\My Videos\\sub dir\\movie name.avi";
207 var = URIUtils::SubstitutePath("https://myserver/some%20other%20path/sub%20dir/movie%20name.avi", true);
208 EXPECT_STREQ(ref.c_str(), var.c_str());
209
210 ref = "D:\\Local Music\\MP3 Collection\\Phil Collins\\Some CD\\01 - Two Hearts.mp3";
211 var = URIUtils::SubstitutePath("davs://otherserver/my%20music%20path/Phil%20Collins/Some%20CD/01%20-%20Two%20Hearts.mp3");
212 EXPECT_STREQ(ref.c_str(), var.c_str());
213
214 ref = "davs://otherserver/my%20music%20path/Phil%20Collins/Some%20CD/01%20-%20Two%20Hearts.mp3";
215 var = URIUtils::SubstitutePath("D:\\Local Music\\MP3 Collection\\Phil Collins\\Some CD\\01 - Two Hearts.mp3", true);
216 EXPECT_STREQ(ref.c_str(), var.c_str());
217
218 ref = "/some/other/path2/to/movie.avi";
219 var = URIUtils::SubstitutePath("/this/path1/to/movie.avi");
220 EXPECT_STREQ(ref.c_str(), var.c_str());
221
222 ref = "/this/path1/to/movie.avi";
223 var = URIUtils::SubstitutePath("/some/other/path2/to/movie.avi", true);
224 EXPECT_STREQ(ref.c_str(), var.c_str());
225
226 ref = "/no/translation path/";
227 var = URIUtils::SubstitutePath(ref);
228 EXPECT_STREQ(ref.c_str(), var.c_str());
229
230 ref = "/no/translation path/";
231 var = URIUtils::SubstitutePath(ref, true);
232 EXPECT_STREQ(ref.c_str(), var.c_str());
233
234 ref = "c:\\no\\translation path";
235 var = URIUtils::SubstitutePath(ref);
236 EXPECT_STREQ(ref.c_str(), var.c_str());
237
238 ref = "c:\\no\\translation path";
239 var = URIUtils::SubstitutePath(ref, true);
240 EXPECT_STREQ(ref.c_str(), var.c_str());
241}
242
243TEST_F(TestURIUtils, IsAddonsPath)
244{
245 EXPECT_TRUE(URIUtils::IsAddonsPath("addons://path/to/addons"));
246}
247
248TEST_F(TestURIUtils, IsSourcesPath)
249{
250 EXPECT_TRUE(URIUtils::IsSourcesPath("sources://path/to/sources"));
251}
252
253TEST_F(TestURIUtils, IsCDDA)
254{
255 EXPECT_TRUE(URIUtils::IsCDDA("cdda://path/to/cdda"));
256}
257
258TEST_F(TestURIUtils, IsDOSPath)
259{
260 EXPECT_TRUE(URIUtils::IsDOSPath("C://path/to/dosfile"));
261}
262
263TEST_F(TestURIUtils, IsDVD)
264{
265 EXPECT_TRUE(URIUtils::IsDVD("dvd://path/in/video_ts.ifo"));
266#if defined(TARGET_WINDOWS)
267 EXPECT_TRUE(URIUtils::IsDVD("dvd://path/in/file"));
268#else
269 EXPECT_TRUE(URIUtils::IsDVD("iso9660://path/in/video_ts.ifo"));
270 EXPECT_TRUE(URIUtils::IsDVD("udf://path/in/video_ts.ifo"));
271 EXPECT_TRUE(URIUtils::IsDVD("dvd://1"));
272#endif
273}
274
275TEST_F(TestURIUtils, IsFTP)
276{
277 EXPECT_TRUE(URIUtils::IsFTP("ftp://path/in/ftp"));
278}
279
280TEST_F(TestURIUtils, IsHD)
281{
282 EXPECT_TRUE(URIUtils::IsHD("/path/to/file"));
283 EXPECT_TRUE(URIUtils::IsHD("file:///path/to/file"));
284 EXPECT_TRUE(URIUtils::IsHD("special://path/to/file"));
285 EXPECT_TRUE(URIUtils::IsHD("stack://path/to/file"));
286 EXPECT_TRUE(URIUtils::IsHD("zip://path/to/file"));
287}
288
289TEST_F(TestURIUtils, IsInArchive)
290{
291 EXPECT_TRUE(URIUtils::IsInArchive("zip://path/to/file"));
292}
293
294TEST_F(TestURIUtils, IsInRAR)
295{
296 EXPECT_TRUE(URIUtils::IsInRAR("rar://path/to/file"));
297}
298
299TEST_F(TestURIUtils, IsInternetStream)
300{
301 CURL url1("http://path/to/file");
302 CURL url2("https://path/to/file");
303 EXPECT_TRUE(URIUtils::IsInternetStream(url1));
304 EXPECT_TRUE(URIUtils::IsInternetStream(url2));
305}
306
307TEST_F(TestURIUtils, IsInZIP)
308{
309 EXPECT_TRUE(URIUtils::IsInZIP("zip://path/to/file"));
310}
311
312TEST_F(TestURIUtils, IsISO9660)
313{
314 EXPECT_TRUE(URIUtils::IsISO9660("iso9660://path/to/file"));
315}
316
317TEST_F(TestURIUtils, IsLiveTV)
318{
319 EXPECT_TRUE(URIUtils::IsLiveTV("whatever://path/to/file.pvr"));
320}
321
322TEST_F(TestURIUtils, IsMultiPath)
323{
324 EXPECT_TRUE(URIUtils::IsMultiPath("multipath://path/to/file"));
325}
326
327TEST_F(TestURIUtils, IsMusicDb)
328{
329 EXPECT_TRUE(URIUtils::IsMusicDb("musicdb://path/to/file"));
330}
331
332TEST_F(TestURIUtils, IsNfs)
333{
334 EXPECT_TRUE(URIUtils::IsNfs("nfs://path/to/file"));
335 EXPECT_TRUE(URIUtils::IsNfs("stack://nfs://path/to/file"));
336}
337
338TEST_F(TestURIUtils, IsOnDVD)
339{
340 EXPECT_TRUE(URIUtils::IsOnDVD("dvd://path/to/file"));
341 EXPECT_TRUE(URIUtils::IsOnDVD("udf://path/to/file"));
342 EXPECT_TRUE(URIUtils::IsOnDVD("iso9660://path/to/file"));
343 EXPECT_TRUE(URIUtils::IsOnDVD("cdda://path/to/file"));
344}
345
346TEST_F(TestURIUtils, IsOnLAN)
347{
348 std::vector<std::string> multiVec;
349 multiVec.emplace_back("smb://path/to/file");
350 EXPECT_TRUE(URIUtils::IsOnLAN(CMultiPathDirectory::ConstructMultiPath(multiVec)));
351 EXPECT_TRUE(URIUtils::IsOnLAN("stack://smb://path/to/file"));
352 EXPECT_TRUE(URIUtils::IsOnLAN("smb://path/to/file"));
353 EXPECT_FALSE(URIUtils::IsOnLAN("plugin://path/to/file"));
354 EXPECT_TRUE(URIUtils::IsOnLAN("upnp://path/to/file"));
355}
356
357TEST_F(TestURIUtils, IsPlugin)
358{
359 EXPECT_TRUE(URIUtils::IsPlugin("plugin://path/to/file"));
360}
361
362TEST_F(TestURIUtils, IsScript)
363{
364 EXPECT_TRUE(URIUtils::IsScript("script://path/to/file"));
365}
366
367TEST_F(TestURIUtils, IsRAR)
368{
369 EXPECT_TRUE(URIUtils::IsRAR("/path/to/rarfile.rar"));
370 EXPECT_TRUE(URIUtils::IsRAR("/path/to/rarfile.cbr"));
371 EXPECT_FALSE(URIUtils::IsRAR("/path/to/file"));
372 EXPECT_FALSE(URIUtils::IsRAR("rar://path/to/file"));
373}
374
375TEST_F(TestURIUtils, IsRemote)
376{
377 EXPECT_TRUE(URIUtils::IsRemote("http://path/to/file"));
378 EXPECT_TRUE(URIUtils::IsRemote("https://path/to/file"));
379 EXPECT_FALSE(URIUtils::IsRemote("addons://user/"));
380 EXPECT_FALSE(URIUtils::IsRemote("sources://video/"));
381 EXPECT_FALSE(URIUtils::IsRemote("videodb://movies/titles"));
382 EXPECT_FALSE(URIUtils::IsRemote("musicdb://genres/"));
383 EXPECT_FALSE(URIUtils::IsRemote("library://video/"));
384 EXPECT_FALSE(URIUtils::IsRemote("androidapp://app"));
385 EXPECT_FALSE(URIUtils::IsRemote("plugin://plugin.video.id"));
386}
387
388TEST_F(TestURIUtils, IsSmb)
389{
390 EXPECT_TRUE(URIUtils::IsSmb("smb://path/to/file"));
391 EXPECT_TRUE(URIUtils::IsSmb("stack://smb://path/to/file"));
392}
393
394TEST_F(TestURIUtils, IsSpecial)
395{
396 EXPECT_TRUE(URIUtils::IsSpecial("special://path/to/file"));
397 EXPECT_TRUE(URIUtils::IsSpecial("stack://special://path/to/file"));
398}
399
400TEST_F(TestURIUtils, IsStack)
401{
402 EXPECT_TRUE(URIUtils::IsStack("stack://path/to/file"));
403}
404
405TEST_F(TestURIUtils, IsUPnP)
406{
407 EXPECT_TRUE(URIUtils::IsUPnP("upnp://path/to/file"));
408}
409
410TEST_F(TestURIUtils, IsURL)
411{
412 EXPECT_TRUE(URIUtils::IsURL("someprotocol://path/to/file"));
413 EXPECT_FALSE(URIUtils::IsURL("/path/to/file"));
414}
415
416TEST_F(TestURIUtils, IsVideoDb)
417{
418 EXPECT_TRUE(URIUtils::IsVideoDb("videodb://path/to/file"));
419}
420
421TEST_F(TestURIUtils, IsZIP)
422{
423 EXPECT_TRUE(URIUtils::IsZIP("/path/to/zipfile.zip"));
424 EXPECT_TRUE(URIUtils::IsZIP("/path/to/zipfile.cbz"));
425 EXPECT_FALSE(URIUtils::IsZIP("/path/to/file"));
426 EXPECT_FALSE(URIUtils::IsZIP("zip://path/to/file"));
427}
428
429TEST_F(TestURIUtils, IsBluray)
430{
431 EXPECT_TRUE(URIUtils::IsBluray("bluray://path/to/file"));
432}
433
434TEST_F(TestURIUtils, AddSlashAtEnd)
435{
436 std::string ref, var;
437
438 ref = "bluray://path/to/file/";
439 var = "bluray://path/to/file/";
440 URIUtils::AddSlashAtEnd(var);
441 EXPECT_STREQ(ref.c_str(), var.c_str());
442}
443
444TEST_F(TestURIUtils, HasSlashAtEnd)
445{
446 EXPECT_TRUE(URIUtils::HasSlashAtEnd("bluray://path/to/file/"));
447 EXPECT_FALSE(URIUtils::HasSlashAtEnd("bluray://path/to/file"));
448}
449
450TEST_F(TestURIUtils, RemoveSlashAtEnd)
451{
452 std::string ref, var;
453
454 ref = "bluray://path/to/file";
455 var = "bluray://path/to/file/";
456 URIUtils::RemoveSlashAtEnd(var);
457 EXPECT_STREQ(ref.c_str(), var.c_str());
458}
459
460TEST_F(TestURIUtils, CreateArchivePath)
461{
462 std::string ref, var;
463
464 ref = "zip://%2fpath%2fto%2f/file";
465 var = URIUtils::CreateArchivePath("zip", CURL("/path/to/"), "file").Get();
466 EXPECT_STREQ(ref.c_str(), var.c_str());
467}
468
469TEST_F(TestURIUtils, AddFileToFolder)
470{
471 std::string ref = "/path/to/file";
472 std::string var = URIUtils::AddFileToFolder("/path/to", "file");
473 EXPECT_STREQ(ref.c_str(), var.c_str());
474
475 ref = "/path/to/file/and/more";
476 var = URIUtils::AddFileToFolder("/path", "to", "file", "and", "more");
477 EXPECT_STREQ(ref.c_str(), var.c_str());
478}
479
480TEST_F(TestURIUtils, HasParentInHostname)
481{
482 EXPECT_TRUE(URIUtils::HasParentInHostname(CURL("zip://")));
483 EXPECT_TRUE(URIUtils::HasParentInHostname(CURL("bluray://")));
484}
485
486TEST_F(TestURIUtils, HasEncodedHostname)
487{
488 EXPECT_TRUE(URIUtils::HasEncodedHostname(CURL("zip://")));
489 EXPECT_TRUE(URIUtils::HasEncodedHostname(CURL("bluray://")));
490 EXPECT_TRUE(URIUtils::HasEncodedHostname(CURL("musicsearch://")));
491}
492
493TEST_F(TestURIUtils, HasEncodedFilename)
494{
495 EXPECT_TRUE(URIUtils::HasEncodedFilename(CURL("shout://")));
496 EXPECT_TRUE(URIUtils::HasEncodedFilename(CURL("dav://")));
497 EXPECT_TRUE(URIUtils::HasEncodedFilename(CURL("rss://")));
498 EXPECT_TRUE(URIUtils::HasEncodedFilename(CURL("davs://")));
499}
500
501TEST_F(TestURIUtils, GetRealPath)
502{
503 std::string ref;
504
505 ref = "/path/to/file/";
506 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath(ref).c_str());
507
508 ref = "path/to/file";
509 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("../path/to/file").c_str());
510 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("./path/to/file").c_str());
511
512 ref = "/path/to/file";
513 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath(ref).c_str());
514 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("/path/to/./file").c_str());
515 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("/./path/to/./file").c_str());
516 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("/path/to/some/../file").c_str());
517 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("/../path/to/some/../file").c_str());
518
519 ref = "/path/to";
520 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("/path/to/some/../file/..").c_str());
521
522#ifdef TARGET_WINDOWS
523 ref = "\\\\path\\to\\file\\";
524 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath(ref).c_str());
525
526 ref = "path\\to\\file";
527 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("..\\path\\to\\file").c_str());
528 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath(".\\path\\to\\file").c_str());
529
530 ref = "\\\\path\\to\\file";
531 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath(ref).c_str());
532 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("\\\\path\\to\\.\\file").c_str());
533 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("\\\\.\\path/to\\.\\file").c_str());
534 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("\\\\path\\to\\some\\..\\file").c_str());
535 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("\\\\..\\path\\to\\some\\..\\file").c_str());
536
537 ref = "\\\\path\\to";
538 EXPECT_STREQ(ref.c_str(), URIUtils::GetRealPath("\\\\path\\to\\some\\..\\file\\..").c_str());
539#endif
540
541 // test rar/zip paths
542 ref = "zip://%2fpath%2fto%2fzip/subpath/to/file";
543 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath(ref).c_str());
544
545 // test rar/zip paths
546 ref = "zip://%2fpath%2fto%2fzip/subpath/to/file";
547 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://%2fpath%2fto%2fzip/../subpath/to/file").c_str());
548 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://%2fpath%2fto%2fzip/./subpath/to/file").c_str());
549 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://%2fpath%2fto%2fzip/subpath/to/./file").c_str());
550 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://%2fpath%2fto%2fzip/subpath/to/some/../file").c_str());
551
552 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://%2fpath%2fto%2f.%2fzip/subpath/to/file").c_str());
553 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://%2fpath%2fto%2fsome%2f..%2fzip/subpath/to/file").c_str());
554
555 // test zip/zip path
556 ref ="zip://zip%3a%2f%2f%252Fpath%252Fto%252Fzip%2fpath%2fto%2fzip/subpath/to/file";
557 EXPECT_STRCASEEQ(ref.c_str(), URIUtils::GetRealPath("zip://zip%3a%2f%2f%252Fpath%252Fto%252Fsome%252F..%252Fzip%2fpath%2fto%2fsome%2f..%2fzip/subpath/to/some/../file").c_str());
558}
559
560TEST_F(TestURIUtils, UpdateUrlEncoding)
561{
562 std::string oldUrl = "stack://zip://%2fpath%2fto%2farchive%2fsome%2darchive%2dfile%2eCD1%2ezip/video.avi , zip://%2fpath%2fto%2farchive%2fsome%2darchive%2dfile%2eCD2%2ezip/video.avi";
563 std::string newUrl = "stack://zip://%2fpath%2fto%2farchive%2fsome-archive-file.CD1.zip/video.avi , zip://%2fpath%2fto%2farchive%2fsome-archive-file.CD2.zip/video.avi";
564
565 EXPECT_TRUE(URIUtils::UpdateUrlEncoding(oldUrl));
566 EXPECT_STRCASEEQ(newUrl.c_str(), oldUrl.c_str());
567
568 oldUrl = "zip://%2fpath%2fto%2farchive%2fsome%2darchive%2efile%2ezip/video.avi";
569 newUrl = "zip://%2fpath%2fto%2farchive%2fsome-archive.file.zip/video.avi";
570
571 EXPECT_TRUE(URIUtils::UpdateUrlEncoding(oldUrl));
572 EXPECT_STRCASEEQ(newUrl.c_str(), oldUrl.c_str());
573
574 oldUrl = "/path/to/some/long%2dnamed%2efile";
575 newUrl = "/path/to/some/long%2dnamed%2efile";
576
577 EXPECT_FALSE(URIUtils::UpdateUrlEncoding(oldUrl));
578 EXPECT_STRCASEEQ(newUrl.c_str(), oldUrl.c_str());
579
580 oldUrl = "/path/to/some/long-named.file";
581 newUrl = "/path/to/some/long-named.file";
582
583 EXPECT_FALSE(URIUtils::UpdateUrlEncoding(oldUrl));
584 EXPECT_STRCASEEQ(newUrl.c_str(), oldUrl.c_str());
585}
diff --git a/xbmc/utils/test/TestUrlOptions.cpp b/xbmc/utils/test/TestUrlOptions.cpp
new file mode 100644
index 0000000..f684fe5
--- /dev/null
+++ b/xbmc/utils/test/TestUrlOptions.cpp
@@ -0,0 +1,193 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/UrlOptions.h"
10#include "utils/Variant.h"
11
12#include <gtest/gtest.h>
13
14TEST(TestUrlOptions, Clear)
15{
16 const char *key = "foo";
17
18 CUrlOptions urlOptions;
19 urlOptions.AddOption(key, "bar");
20 EXPECT_TRUE(urlOptions.HasOption(key));
21
22 urlOptions.Clear();
23 EXPECT_FALSE(urlOptions.HasOption(key));
24}
25
26TEST(TestUrlOptions, AddOption)
27{
28 const char *keyChar = "char";
29 const char *keyString = "string";
30 const char *keyEmpty = "empty";
31 const char *keyInt = "int";
32 const char *keyFloat = "float";
33 const char *keyDouble = "double";
34 const char *keyBool = "bool";
35
36 const char *valueChar = "valueChar";
37 const std::string valueString = "valueString";
38 const char *valueEmpty = "";
39 int valueInt = 1;
40 float valueFloat = 1.0f;
41 double valueDouble = 1.0;
42 bool valueBool = true;
43
44 CVariant variantValue;
45
46 CUrlOptions urlOptions;
47 urlOptions.AddOption(keyChar, valueChar);
48 {
49 CVariant variantValue;
50 EXPECT_TRUE(urlOptions.GetOption(keyChar, variantValue));
51 EXPECT_TRUE(variantValue.isString());
52 EXPECT_STREQ(valueChar, variantValue.asString().c_str());
53 }
54
55 urlOptions.AddOption(keyString, valueString);
56 {
57 CVariant variantValue;
58 EXPECT_TRUE(urlOptions.GetOption(keyString, variantValue));
59 EXPECT_TRUE(variantValue.isString());
60 EXPECT_STREQ(valueString.c_str(), variantValue.asString().c_str());
61 }
62
63 urlOptions.AddOption(keyEmpty, valueEmpty);
64 {
65 CVariant variantValue;
66 EXPECT_TRUE(urlOptions.GetOption(keyEmpty, variantValue));
67 EXPECT_TRUE(variantValue.isString());
68 EXPECT_STREQ(valueEmpty, variantValue.asString().c_str());
69 }
70
71 urlOptions.AddOption(keyInt, valueInt);
72 {
73 CVariant variantValue;
74 EXPECT_TRUE(urlOptions.GetOption(keyInt, variantValue));
75 EXPECT_TRUE(variantValue.isInteger());
76 EXPECT_EQ(valueInt, (int)variantValue.asInteger());
77 }
78
79 urlOptions.AddOption(keyFloat, valueFloat);
80 {
81 CVariant variantValue;
82 EXPECT_TRUE(urlOptions.GetOption(keyFloat, variantValue));
83 EXPECT_TRUE(variantValue.isDouble());
84 EXPECT_EQ(valueFloat, variantValue.asFloat());
85 }
86
87 urlOptions.AddOption(keyDouble, valueDouble);
88 {
89 CVariant variantValue;
90 EXPECT_TRUE(urlOptions.GetOption(keyDouble, variantValue));
91 EXPECT_TRUE(variantValue.isDouble());
92 EXPECT_EQ(valueDouble, variantValue.asDouble());
93 }
94
95 urlOptions.AddOption(keyBool, valueBool);
96 {
97 CVariant variantValue;
98 EXPECT_TRUE(urlOptions.GetOption(keyBool, variantValue));
99 EXPECT_TRUE(variantValue.isBoolean());
100 EXPECT_EQ(valueBool, variantValue.asBoolean());
101 }
102}
103
104TEST(TestUrlOptions, AddOptions)
105{
106 std::string ref = "foo=bar&key=value";
107
108 CUrlOptions urlOptions(ref);
109 {
110 CVariant value;
111 EXPECT_TRUE(urlOptions.GetOption("foo", value));
112 EXPECT_TRUE(value.isString());
113 EXPECT_STREQ("bar", value.asString().c_str());
114 }
115 {
116 CVariant value;
117 EXPECT_TRUE(urlOptions.GetOption("key", value));
118 EXPECT_TRUE(value.isString());
119 EXPECT_STREQ("value", value.asString().c_str());
120 }
121
122 ref = "foo=bar&key";
123 urlOptions.Clear();
124 urlOptions.AddOptions(ref);
125 {
126 CVariant value;
127 EXPECT_TRUE(urlOptions.GetOption("foo", value));
128 EXPECT_TRUE(value.isString());
129 EXPECT_STREQ("bar", value.asString().c_str());
130 }
131 {
132 CVariant value;
133 EXPECT_TRUE(urlOptions.GetOption("key", value));
134 EXPECT_TRUE(value.isString());
135 EXPECT_TRUE(value.empty());
136 }
137}
138
139TEST(TestUrlOptions, RemoveOption)
140{
141 const char *key = "foo";
142
143 CUrlOptions urlOptions;
144 urlOptions.AddOption(key, "bar");
145 EXPECT_TRUE(urlOptions.HasOption(key));
146
147 urlOptions.RemoveOption(key);
148 EXPECT_FALSE(urlOptions.HasOption(key));
149}
150
151TEST(TestUrlOptions, HasOption)
152{
153 const char *key = "foo";
154
155 CUrlOptions urlOptions;
156 urlOptions.AddOption(key, "bar");
157 EXPECT_TRUE(urlOptions.HasOption(key));
158 EXPECT_FALSE(urlOptions.HasOption("bar"));
159}
160
161TEST(TestUrlOptions, GetOptions)
162{
163 const char *key1 = "foo";
164 const char *key2 = "key";
165 const char *value1 = "bar";
166 const char *value2 = "value";
167
168 CUrlOptions urlOptions;
169 urlOptions.AddOption(key1, value1);
170 urlOptions.AddOption(key2, value2);
171 const CUrlOptions::UrlOptions &options = urlOptions.GetOptions();
172 EXPECT_FALSE(options.empty());
173 EXPECT_EQ(2U, options.size());
174
175 CUrlOptions::UrlOptions::const_iterator it1 = options.find(key1);
176 EXPECT_TRUE(it1 != options.end());
177 CUrlOptions::UrlOptions::const_iterator it2 = options.find(key2);
178 EXPECT_TRUE(it2 != options.end());
179 EXPECT_FALSE(options.find("wrong") != options.end());
180 EXPECT_TRUE(it1->second.isString());
181 EXPECT_TRUE(it2->second.isString());
182 EXPECT_STREQ(value1, it1->second.asString().c_str());
183 EXPECT_STREQ(value2, it2->second.asString().c_str());
184}
185
186TEST(TestUrlOptions, GetOptionsString)
187{
188 const char *ref = "foo=bar&key";
189
190 CUrlOptions urlOptions(ref);
191 std::string value = urlOptions.GetOptionsString();
192 EXPECT_STREQ(ref, value.c_str());
193}
diff --git a/xbmc/utils/test/TestVariant.cpp b/xbmc/utils/test/TestVariant.cpp
new file mode 100644
index 0000000..3c96cd0
--- /dev/null
+++ b/xbmc/utils/test/TestVariant.cpp
@@ -0,0 +1,334 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/Variant.h"
10
11#include <gtest/gtest.h>
12
13TEST(TestVariant, VariantTypeInteger)
14{
15 CVariant a((int)0), b((int64_t)1);
16
17 EXPECT_TRUE(a.isInteger());
18 EXPECT_EQ(CVariant::VariantTypeInteger, a.type());
19 EXPECT_TRUE(b.isInteger());
20 EXPECT_EQ(CVariant::VariantTypeInteger, b.type());
21
22 EXPECT_EQ((int64_t)1, b.asInteger());
23}
24
25TEST(TestVariant, VariantTypeUnsignedInteger)
26{
27 CVariant a((unsigned int)0), b((uint64_t)1);
28
29 EXPECT_TRUE(a.isUnsignedInteger());
30 EXPECT_EQ(CVariant::VariantTypeUnsignedInteger, a.type());
31 EXPECT_TRUE(b.isUnsignedInteger());
32 EXPECT_EQ(CVariant::VariantTypeUnsignedInteger, b.type());
33
34 EXPECT_EQ((uint64_t)1, b.asUnsignedInteger());
35}
36
37TEST(TestVariant, VariantTypeBoolean)
38{
39 CVariant a(true);
40
41 EXPECT_TRUE(a.isBoolean());
42 EXPECT_EQ(CVariant::VariantTypeBoolean, a.type());
43
44 EXPECT_TRUE(a.asBoolean());
45}
46
47TEST(TestVariant, VariantTypeString)
48{
49 CVariant a("VariantTypeString");
50 CVariant b("VariantTypeString2", sizeof("VariantTypeString2") - 1);
51 std::string str("VariantTypeString3");
52 CVariant c(str);
53
54 EXPECT_TRUE(a.isString());
55 EXPECT_EQ(CVariant::VariantTypeString, a.type());
56 EXPECT_TRUE(b.isString());
57 EXPECT_EQ(CVariant::VariantTypeString, b.type());
58 EXPECT_TRUE(c.isString());
59 EXPECT_EQ(CVariant::VariantTypeString, c.type());
60
61 EXPECT_STREQ("VariantTypeString", a.asString().c_str());
62 EXPECT_STREQ("VariantTypeString2", b.asString().c_str());
63 EXPECT_STREQ("VariantTypeString3", c.asString().c_str());
64}
65
66TEST(TestVariant, VariantTypeWideString)
67{
68 CVariant a(L"VariantTypeWideString");
69 CVariant b(L"VariantTypeWideString2", sizeof(L"VariantTypeWideString2") - 1);
70 std::wstring str(L"VariantTypeWideString3");
71 CVariant c(str);
72
73 EXPECT_TRUE(a.isWideString());
74 EXPECT_EQ(CVariant::VariantTypeWideString, a.type());
75 EXPECT_TRUE(b.isWideString());
76 EXPECT_EQ(CVariant::VariantTypeWideString, b.type());
77 EXPECT_TRUE(c.isWideString());
78 EXPECT_EQ(CVariant::VariantTypeWideString, c.type());
79
80 EXPECT_STREQ(L"VariantTypeWideString", a.asWideString().c_str());
81 EXPECT_STREQ(L"VariantTypeWideString2", b.asWideString().c_str());
82 EXPECT_STREQ(L"VariantTypeWideString3", c.asWideString().c_str());
83}
84
85TEST(TestVariant, VariantTypeDouble)
86{
87 CVariant a((float)0.0f), b((double)0.1f);
88
89 EXPECT_TRUE(a.isDouble());
90 EXPECT_EQ(CVariant::VariantTypeDouble, a.type());
91 EXPECT_TRUE(b.isDouble());
92 EXPECT_EQ(CVariant::VariantTypeDouble, b.type());
93
94 EXPECT_EQ((float)0.0f, a.asDouble());
95 EXPECT_EQ((double)0.1f, b.asDouble());
96}
97
98TEST(TestVariant, VariantTypeArray)
99{
100 std::vector<std::string> strarray;
101 strarray.emplace_back("string1");
102 strarray.emplace_back("string2");
103 strarray.emplace_back("string3");
104 strarray.emplace_back("string4");
105 CVariant a(strarray);
106
107 EXPECT_TRUE(a.isArray());
108 EXPECT_EQ(CVariant::VariantTypeArray, a.type());
109}
110
111TEST(TestVariant, VariantTypeObject)
112{
113 CVariant a;
114 a["key"] = "value";
115
116 EXPECT_TRUE(a.isObject());
117 EXPECT_EQ(CVariant::VariantTypeObject, a.type());
118}
119
120TEST(TestVariant, VariantTypeNull)
121{
122 CVariant a;
123
124 EXPECT_TRUE(a.isNull());
125 EXPECT_EQ(CVariant::VariantTypeNull, a.type());
126}
127
128TEST(TestVariant, VariantFromMap)
129{
130 std::map<std::string, std::string> strMap;
131 strMap["key"] = "value";
132 CVariant a = strMap;
133
134 EXPECT_TRUE(a.isObject());
135 EXPECT_TRUE(a.size() == 1);
136 EXPECT_EQ(CVariant::VariantTypeObject, a.type());
137 EXPECT_TRUE(a.isMember("key"));
138 EXPECT_TRUE(a["key"].isString());
139 EXPECT_STREQ(a["key"].asString().c_str(), "value");
140
141 std::map<std::string, CVariant> variantMap;
142 variantMap["key"] = CVariant("value");
143 CVariant b = variantMap;
144
145 EXPECT_TRUE(b.isObject());
146 EXPECT_TRUE(b.size() == 1);
147 EXPECT_EQ(CVariant::VariantTypeObject, b.type());
148 EXPECT_TRUE(b.isMember("key"));
149 EXPECT_TRUE(b["key"].isString());
150 EXPECT_STREQ(b["key"].asString().c_str(), "value");
151}
152
153TEST(TestVariant, operatorTest)
154{
155 std::vector<std::string> strarray;
156 strarray.emplace_back("string1");
157 CVariant a, b, c(strarray), d;
158 a["key"] = "value";
159 b = a;
160 c[0] = "value2";
161 d = c;
162
163 EXPECT_TRUE(a.isObject());
164 EXPECT_EQ(CVariant::VariantTypeObject, a.type());
165 EXPECT_TRUE(b.isObject());
166 EXPECT_EQ(CVariant::VariantTypeObject, b.type());
167 EXPECT_TRUE(c.isArray());
168 EXPECT_EQ(CVariant::VariantTypeArray, c.type());
169 EXPECT_TRUE(d.isArray());
170 EXPECT_EQ(CVariant::VariantTypeArray, d.type());
171
172 EXPECT_TRUE(a == b);
173 EXPECT_TRUE(c == d);
174 EXPECT_FALSE(a == d);
175
176 EXPECT_STREQ("value", a["key"].asString().c_str());
177 EXPECT_STREQ("value2", c[0].asString().c_str());
178}
179
180TEST(TestVariant, push_back)
181{
182 CVariant a, b("variant1"), c("variant2"), d("variant3");
183 a.push_back(b);
184 a.push_back(c);
185 a.push_back(d);
186
187 EXPECT_TRUE(a.isArray());
188 EXPECT_EQ(CVariant::VariantTypeArray, a.type());
189 EXPECT_STREQ("variant1", a[0].asString().c_str());
190 EXPECT_STREQ("variant2", a[1].asString().c_str());
191 EXPECT_STREQ("variant3", a[2].asString().c_str());
192}
193
194TEST(TestVariant, append)
195{
196 CVariant a, b("variant1"), c("variant2"), d("variant3");
197 a.append(b);
198 a.append(c);
199 a.append(d);
200
201 EXPECT_TRUE(a.isArray());
202 EXPECT_EQ(CVariant::VariantTypeArray, a.type());
203 EXPECT_STREQ("variant1", a[0].asString().c_str());
204 EXPECT_STREQ("variant2", a[1].asString().c_str());
205 EXPECT_STREQ("variant3", a[2].asString().c_str());
206}
207
208TEST(TestVariant, c_str)
209{
210 CVariant a("variant");
211
212 EXPECT_STREQ("variant", a.c_str());
213}
214
215TEST(TestVariant, swap)
216{
217 CVariant a((int)0), b("variant");
218
219 EXPECT_TRUE(a.isInteger());
220 EXPECT_TRUE(b.isString());
221
222 a.swap(b);
223 EXPECT_TRUE(b.isInteger());
224 EXPECT_TRUE(a.isString());
225}
226
227TEST(TestVariant, iterator_array)
228{
229 std::vector<std::string> strarray;
230 strarray.emplace_back("string");
231 strarray.emplace_back("string");
232 strarray.emplace_back("string");
233 strarray.emplace_back("string");
234 CVariant a(strarray);
235
236 EXPECT_TRUE(a.isArray());
237 EXPECT_EQ(CVariant::VariantTypeArray, a.type());
238
239 for (auto it = a.begin_array(); it != a.end_array(); it++)
240 {
241 EXPECT_STREQ("string", it->c_str());
242 }
243
244 for (auto const_it = a.begin_array(); const_it != a.end_array(); const_it++)
245 {
246 EXPECT_STREQ("string", const_it->c_str());
247 }
248}
249
250TEST(TestVariant, iterator_map)
251{
252 CVariant a;
253 a["key1"] = "string";
254 a["key2"] = "string";
255 a["key3"] = "string";
256 a["key4"] = "string";
257
258 EXPECT_TRUE(a.isObject());
259 EXPECT_EQ(CVariant::VariantTypeObject, a.type());
260
261 for (auto it = a.begin_map(); it != a.end_map(); it++)
262 {
263 EXPECT_STREQ("string", it->second.c_str());
264 }
265
266 for (auto const_it = a.begin_map(); const_it != a.end_map(); const_it++)
267 {
268 EXPECT_STREQ("string", const_it->second.c_str());
269 }
270}
271
272TEST(TestVariant, size)
273{
274 std::vector<std::string> strarray;
275 strarray.emplace_back("string");
276 strarray.emplace_back("string");
277 strarray.emplace_back("string");
278 strarray.emplace_back("string");
279 CVariant a(strarray);
280
281 EXPECT_EQ((unsigned int)4, a.size());
282}
283
284TEST(TestVariant, empty)
285{
286 std::vector<std::string> strarray;
287 CVariant a(strarray);
288
289 EXPECT_TRUE(a.empty());
290}
291
292TEST(TestVariant, clear)
293{
294 std::vector<std::string> strarray;
295 strarray.emplace_back("string");
296 strarray.emplace_back("string");
297 strarray.emplace_back("string");
298 strarray.emplace_back("string");
299 CVariant a(strarray);
300
301 EXPECT_FALSE(a.empty());
302 a.clear();
303 EXPECT_TRUE(a.empty());
304}
305
306TEST(TestVariant, erase)
307{
308 std::vector<std::string> strarray;
309 strarray.emplace_back("string1");
310 strarray.emplace_back("string2");
311 strarray.emplace_back("string3");
312 strarray.emplace_back("string4");
313 CVariant a, b(strarray);
314 a["key1"] = "string1";
315 a["key2"] = "string2";
316 a["key3"] = "string3";
317 a["key4"] = "string4";
318
319 EXPECT_STREQ("string2", a["key2"].c_str());
320 EXPECT_STREQ("string2", b[1].c_str());
321 a.erase("key2");
322 b.erase(1);
323 EXPECT_FALSE(a["key2"].c_str());
324 EXPECT_STREQ("string3", b[1].c_str());
325}
326
327TEST(TestVariant, isMember)
328{
329 CVariant a;
330 a["key1"] = "string1";
331
332 EXPECT_TRUE(a.isMember("key1"));
333 EXPECT_FALSE(a.isMember("key2"));
334}
diff --git a/xbmc/utils/test/TestXBMCTinyXML.cpp b/xbmc/utils/test/TestXBMCTinyXML.cpp
new file mode 100644
index 0000000..b3f84eb
--- /dev/null
+++ b/xbmc/utils/test/TestXBMCTinyXML.cpp
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "test/TestUtils.h"
10#include "utils/StringUtils.h"
11#include "utils/XBMCTinyXML.h"
12
13#include <gtest/gtest.h>
14
15TEST(TestXBMCTinyXML, ParseFromString)
16{
17 bool retval = false;
18 // scraper results with unescaped &
19 CXBMCTinyXML doc;
20 std::string data("<details><url function=\"ParseTMDBRating\" "
21 "cache=\"tmdb-en-12244.json\">"
22 "http://api.themoviedb.org/3/movie/12244"
23 "?api_key=57983e31fb435df4df77afb854740ea9"
24 "&language=en&#x3f;&#x003F;&#0063;</url></details>");
25 doc.Parse(data);
26 TiXmlNode *root = doc.RootElement();
27 if (root && root->ValueStr() == "details")
28 {
29 TiXmlElement *url = root->FirstChildElement("url");
30 if (url && url->FirstChild())
31 {
32 retval = (url->FirstChild()->ValueStr() == "http://api.themoviedb.org/3/movie/12244?api_key=57983e31fb435df4df77afb854740ea9&language=en???");
33 }
34 }
35 EXPECT_TRUE(retval);
36}
37
38TEST(TestXBMCTinyXML, ParseFromFileHandle)
39{
40 bool retval = false;
41 // scraper results with unescaped &
42 CXBMCTinyXML doc;
43 FILE *f = fopen(XBMC_REF_FILE_PATH("/xbmc/utils/test/CXBMCTinyXML-test.xml").c_str(), "r");
44 ASSERT_NE(nullptr, f);
45 doc.LoadFile(f);
46 fclose(f);
47 TiXmlNode *root = doc.RootElement();
48 if (root && root->ValueStr() == "details")
49 {
50 TiXmlElement *url = root->FirstChildElement("url");
51 if (url && url->FirstChild())
52 {
53 std::string str = url->FirstChild()->ValueStr();
54 retval = (StringUtils::Trim(str) == "http://api.themoviedb.org/3/movie/12244?api_key=57983e31fb435df4df77afb854740ea9&language=en???");
55 }
56 }
57 EXPECT_TRUE(retval);
58}
diff --git a/xbmc/utils/test/TestXMLUtils.cpp b/xbmc/utils/test/TestXMLUtils.cpp
new file mode 100644
index 0000000..1a807ff
--- /dev/null
+++ b/xbmc/utils/test/TestXMLUtils.cpp
@@ -0,0 +1,356 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "XBDateTime.h"
10#include "utils/StringUtils.h"
11#include "utils/XMLUtils.h"
12
13#include <gtest/gtest.h>
14
15TEST(TestXMLUtils, GetHex)
16{
17 CXBMCTinyXML a;
18 uint32_t ref, val;
19
20 a.Parse(std::string("<root><node>0xFF</node></root>"));
21 EXPECT_TRUE(XMLUtils::GetHex(a.RootElement(), "node", val));
22
23 ref = 0xFF;
24 EXPECT_EQ(ref, val);
25}
26
27TEST(TestXMLUtils, GetUInt)
28{
29 CXBMCTinyXML a;
30 uint32_t ref, val;
31
32 a.Parse(std::string("<root><node>1000</node></root>"));
33 EXPECT_TRUE(XMLUtils::GetUInt(a.RootElement(), "node", val));
34
35 ref = 1000;
36 EXPECT_EQ(ref, val);
37}
38
39TEST(TestXMLUtils, GetLong)
40{
41 CXBMCTinyXML a;
42 long ref, val;
43
44 a.Parse(std::string("<root><node>1000</node></root>"));
45 EXPECT_TRUE(XMLUtils::GetLong(a.RootElement(), "node", val));
46
47 ref = 1000;
48 EXPECT_EQ(ref, val);
49}
50
51TEST(TestXMLUtils, GetFloat)
52{
53 CXBMCTinyXML a;
54 float ref, val;
55
56 a.Parse(std::string("<root><node>1000.1f</node></root>"));
57 EXPECT_TRUE(XMLUtils::GetFloat(a.RootElement(), "node", val));
58 EXPECT_TRUE(XMLUtils::GetFloat(a.RootElement(), "node", val, 1000.0f,
59 1000.2f));
60 ref = 1000.1f;
61 EXPECT_EQ(ref, val);
62}
63
64TEST(TestXMLUtils, GetDouble)
65{
66 CXBMCTinyXML a;
67 double val;
68 std::string refstr, valstr;
69
70 a.Parse(std::string("<root><node>1000.1f</node></root>"));
71 EXPECT_TRUE(XMLUtils::GetDouble(a.RootElement(), "node", val));
72
73 refstr = "1000.100000";
74 valstr = StringUtils::Format("%f", val);
75 EXPECT_STREQ(refstr.c_str(), valstr.c_str());
76}
77
78TEST(TestXMLUtils, GetInt)
79{
80 CXBMCTinyXML a;
81 int ref, val;
82
83 a.Parse(std::string("<root><node>1000</node></root>"));
84 EXPECT_TRUE(XMLUtils::GetInt(a.RootElement(), "node", val));
85 EXPECT_TRUE(XMLUtils::GetInt(a.RootElement(), "node", val, 999, 1001));
86
87 ref = 1000;
88 EXPECT_EQ(ref, val);
89}
90
91TEST(TestXMLUtils, GetBoolean)
92{
93 CXBMCTinyXML a;
94 bool ref, val;
95
96 a.Parse(std::string("<root><node>true</node></root>"));
97 EXPECT_TRUE(XMLUtils::GetBoolean(a.RootElement(), "node", val));
98
99 ref = true;
100 EXPECT_EQ(ref, val);
101}
102
103TEST(TestXMLUtils, GetString)
104{
105 CXBMCTinyXML a;
106 std::string ref, val;
107
108 a.Parse(std::string("<root><node>some string</node></root>"));
109 EXPECT_TRUE(XMLUtils::GetString(a.RootElement(), "node", val));
110
111 ref = "some string";
112 EXPECT_STREQ(ref.c_str(), val.c_str());
113}
114
115TEST(TestXMLUtils, GetAdditiveString)
116{
117 CXBMCTinyXML a, b;
118 std::string ref, val;
119
120 a.Parse(std::string("<root>\n"
121 " <node>some string1</node>\n"
122 " <node>some string2</node>\n"
123 " <node>some string3</node>\n"
124 " <node>some string4</node>\n"
125 " <node>some string5</node>\n"
126 "</root>\n"));
127 EXPECT_TRUE(XMLUtils::GetAdditiveString(a.RootElement(), "node", ",", val));
128
129 ref = "some string1,some string2,some string3,some string4,some string5";
130 EXPECT_STREQ(ref.c_str(), val.c_str());
131
132 val.clear();
133 b.Parse(std::string("<root>\n"
134 " <node>some string1</node>\n"
135 " <node>some string2</node>\n"
136 " <node clear=\"true\">some string3</node>\n"
137 " <node>some string4</node>\n"
138 " <node>some string5</node>\n"
139 "</root>\n"));
140 EXPECT_TRUE(XMLUtils::GetAdditiveString(b.RootElement(), "node", ",", val));
141
142 ref = "some string3,some string4,some string5";
143 EXPECT_STREQ(ref.c_str(), val.c_str());
144}
145
146TEST(TestXMLUtils, GetStringArray)
147{
148 CXBMCTinyXML a;
149 std::vector<std::string> strarray;
150
151 a.Parse(std::string("<root>\n"
152 " <node>some string1</node>\n"
153 " <node>some string2</node>\n"
154 " <node>some string3</node>\n"
155 " <node>some string4</node>\n"
156 " <node>some string5</node>\n"
157 "</root>\n"));
158 EXPECT_TRUE(XMLUtils::GetStringArray(a.RootElement(), "node", strarray));
159
160 EXPECT_STREQ("some string1", strarray.at(0).c_str());
161 EXPECT_STREQ("some string2", strarray.at(1).c_str());
162 EXPECT_STREQ("some string3", strarray.at(2).c_str());
163 EXPECT_STREQ("some string4", strarray.at(3).c_str());
164 EXPECT_STREQ("some string5", strarray.at(4).c_str());
165}
166
167TEST(TestXMLUtils, GetPath)
168{
169 CXBMCTinyXML a, b;
170 std::string ref, val;
171
172 a.Parse(std::string("<root><node urlencoded=\"yes\">special://xbmc/</node></root>"));
173 EXPECT_TRUE(XMLUtils::GetPath(a.RootElement(), "node", val));
174
175 ref = "special://xbmc/";
176 EXPECT_STREQ(ref.c_str(), val.c_str());
177
178 val.clear();
179 b.Parse(std::string("<root><node>special://xbmcbin/</node></root>"));
180 EXPECT_TRUE(XMLUtils::GetPath(b.RootElement(), "node", val));
181
182 ref = "special://xbmcbin/";
183 EXPECT_STREQ(ref.c_str(), val.c_str());
184}
185
186TEST(TestXMLUtils, GetDate)
187{
188 CXBMCTinyXML a;
189 CDateTime ref, val;
190
191 a.Parse(std::string("<root><node>2012-07-08</node></root>"));
192 EXPECT_TRUE(XMLUtils::GetDate(a.RootElement(), "node", val));
193 ref.SetDate(2012, 7, 8);
194 EXPECT_TRUE(ref == val);
195}
196
197TEST(TestXMLUtils, GetDateTime)
198{
199 CXBMCTinyXML a;
200 CDateTime ref, val;
201
202 a.Parse(std::string("<root><node>2012-07-08 01:02:03</node></root>"));
203 EXPECT_TRUE(XMLUtils::GetDateTime(a.RootElement(), "node", val));
204 ref.SetDateTime(2012, 7, 8, 1, 2, 3);
205 EXPECT_TRUE(ref == val);
206}
207
208TEST(TestXMLUtils, SetString)
209{
210 CXBMCTinyXML a;
211 std::string ref, val;
212
213 a.Parse(std::string("<root></root>"));
214 XMLUtils::SetString(a.RootElement(), "node", "some string");
215 EXPECT_TRUE(XMLUtils::GetString(a.RootElement(), "node", val));
216
217 ref = "some string";
218 EXPECT_STREQ(ref.c_str(), val.c_str());
219}
220
221TEST(TestXMLUtils, SetAdditiveString)
222{
223 CXBMCTinyXML a;
224 std::string ref, val;
225
226 a.Parse(std::string("<root></root>"));
227 XMLUtils::SetAdditiveString(a.RootElement(), "node", ",",
228 "some string1,some string2,some string3,some string4,some string5");
229 EXPECT_TRUE(XMLUtils::GetAdditiveString(a.RootElement(), "node", ",", val));
230
231 ref = "some string1,some string2,some string3,some string4,some string5";
232 EXPECT_STREQ(ref.c_str(), val.c_str());
233}
234
235TEST(TestXMLUtils, SetStringArray)
236{
237 CXBMCTinyXML a;
238 std::vector<std::string> strarray;
239 strarray.emplace_back("some string1");
240 strarray.emplace_back("some string2");
241 strarray.emplace_back("some string3");
242 strarray.emplace_back("some string4");
243 strarray.emplace_back("some string5");
244
245 a.Parse(std::string("<root></root>"));
246 XMLUtils::SetStringArray(a.RootElement(), "node", strarray);
247 EXPECT_TRUE(XMLUtils::GetStringArray(a.RootElement(), "node", strarray));
248
249 EXPECT_STREQ("some string1", strarray.at(0).c_str());
250 EXPECT_STREQ("some string2", strarray.at(1).c_str());
251 EXPECT_STREQ("some string3", strarray.at(2).c_str());
252 EXPECT_STREQ("some string4", strarray.at(3).c_str());
253 EXPECT_STREQ("some string5", strarray.at(4).c_str());
254}
255
256TEST(TestXMLUtils, SetInt)
257{
258 CXBMCTinyXML a;
259 int ref, val;
260
261 a.Parse(std::string("<root></root>"));
262 XMLUtils::SetInt(a.RootElement(), "node", 1000);
263 EXPECT_TRUE(XMLUtils::GetInt(a.RootElement(), "node", val));
264
265 ref = 1000;
266 EXPECT_EQ(ref, val);
267}
268
269TEST(TestXMLUtils, SetFloat)
270{
271 CXBMCTinyXML a;
272 float ref, val;
273
274 a.Parse(std::string("<root></root>"));
275 XMLUtils::SetFloat(a.RootElement(), "node", 1000.1f);
276 EXPECT_TRUE(XMLUtils::GetFloat(a.RootElement(), "node", val));
277
278 ref = 1000.1f;
279 EXPECT_EQ(ref, val);
280}
281
282TEST(TestXMLUtils, SetBoolean)
283{
284 CXBMCTinyXML a;
285 bool ref, val;
286
287 a.Parse(std::string("<root></root>"));
288 XMLUtils::SetBoolean(a.RootElement(), "node", true);
289 EXPECT_TRUE(XMLUtils::GetBoolean(a.RootElement(), "node", val));
290
291 ref = true;
292 EXPECT_EQ(ref, val);
293}
294
295TEST(TestXMLUtils, SetHex)
296{
297 CXBMCTinyXML a;
298 uint32_t ref, val;
299
300 a.Parse(std::string("<root></root>"));
301 XMLUtils::SetHex(a.RootElement(), "node", 0xFF);
302 EXPECT_TRUE(XMLUtils::GetHex(a.RootElement(), "node", val));
303
304 ref = 0xFF;
305 EXPECT_EQ(ref, val);
306}
307
308TEST(TestXMLUtils, SetPath)
309{
310 CXBMCTinyXML a;
311 std::string ref, val;
312
313 a.Parse(std::string("<root></root>"));
314 XMLUtils::SetPath(a.RootElement(), "node", "special://xbmc/");
315 EXPECT_TRUE(XMLUtils::GetPath(a.RootElement(), "node", val));
316
317 ref = "special://xbmc/";
318 EXPECT_STREQ(ref.c_str(), val.c_str());
319}
320
321TEST(TestXMLUtils, SetLong)
322{
323 CXBMCTinyXML a;
324 long ref, val;
325
326 a.Parse(std::string("<root></root>"));
327 XMLUtils::SetLong(a.RootElement(), "node", 1000);
328 EXPECT_TRUE(XMLUtils::GetLong(a.RootElement(), "node", val));
329
330 ref = 1000;
331 EXPECT_EQ(ref, val);
332}
333
334TEST(TestXMLUtils, SetDate)
335{
336 CXBMCTinyXML a;
337 CDateTime ref, val;
338
339 a.Parse(std::string("<root></root>"));
340 ref.SetDate(2012, 7, 8);
341 XMLUtils::SetDate(a.RootElement(), "node", ref);
342 EXPECT_TRUE(XMLUtils::GetDate(a.RootElement(), "node", val));
343 EXPECT_TRUE(ref == val);
344}
345
346TEST(TestXMLUtils, SetDateTime)
347{
348 CXBMCTinyXML a;
349 CDateTime ref, val;
350
351 a.Parse(std::string("<root></root>"));
352 ref.SetDateTime(2012, 7, 8, 1, 2, 3);
353 XMLUtils::SetDateTime(a.RootElement(), "node", ref);
354 EXPECT_TRUE(XMLUtils::GetDateTime(a.RootElement(), "node", val));
355 EXPECT_TRUE(ref == val);
356}
diff --git a/xbmc/utils/test/Testlog.cpp b/xbmc/utils/test/Testlog.cpp
new file mode 100644
index 0000000..7405c02
--- /dev/null
+++ b/xbmc/utils/test/Testlog.cpp
@@ -0,0 +1,102 @@
1/*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "CompileInfo.h"
10#include "ServiceBroker.h"
11#include "filesystem/File.h"
12#include "filesystem/SpecialProtocol.h"
13#include "test/TestUtils.h"
14#include "utils/RegExp.h"
15#include "utils/StringUtils.h"
16#include "utils/log.h"
17
18#include <stdlib.h>
19
20#include <gtest/gtest.h>
21
22class Testlog : public testing::Test
23{
24protected:
25 Testlog() = default;
26 ~Testlog() override { CServiceBroker::GetLogging().Uninitialize(); }
27};
28
29TEST_F(Testlog, Log)
30{
31 std::string logfile, logstring;
32 char buf[100];
33 ssize_t bytesread;
34 XFILE::CFile file;
35 CRegExp regex;
36
37 std::string appName = CCompileInfo::GetAppName();
38 StringUtils::ToLower(appName);
39 logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log";
40 CServiceBroker::GetLogging().Initialize(
41 CSpecialProtocol::TranslatePath("special://temp/").c_str());
42 EXPECT_TRUE(XFILE::CFile::Exists(logfile));
43
44 CLog::Log(LOGDEBUG, "debug log message");
45 CLog::Log(LOGINFO, "info log message");
46 CLog::Log(LOGNOTICE, "notice log message");
47 CLog::Log(LOGWARNING, "warning log message");
48 CLog::Log(LOGERROR, "error log message");
49 CLog::Log(LOGSEVERE, "severe log message");
50 CLog::Log(LOGFATAL, "fatal log message");
51 CLog::Log(LOGNONE, "none type log message");
52 CServiceBroker::GetLogging().Uninitialize();
53
54 EXPECT_TRUE(file.Open(logfile));
55 while ((bytesread = file.Read(buf, sizeof(buf) - 1)) > 0)
56 {
57 buf[bytesread] = '\0';
58 logstring.append(buf);
59 }
60 file.Close();
61 EXPECT_FALSE(logstring.empty());
62
63 EXPECT_STREQ("\xEF\xBB\xBF", logstring.substr(0, 3).c_str());
64
65 EXPECT_TRUE(regex.RegComp(".*DEBUG <general>: debug log message.*"));
66 EXPECT_GE(regex.RegFind(logstring), 0);
67 EXPECT_TRUE(regex.RegComp(".*INFO <general>: info log message.*"));
68 EXPECT_GE(regex.RegFind(logstring), 0);
69 EXPECT_TRUE(regex.RegComp(".*INFO <general>: notice log message.*"));
70 EXPECT_GE(regex.RegFind(logstring), 0);
71 EXPECT_TRUE(regex.RegComp(".*WARNING <general>: warning log message.*"));
72 EXPECT_GE(regex.RegFind(logstring), 0);
73 EXPECT_TRUE(regex.RegComp(".*ERROR <general>: error log message.*"));
74 EXPECT_GE(regex.RegFind(logstring), 0);
75 EXPECT_TRUE(regex.RegComp(".*FATAL <general>: severe log message.*"));
76 EXPECT_GE(regex.RegFind(logstring), 0);
77 EXPECT_TRUE(regex.RegComp(".*FATAL <general>: fatal log message.*"));
78 EXPECT_GE(regex.RegFind(logstring), 0);
79 EXPECT_TRUE(regex.RegComp(".*OFF <general>: none type log message.*"));
80 EXPECT_GE(regex.RegFind(logstring), 0);
81
82 EXPECT_TRUE(XFILE::CFile::Delete(logfile));
83}
84
85TEST_F(Testlog, SetLogLevel)
86{
87 std::string logfile;
88
89 std::string appName = CCompileInfo::GetAppName();
90 StringUtils::ToLower(appName);
91 logfile = CSpecialProtocol::TranslatePath("special://temp/") + appName + ".log";
92 CServiceBroker::GetLogging().Initialize(
93 CSpecialProtocol::TranslatePath("special://temp/").c_str());
94 EXPECT_TRUE(XFILE::CFile::Exists(logfile));
95
96 EXPECT_EQ(LOG_LEVEL_DEBUG, CServiceBroker::GetLogging().GetLogLevel());
97 CServiceBroker::GetLogging().SetLogLevel(LOG_LEVEL_MAX);
98 EXPECT_EQ(LOG_LEVEL_MAX, CServiceBroker::GetLogging().GetLogLevel());
99
100 CServiceBroker::GetLogging().Uninitialize();
101 EXPECT_TRUE(XFILE::CFile::Delete(logfile));
102}
diff --git a/xbmc/utils/test/Testrfft.cpp b/xbmc/utils/test/Testrfft.cpp
new file mode 100644
index 0000000..a6c859d
--- /dev/null
+++ b/xbmc/utils/test/Testrfft.cpp
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2015-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9#include "utils/rfft.h"
10
11#include <gtest/gtest.h>
12
13#if defined(TARGET_WINDOWS) && !defined(_USE_MATH_DEFINES)
14#define _USE_MATH_DEFINES
15#endif
16
17#include <math.h>
18
19
20TEST(TestRFFT, SimpleSignal)
21{
22 const int size = 32;
23 const int freq1 = 5;
24 const int freq2[] = {1,7};
25 std::vector<float> input(2*size);
26 std::vector<float> output(size);
27 for (size_t i=0;i<size;++i)
28 {
29 input[2*i] = cos(freq1*2.0*M_PI*i/size);
30 input[2*i+1] = cos(freq2[0]*2.0*M_PI*i/size)+cos(freq2[1]*2.0*M_PI*i/size);
31 }
32 RFFT transform(size, false);
33
34 transform.calc(&input[0], &output[0]);
35
36 for (int i=0;i<size/2;++i)
37 {
38 EXPECT_NEAR(output[2*i],(i==freq1?1.0:0.0), 1e-7);
39 EXPECT_NEAR(output[2*i+1], ((i==freq2[0]||i==freq2[1])?1.0:0.0), 1e-7);
40 }
41}
diff --git a/xbmc/utils/test/data/language/Spanish/strings.po b/xbmc/utils/test/data/language/Spanish/strings.po
new file mode 100644
index 0000000..8ee8d02
--- /dev/null
+++ b/xbmc/utils/test/data/language/Spanish/strings.po
@@ -0,0 +1,26 @@
1# Kodi Media Center language file
2msgid ""
3msgstr ""
4"Project-Id-Version: XBMC Main\n"
5"Report-Msgid-Bugs-To: http://trac.xbmc.org/\n"
6"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
7"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8"Last-Translator: Kodi Translation Team\n"
9"Language-Team: Spanish (http://www.transifex.com/projects/p/xbmc-main/language/es/)\n"
10"MIME-Version: 1.0\n"
11"Content-Type: text/plain; charset=UTF-8\n"
12"Content-Transfer-Encoding: 8bit\n"
13"Language: es\n"
14"Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
16msgctxt "#0"
17msgid "Programs"
18msgstr "Programas"
19
20msgctxt "#1"
21msgid "Pictures"
22msgstr "Imágenes"
23
24msgctxt "#2"
25msgid "Music"
26msgstr "Música"