File Coverage

blib/lib/Test2/Tools/Compare.pm
Criterion Covered Total %
statement 314 319 98.4
branch 109 128 85.1
condition 13 14 92.8
subroutine 92 93 98.9
pod 53 53 100.0
total 581 607 95.7


line stmt bran cond sub pod time code
1             package Test2::Tools::Compare;
2 164     164   7897 use strict;
  164         425  
  164         4929  
3 164     164   881 use warnings;
  164         3805  
  164         7716  
4              
5             our $VERSION = '0.000156';
6              
7 164     164   1131 use Carp qw/croak/;
  164         333  
  164         8474  
8 164     164   1245 use Scalar::Util qw/reftype/;
  164         462  
  164         8996  
9              
10 164     164   1871 use Test2::API qw/context/;
  164         79463  
  164         8373  
11 164     164   69549 use Test2::Util::Ref qw/rtype/;
  164         421  
  164         9511  
12 164     164   1042 use Test2::Util qw/pkg_to_file/;
  164         367  
  164         7032  
13              
14 164         12664 use Test2::Compare qw{
15             compare
16             get_build push_build pop_build build
17             strict_convert relaxed_convert
18 164     164   73976 };
  164         506  
19              
20 164     164   73886 use Test2::Compare::Array();
  164         609  
  164         4589  
21 164     164   77457 use Test2::Compare::Bag();
  164         396  
  164         3654  
22 164     164   67912 use Test2::Compare::Bool();
  164         449  
  164         3490  
23 164     164   67800 use Test2::Compare::Custom();
  164         435  
  164         3599  
24 164     164   67649 use Test2::Compare::Event();
  164         429  
  164         3617  
25 164     164   71516 use Test2::Compare::Float();
  164         451  
  164         3543  
26 164     164   69679 use Test2::Compare::Hash();
  164         469  
  164         4084  
27 164     164   1089 use Test2::Compare::Isa();
  164         350  
  164         2676  
28 164     164   827 use Test2::Compare::Meta();
  164         337  
  164         2139  
29 164     164   72046 use Test2::Compare::Number();
  164         428  
  164         3609  
30 164     164   1048 use Test2::Compare::Object();
  164         721  
  164         2433  
31 164     164   71622 use Test2::Compare::OrderedSubset();
  164         457  
  164         3568  
32 164     164   67762 use Test2::Compare::Pattern();
  164         459  
  164         3301  
33 164     164   65593 use Test2::Compare::Ref();
  164         458  
  164         3365  
34 164     164   67124 use Test2::Compare::DeepRef();
  164         463  
  164         3345  
35 164     164   66496 use Test2::Compare::Regex();
  164         481  
  164         3326  
36 164     164   67438 use Test2::Compare::Scalar();
  164         390  
  164         3888  
37 164     164   69097 use Test2::Compare::Set();
  164         443  
  164         3576  
38 164     164   66689 use Test2::Compare::String();
  164         471  
  164         3424  
39 164     164   67039 use Test2::Compare::Undef();
  164         446  
  164         3456  
40 164     164   66755 use Test2::Compare::Wildcard();
  164         422  
  164         21672  
