1 // 2 // Automated Testing Framework (atf) 3 // 4 // Copyright (c) 2007 The NetBSD Foundation, Inc. 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions 9 // are met: 10 // 1. Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // 2. Redistributions in binary form must reproduce the above copyright 13 // notice, this list of conditions and the following disclaimer in the 14 // documentation and/or other materials provided with the distribution. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 // 29 30 #include <sstream> 31 32 #include <atf-c++.hpp> 33 34 #include "parser.hpp" 35 #include "test_helpers.hpp" 36 37 // ------------------------------------------------------------------------ 38 // Tests for the "parse_error" class. 39 // ------------------------------------------------------------------------ 40 41 ATF_TEST_CASE(parse_error_to_string); 42 ATF_TEST_CASE_HEAD(parse_error_to_string) 43 { 44 set_md_var("descr", "Tests the parse_error conversion to strings"); 45 } 46 ATF_TEST_CASE_BODY(parse_error_to_string) 47 { 48 using tools::parser::parse_error; 49 50 const parse_error e(123, "This is the message"); 51 ATF_REQUIRE_EQ("123: This is the message", std::string(e)); 52 } 53 54 // ------------------------------------------------------------------------ 55 // Tests for the "parse_errors" class. 56 // ------------------------------------------------------------------------ 57 58 ATF_TEST_CASE(parse_errors_what); 59 ATF_TEST_CASE_HEAD(parse_errors_what) 60 { 61 set_md_var("descr", "Tests the parse_errors description"); 62 } 63 ATF_TEST_CASE_BODY(parse_errors_what) 64 { 65 using tools::parser::parse_error; 66 using tools::parser::parse_errors; 67 68 parse_errors es; 69 es.push_back(parse_error(2, "Second error")); 70 es.push_back(parse_error(1, "First error")); 71 72 ATF_REQUIRE_EQ("2: Second error\n1: First error", std::string(es.what())); 73 } 74 75 // ------------------------------------------------------------------------ 76 // Tests for the "token" class. 77 // ------------------------------------------------------------------------ 78 79 ATF_TEST_CASE(token_getters); 80 ATF_TEST_CASE_HEAD(token_getters) 81 { 82 set_md_var("descr", "Tests the token getters"); 83 } 84 ATF_TEST_CASE_BODY(token_getters) 85 { 86 using tools::parser::token; 87 88 { 89 token t(10, 0); 90 ATF_REQUIRE_EQ(t.lineno(), 10); 91 ATF_REQUIRE_EQ(t.type(), 0); 92 ATF_REQUIRE(t.text().empty()); 93 } 94 95 { 96 token t(10, 0, "foo"); 97 ATF_REQUIRE_EQ(t.lineno(), 10); 98 ATF_REQUIRE_EQ(t.type(), 0); 99 ATF_REQUIRE_EQ(t.text(), "foo"); 100 } 101 102 { 103 token t(20, 1); 104 ATF_REQUIRE_EQ(t.lineno(), 20); 105 ATF_REQUIRE_EQ(t.type(), 1); 106 ATF_REQUIRE(t.text().empty()); 107 } 108 109 { 110 token t(20, 1, "bar"); 111 ATF_REQUIRE_EQ(t.lineno(), 20); 112 ATF_REQUIRE_EQ(t.type(), 1); 113 ATF_REQUIRE_EQ(t.text(), "bar"); 114 } 115 } 116 117 // ------------------------------------------------------------------------ 118 // Tests for the "tokenizer" class. 119 // ------------------------------------------------------------------------ 120 121 #define EXPECT(tkz, ttype, ttext) \ 122 do { \ 123 tools::parser::token t = tkz.next(); \ 124 ATF_REQUIRE(t.type() == ttype); \ 125 ATF_REQUIRE_EQ(t.text(), ttext); \ 126 } while (false); 127 128 namespace minimal { 129 130 static const tools::parser::token_type eof_type = 0; 131 static const tools::parser::token_type nl_type = 1; 132 static const tools::parser::token_type word_type = 2; 133 134 class tokenizer : public tools::parser::tokenizer< std::istream > { 135 public: 136 tokenizer(std::istream& is, bool skipws) : 137 tools::parser::tokenizer< std::istream > 138 (is, skipws, eof_type, nl_type, word_type) 139 { 140 } 141 }; 142 143 } 144 145 namespace delims { 146 147 static const tools::parser::token_type eof_type = 0; 148 static const tools::parser::token_type nl_type = 1; 149 static const tools::parser::token_type word_type = 2; 150 static const tools::parser::token_type plus_type = 3; 151 static const tools::parser::token_type minus_type = 4; 152 static const tools::parser::token_type equal_type = 5; 153 154 class tokenizer : public tools::parser::tokenizer< std::istream > { 155 public: 156 tokenizer(std::istream& is, bool skipws) : 157 tools::parser::tokenizer< std::istream > 158 (is, skipws, eof_type, nl_type, word_type) 159 { 160 add_delim('+', plus_type); 161 add_delim('-', minus_type); 162 add_delim('=', equal_type); 163 } 164 }; 165 166 } 167 168 namespace keywords { 169 170 static const tools::parser::token_type eof_type = 0; 171 static const tools::parser::token_type nl_type = 1; 172 static const tools::parser::token_type word_type = 2; 173 static const tools::parser::token_type var_type = 3; 174 static const tools::parser::token_type loop_type = 4; 175 static const tools::parser::token_type endloop_type = 5; 176 177 class tokenizer : public tools::parser::tokenizer< std::istream > { 178 public: 179 tokenizer(std::istream& is, bool skipws) : 180 tools::parser::tokenizer< std::istream > 181 (is, skipws, eof_type, nl_type, word_type) 182 { 183 add_keyword("var", var_type); 184 add_keyword("loop", loop_type); 185 add_keyword("endloop", endloop_type); 186 } 187 }; 188 189 } 190 191 namespace quotes { 192 193 static const tools::parser::token_type eof_type = 0; 194 static const tools::parser::token_type nl_type = 1; 195 static const tools::parser::token_type word_type = 2; 196 static const tools::parser::token_type dblquote_type = 3; 197 198 class tokenizer : public tools::parser::tokenizer< std::istream > { 199 public: 200 tokenizer(std::istream& is, bool skipws) : 201 tools::parser::tokenizer< std::istream > 202 (is, skipws, eof_type, nl_type, word_type) 203 { 204 add_quote('"', dblquote_type); 205 } 206 }; 207 208 } 209 210 ATF_TEST_CASE(tokenizer_minimal_nows); 211 ATF_TEST_CASE_HEAD(tokenizer_minimal_nows) 212 { 213 set_md_var("descr", "Tests the tokenizer class using a minimal parser " 214 "and not skipping whitespace"); 215 } 216 ATF_TEST_CASE_BODY(tokenizer_minimal_nows) 217 { 218 using namespace minimal; 219 220 { 221 std::istringstream iss(""); 222 tokenizer mt(iss, false); 223 224 EXPECT(mt, eof_type, "<<EOF>>"); 225 EXPECT(mt, eof_type, "<<EOF>>"); 226 } 227 228 { 229 std::istringstream iss("\n"); 230 tokenizer mt(iss, false); 231 232 EXPECT(mt, nl_type, "<<NEWLINE>>"); 233 EXPECT(mt, eof_type, "<<EOF>>"); 234 EXPECT(mt, eof_type, "<<EOF>>"); 235 } 236 237 { 238 std::istringstream iss("\n\n\n"); 239 tokenizer mt(iss, false); 240 241 EXPECT(mt, nl_type, "<<NEWLINE>>"); 242 EXPECT(mt, nl_type, "<<NEWLINE>>"); 243 EXPECT(mt, nl_type, "<<NEWLINE>>"); 244 EXPECT(mt, eof_type, "<<EOF>>"); 245 EXPECT(mt, eof_type, "<<EOF>>"); 246 } 247 248 { 249 std::istringstream iss("line 1"); 250 tokenizer mt(iss, false); 251 252 EXPECT(mt, word_type, "line 1"); 253 EXPECT(mt, eof_type, "<<EOF>>"); 254 EXPECT(mt, eof_type, "<<EOF>>"); 255 } 256 257 { 258 std::istringstream iss("line 1\n"); 259 tokenizer mt(iss, false); 260 261 EXPECT(mt, word_type, "line 1"); 262 EXPECT(mt, nl_type, "<<NEWLINE>>"); 263 EXPECT(mt, eof_type, "<<EOF>>"); 264 EXPECT(mt, eof_type, "<<EOF>>"); 265 } 266 267 { 268 std::istringstream iss("line 1\nline 2"); 269 tokenizer mt(iss, false); 270 271 EXPECT(mt, word_type, "line 1"); 272 EXPECT(mt, nl_type, "<<NEWLINE>>"); 273 EXPECT(mt, word_type, "line 2"); 274 EXPECT(mt, eof_type, "<<EOF>>"); 275 EXPECT(mt, eof_type, "<<EOF>>"); 276 } 277 278 { 279 std::istringstream iss("line 1\nline 2\nline 3\n"); 280 tokenizer mt(iss, false); 281 282 EXPECT(mt, word_type, "line 1"); 283 EXPECT(mt, nl_type, "<<NEWLINE>>"); 284 EXPECT(mt, word_type, "line 2"); 285 EXPECT(mt, nl_type, "<<NEWLINE>>"); 286 EXPECT(mt, word_type, "line 3"); 287 EXPECT(mt, nl_type, "<<NEWLINE>>"); 288 EXPECT(mt, eof_type, "<<EOF>>"); 289 EXPECT(mt, eof_type, "<<EOF>>"); 290 } 291 } 292 293 ATF_TEST_CASE(tokenizer_minimal_ws); 294 ATF_TEST_CASE_HEAD(tokenizer_minimal_ws) 295 { 296 set_md_var("descr", "Tests the tokenizer class using a minimal parser " 297 "and skipping whitespace"); 298 } 299 ATF_TEST_CASE_BODY(tokenizer_minimal_ws) 300 { 301 using namespace minimal; 302 303 { 304 std::istringstream iss(""); 305 minimal::tokenizer mt(iss, true); 306 307 EXPECT(mt, eof_type, "<<EOF>>"); 308 EXPECT(mt, eof_type, "<<EOF>>"); 309 } 310 311 { 312 std::istringstream iss(" \t "); 313 tokenizer mt(iss, true); 314 315 EXPECT(mt, eof_type, "<<EOF>>"); 316 EXPECT(mt, eof_type, "<<EOF>>"); 317 } 318 319 { 320 std::istringstream iss("\n"); 321 tokenizer mt(iss, true); 322 323 EXPECT(mt, nl_type, "<<NEWLINE>>"); 324 EXPECT(mt, eof_type, "<<EOF>>"); 325 EXPECT(mt, eof_type, "<<EOF>>"); 326 } 327 328 { 329 std::istringstream iss(" \t \n \t "); 330 tokenizer mt(iss, true); 331 332 EXPECT(mt, nl_type, "<<NEWLINE>>"); 333 EXPECT(mt, eof_type, "<<EOF>>"); 334 EXPECT(mt, eof_type, "<<EOF>>"); 335 } 336 337 { 338 std::istringstream iss("\n\n\n"); 339 tokenizer mt(iss, true); 340 341 EXPECT(mt, nl_type, "<<NEWLINE>>"); 342 EXPECT(mt, nl_type, "<<NEWLINE>>"); 343 EXPECT(mt, nl_type, "<<NEWLINE>>"); 344 EXPECT(mt, eof_type, "<<EOF>>"); 345 EXPECT(mt, eof_type, "<<EOF>>"); 346 } 347 348 { 349 std::istringstream iss("line 1"); 350 tokenizer mt(iss, true); 351 352 EXPECT(mt, word_type, "line"); 353 EXPECT(mt, word_type, "1"); 354 EXPECT(mt, eof_type, "<<EOF>>"); 355 EXPECT(mt, eof_type, "<<EOF>>"); 356 } 357 358 { 359 std::istringstream iss(" \tline\t 1\t"); 360 tokenizer mt(iss, true); 361 362 EXPECT(mt, word_type, "line"); 363 EXPECT(mt, word_type, "1"); 364 EXPECT(mt, eof_type, "<<EOF>>"); 365 EXPECT(mt, eof_type, "<<EOF>>"); 366 } 367 368 { 369 std::istringstream iss("line 1\n"); 370 tokenizer mt(iss, true); 371 372 EXPECT(mt, word_type, "line"); 373 EXPECT(mt, word_type, "1"); 374 EXPECT(mt, nl_type, "<<NEWLINE>>"); 375 EXPECT(mt, eof_type, "<<EOF>>"); 376 EXPECT(mt, eof_type, "<<EOF>>"); 377 } 378 379 { 380 std::istringstream iss("line 1\nline 2"); 381 tokenizer mt(iss, true); 382 383 EXPECT(mt, word_type, "line"); 384 EXPECT(mt, word_type, "1"); 385 EXPECT(mt, nl_type, "<<NEWLINE>>"); 386 EXPECT(mt, word_type, "line"); 387 EXPECT(mt, word_type, "2"); 388 EXPECT(mt, eof_type, "<<EOF>>"); 389 EXPECT(mt, eof_type, "<<EOF>>"); 390 } 391 392 { 393 std::istringstream iss("line 1\nline 2\nline 3\n"); 394 tokenizer mt(iss, true); 395 396 EXPECT(mt, word_type, "line"); 397 EXPECT(mt, word_type, "1"); 398 EXPECT(mt, nl_type, "<<NEWLINE>>"); 399 EXPECT(mt, word_type, "line"); 400 EXPECT(mt, word_type, "2"); 401 EXPECT(mt, nl_type, "<<NEWLINE>>"); 402 EXPECT(mt, word_type, "line"); 403 EXPECT(mt, word_type, "3"); 404 EXPECT(mt, nl_type, "<<NEWLINE>>"); 405 EXPECT(mt, eof_type, "<<EOF>>"); 406 EXPECT(mt, eof_type, "<<EOF>>"); 407 } 408 409 { 410 std::istringstream iss(" \t line \t 1\n\tline\t2\n line 3 \n"); 411 tokenizer mt(iss, true); 412 413 EXPECT(mt, word_type, "line"); 414 EXPECT(mt, word_type, "1"); 415 EXPECT(mt, nl_type, "<<NEWLINE>>"); 416 EXPECT(mt, word_type, "line"); 417 EXPECT(mt, word_type, "2"); 418 EXPECT(mt, nl_type, "<<NEWLINE>>"); 419 EXPECT(mt, word_type, "line"); 420 EXPECT(mt, word_type, "3"); 421 EXPECT(mt, nl_type, "<<NEWLINE>>"); 422 EXPECT(mt, eof_type, "<<EOF>>"); 423 EXPECT(mt, eof_type, "<<EOF>>"); 424 } 425 } 426 427 ATF_TEST_CASE(tokenizer_delims_nows); 428 ATF_TEST_CASE_HEAD(tokenizer_delims_nows) 429 { 430 set_md_var("descr", "Tests the tokenizer class using a parser with some " 431 "additional delimiters and not skipping whitespace"); 432 } 433 ATF_TEST_CASE_BODY(tokenizer_delims_nows) 434 { 435 using namespace delims; 436 437 { 438 std::istringstream iss("+-="); 439 tokenizer mt(iss, false); 440 441 EXPECT(mt, plus_type, "+"); 442 EXPECT(mt, minus_type, "-"); 443 EXPECT(mt, equal_type, "="); 444 EXPECT(mt, eof_type, "<<EOF>>"); 445 EXPECT(mt, eof_type, "<<EOF>>"); 446 } 447 448 { 449 std::istringstream iss("+++"); 450 tokenizer mt(iss, false); 451 452 EXPECT(mt, plus_type, "+"); 453 EXPECT(mt, plus_type, "+"); 454 EXPECT(mt, plus_type, "+"); 455 EXPECT(mt, eof_type, "<<EOF>>"); 456 EXPECT(mt, eof_type, "<<EOF>>"); 457 } 458 459 { 460 std::istringstream iss("\n+\n++\n"); 461 tokenizer mt(iss, false); 462 463 EXPECT(mt, nl_type, "<<NEWLINE>>"); 464 EXPECT(mt, plus_type, "+"); 465 EXPECT(mt, nl_type, "<<NEWLINE>>"); 466 EXPECT(mt, plus_type, "+"); 467 EXPECT(mt, plus_type, "+"); 468 EXPECT(mt, nl_type, "<<NEWLINE>>"); 469 EXPECT(mt, eof_type, "<<EOF>>"); 470 EXPECT(mt, eof_type, "<<EOF>>"); 471 } 472 473 { 474 std::istringstream iss("foo+bar=baz"); 475 tokenizer mt(iss, false); 476 477 EXPECT(mt, word_type, "foo"); 478 EXPECT(mt, plus_type, "+"); 479 EXPECT(mt, word_type, "bar"); 480 EXPECT(mt, equal_type, "="); 481 EXPECT(mt, word_type, "baz"); 482 EXPECT(mt, eof_type, "<<EOF>>"); 483 EXPECT(mt, eof_type, "<<EOF>>"); 484 } 485 486 { 487 std::istringstream iss(" foo\t+\tbar = baz "); 488 tokenizer mt(iss, false); 489 490 EXPECT(mt, word_type, " foo\t"); 491 EXPECT(mt, plus_type, "+"); 492 EXPECT(mt, word_type, "\tbar "); 493 EXPECT(mt, equal_type, "="); 494 EXPECT(mt, word_type, " baz "); 495 EXPECT(mt, eof_type, "<<EOF>>"); 496 EXPECT(mt, eof_type, "<<EOF>>"); 497 } 498 } 499 500 ATF_TEST_CASE(tokenizer_delims_ws); 501 ATF_TEST_CASE_HEAD(tokenizer_delims_ws) 502 { 503 set_md_var("descr", "Tests the tokenizer class using a parser with some " 504 "additional delimiters and skipping whitespace"); 505 } 506 ATF_TEST_CASE_BODY(tokenizer_delims_ws) 507 { 508 using namespace delims; 509 510 { 511 std::istringstream iss(" foo\t+\tbar = baz "); 512 tokenizer mt(iss, true); 513 514 EXPECT(mt, word_type, "foo"); 515 EXPECT(mt, plus_type, "+"); 516 EXPECT(mt, word_type, "bar"); 517 EXPECT(mt, equal_type, "="); 518 EXPECT(mt, word_type, "baz"); 519 EXPECT(mt, eof_type, "<<EOF>>"); 520 EXPECT(mt, eof_type, "<<EOF>>"); 521 } 522 } 523 524 ATF_TEST_CASE(tokenizer_keywords_nows); 525 ATF_TEST_CASE_HEAD(tokenizer_keywords_nows) 526 { 527 set_md_var("descr", "Tests the tokenizer class using a parser with some " 528 "additional keywords and not skipping whitespace"); 529 } 530 ATF_TEST_CASE_BODY(tokenizer_keywords_nows) 531 { 532 using namespace keywords; 533 534 { 535 std::istringstream iss("var"); 536 tokenizer mt(iss, false); 537 538 EXPECT(mt, var_type, "var"); 539 EXPECT(mt, eof_type, "<<EOF>>"); 540 EXPECT(mt, eof_type, "<<EOF>>"); 541 } 542 543 { 544 std::istringstream iss("va"); 545 tokenizer mt(iss, false); 546 547 EXPECT(mt, word_type, "va"); 548 EXPECT(mt, eof_type, "<<EOF>>"); 549 EXPECT(mt, eof_type, "<<EOF>>"); 550 } 551 552 { 553 std::istringstream iss("vara"); 554 tokenizer mt(iss, false); 555 556 EXPECT(mt, word_type, "vara"); 557 EXPECT(mt, eof_type, "<<EOF>>"); 558 EXPECT(mt, eof_type, "<<EOF>>"); 559 } 560 561 { 562 std::istringstream iss("var "); 563 tokenizer mt(iss, false); 564 565 EXPECT(mt, word_type, "var "); 566 EXPECT(mt, eof_type, "<<EOF>>"); 567 EXPECT(mt, eof_type, "<<EOF>>"); 568 } 569 570 { 571 std::istringstream iss("var\nloop\nendloop"); 572 tokenizer mt(iss, false); 573 574 EXPECT(mt, var_type, "var"); 575 EXPECT(mt, nl_type, "<<NEWLINE>>"); 576 EXPECT(mt, loop_type, "loop"); 577 EXPECT(mt, nl_type, "<<NEWLINE>>"); 578 EXPECT(mt, endloop_type, "endloop"); 579 EXPECT(mt, eof_type, "<<EOF>>"); 580 EXPECT(mt, eof_type, "<<EOF>>"); 581 } 582 } 583 584 ATF_TEST_CASE(tokenizer_keywords_ws); 585 ATF_TEST_CASE_HEAD(tokenizer_keywords_ws) 586 { 587 set_md_var("descr", "Tests the tokenizer class using a parser with some " 588 "additional keywords and not skipping whitespace"); 589 } 590 ATF_TEST_CASE_BODY(tokenizer_keywords_ws) 591 { 592 using namespace keywords; 593 594 { 595 std::istringstream iss("var "); 596 tokenizer mt(iss, true); 597 598 EXPECT(mt, var_type, "var"); 599 EXPECT(mt, eof_type, "<<EOF>>"); 600 EXPECT(mt, eof_type, "<<EOF>>"); 601 } 602 603 { 604 std::istringstream iss(" var \n\tloop\t\n \tendloop \t"); 605 tokenizer mt(iss, true); 606 607 EXPECT(mt, var_type, "var"); 608 EXPECT(mt, nl_type, "<<NEWLINE>>"); 609 EXPECT(mt, loop_type, "loop"); 610 EXPECT(mt, nl_type, "<<NEWLINE>>"); 611 EXPECT(mt, endloop_type, "endloop"); 612 EXPECT(mt, eof_type, "<<EOF>>"); 613 EXPECT(mt, eof_type, "<<EOF>>"); 614 } 615 616 { 617 std::istringstream iss("var loop endloop"); 618 tokenizer mt(iss, true); 619 620 EXPECT(mt, var_type, "var"); 621 EXPECT(mt, loop_type, "loop"); 622 EXPECT(mt, endloop_type, "endloop"); 623 EXPECT(mt, eof_type, "<<EOF>>"); 624 EXPECT(mt, eof_type, "<<EOF>>"); 625 } 626 } 627 628 ATF_TEST_CASE(tokenizer_quotes_nows); 629 ATF_TEST_CASE_HEAD(tokenizer_quotes_nows) 630 { 631 set_md_var("descr", "Tests the tokenizer class using a parser with " 632 "quoted strings and not skipping whitespace"); 633 } 634 ATF_TEST_CASE_BODY(tokenizer_quotes_nows) 635 { 636 using namespace quotes; 637 638 { 639 std::istringstream iss("var"); 640 tokenizer mt(iss, false); 641 642 EXPECT(mt, word_type, "var"); 643 EXPECT(mt, eof_type, "<<EOF>>"); 644 EXPECT(mt, eof_type, "<<EOF>>"); 645 } 646 647 { 648 std::istringstream iss("\"var\""); 649 tokenizer mt(iss, false); 650 651 EXPECT(mt, word_type, "var"); 652 EXPECT(mt, eof_type, "<<EOF>>"); 653 EXPECT(mt, eof_type, "<<EOF>>"); 654 } 655 656 { 657 std::istringstream iss("var1\"var2\""); 658 tokenizer mt(iss, false); 659 660 EXPECT(mt, word_type, "var1"); 661 EXPECT(mt, word_type, "var2"); 662 EXPECT(mt, eof_type, "<<EOF>>"); 663 EXPECT(mt, eof_type, "<<EOF>>"); 664 } 665 666 { 667 std::istringstream iss("var1\" var2 \""); 668 tokenizer mt(iss, false); 669 670 EXPECT(mt, word_type, "var1"); 671 EXPECT(mt, word_type, " var2 "); 672 EXPECT(mt, eof_type, "<<EOF>>"); 673 EXPECT(mt, eof_type, "<<EOF>>"); 674 } 675 } 676 677 ATF_TEST_CASE(tokenizer_quotes_ws); 678 ATF_TEST_CASE_HEAD(tokenizer_quotes_ws) 679 { 680 set_md_var("descr", "Tests the tokenizer class using a parser with " 681 "quoted strings and skipping whitespace"); 682 } 683 ATF_TEST_CASE_BODY(tokenizer_quotes_ws) 684 { 685 using namespace quotes; 686 687 { 688 std::istringstream iss(" var "); 689 tokenizer mt(iss, true); 690 691 EXPECT(mt, word_type, "var"); 692 EXPECT(mt, eof_type, "<<EOF>>"); 693 EXPECT(mt, eof_type, "<<EOF>>"); 694 } 695 696 { 697 std::istringstream iss(" \"var\" "); 698 tokenizer mt(iss, true); 699 700 EXPECT(mt, word_type, "var"); 701 EXPECT(mt, eof_type, "<<EOF>>"); 702 EXPECT(mt, eof_type, "<<EOF>>"); 703 } 704 705 { 706 std::istringstream iss(" var1 \"var2\" "); 707 tokenizer mt(iss, true); 708 709 EXPECT(mt, word_type, "var1"); 710 EXPECT(mt, word_type, "var2"); 711 EXPECT(mt, eof_type, "<<EOF>>"); 712 EXPECT(mt, eof_type, "<<EOF>>"); 713 } 714 715 { 716 std::istringstream iss(" var1 \" var2 \" "); 717 tokenizer mt(iss, true); 718 719 EXPECT(mt, word_type, "var1"); 720 EXPECT(mt, word_type, " var2 "); 721 EXPECT(mt, eof_type, "<<EOF>>"); 722 EXPECT(mt, eof_type, "<<EOF>>"); 723 } 724 } 725 726 // ------------------------------------------------------------------------ 727 // Tests for the headers parser. 728 // ------------------------------------------------------------------------ 729 730 class header_reader { 731 std::istream& m_is; 732 733 public: 734 header_reader(std::istream& is) : 735 m_is(is) 736 { 737 } 738 739 void 740 read(void) 741 { 742 std::pair< size_t, tools::parser::headers_map > hml = 743 tools::parser::read_headers(m_is, 1); 744 tools::parser::validate_content_type(hml.second, 745 "application/X-atf-headers-test", 1234); 746 } 747 748 std::vector< std::string > m_calls; 749 }; 750 751 ATF_TEST_CASE_WITHOUT_HEAD(headers_1); 752 ATF_TEST_CASE_BODY(headers_1) 753 { 754 const char* input = 755 "" 756 ; 757 758 const char* exp_calls[] = { 759 NULL 760 }; 761 762 const char* exp_errors[] = { 763 "1: Unexpected token `<<EOF>>'; expected a header name", 764 NULL 765 }; 766 767 do_parser_test< header_reader >(input, exp_calls, exp_errors); 768 } 769 770 ATF_TEST_CASE_WITHOUT_HEAD(headers_2); 771 ATF_TEST_CASE_BODY(headers_2) 772 { 773 const char* input = 774 "Content-Type\n" 775 ; 776 777 const char* exp_calls[] = { 778 NULL 779 }; 780 781 const char* exp_errors[] = { 782 "1: Unexpected token `<<NEWLINE>>'; expected `:'", 783 NULL 784 }; 785 786 do_parser_test< header_reader >(input, exp_calls, exp_errors); 787 } 788 789 ATF_TEST_CASE_WITHOUT_HEAD(headers_3); 790 ATF_TEST_CASE_BODY(headers_3) 791 { 792 const char* input = 793 "Content-Type:\n" 794 ; 795 796 const char* exp_calls[] = { 797 NULL 798 }; 799 800 const char* exp_errors[] = { 801 "1: Unexpected token `<<NEWLINE>>'; expected a textual value", 802 NULL 803 }; 804 805 do_parser_test< header_reader >(input, exp_calls, exp_errors); 806 } 807 808 ATF_TEST_CASE_WITHOUT_HEAD(headers_4); 809 ATF_TEST_CASE_BODY(headers_4) 810 { 811 const char* input = 812 "Content-Type: application/X-atf-headers-test\n" 813 ; 814 815 const char* exp_calls[] = { 816 NULL 817 }; 818 819 const char* exp_errors[] = { 820 "2: Unexpected token `<<EOF>>'; expected a header name", 821 NULL 822 }; 823 824 do_parser_test< header_reader >(input, exp_calls, exp_errors); 825 } 826 827 ATF_TEST_CASE_WITHOUT_HEAD(headers_5); 828 ATF_TEST_CASE_BODY(headers_5) 829 { 830 const char* input = 831 "Content-Type: application/X-atf-headers-test;\n" 832 ; 833 834 const char* exp_calls[] = { 835 NULL 836 }; 837 838 const char* exp_errors[] = { 839 "1: Unexpected token `<<NEWLINE>>'; expected an attribute name", 840 NULL 841 }; 842 843 do_parser_test< header_reader >(input, exp_calls, exp_errors); 844 } 845 846 ATF_TEST_CASE_WITHOUT_HEAD(headers_6); 847 ATF_TEST_CASE_BODY(headers_6) 848 { 849 const char* input = 850 "Content-Type: application/X-atf-headers-test; version\n" 851 ; 852 853 const char* exp_calls[] = { 854 NULL 855 }; 856 857 const char* exp_errors[] = { 858 "1: Unexpected token `<<NEWLINE>>'; expected `='", 859 NULL 860 }; 861 862 do_parser_test< header_reader >(input, exp_calls, exp_errors); 863 } 864 865 ATF_TEST_CASE_WITHOUT_HEAD(headers_7); 866 ATF_TEST_CASE_BODY(headers_7) 867 { 868 const char* input = 869 "Content-Type: application/X-atf-headers-test; version=\n" 870 ; 871 872 const char* exp_calls[] = { 873 NULL 874 }; 875 876 const char* exp_errors[] = { 877 "1: Unexpected token `<<NEWLINE>>'; expected word or quoted string", 878 NULL 879 }; 880 881 do_parser_test< header_reader >(input, exp_calls, exp_errors); 882 } 883 884 ATF_TEST_CASE_WITHOUT_HEAD(headers_8); 885 ATF_TEST_CASE_BODY(headers_8) 886 { 887 const char* input = 888 "Content-Type: application/X-atf-headers-test; version=\"1234\n" 889 ; 890 891 const char* exp_calls[] = { 892 NULL 893 }; 894 895 const char* exp_errors[] = { 896 "1: Missing double quotes before end of line", 897 NULL 898 }; 899 900 do_parser_test< header_reader >(input, exp_calls, exp_errors); 901 } 902 903 ATF_TEST_CASE_WITHOUT_HEAD(headers_9); 904 ATF_TEST_CASE_BODY(headers_9) 905 { 906 const char* input = 907 "Content-Type: application/X-atf-headers-test; version=1234\"\n" 908 ; 909 910 const char* exp_calls[] = { 911 NULL 912 }; 913 914 const char* exp_errors[] = { 915 "1: Missing double quotes before end of line", 916 NULL 917 }; 918 919 do_parser_test< header_reader >(input, exp_calls, exp_errors); 920 } 921 922 ATF_TEST_CASE_WITHOUT_HEAD(headers_10); 923 ATF_TEST_CASE_BODY(headers_10) 924 { 925 const char* input = 926 "Content-Type: application/X-atf-headers-test; version=1234\n" 927 ; 928 929 const char* exp_calls[] = { 930 NULL 931 }; 932 933 const char* exp_errors[] = { 934 "2: Unexpected token `<<EOF>>'; expected a header name", 935 NULL 936 }; 937 938 do_parser_test< header_reader >(input, exp_calls, exp_errors); 939 } 940 941 ATF_TEST_CASE_WITHOUT_HEAD(headers_11); 942 ATF_TEST_CASE_BODY(headers_11) 943 { 944 const char* input = 945 "Content-Type: application/X-atf-headers-test; version=\"1234\"\n" 946 ; 947 948 const char* exp_calls[] = { 949 NULL 950 }; 951 952 const char* exp_errors[] = { 953 "2: Unexpected token `<<EOF>>'; expected a header name", 954 NULL 955 }; 956 957 do_parser_test< header_reader >(input, exp_calls, exp_errors); 958 } 959 960 ATF_TEST_CASE_WITHOUT_HEAD(headers_12); 961 ATF_TEST_CASE_BODY(headers_12) 962 { 963 const char* input = 964 "Content-Type: application/X-atf-headers-test; version=\"1234\"\n" 965 "a b\n" 966 "a-b:\n" 967 "a-b: foo;\n" 968 "a-b: foo; var\n" 969 "a-b: foo; var=\n" 970 "a-b: foo; var=\"a\n" 971 "a-b: foo; var=a\"\n" 972 "a-b: foo; var=\"a\";\n" 973 "a-b: foo; var=\"a\"; second\n" 974 "a-b: foo; var=\"a\"; second=\n" 975 "a-b: foo; var=\"a\"; second=\"b\n" 976 "a-b: foo; var=\"a\"; second=b\"\n" 977 "a-b: foo; var=\"a\"; second=\"b\"\n" 978 ; 979 980 const char* exp_calls[] = { 981 NULL 982 }; 983 984 const char* exp_errors[] = { 985 "2: Unexpected token `b'; expected `:'", 986 "3: Unexpected token `<<NEWLINE>>'; expected a textual value", 987 "4: Unexpected token `<<NEWLINE>>'; expected an attribute name", 988 "5: Unexpected token `<<NEWLINE>>'; expected `='", 989 "6: Unexpected token `<<NEWLINE>>'; expected word or quoted string", 990 "7: Missing double quotes before end of line", 991 "8: Missing double quotes before end of line", 992 "9: Unexpected token `<<NEWLINE>>'; expected an attribute name", 993 "10: Unexpected token `<<NEWLINE>>'; expected `='", 994 "11: Unexpected token `<<NEWLINE>>'; expected word or quoted string", 995 "12: Missing double quotes before end of line", 996 "13: Missing double quotes before end of line", 997 NULL 998 }; 999 1000 do_parser_test< header_reader >(input, exp_calls, exp_errors); 1001 } 1002 1003 // ------------------------------------------------------------------------ 1004 // Main. 1005 // ------------------------------------------------------------------------ 1006 1007 ATF_INIT_TEST_CASES(tcs) 1008 { 1009 // Add test cases for the "parse_error" class. 1010 ATF_ADD_TEST_CASE(tcs, parse_error_to_string); 1011 1012 // Add test cases for the "parse_errors" class. 1013 ATF_ADD_TEST_CASE(tcs, parse_errors_what); 1014 1015 // Add test cases for the "token" class. 1016 ATF_ADD_TEST_CASE(tcs, token_getters); 1017 1018 // Add test cases for the "tokenizer" class. 1019 ATF_ADD_TEST_CASE(tcs, tokenizer_minimal_nows); 1020 ATF_ADD_TEST_CASE(tcs, tokenizer_minimal_ws); 1021 ATF_ADD_TEST_CASE(tcs, tokenizer_delims_nows); 1022 ATF_ADD_TEST_CASE(tcs, tokenizer_delims_ws); 1023 ATF_ADD_TEST_CASE(tcs, tokenizer_keywords_nows); 1024 ATF_ADD_TEST_CASE(tcs, tokenizer_keywords_ws); 1025 ATF_ADD_TEST_CASE(tcs, tokenizer_quotes_nows); 1026 ATF_ADD_TEST_CASE(tcs, tokenizer_quotes_ws); 1027 1028 // Add the tests for the headers parser. 1029 1030 // Add the test cases for the header file. 1031 ATF_ADD_TEST_CASE(tcs, headers_1); 1032 ATF_ADD_TEST_CASE(tcs, headers_2); 1033 ATF_ADD_TEST_CASE(tcs, headers_3); 1034 ATF_ADD_TEST_CASE(tcs, headers_4); 1035 ATF_ADD_TEST_CASE(tcs, headers_5); 1036 ATF_ADD_TEST_CASE(tcs, headers_6); 1037 ATF_ADD_TEST_CASE(tcs, headers_7); 1038 ATF_ADD_TEST_CASE(tcs, headers_8); 1039 ATF_ADD_TEST_CASE(tcs, headers_9); 1040 ATF_ADD_TEST_CASE(tcs, headers_10); 1041 ATF_ADD_TEST_CASE(tcs, headers_11); 1042 ATF_ADD_TEST_CASE(tcs, headers_12); 1043 } 1044