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