41              
42             %Carp::Internal = (
43             %Carp::Internal,
44             'Test2::Tools::Compare' => 1,
45             'Test2::Compare::Array' => 1,
46             'Test2::Compare::Bag' => 1,
47             'Test2::Compare::Bool' => 1,
48             'Test2::Compare::Custom' => 1,
49             'Test2::Compare::Event' => 1,
50             'Test2::Compare::Float' => 1,
51             'Test2::Compare::Hash' => 1,
52             'Test2::Compare::Isa' => 1,
53             'Test2::Compare::Meta' => 1,
54             'Test2::Compare::Number' => 1,
55             'Test2::Compare::Object' => 1,
56             'Test2::Compare::Pattern' => 1,
57             'Test2::Compare::Ref' => 1,
58             'Test2::Compare::Regex' => 1,
59             'Test2::Compare::Scalar' => 1,
60             'Test2::Compare::Set' => 1,
61             'Test2::Compare::String' => 1,
62             'Test2::Compare::Undef' => 1,
63             'Test2::Compare::Wildcard' => 1,
64             'Test2::Compare::OrderedSubset' => 1,
65             );
66              
67             our @EXPORT = qw/is like/;
68             our @EXPORT_OK = qw{
69             is like isnt unlike
70             match mismatch validator
71             hash array bag object meta meta_check number float rounded within string subset bool check_isa
72             number_lt number_le number_ge number_gt
73             in_set not_in_set check_set
74             item field call call_list call_hash prop check all_items all_keys all_vals all_values
75             etc end filter_items
76             T F D DF E DNE FDNE U L
77             event fail_events
78             exact_ref
79             };
80 164     164   1211 use base 'Exporter';
  164         362  
  164         778483  
