2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include <gtest/gtest.h>
13 using ::testing::Test
;
14 using ::testing::ValuesIn
;
15 using ::testing::WithParamInterface
;
17 TEST(TestUtil
, GetQualifiedFilename
)
19 std::string file
= "../foo";
20 CUtil::GetQualifiedFilename("smb://", file
);
21 EXPECT_EQ(file
, "foo");
22 file
= "C:\\foo\\bar";
23 CUtil::GetQualifiedFilename("smb://", file
);
24 EXPECT_EQ(file
, "C:\\foo\\bar");
25 file
= "../foo/./bar";
26 CUtil::GetQualifiedFilename("smb://my/path", file
);
27 EXPECT_EQ(file
, "smb://my/foo/bar");
28 file
= "smb://foo/bar/";
29 CUtil::GetQualifiedFilename("upnp://", file
);
30 EXPECT_EQ(file
, "smb://foo/bar/");
33 TEST(TestUtil
, MakeLegalPath
)
37 path
= "C:\\foo\\bar";
38 EXPECT_EQ(CUtil::MakeLegalPath(path
), "C:\\foo\\bar");
39 path
= "C:\\foo:\\bar\\";
40 EXPECT_EQ(CUtil::MakeLegalPath(path
), "C:\\foo_\\bar\\");
43 EXPECT_EQ(CUtil::MakeLegalPath(path
),"/foo/bar/");
45 EXPECT_EQ(CUtil::MakeLegalPath(path
),"/foo_/bar");
47 path
= "smb://foo/bar";
48 EXPECT_EQ(CUtil::MakeLegalPath(path
), "smb://foo/bar");
49 path
= "smb://foo/bar?/";
50 EXPECT_EQ(CUtil::MakeLegalPath(path
), "smb://foo/bar_/");
53 TEST(TestUtil
, MakeShortenPath
)
56 EXPECT_EQ(true, CUtil::MakeShortenPath("smb://test/string/is/long/and/very/much/so", result
, 10));
57 EXPECT_EQ("smb:/../so", result
);
59 EXPECT_EQ(true, CUtil::MakeShortenPath("smb://test/string/is/long/and/very/much/so", result
, 30));
60 EXPECT_EQ("smb://../../../../../../../so", result
);
62 EXPECT_EQ(true, CUtil::MakeShortenPath("smb://test//string/is/long/and/very//much/so", result
, 30));
63 EXPECT_EQ("smb:/../../../../../so", result
);
65 EXPECT_EQ(true, CUtil::MakeShortenPath("//test//string/is/long/and/very//much/so", result
, 30));
66 EXPECT_EQ("/../../../../../so", result
);
69 TEST(TestUtil
, ValidatePath
)
74 EXPECT_EQ(CUtil::ValidatePath(path
), "C:\\foo\\bar\\");
75 path
= "C:\\\\foo\\\\bar\\";
76 EXPECT_EQ(CUtil::ValidatePath(path
, true), "C:\\foo\\bar\\");
77 path
= "\\\\foo\\\\bar\\";
78 EXPECT_EQ(CUtil::ValidatePath(path
, true), "\\\\foo\\bar\\");
80 path
= "\\foo\\bar\\";
81 EXPECT_EQ(CUtil::ValidatePath(path
), "/foo/bar/");
83 EXPECT_EQ(CUtil::ValidatePath(path
, true), "/foo/bar/");
85 path
= "smb://foo/bar/";
86 EXPECT_EQ(CUtil::ValidatePath(path
), "smb://foo/bar/");
87 path
= "smb://foo//bar/";
88 EXPECT_EQ(CUtil::ValidatePath(path
, true), "smb://foo/bar/");
89 path
= "smb:\\\\foo\\\\bar\\";
90 EXPECT_EQ(CUtil::ValidatePath(path
, true), "smb://foo/bar/");
93 struct TestUtilCleanStringData
98 std::string expTitleYear
;
100 std::string expIdentifierType
{};
101 std::string expIdentifier
{};
104 std::ostream
& operator<<(std::ostream
& os
, const TestUtilCleanStringData
& rhs
)
106 return os
<< "(input: " << rhs
.input
<< "; first: " << (rhs
.first
? "true" : "false")
107 << "; expTitle: " << rhs
.expTitle
<< "; expTitleYear: " << rhs
.expTitleYear
108 << "; expYear: " << rhs
.expYear
<< ")";
111 class TestUtilCleanString
: public Test
, public WithParamInterface
<TestUtilCleanStringData
>
115 TEST_P(TestUtilCleanString
, GetFilenameIdentifier
)
117 std::string identifierType
;
118 std::string identifier
;
119 CUtil::GetFilenameIdentifier(GetParam().input
, identifierType
, identifier
);
120 EXPECT_EQ(identifierType
, GetParam().expIdentifierType
);
121 EXPECT_EQ(identifier
, GetParam().expIdentifier
);
124 TEST_P(TestUtilCleanString
, CleanString
)
126 std::string title
, titleYear
, year
;
127 CUtil::CleanString(GetParam().input
, title
, titleYear
, year
, true, GetParam().first
);
128 EXPECT_EQ(title
, GetParam().expTitle
);
129 EXPECT_EQ(titleYear
, GetParam().expTitleYear
);
130 EXPECT_EQ(year
, GetParam().expYear
);
132 const TestUtilCleanStringData values
[] = {
133 {"Some.BDRemux.mkv", true, "Some", "Some", ""},
134 {"SomeMovie.2018.UHD.BluRay.2160p.HEVC.TrueHD.Atmos.7.1-BeyondHD", true, "SomeMovie",
135 "SomeMovie (2018)", "2018"},
136 {"SOME_UHD_HDR10+_DV_2022_remux_dub atmos_soundmovie", true, "SOME", "SOME (2022)", "2022"},
137 // no result because of the . and spaces in movie name
138 {"Some Movie.Some Story.2013.BDRemux.1080p", true, "Some Movie.Some Story",
139 "Some Movie.Some Story (2013)", "2013"},
140 {"Movie.Some.Story.2017.2160p.BDRemux.IMAX.HDR.DV.IVA(ENG.RUS).ExKinoRay", true,
141 "Movie Some Story", "Movie Some Story (2017)", "2017"},
142 {"Some.Movie.1954.BDRip.1080p.mkv", true, "Some Movie", "Some Movie (1954)", "1954"},
143 {"Some «Movie».2021.WEB-DL.2160p.HDR.mkv", true, "Some «Movie»", "Some «Movie» (2021)", "2021"},
144 {"Some Movie (2013).mp4", true, "Some Movie", "Some Movie (2013)", "2013"},
145 {"Some Movie (2013) [imdbid-tt123].mp4", true, "Some Movie", "Some Movie (2013)", "2013",
147 {"Some Movie (2013) {tmdb-123}.mp4", true, "Some Movie", "Some Movie (2013)", "2013", "tmdb",
149 {"Some Movie (2013) {tmdb=123}.mp4", true, "Some Movie", "Some Movie (2013)", "2013", "tmdb",
151 // no result because of the text (Director Cut), it can also a be a movie translation
152 {"Some (Director Cut).BDRemux.mkv", true, "Some (Director Cut)", "Some (Director Cut)", ""}};
154 INSTANTIATE_TEST_SUITE_P(URL
, TestUtilCleanString
, ValuesIn(values
));
156 struct TestUtilSplitParamsData
159 std::vector
<std::string
> expectedResult
;
162 std::ostream
& operator<<(std::ostream
& os
, const TestUtilSplitParamsData
& rhs
)
164 os
<< "(input: " << rhs
.input
<< "; expCount: " << rhs
.expectedResult
.size();
165 for (unsigned int i
= 0; i
< rhs
.expectedResult
.size(); ++i
)
166 os
<< "; expParam " << i
+ 1 << ": " << rhs
.expectedResult
[i
];
171 class TestUtilSplitParams
: public Test
, public WithParamInterface
<TestUtilSplitParamsData
>
175 TEST_P(TestUtilSplitParams
, SplitParams
)
177 std::vector
<std::string
> actual
;
178 CUtil::SplitParams(GetParam().input
, actual
);
179 EXPECT_EQ(actual
.size(), GetParam().expectedResult
.size());
180 EXPECT_EQ(actual
, GetParam().expectedResult
);
183 const TestUtilSplitParamsData valuesSplitParams
[] = {
189 // quotes " removed only when at beginning and end of param (after trimming)
190 {R
"(" one
")", {R
"( one)"}},
191 {R
"("one
")", {R
"(one )"}},
192 {R
"("on
"e )", {R
"("on
"e)"}},
193 {R
"(o"n
"e )", {R
"(o"n
"e)"}},
194 {R
"(o" n
"e )", {R
"(o" n
"e)"}},
195 {R
"( "one
" )", {R
"(one)"}},
196 {R
"( " one
")", {R
"( one)"}},
197 {R
"( " one
" )", {R
"( one )"}},
198 {R
"(o" n
"e )", {R
"(o" n
"e)"}},
199 {R
"(o"ne
" )", {R
"(o"ne
")"}},
200 {R
"(o\"ne
")", {R
"(o"ne
")"}},
201 {R
"(\" one
")", {R
"( one)"}},
202 {R
"(\" one
\")", {R"( one
)"}},
203 {R"("one " one
)", {R"("one " one
)"}},
204 // function 1 parameter
205 {"fun(p1
)", {"fun(p1
)"}},
206 {" fun(p1
)", {"fun(p1
)"}},
207 {"fun(p1
) ", {"fun(p1
)"}},
208 {"fun(p1 p1
) ", {"fun(p1 p1
)"}},
209 {"fun( p1
) ", {"fun( p1
)"}}, // no trim: likely omission of the code?
211 {"one
,", {"one
", ""}},
212 {"one
,two
", {"one
", "two
"}},
213 {"one
,two
", {"one
", "two
"}},
214 {"one
,two
", {"one
", "two
"}},
215 {"one
, two
", {"one
", "two
"}},
216 {"one
,two two
", {"one
", "two two
"}},
217 {"one
, two two
", {"one
", "two two
"}},
218 {"one
,two two
", {"one
", "two two
"}},
219 {R"(\" one
\", two
)", {R"( one
)", "two
"}},
220 //{R"(\" one
", two)", {R
"( one)", "two"}}, // mixing \" & " not supported for multi param
221 {R
"(one, \" two
\")", {"one
", R"( two
)"}},
222 //{R"(one
, \" two
")", {"one", R
"( two)"}}, // mixing \" & " not supported for multi param
224 // function 2 parameters
225 {"fun(p1,p2)", {"fun(p1,p2)"}},
226 {"fun(p1 ,p2)", {"fun(p1 ,p2)"}}, // no trim: omission in the code?
227 {"fun(p1, p2)", {"fun(p1, p2)"}}, // no trim: omission in the code?
228 {"fun(p1 p1 ,p2)", {"fun(p1 p1 ,p2)"}}, // no trim: omission in the code?
229 {"fun(p1,p2), two", {"fun(p1,p2)", "two"}},
230 {"\"fun(p1,p2)\",two", {"fun(p1,p2)", "two"}},
231 {"\"fun(p1,p2)\",\" two\"", {"fun(p1,p2)", " two"}},
232 {"fun(p1,p2),\" two\"", {"fun(p1,p2)", " two"}},
233 {"\\\"fun(p1,p2)\\\",two", {"fun(p1,p2)", "two"}},
234 {"fun(p1,p2),\\\"two\\\"", {"fun(p1,p2)", "two"}},
235 {"fun(fun2(p1,p2),p3),two", {"fun(fun2(p1,p2),p3)", "two"}},
236 {"fun\"ction(p1,p2\",p3,p4)\"", {"fun\"ction(p1,p2\"", "p3", "p4)\""}},
238 {"one,two,three", {"one", "two", "three"}},
239 {"one,two two,three", {"one", "two two", "three"}},
240 {"one, two, three", {"one", "two", "three"}},
241 {"one, two two, three", {"one", "two two", "three"}},
243 {R
"(D:\foo\bar\baz.m2ts)", {R
"(D:\foo\bar\baz.m2ts)"}},
244 {R
"(D:\foo\bar\)", {R
"(D:\foo\bar\)"}},
245 {R
"(D:\\foo\bar\)", {R
"(D:\foo\bar\)"}},
246 {R
"(D:\foo\\bar\)", {R
"(D:\foo\bar\)"}},
247 {R
"(D:\foo\bar\\)", {R
"(D:\foo\bar\)"}},
248 {R
"(D:\\\foo\bar\)", {R
"(D:\\foo\bar\)"}},
249 {R
"(D:\foo\\\bar\)", {R
"(D:\foo\\bar\)"}},
250 {R
"(D:\foo\bar\\\)", {R
"(D:\foo\bar\\)"}},
251 {R
"(D:\\\\foo\bar\)", {R
"(D:\\foo\bar\)"}},
252 {R
"(D:\foo\\\\bar\)", {R
"(D:\foo\\bar\)"}},
253 {R
"(D:\foo\bar\\\\)", {R
"(D:\foo\bar\\)"}},
254 {R
"("D
:\foo
\\bar
\\\baz
.m2ts
\\\\")", {R
"(D:\foo\bar\\baz.m2ts\\)"}},
255 {R
"(" D
:\foo
\\bar
\\\baz
.m2ts
\\\\")", {R
"( D:\foo\bar\\baz.m2ts\\)"}},
256 {R
"(\"D
:\foo
\\bar
\\\baz
.m2ts
\\\\\")", {R"(D
:\foo
\bar
\\baz
.m2ts
\\)"}},
257 {R"(\" D
:\foo
\\bar
\\\baz
.m2ts
\\\\\")", {R"( D
:\foo
\bar
\\baz
.m2ts
\\)"}},
258 {R"(123,D
:\foo
\\bar
\\\baz
.m2ts
\\\\,abc
)", {"123", R"(D
:\foo
\bar
\\baz
.m2ts
\\)", "abc
"}},
259 {R"(123,"D:\foo\\bar\\\baz.m2ts\\\\",abc
)", {"123", R"(D
:\foo
\bar
\\baz
.m2ts
\\)", "abc
"}},
260 {R"(123," D:\foo\\bar\\\baz.m2ts\\\\",abc
)", {"123", R"( D
:\foo
\bar
\\baz
.m2ts
\\)", "abc
"}},
261 {R"(123,\"D
:\foo
\\bar
\\\baz
.m2ts
\\\\\",abc
)", {"123", R"(D
:\foo
\bar
\\baz
.m2ts
\\)", "abc
"}},
262 {R"(123,\" D
:\foo
\\bar
\\\baz
.m2ts
\\\\\",abc
)", {"123", R"( D
:\foo
\bar
\\baz
.m2ts
\\)", "abc
"}},
263 // name="value
" parameter form
264 {R"(name
="value")", {"name
=value
"}},
265 {R"(name
="value1 value2")", {"name
=value1 value2
"}},
266 {R"(name
="value1,value2")", {"name
=value1
,value2
"}},
267 {R"(name
="value1, value2")", {"name
=value1
, value2
"}},
268 {R"(name
="value1 "value2
" value3")", {R"(name
=value1
"value2 " value3
)"}},
269 {R"(name
="value1 \"value2 \" value 3")", {R"(name
=value1
"value2 " value
3)"}},
270 {R"(name
=\"value
\")", {R"(name
=value
)"}},
271 {R"("name=\"value\"")", {R"(name
="value")"}},
272 {R"(name
=value1
,value2
)", {"name
=value1
", "value2
"}},
273 {R"(foo
=bar
=value1
,value2
)", {"foo
=bar
=value1
", "value2
"}},
274 {R"(foo
=bar
="value1,value2")", {"foo
=bar
=value1
,value2
"}},
275 {R"("name=value1 value2")", {"name
=value1 value2
"}},
276 {R"(abc
, name
="value", cde
)", {"abc
", "name
=value
", "cde
"}},
279 INSTANTIATE_TEST_SUITE_P(SP, TestUtilSplitParams, ValuesIn(valuesSplitParams));