Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
StringTests.cpp
Go to the documentation of this file.
2
5
6namespace Divide
7{
8
9//TEST_FAILURE_INDENT(4);
10// We are using third party string libraries (STL, Boost, EASTL) that went through proper testing
11// This list of tests only verifies utility functions
12
13namespace detail
14{
15template<bool include>
16constexpr std::string getFile(std::string_view sv)
17{
18 if constexpr ( include )
19 {
20 if ( auto m = ctre::match<Paths::g_includePattern>(sv) )
21 {
22 return Util::Trim( m.get<1>().str() );
23 }
24 }
25 else
26 {
27 if ( auto m = ctre::match<Paths::g_usePattern>( sv ) )
28 {
29 return Util::Trim( m.get<1>().str() );
30 }
31 }
32
33 return "";
34}
35} //detail
36
37template<bool include>
38vector<string> getFiles( const string& sv )
39{
40 istringstream inputStream( sv );
41 string line;
42 vector<string> includeFiles;
43 while ( Util::GetLine(inputStream, line))
44 {
45 auto str = detail::getFile<include>(line);
46 if (!str.empty() )
47 {
48 includeFiles.emplace_back(str);
49 }
50 }
51 if (includeFiles.empty())
52 {
53 includeFiles.emplace_back(detail::getFile<include>(sv));
54 }
55 return includeFiles;
56}
57
58TEST_CASE("Regex Test", "[string_tests]")
59{
61
62 SECTION("Success")
63 {
64 {
65 const string& inputInclude1("#include \"blaBla.h\"\r");
66 const string& inputInclude2("#include <blaBla.h>");
67 const string& inputInclude3("# include \"blaBla.h\"");
68 const string& inputInclude4(" #include < blaBla.h>");
69 const string& inputInclude5("#include < blaBla.h>\n#include < blaBla2.h >\n#include \"blaBla3.h \"");
70 const string& resultInclude("blaBla.h");
71 const string& resultInclude2("blaBla2.h");
72 const string& resultInclude3("blaBla3.h");
73
74 const string temp1 = getFiles<true>(inputInclude1).front();
75 CHECK_EQUAL(resultInclude, temp1);
76
77 const string temp2 = getFiles<true>(inputInclude2).front();
78 CHECK_EQUAL(resultInclude, temp2);
79
80 const string temp3 = getFiles<true>(inputInclude3).front();
81 CHECK_EQUAL(resultInclude, temp3);
82
83 const string temp4 = getFiles<true>(inputInclude4).front();
84 CHECK_EQUAL(resultInclude, temp4);
85
86 const vector<string> temp5 = getFiles<true>( inputInclude5 );
87 CHECK_TRUE(temp5.size() == 3);
88 CHECK_EQUAL( resultInclude, temp5[0]);
89 CHECK_EQUAL( resultInclude2, temp5[1]);
90 CHECK_EQUAL( resultInclude3, temp5[2]);
91 }
92 {
93 const string& inputUse1("use(\"blaBla.h\")");
94 const string& inputUse2("use( \"blaBla.h\")");
95 const string& inputUse3(" use (\"blaBla.h\")");
96 const string& inputUse4("use(\"blaBla.h\" )");
97 const string& inputUse5( "use(\"blaBla.h\")\nuse(\"blaBla2.h\")" );
98 const string& resultUse("blaBla.h");
99 const string& resultUse2("blaBla2.h");
100
101 const string temp1 = getFiles<false>(inputUse1).front();
102 CHECK_EQUAL(resultUse, temp1);
103
104 const string temp2 = getFiles<false>(inputUse2).front();
105 CHECK_EQUAL(resultUse, temp2);
106
107 const string temp3 = getFiles<false>(inputUse3).front();
108 CHECK_EQUAL(resultUse, temp3);
109
110 const string temp4 = getFiles<false>(inputUse4).front();
111 CHECK_EQUAL(resultUse, temp4);
112
113 vector<string> temp5 = getFiles<false>(inputUse5);
114 CHECK_TRUE(temp5.size() == 2);
115 CHECK_EQUAL(resultUse, temp5[0]);
116 CHECK_EQUAL(resultUse2, temp5[1]);
117 }
118 }
119
120 SECTION( "Fail" )
121 {
122 {
123 const string& inputInclude1("#include\"blaBla.h\"");
124 const string& inputInclude2("#include<blaBla.h>");
125 const string& inputInclude3("# include \"blaBla.h");
126 const string& inputInclude4(" include < blaBla.h>");
127
128 const string temp1 = getFiles<true>(inputInclude1).front();
129 CHECK_TRUE(temp1.empty());
130 const string temp2 = getFiles<true>(inputInclude2).front();
131 CHECK_TRUE(temp2.empty() );
132 const string temp3 = getFiles<true>(inputInclude3).front();
133 CHECK_TRUE(temp3.empty() );
134 const string temp4 = getFiles<true>(inputInclude4).front();
135 CHECK_TRUE(temp4.empty() );
136 }
137 {
138 const string& inputUse1("use(\"blaBla.h)");
139 const string& inputUse2("usadfse( \"blaBla.h\")");
140 const string& inputUse3(" use --- (\"blaBla.h\")");
141
142 const string temp1 = getFiles<false>(inputUse1).front();
143 CHECK_TRUE(temp1.empty() );
144 const string temp2 = getFiles<false>(inputUse2).front();
145 CHECK_TRUE(temp2.empty() );
146 const string temp3 = getFiles<false>(inputUse3).front();
147 CHECK_TRUE(temp3.empty() );
148 }
149 }
150}
151
152TEST_CASE( "Begins With Test", "[string_tests]" )
153{
154 const string input1("STRING TO BE TESTED");
155 const string input2(" STRING TO BE TESTED");
156
157 CHECK_TRUE(Util::BeginsWith(input1, "STRING", true));
158 CHECK_TRUE(Util::BeginsWith(input2, "STRING", true));
159 CHECK_TRUE(Util::BeginsWith(input2, " STRING", false));
160 CHECK_FALSE(Util::BeginsWith(input2, "STRING", false));
161}
162
163TEST_CASE( "Replace In Place Test", "[string_tests]" )
164{
165 string input("STRING TO BE TESTED");
166
167 const string match("TO BE");
168 const string replacement("HAS BEEN");
169 const string output("STRING HAS BEEN TESTED");
170
171 Util::ReplaceStringInPlace(input, match, replacement);
172 CHECK_EQUAL(input, output);
173}
174
175TEST_CASE( "Get Permutations Test", "[string_tests]" )
176{
177 const string input("ABC");
178 vector<string> permutations;
179 Util::GetPermutations(input, permutations);
180 CHECK_TRUE(permutations.size() == 6);
181}
182
183TEST_CASE( "Parse Numbers Test", "[string_tests]" )
184{
185 const string input1("2");
186 const string input2("b");
187 CHECK_TRUE(Util::IsNumber(input1));
188 CHECK_FALSE(Util::IsNumber(input2));
189}
190
191TEST_CASE( "Trailing Characters Test", "[string_tests]" )
192{
193 const string input("abcdefg");
194 const string extension("efg");
195 CHECK_TRUE(Util::GetTrailingCharacters(input, 3) == extension);
196 CHECK_TRUE(Util::GetTrailingCharacters(input, 20) == input);
197
198 constexpr size_t length = 4;
199 CHECK_TRUE(Util::GetTrailingCharacters(input, length).size() == length);
200}
201
202TEST_CASE( "Compare (case-insensitive) Test", "[string_tests]" )
203{
204 const string inputA("aBcdEf");
205 const string inputB("ABCdef");
206 const string inputC("abcdefg");
207 CHECK_TRUE(Util::CompareIgnoreCase(inputA, inputA));
208 CHECK_TRUE(Util::CompareIgnoreCase(inputA, inputB));
209 CHECK_FALSE(Util::CompareIgnoreCase(inputB, inputC));
210}
211
212TEST_CASE( "Has Extension Test", "[string_tests]" )
213{
214 const ResourcePath input{ "something.ext" };
215 const char* ext1 = "ext";
216 const char* ext2 = "bak";
217 CHECK_TRUE(hasExtension(input, ext1));
218 CHECK_FALSE(hasExtension(input, ext2));
219}
220
221TEST_CASE( "Split Test", "[string_tests]" )
222{
223 const string input1("a b c d");
224 const vector<string> result = {"a", "b", "c", "d"};
225
226 CHECK_EQUAL((Util::Split<vector<string>, string>(input1.c_str(), ' ')), result);
227 CHECK_TRUE((Util::Split<vector<string>, string>(input1.c_str(), ',').size()) == 1);
228 CHECK_TRUE((Util::Split<vector<string>, string>(input1.c_str(), ',')[0]) == input1);
229
230 const string input2("a,b,c,d");
231 CHECK_EQUAL((Util::Split<vector<string>, string>(input2.c_str(), ',')), result);
232}
233
234TEST_CASE( "Path Split Test", "[string_tests]" )
235{
236 const ResourcePath input { "/path/path2/path4/file.test" };
237 const Str<256> result1("file.test");
238 const ResourcePath result2("/path/path2/path4");
239
240 const FileNameAndPath result3 =
241 {
242 ._fileName = result1,
243 ._path = result2
244 };
245
247
248 CHECK_EQUAL(ret, result3);
249 CHECK_EQUAL(ret._fileName, result1);
250 CHECK_EQUAL(ret._path, result2);
251}
252
253TEST_CASE( "Line Count Test", "[string_tests]" )
254{
255
256 const string input1("bla");
257 const string input2("bla\nbla");
258 const string input3("bla\nbla\nbla");
259
260 CHECK_EQUAL(Util::LineCount(input1), 1u);
261 CHECK_EQUAL(Util::LineCount(input2), 2u);
262 CHECK_EQUAL(Util::LineCount(input3), 3u);
263}
264
265TEST_CASE( "Trim Test", "[string_tests]" )
266{
267 const string input1(" abc");
268 const string input2("abc ");
269 const string input3(" abc ");
270 const string result("abc");
271
272 CHECK_EQUAL(Util::Ltrim(input1), result);
273 CHECK_EQUAL(Util::Ltrim(input2), input2);
274 CHECK_EQUAL(Util::Ltrim(input3), input2);
275 CHECK_EQUAL(Util::Ltrim(result), result);
276
277 CHECK_EQUAL(Util::Rtrim(input1), input1);
278 CHECK_EQUAL(Util::Rtrim(input2), result);
279 CHECK_EQUAL(Util::Rtrim(input3), input1);
280 CHECK_EQUAL(Util::Rtrim(result), result);
281
282 CHECK_EQUAL(Util::Trim(input1), result);
283 CHECK_EQUAL(Util::Trim(input2), result);
284 CHECK_EQUAL(Util::Trim(input3), result);
285 CHECK_EQUAL(Util::Trim(result), result);
286}
287
288TEST_CASE( "Format Test", "[string_tests]" )
289{
290 const char* input1("A {} b is {} {}");
291 const char* input2("{:2.2f}");
292 const string result1("A is ok, b is 2 \n");
293 const string result2("12.21");
294
295 CHECK_EQUAL(Util::StringFormat<string>(input1, "is ok,", 2, "\n"), result1);
296 CHECK_EQUAL(Util::StringFormat<string>(input2, 12.2111f), result2);
297}
298
299TEST_CASE( "Format Test In Place", "[string_tests]" )
300{
301 const char* input1( "A {} b is {} {}" );
302 const char* input2( "{:2.2f}" );
303 const string result1( "A is ok, b is 2 \n" );
304 const string result2( "12.21" );
305
306 string temp1;
307 string temp2;
308
309 Util::StringFormat<string>( temp1, input1, "is ok,", 2, "\n" );
310 Util::StringFormat<string>( temp2, input2, 12.2111f );
311
312 CHECK_EQUAL( temp1, result1 );
313 CHECK_EQUAL( temp2, result2 );
314}
315
316TEST_CASE( "Remove Char Test", "[string_tests]" )
317{
318 char input[] = {'a', 'b', 'c', 'b', 'd', '7', 'b', '\0' };
319 char result[] = { 'a', 'c', 'd', '7', '\0'};
320
321 Util::CStringRemoveChar(&input[0], 'b');
322
323 CHECK_EQUAL(strlen(input), strlen(result));
324
325 char* in = input;
326 char* res = result;
327 while(*in != '\0') {
328 CHECK_EQUAL(*in, *res);
329
330 in++; res++;
331 }
332}
333
334TEST_CASE( "Constexpr Hash Test", "[string_tests]" )
335{
336 constexpr const char* const str = "TEST test TEST";
337 constexpr std::string_view str2 = str;
338
339 constexpr U64 value = _ID(str);
340 CHECK_EQUAL(value, _ID(str));
341
342 constexpr U64 value2 = _ID_VIEW(str2.data(), str2.length());
343 CHECK_EQUAL(value2, value);
344
345 CHECK_EQUAL(value, "TEST test TEST"_id);
346}
347
348TEST_CASE( "Runtime Hash Test", "[string_tests]" )
349{
350 const char* str = "TEST String garbagegarbagegarbage";
351 const std::string_view str2 = str;
352
353 const U64 input1 = _ID(str);
354 const U64 input2 = _ID_VIEW(str2.data(), str2.length());
355
356 CHECK_EQUAL(input1, _ID(str));
357 CHECK_EQUAL(_ID(str), _ID(string(str).c_str()));
358 CHECK_EQUAL(input1, _ID(string(str).c_str()));
359 CHECK_EQUAL(input1, input2);
360}
361
362TEST_CASE( "Allocator Test", "[string_tests]" )
363{
364 const char* input = "TEST test TEST";
365 std::string input1(input);
366 Divide::string input2(input);
367 for( size_t i = 0; i < input1.size(); ++i)
368 {
369 CHECK_EQUAL(input1[i], input2[i]);
370 }
371}
372
373TEST_CASE( "Stringstream Test", "[string_tests]" )
374{
375 string result1;
376 stringstream s;
377 const char* input = "TEST-test-TEST";
378 s << input;
379 s >> result1;
380 CHECK_EQUAL(result1, string(input));
381}
382
383} //namespace Divide
bool GetLine(istringstream &input, T_str &line, char delimiter='\n')
void GetPermutations(std::string_view subject, vector< T_str > &permutationContainer)
bool CompareIgnoreCase(const char *a, const char *b) noexcept
bool BeginsWith(std::string_view input, std::string_view compare, bool ignoreWhitespace)
T_vec Split(const char *input, char delimiter)
http://stackoverflow.com/questions/236129/split-a-string-in-c
T_str & Trim(T_str &s)
T_str & Ltrim(T_str &s)
http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
void CStringRemoveChar(char *str, char charToRemove) noexcept
bool IsNumber(const T_str &s)
U32 LineCount(const T_str &str)
T_str & Rtrim(T_str &s)
bool ReplaceStringInPlace(T_str &subject, std::span< const std::string_view > search, std::string_view replace, bool recursive=false)
T_str GetTrailingCharacters(const T_str &input, size_t count)
constexpr std::string getFile(std::string_view sv)
Definition: StringTests.cpp:16
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
std::basic_stringstream< char, std::char_traits< char >, dvd_allocator< char > > stringstream
Definition: STLString.h:43
bool hasExtension(const ResourcePath &filePath, const std::string_view extensionNoDot)
constexpr U64 _ID_VIEW(const char *const str, const size_t len, const U64 value=val_64_const) noexcept
eastl::vector< Type > vector
Definition: Vector.h:42
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
std::basic_istringstream< char, std::char_traits< char >, dvd_allocator< char > > istringstream
Definition: STLString.h:47
std::basic_string< char, std::char_traits< char >, dvd_allocator< char > > string
Definition: STLString.h:41
vector< string > getFiles(const string &sv)
Definition: StringTests.cpp:38
TEST_CASE("ByteBuffer RW Bool", "[byte_buffer]")
uint64_t U64
FileNameAndPath splitPathToNameAndLocation(const ResourcePath &input)
#define CHECK_EQUAL(LHS, RHS)
#define CHECK_TRUE(...)