1#!perl -w 2 3use strict; 4use warnings; 5use lib 't/lib'; 6 7use Test::More; 8 9use TAP::Parser::YAMLish::Reader; 10 11my @SCHEDULE; 12 13BEGIN { 14 @SCHEDULE = ( 15 { name => 'Hello World', 16 in => [ 17 '--- Hello, World', 18 '...', 19 ], 20 out => "Hello, World", 21 }, 22 { name => 'Hello World 2', 23 in => [ 24 '--- \'Hello, \'\'World\'', 25 '...', 26 ], 27 out => "Hello, 'World", 28 }, 29 { name => 'Hello World 3', 30 in => [ 31 '--- "Hello, World"', 32 '...', 33 ], 34 out => "Hello, World", 35 }, 36 { name => 'Hello World 4', 37 in => [ 38 '--- "Hello, World"', 39 '...', 40 ], 41 out => "Hello, World", 42 }, 43 { name => 'Hello World 4', 44 in => [ 45 '--- >', 46 ' Hello,', 47 ' World', 48 '...', 49 ], 50 out => "Hello, World\n", 51 }, 52 { name => 'Hello World Block', 53 in => [ 54 '--- |', 55 ' Hello,', 56 ' World', 57 '...', 58 ], 59 out => "Hello,\n World\n", 60 }, 61 { name => 'Hello World 5', 62 in => [ 63 '--- >', 64 ' Hello,', 65 ' World', 66 '...', 67 ], 68 error => qr{Missing\s+'[.][.][.]'}, 69 }, 70 { name => 'Simple array', 71 in => [ 72 '---', 73 '- 1', 74 '- 2', 75 '- 3', 76 '...', 77 ], 78 out => [ '1', '2', '3' ], 79 }, 80 { name => 'Mixed array', 81 in => [ 82 '---', 83 '- 1', 84 '- \'two\'', 85 '- "three\n"', 86 '...', 87 ], 88 out => [ '1', 'two', "three\n" ], 89 }, 90 { name => 'Hash in array', 91 in => [ 92 '---', 93 '- 1', 94 '- two: 2', 95 '- 3', 96 '...', 97 ], 98 out => [ '1', { two => '2' }, '3' ], 99 }, 100 { name => 'Hash in array 2', 101 in => [ 102 '---', 103 '- 1', 104 '- two: 2', 105 ' three: 3', 106 '- 4', 107 '...', 108 ], 109 out => [ '1', { two => '2', three => '3' }, '4' ], 110 }, 111 { name => 'Nested array', 112 in => [ 113 '---', 114 '- one', 115 '-', 116 ' - two', 117 ' -', 118 ' - three', 119 ' - four', 120 '- five', 121 '...', 122 ], 123 out => [ 'one', [ 'two', ['three'], 'four' ], 'five' ], 124 }, 125 { name => 'Nested hash', 126 in => [ 127 '---', 128 'one:', 129 ' five: 5', 130 ' two:', 131 ' four: 4', 132 ' three: 3', 133 'six: 6', 134 '...', 135 ], 136 out => { 137 one => { two => { three => '3', four => '4' }, five => '5' }, 138 six => '6' 139 }, 140 }, 141 { name => 'Space after colon', 142 in => [ '---', 'spog: ', ' - 1', ' - 2', '...' ], 143 out => { spog => [ 1, 2 ] }, 144 }, 145 { name => 'Original YAML::Tiny test', 146 in => [ 147 '---', 148 'invoice: 34843', 149 'date : 2001-01-23', 150 'bill-to:', 151 ' given : Chris', 152 ' family : Dumars', 153 ' address:', 154 ' lines: |', 155 ' 458 Walkman Dr.', 156 ' Suite #292', 157 ' city : Royal Oak', 158 ' state : MI', 159 ' postal : 48046', 160 'product:', 161 ' - sku : BL394D', 162 ' quantity : 4', 163 ' description : Basketball', 164 ' price : 450.00', 165 ' - sku : BL4438H', 166 ' quantity : 1', 167 ' description : Super Hoop', 168 ' price : 2392.00', 169 'tax : 251.42', 170 'total: 4443.52', 171 'comments: >', 172 ' Late afternoon is best.', 173 ' Backup contact is Nancy', 174 ' Billsmer @ 338-4338', 175 '...', 176 ], 177 out => { 178 'bill-to' => { 179 'given' => 'Chris', 180 'address' => { 181 'city' => 'Royal Oak', 182 'postal' => '48046', 183 'lines' => "458 Walkman Dr.\nSuite #292\n", 184 'state' => 'MI' 185 }, 186 'family' => 'Dumars' 187 }, 188 'invoice' => '34843', 189 'date' => '2001-01-23', 190 'tax' => '251.42', 191 'product' => [ 192 { 'sku' => 'BL394D', 193 'quantity' => '4', 194 'price' => '450.00', 195 'description' => 'Basketball' 196 }, 197 { 'sku' => 'BL4438H', 198 'quantity' => '1', 199 'price' => '2392.00', 200 'description' => 'Super Hoop' 201 } 202 ], 203 'comments' => 204 "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338\n", 205 'total' => '4443.52' 206 } 207 }, 208 209 # Tests harvested from YAML::Tiny 210 { in => ['...'], 211 name => 'Regression: empty', 212 error => qr{document\s+header\s+not\s+found} 213 }, 214 { in => [ 215 '# comment', 216 '...' 217 ], 218 name => 'Regression: only_comment', 219 error => qr{document\s+header\s+not\s+found} 220 }, 221 { out => undef, 222 in => [ 223 '---', 224 '...' 225 ], 226 name => 'Regression: only_header', 227 error => qr{Premature\s+end}i, 228 }, 229 { out => undef, 230 in => [ 231 '---', 232 '---', 233 '...' 234 ], 235 name => 'Regression: two_header', 236 error => qr{Unexpected\s+start}i, 237 }, 238 { out => undef, 239 in => [ 240 '--- ~', 241 '...' 242 ], 243 name => 'Regression: one_undef' 244 }, 245 { out => undef, 246 in => [ 247 '--- ~', 248 '...' 249 ], 250 name => 'Regression: one_undef2' 251 }, 252 { in => [ 253 '--- ~', 254 '---', 255 '...' 256 ], 257 name => 'Regression: two_undef', 258 error => qr{Missing\s+'[.][.][.]'}, 259 }, 260 { out => 'foo', 261 in => [ 262 '--- foo', 263 '...' 264 ], 265 name => 'Regression: one_scalar', 266 }, 267 { out => 'foo', 268 in => [ 269 '--- foo', 270 '...' 271 ], 272 name => 'Regression: one_scalar2', 273 }, 274 { in => [ 275 '--- foo', 276 '--- bar', 277 '...' 278 ], 279 name => 'Regression: two_scalar', 280 error => qr{Missing\s+'[.][.][.]'}, 281 }, 282 { out => ['foo'], 283 in => [ 284 '---', 285 '- foo', 286 '...' 287 ], 288 name => 'Regression: one_list1' 289 }, 290 { out => [ 291 'foo', 292 'bar' 293 ], 294 in => [ 295 '---', 296 '- foo', 297 '- bar', 298 '...' 299 ], 300 name => 'Regression: one_list2' 301 }, 302 { out => [ 303 undef, 304 'bar' 305 ], 306 in => [ 307 '---', 308 '- ~', 309 '- bar', 310 '...' 311 ], 312 name => 'Regression: one_listundef' 313 }, 314 { out => { 'foo' => 'bar' }, 315 in => [ 316 '---', 317 'foo: bar', 318 '...' 319 ], 320 name => 'Regression: one_hash1' 321 }, 322 { out => { 323 'foo' => 'bar', 324 'this' => undef 325 }, 326 in => [ 327 '---', 328 'foo: bar', 329 'this: ~', 330 '...' 331 ], 332 name => 'Regression: one_hash2' 333 }, 334 { out => { 335 'foo' => [ 336 'bar', 337 undef, 338 'baz' 339 ] 340 }, 341 in => [ 342 '---', 343 'foo:', 344 ' - bar', 345 ' - ~', 346 ' - baz', 347 '...' 348 ], 349 name => 'Regression: array_in_hash' 350 }, 351 { out => { 352 'bar' => { 'foo' => 'bar' }, 353 'foo' => undef 354 }, 355 in => [ 356 '---', 357 'foo: ~', 358 'bar:', 359 ' foo: bar', 360 '...' 361 ], 362 name => 'Regression: hash_in_hash' 363 }, 364 { out => [ 365 { 'foo' => undef, 366 'this' => 'that' 367 }, 368 'foo', undef, 369 { 'foo' => 'bar', 370 'this' => 'that' 371 } 372 ], 373 in => [ 374 '---', 375 '-', 376 ' foo: ~', 377 ' this: that', 378 '- foo', 379 '- ~', 380 '-', 381 ' foo: bar', 382 ' this: that', 383 '...' 384 ], 385 name => 'Regression: hash_in_array' 386 }, 387 { out => ['foo'], 388 in => [ 389 '---', 390 '- \'foo\'', 391 '...' 392 ], 393 name => 'Regression: single_quote1' 394 }, 395 { out => [' '], 396 in => [ 397 '---', 398 '- \' \'', 399 '...' 400 ], 401 name => 'Regression: single_spaces' 402 }, 403 { out => [''], 404 in => [ 405 '---', 406 '- \'\'', 407 '...' 408 ], 409 name => 'Regression: single_null' 410 }, 411 { out => ' ', 412 in => [ 413 '--- " "', 414 '...' 415 ], 416 name => 'Regression: only_spaces' 417 }, 418 { out => ['first','second'], 419 in => [ 420 '--- ', 421 '- first ', 422 '- second ', 423 '...' 424 ], 425 name => "Space after header for array", 426 }, 427 { out => {'key' => [{'value' => {'key2' => 'value2'}}]}, 428 in => [ 429 '--- ', 430 'key: ', 431 '- value: ', 432 ' key2: value2 ', 433 '... ' 434 ], 435 name => "Space after header for hash", 436 }, 437 { out => [ 438 undef, 439 { 'foo' => 'bar', 440 'this' => 'that' 441 }, 442 'baz' 443 ], 444 in => [ 445 '---', 446 '- ~', 447 '- foo: bar', 448 ' this: that', 449 '- baz', 450 '...' 451 ], 452 name => 'Regression: inline_nested_hash' 453 }, 454 { name => "Unprintables", 455 in => [ 456 "---", 457 "- \"\\z\\x01\\x02\\x03\\x04\\x05\\x06\\a\\x08\\t\\n\\v\\f\\r\\x0e\\x0f\"", 458 "- \"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\e\\x1c\\x1d\\x1e\\x1f\"", 459 "- \" !\\\"#\$%&'()*+,-./\"", 460 "- 0123456789:;<=>?", 461 "- '\@ABCDEFGHIJKLMNO'", 462 "- 'PQRSTUVWXYZ[\\]^_'", 463 "- '`abcdefghijklmno'", 464 "- 'pqrstuvwxyz{|}~\177'", 465 "- \200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217", 466 "- \220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237", 467 "- \240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257", 468 "- \260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277", 469 "- \300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317", 470 "- \320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337", 471 "- \340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357", 472 "- \360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377", 473 "..." 474 ], 475 out => [ 476 "\0\1\2\3\4\5\6\a\b\t\n\13\f\r\16\17", 477 "\20\21\22\23\24\25\26\27\30\31\32\e\34\35\36\37", 478 " !\"#\$%&'()*+,-./", 479 "0123456789:;<=>?", 480 "\@ABCDEFGHIJKLMNO", 481 "PQRSTUVWXYZ[\\]^_", 482 "`abcdefghijklmno", 483 "pqrstuvwxyz{|}~\177", 484 "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217", 485 "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237", 486 "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257", 487 "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277", 488 "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317", 489 "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337", 490 "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357", 491 "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377" 492 ], 493 }, 494 { name => 'Quoted hash keys', 495 in => [ 496 '---', 497 ' "quoted": Magic!', 498 ' "\n\t": newline, tab', 499 '...', 500 ], 501 out => { 502 quoted => 'Magic!', 503 "\n\t" => 'newline, tab', 504 }, 505 }, 506 { name => 'Empty', 507 in => [], 508 out => undef, 509 }, 510 ); 511 512 plan tests => @SCHEDULE * 5; 513} 514 515sub iter { 516 my $ar = shift; 517 return sub { 518 return shift @$ar; 519 }; 520} 521 522for my $test (@SCHEDULE) { 523 my $name = $test->{name}; 524 ok my $yaml = TAP::Parser::YAMLish::Reader->new, "$name: Created"; 525 isa_ok $yaml, 'TAP::Parser::YAMLish::Reader'; 526 527 my $source = join( "\n", @{ $test->{in} } ) . "\n"; 528 529 my $iter = iter( $test->{in} ); 530 my $got = eval { $yaml->read($iter) }; 531 532 my $raw = $yaml->get_raw; 533 534 if ( my $err = $test->{error} ) { 535 unless ( like $@, $err, "$name: Error message" ) { 536 diag "Error: $@\n"; 537 } 538 ok !$got, "$name: No result"; 539 pass; 540 } 541 else { 542 my $want = $test->{out}; 543 unless ( ok !$@, "$name: No error" ) { 544 diag "Error: $@\n"; 545 } 546 is_deeply $got, $want, "$name: Result matches"; 547 is $raw, $source, "$name: Captured source matches"; 548 } 549} 550