Line data Source code
1 : // Copyright (c) 2006-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/advgetopt
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // advgetopt
21 : //
22 : #include <advgetopt/utils.h>
23 :
24 : #include <advgetopt/conf_file.h>
25 : #include <advgetopt/exception.h>
26 :
27 :
28 : // self
29 : //
30 : #include "catch_main.h"
31 :
32 :
33 : // snapdev
34 : //
35 : #include <snapdev/safe_setenv.h>
36 :
37 :
38 : // C++
39 : //
40 : #include <fstream>
41 :
42 :
43 : // last include
44 : //
45 : #include <snapdev/poison.h>
46 :
47 :
48 :
49 99 : int shuffle_rand(int n)
50 : {
51 99 : return rand() % n;
52 : }
53 :
54 :
55 :
56 4 : CATCH_TEST_CASE("utils_unquote", "[utils][valid]")
57 : {
58 4 : CATCH_START_SECTION("Unquote, default pairs")
59 : {
60 1 : CATCH_REQUIRE(advgetopt::unquote("") == "");
61 1 : CATCH_REQUIRE(advgetopt::unquote("a") == "a");
62 1 : CATCH_REQUIRE(advgetopt::unquote("ab") == "ab");
63 1 : CATCH_REQUIRE(advgetopt::unquote("abc") == "abc");
64 :
65 1 : CATCH_REQUIRE(advgetopt::unquote("''") == "");
66 1 : CATCH_REQUIRE(advgetopt::unquote("'a'") == "a");
67 1 : CATCH_REQUIRE(advgetopt::unquote("'ab'") == "ab");
68 1 : CATCH_REQUIRE(advgetopt::unquote("'abc'") == "abc");
69 1 : CATCH_REQUIRE(advgetopt::unquote("'abcd'") == "abcd");
70 :
71 1 : CATCH_REQUIRE(advgetopt::unquote("\"\"") == "");
72 1 : CATCH_REQUIRE(advgetopt::unquote("\"a\"") == "a");
73 1 : CATCH_REQUIRE(advgetopt::unquote("\"ab\"") == "ab");
74 1 : CATCH_REQUIRE(advgetopt::unquote("\"abc\"") == "abc");
75 1 : CATCH_REQUIRE(advgetopt::unquote("\"abcd\"") == "abcd");
76 :
77 1 : CATCH_REQUIRE(advgetopt::unquote("\"'") == "\"'");
78 1 : CATCH_REQUIRE(advgetopt::unquote("\"a'") == "\"a'");
79 1 : CATCH_REQUIRE(advgetopt::unquote("\"ab'") == "\"ab'");
80 1 : CATCH_REQUIRE(advgetopt::unquote("\"abc'") == "\"abc'");
81 1 : CATCH_REQUIRE(advgetopt::unquote("\"abcd'") == "\"abcd'");
82 :
83 1 : CATCH_REQUIRE(advgetopt::unquote("'\"") == "'\"");
84 1 : CATCH_REQUIRE(advgetopt::unquote("'a\"") == "'a\"");
85 1 : CATCH_REQUIRE(advgetopt::unquote("'ab\"") == "'ab\"");
86 1 : CATCH_REQUIRE(advgetopt::unquote("'abc\"") == "'abc\"");
87 1 : CATCH_REQUIRE(advgetopt::unquote("'abcd\"") == "'abcd\"");
88 :
89 1 : CATCH_REQUIRE(advgetopt::unquote("\"") == "\"");
90 1 : CATCH_REQUIRE(advgetopt::unquote("\"a") == "\"a");
91 1 : CATCH_REQUIRE(advgetopt::unquote("\"ab") == "\"ab");
92 1 : CATCH_REQUIRE(advgetopt::unquote("\"abc") == "\"abc");
93 1 : CATCH_REQUIRE(advgetopt::unquote("\"abcd") == "\"abcd");
94 :
95 1 : CATCH_REQUIRE(advgetopt::unquote("'") == "'");
96 1 : CATCH_REQUIRE(advgetopt::unquote("'a") == "'a");
97 1 : CATCH_REQUIRE(advgetopt::unquote("'ab") == "'ab");
98 1 : CATCH_REQUIRE(advgetopt::unquote("'abc") == "'abc");
99 1 : CATCH_REQUIRE(advgetopt::unquote("'abcd") == "'abcd");
100 :
101 1 : CATCH_REQUIRE(advgetopt::unquote("'") == "'");
102 1 : CATCH_REQUIRE(advgetopt::unquote("a'") == "a'");
103 1 : CATCH_REQUIRE(advgetopt::unquote("ab'") == "ab'");
104 1 : CATCH_REQUIRE(advgetopt::unquote("abc'") == "abc'");
105 1 : CATCH_REQUIRE(advgetopt::unquote("abcd'") == "abcd'");
106 :
107 1 : CATCH_REQUIRE(advgetopt::unquote("\"") == "\"");
108 1 : CATCH_REQUIRE(advgetopt::unquote("a\"") == "a\"");
109 1 : CATCH_REQUIRE(advgetopt::unquote("ab\"") == "ab\"");
110 1 : CATCH_REQUIRE(advgetopt::unquote("abc\"") == "abc\"");
111 1 : CATCH_REQUIRE(advgetopt::unquote("abcd\"") == "abcd\"");
112 : }
113 : CATCH_END_SECTION()
114 :
115 4 : CATCH_START_SECTION("Unquote, brackets")
116 : {
117 1 : CATCH_REQUIRE(advgetopt::unquote("", "[]<>{}") == "");
118 1 : CATCH_REQUIRE(advgetopt::unquote("a", "[]<>{}") == "a");
119 1 : CATCH_REQUIRE(advgetopt::unquote("ab", "[]<>{}") == "ab");
120 1 : CATCH_REQUIRE(advgetopt::unquote("abc", "[]<>{}") == "abc");
121 :
122 1 : CATCH_REQUIRE(advgetopt::unquote("{}", "[]<>{}") == "");
123 1 : CATCH_REQUIRE(advgetopt::unquote("{a}", "[]<>{}") == "a");
124 1 : CATCH_REQUIRE(advgetopt::unquote("{ab}", "[]<>{}") == "ab");
125 1 : CATCH_REQUIRE(advgetopt::unquote("{abc}", "[]<>{}") == "abc");
126 1 : CATCH_REQUIRE(advgetopt::unquote("{abcd}", "[]<>{}") == "abcd");
127 :
128 1 : CATCH_REQUIRE(advgetopt::unquote("[]", "[]<>{}") == "");
129 1 : CATCH_REQUIRE(advgetopt::unquote("[a]", "[]<>{}") == "a");
130 1 : CATCH_REQUIRE(advgetopt::unquote("[ab]", "[]<>{}") == "ab");
131 1 : CATCH_REQUIRE(advgetopt::unquote("[abc]", "[]<>{}") == "abc");
132 1 : CATCH_REQUIRE(advgetopt::unquote("[abcd]", "[]<>{}") == "abcd");
133 :
134 1 : CATCH_REQUIRE(advgetopt::unquote("<>", "[]<>{}") == "");
135 1 : CATCH_REQUIRE(advgetopt::unquote("<a>", "[]<>{}") == "a");
136 1 : CATCH_REQUIRE(advgetopt::unquote("<ab>", "[]<>{}") == "ab");
137 1 : CATCH_REQUIRE(advgetopt::unquote("<abc>", "[]<>{}") == "abc");
138 1 : CATCH_REQUIRE(advgetopt::unquote("<abcd>", "[]<>{}") == "abcd");
139 :
140 1 : CATCH_REQUIRE(advgetopt::unquote("[}", "[]<>{}") == "[}");
141 1 : CATCH_REQUIRE(advgetopt::unquote("[a}", "[]<>{}") == "[a}");
142 1 : CATCH_REQUIRE(advgetopt::unquote("[ab}", "[]<>{}") == "[ab}");
143 1 : CATCH_REQUIRE(advgetopt::unquote("[abc}", "[]<>{}") == "[abc}");
144 1 : CATCH_REQUIRE(advgetopt::unquote("[abcd}", "[]<>{}") == "[abcd}");
145 :
146 1 : CATCH_REQUIRE(advgetopt::unquote("[>", "[]<>{}") == "[>");
147 1 : CATCH_REQUIRE(advgetopt::unquote("[a>", "[]<>{}") == "[a>");
148 1 : CATCH_REQUIRE(advgetopt::unquote("[ab>", "[]<>{}") == "[ab>");
149 1 : CATCH_REQUIRE(advgetopt::unquote("[abc>", "[]<>{}") == "[abc>");
150 1 : CATCH_REQUIRE(advgetopt::unquote("[abcd>", "[]<>{}") == "[abcd>");
151 :
152 1 : CATCH_REQUIRE(advgetopt::unquote("'\"", "[]<>{}") == "'\"");
153 1 : CATCH_REQUIRE(advgetopt::unquote("'a\"", "[]<>{}") == "'a\"");
154 1 : CATCH_REQUIRE(advgetopt::unquote("'ab\"", "[]<>{}") == "'ab\"");
155 1 : CATCH_REQUIRE(advgetopt::unquote("'abc\"", "[]<>{}") == "'abc\"");
156 1 : CATCH_REQUIRE(advgetopt::unquote("'abcd\"", "[]<>{}") == "'abcd\"");
157 :
158 1 : CATCH_REQUIRE(advgetopt::unquote("[", "[]<>{}") == "[");
159 1 : CATCH_REQUIRE(advgetopt::unquote("[a", "[]<>{}") == "[a");
160 1 : CATCH_REQUIRE(advgetopt::unquote("[ab", "[]<>{}") == "[ab");
161 1 : CATCH_REQUIRE(advgetopt::unquote("[abc", "[]<>{}") == "[abc");
162 1 : CATCH_REQUIRE(advgetopt::unquote("[abcd", "[]<>{}") == "[abcd");
163 :
164 1 : CATCH_REQUIRE(advgetopt::unquote("{", "[]<>{}") == "{");
165 1 : CATCH_REQUIRE(advgetopt::unquote("{a", "[]<>{}") == "{a");
166 1 : CATCH_REQUIRE(advgetopt::unquote("{ab", "[]<>{}") == "{ab");
167 1 : CATCH_REQUIRE(advgetopt::unquote("{abc", "[]<>{}") == "{abc");
168 1 : CATCH_REQUIRE(advgetopt::unquote("{abcd", "[]<>{}") == "{abcd");
169 :
170 1 : CATCH_REQUIRE(advgetopt::unquote("<", "[]<>{}") == "<");
171 1 : CATCH_REQUIRE(advgetopt::unquote("<a", "[]<>{}") == "<a");
172 1 : CATCH_REQUIRE(advgetopt::unquote("<ab", "[]<>{}") == "<ab");
173 1 : CATCH_REQUIRE(advgetopt::unquote("<abc", "[]<>{}") == "<abc");
174 1 : CATCH_REQUIRE(advgetopt::unquote("<abcd", "[]<>{}") == "<abcd");
175 :
176 1 : CATCH_REQUIRE(advgetopt::unquote("}", "[]<>{}") == "}");
177 1 : CATCH_REQUIRE(advgetopt::unquote("a}", "[]<>{}") == "a}");
178 1 : CATCH_REQUIRE(advgetopt::unquote("ab}", "[]<>{}") == "ab}");
179 1 : CATCH_REQUIRE(advgetopt::unquote("abc}", "[]<>{}") == "abc}");
180 1 : CATCH_REQUIRE(advgetopt::unquote("abcd}", "[]<>{}") == "abcd}");
181 :
182 1 : CATCH_REQUIRE(advgetopt::unquote("]", "[]<>{}") == "]");
183 1 : CATCH_REQUIRE(advgetopt::unquote("a]", "[]<>{}") == "a]");
184 1 : CATCH_REQUIRE(advgetopt::unquote("ab]", "[]<>{}") == "ab]");
185 1 : CATCH_REQUIRE(advgetopt::unquote("abc]", "[]<>{}") == "abc]");
186 1 : CATCH_REQUIRE(advgetopt::unquote("abcd]", "[]<>{}") == "abcd]");
187 :
188 1 : CATCH_REQUIRE(advgetopt::unquote(">", "[]<>{}") == ">");
189 1 : CATCH_REQUIRE(advgetopt::unquote("a>", "[]<>{}") == "a>");
190 1 : CATCH_REQUIRE(advgetopt::unquote("ab>", "[]<>{}") == "ab>");
191 1 : CATCH_REQUIRE(advgetopt::unquote("abc>", "[]<>{}") == "abc>");
192 1 : CATCH_REQUIRE(advgetopt::unquote("abcd>", "[]<>{}") == "abcd>");
193 : }
194 : CATCH_END_SECTION()
195 2 : }
196 :
197 :
198 :
199 :
200 3 : CATCH_TEST_CASE("utils_quote", "[utils][valid]")
201 : {
202 2 : CATCH_START_SECTION("Quote, default pairs")
203 : {
204 1 : CATCH_REQUIRE(advgetopt::quote("") == "\"\"");
205 1 : CATCH_REQUIRE(advgetopt::quote("a") == "\"a\"");
206 1 : CATCH_REQUIRE(advgetopt::quote("ab") == "\"ab\"");
207 1 : CATCH_REQUIRE(advgetopt::quote("abc") == "\"abc\"");
208 :
209 1 : CATCH_REQUIRE(advgetopt::quote("", '"') == "\"\"");
210 1 : CATCH_REQUIRE(advgetopt::quote("a", '"') == "\"a\"");
211 1 : CATCH_REQUIRE(advgetopt::quote("ab", '"') == "\"ab\"");
212 1 : CATCH_REQUIRE(advgetopt::quote("abc", '"') == "\"abc\"");
213 1 : CATCH_REQUIRE(advgetopt::quote("abcd", '"') == "\"abcd\"");
214 :
215 1 : CATCH_REQUIRE(advgetopt::quote("", '\'') == "''");
216 1 : CATCH_REQUIRE(advgetopt::quote("a", '\'') == "'a'");
217 1 : CATCH_REQUIRE(advgetopt::quote("ab", '\'') == "'ab'");
218 1 : CATCH_REQUIRE(advgetopt::quote("abc", '\'') == "'abc'");
219 1 : CATCH_REQUIRE(advgetopt::quote("abcd", '\'') == "'abcd'");
220 :
221 1 : CATCH_REQUIRE(advgetopt::quote("", '[', ']') == "[]");
222 1 : CATCH_REQUIRE(advgetopt::quote("a", '[', ']') == "[a]");
223 1 : CATCH_REQUIRE(advgetopt::quote("ab", '[', ']') == "[ab]");
224 1 : CATCH_REQUIRE(advgetopt::quote("abc", '[', ']') == "[abc]");
225 1 : CATCH_REQUIRE(advgetopt::quote("abcd", '[', ']') == "[abcd]");
226 :
227 1 : CATCH_REQUIRE(advgetopt::quote("[]", '[', ']') == "[\\[\\]]");
228 1 : CATCH_REQUIRE(advgetopt::quote("[a]", '[', ']') == "[\\[a\\]]");
229 1 : CATCH_REQUIRE(advgetopt::quote("[ab]", '[', ']') == "[\\[ab\\]]");
230 1 : CATCH_REQUIRE(advgetopt::quote("[abc]", '[', ']') == "[\\[abc\\]]");
231 1 : CATCH_REQUIRE(advgetopt::quote("[abcd]", '[', ']') == "[\\[abcd\\]]");
232 : }
233 : CATCH_END_SECTION()
234 1 : }
235 :
236 :
237 :
238 :
239 13 : CATCH_TEST_CASE("utils_split", "[utils][valid]")
240 : {
241 22 : CATCH_START_SECTION("Split three words")
242 2 : advgetopt::string_list_t result;
243 2 : advgetopt::split_string("test with spaces"
244 : , result
245 1 : , {" "});
246 1 : CATCH_REQUIRE(result.size() == 3);
247 1 : CATCH_REQUIRE(result[0] == "test");
248 1 : CATCH_REQUIRE(result[1] == "with");
249 1 : CATCH_REQUIRE(result[2] == "spaces");
250 : CATCH_END_SECTION()
251 :
252 22 : CATCH_START_SECTION("Split three words, one with single quotes")
253 2 : advgetopt::string_list_t result;
254 2 : advgetopt::split_string("test 'with quotes and' spaces"
255 : , result
256 1 : , {" "});
257 1 : CATCH_REQUIRE(result.size() == 3);
258 1 : CATCH_REQUIRE(result[0] == "test");
259 1 : CATCH_REQUIRE(result[1] == "with quotes and");
260 1 : CATCH_REQUIRE(result[2] == "spaces");
261 : CATCH_END_SECTION()
262 :
263 22 : CATCH_START_SECTION("Split three words, one with double quotes")
264 2 : advgetopt::string_list_t result;
265 2 : advgetopt::split_string("test \"with quotes and\" spaces"
266 : , result
267 1 : , {" "});
268 1 : CATCH_REQUIRE(result.size() == 3);
269 1 : CATCH_REQUIRE(result[0] == "test");
270 1 : CATCH_REQUIRE(result[1] == "with quotes and");
271 1 : CATCH_REQUIRE(result[2] == "spaces");
272 : CATCH_END_SECTION()
273 :
274 22 : CATCH_START_SECTION("Split three words, one with single quotes but no spaces")
275 2 : advgetopt::string_list_t result;
276 2 : advgetopt::split_string("test'with quotes and'nospaces"
277 : , result
278 1 : , {" "});
279 1 : CATCH_REQUIRE(result.size() == 3);
280 1 : CATCH_REQUIRE(result[0] == "test");
281 1 : CATCH_REQUIRE(result[1] == "with quotes and");
282 1 : CATCH_REQUIRE(result[2] == "nospaces");
283 : CATCH_END_SECTION()
284 :
285 22 : CATCH_START_SECTION("Split three words, one with double quotes but no spaces")
286 2 : advgetopt::string_list_t result;
287 2 : advgetopt::split_string("test\"with quotes and\"nospaces"
288 : , result
289 1 : , {" "});
290 1 : CATCH_REQUIRE(result.size() == 3);
291 1 : CATCH_REQUIRE(result[0] == "test");
292 1 : CATCH_REQUIRE(result[1] == "with quotes and");
293 1 : CATCH_REQUIRE(result[2] == "nospaces");
294 : CATCH_END_SECTION()
295 :
296 22 : CATCH_START_SECTION("Split five words, four separators")
297 2 : advgetopt::string_list_t result;
298 5 : advgetopt::split_string("test,with quite|many;separators"
299 : , result
300 4 : , {" ",",","|",";"});
301 1 : CATCH_REQUIRE(result.size() == 5);
302 1 : CATCH_REQUIRE(result[0] == "test");
303 1 : CATCH_REQUIRE(result[1] == "with");
304 1 : CATCH_REQUIRE(result[2] == "quite");
305 1 : CATCH_REQUIRE(result[3] == "many");
306 1 : CATCH_REQUIRE(result[4] == "separators");
307 : CATCH_END_SECTION()
308 :
309 22 : CATCH_START_SECTION("Split five words, multiple/repeated separators")
310 2 : advgetopt::string_list_t result;
311 5 : advgetopt::split_string("test, with quite|||many ; separators"
312 : , result
313 4 : , {" ",",","|",";"});
314 1 : CATCH_REQUIRE(result.size() == 5);
315 1 : CATCH_REQUIRE(result[0] == "test");
316 1 : CATCH_REQUIRE(result[1] == "with");
317 1 : CATCH_REQUIRE(result[2] == "quite");
318 1 : CATCH_REQUIRE(result[3] == "many");
319 1 : CATCH_REQUIRE(result[4] == "separators");
320 : CATCH_END_SECTION()
321 :
322 22 : CATCH_START_SECTION("Split five words, and empty entries")
323 2 : advgetopt::string_list_t result;
324 5 : advgetopt::split_string("|||test, with quite\"\"many ; ''separators''"
325 : , result
326 4 : , {" ",",","|",";"});
327 1 : CATCH_REQUIRE(result.size() == 5);
328 1 : CATCH_REQUIRE(result[0] == "test");
329 1 : CATCH_REQUIRE(result[1] == "with");
330 1 : CATCH_REQUIRE(result[2] == "quite");
331 1 : CATCH_REQUIRE(result[3] == "many");
332 1 : CATCH_REQUIRE(result[4] == "separators");
333 : CATCH_END_SECTION()
334 :
335 22 : CATCH_START_SECTION("Split five words, start/end with separator")
336 2 : advgetopt::string_list_t result;
337 2 : advgetopt::split_string("|start|and|end|with|separator|"
338 : , result
339 1 : , {"|"});
340 1 : CATCH_REQUIRE(result.size() == 5);
341 1 : CATCH_REQUIRE(result[0] == "start");
342 1 : CATCH_REQUIRE(result[1] == "and");
343 1 : CATCH_REQUIRE(result[2] == "end");
344 1 : CATCH_REQUIRE(result[3] == "with");
345 1 : CATCH_REQUIRE(result[4] == "separator");
346 : CATCH_END_SECTION()
347 :
348 22 : CATCH_START_SECTION("Split five words, unclosed double quote")
349 2 : advgetopt::string_list_t result;
350 2 : advgetopt::split_string("\"unclosed quote|mark"
351 : , result
352 1 : , {"|"});
353 1 : CATCH_REQUIRE(result.size() == 1);
354 1 : CATCH_REQUIRE(result[0] == "unclosed quote|mark");
355 : CATCH_END_SECTION()
356 :
357 22 : CATCH_START_SECTION("Split five words, unclosed single quote")
358 2 : advgetopt::string_list_t result;
359 3 : advgetopt::split_string("here is an \"unclosed quote|mark"
360 : , result
361 2 : , {"|"," "});
362 : //CATCH_REQUIRE(result.size() == 4);
363 1 : CATCH_REQUIRE(result[0] == "here");
364 1 : CATCH_REQUIRE(result[1] == "is");
365 1 : CATCH_REQUIRE(result[2] == "an");
366 1 : CATCH_REQUIRE(result[3] == "unclosed quote|mark");
367 : CATCH_END_SECTION()
368 11 : }
369 :
370 :
371 :
372 :
373 7 : CATCH_TEST_CASE("utils_insert_group_name", "[utils][valid]")
374 : {
375 10 : CATCH_START_SECTION("utils_insert_group_name: Full insert")
376 : {
377 : // CONFIG FILE HAS NO EXTENSION
378 : {
379 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
380 : "/this/is/a/path"
381 : , "group-name"
382 2 : , "project-name"));
383 1 : CATCH_REQUIRE(fullname.size() == 1);
384 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/group-name.d/50-path");
385 : }
386 :
387 : {
388 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
389 : "/this/is/a/path"
390 : , "group-name"
391 2 : , ""));
392 1 : CATCH_REQUIRE(fullname.size() == 1);
393 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/group-name.d/50-path");
394 : }
395 :
396 : {
397 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
398 : "/this/is/a/path"
399 : , "group-name"
400 2 : , nullptr));
401 1 : CATCH_REQUIRE(fullname.size() == 1);
402 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/group-name.d/50-path");
403 : }
404 :
405 : {
406 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
407 : "/this/is/a/path"
408 : , ""
409 2 : , "project-name"));
410 1 : CATCH_REQUIRE(fullname.size() == 1);
411 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/project-name.d/50-path");
412 : }
413 :
414 : {
415 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
416 : "/this/is/a/path"
417 : , nullptr
418 2 : , "project-name"));
419 1 : CATCH_REQUIRE(fullname.size() == 1);
420 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/project-name.d/50-path");
421 : }
422 :
423 : // CONFIG FILE HAS EXTENSION
424 : {
425 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
426 : "/this/is/a/basename.ext"
427 : , "group-name"
428 2 : , "project-name"));
429 1 : CATCH_REQUIRE(fullname.size() == 1);
430 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/group-name.d/50-basename.ext");
431 : }
432 :
433 : {
434 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
435 : "/this/is/a/basename.ext"
436 : , "group-name"
437 2 : , ""));
438 1 : CATCH_REQUIRE(fullname.size() == 1);
439 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/group-name.d/50-basename.ext");
440 : }
441 :
442 : {
443 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
444 : "/this/is/a/basename.ext"
445 : , "group-name"
446 2 : , nullptr));
447 1 : CATCH_REQUIRE(fullname.size() == 1);
448 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/group-name.d/50-basename.ext");
449 : }
450 :
451 : {
452 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
453 : "/this/is/a/basename.ext"
454 : , ""
455 2 : , "project-name"));
456 1 : CATCH_REQUIRE(fullname.size() == 1);
457 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/project-name.d/50-basename.ext");
458 : }
459 :
460 : {
461 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
462 : "/this/is/a/basename.ext"
463 : , nullptr
464 2 : , "project-name"));
465 1 : CATCH_REQUIRE(fullname.size() == 1);
466 1 : CATCH_REQUIRE(fullname[0] == "/this/is/a/project-name.d/50-basename.ext");
467 : }
468 : }
469 : CATCH_END_SECTION()
470 :
471 10 : CATCH_START_SECTION("utils_insert_group_name: Empty cases")
472 : {
473 : {
474 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
475 : "/this/is/a/path"
476 : , nullptr
477 2 : , nullptr));
478 1 : CATCH_REQUIRE(fullname.empty());
479 : }
480 :
481 : {
482 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
483 : "/this/is/a/path"
484 : , nullptr
485 2 : , ""));
486 1 : CATCH_REQUIRE(fullname.empty());
487 : }
488 :
489 : {
490 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
491 : "/this/is/a/path"
492 : , ""
493 2 : , nullptr));
494 1 : CATCH_REQUIRE(fullname.empty());
495 : }
496 :
497 : {
498 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
499 : "/this/is/a/path"
500 : , ""
501 2 : , ""));
502 1 : CATCH_REQUIRE(fullname.empty());
503 : }
504 :
505 : {
506 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
507 : ""
508 : , "group-name"
509 2 : , "project-name"));
510 1 : CATCH_REQUIRE(fullname.empty());
511 : }
512 :
513 : {
514 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
515 : ""
516 : , ""
517 2 : , "project-name"));
518 1 : CATCH_REQUIRE(fullname.empty());
519 : }
520 :
521 : {
522 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
523 : ""
524 : , nullptr
525 2 : , "project-name"));
526 1 : CATCH_REQUIRE(fullname.empty());
527 : }
528 :
529 : {
530 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
531 : ""
532 : , nullptr
533 2 : , ""));
534 1 : CATCH_REQUIRE(fullname.empty());
535 : }
536 :
537 : {
538 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
539 : ""
540 : , nullptr
541 2 : , nullptr));
542 1 : CATCH_REQUIRE(fullname.empty());
543 : }
544 : }
545 : CATCH_END_SECTION()
546 :
547 10 : CATCH_START_SECTION("utils_insert_group_name: cases")
548 : {
549 1 : CATCH_REQUIRE_THROWS_MATCHES(advgetopt::insert_group_name(
550 : "/this-is-a-path"
551 : , "group"
552 : , "project")
553 : , advgetopt::getopt_root_filename
554 : , Catch::Matchers::ExceptionMessage(
555 : "getopt_exception: filename \"/this-is-a-path\" last slash (/) is at the start, which is not allowed."));
556 : }
557 : CATCH_END_SECTION()
558 :
559 10 : CATCH_START_SECTION("utils_insert_group_name: Basename Only")
560 : {
561 : {
562 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
563 : "basename"
564 : , nullptr
565 2 : , "advgetopt"));
566 1 : CATCH_REQUIRE(fullname.size() == 1);
567 1 : CATCH_REQUIRE(fullname[0] == "advgetopt.d/50-basename");
568 : }
569 :
570 : {
571 1 : advgetopt::string_list_t fullname(advgetopt::insert_group_name(
572 : "basename.ext"
573 : , "advgetopt"
574 2 : , nullptr));
575 1 : CATCH_REQUIRE(fullname.size() == 1);
576 1 : CATCH_REQUIRE(fullname[0] == "advgetopt.d/50-basename.ext");
577 : }
578 : }
579 : CATCH_END_SECTION()
580 :
581 10 : CATCH_START_SECTION("utils_insert_group_name: Actual List of Files on Disk")
582 : {
583 1 : SNAP_CATCH2_NAMESPACE::init_tmp_dir("advgetopt-multi", "sorted-user-conf", false);
584 :
585 : // generate an array of numbers from 00 to 99
586 : //
587 2 : std::vector<int> numbers;
588 101 : for(int i = 0; i < 100; ++i)
589 : {
590 100 : numbers.push_back(i);
591 : }
592 1 : std::random_shuffle(numbers.begin(), numbers.end(), shuffle_rand);
593 1 : int const max(rand() % 50 + 10);
594 1 : numbers.resize(max);
595 2 : std::string path(SNAP_CATCH2_NAMESPACE::g_config_project_filename);
596 1 : std::string::size_type const pos(path.rfind('/'));
597 1 : path = path.substr(0, pos);
598 2 : advgetopt::string_list_t filenames;
599 24 : for(int i = 0; i < max; ++i)
600 : {
601 46 : std::stringstream ss;
602 23 : ss << path;
603 23 : ss << '/';
604 23 : int const n(numbers[i]);
605 23 : if(n < 10)
606 : {
607 2 : ss << '0';
608 : }
609 23 : ss << n;
610 23 : ss << "-sorted-user-conf.config";
611 23 : filenames.push_back(ss.str());
612 46 : std::ofstream conf;
613 23 : conf.open(ss.str(), std::ios_base::out);
614 23 : CATCH_REQUIRE(conf.is_open());
615 23 : conf << "# Config with a number" << std::endl;
616 23 : conf << "var=\"value: " << numbers[i] << "\"" << std::endl;
617 : }
618 1 : std::sort(filenames.begin(), filenames.end());
619 2 : std::string const last_filename(*filenames.rbegin());
620 1 : std::string::size_type const slash_pos(last_filename.rfind('/'));
621 2 : std::string const expected_var("value: " + last_filename.substr(slash_pos + 1, 2));
622 :
623 1 : advgetopt::string_list_t fullnames(advgetopt::insert_group_name(
624 : SNAP_CATCH2_NAMESPACE::g_config_filename
625 : , "advgetopt-multi"
626 2 : , "multi-channels"));
627 1 : CATCH_REQUIRE(fullnames.size() == filenames.size());
628 24 : for(size_t idx(0); idx < filenames.size(); ++idx)
629 : {
630 23 : CATCH_REQUIRE(fullnames[idx] == filenames[idx]);
631 : }
632 :
633 : {
634 2 : std::ofstream conf;
635 1 : conf.open(SNAP_CATCH2_NAMESPACE::g_config_filename, std::ios_base::out);
636 1 : CATCH_REQUIRE(conf.is_open());
637 1 : conf << "# Original Config with a number" << std::endl;
638 1 : conf << "var=master value" << std::endl;
639 :
640 : // verify the master config file
641 : //
642 2 : advgetopt::conf_file_setup setup(SNAP_CATCH2_NAMESPACE::g_config_filename);
643 2 : advgetopt::conf_file::pointer_t config_file(advgetopt::conf_file::get_conf_file(setup));
644 1 : CATCH_REQUIRE(config_file->get_parameter("var") == "master value");
645 : }
646 :
647 : {
648 : // run a load to verify that we indeed get the last var=...
649 : // value and not some random entry
650 : //
651 2 : std::string temp_dir = SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/.config";
652 1 : char const * const dirs[] = {
653 1 : temp_dir.c_str(),
654 : nullptr
655 1 : };
656 1 : advgetopt::option opts[] = {
657 : advgetopt::define_option(
658 : advgetopt::Name("var")
659 : , advgetopt::Flags(advgetopt::all_flags<advgetopt::GETOPT_FLAG_SHOW_USAGE_ON_ERROR>())
660 : , advgetopt::Help("verify loading configuration files in a serie.")
661 : ),
662 : advgetopt::end_options()
663 : };
664 : #pragma GCC diagnostic push
665 : #pragma GCC diagnostic ignored "-Wpedantic"
666 1 : advgetopt::options_environment env = {
667 : .f_project_name = "sorted-configs",
668 : .f_group_name = "advgetopt-multi",
669 : .f_options = opts,
670 : .f_options_files_directory = nullptr,
671 : .f_environment_variable_name = nullptr,
672 : .f_environment_variable_intro = nullptr,
673 : .f_section_variables_name = nullptr,
674 : .f_configuration_files = nullptr,
675 : .f_configuration_filename = "sorted-user-conf.config",
676 : .f_configuration_directories = dirs,
677 : .f_environment_flags = advgetopt::GETOPT_ENVIRONMENT_FLAG_PROCESS_SYSTEM_PARAMETERS,
678 : .f_help_header = nullptr,
679 : .f_help_footer = nullptr,
680 : .f_version = nullptr,
681 : .f_license = nullptr,
682 : .f_copyright = nullptr,
683 : .f_build_date = UTC_BUILD_DATE,
684 : .f_build_time = UTC_BUILD_TIME,
685 : .f_groups = nullptr
686 1 : };
687 : #pragma GCC diagnostic pop
688 1 : char const * const argv[] = {
689 : "test",
690 : nullptr
691 : };
692 2 : advgetopt::getopt opt(env, 1, const_cast<char **>(argv));
693 1 : CATCH_REQUIRE(memcmp(&opt.get_options_environment(), &env, sizeof(env)) == 0);
694 1 : CATCH_REQUIRE(opt.get_string("var") == expected_var);
695 : }
696 : }
697 : CATCH_END_SECTION()
698 5 : }
699 :
700 :
701 7 : CATCH_TEST_CASE("utils_default_group_name", "[utils][valid]")
702 : {
703 10 : CATCH_START_SECTION("utils_default_group_name: Full insert")
704 : {
705 : // CONFIG FILE HAS NO EXTENSION
706 : {
707 1 : std::string const fullname(advgetopt::default_group_name(
708 : "/this/is/a/config"
709 : , "group-name"
710 2 : , "project-name"));
711 1 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/50-config");
712 : }
713 :
714 : {
715 1 : std::string const fullname(advgetopt::default_group_name(
716 : "/this/is/a/advgetopt"
717 : , "group-name"
718 2 : , ""));
719 1 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/50-advgetopt");
720 : }
721 :
722 : {
723 1 : std::string const fullname(advgetopt::default_group_name(
724 : "/this/is/a/complete"
725 : , "group-name"
726 2 : , nullptr));
727 1 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/50-complete");
728 : }
729 :
730 : {
731 1 : std::string const fullname(advgetopt::default_group_name(
732 : "/this/is/a/swapped"
733 : , ""
734 2 : , "project-name"));
735 1 : CATCH_REQUIRE(fullname == "/this/is/a/project-name.d/50-swapped");
736 : }
737 :
738 : {
739 1 : std::string const fullname(advgetopt::default_group_name(
740 : "/this/is/a/null"
741 : , nullptr
742 2 : , "project-name"));
743 1 : CATCH_REQUIRE(fullname == "/this/is/a/project-name.d/50-null");
744 : }
745 :
746 : // CONFIG FILE HAS EXTENSION
747 : {
748 1 : std::string const fullname(advgetopt::default_group_name(
749 : "/this/is/a/basename.ext"
750 : , "group-name"
751 2 : , "project-name"));
752 1 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/50-basename.ext");
753 : }
754 :
755 : {
756 1 : std::string const fullname(advgetopt::default_group_name(
757 : "/this/is/a/basename.ext"
758 : , "group-name"
759 2 : , ""));
760 1 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/50-basename.ext");
761 : }
762 :
763 : {
764 1 : std::string const fullname(advgetopt::default_group_name(
765 : "/this/is/a/basename.ext"
766 : , "group-name"
767 2 : , nullptr));
768 1 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/50-basename.ext");
769 : }
770 :
771 : {
772 1 : std::string const fullname(advgetopt::default_group_name(
773 : "/this/is/a/basename.ext"
774 : , ""
775 2 : , "project-name"));
776 1 : CATCH_REQUIRE(fullname == "/this/is/a/project-name.d/50-basename.ext");
777 : }
778 :
779 : {
780 1 : std::string const fullname(advgetopt::default_group_name(
781 : "/this/is/a/basename.ext"
782 : , nullptr
783 2 : , "project-name"));
784 1 : CATCH_REQUIRE(fullname == "/this/is/a/project-name.d/50-basename.ext");
785 : }
786 :
787 : // verify all valid priorities
788 : //
789 11 : for(int priority(0); priority < 10; ++priority)
790 : {
791 10 : std::string const fullname(advgetopt::default_group_name(
792 : "/this/is/a/basename.ext"
793 : , "group-name"
794 : , "project-name"
795 20 : , priority));
796 10 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/0"
797 : + std::to_string(priority)
798 : + "-basename.ext");
799 : }
800 91 : for(int priority(10); priority < 100; ++priority)
801 : {
802 90 : std::string const fullname(advgetopt::default_group_name(
803 : "/this/is/a/basename.ext"
804 : , "group-name"
805 : , "project-name"
806 180 : , priority));
807 90 : CATCH_REQUIRE(fullname == "/this/is/a/group-name.d/"
808 : + std::to_string(priority)
809 : + "-basename.ext");
810 : }
811 : }
812 : CATCH_END_SECTION()
813 :
814 10 : CATCH_START_SECTION("utils_default_group_name: Empty cases")
815 : {
816 : {
817 1 : std::string const fullname(advgetopt::default_group_name(
818 : "/this/is/a/path"
819 : , nullptr
820 2 : , nullptr));
821 1 : CATCH_REQUIRE(fullname.empty());
822 : }
823 :
824 : {
825 1 : std::string const fullname(advgetopt::default_group_name(
826 : "/this/is/a/path"
827 : , nullptr
828 2 : , ""));
829 1 : CATCH_REQUIRE(fullname.empty());
830 : }
831 :
832 : {
833 1 : std::string const fullname(advgetopt::default_group_name(
834 : "/this/is/a/path"
835 : , ""
836 2 : , nullptr));
837 1 : CATCH_REQUIRE(fullname.empty());
838 : }
839 :
840 : {
841 1 : std::string const fullname(advgetopt::default_group_name(
842 : "/this/is/a/path"
843 : , ""
844 2 : , ""));
845 1 : CATCH_REQUIRE(fullname.empty());
846 : }
847 :
848 : {
849 1 : std::string const fullname(advgetopt::default_group_name(
850 : ""
851 : , "group-name"
852 2 : , "project-name"));
853 1 : CATCH_REQUIRE(fullname.empty());
854 : }
855 :
856 : {
857 1 : std::string const fullname(advgetopt::default_group_name(
858 : ""
859 : , ""
860 2 : , "project-name"));
861 1 : CATCH_REQUIRE(fullname.empty());
862 : }
863 :
864 : {
865 1 : std::string const fullname(advgetopt::default_group_name(
866 : ""
867 : , nullptr
868 2 : , "project-name"));
869 1 : CATCH_REQUIRE(fullname.empty());
870 : }
871 :
872 : {
873 1 : std::string const fullname(advgetopt::default_group_name(
874 : ""
875 : , nullptr
876 2 : , ""));
877 1 : CATCH_REQUIRE(fullname.empty());
878 : }
879 :
880 : {
881 1 : std::string const fullname(advgetopt::default_group_name(
882 : ""
883 : , nullptr
884 2 : , nullptr));
885 1 : CATCH_REQUIRE(fullname.empty());
886 : }
887 : }
888 : CATCH_END_SECTION()
889 :
890 10 : CATCH_START_SECTION("utils_default_group_name: single '/' at the start")
891 : {
892 1 : CATCH_REQUIRE_THROWS_MATCHES(advgetopt::default_group_name(
893 : "/this-is-a-path"
894 : , "group"
895 : , "project")
896 : , advgetopt::getopt_root_filename
897 : , Catch::Matchers::ExceptionMessage(
898 : "getopt_exception: filename \"/this-is-a-path\" starts with a slash (/), which is not allowed."));
899 : }
900 : CATCH_END_SECTION()
901 :
902 10 : CATCH_START_SECTION("utils_default_group_name: invalid priority")
903 : {
904 : // verify that negative priorities are prevented
905 : //
906 21 : for(int priority(-20); priority < 0; ++priority)
907 : {
908 20 : CATCH_REQUIRE_THROWS_MATCHES(advgetopt::default_group_name(
909 : "/this/is/a/basename.ext"
910 : , ((rand() & 1) == 0 ? "group-name" : nullptr)
911 : , "project-name"
912 : , priority)
913 : , advgetopt::getopt_invalid_parameter
914 : , Catch::Matchers::ExceptionMessage(
915 : "getopt_exception: priority must be a number between 0 and 99 inclusive; "
916 : + std::to_string(priority)
917 : + " is invalid."));
918 : }
919 :
920 : // verify that large priorities are prevented
921 : //
922 21 : for(int priority(100); priority < 120; ++priority)
923 : {
924 20 : CATCH_REQUIRE_THROWS_MATCHES(advgetopt::default_group_name(
925 : "/this/is/a/basename.ext"
926 : , ((rand() & 1) == 0 ? "group-name" : nullptr)
927 : , "project-name"
928 : , priority)
929 : , advgetopt::getopt_invalid_parameter
930 : , Catch::Matchers::ExceptionMessage(
931 : "getopt_exception: priority must be a number between 0 and 99 inclusive; "
932 : + std::to_string(priority)
933 : + " is invalid."));
934 : }
935 : }
936 : CATCH_END_SECTION()
937 :
938 10 : CATCH_START_SECTION("utils_default_group_name: Basename Only")
939 : {
940 : {
941 1 : std::string const fullname(advgetopt::default_group_name(
942 : "basename"
943 : , nullptr
944 2 : , "advgetopt"));
945 1 : CATCH_REQUIRE(fullname == "advgetopt.d/50-basename");
946 : }
947 :
948 : {
949 1 : std::string const fullname(advgetopt::default_group_name(
950 : "basename.ext"
951 : , "advgetopt"
952 2 : , nullptr));
953 1 : CATCH_REQUIRE(fullname == "advgetopt.d/50-basename.ext");
954 : }
955 : }
956 : CATCH_END_SECTION()
957 5 : }
958 :
959 :
960 :
961 :
962 :
963 :
964 :
965 5 : CATCH_TEST_CASE("utils_handle_user_directory", "[utils][valid]")
966 : {
967 6 : CATCH_START_SECTION("Valid cases")
968 2 : snapdev::safe_setenv env("HOME", "/home/advgetopt");
969 :
970 : {
971 2 : std::string result(advgetopt::handle_user_directory("~"));
972 1 : CATCH_REQUIRE(result == "/home/advgetopt");
973 : }
974 :
975 : {
976 2 : std::string result(advgetopt::handle_user_directory("~/"));
977 1 : CATCH_REQUIRE(result == "/home/advgetopt/");
978 : }
979 :
980 : {
981 2 : std::string result(advgetopt::handle_user_directory("~/.config/advgetopt.conf"));
982 1 : CATCH_REQUIRE(result == "/home/advgetopt/.config/advgetopt.conf");
983 : }
984 : CATCH_END_SECTION()
985 :
986 6 : CATCH_START_SECTION("$HOME is empty")
987 2 : snapdev::safe_setenv env("HOME", "");
988 :
989 : {
990 2 : std::string result(advgetopt::handle_user_directory("~"));
991 1 : CATCH_REQUIRE(result == "~");
992 : }
993 :
994 : {
995 2 : std::string result(advgetopt::handle_user_directory("~/.config/advgetopt.conf"));
996 1 : CATCH_REQUIRE(result == "~/.config/advgetopt.conf");
997 : }
998 : CATCH_END_SECTION()
999 :
1000 6 : CATCH_START_SECTION("Paths do not start with ~")
1001 2 : snapdev::safe_setenv env("HOME", "/home/advgetopt");
1002 :
1003 : {
1004 2 : std::string result(advgetopt::handle_user_directory("/~"));
1005 1 : CATCH_REQUIRE(result == "/~");
1006 : }
1007 :
1008 : {
1009 2 : std::string result(advgetopt::handle_user_directory("/~/.config/advgetopt.conf"));
1010 1 : CATCH_REQUIRE(result == "/~/.config/advgetopt.conf");
1011 : }
1012 : CATCH_END_SECTION()
1013 3 : }
1014 :
1015 :
1016 :
1017 :
1018 :
1019 4 : CATCH_TEST_CASE("utils_true_false", "[utils][boolean]")
1020 : {
1021 4 : CATCH_START_SECTION("True Values")
1022 : {
1023 1 : CATCH_REQUIRE(advgetopt::is_true("true"));
1024 1 : CATCH_REQUIRE(advgetopt::is_true("on"));
1025 1 : CATCH_REQUIRE(advgetopt::is_true("1"));
1026 :
1027 1 : CATCH_REQUIRE_FALSE(advgetopt::is_true("false"));
1028 1 : CATCH_REQUIRE_FALSE(advgetopt::is_true("off"));
1029 1 : CATCH_REQUIRE_FALSE(advgetopt::is_true("0"));
1030 :
1031 1 : CATCH_REQUIRE_FALSE(advgetopt::is_true("random"));
1032 : }
1033 : CATCH_END_SECTION()
1034 :
1035 4 : CATCH_START_SECTION("False Values")
1036 : {
1037 1 : CATCH_REQUIRE(advgetopt::is_false("false"));
1038 1 : CATCH_REQUIRE(advgetopt::is_false("off"));
1039 1 : CATCH_REQUIRE(advgetopt::is_false("0"));
1040 :
1041 1 : CATCH_REQUIRE_FALSE(advgetopt::is_false("true"));
1042 1 : CATCH_REQUIRE_FALSE(advgetopt::is_false("on"));
1043 1 : CATCH_REQUIRE_FALSE(advgetopt::is_false("1"));
1044 :
1045 1 : CATCH_REQUIRE_FALSE(advgetopt::is_false("random"));
1046 : }
1047 : CATCH_END_SECTION()
1048 8 : }
1049 :
1050 :
1051 :
1052 :
1053 :
1054 :
1055 :
1056 : // vim: ts=4 sw=4 et
|