14 #define BOOST_TEST_MODULE ( ParsingToolkit_test )
15 #include <boost/test/unit_test.hpp>
20 #include <string_view>
33 std::string
const s { R
"(\a\\a\\\a\\\\a\\\\\a\\\\\\a\\\)" };
34 auto const b =
s.begin();
67 assert(it ==
s.end());
76 using namespace std::string_literals;
77 using namespace std::string_view_literals;
80 BOOST_TEST(tk.removeTrailingBlanks(
""s) ==
""sv);
82 BOOST_TEST(tk.removeTrailingBlanks(
"a b c "s) ==
"a b c "sv);
84 BOOST_TEST(tk.removeTrailingBlanks(
" \\ a b c "s) ==
"\\ a b c "sv);
86 BOOST_TEST(tk.removeTrailingBlanks(
" \t a b c "s) ==
"a b c "sv);
94 using namespace std::string_literals;
95 using namespace std::string_view_literals;
116 using namespace std::string_literals;
119 "This line is not empty. The previous and the next two are."s
120 ,
"This is a multiline line of one, "s
123 , R
"(This "is a" "multi\"quoted\" strange)"s
125 , "This is a normal line, but its not terminated end gets to: EOF"s
128 std::istringstream
stream {
145 auto [ line, nPieces ] = tk.readMultiline(
stream);
146 BOOST_TEST(line ==
""s);
147 BOOST_TEST(nPieces == 1U);
150 std::tie(line, nPieces) = tk.readMultiline(
stream);
151 BOOST_TEST(line == lines[0]);
152 BOOST_TEST(nPieces == 1U);
155 std::tie(line, nPieces) = tk.readMultiline(
stream);
156 BOOST_TEST(line ==
"");
157 BOOST_TEST(nPieces == 1U);
160 std::tie(line, nPieces) = tk.readMultiline(
stream);
161 BOOST_TEST(line ==
"");
162 BOOST_TEST(nPieces == 1U);
165 std::tie(line, nPieces) = tk.readMultiline(
stream);
166 BOOST_TEST(line == lines[1] + lines[2] + lines[3]);
167 BOOST_TEST(nPieces == 3U);
170 std::tie(line, nPieces) = tk.readMultiline(
stream);
171 BOOST_TEST(line == lines[4] +
"\n"s + lines[5]);
172 BOOST_TEST(nPieces == 2U);
175 std::tie(line, nPieces) = tk.readMultiline(
stream);
176 BOOST_TEST(line == lines[6]);
177 BOOST_TEST(nPieces == 1U);
180 std::tie(line, nPieces) = tk.readMultiline(
stream);
181 BOOST_TEST(line.empty());
182 BOOST_TEST(nPieces == 0U);
188 void readMultiline_endOfInput_test() {
190 using namespace std::string_literals;
194 std::istringstream
stream;
195 auto const refillStream = [&
stream](std::string
s) -> std::istringstream&
201 auto [ line, nPieces ] = tk.readMultiline(
stream);
202 BOOST_TEST(line ==
"");
203 BOOST_TEST(nPieces == 0U);
208 std::tie(line, nPieces) = tk.readMultiline(
stream);
209 BOOST_TEST(line ==
"The end.");
210 BOOST_TEST(nPieces == 1U);
211 std::tie(line, nPieces) = tk.readMultiline(
stream);
212 BOOST_TEST(line ==
"");
213 BOOST_TEST(nPieces == 0U);
216 R
"(Unfinished business)"
218 std::tie(line, nPieces) = tk.readMultiline(stream);
219 BOOST_TEST(line == "Unfinished business");
220 BOOST_TEST(nPieces == 1U);
223 R
"(Unfinished business\)"
225 std::tie(line, nPieces) = tk.readMultiline(stream);
226 BOOST_TEST(line == "Unfinished business");
227 BOOST_TEST(nPieces == 1U);
230 R
"(Unfinished "business)"
232 std::tie(line, nPieces) = tk.readMultiline(stream);
233 BOOST_TEST(line == R"(Unfinished "business)");
234 BOOST_TEST(nPieces == 1U);
241 std::tie(line, nPieces) = tk.readMultiline(stream);
242 BOOST_TEST(line == "Unfinished business");
243 BOOST_TEST(nPieces == 2U);
250 std::tie(line, nPieces) = tk.readMultiline(stream);
251 BOOST_TEST(line == "\"Unfinished\n business\""s);
252 BOOST_TEST(nPieces == 2U);
259 std::tie(line, nPieces) = tk.readMultiline(stream);
260 BOOST_TEST(line == "\"Unfinished\n business");
261 BOOST_TEST(nPieces == 2U);
267 void splitWords_test() {
269 using namespace std::string_literals;
271 using Words_t = std::vector<std::string>;
276 std::string
const s { R
"(a b c)" };
277 auto const& words = tk.splitWords(
s);
278 Words_t
const expected { R
"(a)"s, R"(b)"s, R"(c)"s };
279 BOOST_CHECK_EQUAL_COLLECTIONS
280 (words.begin(), words.end(), expected.begin(), expected.end());
284 std::string const s { R
"( a "bb" c )" };
285 auto const& words = tk.splitWords(
s);
286 Words_t
const expected { R
"(a)"s, R"("bb")"s, R"(c)"s };
287 BOOST_CHECK_EQUAL_COLLECTIONS
288 (words.begin(), words.end(), expected.begin(), expected.end());
292 std::string const s { R
"(a "b c")" };
293 auto const& words = tk.splitWords(
s);
294 Words_t
const expected { R
"(a)"s, R"("b c")"s };
295 BOOST_CHECK_EQUAL_COLLECTIONS
296 (words.begin(), words.end(), expected.begin(), expected.end());
300 std::string const s { R
"("")" };
301 auto const& words = tk.splitWords(
s);
302 Words_t
const expected { R
"("")"s };
303 BOOST_CHECK_EQUAL_COLLECTIONS
304 (words.begin(), words.end(), expected.begin(), expected.end());
308 std::string const s { R
"(a\ b c)" };
309 auto const& words = tk.splitWords(
s);
310 Words_t
const expected { R
"(a\ b)"s, R"(c)"s };
311 BOOST_CHECK_EQUAL_COLLECTIONS
312 (words.begin(), words.end(), expected.begin(), expected.end());
316 std::string const s { R
"(a b" c")" };
317 auto const& words = tk.splitWords(
s);
318 Words_t
const expected { R
"(a)"s, R"(b" c")"s };
319 BOOST_CHECK_EQUAL_COLLECTIONS
320 (words.begin(), words.end(), expected.begin(), expected.end());
324 std::string const s { R
"("a "b \"c d"")" };
325 auto const& words = tk.splitWords(
s);
326 Words_t
const expected { R
"("a "b)"s, R"(\"c)"s, R"(d"")"s };
327 BOOST_CHECK_EQUAL_COLLECTIONS
328 (words.begin(), words.end(), expected.begin(), expected.end());
336 void findFirstUnescaped_test() {
338 using namespace std::string_view_literals;
343 std::string_view
const sv { R
"()" };
345 BOOST_TEST(key ==
"");
350 std::string_view
const sv { R
"(a :: b)" };
351 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
352 BOOST_TEST(key ==
":");
357 std::string_view
const sv { R
"(a ::+ b)" };
358 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
359 BOOST_TEST(key ==
":");
364 std::string_view
const sv { R
"(a \::+ b)" };
365 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
366 BOOST_TEST(key ==
":+");
371 std::string_view
const sv { R
"(a\ ::+ b)" };
372 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
373 BOOST_TEST(key ==
":");
378 std::string_view
const sv { R
"(a :+)" };
379 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
380 BOOST_TEST(key ==
":+");
385 std::string_view
const sv { R
"(a \:+)" };
386 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
387 BOOST_TEST(key ==
"");
392 std::string_view
const sv { R
"(:+ b)" };
393 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
394 BOOST_TEST(key ==
":+");
399 std::string_view
const sv { R
"(nope)" };
400 std::string_view const key = tk.findFirstUnescaped(sv, {
":+",
":" });
401 BOOST_TEST(key ==
"");
410 void findFirstUnquoted_test() {
412 using namespace std::string_view_literals;
416 auto const findAndSplit = [tk](std::string_view sv)
417 {
return tk.
splitOn(sv, tk.findFirstUnquoted(sv, {
":+",
":" })); };
420 auto const [ pre, sep, post ] = findAndSplit(
""sv);
421 BOOST_TEST(pre == R
"()"sv);
422 BOOST_TEST(sep == R"()"sv);
423 BOOST_TEST(post == R"()"sv);
427 auto const [ pre, sep, post ] = findAndSplit(R
"(a:+b)"sv);
428 BOOST_TEST(pre == R"(a)"sv);
429 BOOST_TEST(sep == R"(:+)"sv);
430 BOOST_TEST(post == R"(b)"sv);
434 auto const [ pre, sep, post ] = findAndSplit(R
"(a::b)"sv);
435 BOOST_TEST(pre == R"(a)"sv);
436 BOOST_TEST(sep == R"(:)"sv);
437 BOOST_TEST(post == R"(:b)"sv);
441 auto const [ pre, sep, post ] = findAndSplit(R
"(a\:b)"sv);
442 BOOST_TEST(pre == R"(a\:b)"sv);
443 BOOST_TEST(sep == R"()"sv);
444 BOOST_TEST(post == R"()"sv);
448 auto const [ pre, sep, post ] = findAndSplit(R
"(a :+ b)"sv);
449 BOOST_TEST(pre == R"(a )"sv);
450 BOOST_TEST(sep == R"(:+)"sv);
451 BOOST_TEST(post == R"( b)"sv);
455 auto const [ pre, sep, post ] = findAndSplit(R
"(a\ :+ b)"sv);
456 BOOST_TEST(pre == R"(a\ )"sv);
457 BOOST_TEST(sep == R"(:+)"sv);
458 BOOST_TEST(post == R"( b)"sv);
462 auto const [ pre, sep, post ] = findAndSplit(R
"(a\ \::+ b)"sv);
463 BOOST_TEST(pre == R"(a\ \:)"sv);
464 BOOST_TEST(sep == R"(:+)"sv);
465 BOOST_TEST(post == R"( b)"sv);
469 auto const [ pre, sep, post ] = findAndSplit(R
"(a\ \:+ b)"sv);
470 BOOST_TEST(pre == R"(a\ \:+ b)"sv);
471 BOOST_TEST(sep == R"()"sv);
472 BOOST_TEST(post == R"()"sv);
476 auto const [ pre, sep, post ] = findAndSplit(R
"(a\ :+\ b)"sv);
477 BOOST_TEST(pre == R"(a\ )"sv);
478 BOOST_TEST(sep == R"(:+)"sv);
479 BOOST_TEST(post == R"(\ b)"sv);
483 auto const [ pre, sep, post ] = findAndSplit(R
"("a":+"b")"sv);
484 BOOST_TEST(pre == R"("a")"sv);
485 BOOST_TEST(sep == R"(:+)"sv);
486 BOOST_TEST(post == R"("b")"sv);
490 auto const [ pre, sep, post ] = findAndSplit(R
"("a:":+"b")"sv);
491 BOOST_TEST(pre == R"("a:")"sv);
492 BOOST_TEST(sep == R"(:+)"sv);
493 BOOST_TEST(post == R"("b")"sv);
497 auto const [ pre, sep, post ] = findAndSplit(R
"(a:":+"b)"sv);
498 BOOST_TEST(pre == R"(a)"sv);
499 BOOST_TEST(sep == R"(:)"sv);
500 BOOST_TEST(post == R"(":+"b)"sv);
504 auto const [ pre, sep, post ] = findAndSplit(R
"("a:"aa:+b"b)"sv);
505 BOOST_TEST(pre == R"("a:"aa)"sv);
506 BOOST_TEST(sep == R"(:+)"sv);
507 BOOST_TEST(post == R"(b"b)"sv);
514 void removeCommentLine_test() {
516 using namespace std::string_view_literals;
520 std::vector<std::string_view> words, expected;
522 std::distance(words.begin(), tk.findCommentWord(words.begin(), words.end()))
525 BOOST_CHECK_EQUAL_COLLECTIONS
526 (words.begin(), words.end(), expected.begin(), expected.end());
529 words = {
" One"sv,
"Two#"sv,
"Th#ree"sv,
" #Four"sv,
"Five"sv,
"Six"sv };
532 std::distance(words.begin(), tk.findCommentWord(words.begin(), words.end()))
536 BOOST_CHECK_EQUAL_COLLECTIONS
537 (words.begin(), words.end(), expected.begin(), expected.end());
540 words = {
"#"sv,
"a"sv,
"long"sv,
"comment"sv };
543 std::distance(words.begin(), tk.findCommentWord(words.begin(), words.end()))
546 tk.removeCommentLine(words);
547 BOOST_CHECK_EQUAL_COLLECTIONS
548 (words.begin(), words.end(), expected.begin(), expected.end());
551 words = {
"#acompactcomment"sv,
"!"sv };
554 std::distance(words.begin(), tk.findCommentWord(words.begin(), words.end()))
557 tk.removeCommentLine(words);
558 BOOST_CHECK_EQUAL_COLLECTIONS
559 (words.begin(), words.end(), expected.begin(), expected.end());
562 words = {
" One"sv,
"Two#"sv,
"Th#ree"sv,
" #Four"sv,
"#Five"sv,
"Six"sv };
563 expected = {
" One"sv,
"Two#"sv,
"Th#ree"sv,
" #Four"sv };
565 std::distance(words.begin(), tk.findCommentWord(words.begin(), words.end()))
568 tk.removeCommentLine(words);
569 BOOST_CHECK_EQUAL_COLLECTIONS
570 (words.begin(), words.end(), expected.begin(), expected.end());
573 words = {
" One"sv,
"Two#"sv,
"Th#ree"sv,
"\\#Four"sv,
"#"sv,
"Six"sv };
574 expected = {
" One"sv,
"Two#"sv,
"Th#ree"sv,
"\\#Four"sv };
576 std::distance(words.begin(), tk.findCommentWord(words.begin(), words.end()))
579 tk.removeCommentLine(words);
580 BOOST_CHECK_EQUAL_COLLECTIONS
581 (words.begin(), words.end(), expected.begin(), expected.end());
588 void findQuotationStart_test() {
590 using namespace std::string_literals;
592 std::string_view sv {
593 R
"(No quote. Still no \"quote\". "a" "b c" 'd' "e 'f' g" "h 'i" "j' k" "unfinished 'm')"
598 std::string_view qsv;
602 BOOST_TEST_REQUIRE(qsv == R
"("a" "b c" 'd' "e 'f' g" "h 'i" "j' k" "unfinished 'm')");
603 BOOST_TEST_REQUIRE(qptr != nullptr);
604 BOOST_TEST_REQUIRE(qptr->first ==
"\""s);
608 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
609 BOOST_TEST_REQUIRE(qsv == R
"("b c" 'd' "e 'f' g" "h 'i" "j' k" "unfinished 'm')");
610 BOOST_TEST_REQUIRE(qptr != nullptr);
611 BOOST_TEST_REQUIRE(qptr->first ==
"\""s);
615 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
616 BOOST_TEST_REQUIRE(qsv == R
"('d' "e 'f' g" "h 'i" "j' k" "unfinished 'm')");
617 BOOST_TEST_REQUIRE(qptr != nullptr);
618 BOOST_TEST_REQUIRE(qptr->first ==
"'"s);
622 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
623 BOOST_TEST_REQUIRE(qsv == R
"("e 'f' g" "h 'i" "j' k" "unfinished 'm')");
624 BOOST_TEST_REQUIRE(qptr != nullptr);
625 BOOST_TEST_REQUIRE(qptr->first ==
"\""s);
629 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
630 BOOST_TEST_REQUIRE(qsv == R
"("h 'i" "j' k" "unfinished 'm')");
631 BOOST_TEST_REQUIRE(qptr != nullptr);
632 BOOST_TEST_REQUIRE(qptr->first ==
"\""s);
636 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
637 BOOST_TEST_REQUIRE(qsv == R
"("j' k" "unfinished 'm')");
638 BOOST_TEST_REQUIRE(qptr != nullptr);
639 BOOST_TEST_REQUIRE(qptr->first ==
"\""s);
643 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
644 BOOST_TEST_REQUIRE(qsv == R
"("unfinished 'm')");
645 BOOST_TEST_REQUIRE(qptr != nullptr);
646 BOOST_TEST_REQUIRE(qptr->first ==
"\""s);
650 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
651 BOOST_TEST_REQUIRE(qsv == R
"('m')");
652 BOOST_TEST_REQUIRE(qptr != nullptr);
653 BOOST_TEST_REQUIRE(qptr->first ==
"'"s);
657 std::tie(qsv, qptr) = tk.findQuotationStart(sv);
658 BOOST_TEST_REQUIRE(qsv.empty());
659 BOOST_TEST_REQUIRE(qptr ==
nullptr);
664 void findQuotationStart_noquote_test() {
668 std::string_view sv {
"No quotes at all." };
670 BOOST_TEST(qsv.empty());
671 BOOST_TEST(qptr ==
nullptr);
674 BOOST_TEST((qsv.begin() == sv.end()));
680 void findQuotationEnd_test() {
682 using namespace std::string_literals;
683 using namespace std::string_view_literals;
695 void findQuotationEnd_noquote_test() {
699 std::string_view
const sv {
"No end quotes at all." };
704 std::string
const& firstEndQuote = tk.
params().
quotes.front().second;
707 BOOST_TEST(qsv.empty());
710 BOOST_TEST((qsv.begin() == sv.end()));
716 void isQuotationUnclosed_test() {
718 using namespace std::string_literals;
720 std::string_view sv {
721 R
"(No quote. Still no \"quote\". "a" "b c" 'd' "e 'f' g" "h 'i" "j' k" "unfinished 'm'".)"
742 void splitOn_test() {
744 std::string_view
const sv {
"aa:bbb" };
747 std::string_view
const key = sv.substr(2,1);
748 BOOST_TEST_REQUIRE(key ==
":");
750 BOOST_TEST(sep == key);
751 BOOST_TEST(pre ==
"aa");
752 BOOST_TEST(post ==
"bbb");
755 std::string_view
const key = sv.substr(0,2);
756 BOOST_TEST_REQUIRE(key ==
"aa");
758 BOOST_TEST(sep == key);
759 BOOST_TEST(pre ==
"");
760 BOOST_TEST(post ==
":bbb");
764 std::string_view
const key = sv.substr(4, 1);
765 BOOST_TEST_REQUIRE(key ==
"b");
767 BOOST_TEST(sep == key);
768 BOOST_TEST(pre ==
"aa:b");
769 BOOST_TEST(post ==
"b");
773 std::string_view
const key
775 BOOST_TEST_REQUIRE(key ==
"");
777 BOOST_TEST(sep == key);
778 BOOST_TEST(pre == sv);
779 BOOST_TEST(post ==
"");
783 std::string_view
const key
785 BOOST_TEST_REQUIRE(key ==
"");
787 BOOST_TEST(sep == key);
788 BOOST_TEST(pre ==
"");
789 BOOST_TEST(post == sv);
793 std::string_view
const key = sv;
795 BOOST_TEST(sep == key);
796 BOOST_TEST(pre ==
"");
797 BOOST_TEST(post ==
"");
804 void removeEscapes_test() {
808 std::string
s { R
"()" };
822 void removeEscapesDocumentation_test() {
828 std::string
s { R
"(\\\\a)" };
831 BOOST_TEST(s == R"(\\a)");
834 BOOST_TEST(s == R"(\a)");
837 BOOST_TEST(s == R"(a)");
840 BOOST_TEST(s == R"(a)");
846 void removeQuotations_test() {
848 using namespace std::string_literals;
855 BOOST_TEST(s == R"(a'bc'b"a)");
858 BOOST_TEST(s == R"(abcb"a)");
861 BOOST_TEST(s == R"(abcb"a)");
865 BOOST_TEST(s == R"(a'bc'ba)");
869 BOOST_TEST(s == R"(a'b\"c'ba)");
872 BOOST_TEST(s == R"(ab\"cba)");
875 BOOST_TEST(s == R"(ab\"cba)");
880 void removeQuotationsDocumentation_test() {
882 using namespace std::string_literals;
892 std::string
s { R
"(a1 << "b1 << 'c1 << " or " << c2' << b2" << a2)" };
895 BOOST_TEST(s == R"(a1 << b1 << 'c1 << or << c2' << b2 << a2)");
898 BOOST_TEST(s == R"(a1 << b1 << c1 << or << c2 << b2 << a2)");
901 BOOST_TEST(s == R"(a1 << b1 << c1 << or << c2 << b2 << a2)");
933 readMultiline_endOfInput_test();
947 findFirstUnescaped_test();
954 findFirstUnquoted_test();
961 removeCommentLine_test();
968 findQuotationStart_test();
969 findQuotationStart_noquote_test();
976 findQuotationEnd_test();
977 findQuotationEnd_noquote_test();
984 isQuotationUnclosed_test();
998 removeEscapes_test();
999 removeEscapesDocumentation_test();
1006 removeQuotations_test();
1007 removeQuotationsDocumentation_test();
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
then echo File list $list not found else cat $list while read file do echo $file sed s