1use strict; 2use warnings; 3use Test2::Tools::Tiny; 4 5use Test2::Event(); 6use Test2::EventFacet::Trace(); 7use Test2::Event::Generic; 8 9use Test2::API qw/context/; 10use Scalar::Util qw/reftype/; 11 12tests old_api => sub { 13 { 14 package My::MockEvent; 15 16 use base 'Test2::Event'; 17 use Test2::Util::HashBase qw/foo bar baz/; 18 } 19 20 ok(My::MockEvent->can($_), "Added $_ accessor") for qw/foo bar baz/; 21 22 my $one = My::MockEvent->new(trace => 'fake'); 23 24 ok(!$one->causes_fail, "Events do not cause failures by default"); 25 26 ok(!$one->$_, "$_ is false by default") for qw/increments_count terminate global/; 27 28 ok(!$one->get_meta('xxx'), "no meta-data associated for key 'xxx'"); 29 30 $one->set_meta('xxx', '123'); 31 32 is($one->meta('xxx'), '123', "got meta-data"); 33 34 is($one->meta('xxx', '321'), '123', "did not use default"); 35 36 is($one->meta('yyy', '1221'), '1221', "got the default"); 37 38 is($one->meta('yyy'), '1221', "last call set the value to the default for future use"); 39 40 is($one->summary, 'My::MockEvent', "Default summary is event package"); 41 42 is($one->diagnostics, 0, "Not diagnostics by default"); 43}; 44 45tests deprecated => sub { 46 my $e = Test2::Event->new(trace => Test2::EventFacet::Trace->new(frame => ['foo', 'foo.pl', 42], nested => 2, hid => 'maybe')); 47 48 my $warnings = warnings { 49 local $ENV{AUTHOR_TESTING} = 1; 50 is($e->nested, 2, "Got nested from the trace"); 51 is($e->in_subtest, 'maybe', "got hid from trace"); 52 53 $e->trace->{nested} = 0; 54 55 local $ENV{AUTHOR_TESTING} = 0; 56 is($e->nested, 0, "Not nested"); 57 is($e->in_subtest, undef, "Did not get hid"); 58 }; 59 60 is(@$warnings, 2, "got warnings once each"); 61 like($warnings->[0], qr/Use of Test2::Event->nested\(\) is deprecated/, "Warned about deprecation"); 62 like($warnings->[1], qr/Use of Test2::Event->in_subtest\(\) is deprecated/, "Warned about deprecation"); 63}; 64 65tests facet_data => sub { 66 my $e = Test2::Event::Generic->new( 67 causes_fail => 0, 68 increments_count => 0, 69 diagnostics => 0, 70 no_display => 0, 71 callback => undef, 72 terminate => undef, 73 global => undef, 74 sets_plan => undef, 75 summary => undef, 76 facet_data => undef, 77 ); 78 79 is_deeply( 80 $e->facet_data, 81 { 82 about => { 83 package => 'Test2::Event::Generic', 84 details => 'Test2::Event::Generic', 85 eid => $e->eid, 86 no_display => undef, 87 }, 88 control => { 89 has_callback => 0, 90 terminate => undef, 91 global => 0 92 }, 93 }, 94 "Facet data has control with only false values, and an about" 95 ); 96 97 $e->set_trace(Test2::EventFacet::Trace->new(frame => ['foo', 'foo.t', 42])); 98 is_deeply( 99 $e->facet_data, 100 { 101 about => { 102 package => 'Test2::Event::Generic', 103 details => 'Test2::Event::Generic', 104 eid => $e->eid, 105 no_display => undef, 106 }, 107 control => { 108 has_callback => 0, 109 terminate => undef, 110 global => 0 111 }, 112 trace => { 113 frame => ['foo', 'foo.t', 42], 114 pid => $$, 115 tid => 0, 116 }, 117 }, 118 "Got a trace now" 119 ); 120 121 $e->set_causes_fail(1); 122 is_deeply( 123 $e->facet_data, 124 { 125 about => { 126 package => 'Test2::Event::Generic', 127 details => 'Test2::Event::Generic', 128 eid => $e->eid, 129 no_display => undef 130 }, 131 control => { 132 has_callback => 0, 133 terminate => undef, 134 global => 0 135 }, 136 trace => { 137 frame => ['foo', 'foo.t', 42], 138 pid => $$, 139 tid => 0, 140 }, 141 errors => [ 142 { 143 tag => 'FAIL', 144 details => 'Test2::Event::Generic', 145 fail => 1, 146 } 147 ], 148 }, 149 "Got an error" 150 ); 151 152 $e->set_increments_count(1); 153 is_deeply( 154 $e->facet_data, 155 { 156 about => { 157 package => 'Test2::Event::Generic', 158 details => 'Test2::Event::Generic', 159 eid => $e->eid, 160 no_display => undef 161 }, 162 control => { 163 has_callback => 0, 164 terminate => undef, 165 global => 0 166 }, 167 trace => { 168 frame => ['foo', 'foo.t', 42], 169 pid => $$, 170 tid => 0, 171 }, 172 assert => { 173 no_debug => 1, 174 pass => 0, 175 details => 'Test2::Event::Generic', 176 }, 177 }, 178 "Got an assert now" 179 ); 180 181 $e->set_causes_fail(0); 182 is_deeply( 183 $e->facet_data, 184 { 185 about => { 186 package => 'Test2::Event::Generic', 187 details => 'Test2::Event::Generic', 188 eid => $e->eid, 189 no_display => undef 190 }, 191 control => { 192 has_callback => 0, 193 terminate => undef, 194 global => 0 195 }, 196 trace => { 197 frame => ['foo', 'foo.t', 42], 198 pid => $$, 199 tid => 0, 200 }, 201 assert => { 202 no_debug => 1, 203 pass => 1, 204 details => 'Test2::Event::Generic', 205 }, 206 }, 207 "Got a passing assert now" 208 ); 209 210 $e->set_global(1); 211 $e->set_terminate(255); 212 $e->set_callback(sub {1}); 213 is_deeply( 214 $e->facet_data, 215 { 216 about => { 217 package => 'Test2::Event::Generic', 218 details => 'Test2::Event::Generic', 219 eid => $e->eid, 220 no_display => undef 221 }, 222 control => { 223 has_callback => 1, 224 terminate => 255, 225 global => 1, 226 }, 227 trace => { 228 frame => ['foo', 'foo.t', 42], 229 pid => $$, 230 tid => 0, 231 }, 232 assert => { 233 no_debug => 1, 234 pass => 1, 235 details => 'Test2::Event::Generic', 236 }, 237 }, 238 "control fields were altered" 239 ); 240 241 my $data; 242 { 243 no warnings 'once'; 244 local *Test2::Event::Generic::subtest_id = sub { 123 }; 245 $data = $e->facet_data; 246 } 247 is_deeply( 248 $data, 249 { 250 about => { 251 package => 'Test2::Event::Generic', 252 details => 'Test2::Event::Generic', 253 eid => $e->eid, 254 no_display => undef 255 }, 256 control => { 257 has_callback => 1, 258 terminate => 255, 259 global => 1, 260 }, 261 trace => { 262 frame => ['foo', 'foo.t', 42], 263 pid => $$, 264 tid => 0, 265 }, 266 assert => { 267 no_debug => 1, 268 pass => 1, 269 details => 'Test2::Event::Generic', 270 }, 271 parent => {hid => 123}, 272 }, 273 "Added parent" 274 ); 275 276 $e->set_meta('foo', {a => 1}); 277 is_deeply( 278 $e->facet_data, 279 { 280 about => { 281 package => 'Test2::Event::Generic', 282 details => 'Test2::Event::Generic', 283 eid => $e->eid, 284 no_display => undef 285 }, 286 control => { 287 has_callback => 1, 288 terminate => 255, 289 global => 1, 290 }, 291 trace => { 292 frame => ['foo', 'foo.t', 42], 293 pid => $$, 294 tid => 0, 295 }, 296 assert => { 297 no_debug => 1, 298 pass => 1, 299 details => 'Test2::Event::Generic', 300 }, 301 meta => {foo => {a => 1}}, 302 }, 303 "Grabbed meta" 304 ); 305 306 307 $e->set_sets_plan([5]); 308 is_deeply( 309 $e->facet_data, 310 { 311 about => { 312 package => 'Test2::Event::Generic', 313 details => 'Test2::Event::Generic', 314 eid => $e->eid, 315 no_display => undef 316 }, 317 control => { 318 has_callback => 1, 319 terminate => 255, 320 global => 1, 321 }, 322 trace => { 323 frame => ['foo', 'foo.t', 42], 324 pid => $$, 325 tid => 0, 326 }, 327 assert => { 328 no_debug => 1, 329 pass => 1, 330 details => 'Test2::Event::Generic', 331 }, 332 meta => {foo => {a => 1}}, 333 plan => { count => 5 }, 334 }, 335 "Plan facet added" 336 ); 337 338 $e->set_terminate(undef); 339 $e->set_sets_plan([0, SKIP => 'because']); 340 is_deeply( 341 $e->facet_data, 342 { 343 about => { 344 package => 'Test2::Event::Generic', 345 details => 'Test2::Event::Generic', 346 eid => $e->eid, 347 no_display => undef 348 }, 349 control => { 350 has_callback => 1, 351 terminate => 0, 352 global => 1, 353 }, 354 trace => { 355 frame => ['foo', 'foo.t', 42], 356 pid => $$, 357 tid => 0, 358 }, 359 assert => { 360 no_debug => 1, 361 pass => 1, 362 details => 'Test2::Event::Generic', 363 }, 364 meta => {foo => {a => 1}}, 365 plan => { count => 0, skip => 1, details => 'because' }, 366 }, 367 "Plan set terminate, skip, and details" 368 ); 369 370 $e->set_sets_plan([0, 'NO PLAN' => 'because']); 371 is_deeply( 372 $e->facet_data, 373 { 374 about => { 375 package => 'Test2::Event::Generic', 376 details => 'Test2::Event::Generic', 377 eid => $e->eid, 378 no_display => undef 379 }, 380 control => { 381 has_callback => 1, 382 terminate => undef, 383 global => 1, 384 }, 385 trace => { 386 frame => ['foo', 'foo.t', 42], 387 pid => $$, 388 tid => 0, 389 }, 390 assert => { 391 no_debug => 1, 392 pass => 1, 393 details => 'Test2::Event::Generic', 394 }, 395 meta => {foo => {a => 1}}, 396 plan => { count => 0, none => 1, details => 'because' }, 397 }, 398 "Plan does not set terminate, but sets 'none' and 'details'" 399 ); 400 401 $e->add_amnesty({tag => 'foo', details => 'bar'}); 402 $e->add_amnesty({tag => 'baz', details => 'bat'}); 403 is_deeply( 404 $e->facet_data, 405 { 406 about => { 407 package => 'Test2::Event::Generic', 408 details => 'Test2::Event::Generic', 409 eid => $e->eid, 410 no_display => undef 411 }, 412 control => { 413 has_callback => 1, 414 terminate => undef, 415 global => 1, 416 }, 417 trace => { 418 frame => ['foo', 'foo.t', 42], 419 pid => $$, 420 tid => 0, 421 }, 422 assert => { 423 no_debug => 1, 424 pass => 1, 425 details => 'Test2::Event::Generic', 426 }, 427 meta => {foo => {a => 1}}, 428 plan => { count => 0, none => 1, details => 'because' }, 429 amnesty => [ 430 { tag => 'foo', details => 'bar' }, 431 { tag => 'baz', details => 'bat' }, 432 ], 433 }, 434 "Amnesty added" 435 ); 436 437 $e = Test2::Event::Generic->new(); 438 $e->set_diagnostics(1); 439 $e->set_no_display(1); 440 is_deeply( 441 $e->facet_data, 442 { 443 about => { 444 package => 'Test2::Event::Generic', 445 details => 'Test2::Event::Generic', 446 eid => $e->eid, 447 no_display => 1, 448 }, 449 control => { 450 has_callback => 0, 451 terminate => undef, 452 global => 0, 453 }, 454 }, 455 "No Info" 456 ); 457 458 $e->set_no_display(0); 459 is_deeply( 460 $e->facet_data, 461 { 462 about => { 463 package => 'Test2::Event::Generic', 464 details => 'Test2::Event::Generic', 465 eid => $e->eid, 466 no_display => undef, 467 }, 468 control => { 469 has_callback => 0, 470 terminate => undef, 471 global => 0, 472 }, 473 info => [{ 474 details => 'Test2::Event::Generic', 475 tag => 'DIAG', 476 debug => 1, 477 }], 478 }, 479 "Got debug Info" 480 ); 481 482 $e->set_summary("foo bar baz"); 483 is_deeply( 484 $e->facet_data, 485 { 486 about => { 487 package => 'Test2::Event::Generic', 488 details => 'foo bar baz', 489 eid => $e->eid, 490 no_display => undef, 491 }, 492 control => { 493 has_callback => 0, 494 terminate => undef, 495 global => 0, 496 }, 497 info => [{ 498 details => 'foo bar baz', 499 tag => 'DIAG', 500 debug => 1, 501 }], 502 }, 503 "Got debug Info with summary change" 504 ); 505}; 506 507tests facets => sub { 508 my $data = { 509 about => { 510 package => 'Test2::Event::Generic', 511 details => 'Test2::Event::Generic', 512 no_display => undef 513 }, 514 control => { 515 has_callback => 1, 516 terminate => undef, 517 global => 1, 518 }, 519 trace => { 520 frame => ['foo', 'foo.t', 42], 521 pid => $$, 522 tid => 0, 523 }, 524 assert => { 525 no_debug => 1, 526 pass => 1, 527 details => 'Test2::Event::Generic', 528 }, 529 meta => {foo => {a => 1}}, 530 plan => {count => 0, none => 1, details => 'because'}, 531 parent => {hid => 123, children => []}, 532 amnesty => [ 533 {tag => 'foo', details => 'bar'}, 534 {tag => 'baz', details => 'bat'}, 535 ], 536 info => [ 537 { 538 details => 'foo bar baz', 539 tag => 'DIAG', 540 debug => 1, 541 } 542 ], 543 errors => [{ 544 tag => 'FAIL', 545 details => 'Test2::Event::Generic', 546 fail => 1, 547 }], 548 }; 549 550 my $e = Test2::Event::Generic->new(facet_data => $data); 551 is_deeply( 552 $e->facet_data, 553 $e->facets, 554 "Facets and facet_data have the same structure" 555 ); 556 557 my $facets = $e->facets; 558 559 for my $key (sort keys %$facets) { 560 my $type = "Test2::EventFacet::" . ucfirst($key); 561 $type =~ s/s$//; 562 my $val = $facets->{$key}; 563 if ($type->is_list) { 564 for my $f (@$val) { 565 ok($f->isa('Test2::EventFacet'), "'$key' has a blessed facet"); 566 ok($f->isa("$type"), "'$key' is a '$type'") or diag("$f"); 567 } 568 } 569 else { 570 ok($val->isa('Test2::EventFacet'), "'$key' has a blessed facet"); 571 ok($val->isa($type), "'$key' is a '$type'"); 572 } 573 } 574}; 575 576tests common_facet_data => sub { 577 my $e = Test2::Event::Generic->new( 578 causes_fail => 0, 579 increments_count => 0, 580 diagnostics => 0, 581 no_display => 0, 582 callback => undef, 583 terminate => undef, 584 global => undef, 585 sets_plan => undef, 586 summary => undef, 587 facet_data => undef, 588 ); 589 590 is_deeply( 591 $e->common_facet_data, 592 { 593 about => { 594 package => 'Test2::Event::Generic', 595 eid => $e->eid, 596 }, 597 }, 598 "Facet data has an about" 599 ); 600 601 $e->set_trace(Test2::EventFacet::Trace->new(frame => ['foo', 'foo.t', 42])); 602 is_deeply( 603 $e->common_facet_data, 604 { 605 about => { 606 package => 'Test2::Event::Generic', 607 eid => $e->eid, 608 }, 609 trace => { 610 frame => ['foo', 'foo.t', 42], 611 pid => $$, 612 tid => 0, 613 }, 614 }, 615 "Got a trace now" 616 ); 617 618 $e->set_meta('foo', {a => 1}); 619 is_deeply( 620 $e->common_facet_data, 621 { 622 about => { 623 package => 'Test2::Event::Generic', 624 eid => $e->eid, 625 }, 626 trace => { 627 frame => ['foo', 'foo.t', 42], 628 pid => $$, 629 tid => 0, 630 }, 631 meta => {foo => {a => 1}}, 632 }, 633 "Grabbed meta" 634 ); 635 636 $e->add_amnesty({tag => 'foo', details => 'bar'}); 637 $e->add_amnesty({tag => 'baz', details => 'bat'}); 638 is_deeply( 639 $e->common_facet_data, 640 { 641 about => { 642 package => 'Test2::Event::Generic', 643 eid => $e->eid, 644 }, 645 trace => { 646 frame => ['foo', 'foo.t', 42], 647 pid => $$, 648 tid => 0, 649 }, 650 meta => {foo => {a => 1}}, 651 amnesty => [ 652 {tag => 'foo', details => 'bar'}, 653 {tag => 'baz', details => 'bat'}, 654 ], 655 }, 656 "Amnesty added" 657 ); 658}; 659 660tests related => sub { 661 my $ctx = context(); 662 my $ev_a = $ctx->build_ev2(about => {}); 663 my $ev_b = $ctx->build_ev2(about => {}); 664 $ctx->release; 665 666 $ctx = context(); 667 my $ev_c = $ctx->build_ev2(about => {}); 668 $ctx->release; 669 670 delete $ev_a->{trace}->{uuid}; 671 delete $ev_b->{trace}->{uuid}; 672 delete $ev_c->{trace}->{uuid}; 673 674 ok($ev_a->related($ev_b), "Related as they were created with the same context (no uuid)"); 675 ok(!$ev_a->related($ev_c), "Not related as they were created with a different context (no uuid)"); 676 677 $ev_a->{trace}->{uuid} = 'xxx'; # Yes I know it is not valid. 678 $ev_b->{trace}->{uuid} = 'yyy'; # Yes I know it is not valid. 679 $ev_c->{trace}->{uuid} = 'xxx'; # Yes I know it is not valid. 680 681 ok(!$ev_a->related($ev_b), "Not related, traces have different UUID's"); 682 ok($ev_a->related($ev_c), "Related, traces have the same UUID's"); 683}; 684 685tests verify_facet_data => sub { 686 my $ev1 = Test2::Event::V2->new( 687 assert => { pass => 1 }, 688 info => [{tag => 'NOTE', details => 'oops' }], 689 'a custom one' => {}, 690 ); 691 692 is_deeply( 693 [$ev1->validate_facet_data], 694 [], 695 "No errors" 696 ); 697 698 my $ev2 = Test2::Event::V2->new( 699 assert => [{ pass => 1 }], 700 info => {tag => 'NOTE', details => 'oops' }, 701 'a custom one' => {}, 702 ); 703 704 my @errors = $ev2->validate_facet_data; 705 is(@errors, 2, "Got 2 errors"); 706 like($errors[0], qr/^Facet 'assert' should not be a list, but got a a list/, "Got a list for a non-list type"); 707 like($errors[1], qr/^Facet 'info' should be a list, but got a single item/, "Got a single item when a list is needed"); 708 709 @errors = $ev2->validate_facet_data(require_facet_class => 1); 710 is(@errors, 3, "Got 3 errors"); 711 is($errors[0], "Could not find a facet class for facet 'a custom one'", "Classes required"); 712 like($errors[1], qr/^Facet 'assert' should not be a list, but got a a list/, "Got a list for a non-list type"); 713 like($errors[2], qr/^Facet 'info' should be a list, but got a single item/, "Got a single item when a list is needed"); 714 715 is_deeply( 716 [Test2::Event->validate_facet_data($ev1->facet_data)], 717 [], 718 "No errors" 719 ); 720 721 @errors = Test2::Event->validate_facet_data($ev2->facet_data); 722 is(@errors, 2, "Got 2 errors"); 723 like($errors[0], qr/^Facet 'assert' should not be a list, but got a a list/, "Got a list for a non-list type"); 724 like($errors[1], qr/^Facet 'info' should be a list, but got a single item/, "Got a single item when a list is needed"); 725 726 @errors = Test2::Event->validate_facet_data($ev2->facet_data, require_facet_class => 1); 727 is(@errors, 3, "Got 3 errors"); 728 is($errors[0], "Could not find a facet class for facet 'a custom one'", "Classes required"); 729 like($errors[1], qr/^Facet 'assert' should not be a list, but got a a list/, "Got a list for a non-list type"); 730 like($errors[2], qr/^Facet 'info' should be a list, but got a single item/, "Got a single item when a list is needed"); 731}; 732 733done_testing; 734