81              
82             my $_autodump = sub {
83             my ($ctx, $got) = @_;
84              
85             my $module = $ENV{'T2_AUTO_DUMP'} or return;
86             $module = 'Data::Dumper' if $module eq '1';
87              
88             my $file = pkg_to_file($module);
89             eval { require $file };
90              
91             if (not $module->can('Dump')) {
92             require Data::Dumper;
93             $module = 'Data::Dumper';
94             }
95              
96             my $deparse = $Data::Dumper::Deparse;
97             $deparse = !!$ENV{'T2_AUTO_DEPARSE'} if exists $ENV{'T2_AUTO_DEPARSE'};
98             local $Data::Dumper::Deparse = $deparse;
99              
100             $ctx->diag($module->Dump([$got], ['GOT']));
101             };
102              
103             sub is($$;$@) {
104 1397     1397 1 98040 my ($got, $exp, $name, @diag) = @_;
105 1397         4964 my $ctx = context();
106              
107 1397         167388 my $delta = compare($got, $exp, \&strict_convert);
108              
109 1397 100       5153 if ($delta) {
110             # Temporary thing.
111 218         353 my $count = 0;
112 218         346 my $implicit = 0;
113 218         420 my @deltas = ($delta);
114 218         563 while (my $d = shift @deltas) {
115 321         1120 my $add = $d->children;
116 321 100 100     1738 push @deltas => @$add if $add && @$add;
117 321 100       709 next if $d->verified;
118 260         1042 $count++;
119 260 100 66     554 $implicit++ if $d->note && $d->note eq 'implicit end';
120             }
121              
122 218 50       1311 if ($implicit == $count) {
123 0         0 $ctx->ok(1, $name);
124 0 0       0 my $meth = $ENV{AUTHOR_TESTING} ? 'throw' : 'alert';
125 0         0 my $type = $delta->render_check;
126 0         0 $ctx->$meth(
127             join "\n",
128             "!!! NOTICE OF BEHAVIOR CHANGE !!!",
129             "This test uses at least 1 $type check without using end() or etc().",
130             "The old behavior was to default to etc() when inside is().",
131             "The old behavior was a bug.",
132             "The new behavior is to default to end().",
133             "This test will soon start to fail with the following diagnostics:",
134             $delta->diag->as_string,
135             "",
136             );
137             }
138             else {
139 218         643 $ctx->fail($name, $delta->diag, @diag);
140 218         45516 $ctx->$_autodump($got);
141             }
142             }
143             else {
144 1179         5140 $ctx->ok(1, $name);
145             }
146              
147 1397         186931 $ctx->release;
148 1397         40488 return !$delta;
149             }
150              
151             sub isnt($$;$@) {
152 12     12 1 1108 my ($got, $exp, $name, @diag) = @_;
153 12         204 my $ctx = context();
154              
155 12         3137 my $delta = compare($got, $exp, \&strict_convert);
156              
157 12 100       187 if ($delta) {
158 8         190 $ctx->ok(1, $name);
159             }
160             else {
161 4         19 $ctx->ok(0, $name, ["Comparison matched (it should not).", @diag]);
162 4         2328 $ctx->$_autodump($got);
163             }
164              
165 12         4602 $ctx->release;
166 12 100       779 return $delta ? 1 : 0;
167             }
168              
169             sub like($$;$@) {
170 338     338 1 112926 my ($got, $exp, $name, @diag) = @_;
171 338         1093 my $ctx = context();
172              
173 338         33710 my $delta = compare($got, $exp, \&relaxed_convert);
174              
175 338 100       1552 if ($delta) {
176 3         28 $ctx->fail($name, $delta->diag, @diag);
177 3         662 $ctx->$_autodump($got);
178             }
179             else {
180 335         1410 $ctx->ok(1, $name);
181             }
182              
183 338         57294 $ctx->release;
184 338         9975 return !$delta;
185             }
186              
187             sub unlike($$;$@) {
188 9     9 1 684 my ($got, $exp, $name, @diag) = @_;
189 9         24 my $ctx = context();
190              
191 9         800 my $delta = compare($got, $exp, \&relaxed_convert);
192              
193 9 100       50 if ($delta) {
194 4         15 $ctx->ok(1, $name);
195             }
196             else {
197 5         37 $ctx->ok(0, $name, ["Comparison matched (it should not).", @diag]);
198 5         2787 $ctx->$_autodump($got);
199             }
200              
201 9         583 $ctx->release;
202 9 100       262 return $delta ? 1 : 0;
203             }
204              
205 7     7 1 304 sub meta(&) { build('Test2::Compare::Meta', @_) }
206 0     0 1 0 sub meta_check(&) { build('Test2::Compare::Meta', @_) }
207 549     549 1 4364 sub hash(&) { build('Test2::Compare::Hash', @_) }
208 643     643 1 1323815 sub array(&) { build('Test2::Compare::Array', @_) }
209 425     425 1 3361 sub bag(&) { build('Test2::Compare::Bag', @_) }
210 10     10 1 375 sub object(&) { build('Test2::Compare::Object', @_) }
211 31     31 1 79734 sub subset(&) { build('Test2::Compare::OrderedSubset', @_) }
212              
213             sub U() {
214 2     2 1 337 my @caller = caller;
215             Test2::Compare::Custom->new(
216 2 100   2   17 code => sub { defined $_ ? 0 : 1 }, name => 'UNDEFINED', operator => '!DEFINED()',
  2         9  
217             file => $caller[1],
218             lines => [$caller[2]],
219             );
220             }
221              
222             sub D() {
223 6     6 1 384 my @caller = caller;
224             Test2::Compare::Custom->new(
225 6 100   6   40 code => sub { defined $_ ? 1 : 0 }, name => 'DEFINED', operator => 'DEFINED()',
  6         30  
226             file => $caller[1],
227             lines => [$caller[2]],
228             );
229             }
230              
231             sub DF() {
232 6     6 1 425 my @caller = caller;
233             Test2::Compare::Custom->new(
234 6 100 100 6   43 code => sub { defined $_ && ( ! ref $_ && ! $_ ) ? 1 : 0 }, name => 'DEFINED BUT FALSE', operator => 'DEFINED() && FALSE()',
  6         84  
235             file => $caller[1],
236             lines => [$caller[2]],
237             );
238             }
239              
240             sub DNE() {
241 26     26 1 835 my @caller = caller;
242             Test2::Compare::Custom->new(
243 26 100   30   280 code => sub { my %p = @_; $p{exists} ? 0 : 1 }, name => '', operator => '!exists',
  30         119  
  30         2148  
244             file => $caller[1],
245             lines => [$caller[2]],
246             );
247             }
248              
249             sub E() {
250 2     2 1 339 my @caller = caller;
251             Test2::Compare::Custom->new(
252 2 100   2   21 code => sub { my %p = @_; $p{exists} ? 1 : 0 }, name => '', operator => '!exists',
  2         9  
  2         12  
253             file => $caller[1],
254             lines => [$caller[2]],
255             );
256             }
257              
258             sub F() {
259 32     32 1 692 my @caller = caller;
260             Test2::Compare::Custom->new(
261 32 100   30   223 code => sub { my %p = @_; $p{got} ? 0 : $p{exists} }, name => 'FALSE', operator => 'FALSE()',
  30         127  
  30         112  
262             file => $caller[1],
263             lines => [$caller[2]],
264             );
265             }
266              
267             sub FDNE() {
268 6     6 1 446 my @caller = caller;
269             Test2::Compare::Custom->new(
270             code => sub {
271 6     6   29 my %p = @_;
272 6 100       21 return 1 unless $p{exists};
273 4 100       18 return $p{got} ? 0 : 1;
274             },
275 6         39 name => 'FALSE', operator => 'FALSE() || !exists',
276             file => $caller[1],
277             lines => [$caller[2]],
278             );
279             }
280              
281             sub T() {
282 164     164 1 2877 my @caller = caller;
283             Test2::Compare::Custom->new(
284             code => sub {
285 163     163   753 my %p = @_;
286 163 50       509 return 0 unless $p{exists};
287 163 100       867 return $p{got} ? 1 : 0;
288             },
289 164         3359 name => 'TRUE', operator => 'TRUE()',
290             file => $caller[1],
291             lines => [$caller[2]],
292             );
293             }
294              
295             sub L() {
296 5     5 1 411 my @caller = caller;
297             Test2::Compare::Custom->new(
298 5 100 100 5   32 code => sub { defined $_ && length $_ ? 1 : 0 }, name => 'LENGTH', operator => 'DEFINED() && LENGTH()',
  5         29  
299             file => $caller[1],
300             lines => [$caller[2]],
301             );
302             }
303              
304             sub exact_ref($) {
305 30     30 1 767 my @caller = caller;
306 30         154 return Test2::Compare::Ref->new(
307             file => $caller[1],
308             lines => [$caller[2]],
309             input => $_[0],
310             );
311             }
312              
313             sub match($) {
314 556     556 1 9173 my @caller = caller;
315 556         2172 return Test2::Compare::Pattern->new(
316             file => $caller[1],
317             lines => [$caller[2]],
318             pattern => $_[0],
319             );
320             }
321              
322             sub mismatch($) {
323 4     4 1 550 my @caller = caller;
324 4         30 return Test2::Compare::Pattern->new(
325             file => $caller[1],
326             lines => [$caller[2]],
327             negate => 1,
328             pattern => $_[0],
329             );
330             }
331              
332             sub validator {
333 6     6 1 29112 my $code = pop;
334 6         14 my $cname = pop;
335 6         12 my $op = pop;
336              
337 6         25 my @caller = caller;
338 6         44 return Test2::Compare::Custom->new(
339             file => $caller[1],
340             lines => [$caller[2]],
341             code => $code,
342             name => $cname,
343             operator => $op,
344             );
345             }
346              
347             sub number($;@) {
348 3     3 1 231 my ($num, @args) = @_;
349 3         12 my @caller = caller;
350 3         23 return Test2::Compare::Number->new(
351             file => $caller[1],
352             lines => [$caller[2]],
353             input => $num,
354             @args,
355             );
356             }
357              
358             sub number_lt($;@) {
359 1     1 1 155 my ($num, @args) = @_;
360 1         10 my @caller = caller;
361 1         9 return Test2::Compare::Number->new(
362             file => $caller[1],
363             lines => [$caller[2]],
364             input => $num,
365             mode => '<',
366             @args,
367             );
368             }
369              
370             sub number_le($;@) {
371 1     1 1 24 my ($num, @args) = @_;
372 1         4 my @caller = caller;
373 1         6 return Test2::Compare::Number->new(
374             file => $caller[1],
375             lines => [$caller[2]],
376             input => $num,
377             mode => '<=',
378             @args,
379             );
380             }
381              
382             sub number_ge($;@) {
383 1     1 1 18 my ($num, @args) = @_;
384 1         6 my @caller = caller;
385 1         6 return Test2::Compare::Number->new(
386             file => $caller[1],
387             lines => [$caller[2]],
388             input => $num,
389             mode => '>=',
390             @args,
391             );
392             }
393              
394             sub number_gt($;@) {
395 1     1 1 25 my ($num, @args) = @_;
396 1         4 my @caller = caller;
397 1         5 return Test2::Compare::Number->new(
398             file => $caller[1],
399             lines => [$caller[2]],
400             input => $num,
401             mode => '>',
402             @args,
403             );
404             }
405              
406             sub float($;@) {
407 6     6 1 533 my ($num, @args) = @_;
408 6         21 my @caller = caller;
409 6         40 return Test2::Compare::Float->new(
410             file => $caller[1],
411             lines => [$caller[2]],
412             input => $num,
413             @args,
414             );
415             }
416              
417             sub rounded($$) {
418 1     1 1 24 my ($num, $precision) = @_;
419 1         4 my @caller = caller;
420 1         7 return Test2::Compare::Float->new(
421             file => $caller[1],
422             lines => [$caller[2]],
423             input => $num,
424             precision => $precision,
425             );
426             }
427              
428             sub within($;$) {
429 2     2 1 248 my ($num, $tolerance) = @_;
430 2         7 my @caller = caller;
431 2 100       16 return Test2::Compare::Float->new(
432             file => $caller[1],
433             lines => [$caller[2]],
434             input => $num,
435             defined $tolerance ? ( tolerance => $tolerance ) : (),
436             );
437             }
438              
439             sub bool($;@) {
440 203     203 1 32219 my ($bool, @args) = @_;
441 203         683 my @caller = caller;
442 203         924 return Test2::Compare::Bool->new(
443             file => $caller[1],
444             lines => [$caller[2]],
445             input => $bool,
446             @args,
447             );
448             }
449              
450             sub string($;@) {
451 4     4 1 223 my ($str, @args) = @_;
452 4         17 my @caller = caller;
453 4         21 return Test2::Compare::String->new(
454             file => $caller[1],
455             lines => [$caller[2]],
456             input => $str,
457             @args,
458             );
459             }
460              
461             sub check_isa($;@) {
462 3     3 1 308 my ($class_name, @args) = @_;
463 3         12 my @caller = caller;
464 3         31 return Test2::Compare::Isa->new(
465             file => $caller[1],
466             lines => [$caller[2]],
467             input => $class_name,
468             @args,
469             );
470             }
471              
472             sub filter_items(&) {
473 18 100   18 1 217 defined( my $build = get_build() ) or croak "No current build!";
474              
475 17 100       198 croak "'$build' does not support filters"
476             unless $build->can('add_filter');
477              
478 16 100       180 croak "'filter_items' should only ever be called in void context"
479             if defined wantarray;
480              
481 15         83 $build->add_filter(@_);
482             }
483              
484             sub all_items {
485 5 50   5 1 52 defined( my $build = get_build() ) or croak "No current build!";
486              
487 5 50       25 croak "'$build' does not support all-items"
488             unless $build->can('add_for_each');
489              
490 5 50       449 croak "'all_items' should only ever be called in void context"
491             if defined wantarray;
492              
493 5         22 $build->add_for_each(@_);
494             }
495              
496             sub all_keys {
497 2 50   2 1 25 defined( my $build = get_build() ) or croak "No current build!";
498              
499 2 50       13 croak "'$build' does not support all-keys"
500             unless $build->can('add_for_each_key');
501              
502 2 50       7 croak "'all_keys' should only ever be called in void context"
503             if defined wantarray;
504              
505 2         9 $build->add_for_each_key(@_);
506             }
507              
508             *all_vals = *all_values;
509             sub all_values {
510 2 50   2 1 29 defined( my $build = get_build() ) or croak "No current build!";
511              
512 2 50       12 croak "'$build' does not support all-values"
513             unless $build->can('add_for_each_val');
514              
515 2 50       10 croak "'all_values' should only ever be called in void context"
516             if defined wantarray;
517              
518 2         11 $build->add_for_each_val(@_);
519             }
520              
521              
522             sub end() {
523 322 100   322 1 2359 defined( my $build = get_build() ) or croak "No current build!";
524              
525 321 100       1405 croak "'$build' does not support 'ending'"
526             unless $build->can('ending');
527              
528 320 100       7526 croak "'end' should only ever be called in void context"
529             if defined wantarray;
530              
531 319         1201 $build->set_ending(1);
532             }
533              
534             sub etc() {
535 1104 50   1104 1 3196 defined( my $build = get_build() ) or croak "No current build!";
536              
537 1104 50       3300 croak "'$build' does not support 'ending'"
538             unless $build->can('ending');
539              
540 1104 50       2054 croak "'etc' should only ever be called in void context"
541             if defined wantarray;
542              
543 1104         2591 $build->set_ending(0);
544             }
545              
546             my $_call = sub {
547             my ($name, $expect, $context, $func_name) = @_;
548             defined( my $build = get_build() ) or croak "No current build!";
549              
550             croak "'$build' does not support method calls"
551             unless $build->can('add_call');
552              
553             croak "'$func_name' should only ever be called in void context"
554             if defined wantarray;
555              
556             my @caller = caller;
557             $build->add_call(
558             $name,
559             Test2::Compare::Wildcard->new(
560             expect => $expect,
561             file => $caller[1],
562             lines => [$caller[2]],
563             ),
564             undef,
565             $context,
566             );
567             };
568              
569 1838     1838 1 44998 sub call($$) { $_call->(@_,'scalar','call') }
570 7     7 1 62 sub call_list($$) { $_call->(@_,'list','call_list') }
571 7     7 1 70 sub call_hash($$) { $_call->(@_,'hash','call_hash') }
572              
573             sub prop($$) {
574 822     822 1 4998 my ($name, $expect) = @_;
575 822 100       1717 defined( my $build = get_build() ) or croak "No current build!";
576              
577 821 50       2265 croak "'$build' does not support meta-checks"
578             unless $build->can('add_prop');
579              
580 821 100       1432 croak "'prop' should only ever be called in void context"
581             if defined wantarray;
582              
583 820         2045 my @caller = caller;
584 820         2739 $build->add_prop(
585             $name,
586             Test2::Compare::Wildcard->new(
587             expect => $expect,
588             file => $caller[1],
589             lines => [$caller[2]],
590             ),
591             );
592             }
593              
594             sub item($;$) {
595 1503     1503 1 4780 my @args = @_;
596 1503         2092 my $expect = pop @args;
597              
598 1503 100       2893 defined( my $build = get_build() ) or croak "No current build!";
599              
600 1502 100       4361 croak "'$build' does not support array item checks"
601             unless $build->can('add_item');
602              
603 1501 100       3072 croak "'item' should only ever be called in void context"
604             if defined wantarray;
605              
606 1500         3854 my @caller = caller;
607 1500         4356 push @args => Test2::Compare::Wildcard->new(
608             expect => $expect,
609             file => $caller[1],
610             lines => [$caller[2]],
611             );
612              
613 1500         5804 $build->add_item(@args);
614             }
615              
616             sub field($$) {
617 1023     1023 1 2901 my ($name, $expect) = @_;
618              
619 1023 100       2074 defined( my $build = get_build() ) or croak "No current build!";
620              
621 1022 100       3322 croak "'$build' does not support hash field checks"
622             unless $build->can('add_field');
623              
624 1021 100       2126 croak "'field' should only ever be called in void context"
625             if defined wantarray;
626              
627 1020         2605 my @caller = caller;
628 1020         3211 $build->add_field(
629             $name,
630             Test2::Compare::Wildcard->new(
631             expect => $expect,
632             file => $caller[1],
633             lines => [$caller[2]],
634             ),
635             );
636             }
637              
638             sub check($) {
639 18     18 1 128 my ($check) = @_;
640              
641 18 100       40 defined( my $build = get_build() ) or croak "No current build!";
642              
643 17 100       173 croak "'$build' is not a check-set"
644             unless $build->can('add_check');
645              
646 16 100       134 croak "'check' should only ever be called in void context"
647             if defined wantarray;
648              
649 15         40 my @caller = caller;
650 15         54 my $wc = Test2::Compare::Wildcard->new(
651             expect => $check,
652             file => $caller[1],
653             lines => [$caller[2]],
654             );
655              
656 15         64 $build->add_check($wc);
657             }
658              
659 9     9 1 963 sub check_set { return _build_set('all' => @_) }
660 9     9 1 581 sub in_set { return _build_set('any' => @_) }
661 5     5 1 550 sub not_in_set { return _build_set('none' => @_) }
662              
663             sub _build_set {
664 23     23   56 my $redux = shift;
665 23         47 my ($builder) = @_;
666 23   100     124 my $btype = reftype($builder) || '';
667              
668 23         61 my $set;
669 23 100       74 if ($btype eq 'CODE') {
670 7         22 $set = build('Test2::Compare::Set', $builder);
671 6         23 $set->set_builder($builder);
672             }
673             else {
674 16         169 $set = Test2::Compare::Set->new(checks => [@_]);
675             }
676              
677 22         123 $set->set_reduction($redux);
678 22         199 return $set;
679             }
680              
681             sub fail_events($;$) {
682 37     37 1 398 my $event = &event(@_);
683              
684 37         96 my $diag = event('Diag');
685              
686 37 50       117 return ($event, $diag) if defined wantarray;
687              
688 37 50       109 defined( my $build = get_build() ) or croak "No current build!";
689 37         139 $build->add_item($event);
690 37         107 $build->add_item($diag);
691             }
692              
693             sub event($;$) {
694 2207     2207 1 552362 my ($intype, $spec) = @_;
695              
696 2207         6419 my @caller = caller;
697              
698 2207 100       5264 croak "type is required" unless $intype;
699              
700 2206         3195 my $type;
701 2206 100       6993 if ($intype =~ m/^\+(.*)$/) {
702 99         708 $type = $1;
703             }
704             else {
705 2107         4759 $type = "Test2::Event::$intype";
706             }
707              
708 2206         3446 my $event;
709 2206 100       9590 if (!$spec) {
    100          
    100          
710 134         688 $event = Test2::Compare::Event->new(
711             etype => $intype,
712             file => $caller[1],
713             lines => [$caller[2]],
714             ending => 0,
715             );
716             }
717             elsif (!ref $spec) {
718 1         127 croak "'$spec' is not a valid event specification";
719             }
720             elsif (reftype($spec) eq 'CODE') {
721 849         2713 $event = build('Test2::Compare::Event', $spec);
722 849         2891 $event->set_etype($intype);
723 849         5046 $event->set_builder($spec);
724 849 100       3402 $event->set_ending(0) unless defined $event->ending;
725             }
726             else {
727 1222         5774 my $refcheck = Test2::Compare::Hash->new(
728             inref => $spec,
729             file => $caller[1],
730             lines => [$caller[2]],
731             );
732 1222         6907 $event = Test2::Compare::Event->new(
733             refcheck => $refcheck,
734             file => $caller[1],
735             lines => [$caller[2]],
736             etype => $intype,
737             ending => 0,
738             );
739             }
740              
741 2205         13364 $event->add_prop('blessed' => $type);
742              
743 2205 100       4876 return $event if defined wantarray;
744              
745 2120 100       4861 defined( my $build = get_build() ) or croak "No current build!";
746 2119         8510 $build->add_item($event);
747             }
748              
749             1;
750              
751             __END__