emitter_test.cpp (41681B)
1 #include "yaml-cpp/emitterstyle.h" 2 #include "yaml-cpp/eventhandler.h" 3 #include "yaml-cpp/yaml.h" // IWYU pragma: keep 4 #include "gtest/gtest.h" 5 6 namespace YAML { 7 namespace { 8 9 class NullEventHandler : public EventHandler { 10 virtual void OnDocumentStart(const Mark&) {} 11 virtual void OnDocumentEnd() {} 12 13 virtual void OnNull(const Mark&, anchor_t) {} 14 virtual void OnAlias(const Mark&, anchor_t) {} 15 virtual void OnScalar(const Mark&, const std::string&, anchor_t, 16 const std::string&) {} 17 18 virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t, 19 EmitterStyle::value /* style */) {} 20 virtual void OnSequenceEnd() {} 21 22 virtual void OnMapStart(const Mark&, const std::string&, anchor_t, 23 EmitterStyle::value /* style */) {} 24 virtual void OnMapEnd() {} 25 }; 26 27 class EmitterTest : public ::testing::Test { 28 protected: 29 void ExpectEmit(const std::string& expected) { 30 EXPECT_EQ(expected, out.c_str()); 31 EXPECT_TRUE(out.good()) << "Emitter raised: " << out.GetLastError(); 32 if (expected == out.c_str()) { 33 std::stringstream stream(expected); 34 Parser parser; 35 NullEventHandler handler; 36 parser.HandleNextDocument(handler); 37 } 38 } 39 40 Emitter out; 41 }; 42 43 TEST_F(EmitterTest, SimpleScalar) { 44 out << "Hello, World!"; 45 46 ExpectEmit("Hello, World!"); 47 } 48 49 TEST_F(EmitterTest, SimpleQuotedScalar) { 50 Node n(Load("\"test\"")); 51 out << n; 52 ExpectEmit("test"); 53 } 54 55 TEST_F(EmitterTest, DumpAndSize) { 56 Node n(Load("test")); 57 EXPECT_EQ("test", Dump(n)); 58 out << n; 59 EXPECT_EQ(4, out.size()); 60 } 61 62 TEST_F(EmitterTest, NullScalar) { 63 Node n(Load("null")); 64 out << n; 65 ExpectEmit("~"); 66 } 67 68 TEST_F(EmitterTest, AliasScalar) { 69 Node n(Load("[&a str, *a]")); 70 out << n; 71 ExpectEmit("[&1 str, *1]"); 72 } 73 74 TEST_F(EmitterTest, StringFormat) { 75 out << BeginSeq; 76 out.SetStringFormat(SingleQuoted); 77 out << "string"; 78 out.SetStringFormat(DoubleQuoted); 79 out << "string"; 80 out.SetStringFormat(Literal); 81 out << "string"; 82 out << EndSeq; 83 84 ExpectEmit("- 'string'\n- \"string\"\n- |\n string"); 85 } 86 87 TEST_F(EmitterTest, IntBase) { 88 out << BeginSeq; 89 out.SetIntBase(Dec); 90 out << 1024; 91 out.SetIntBase(Hex); 92 out << 1024; 93 out.SetIntBase(Oct); 94 out << 1024; 95 out << EndSeq; 96 97 ExpectEmit("- 1024\n- 0x400\n- 02000"); 98 } 99 100 TEST_F(EmitterTest, NumberPrecision) { 101 out.SetFloatPrecision(3); 102 out.SetDoublePrecision(2); 103 out << BeginSeq; 104 out << 3.1425926f; 105 out << 53.5893; 106 out << 2384626.4338; 107 out << EndSeq; 108 109 ExpectEmit("- 3.14\n- 54\n- 2.4e+06"); 110 } 111 112 TEST_F(EmitterTest, SimpleSeq) { 113 out << BeginSeq; 114 out << "eggs"; 115 out << "bread"; 116 out << "milk"; 117 out << EndSeq; 118 119 ExpectEmit("- eggs\n- bread\n- milk"); 120 } 121 122 TEST_F(EmitterTest, SimpleFlowSeq) { 123 out << Flow; 124 out << BeginSeq; 125 out << "Larry"; 126 out << "Curly"; 127 out << "Moe"; 128 out << EndSeq; 129 130 ExpectEmit("[Larry, Curly, Moe]"); 131 } 132 133 TEST_F(EmitterTest, EmptyFlowSeq) { 134 out << Flow; 135 out << BeginSeq; 136 out << EndSeq; 137 138 ExpectEmit("[]"); 139 } 140 141 TEST_F(EmitterTest, EmptyBlockSeqWithBegunContent) { 142 out << BeginSeq; 143 out << BeginSeq << Comment("comment") << EndSeq; 144 out << BeginSeq << Newline << EndSeq; 145 out << EndSeq; 146 147 ExpectEmit(R"(- 148 # comment 149 [] 150 - 151 152 [])"); 153 } 154 155 TEST_F(EmitterTest, EmptyBlockMapWithBegunContent) { 156 out << BeginSeq; 157 out << BeginMap << Comment("comment") << EndMap; 158 out << BeginMap << Newline << EndMap; 159 out << EndSeq; 160 161 ExpectEmit(R"(- # comment 162 {} 163 - 164 {})"); 165 } 166 167 TEST_F(EmitterTest, EmptyFlowSeqWithBegunContent) { 168 out << Flow; 169 out << BeginSeq; 170 out << BeginSeq << Comment("comment") << EndSeq; 171 out << BeginSeq << Newline << EndSeq; 172 out << EndSeq; 173 174 ExpectEmit(R"([[ # comment 175 ], [ 176 ]])"); 177 } 178 179 TEST_F(EmitterTest, EmptyFlowMapWithBegunContent) { 180 out << Flow; 181 out << BeginSeq; 182 out << BeginMap << Comment("comment") << EndMap; 183 out << BeginMap << Newline << EndMap; 184 out << EndSeq; 185 186 ExpectEmit(R"([{ # comment 187 }, { 188 }])"); 189 } 190 191 TEST_F(EmitterTest, NestedBlockSeq) { 192 out << BeginSeq; 193 out << "item 1"; 194 out << BeginSeq << "subitem 1" 195 << "subitem 2" << EndSeq; 196 out << EndSeq; 197 198 ExpectEmit("- item 1\n-\n - subitem 1\n - subitem 2"); 199 } 200 201 TEST_F(EmitterTest, NestedFlowSeq) { 202 out << BeginSeq; 203 out << "one"; 204 out << Flow << BeginSeq << "two" 205 << "three" << EndSeq; 206 out << EndSeq; 207 208 ExpectEmit("- one\n- [two, three]"); 209 } 210 211 TEST_F(EmitterTest, SimpleMap) { 212 out << BeginMap; 213 out << Key << "name"; 214 out << Value << "Ryan Braun"; 215 out << Key << "position"; 216 out << Value << "3B"; 217 out << EndMap; 218 219 ExpectEmit("name: Ryan Braun\nposition: 3B"); 220 } 221 222 TEST_F(EmitterTest, SimpleFlowMap) { 223 out << Flow; 224 out << BeginMap; 225 out << Key << "shape"; 226 out << Value << "square"; 227 out << Key << "color"; 228 out << Value << "blue"; 229 out << EndMap; 230 231 ExpectEmit("{shape: square, color: blue}"); 232 } 233 234 TEST_F(EmitterTest, MapAndList) { 235 out << BeginMap; 236 out << Key << "name"; 237 out << Value << "Barack Obama"; 238 out << Key << "children"; 239 out << Value << BeginSeq << "Sasha" 240 << "Malia" << EndSeq; 241 out << EndMap; 242 243 ExpectEmit("name: Barack Obama\nchildren:\n - Sasha\n - Malia"); 244 } 245 246 TEST_F(EmitterTest, ListAndMap) { 247 out << BeginSeq; 248 out << "item 1"; 249 out << BeginMap; 250 out << Key << "pens" << Value << 8; 251 out << Key << "pencils" << Value << 14; 252 out << EndMap; 253 out << "item 2"; 254 out << EndSeq; 255 256 ExpectEmit("- item 1\n- pens: 8\n pencils: 14\n- item 2"); 257 } 258 259 TEST_F(EmitterTest, NestedBlockMap) { 260 out << BeginMap; 261 out << Key << "name"; 262 out << Value << "Fred"; 263 out << Key << "grades"; 264 out << Value; 265 out << BeginMap; 266 out << Key << "algebra" << Value << "A"; 267 out << Key << "physics" << Value << "C+"; 268 out << Key << "literature" << Value << "B"; 269 out << EndMap; 270 out << EndMap; 271 272 ExpectEmit( 273 "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B"); 274 } 275 276 TEST_F(EmitterTest, NestedFlowMap) { 277 out << Flow; 278 out << BeginMap; 279 out << Key << "name"; 280 out << Value << "Fred"; 281 out << Key << "grades"; 282 out << Value; 283 out << BeginMap; 284 out << Key << "algebra" << Value << "A"; 285 out << Key << "physics" << Value << "C+"; 286 out << Key << "literature" << Value << "B"; 287 out << EndMap; 288 out << EndMap; 289 290 ExpectEmit("{name: Fred, grades: {algebra: A, physics: C+, literature: B}}"); 291 } 292 293 TEST_F(EmitterTest, MapListMix) { 294 out << BeginMap; 295 out << Key << "name"; 296 out << Value << "Bob"; 297 out << Key << "position"; 298 out << Value; 299 out << Flow << BeginSeq << 2 << 4 << EndSeq; 300 out << Key << "invincible" << Value << OnOffBool << false; 301 out << EndMap; 302 303 ExpectEmit("name: Bob\nposition: [2, 4]\ninvincible: off"); 304 } 305 306 TEST_F(EmitterTest, SimpleLongKey) { 307 out << LongKey; 308 out << BeginMap; 309 out << Key << "height"; 310 out << Value << "5'9\""; 311 out << Key << "weight"; 312 out << Value << 145; 313 out << EndMap; 314 315 ExpectEmit("? height\n: 5'9\"\n? weight\n: 145"); 316 } 317 318 TEST_F(EmitterTest, SingleLongKey) { 319 const std::string shortKey(1024, 'a'); 320 const std::string longKey(1025, 'a'); 321 out << BeginMap; 322 out << Key << "age"; 323 out << Value << "24"; 324 out << LongKey << Key << "height"; 325 out << Value << "5'9\""; 326 out << Key << "weight"; 327 out << Value << 145; 328 out << Key << shortKey; 329 out << Value << "1"; 330 out << Key << longKey; 331 out << Value << "1"; 332 out << EndMap; 333 334 ExpectEmit("age: 24\n? height\n: 5'9\"\nweight: 145\n" + shortKey + 335 ": 1\n? " + longKey + "\n: 1"); 336 } 337 338 TEST_F(EmitterTest, ComplexLongKey) { 339 out << LongKey; 340 out << BeginMap; 341 out << Key << BeginSeq << 1 << 3 << EndSeq; 342 out << Value << "monster"; 343 out << Key << Flow << BeginSeq << 2 << 0 << EndSeq; 344 out << Value << "demon"; 345 out << EndMap; 346 347 ExpectEmit("? - 1\n - 3\n: monster\n? [2, 0]\n: demon"); 348 } 349 350 TEST_F(EmitterTest, AutoLongKey) { 351 out << BeginMap; 352 out << Key << BeginSeq << 1 << 3 << EndSeq; 353 out << Value << "monster"; 354 out << Key << Flow << BeginSeq << 2 << 0 << EndSeq; 355 out << Value << "demon"; 356 out << Key << "the origin"; 357 out << Value << "angel"; 358 out << EndMap; 359 360 ExpectEmit("? - 1\n - 3\n: monster\n[2, 0]: demon\nthe origin: angel"); 361 } 362 363 TEST_F(EmitterTest, ScalarFormat) { 364 out << BeginSeq; 365 out << "simple scalar"; 366 out << SingleQuoted << "explicit single-quoted scalar"; 367 out << DoubleQuoted << "explicit double-quoted scalar"; 368 out << "auto-detected\ndouble-quoted scalar"; 369 out << "a non-\"auto-detected\" double-quoted scalar"; 370 out << Literal 371 << "literal scalar\nthat may span\nmany, many\nlines " 372 "and have \"whatever\" crazy\tsymbols that we like"; 373 out << EndSeq; 374 375 ExpectEmit( 376 "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit " 377 "double-quoted scalar\"\n- \"auto-detected\\ndouble-quoted " 378 "scalar\"\n- a " 379 "non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n " 380 " " 381 "that may span\n many, many\n lines and have \"whatever\" " 382 "crazy\tsymbols that we like"); 383 } 384 385 TEST_F(EmitterTest, LiteralWithoutTrailingSpaces) { 386 out << YAML::BeginMap; 387 out << YAML::Key << "key"; 388 out << YAML::Value << YAML::Literal; 389 out << "expect that with two newlines\n\n" 390 "no spaces are emitted in the empty line"; 391 out << YAML::EndMap; 392 393 ExpectEmit( 394 "key: |\n" 395 " expect that with two newlines\n\n" 396 " no spaces are emitted in the empty line"); 397 } 398 399 TEST_F(EmitterTest, AutoLongKeyScalar) { 400 out << BeginMap; 401 out << Key << Literal << "multi-line\nscalar"; 402 out << Value << "and its value"; 403 out << EndMap; 404 405 ExpectEmit("? |\n multi-line\n scalar\n: and its value"); 406 } 407 408 TEST_F(EmitterTest, LongKeyFlowMap) { 409 out << Flow; 410 out << BeginMap; 411 out << Key << "simple key"; 412 out << Value << "and value"; 413 out << LongKey << Key << "long key"; 414 out << Value << "and its value"; 415 out << EndMap; 416 417 ExpectEmit("{simple key: and value, ? long key: and its value}"); 418 } 419 420 TEST_F(EmitterTest, BlockMapAsKey) { 421 out << BeginMap; 422 out << Key; 423 out << BeginMap; 424 out << Key << "key" << Value << "value"; 425 out << Key << "next key" << Value << "next value"; 426 out << EndMap; 427 out << Value; 428 out << "total value"; 429 out << EndMap; 430 431 ExpectEmit("? key: value\n next key: next value\n: total value"); 432 } 433 434 TEST_F(EmitterTest, AliasAndAnchor) { 435 out << BeginSeq; 436 out << Anchor("fred"); 437 out << BeginMap; 438 out << Key << "name" << Value << "Fred"; 439 out << Key << "age" << Value << 42; 440 out << EndMap; 441 out << Alias("fred"); 442 out << EndSeq; 443 444 ExpectEmit("- &fred\n name: Fred\n age: 42\n- *fred"); 445 } 446 447 TEST_F(EmitterTest, AliasOnKey) { 448 out << BeginSeq; 449 out << Anchor("name") << "Name"; 450 out << BeginMap; 451 out << Key << Alias("name") << Value << "Fred"; 452 out << EndMap; 453 out << Flow << BeginMap; 454 out << Key << Alias("name") << Value << "Mike"; 455 out << EndMap; 456 out << EndSeq; 457 ExpectEmit(R"(- &name Name 458 - *name : Fred 459 - {*name : Mike})"); 460 } 461 462 TEST_F(EmitterTest, AliasAndAnchorWithNull) { 463 out << BeginSeq; 464 out << Anchor("fred") << Null; 465 out << Alias("fred"); 466 out << EndSeq; 467 468 ExpectEmit("- &fred ~\n- *fred"); 469 } 470 471 TEST_F(EmitterTest, AliasAndAnchorInFlow) { 472 out << Flow << BeginSeq; 473 out << Anchor("fred"); 474 out << BeginMap; 475 out << Key << "name" << Value << "Fred"; 476 out << Key << "age" << Value << 42; 477 out << EndMap; 478 out << Alias("fred"); 479 out << EndSeq; 480 481 ExpectEmit("[&fred {name: Fred, age: 42}, *fred]"); 482 } 483 484 TEST_F(EmitterTest, SimpleVerbatimTag) { 485 out << VerbatimTag("!foo") << "bar"; 486 487 ExpectEmit("!<!foo> bar"); 488 } 489 490 TEST_F(EmitterTest, VerbatimTagInBlockSeq) { 491 out << BeginSeq; 492 out << VerbatimTag("!foo") << "bar"; 493 out << "baz"; 494 out << EndSeq; 495 496 ExpectEmit("- !<!foo> bar\n- baz"); 497 } 498 499 TEST_F(EmitterTest, VerbatimTagInFlowSeq) { 500 out << Flow << BeginSeq; 501 out << VerbatimTag("!foo") << "bar"; 502 out << "baz"; 503 out << EndSeq; 504 505 ExpectEmit("[!<!foo> bar, baz]"); 506 } 507 508 TEST_F(EmitterTest, VerbatimTagInFlowSeqWithNull) { 509 out << Flow << BeginSeq; 510 out << VerbatimTag("!foo") << Null; 511 out << "baz"; 512 out << EndSeq; 513 514 ExpectEmit("[!<!foo> ~, baz]"); 515 } 516 517 TEST_F(EmitterTest, VerbatimTagInBlockMap) { 518 out << BeginMap; 519 out << Key << VerbatimTag("!foo") << "bar"; 520 out << Value << VerbatimTag("!waz") << "baz"; 521 out << EndMap; 522 523 ExpectEmit("!<!foo> bar: !<!waz> baz"); 524 } 525 526 TEST_F(EmitterTest, VerbatimTagInFlowMap) { 527 out << Flow << BeginMap; 528 out << Key << VerbatimTag("!foo") << "bar"; 529 out << Value << "baz"; 530 out << EndMap; 531 532 ExpectEmit("{!<!foo> bar: baz}"); 533 } 534 535 TEST_F(EmitterTest, VerbatimTagInFlowMapWithNull) { 536 out << Flow << BeginMap; 537 out << Key << VerbatimTag("!foo") << Null; 538 out << Value << "baz"; 539 out << EndMap; 540 541 ExpectEmit("{!<!foo> ~: baz}"); 542 } 543 544 TEST_F(EmitterTest, VerbatimTagWithEmptySeq) { 545 out << VerbatimTag("!foo") << BeginSeq << EndSeq; 546 547 ExpectEmit("!<!foo>\n[]"); 548 } 549 550 TEST_F(EmitterTest, VerbatimTagWithEmptyMap) { 551 out << VerbatimTag("!bar") << BeginMap << EndMap; 552 553 ExpectEmit("!<!bar>\n{}"); 554 } 555 556 TEST_F(EmitterTest, VerbatimTagWithEmptySeqAndMap) { 557 out << BeginSeq; 558 out << VerbatimTag("!foo") << BeginSeq << EndSeq; 559 out << VerbatimTag("!bar") << BeginMap << EndMap; 560 out << EndSeq; 561 562 ExpectEmit("- !<!foo>\n []\n- !<!bar>\n {}"); 563 } 564 565 TEST_F(EmitterTest, ByKindTagWithScalar) { 566 out << BeginSeq; 567 out << DoubleQuoted << "12"; 568 out << "12"; 569 out << TagByKind << "12"; 570 out << EndSeq; 571 572 ExpectEmit("- \"12\"\n- 12\n- ! 12"); 573 } 574 575 TEST_F(EmitterTest, LocalTagInNameHandle) { 576 out << LocalTag("a", "foo") << "bar"; 577 578 ExpectEmit("!a!foo bar"); 579 } 580 581 TEST_F(EmitterTest, LocalTagWithScalar) { 582 out << LocalTag("foo") << "bar"; 583 584 ExpectEmit("!foo bar"); 585 } 586 587 TEST_F(EmitterTest, ComplexDoc) { 588 out << BeginMap; 589 out << Key << "receipt"; 590 out << Value << "Oz-Ware Purchase Invoice"; 591 out << Key << "date"; 592 out << Value << "2007-08-06"; 593 out << Key << "customer"; 594 out << Value; 595 out << BeginMap; 596 out << Key << "given"; 597 out << Value << "Dorothy"; 598 out << Key << "family"; 599 out << Value << "Gale"; 600 out << EndMap; 601 out << Key << "items"; 602 out << Value; 603 out << BeginSeq; 604 out << BeginMap; 605 out << Key << "part_no"; 606 out << Value << "A4786"; 607 out << Key << "descrip"; 608 out << Value << "Water Bucket (Filled)"; 609 out << Key << "price"; 610 out << Value << 1.47; 611 out << Key << "quantity"; 612 out << Value << 4; 613 out << EndMap; 614 out << BeginMap; 615 out << Key << "part_no"; 616 out << Value << "E1628"; 617 out << Key << "descrip"; 618 out << Value << "High Heeled \"Ruby\" Slippers"; 619 out << Key << "price"; 620 out << Value << 100.27; 621 out << Key << "quantity"; 622 out << Value << 1; 623 out << EndMap; 624 out << EndSeq; 625 out << Key << "bill-to"; 626 out << Value << Anchor("id001"); 627 out << BeginMap; 628 out << Key << "street"; 629 out << Value << Literal << "123 Tornado Alley\nSuite 16"; 630 out << Key << "city"; 631 out << Value << "East Westville"; 632 out << Key << "state"; 633 out << Value << "KS"; 634 out << EndMap; 635 out << Key << "ship-to"; 636 out << Value << Alias("id001"); 637 out << EndMap; 638 639 ExpectEmit( 640 "receipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n " 641 "given: Dorothy\n family: Gale\nitems:\n - part_no: A4786\n " 642 "descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n - " 643 "part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: " 644 "100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado " 645 "Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: " 646 "*id001"); 647 } 648 649 TEST_F(EmitterTest, STLContainers) { 650 out << BeginSeq; 651 std::vector<int> primes; 652 primes.push_back(2); 653 primes.push_back(3); 654 primes.push_back(5); 655 primes.push_back(7); 656 primes.push_back(11); 657 primes.push_back(13); 658 out << Flow << primes; 659 std::map<std::string, int> ages; 660 ages["Daniel"] = 26; 661 ages["Jesse"] = 24; 662 out << ages; 663 out << EndSeq; 664 665 ExpectEmit("- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24"); 666 } 667 668 TEST_F(EmitterTest, CommentStyle) { 669 out.SetPreCommentIndent(1); 670 out.SetPostCommentIndent(2); 671 out << BeginMap; 672 out << Key << "method"; 673 out << Value << "least squares" << Comment("should we change this method?"); 674 out << EndMap; 675 676 ExpectEmit("method: least squares # should we change this method?"); 677 } 678 679 TEST_F(EmitterTest, SimpleComment) { 680 out << BeginMap; 681 out << Key << "method"; 682 out << Value << "least squares" << Comment("should we change this method?"); 683 out << EndMap; 684 685 ExpectEmit("method: least squares # should we change this method?"); 686 } 687 688 TEST_F(EmitterTest, MultiLineComment) { 689 out << BeginSeq; 690 out << "item 1" 691 << Comment( 692 "really really long\ncomment that couldn't " 693 "possibly\nfit on one line"); 694 out << "item 2"; 695 out << EndSeq; 696 697 ExpectEmit( 698 "- item 1 # really really long\n # comment that couldn't " 699 "possibly\n # fit on one line\n- item 2"); 700 } 701 702 TEST_F(EmitterTest, ComplexComments) { 703 out << BeginMap; 704 out << LongKey << Key << "long key" << Comment("long key"); 705 out << Value << "value"; 706 out << EndMap; 707 708 ExpectEmit("? long key # long key\n: value"); 709 } 710 711 TEST_F(EmitterTest, InitialComment) { 712 out << Comment("A comment describing the purpose of the file."); 713 out << BeginMap << Key << "key" << Value << "value" << EndMap; 714 715 ExpectEmit("# A comment describing the purpose of the file.\nkey: value"); 716 } 717 718 TEST_F(EmitterTest, InitialCommentWithDocIndicator) { 719 out << BeginDoc << Comment("A comment describing the purpose of the file."); 720 out << BeginMap << Key << "key" << Value << "value" << EndMap; 721 722 ExpectEmit( 723 "---\n# A comment describing the purpose of the file.\nkey: value"); 724 } 725 726 TEST_F(EmitterTest, CommentInFlowSeq) { 727 out << Flow << BeginSeq << "foo" << Comment("foo!") << "bar" << EndSeq; 728 729 ExpectEmit("[foo, # foo!\nbar]"); 730 } 731 732 TEST_F(EmitterTest, CommentInFlowMap) { 733 out << Flow << BeginMap; 734 out << Key << "foo" << Value << "foo value"; 735 out << Key << "bar" << Value << "bar value" << Comment("bar!"); 736 out << Key << "baz" << Value << "baz value" << Comment("baz!"); 737 out << EndMap; 738 739 ExpectEmit( 740 "{foo: foo value, bar: bar value, # bar!\nbaz: baz value, # baz!\n}"); 741 } 742 743 TEST_F(EmitterTest, Indentation) { 744 out << Indent(4); 745 out << BeginSeq; 746 out << BeginMap; 747 out << Key << "key 1" << Value << "value 1"; 748 out << Key << "key 2" << Value << BeginSeq << "a" 749 << "b" 750 << "c" << EndSeq; 751 out << EndMap; 752 out << EndSeq; 753 754 ExpectEmit( 755 "- key 1: value 1\n key 2:\n - a\n - b\n - " 756 " c"); 757 } 758 759 TEST_F(EmitterTest, SimpleGlobalSettings) { 760 out.SetIndent(4); 761 out.SetMapFormat(LongKey); 762 763 out << BeginSeq; 764 out << BeginMap; 765 out << Key << "key 1" << Value << "value 1"; 766 out << Key << "key 2" << Value << Flow << BeginSeq << "a" 767 << "b" 768 << "c" << EndSeq; 769 out << EndMap; 770 out << EndSeq; 771 772 ExpectEmit("- ? key 1\n : value 1\n ? key 2\n : [a, b, c]"); 773 } 774 775 TEST_F(EmitterTest, GlobalLongKeyOnSeq) { 776 out.SetMapFormat(LongKey); 777 778 out << BeginMap; 779 out << Key << Anchor("key"); 780 out << BeginSeq << "a" 781 << "b" << EndSeq; 782 out << Value << Anchor("value"); 783 out << BeginSeq << "c" 784 << "d" << EndSeq; 785 out << Key << Alias("key") << Value << Alias("value"); 786 out << EndMap; 787 788 ExpectEmit(R"(? &key 789 - a 790 - b 791 : &value 792 - c 793 - d 794 ? *key 795 : *value)"); 796 } 797 798 TEST_F(EmitterTest, GlobalLongKeyOnMap) { 799 out.SetMapFormat(LongKey); 800 801 out << BeginMap; 802 out << Key << Anchor("key"); 803 out << BeginMap << "a" 804 << "b" << EndMap; 805 out << Value << Anchor("value"); 806 out << BeginMap << "c" 807 << "d" << EndMap; 808 out << Key << Alias("key") << Value << Alias("value"); 809 out << EndMap; 810 811 ExpectEmit(R"(? &key 812 ? a 813 : b 814 : &value 815 ? c 816 : d 817 ? *key 818 : *value)"); 819 } 820 821 TEST_F(EmitterTest, GlobalSettingStyleOnSeqNode) { 822 Node n(Load(R"(foo: 823 - 1 824 - 2 825 - 3 826 bar: aa)")); 827 out.SetSeqFormat(YAML::Flow); 828 out << n; 829 ExpectEmit(R"(foo: [1, 2, 3] 830 bar: aa)"); 831 } 832 833 TEST_F(EmitterTest, GlobalSettingStyleOnMapNode) { 834 Node n(Load(R"(- 835 foo: a 836 bar: b 837 - 2 838 - 3)")); 839 out.SetMapFormat(YAML::Flow); 840 out << n; 841 ExpectEmit(R"(- {foo: a, bar: b} 842 - 2 843 - 3)"); 844 } 845 846 TEST_F(EmitterTest, ComplexGlobalSettings) { 847 out << BeginSeq; 848 out << Block; 849 out << BeginMap; 850 out << Key << "key 1" << Value << "value 1"; 851 out << Key << "key 2" << Value; 852 out.SetSeqFormat(Flow); 853 out << BeginSeq << "a" 854 << "b" 855 << "c" << EndSeq; 856 out << EndMap; 857 out << BeginMap; 858 out << Key << BeginSeq << 1 << 2 << EndSeq; 859 out << Value << BeginMap << Key << "a" << Value << "b" << EndMap; 860 out << EndMap; 861 out << EndSeq; 862 863 ExpectEmit("- key 1: value 1\n key 2: [a, b, c]\n- [1, 2]:\n a: b"); 864 } 865 866 TEST_F(EmitterTest, Null) { 867 out << BeginSeq; 868 out << Null; 869 out << BeginMap; 870 out << Key << "null value" << Value << Null; 871 out << Key << Null << Value << "null key"; 872 out << EndMap; 873 out << EndSeq; 874 875 ExpectEmit("- ~\n- null value: ~\n ~: null key"); 876 } 877 878 TEST_F(EmitterTest, OutputCharset) { 879 out << BeginSeq; 880 out.SetOutputCharset(EmitNonAscii); 881 out << "\x24 \xC2\xA2 \xE2\x82\xAC"; 882 out.SetOutputCharset(EscapeNonAscii); 883 out << "\x24 \xC2\xA2 \xE2\x82\xAC"; 884 out << EndSeq; 885 886 ExpectEmit("- \x24 \xC2\xA2 \xE2\x82\xAC\n- \"\x24 \\xa2 \\u20ac\""); 887 } 888 889 TEST_F(EmitterTest, EscapedUnicode) { 890 out << EscapeNonAscii << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; 891 892 ExpectEmit("\"$ \\xa2 \\u20ac \\U00024b62\""); 893 } 894 895 TEST_F(EmitterTest, Unicode) { 896 out << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; 897 ExpectEmit("\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"); 898 } 899 900 TEST_F(EmitterTest, DoubleQuotedUnicode) { 901 out << DoubleQuoted << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; 902 ExpectEmit("\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\""); 903 } 904 905 TEST_F(EmitterTest, EscapedJsonString) { 906 out.SetStringFormat(DoubleQuoted); 907 out.SetOutputCharset(EscapeAsJson); 908 out << "\" \\ " 909 "\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0A \x0B \x0C \x0D \x0E \x0F " 910 "\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1A \x1B \x1C \x1D \x1E \x1F " 911 "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; 912 913 ExpectEmit(R"("\" \\ \u0001 \u0002 \u0003 \u0004 \u0005 \u0006 \u0007 \b \t )" 914 R"(\n \u000b \f \r \u000e \u000f \u0010 \u0011 \u0012 \u0013 )" 915 R"(\u0014 \u0015 \u0016 \u0017 \u0018 \u0019 \u001a \u001b )" 916 R"(\u001c \u001d \u001e \u001f )" 917 "$ \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\""); 918 } 919 920 TEST_F(EmitterTest, EscapedCharacters) { 921 out << BeginSeq 922 << '\x00' 923 << '\x0C' 924 << '\x0D' 925 << EndSeq; 926 927 ExpectEmit("- \"\\x00\"\n- \"\\f\"\n- \"\\r\""); 928 } 929 930 TEST_F(EmitterTest, CharactersEscapedAsJson) { 931 out.SetOutputCharset(EscapeAsJson); 932 out << BeginSeq 933 << '\x00' 934 << '\x0C' 935 << '\x0D' 936 << EndSeq; 937 938 ExpectEmit("- \"\\u0000\"\n- \"\\f\"\n- \"\\r\""); 939 } 940 941 TEST_F(EmitterTest, DoubleQuotedString) { 942 out << DoubleQuoted << "\" \\ \n \t \r \b \x15 \xEF\xBB\xBF \x24"; 943 ExpectEmit("\"\\\" \\\\ \\n \\t \\r \\b \\x15 \\ufeff $\""); 944 } 945 946 struct Foo { 947 Foo() : x(0) {} 948 Foo(int x_, const std::string& bar_) : x(x_), bar(bar_) {} 949 950 int x; 951 std::string bar; 952 }; 953 954 Emitter& operator<<(Emitter& out, const Foo& foo) { 955 out << BeginMap; 956 out << Key << "x" << Value << foo.x; 957 out << Key << "bar" << Value << foo.bar; 958 out << EndMap; 959 return out; 960 } 961 962 TEST_F(EmitterTest, UserType) { 963 out << BeginSeq; 964 out << Foo(5, "hello"); 965 out << Foo(3, "goodbye"); 966 out << EndSeq; 967 968 ExpectEmit("- x: 5\n bar: hello\n- x: 3\n bar: goodbye"); 969 } 970 971 TEST_F(EmitterTest, UserTypeInContainer) { 972 std::vector<Foo> fv; 973 fv.push_back(Foo(5, "hello")); 974 fv.push_back(Foo(3, "goodbye")); 975 out << fv; 976 977 ExpectEmit("- x: 5\n bar: hello\n- x: 3\n bar: goodbye"); 978 } 979 980 template <typename T> 981 Emitter& operator<<(Emitter& out, const T* v) { 982 if (v) 983 out << *v; 984 else 985 out << Null; 986 return out; 987 } 988 989 TEST_F(EmitterTest, PointerToInt) { 990 int foo = 5; 991 int* bar = &foo; 992 int* baz = 0; 993 out << BeginSeq; 994 out << bar << baz; 995 out << EndSeq; 996 997 ExpectEmit("- 5\n- ~"); 998 } 999 1000 TEST_F(EmitterTest, PointerToUserType) { 1001 Foo foo(5, "hello"); 1002 Foo* bar = &foo; 1003 Foo* baz = 0; 1004 out << BeginSeq; 1005 out << bar << baz; 1006 out << EndSeq; 1007 1008 ExpectEmit("- x: 5\n bar: hello\n- ~"); 1009 } 1010 1011 TEST_F(EmitterTest, NewlineAtEnd) { 1012 out << "Hello" << Newline << Newline; 1013 ExpectEmit("Hello\n\n"); 1014 } 1015 1016 TEST_F(EmitterTest, NewlineInBlockSequence) { 1017 out << BeginSeq; 1018 out << "a" << Newline << "b" 1019 << "c" << Newline << "d"; 1020 out << EndSeq; 1021 ExpectEmit("- a\n\n- b\n- c\n\n- d"); 1022 } 1023 1024 TEST_F(EmitterTest, NewlineInFlowSequence) { 1025 out << Flow << BeginSeq; 1026 out << "a" << Newline << "b" 1027 << "c" << Newline << "d"; 1028 out << EndSeq; 1029 ExpectEmit("[a,\nb, c,\nd]"); 1030 } 1031 1032 TEST_F(EmitterTest, NewlineInBlockMap) { 1033 out << BeginMap; 1034 out << Key << "a" << Value << "foo" << Newline; 1035 out << Key << "b" << Newline << Value << "bar"; 1036 out << LongKey << Key << "c" << Newline << Value << "car"; 1037 out << EndMap; 1038 ExpectEmit("a: foo\nb:\n bar\n? c\n\n: car"); 1039 } 1040 1041 TEST_F(EmitterTest, NewlineInFlowMap) { 1042 out << Flow << BeginMap; 1043 out << Key << "a" << Value << "foo" << Newline; 1044 out << Key << "b" << Value << "bar"; 1045 out << EndMap; 1046 ExpectEmit("{a: foo,\nb: bar}"); 1047 } 1048 1049 TEST_F(EmitterTest, LotsOfNewlines) { 1050 out << BeginSeq; 1051 out << "a" << Newline; 1052 out << BeginSeq; 1053 out << "b" 1054 << "c" << Newline; 1055 out << EndSeq; 1056 out << Newline; 1057 out << BeginMap; 1058 out << Newline << Key << "d" << Value << Newline << "e"; 1059 out << LongKey << Key << "f" << Newline << Value << "foo"; 1060 out << EndMap; 1061 out << EndSeq; 1062 ExpectEmit("- a\n\n-\n - b\n - c\n\n\n-\n d:\n e\n ? f\n\n : foo"); 1063 } 1064 1065 TEST_F(EmitterTest, Binary) { 1066 out << Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13); 1067 ExpectEmit("!!binary \"SGVsbG8sIFdvcmxkIQ==\""); 1068 } 1069 1070 TEST_F(EmitterTest, LongBinary) { 1071 out << Binary( 1072 reinterpret_cast<const unsigned char*>( 1073 "Man is distinguished, not only by his reason, but by this " 1074 "singular passion from other animals, which is a lust of the " 1075 "mind, that by a perseverance of delight in the continued and " 1076 "indefatigable generation of knowledge, exceeds the short " 1077 "vehemence of any carnal pleasure.\n"), 1078 270); 1079 ExpectEmit( 1080 "!!binary " 1081 "\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS" 1082 "B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG" 1083 "x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi" 1084 "B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG" 1085 "dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS" 1086 "4K\""); 1087 } 1088 1089 TEST_F(EmitterTest, EmptyBinary) { 1090 out << Binary(reinterpret_cast<const unsigned char*>(""), 0); 1091 ExpectEmit("!!binary \"\""); 1092 } 1093 1094 TEST_F(EmitterTest, ColonAtEndOfScalar) { 1095 out << "a:"; 1096 ExpectEmit("\"a:\""); 1097 } 1098 1099 TEST_F(EmitterTest, ColonAsScalar) { 1100 out << BeginMap; 1101 out << Key << "apple" << Value << ":"; 1102 out << Key << "banana" << Value << ":"; 1103 out << EndMap; 1104 ExpectEmit("apple: \":\"\nbanana: \":\""); 1105 } 1106 1107 TEST_F(EmitterTest, ColonAtEndOfScalarInFlow) { 1108 out << Flow << BeginMap << Key << "C:" << Value << "C:" << EndMap; 1109 ExpectEmit("{\"C:\": \"C:\"}"); 1110 } 1111 1112 TEST_F(EmitterTest, GlobalBoolFormatting) { 1113 out << BeginSeq; 1114 out.SetBoolFormat(UpperCase); 1115 out.SetBoolFormat(YesNoBool); 1116 out << true; 1117 out << false; 1118 out.SetBoolFormat(TrueFalseBool); 1119 out << true; 1120 out << false; 1121 out.SetBoolFormat(OnOffBool); 1122 out << true; 1123 out << false; 1124 out.SetBoolFormat(LowerCase); 1125 out.SetBoolFormat(YesNoBool); 1126 out << true; 1127 out << false; 1128 out.SetBoolFormat(TrueFalseBool); 1129 out << true; 1130 out << false; 1131 out.SetBoolFormat(OnOffBool); 1132 out << true; 1133 out << false; 1134 out.SetBoolFormat(CamelCase); 1135 out.SetBoolFormat(YesNoBool); 1136 out << true; 1137 out << false; 1138 out.SetBoolFormat(TrueFalseBool); 1139 out << true; 1140 out << false; 1141 out.SetBoolFormat(OnOffBool); 1142 out << true; 1143 out << false; 1144 out.SetBoolFormat(ShortBool); 1145 out.SetBoolFormat(UpperCase); 1146 out.SetBoolFormat(YesNoBool); 1147 out << true; 1148 out << false; 1149 out.SetBoolFormat(TrueFalseBool); 1150 out << true; 1151 out << false; 1152 out.SetBoolFormat(OnOffBool); 1153 out << true; 1154 out << false; 1155 out << EndSeq; 1156 ExpectEmit( 1157 "- YES\n- NO\n- TRUE\n- FALSE\n- ON\n- OFF\n" 1158 "- yes\n- no\n- true\n- false\n- on\n- off\n" 1159 "- Yes\n- No\n- True\n- False\n- On\n- Off\n" 1160 "- Y\n- N\n- Y\n- N\n- Y\n- N"); 1161 } 1162 1163 TEST_F(EmitterTest, BoolFormatting) { 1164 out << BeginSeq; 1165 out << TrueFalseBool << UpperCase << true; 1166 out << TrueFalseBool << CamelCase << true; 1167 out << TrueFalseBool << LowerCase << true; 1168 out << TrueFalseBool << UpperCase << false; 1169 out << TrueFalseBool << CamelCase << false; 1170 out << TrueFalseBool << LowerCase << false; 1171 out << YesNoBool << UpperCase << true; 1172 out << YesNoBool << CamelCase << true; 1173 out << YesNoBool << LowerCase << true; 1174 out << YesNoBool << UpperCase << false; 1175 out << YesNoBool << CamelCase << false; 1176 out << YesNoBool << LowerCase << false; 1177 out << OnOffBool << UpperCase << true; 1178 out << OnOffBool << CamelCase << true; 1179 out << OnOffBool << LowerCase << true; 1180 out << OnOffBool << UpperCase << false; 1181 out << OnOffBool << CamelCase << false; 1182 out << OnOffBool << LowerCase << false; 1183 out << ShortBool << UpperCase << true; 1184 out << ShortBool << CamelCase << true; 1185 out << ShortBool << LowerCase << true; 1186 out << ShortBool << UpperCase << false; 1187 out << ShortBool << CamelCase << false; 1188 out << ShortBool << LowerCase << false; 1189 out << EndSeq; 1190 ExpectEmit( 1191 "- TRUE\n- True\n- true\n- FALSE\n- False\n- false\n" 1192 "- YES\n- Yes\n- yes\n- NO\n- No\n- no\n" 1193 "- ON\n- On\n- on\n- OFF\n- Off\n- off\n" 1194 "- Y\n- Y\n- y\n- N\n- N\n- n"); 1195 } 1196 1197 TEST_F(EmitterTest, GlobalNullFormatting) { 1198 out << Flow << BeginSeq; 1199 out.SetNullFormat(LowerNull); 1200 out << Null; 1201 out.SetNullFormat(UpperNull); 1202 out << Null; 1203 out.SetNullFormat(CamelNull); 1204 out << Null; 1205 out.SetNullFormat(TildeNull); 1206 out << Null; 1207 out << EndSeq; 1208 ExpectEmit("[null, NULL, Null, ~]"); 1209 } 1210 1211 TEST_F(EmitterTest, NullFormatting) { 1212 out << Flow << BeginSeq; 1213 out << LowerNull << Null; 1214 out << UpperNull << Null; 1215 out << CamelNull << Null; 1216 out << TildeNull << Null; 1217 out << EndSeq; 1218 ExpectEmit("[null, NULL, Null, ~]"); 1219 } 1220 1221 TEST_F(EmitterTest, NullFormattingOnNode) { 1222 Node n(Load("null")); 1223 out << Flow << BeginSeq; 1224 out.SetNullFormat(LowerNull); 1225 out << n; 1226 out.SetNullFormat(UpperNull); 1227 out << n; 1228 out.SetNullFormat(CamelNull); 1229 out << n; 1230 out.SetNullFormat(TildeNull); 1231 out << n; 1232 out << EndSeq; 1233 ExpectEmit("[null, NULL, Null, ~]"); 1234 } 1235 1236 // TODO: Fix this test. 1237 // TEST_F(EmitterTest, DocStartAndEnd) { 1238 // out << BeginDoc; 1239 // out << BeginSeq << 1 << 2 << 3 << EndSeq; 1240 // out << BeginDoc; 1241 // out << "Hi there!"; 1242 // out << EndDoc; 1243 // out << EndDoc; 1244 // out << EndDoc; 1245 // out << BeginDoc; 1246 // out << VerbatimTag("foo") << "bar"; 1247 // ExpectEmit( 1248 // "---\n- 1\n- 2\n- 3\n---\nHi there!\n...\n...\n...\n---\n!<foo> bar"); 1249 //} 1250 1251 TEST_F(EmitterTest, ImplicitDocStart) { 1252 out << "Hi"; 1253 out << "Bye"; 1254 out << "Oops"; 1255 ExpectEmit("Hi\n---\nBye\n---\nOops"); 1256 } 1257 1258 TEST_F(EmitterTest, EmptyString) { 1259 out << BeginMap; 1260 out << Key << "key" << Value << ""; 1261 out << EndMap; 1262 ExpectEmit("key: \"\""); 1263 } 1264 1265 TEST_F(EmitterTest, SingleChar) { 1266 out << BeginSeq; 1267 out << 'a'; 1268 out << ':'; 1269 out << (char)0x10; 1270 out << '\n'; 1271 out << ' '; 1272 out << '\t'; 1273 out << EndSeq; 1274 ExpectEmit("- a\n- \":\"\n- \"\\x10\"\n- \"\\n\"\n- \" \"\n- \"\\t\""); 1275 } 1276 1277 TEST_F(EmitterTest, DefaultPrecision) { 1278 out << BeginSeq; 1279 out << 1.3125f; 1280 out << 1.23455810546875; 1281 out << EndSeq; 1282 ExpectEmit("- 1.3125\n- 1.23455810546875"); 1283 } 1284 1285 TEST_F(EmitterTest, SetPrecision) { 1286 out << BeginSeq; 1287 out << FloatPrecision(3) << 1.3125f; 1288 out << DoublePrecision(6) << 1.23455810546875; 1289 out << EndSeq; 1290 ExpectEmit("- 1.31\n- 1.23456"); 1291 } 1292 1293 TEST_F(EmitterTest, DashInBlockContext) { 1294 out << BeginMap; 1295 out << Key << "key" << Value << "-"; 1296 out << EndMap; 1297 ExpectEmit("key: \"-\""); 1298 } 1299 1300 TEST_F(EmitterTest, HexAndOct) { 1301 out << Flow << BeginSeq; 1302 out << 31; 1303 out << Hex << 31; 1304 out << Oct << 31; 1305 out << EndSeq; 1306 ExpectEmit("[31, 0x1f, 037]"); 1307 } 1308 1309 TEST_F(EmitterTest, CompactMapWithNewline) { 1310 out << Comment("Characteristics"); 1311 out << BeginSeq; 1312 out << BeginMap; 1313 out << Key << "color" << Value << "blue"; 1314 out << Key << "height" << Value << 120; 1315 out << EndMap; 1316 out << Newline << Newline; 1317 out << Comment("Skills"); 1318 out << BeginMap; 1319 out << Key << "attack" << Value << 23; 1320 out << Key << "intelligence" << Value << 56; 1321 out << EndMap; 1322 out << EndSeq; 1323 1324 ExpectEmit( 1325 "# Characteristics\n" 1326 "- color: blue\n" 1327 " height: 120\n" 1328 "\n" 1329 "# Skills\n" 1330 "- attack: 23\n" 1331 " intelligence: 56"); 1332 } 1333 1334 TEST_F(EmitterTest, ForceSingleQuotedToDouble) { 1335 out << SingleQuoted << "Hello\nWorld"; 1336 1337 ExpectEmit("\"Hello\\nWorld\""); 1338 } 1339 1340 TEST_F(EmitterTest, QuoteNull) { 1341 out << "null"; 1342 1343 ExpectEmit("\"null\""); 1344 } 1345 1346 TEST_F(EmitterTest, ValueOfDoubleQuote) { 1347 out << YAML::BeginMap; 1348 out << YAML::Key << "foo" << YAML::Value << '"'; 1349 out << YAML::EndMap; 1350 1351 ExpectEmit("foo: \"\\\"\""); 1352 } 1353 1354 TEST_F(EmitterTest, ValueOfBackslash) { 1355 out << YAML::BeginMap; 1356 out << YAML::Key << "foo" << YAML::Value << '\\'; 1357 out << YAML::EndMap; 1358 1359 ExpectEmit("foo: \"\\\\\""); 1360 } 1361 1362 TEST_F(EmitterTest, Infinity) { 1363 out << YAML::BeginMap; 1364 out << YAML::Key << "foo" << YAML::Value 1365 << std::numeric_limits<float>::infinity(); 1366 out << YAML::Key << "bar" << YAML::Value 1367 << std::numeric_limits<double>::infinity(); 1368 out << YAML::EndMap; 1369 1370 ExpectEmit( 1371 "foo: .inf\n" 1372 "bar: .inf"); 1373 } 1374 1375 TEST_F(EmitterTest, NegInfinity) { 1376 out << YAML::BeginMap; 1377 out << YAML::Key << "foo" << YAML::Value 1378 << -std::numeric_limits<float>::infinity(); 1379 out << YAML::Key << "bar" << YAML::Value 1380 << -std::numeric_limits<double>::infinity(); 1381 out << YAML::EndMap; 1382 1383 ExpectEmit( 1384 "foo: -.inf\n" 1385 "bar: -.inf"); 1386 } 1387 1388 TEST_F(EmitterTest, NaN) { 1389 out << YAML::BeginMap; 1390 out << YAML::Key << "foo" << YAML::Value 1391 << std::numeric_limits<float>::quiet_NaN(); 1392 out << YAML::Key << "bar" << YAML::Value 1393 << std::numeric_limits<double>::quiet_NaN(); 1394 out << YAML::EndMap; 1395 1396 ExpectEmit( 1397 "foo: .nan\n" 1398 "bar: .nan"); 1399 } 1400 1401 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLine) { 1402 out << YAML::BeginMap; 1403 1404 out << YAML::Key << "NodeA" << YAML::Value << YAML::BeginMap; 1405 out << YAML::Key << "k" << YAML::Value << YAML::Flow << YAML::BeginSeq; 1406 out << YAML::BeginMap << YAML::Key << "i" << YAML::Value << 0 << YAML::EndMap 1407 << YAML::Newline; 1408 out << YAML::BeginMap << YAML::Key << "i" << YAML::Value << 1 << YAML::EndMap 1409 << YAML::Newline; 1410 out << YAML::EndSeq; 1411 out << YAML::EndMap; 1412 1413 out << YAML::Key << "NodeB" << YAML::Value << YAML::BeginMap; 1414 out << YAML::Key << "k" << YAML::Value << YAML::Flow << YAML::BeginSeq; 1415 out << YAML::BeginMap << YAML::Key << "i" << YAML::Value << 0 << YAML::EndMap 1416 << YAML::Newline; 1417 out << YAML::BeginMap << YAML::Key << "i" << YAML::Value << 1 << YAML::EndMap 1418 << YAML::Newline; 1419 out << YAML::EndSeq; 1420 out << YAML::EndMap; 1421 1422 out << YAML::EndMap; 1423 1424 ExpectEmit(R"(NodeA: 1425 k: [{i: 0}, 1426 {i: 1}, 1427 ] 1428 NodeB: 1429 k: [{i: 0}, 1430 {i: 1}, 1431 ])"); 1432 } 1433 1434 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLineUsingAliases) { 1435 out << BeginMap; 1436 1437 out << Key << "Node" << Anchor("Node") << Value << BeginMap; 1438 out << Key << "k" << Value << Flow << BeginSeq; 1439 out << BeginMap << Key << "i" << Value << 0 << EndMap; 1440 out << YAML::Newline; 1441 out << BeginMap << Key << "i" << Value << 1 << EndMap; 1442 out << YAML::Newline; 1443 out << EndSeq << EndMap; 1444 1445 out << Key << "NodeA" << Alias("Node"); 1446 out << Key << "NodeB" << Alias("Node"); 1447 1448 out << EndMap; 1449 1450 ExpectEmit(R"(Node: &Node 1451 k: [{i: 0}, 1452 {i: 1}, 1453 ] 1454 NodeA: *Node 1455 NodeB: *Node)"); 1456 } 1457 1458 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapUsingAliases) { 1459 out << BeginMap; 1460 1461 out << Key << "Node" << Anchor("Node") << Value << BeginMap; 1462 out << Key << "k" << Value << Flow << BeginSeq; 1463 out << BeginMap << Key << "i" << Value << 0 << EndMap; 1464 out << BeginMap << Key << "i" << Value << 1 << EndMap; 1465 out << EndSeq << EndMap; 1466 1467 out << Key << "NodeA" << Alias("Node"); 1468 out << Key << "NodeB" << Alias("Node"); 1469 1470 out << EndMap; 1471 1472 ExpectEmit(R"(Node: &Node 1473 k: [{i: 0}, {i: 1}] 1474 NodeA: *Node 1475 NodeB: *Node)"); 1476 } 1477 1478 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLineUsingAliases2) { 1479 out << BeginMap; 1480 1481 out << Key << "Seq" << Anchor("Seq") << Flow << BeginSeq; 1482 out << BeginMap << Key << "i" << Value << 0 << EndMap; 1483 out << YAML::Newline; 1484 out << BeginMap << Key << "i" << Value << 1 << EndMap; 1485 out << YAML::Newline; 1486 out << EndSeq; 1487 1488 out << Key << "NodeA" << Value << BeginMap; 1489 out << Key << "k" << Value << Alias("Seq") << EndMap; 1490 out << Key << "NodeB" << Value << BeginMap; 1491 out << Key << "k" << Value << Alias("Seq") << EndMap; 1492 1493 out << EndMap; 1494 1495 ExpectEmit(R"(Seq: &Seq [{i: 0}, 1496 {i: 1}, 1497 ] 1498 NodeA: 1499 k: *Seq 1500 NodeB: 1501 k: *Seq)"); 1502 } 1503 1504 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapUsingAliases2) { 1505 out << BeginMap; 1506 1507 out << Key << "Seq" << Anchor("Seq") << Value << Flow << BeginSeq; 1508 out << BeginMap << Key << "i" << Value << 0 << EndMap; 1509 out << BeginMap << Key << "i" << Value << 1 << EndMap; 1510 out << EndSeq; 1511 1512 out << Key << "NodeA" << Value << BeginMap; 1513 out << Key << "k" << Value << Alias("Seq") << EndMap; 1514 out << Key << "NodeB" << Value << BeginMap; 1515 out << Key << "k" << Value << Alias("Seq") << EndMap; 1516 1517 out << EndMap; 1518 1519 ExpectEmit(R"(Seq: &Seq [{i: 0}, {i: 1}] 1520 NodeA: 1521 k: *Seq 1522 NodeB: 1523 k: *Seq)"); 1524 } 1525 1526 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLineUsingAliases3) { 1527 out << BeginMap; 1528 1529 out << Key << "Keys" << Value << Flow << BeginSeq; 1530 out << Anchor("k0") << BeginMap << Key << "i" << Value << 0 << EndMap 1531 << Newline; 1532 out << Anchor("k1") << BeginMap << Key << "i" << Value << 1 << EndMap 1533 << Newline; 1534 out << EndSeq; 1535 1536 out << Key << "NodeA" << Value << BeginMap; 1537 out << Key << "k" << Value << Flow << BeginSeq; 1538 out << Alias("k0") << Newline << Alias("k1") << Newline; 1539 out << EndSeq << EndMap; 1540 1541 out << Key << "NodeB" << Value << BeginMap; 1542 out << Key << "k" << Value << Flow << BeginSeq; 1543 out << Alias("k0") << Newline << Alias("k1") << Newline; 1544 out << EndSeq << EndMap; 1545 1546 out << EndMap; 1547 1548 ExpectEmit(R"(Keys: [&k0 {i: 0}, 1549 &k1 {i: 1}, 1550 ] 1551 NodeA: 1552 k: [*k0, 1553 *k1, 1554 ] 1555 NodeB: 1556 k: [*k0, 1557 *k1, 1558 ])"); 1559 } 1560 1561 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapUsingAliases3a) { 1562 out << BeginMap; 1563 1564 out << Key << "Keys" << Value << BeginSeq; 1565 out << Anchor("k0") << BeginMap << Key << "i" << Value << 0 << EndMap; 1566 out << Anchor("k1") << BeginMap << Key << "i" << Value << 1 << EndMap; 1567 out << EndSeq; 1568 1569 out << Key << "NodeA" << Value << BeginMap; 1570 out << Key << "k" << Value << Flow << BeginSeq; 1571 out << Alias("k0") << Alias("k1"); 1572 out << EndSeq << EndMap; 1573 1574 out << Key << "NodeB" << Value << BeginMap; 1575 out << Key << "k" << Value << Flow << BeginSeq; 1576 out << Alias("k0") << Alias("k1"); 1577 out << EndSeq << EndMap; 1578 1579 out << EndMap; 1580 1581 ExpectEmit(R"(Keys: 1582 - &k0 1583 i: 0 1584 - &k1 1585 i: 1 1586 NodeA: 1587 k: [*k0, *k1] 1588 NodeB: 1589 k: [*k0, *k1])"); 1590 } 1591 1592 TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapUsingAliases3b) { 1593 out << BeginMap; 1594 1595 out << Key << "Keys" << Value << Flow << BeginSeq; 1596 out << Anchor("k0") << BeginMap << Key << "i" << Value << 0 << EndMap; 1597 out << Anchor("k1") << BeginMap << Key << "i" << Value << 1 << EndMap; 1598 out << EndSeq; 1599 1600 out << Key << "NodeA" << Value << BeginMap; 1601 out << Key << "k" << Value << Flow << BeginSeq; 1602 out << Alias("k0") << Alias("k1"); 1603 out << EndSeq << EndMap; 1604 1605 out << Key << "NodeB" << Value << BeginMap; 1606 out << Key << "k" << Value << Flow << BeginSeq; 1607 out << Alias("k0") << Alias("k1"); 1608 out << EndSeq << EndMap; 1609 1610 out << EndMap; 1611 1612 ExpectEmit(R"(Keys: [&k0 {i: 0}, &k1 {i: 1}] 1613 NodeA: 1614 k: [*k0, *k1] 1615 NodeB: 1616 k: [*k0, *k1])"); 1617 } 1618 1619 class EmitterErrorTest : public ::testing::Test { 1620 protected: 1621 void ExpectEmitError(const std::string& expectedError) { 1622 ASSERT_FALSE(out.good()) << "Emitter cleanly produced: " << out.c_str(); 1623 EXPECT_EQ(expectedError, out.GetLastError()); 1624 } 1625 1626 Emitter out; 1627 }; 1628 1629 TEST_F(EmitterErrorTest, BadLocalTag) { 1630 out << LocalTag("e!far") << "bar"; 1631 1632 ExpectEmitError("invalid tag"); 1633 } 1634 1635 TEST_F(EmitterErrorTest, BadTagAndTag) { 1636 out << VerbatimTag("!far") << VerbatimTag("!foo") << "bar"; 1637 ExpectEmitError(ErrorMsg::INVALID_TAG); 1638 } 1639 1640 TEST_F(EmitterErrorTest, BadAnchorAndAnchor) { 1641 out << Anchor("far") << Anchor("foo") << "bar"; 1642 ExpectEmitError(ErrorMsg::INVALID_ANCHOR); 1643 } 1644 1645 TEST_F(EmitterErrorTest, BadEmptyAnchorOnGroup) { 1646 out << BeginSeq << "bar" << Anchor("foo") << EndSeq; 1647 ExpectEmitError(ErrorMsg::INVALID_ANCHOR); 1648 } 1649 1650 TEST_F(EmitterErrorTest, BadEmptyTagOnGroup) { 1651 out << BeginSeq << "bar" << VerbatimTag("!foo") << EndSeq; 1652 ExpectEmitError(ErrorMsg::INVALID_TAG); 1653 } 1654 1655 TEST_F(EmitterErrorTest, ExtraEndSeq) { 1656 out << BeginSeq; 1657 out << "Hello"; 1658 out << "World"; 1659 out << EndSeq; 1660 out << EndSeq; 1661 1662 ExpectEmitError(ErrorMsg::UNEXPECTED_END_SEQ); 1663 } 1664 1665 TEST_F(EmitterErrorTest, ExtraEndMap) { 1666 out << BeginMap; 1667 out << Key << "Hello" << Value << "World"; 1668 out << EndMap; 1669 out << EndMap; 1670 1671 ExpectEmitError(ErrorMsg::UNEXPECTED_END_MAP); 1672 } 1673 1674 TEST_F(EmitterErrorTest, InvalidAnchor) { 1675 out << BeginSeq; 1676 out << Anchor("new\nline") << "Test"; 1677 out << EndSeq; 1678 1679 ExpectEmitError(ErrorMsg::INVALID_ANCHOR); 1680 } 1681 1682 TEST_F(EmitterErrorTest, InvalidAlias) { 1683 out << BeginSeq; 1684 out << Alias("new\nline"); 1685 out << EndSeq; 1686 1687 ExpectEmitError(ErrorMsg::INVALID_ALIAS); 1688 } 1689 } // namespace 1690 } // namespace YAML