| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Test::Stream::Plugin::Compare; | 
| 2 | 100 |  |  | 100 |  | 744 | use strict; | 
|  | 100 |  |  |  |  | 95 |  | 
|  | 100 |  |  |  |  | 2249 |  | 
| 3 | 100 |  |  | 100 |  | 285 | use warnings; | 
|  | 100 |  |  |  |  | 103 |  | 
|  | 100 |  |  |  |  | 2160 |  | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 100 |  |  | 100 |  | 310 | use Test::Stream::Exporter qw/import default_exports exports/; | 
|  | 100 |  |  |  |  | 91 |  | 
|  | 100 |  |  |  |  | 464 |  | 
| 6 |  |  |  |  |  |  | default_exports qw/is like/; | 
| 7 |  |  |  |  |  |  | exports qw{ | 
| 8 |  |  |  |  |  |  | match mismatch validator | 
| 9 |  |  |  |  |  |  | hash array object meta number string | 
| 10 |  |  |  |  |  |  | in_set not_in_set check_set | 
| 11 |  |  |  |  |  |  | item field call prop check | 
| 12 |  |  |  |  |  |  | end filter_items | 
| 13 |  |  |  |  |  |  | T F D DNE FDNE | 
| 14 |  |  |  |  |  |  | event | 
| 15 |  |  |  |  |  |  | exact_ref | 
| 16 |  |  |  |  |  |  | }; | 
| 17 | 100 |  |  | 100 |  | 389 | no Test::Stream::Exporter; | 
|  | 100 |  |  |  |  | 103 |  | 
|  | 100 |  |  |  |  | 285 |  | 
| 18 |  |  |  |  |  |  |  | 
| 19 | 100 |  |  | 100 |  | 340 | use Carp qw/croak/; | 
|  | 100 |  |  |  |  | 111 |  | 
|  | 100 |  |  |  |  | 3638 |  | 
| 20 | 100 |  |  | 100 |  | 334 | use Scalar::Util qw/reftype blessed/; | 
|  | 100 |  |  |  |  | 99 |  | 
|  | 100 |  |  |  |  | 3960 |  | 
| 21 |  |  |  |  |  |  |  | 
| 22 | 100 |  |  | 100 |  | 30603 | use Test::Stream::Compare qw/compare get_build push_build pop_build build/; | 
|  | 100 |  |  |  |  | 150 |  | 
|  | 100 |  |  |  |  | 318 |  | 
| 23 | 100 |  |  | 100 |  | 491 | use Test::Stream::Context qw/context/; | 
|  | 100 |  |  |  |  | 118 |  | 
|  | 100 |  |  |  |  | 563 |  | 
| 24 | 100 |  |  | 100 |  | 376 | use Test::Stream::Util qw/rtype/; | 
|  | 100 |  |  |  |  | 118 |  | 
|  | 100 |  |  |  |  | 287 |  | 
| 25 |  |  |  |  |  |  |  | 
| 26 | 100 |  |  | 100 |  | 36185 | use Test::Stream::Compare::Array(); | 
|  | 100 |  |  |  |  | 157 |  | 
|  | 100 |  |  |  |  | 1575 |  | 
| 27 | 100 |  |  | 100 |  | 33899 | use Test::Stream::Compare::Custom(); | 
|  | 100 |  |  |  |  | 154 |  | 
|  | 100 |  |  |  |  | 1421 |  | 
| 28 | 100 |  |  | 100 |  | 33490 | use Test::Stream::Compare::Event(); | 
|  | 100 |  |  |  |  | 199 |  | 
|  | 100 |  |  |  |  | 1493 |  | 
| 29 | 100 |  |  | 100 |  | 34789 | use Test::Stream::Compare::Hash(); | 
|  | 100 |  |  |  |  | 159 |  | 
|  | 100 |  |  |  |  | 1506 |  | 
| 30 | 100 |  |  | 100 |  | 409 | use Test::Stream::Compare::Meta(); | 
|  | 100 |  |  |  |  | 114 |  | 
|  | 100 |  |  |  |  | 1054 |  | 
| 31 | 100 |  |  | 100 |  | 33879 | use Test::Stream::Compare::Number(); | 
|  | 100 |  |  |  |  | 182 |  | 
|  | 100 |  |  |  |  | 1518 |  | 
| 32 | 100 |  |  | 100 |  | 485 | use Test::Stream::Compare::Object(); | 
|  | 100 |  |  |  |  | 112 |  | 
|  | 100 |  |  |  |  | 1101 |  | 
| 33 | 100 |  |  | 100 |  | 33133 | use Test::Stream::Compare::Pattern(); | 
|  | 100 |  |  |  |  | 154 |  | 
|  | 100 |  |  |  |  | 1410 |  | 
| 34 | 100 |  |  | 100 |  | 32955 | use Test::Stream::Compare::Ref(); | 
|  | 100 |  |  |  |  | 169 |  | 
|  | 100 |  |  |  |  | 1493 |  | 
| 35 | 100 |  |  | 100 |  | 32421 | use Test::Stream::Compare::Regex(); | 
|  | 100 |  |  |  |  | 158 |  | 
|  | 100 |  |  |  |  | 1430 |  | 
| 36 | 100 |  |  | 100 |  | 32719 | use Test::Stream::Compare::Scalar(); | 
|  | 100 |  |  |  |  | 160 |  | 
|  | 100 |  |  |  |  | 1432 |  | 
| 37 | 100 |  |  | 100 |  | 33588 | use Test::Stream::Compare::Set(); | 
|  | 100 |  |  |  |  | 179 |  | 
|  | 100 |  |  |  |  | 1605 |  | 
| 38 | 100 |  |  | 100 |  | 32070 | use Test::Stream::Compare::String(); | 
|  | 100 |  |  |  |  | 173 |  | 
|  | 100 |  |  |  |  | 1482 |  | 
| 39 | 100 |  |  | 100 |  | 32750 | use Test::Stream::Compare::Undef(); | 
|  | 100 |  |  |  |  | 181 |  | 
|  | 100 |  |  |  |  | 1391 |  | 
| 40 | 100 |  |  | 100 |  | 32332 | use Test::Stream::Compare::Value(); | 
|  | 100 |  |  |  |  | 159 |  | 
|  | 100 |  |  |  |  | 1477 |  | 
| 41 | 100 |  |  | 100 |  | 32449 | use Test::Stream::Compare::Wildcard(); | 
|  | 100 |  |  |  |  | 174 |  | 
|  | 100 |  |  |  |  | 164175 |  | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | sub is($$;$@) { | 
| 44 | 1450 |  |  | 1450 | 1 | 8168965 | my ($got, $exp, $name, @diag) = @_; | 
| 45 | 1450 |  |  |  |  | 2762 | my $ctx = context(); | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 1450 |  |  |  |  | 3859 | my $delta = compare($got, $exp, \&strict_convert); | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 1450 | 100 |  |  |  | 2483 | if ($delta) { | 
| 50 | 78 |  |  |  |  | 182 | $ctx->ok(0, $name, [$delta->table, @diag]); | 
| 51 |  |  |  |  |  |  | } | 
| 52 |  |  |  |  |  |  | else { | 
| 53 | 1372 |  |  |  |  | 3121 | $ctx->ok(1, $name); | 
| 54 |  |  |  |  |  |  | } | 
| 55 |  |  |  |  |  |  |  | 
| 56 | 1450 |  |  |  |  | 3340 | $ctx->release; | 
| 57 | 1450 |  |  |  |  | 3564 | return !$delta; | 
| 58 |  |  |  |  |  |  | } | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | sub like($$;$@) { | 
| 61 | 434 |  |  | 434 | 1 | 1141 | my ($got, $exp, $name, @diag) = @_; | 
| 62 | 434 |  |  |  |  | 1002 | my $ctx = context(); | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 434 |  |  |  |  | 1256 | my $delta = compare($got, $exp, \&relaxed_convert); | 
| 65 |  |  |  |  |  |  |  | 
| 66 | 434 | 100 |  |  |  | 901 | if ($delta) { | 
| 67 | 4 |  |  |  |  | 13 | $ctx->ok(0, $name, [$delta->table, @diag]); | 
| 68 |  |  |  |  |  |  | } | 
| 69 |  |  |  |  |  |  | else { | 
| 70 | 430 |  |  |  |  | 1136 | $ctx->ok(1, $name); | 
| 71 |  |  |  |  |  |  | } | 
| 72 |  |  |  |  |  |  |  | 
| 73 | 434 |  |  |  |  | 1124 | $ctx->release; | 
| 74 | 434 |  |  |  |  | 1070 | return !$delta; | 
| 75 |  |  |  |  |  |  | } | 
| 76 |  |  |  |  |  |  |  | 
| 77 | 4 |  |  | 4 | 1 | 33 | sub meta(&)   { build('Test::Stream::Compare::Meta',   @_) } | 
| 78 | 10 |  |  | 10 | 1 | 58 | sub hash(&)   { build('Test::Stream::Compare::Hash',   @_) } | 
| 79 | 199 |  |  | 199 | 1 | 1162 | sub array(&)  { build('Test::Stream::Compare::Array',  @_) } | 
| 80 | 125 |  |  | 125 | 1 | 558 | sub object(&) { build('Test::Stream::Compare::Object', @_) } | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | my $FDNE = Test::Stream::Compare::Custom->new(code => sub { $_ ? 0 : 1 }, name => 'FALSE', operator => 'FALSE() || !exists'); | 
| 83 |  |  |  |  |  |  | my $DNE = Test::Stream::Compare::Custom->new(code => sub { my %p = @_; $p{exists} ? 0 : 1 },          name => '', operator => '!exists'); | 
| 84 |  |  |  |  |  |  | my $F   = Test::Stream::Compare::Custom->new(code => sub { my %p = @_; $p{got}    ? 0 : $p{exists} }, name => 'FALSE',            operator => 'FALSE()'); | 
| 85 |  |  |  |  |  |  | my $T = Test::Stream::Compare::Custom->new(code => sub { $_         ? 1 : 0 }, name => 'TRUE',    operator => 'TRUE()'); | 
| 86 |  |  |  |  |  |  | my $D = Test::Stream::Compare::Custom->new(code => sub { defined $_ ? 1 : 0 }, name => 'DEFINED', operator => 'DEFINED()'); | 
| 87 |  |  |  |  |  |  |  | 
| 88 | 62 |  |  | 62 | 1 | 300 | sub T()    { $T } | 
| 89 | 32 |  |  | 32 | 1 | 97 | sub F()    { $F } | 
| 90 | 6 |  |  | 6 | 1 | 16 | sub D()    { $D } | 
| 91 | 53 |  |  | 53 | 1 | 273 | sub DNE()  { $DNE } | 
| 92 | 6 |  |  | 6 | 1 | 16 | sub FDNE() { $FDNE } | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 5213 |  |  | 5213 | 0 | 7791 | sub strict_convert  { convert($_[0], 1) } | 
| 95 | 2295 |  |  | 2295 | 0 | 3425 | sub relaxed_convert { convert($_[0], 0) } | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | sub exact_ref($) { | 
| 98 | 19 |  |  | 19 | 1 | 82 | my @caller = caller; | 
| 99 | 19 |  |  |  |  | 97 | return Test::Stream::Compare::Ref->new( | 
| 100 |  |  |  |  |  |  | file  => $caller[1], | 
| 101 |  |  |  |  |  |  | lines => [$caller[2]], | 
| 102 |  |  |  |  |  |  | input => $_[0], | 
| 103 |  |  |  |  |  |  | ); | 
| 104 |  |  |  |  |  |  | } | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | sub match($) { | 
| 107 | 30 |  |  | 30 | 1 | 165 | my @caller = caller; | 
| 108 | 30 |  |  |  |  | 139 | return Test::Stream::Compare::Pattern->new( | 
| 109 |  |  |  |  |  |  | file    => $caller[1], | 
| 110 |  |  |  |  |  |  | lines   => [$caller[2]], | 
| 111 |  |  |  |  |  |  | pattern => $_[0], | 
| 112 |  |  |  |  |  |  | ); | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | sub mismatch($) { | 
| 116 | 4 |  |  | 4 | 1 | 31 | my @caller = caller; | 
| 117 | 4 |  |  |  |  | 24 | return Test::Stream::Compare::Pattern->new( | 
| 118 |  |  |  |  |  |  | file    => $caller[1], | 
| 119 |  |  |  |  |  |  | lines   => [$caller[2]], | 
| 120 |  |  |  |  |  |  | negate  => 1, | 
| 121 |  |  |  |  |  |  | pattern => $_[0], | 
| 122 |  |  |  |  |  |  | ); | 
| 123 |  |  |  |  |  |  | } | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | sub validator { | 
| 126 | 109 |  |  | 109 | 1 | 479 | my $code = pop; | 
| 127 | 109 |  |  |  |  | 99 | my $cname = pop; | 
| 128 | 109 |  |  |  |  | 71 | my $op = pop; | 
| 129 |  |  |  |  |  |  |  | 
| 130 | 109 |  |  |  |  | 223 | my @caller = caller; | 
| 131 | 109 |  |  |  |  | 346 | return Test::Stream::Compare::Custom->new( | 
| 132 |  |  |  |  |  |  | file     => $caller[1], | 
| 133 |  |  |  |  |  |  | lines    => [$caller[2]], | 
| 134 |  |  |  |  |  |  | code     => $code, | 
| 135 |  |  |  |  |  |  | name     => $cname, | 
| 136 |  |  |  |  |  |  | operator => $op, | 
| 137 |  |  |  |  |  |  | ); | 
| 138 |  |  |  |  |  |  | } | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | sub number($;@) { | 
| 141 | 2 |  |  | 2 | 1 | 6 | my ($num, @args) = @_; | 
| 142 | 2 |  |  |  |  | 6 | my @caller = caller; | 
| 143 | 2 |  |  |  |  | 15 | return Test::Stream::Compare::Number->new( | 
| 144 |  |  |  |  |  |  | file  => $caller[1], | 
| 145 |  |  |  |  |  |  | lines => [$caller[2]], | 
| 146 |  |  |  |  |  |  | input => $num, | 
| 147 |  |  |  |  |  |  | @args, | 
| 148 |  |  |  |  |  |  | ); | 
| 149 |  |  |  |  |  |  | } | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | sub string($;@) { | 
| 152 | 2 |  |  | 2 | 1 | 6 | my ($str, @args) = @_; | 
| 153 | 2 |  |  |  |  | 5 | my @caller = caller; | 
| 154 | 2 |  |  |  |  | 11 | return Test::Stream::Compare::String->new( | 
| 155 |  |  |  |  |  |  | file  => $caller[1], | 
| 156 |  |  |  |  |  |  | lines => [$caller[2]], | 
| 157 |  |  |  |  |  |  | input => $str, | 
| 158 |  |  |  |  |  |  | @args, | 
| 159 |  |  |  |  |  |  | ); | 
| 160 |  |  |  |  |  |  | } | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | sub filter_items(&) { | 
| 163 | 5 | 100 |  | 5 | 1 | 33 | my $build = get_build() or croak "No current build!"; | 
| 164 |  |  |  |  |  |  |  | 
| 165 | 4 | 100 |  |  |  | 95 | croak "'$build' does not support filters" | 
| 166 |  |  |  |  |  |  | unless $build->can('add_filter'); | 
| 167 |  |  |  |  |  |  |  | 
| 168 | 3 | 100 |  |  |  | 138 | croak "'filter_items' should only ever be called in void context" | 
| 169 |  |  |  |  |  |  | if defined wantarray; | 
| 170 |  |  |  |  |  |  |  | 
| 171 | 2 |  |  |  |  | 8 | $build->add_filter(@_); | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | sub end() { | 
| 175 | 139 | 100 |  | 139 | 1 | 471 | my $build = get_build() or croak "No current build!"; | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 138 | 100 |  |  |  | 503 | croak "'$build' does not support 'ending'" | 
| 178 |  |  |  |  |  |  | unless $build->can('ending'); | 
| 179 |  |  |  |  |  |  |  | 
| 180 | 137 | 100 |  |  |  | 307 | croak "'end' should only ever be called in void context" | 
| 181 |  |  |  |  |  |  | if defined wantarray; | 
| 182 |  |  |  |  |  |  |  | 
| 183 | 136 |  |  |  |  | 360 | $build->set_ending(1); | 
| 184 |  |  |  |  |  |  | } | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | sub call($$) { | 
| 187 | 1074 |  |  | 1074 | 1 | 1650 | my ($name, $expect) = @_; | 
| 188 | 1074 | 100 |  |  |  | 1446 | my $build = get_build() or croak "No current build!"; | 
| 189 |  |  |  |  |  |  |  | 
| 190 | 1073 | 100 |  |  |  | 2280 | croak "'$build' does not support method calls" | 
| 191 |  |  |  |  |  |  | unless $build->can('add_call'); | 
| 192 |  |  |  |  |  |  |  | 
| 193 | 1072 | 100 |  |  |  | 1496 | croak "'call' should only ever be called in void context" | 
| 194 |  |  |  |  |  |  | if defined wantarray; | 
| 195 |  |  |  |  |  |  |  | 
| 196 | 1071 |  |  |  |  | 1718 | my @caller = caller; | 
| 197 | 1071 |  |  |  |  | 2549 | $build->add_call( | 
| 198 |  |  |  |  |  |  | $name, | 
| 199 |  |  |  |  |  |  | Test::Stream::Compare::Wildcard->new( | 
| 200 |  |  |  |  |  |  | expect => $expect, | 
| 201 |  |  |  |  |  |  | file   => $caller[1], | 
| 202 |  |  |  |  |  |  | lines  => [$caller[2]], | 
| 203 |  |  |  |  |  |  | ), | 
| 204 |  |  |  |  |  |  | ); | 
| 205 |  |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | sub prop($$) { | 
| 208 | 217 |  |  | 217 | 1 | 480 | my ($name, $expect) = @_; | 
| 209 | 217 | 100 |  |  |  | 350 | my $build = get_build() or croak "No current build!"; | 
| 210 |  |  |  |  |  |  |  | 
| 211 | 216 | 100 |  |  |  | 612 | croak "'$build' does not support meta-checks" | 
| 212 |  |  |  |  |  |  | unless $build->can('add_prop'); | 
| 213 |  |  |  |  |  |  |  | 
| 214 | 215 | 100 |  |  |  | 409 | croak "'prop' should only ever be called in void context" | 
| 215 |  |  |  |  |  |  | if defined wantarray; | 
| 216 |  |  |  |  |  |  |  | 
| 217 | 214 |  |  |  |  | 416 | my @caller = caller; | 
| 218 | 214 |  |  |  |  | 678 | $build->add_prop( | 
| 219 |  |  |  |  |  |  | $name, | 
| 220 |  |  |  |  |  |  | Test::Stream::Compare::Wildcard->new( | 
| 221 |  |  |  |  |  |  | expect => $expect, | 
| 222 |  |  |  |  |  |  | file   => $caller[1], | 
| 223 |  |  |  |  |  |  | lines  => [$caller[2]], | 
| 224 |  |  |  |  |  |  | ), | 
| 225 |  |  |  |  |  |  | ); | 
| 226 |  |  |  |  |  |  | } | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | sub item($;$) { | 
| 229 | 196 |  |  | 196 | 1 | 298 | my @args   = @_; | 
| 230 | 196 |  |  |  |  | 150 | my $expect = pop @args; | 
| 231 |  |  |  |  |  |  |  | 
| 232 | 196 | 100 |  |  |  | 313 | my $build = get_build() or croak "No current build!"; | 
| 233 |  |  |  |  |  |  |  | 
| 234 | 195 | 100 |  |  |  | 511 | croak "'$build' does not support array item checks" | 
| 235 |  |  |  |  |  |  | unless $build->can('add_item'); | 
| 236 |  |  |  |  |  |  |  | 
| 237 | 194 | 100 |  |  |  | 353 | croak "'item' should only ever be called in void context" | 
| 238 |  |  |  |  |  |  | if defined wantarray; | 
| 239 |  |  |  |  |  |  |  | 
| 240 | 193 |  |  |  |  | 334 | my @caller = caller; | 
| 241 | 193 |  |  |  |  | 457 | push @args => Test::Stream::Compare::Wildcard->new( | 
| 242 |  |  |  |  |  |  | expect => $expect, | 
| 243 |  |  |  |  |  |  | file   => $caller[1], | 
| 244 |  |  |  |  |  |  | lines  => [$caller[2]], | 
| 245 |  |  |  |  |  |  | ); | 
| 246 |  |  |  |  |  |  |  | 
| 247 | 193 |  |  |  |  | 382 | $build->add_item(@args); | 
| 248 |  |  |  |  |  |  | } | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | sub field($$) { | 
| 251 | 80 |  |  | 80 | 1 | 238 | my ($name, $expect) = @_; | 
| 252 |  |  |  |  |  |  |  | 
| 253 | 80 | 100 |  |  |  | 123 | my $build = get_build() or croak "No current build!"; | 
| 254 |  |  |  |  |  |  |  | 
| 255 | 79 | 100 |  |  |  | 310 | croak "'$build' does not support hash field checks" | 
| 256 |  |  |  |  |  |  | unless $build->can('add_field'); | 
| 257 |  |  |  |  |  |  |  | 
| 258 | 78 | 100 |  |  |  | 200 | croak "'field' should only ever be called in void context" | 
| 259 |  |  |  |  |  |  | if defined wantarray; | 
| 260 |  |  |  |  |  |  |  | 
| 261 | 77 |  |  |  |  | 141 | my @caller = caller; | 
| 262 | 77 |  |  |  |  | 289 | $build->add_field( | 
| 263 |  |  |  |  |  |  | $name, | 
| 264 |  |  |  |  |  |  | Test::Stream::Compare::Wildcard->new( | 
| 265 |  |  |  |  |  |  | expect => $expect, | 
| 266 |  |  |  |  |  |  | file   => $caller[1], | 
| 267 |  |  |  |  |  |  | lines  => [$caller[2]], | 
| 268 |  |  |  |  |  |  | ), | 
| 269 |  |  |  |  |  |  | ); | 
| 270 |  |  |  |  |  |  | } | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | sub check($) { | 
| 273 | 18 |  |  | 18 | 1 | 45 | my ($check) = @_; | 
| 274 |  |  |  |  |  |  |  | 
| 275 | 18 | 100 |  |  |  | 28 | my $build = get_build() or croak "No current build!"; | 
| 276 |  |  |  |  |  |  |  | 
| 277 | 17 | 100 |  |  |  | 120 | croak "'$build' is not a check-set" | 
| 278 |  |  |  |  |  |  | unless $build->can('add_check'); | 
| 279 |  |  |  |  |  |  |  | 
| 280 | 16 | 100 |  |  |  | 95 | croak "'check' should only ever be called in void context" | 
| 281 |  |  |  |  |  |  | if defined wantarray; | 
| 282 |  |  |  |  |  |  |  | 
| 283 | 15 |  |  |  |  | 23 | my @caller = caller; | 
| 284 | 15 |  |  |  |  | 51 | my $wc = Test::Stream::Compare::Wildcard->new( | 
| 285 |  |  |  |  |  |  | expect => $check, | 
| 286 |  |  |  |  |  |  | file   => $caller[1], | 
| 287 |  |  |  |  |  |  | lines  => [$caller[2]], | 
| 288 |  |  |  |  |  |  | ); | 
| 289 |  |  |  |  |  |  |  | 
| 290 | 15 |  |  |  |  | 26 | $build->add_check($wc); | 
| 291 |  |  |  |  |  |  | } | 
| 292 |  |  |  |  |  |  |  | 
| 293 | 4 |  |  | 4 | 1 | 18 | sub check_set  { return _build_set('all'  => @_) } | 
| 294 | 13 |  |  | 13 | 1 | 35 | sub in_set     { return _build_set('any'  => @_) } | 
| 295 | 4 |  |  | 4 | 1 | 15 | sub not_in_set { return _build_set('none' => @_) } | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | sub _build_set { | 
| 298 | 21 |  |  | 21 |  | 23 | my $redux = shift; | 
| 299 | 21 |  |  |  |  | 18 | my ($builder) = @_; | 
| 300 | 21 |  | 100 |  |  | 68 | my $btype = reftype($builder) || ''; | 
| 301 |  |  |  |  |  |  |  | 
| 302 | 21 |  |  |  |  | 13 | my $set; | 
| 303 | 21 | 100 |  |  |  | 32 | if ($btype eq 'CODE') { | 
| 304 | 7 |  |  |  |  | 16 | $set = build('Test::Stream::Compare::Set', $builder); | 
| 305 | 6 |  |  |  |  | 20 | $set->set_builder($builder); | 
| 306 |  |  |  |  |  |  | } | 
| 307 |  |  |  |  |  |  | else { | 
| 308 | 14 |  |  |  |  | 42 | $set = Test::Stream::Compare::Set->new(checks => [@_]); | 
| 309 |  |  |  |  |  |  | } | 
| 310 |  |  |  |  |  |  |  | 
| 311 | 20 |  |  |  |  | 47 | $set->set_reduction($redux); | 
| 312 | 20 |  |  |  |  | 60 | return $set; | 
| 313 |  |  |  |  |  |  | } | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | sub event($;$) { | 
| 316 | 301 |  |  | 301 | 1 | 1807 | my ($intype, $spec) = @_; | 
| 317 |  |  |  |  |  |  |  | 
| 318 | 301 |  |  |  |  | 660 | my @caller = caller; | 
| 319 |  |  |  |  |  |  |  | 
| 320 | 301 | 100 |  |  |  | 684 | croak "type is required" unless $intype; | 
| 321 |  |  |  |  |  |  |  | 
| 322 | 300 |  |  |  |  | 281 | my $type; | 
| 323 | 300 | 100 |  |  |  | 580 | if ($intype =~ m/^\+(.*)$/) { | 
| 324 | 1 |  |  |  |  | 3 | $type = $1; | 
| 325 |  |  |  |  |  |  | } | 
| 326 |  |  |  |  |  |  | else { | 
| 327 | 299 |  |  |  |  | 550 | $type = "Test::Stream::Event::$intype"; | 
| 328 |  |  |  |  |  |  | } | 
| 329 |  |  |  |  |  |  |  | 
| 330 | 300 |  |  |  |  | 250 | my $event; | 
| 331 | 300 | 100 |  |  |  | 1231 | if (!$spec) { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 332 | 1 |  |  |  |  | 5 | $event = Test::Stream::Compare::Event->new( | 
| 333 |  |  |  |  |  |  | etype => $intype, | 
| 334 |  |  |  |  |  |  | file  => $caller[1], | 
| 335 |  |  |  |  |  |  | lines => [$caller[2]], | 
| 336 |  |  |  |  |  |  | ); | 
| 337 |  |  |  |  |  |  | } | 
| 338 |  |  |  |  |  |  | elsif (!ref $spec) { | 
| 339 | 1 |  |  |  |  | 81 | croak "'$spec' is not a valid event specification" | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  | elsif (reftype($spec) eq 'CODE') { | 
| 342 | 117 |  |  |  |  | 298 | $event = build('Test::Stream::Compare::Event', $spec); | 
| 343 | 117 |  |  |  |  | 334 | $event->set_etype($intype), | 
| 344 |  |  |  |  |  |  | $event->set_builder($spec); | 
| 345 |  |  |  |  |  |  | } | 
| 346 |  |  |  |  |  |  | else { | 
| 347 | 181 |  |  |  |  | 810 | my $refcheck = Test::Stream::Compare::Hash->new( | 
| 348 |  |  |  |  |  |  | inref => $spec, | 
| 349 |  |  |  |  |  |  | file  => $caller[1], | 
| 350 |  |  |  |  |  |  | lines => [$caller[2]], | 
| 351 |  |  |  |  |  |  | ); | 
| 352 | 181 |  |  |  |  | 691 | $event = Test::Stream::Compare::Event->new( | 
| 353 |  |  |  |  |  |  | refcheck => $refcheck, | 
| 354 |  |  |  |  |  |  | file     => $caller[1], | 
| 355 |  |  |  |  |  |  | lines    => [$caller[2]], | 
| 356 |  |  |  |  |  |  | etype => $intype, | 
| 357 |  |  |  |  |  |  | ); | 
| 358 |  |  |  |  |  |  | } | 
| 359 |  |  |  |  |  |  |  | 
| 360 | 299 |  |  |  |  | 1140 | $event->add_prop('blessed' => $type); | 
| 361 |  |  |  |  |  |  |  | 
| 362 | 299 | 100 |  |  |  | 540 | return $event if defined wantarray; | 
| 363 |  |  |  |  |  |  |  | 
| 364 | 294 | 100 |  |  |  | 554 | my $build = get_build() or croak "No current build!"; | 
| 365 | 293 |  |  |  |  | 697 | $build->add_item($event); | 
| 366 |  |  |  |  |  |  | } | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | sub convert { | 
| 369 | 9184 |  |  | 9184 | 0 | 10438 | my ($thing, $strict) = @_; | 
| 370 |  |  |  |  |  |  |  | 
| 371 | 9184 | 100 |  |  |  | 13280 | return Test::Stream::Compare::Undef->new() | 
| 372 |  |  |  |  |  |  | unless defined $thing; | 
| 373 |  |  |  |  |  |  |  | 
| 374 | 8649 | 100 | 100 |  |  | 40657 | if ($thing && blessed($thing) && $thing->isa('Test::Stream::Compare')) { | 
|  |  |  | 100 |  |  |  |  | 
| 375 | 2715 | 100 |  |  |  | 8076 | return $thing unless $thing->isa('Test::Stream::Compare::Wildcard'); | 
| 376 | 1667 |  |  |  |  | 3081 | my $newthing = convert($thing->expect, $strict); | 
| 377 | 1667 | 100 |  |  |  | 3105 | $newthing->set_builder($thing->builder) unless $newthing->builder; | 
| 378 | 1667 | 100 |  |  |  | 9527 | $newthing->set_file($thing->_file)      unless $newthing->_file; | 
| 379 | 1667 | 100 |  |  |  | 9767 | $newthing->set_lines($thing->_lines)    unless $newthing->_lines; | 
| 380 | 1667 |  |  |  |  | 9508 | return $newthing; | 
| 381 |  |  |  |  |  |  | } | 
| 382 |  |  |  |  |  |  |  | 
| 383 | 5934 |  |  |  |  | 10920 | my $type = rtype($thing); | 
| 384 |  |  |  |  |  |  |  | 
| 385 | 5934 | 100 |  |  |  | 11381 | return Test::Stream::Compare::Array->new(inref => $thing, $strict ? (ending => 1) : ()) | 
|  |  | 100 |  |  |  |  |  | 
| 386 |  |  |  |  |  |  | if $type eq 'ARRAY'; | 
| 387 |  |  |  |  |  |  |  | 
| 388 | 5228 | 100 |  |  |  | 8494 | return Test::Stream::Compare::Hash->new(inref => $thing, $strict ? (ending => 1) : ()) | 
|  |  | 100 |  |  |  |  |  | 
| 389 |  |  |  |  |  |  | if $type eq 'HASH'; | 
| 390 |  |  |  |  |  |  |  | 
| 391 | 4612 | 100 |  |  |  | 6172 | unless ($strict) { | 
| 392 | 1475 | 100 |  |  |  | 3532 | return Test::Stream::Compare::Pattern->new( | 
| 393 |  |  |  |  |  |  | pattern       => $thing, | 
| 394 |  |  |  |  |  |  | stringify_got => 1, | 
| 395 |  |  |  |  |  |  | ) if $type eq 'REGEXP'; | 
| 396 |  |  |  |  |  |  |  | 
| 397 | 956 | 100 |  |  |  | 1439 | return Test::Stream::Compare::Custom->new(code => $thing) | 
| 398 |  |  |  |  |  |  | if $type eq 'CODE'; | 
| 399 |  |  |  |  |  |  | } | 
| 400 |  |  |  |  |  |  |  | 
| 401 | 4062 | 100 |  |  |  | 5161 | return Test::Stream::Compare::Regex->new(input => $thing) | 
| 402 |  |  |  |  |  |  | if $type eq 'REGEXP'; | 
| 403 |  |  |  |  |  |  |  | 
| 404 | 4058 | 100 |  |  |  | 5045 | if ($type eq 'SCALAR') { | 
| 405 | 9 |  |  |  |  | 26 | my $nested = convert($$thing, $strict); | 
| 406 | 9 |  |  |  |  | 28 | return Test::Stream::Compare::Scalar->new(item => $nested) | 
| 407 |  |  |  |  |  |  | } | 
| 408 |  |  |  |  |  |  |  | 
| 409 | 4049 | 100 |  |  |  | 5357 | return Test::Stream::Compare::Ref->new(input => $thing) | 
| 410 |  |  |  |  |  |  | if $type; | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | # is() will assume string and use 'eq' | 
| 413 | 3906 |  |  |  |  | 9435 | return Test::Stream::Compare::String->new(input => $thing); | 
| 414 |  |  |  |  |  |  | } | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | 1; | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | __END__ |