Profile of Test/Deep.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For t/app_dpath.t
Run on Tue Jun 5 15:25:28 2012
Reported on Tue Jun 5 15:26:00 2012

Filename | /home/ss5/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Test/Deep.pm
Statements | Executed 3405 statements in 46.4ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
162 | 13 | 10 | 16.1ms | 122ms | Test::Deep::::descendTest::Deep::descend (recurses: max depth 3, inclusive time 108ms)
135 | 8 | 6 | 15.1ms | 34.0ms | Test::Deep::::__ANON__[:80]Test::Deep::__ANON__[:80]
144 | 1 | 1 | 4.24ms | 20.0ms | Test::Deep::::wrapTest::Deep::wrap
18 | 1 | 1 | 2.33ms | 133ms | Test::Deep::::cmp_detailsTest::Deep::cmp_details
1 | 1 | 1 | 1.94ms | 4.72ms | Test::Deep::::BEGIN@8Test::Deep::BEGIN@8
1 | 1 | 1 | 1.62ms | 7.92ms | Test::Deep::::BEGIN@7Test::Deep::BEGIN@7
18 | 1 | 1 | 1.38ms | 165ms | Test::Deep::::cmp_deeplyTest::Deep::cmp_deeply
18 | 1 | 1 | 708µs | 861µs | Test::Deep::::class_baseTest::Deep::class_base
1 | 1 | 1 | 504µs | 629µs | Test::Deep::::BEGIN@9Test::Deep::BEGIN@9
1 | 1 | 1 | 51µs | 67µs | main::::BEGIN@1 main::BEGIN@1
1 | 1 | 1 | 32µs | 244µs | Test::Deep::::BEGIN@5Test::Deep::BEGIN@5
1 | 1 | 1 | 31µs | 88µs | Test::Deep::::BEGIN@82Test::Deep::BEGIN@82
1 | 1 | 1 | 30µs | 130µs | Test::Deep::::BEGIN@12Test::Deep::BEGIN@12
1 | 1 | 1 | 28µs | 58µs | main::::BEGIN@2 main::BEGIN@2
0 | 0 | 0 | 0s | 0s | Test::Deep::::bagTest::Deep::bag
0 | 0 | 0 | 0s | 0s | Test::Deep::::builderTest::Deep::builder
0 | 0 | 0 | 0s | 0s | Test::Deep::::cmp_bagTest::Deep::cmp_bag
0 | 0 | 0 | 0s | 0s | Test::Deep::::cmp_methodsTest::Deep::cmp_methods
0 | 0 | 0 | 0s | 0s | Test::Deep::::cmp_setTest::Deep::cmp_set
0 | 0 | 0 | 0s | 0s | Test::Deep::::deep_diagTest::Deep::deep_diag
0 | 0 | 0 | 0s | 0s | Test::Deep::::eq_deeplyTest::Deep::eq_deeply
0 | 0 | 0 | 0s | 0s | Test::Deep::::eq_deeply_cacheTest::Deep::eq_deeply_cache
0 | 0 | 0 | 0s | 0s | Test::Deep::::isaTest::Deep::isa
0 | 0 | 0 | 0s | 0s | Test::Deep::::noclassTest::Deep::noclass
0 | 0 | 0 | 0s | 0s | Test::Deep::::render_stackTest::Deep::render_stack
0 | 0 | 0 | 0s | 0s | Test::Deep::::render_valTest::Deep::render_val
0 | 0 | 0 | 0s | 0s | Test::Deep::::requireclassTest::Deep::requireclass
0 | 0 | 0 | 0s | 0s | Test::Deep::::setTest::Deep::set
0 | 0 | 0 | 0s | 0s | Test::Deep::::subbagofTest::Deep::subbagof
0 | 0 | 0 | 0s | 0s | Test::Deep::::subhashofTest::Deep::subhashof
0 | 0 | 0 | 0s | 0s | Test::Deep::::subsetofTest::Deep::subsetof
0 | 0 | 0 | 0s | 0s | Test::Deep::::superbagofTest::Deep::superbagof
0 | 0 | 0 | 0s | 0s | Test::Deep::::superhashofTest::Deep::superhashof
0 | 0 | 0 | 0s | 0s | Test::Deep::::supersetofTest::Deep::supersetof

Call graph for these subroutines as a Graphviz dot language file.

Line | State ments | Time on line | Calls | Time in subs | Code
--- | --- | --- | --- | --- | ---
1 | 2 | 97µs | 2 | 82µs | # spent 67µs (51+16) within main::BEGIN@1 which was called: # once (51µs+16µs) by main::BEGIN@8 at line 1 use strict; # spent 67µs making 1 call to main::BEGIN@1 # spent 16µs making 1 call to strict::import
2 | 2 | 132µs | 2 | 88µs | # spent 58µs (28+30) within main::BEGIN@2 which was called: # once (28µs+30µs) by main::BEGIN@8 at line 2 use warnings; # spent 58µs making 1 call to main::BEGIN@2 # spent 30µs making 1 call to warnings::import
3 |  |  |  |  |
4 |  |  |  |  | package Test::Deep;
5 | 2 | 103µs | 2 | 456µs | # spent 244µs (32+212) within Test::Deep::BEGIN@5 which was called: # once (32µs+212µs) by main::BEGIN@8 at line 5 use Carp qw( confess ); # spent 244µs making 1 call to Test::Deep::BEGIN@5 # spent 212µs making 1 call to Exporter::import
6 |  |  |  |  |
7 | 2 | 374µs | 1 | 7.92ms | # spent 7.92ms (1.62+6.31) within Test::Deep::BEGIN@7 which was called: # once (1.62ms+6.31ms) by main::BEGIN@8 at line 7 use Test::Deep::Cache; # spent 7.92ms making 1 call to Test::Deep::BEGIN@7
8 | 2 | 400µs | 1 | 4.72ms | # spent 4.72ms (1.94+2.78) within Test::Deep::BEGIN@8 which was called: # once (1.94ms+2.78ms) by main::BEGIN@8 at line 8 use Test::Deep::Stack; # spent 4.72ms making 1 call to Test::Deep::BEGIN@8
9 | 2 | 397µs | 1 | 629µs | # spent 629µs (504+126) within Test::Deep::BEGIN@9 which was called: # once (504µs+126µs) by main::BEGIN@8 at line 9 use Test::Deep::RegexpVersion; # spent 629µs making 1 call to Test::Deep::BEGIN@9
10 |  |  |  |  |
11 | 1 | 3µs |  |  | require overload;
12 | 2 | 1.27ms | 2 | 230µs | # spent 130µs (30+100) within Test::Deep::BEGIN@12 which was called: # once (30µs+100µs) by main::BEGIN@8 at line 12 use Scalar::Util; # spent 130µs making 1 call to Test::Deep::BEGIN@12 # spent 100µs making 1 call to Exporter::import
13 |  |  |  |  |
14 | 1 | 1µs |  |  | my $Test;
15 | 1 | 4µs |  |  | unless (defined $Test::Deep::NoTest::NoTest)
16 |  |  |  |  | {
17 |  |  |  |  | # for people who want eq_deeply but not Test::Builder
18 | 1 | 2µs |  |  | require Test::Builder;
19 | 1 | 21µs | 1 | 23µs | $Test = Test::Builder->new; # spent 23µs making 1 call to Test::Builder::new
20 |  |  |  |  | }
21 |  |  |  |  |
22 | 1 | 3µs |  |  | our ($Stack, %Compared, $CompareCache, %WrapCache, $Shallow);
23 |  |  |  |  |
24 | 1 | 2µs |  |  | our $VERSION = '0.109';
25 | 1 | 70µs |  |  | $VERSION = eval $VERSION; # spent 12µs executing statements in string eval
26 |  |  |  |  |
27 | 1 | 2µs |  |  | require Exporter;
28 | 1 | 29µs |  |  | our @ISA = qw( Exporter );
29 |  |  |  |  |
30 | 1 | 2µs |  |  | our $Snobby = 1; # should we compare classes?
31 | 1 | 1µs |  |  | our $Expects = 0; # are we comparing got vs expect or expect vs expect
32 |  |  |  |  |
33 | 1 | 900ns |  |  | our $DNE = \"";
34 | 1 | 48µs | 1 | 26µs | our $DNE_ADDR = Scalar::Util::refaddr($DNE); # spent 26µs making 1 call to Scalar::Util::refaddr
35 |  |  |  |  |
36 |  |  |  |  | # if no sub name is supplied then we use the package name in lower case
37 | 1 | 59µs |  |  | my %constructors = (
38 |  |  |  |  | All => "",
39 |  |  |  |  | Any => "",
40 |  |  |  |  | Array => "",
41 |  |  |  |  | ArrayEach => "array_each",
42 |  |  |  |  | ArrayElementsOnly => "",
43 |  |  |  |  | ArrayLength => "",
44 |  |  |  |  | ArrayLengthOnly => "",
45 |  |  |  |  | Blessed => "",
46 |  |  |  |  | Boolean => "bool",
47 |  |  |  |  | Code => "",
48 |  |  |  |  | Hash => "",
49 |  |  |  |  | HashEach => "hash_each",
50 |  |  |  |  | HashKeys => "",
51 |  |  |  |  | HashKeysOnly => "",
52 |  |  |  |  | Ignore => "",
53 |  |  |  |  | Isa => "Isa",
54 |  |  |  |  | ListMethods => "",
55 |  |  |  |  | Methods => "",
56 |  |  |  |  | Number => "num",
57 |  |  |  |  | RefType => "",
58 |  |  |  |  | Regexp => "re",
59 |  |  |  |  | RegexpMatches => "",
60 |  |  |  |  | RegexpOnly => "",
61 |  |  |  |  | RegexpRef => "",
62 |  |  |  |  | RegexpRefOnly => "",
63 |  |  |  |  | ScalarRef => "scalref",
64 |  |  |  |  | ScalarRefOnly => "",
65 |  |  |  |  | Shallow => "",
66 |  |  |  |  | String => "str",
67 |  |  |  |  | );
68 |  |  |  |  |
69 | 1 | 1µs |  |  | our @CONSTRUCTORS_FROM_CLASSES;
70 |  |  |  |  |
71 | 1 | 170µs |  |  | while (my ($pkg, $name) = each %constructors)
72 |  |  |  |  | {
73 | 29 | 35µs |  |  | $name = lc($pkg) unless $name;
74 | 29 | 61µs |  |  | my $full_pkg = "Test::Deep::$pkg";
75 | 29 | 51µs |  |  | my $file = "$full_pkg.pm";
76 | 29 | 501µs | 29 | 239µs | $file =~ s#::#/#g; # spent 239µs making 29 calls to Test::Deep::CORE:subst, avg 8µs/call
77 |  |  |  |  | # spent 34.0ms (15.1+18.9) within Test::Deep::__ANON__[/home/ss5/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Test/Deep.pm:80] which was called 135 times, avg 252µs/call: # 18 times (4.51ms+9.14ms) by Test::Deep::wrap at line 362, avg 758µs/call # 18 times (1.99ms+1.92ms) by Test::Deep::RefType::descend at line 26 of Test/Deep/RefType.pm, avg 217µs/call # 18 times (1.61ms+1.53ms) by Test::Deep::Ref::test_reftype at line 33 of Test/Deep/Ref.pm, avg 175µs/call # 18 times (1.64ms+1.42ms) by Test::Deep::Ref::test_class at line 17 of Test/Deep/Ref.pm, avg 170µs/call # 18 times (297µs+614µs) by Test::Deep::Blessed::descend at line 27 of Test/Deep/Blessed.pm, avg 51µs/call # 15 times (1.96ms+1.27ms) by Test::Deep::ArrayLength::descend at line 26 of Test/Deep/ArrayLength.pm, avg 215µs/call # 15 times (1.75ms+1.37ms) by Test::Deep::Array::descend at line 28 of Test/Deep/Array.pm, avg 208µs/call # 15 times (1.39ms+1.61ms) by Test::Deep::Array::descend at line 24 of Test/Deep/Array.pm, avg 200µs/call my $sub = sub {
78 | 270 | 6.45ms |  |  | require $file;
79 |  |  | 135 | 9.80ms | return $full_pkg->new(@_); # spent 9.80ms making 135 calls to Test::Deep::Cmp::new, avg 73µs/call
80 | 29 | 286µs |  |  | };
81 |  |  |  |  | {
82 | 31 | 7.79ms | 2 | 146µs | # spent 88µs (31+57) within Test::Deep::BEGIN@82 which was called: # once (31µs+57µs) by main::BEGIN@8 at line 82 no strict 'refs'; # spent 88µs making 1 call to Test::Deep::BEGIN@82 # spent 58µs making 1 call to strict::unimport
83 | 29 | 252µs |  |  | *{$name} = $sub;
84 |  |  |  |  | }
85 |  |  |  |  |
86 | 29 | 142µs |  |  | push @CONSTRUCTORS_FROM_CLASSES, $name;
87 |  |  |  |  | }
88 |  |  |  |  |
89 |  |  |  |  | {
90 | 2 | 9µs |  |  | our @EXPORT_OK = qw( descend render_stack class_base cmp_details deep_diag );
91 |  |  |  |  |
92 | 1 | 900ns |  |  | our %EXPORT_TAGS;
93 | 1 | 38µs |  |  | $EXPORT_TAGS{v0} = [
94 |  |  |  |  | qw(
95 |  |  |  |  | Isa
96 |  |  |  |  |
97 |  |  |  |  | all any array array_each arrayelementsonly arraylength arraylengthonly
98 |  |  |  |  | bag blessed bool cmp_bag cmp_deeply cmp_methods cmp_set code eq_deeply
99 |  |  |  |  | hash hash_each hashkeys hashkeysonly ignore isa listmethods methods
100 |  |  |  |  | noclass num re reftype regexpmatches regexponly regexpref regexprefonly
101 |  |  |  |  | scalarrefonly scalref set shallow str subbagof subhashof subsetof
102 |  |  |  |  | superbagof superhashof supersetof useclass
103 |  |  |  |  | )
104 |  |  |  |  | ];
105 |  |  |  |  |
106 | 1 | 36µs |  |  | our @EXPORT = @{ $EXPORT_TAGS{ v0 } };
107 |  |  |  |  |
108 | 1 | 39µs |  |  | $EXPORT_TAGS{all} = [ @EXPORT, @EXPORT_OK ];
109 |  |  |  |  | }
110 |  |  |  |  |
111 |  |  |  |  | # this is ugly, I should never have exported a sub called isa now I
112 |  |  |  |  | # have to try figure out if the recipient wanted my isa or if a class
113 |  |  |  |  | # imported us and UNIVERSAL::isa is being called on that class.
114 |  |  |  |  | # Luckily our isa always expects 1 argument and U::isa always expects
115 |  |  |  |  | # 2, so we can figure out (assuming the caller is not buggy).
116 |  |  |  |  | sub isa
117 |  |  |  |  | {
118 |  |  |  |  | if (@_ == 1)
119 |  |  |  |  | {
120 |  |  |  |  | goto &Isa;
121 |  |  |  |  | }
122 |  |  |  |  | else
123 |  |  |  |  | {
124 |  |  |  |  | goto &UNIVERSAL::isa;
125 |  |  |  |  | }
126 |  |  |  |  | }
127 |  |  |  |  |
128 |  |  |  |  | sub cmp_deeply
129 |  |  |  |  | # spent 165ms (1.38+164) within Test::Deep::cmp_deeply which was called 18 times, avg 9.19ms/call: # 18 times (1.38ms+164ms) by main::check at line 49 of t/app_dpath.t, avg 9.19ms/call {
130 | 72 | 1.47ms |  |  | my ($d1, $d2, $name) = @_;
131 |  |  |  |  |
132 |  |  | 18 | 133ms | my ($ok, $stack) = cmp_details($d1, $d2); # spent 133ms making 18 calls to Test::Deep::cmp_details, avg 7.39ms/call
133 |  |  |  |  |
134 |  |  | 18 | 30.9ms | if (not $Test->ok($ok, $name)) # spent 30.9ms making 18 calls to Test::Builder::ok, avg 1.72ms/call
135 |  |  |  |  | {
136 |  |  |  |  | my $diag = deep_diag($stack);
137 |  |  |  |  | $Test->diag($diag);
138 |  |  |  |  | }
139 |  |  |  |  |
140 |  |  |  |  | return $ok;
141 |  |  |  |  | }
142 |  |  |  |  |
143 |  |  |  |  | sub cmp_details
144 |  |  |  |  | # spent 133ms (2.33+131) within Test::Deep::cmp_details which was called 18 times, avg 7.39ms/call: # 18 times (2.33ms+131ms) by Test::Deep::cmp_deeply at line 132, avg 7.39ms/call {
145 | 108 | 2.86ms |  |  | my ($d1, $d2) = @_;
146 |  |  |  |  |
147 |  |  | 18 | 4.14ms | local $Stack = Test::Deep::Stack->new; # spent 4.14ms making 18 calls to Test::Deep::MM::new, avg 230µs/call
148 |  |  | 18 | 4.86ms | local $CompareCache = Test::Deep::Cache->new; # spent 4.86ms making 18 calls to Test::Deep::Cache::new, avg 270µs/call
149 |  |  |  |  | local %WrapCache;
150 |  |  |  |  |
151 |  |  | 18 | 122ms | my $ok = descend($d1, $d2); # spent 122ms making 18 calls to Test::Deep::descend, avg 6.76ms/call
152 |  |  |  |  |
153 |  |  |  |  | return ($ok, $Stack);
154 |  |  |  |  | }
155 |  |  |  |  |
156 |  |  |  |  | sub eq_deeply
157 |  |  |  |  | {
158 |  |  |  |  | my ($d1, $d2) = @_;
159 |  |  |  |  |
160 |  |  |  |  | my ($ok) = cmp_details($d1, $d2);
161 |  |  |  |  |
162 |  |  |  |  | return $ok
163 |  |  |  |  | }
164 |  |  |  |  |
165 |  |  |  |  | sub eq_deeply_cache
166 |  |  |  |  | {
167 |  |  |  |  | # this is like cross between eq_deeply and descend(). It doesn't start
168 |  |  |  |  | # with a new $CompareCache but if the comparison fails it will leave
169 |  |  |  |  | # $CompareCache as if nothing happened. However, if the comparison
170 |  |  |  |  | # succeeds then $CompareCache retains all the new information
171 |  |  |  |  |
172 |  |  |  |  | # this allows Set and Bag to handle circular refs
173 |  |  |  |  |
174 |  |  |  |  | my ($d1, $d2, $name) = @_;
175 |  |  |  |  |
176 |  |  |  |  | local $Stack = Test::Deep::Stack->new;
177 |  |  |  |  | $CompareCache->local;
178 |  |  |  |  |
179 |  |  |  |  | my $ok = descend($d1, $d2);
180 |  |  |  |  |
181 |  |  |  |  | $CompareCache->finish($ok);
182 |  |  |  |  |
183 |  |  |  |  | return $ok;
184 |  |  |  |  | }
185 |  |  |  |  |
186 |  |  |  |  | sub deep_diag
187 |  |  |  |  | {
188 |  |  |  |  | my $stack = shift;
189 |  |  |  |  | # ick! incArrow and other things expect the stack has to be visible
190 |  |  |  |  | # in a well known place . TODO clean this up
191 |  |  |  |  | local $Stack = $stack;
192 |  |  |  |  |
193 |  |  |  |  | my $where = render_stack('$data', $stack);
194 |  |  |  |  |
195 |  |  |  |  | confess "No stack to diagnose" unless $stack;
196 |  |  |  |  | my $last = $stack->getLast;
197 |  |  |  |  |
198 |  |  |  |  | my $diag;
199 |  |  |  |  | my $message;
200 |  |  |  |  | my $got;
201 |  |  |  |  | my $expected;
202 |  |  |  |  |
203 |  |  |  |  | my $exp = $last->{exp};
204 |  |  |  |  | if (Scalar::Util::blessed($exp))
205 |  |  |  |  | {
206 |  |  |  |  | if ($exp->can("diagnostics"))
207 |  |  |  |  | {
208 |  |  |  |  | $diag = $exp->diagnostics($where, $last);
209 |  |  |  |  | $diag =~ s/\n+$/\n/;
210 |  |  |  |  | }
211 |  |  |  |  | else
212 |  |  |  |  | {
213 |  |  |  |  | if ($exp->can("diag_message"))
214 |  |  |  |  | {
215 |  |  |  |  | $message = $exp->diag_message($where);
216 |  |  |  |  | }
217 |  |  |  |  | }
218 |  |  |  |  | }
219 |  |  |  |  |
220 |  |  |  |  | if (not defined $diag)
221 |  |  |  |  | {
222 |  |  |  |  | $got = $exp->renderGot($last->{got}) unless defined $got;
223 |  |  |  |  | $expected = $exp->renderExp unless defined $expected;
224 |  |  |  |  | $message = "Compared $where" unless defined $message;
225 |  |  |  |  |
226 |  |  |  |  | $diag = <<EOM
227 |  |  |  |  | $message
228 |  |  |  |  | got : $got
229 |  |  |  |  | expect : $expected
230 |  |  |  |  | EOM
231 |  |  |  |  | }
232 |  |  |  |  |
233 |  |  |  |  | return $diag;
234 |  |  |  |  | }
235 |  |  |  |  |
236 |  |  |  |  | sub render_val
237 |  |  |  |  | {
238 |  |  |  |  | my $val = shift;
239 |  |  |  |  |
240 |  |  |  |  | my $rendered;
241 |  |  |  |  | if (defined $val)
242 |  |  |  |  | {
243 |  |  |  |  | $rendered = ref($val) ?
244 |  |  |  |  | (Scalar::Util::refaddr($val) eq $DNE_ADDR ?
245 |  |  |  |  | "Does not exist" :
246 |  |  |  |  | overload::StrVal($val)
247 |  |  |  |  | ) :
248 |  |  |  |  | qq('$val');
249 |  |  |  |  | }
250 |  |  |  |  | else
251 |  |  |  |  | {
252 |  |  |  |  | $rendered = "undef";
253 |  |  |  |  | }
254 |  |  |  |  |
255 |  |  |  |  | return $rendered;
256 |  |  |  |  | }
257 |  |  |  |  |
258 |  |  |  |  | sub descend
259 |  |  |  |  | # spent 122ms (16.1+106) within Test::Deep::descend which was called 162 times, avg 751µs/call: # 18 times (3.30ms+118ms) by Test::Deep::cmp_details at line 151, avg 6.76ms/call # 18 times (1.02ms+-1.02ms) by Test::Deep::Blessed::descend at line 27 of Test/Deep/Blessed.pm, avg 0s/call # 18 times (2.10ms+-2.10ms) by Test::Deep::Ref::test_reftype at line 33 of Test/Deep/Ref.pm, avg 0s/call # 18 times (1.82ms+-1.82ms) by Test::Deep::Ref::test_class at line 17 of Test/Deep/Ref.pm, avg 0s/call # 18 times (1.40ms+-1.40ms) by Test::Deep::RefType::descend at line 26 of Test/Deep/RefType.pm, avg 0s/call # 15 times (199µs+-199µs) by Test::Deep::ArrayElementsOnly::descend at line 33 of Test/Deep/ArrayElementsOnly.pm, avg 0s/call # 15 times (1.64ms+-1.64ms) by Test::Deep::ArrayLength::descend at line 26 of Test/Deep/ArrayLength.pm, avg 0s/call # 15 times (1.53ms+-1.53ms) by Test::Deep::Array::descend at line 28 of Test/Deep/Array.pm, avg 0s/call # 15 times (2.00ms+-2.00ms) by Test::Deep::Array::descend at line 24 of Test/Deep/Array.pm, avg 0s/call # 3 times (427µs+-427µs) by Test::Deep::Hash::descend at line 27 of Test/Deep/Hash.pm, avg 0s/call # 3 times (318µs+-318µs) by Test::Deep::Hash::descend at line 31 of Test/Deep/Hash.pm, avg 0s/call # 3 times (38µs+-38µs) by Test::Deep::HashElements::descend at line 36 of Test/Deep/HashElements.pm, avg 0s/call # 3 times (336µs+-336µs) by Test::Deep::HashKeys::descend at line 27 of Test/Deep/HashKeys.pm, avg 0s/call {
260 | 2124 | 16.5ms |  |  | my ($d1, $d2) = @_;
261 |  |  |  |  |
262 |  |  |  |  | if (!ref $d1 and !ref $d2)
263 |  |  |  |  | {
264 |  |  |  |  | # Shortcut comparison for the non-reference case.
265 |  |  |  |  | if (defined $d1)
266 |  |  |  |  | {
267 |  |  |  |  | return 1 if defined $d2 and $d1 eq $d2;
268 |  |  |  |  | }
269 |  |  |  |  | else
270 |  |  |  |  | {
271 |  |  |  |  | return 1 if !defined $d2;
272 |  |  |  |  | }
273 |  |  |  |  | }
274 |  |  |  |  |
275 |  |  | 144 | 612µs | if (! $Expects and Scalar::Util::blessed($d1) and $d1->isa("Test::Deep::Cmp")) # spent 612µs making 144 calls to Scalar::Util::blessed, avg 4µs/call
276 |  |  |  |  | {
277 |  |  |  |  | my $where = $Stack->render('$data');
278 |  |  |  |  | confess "Found a special comparison in $where\nYou can only the specials in the expects structure";
279 |  |  |  |  | }
280 |  |  |  |  |
281 |  |  |  |  | if (ref $d1 and ref $d2)
282 |  |  |  |  | {
283 |  |  |  |  | # this check is only done when we're comparing 2 expecteds against each
284 |  |  |  |  | # other
285 |  |  |  |  |
286 |  |  |  |  | if ($Expects and Scalar::Util::blessed($d1) and $d1->isa("Test::Deep::Cmp"))
287 |  |  |  |  | {
288 |  |  |  |  | # check they are the same class
289 |  |  |  |  | return 0 unless Test::Deep::blessed(Scalar::Util::blessed($d2))->descend($d1);
290 |  |  |  |  | if ($d1->can("compare"))
291 |  |  |  |  | {
292 |  |  |  |  | return $d1->compare($d2);
293 |  |  |  |  | }
294 |  |  |  |  | }
295 |  |  |  |  |
296 |  |  | 108 | 417µs | my $s1 = Scalar::Util::refaddr($d1); # spent 417µs making 108 calls to Scalar::Util::refaddr, avg 4µs/call
297 |  |  | 108 | 326µs | my $s2 = Scalar::Util::refaddr($d2); # spent 326µs making 108 calls to Scalar::Util::refaddr, avg 3µs/call
298 |  |  |  |  |
299 |  |  |  |  | if ($s1 eq $s2)
300 |  |  |  |  | {
301 |  |  |  |  | return 1;
302 |  |  |  |  | }
303 |  |  | 108 | 20.3ms | if ($CompareCache->cmp($d1, $d2)) # spent 20.3ms making 108 calls to Test::Deep::Cache::cmp, avg 188µs/call
304 |  |  |  |  | {
305 |  |  |  |  | # we've tried comparing these already so either they turned out to
306 |  |  |  |  | # be the same or we must be in a loop and we have to assume they're
307 |  |  |  |  | # the same
308 |  |  |  |  |
309 |  |  |  |  | return 1;
310 |  |  |  |  | }
311 |  |  |  |  | else
312 |  |  |  |  | {
313 |  |  | 108 | 16.0ms | $CompareCache->add($d1, $d2) # spent 16.0ms making 108 calls to Test::Deep::Cache::add, avg 148µs/call
314 |  |  |  |  | }
315 |  |  |  |  | }
316 |  |  |  |  |
317 |  |  | 144 | 20.0ms | $d2 = wrap($d2); # spent 20.0ms making 144 calls to Test::Deep::wrap, avg 139µs/call
318 |  |  |  |  |
319 |  |  | 144 | 3.56ms | $Stack->push({exp => $d2, got => $d1}); # spent 3.56ms making 144 calls to Test::Deep::Stack::push, avg 25µs/call
320 |  |  |  |  |
321 |  |  | 108 | 366µs | if (ref($d1) and (Scalar::Util::refaddr($d1) == $DNE_ADDR)) # spent 366µs making 108 calls to Scalar::Util::refaddr, avg 3µs/call
322 |  |  |  |  | {
323 |  |  |  |  | # whatever it was suposed to be, it didn't exist and so it's an
324 |  |  |  |  | # automatic fail
325 |  |  |  |  | return 0;
326 |  |  |  |  | }
327 |  |  |  |  |
328 |  |  | 144 | 150ms | if ($d2->descend($d1)) # spent 70.5ms making 15 calls to Test::Deep::Array::descend, avg 4.70ms/call # spent 30.5ms making 15 calls to Test::Deep::ArrayLength::descend, avg 2.03ms/call # spent 23.0ms making 3 calls to Test::Deep::Hash::descend, avg 7.67ms/call # spent 9.24ms making 3 calls to Test::Deep::HashKeys::descend, avg 3.08ms/call # spent 8.28ms making 18 calls to Test::Deep::RefType::descend, avg 460µs/call # spent 4.27ms making 18 calls to Test::Deep::Blessed::descend, avg 237µs/call # spent 2.09ms making 15 calls to Test::Deep::ArrayElementsOnly::descend, avg 139µs/call # spent 751µs making 36 calls to Test::Deep::Shallow::descend, avg 21µs/call # spent 422µs making 3 calls to Test::Deep::HashElements::descend, avg 141µs/call # spent 343µs making 3 calls to Test::Deep::HashKeysOnly::descend, avg 114µs/call # spent 198µs making 15 calls to Test::Deep::ArrayLengthOnly::descend, avg 13µs/call
329 |  |  |  |  | {
330 |  |  |  |  | # print "d1 = $d1, d2 = $d2\nok\n";
331 |  |  | 144 | 3.02ms | $Stack->pop; # spent 3.02ms making 144 calls to Test::Deep::Stack::pop, avg 21µs/call
332 |  |  |  |  |
333 |  |  |  |  | return 1;
334 |  |  |  |  | }
335 |  |  |  |  | else
336 |  |  |  |  | {
337 |  |  |  |  | # print "d1 = $d1, d2 = $d2\nnot ok\n";
338 |  |  |  |  | return 0;
339 |  |  |  |  | }
340 |  |  |  |  | }
341 |  |  |  |  |
342 |  |  |  |  | sub wrap
343 |  |  |  |  | # spent 20.0ms (4.24+15.7) within Test::Deep::wrap which was called 144 times, avg 139µs/call: # 144 times (4.24ms+15.7ms) by Test::Deep::descend at line 317, avg 139µs/call {
344 | 432 | 5.70ms |  |  | my $data = shift;
345 |  |  |  |  |
346 |  |  | 270 | 1.16ms | return $data if Scalar::Util::blessed($data) and $data->isa("Test::Deep::Cmp"); # spent 614µs making 144 calls to Scalar::Util::blessed, avg 4µs/call # spent 549µs making 126 calls to UNIVERSAL::isa, avg 4µs/call
347 |  |  |  |  |
348 |  |  | 18 | 861µs | my ($class, $base) = class_base($data); # spent 861µs making 18 calls to Test::Deep::class_base, avg 48µs/call
349 |  |  |  |  |
350 |  |  |  |  | my $cmp;
351 |  |  |  |  |
352 |  |  |  |  | if($base eq '')
353 |  |  |  |  | {
354 |  |  |  |  | $cmp = shallow($data);
355 |  |  |  |  | }
356 |  |  |  |  | else
357 |  |  |  |  | {
358 |  |  | 18 | 57µs | my $addr = Scalar::Util::refaddr($data); # spent 57µs making 18 calls to Scalar::Util::refaddr, avg 3µs/call
359 |  |  |  |  |
360 |  |  |  |  | return $WrapCache{$addr} if $WrapCache{$addr};
361 |  |  |  |  |
362 |  |  | 18 | 13.7ms | if($base eq 'ARRAY') # spent 13.7ms making 18 calls to Test::Deep::__ANON__[Test/Deep.pm:80], avg 758µs/call
363 |  |  |  |  | {
364 |  |  |  |  | $cmp = array($data);
365 |  |  |  |  | }
366 |  |  |  |  | elsif($base eq 'HASH')
367 |  |  |  |  | {
368 |  |  |  |  | $cmp = hash($data);
369 |  |  |  |  | }
370 |  |  |  |  | elsif($base eq 'SCALAR' or $base eq 'REF')
371 |  |  |  |  | {
372 |  |  |  |  | $cmp = scalref($data);
373 |  |  |  |  | }
374 |  |  |  |  | elsif(($base eq 'Regexp') or ($base eq 'REGEXP'))
375 |  |  |  |  | {
376 |  |  |  |  | $cmp = regexpref($data);
377 |  |  |  |  | }
378 |  |  |  |  | else
379 |  |  |  |  | {
380 |  |  |  |  | $cmp = shallow($data);
381 |  |  |  |  | }
382 |  |  |  |  |
383 |  |  |  |  | $WrapCache{$addr} = $cmp;
384 |  |  |  |  | }
385 |  |  |  |  | return $cmp;
386 |  |  |  |  | }
387 |  |  |  |  |
388 |  |  |  |  | sub class_base
389 |  |  |  |  | # spent 861µs (708+152) within Test::Deep::class_base which was called 18 times, avg 48µs/call: # 18 times (708µs+152µs) by Test::Deep::wrap at line 348, avg 48µs/call {
390 | 126 | 789µs |  |  | my $val = shift;
391 |  |  |  |  |
392 |  |  |  |  | if (ref $val)
393 |  |  |  |  | {
394 |  |  | 18 | 64µs | my $blessed = Scalar::Util::blessed($val); # spent 64µs making 18 calls to Scalar::Util::blessed, avg 4µs/call
395 |  |  |  |  | $blessed = defined($blessed) ? $blessed : "";
396 |  |  | 18 | 88µs | my $reftype = Scalar::Util::reftype($val); # spent 88µs making 18 calls to Scalar::Util::reftype, avg 5µs/call
397 |  |  |  |  |
398 |  |  |  |  |
399 |  |  |  |  | if ($Test::Deep::RegexpVersion::OldStyle) {
400 |  |  |  |  | if ($blessed eq "Regexp" and $reftype eq "SCALAR")
401 |  |  |  |  | {
402 |  |  |  |  | $reftype = "Regexp"
403 |  |  |  |  | }
404 |  |  |  |  | }
405 |  |  |  |  | return ($blessed, $reftype);
406 |  |  |  |  | }
407 |  |  |  |  | else
408 |  |  |  |  | {
409 |  |  |  |  | return ("", "");
410 |  |  |  |  | }
411 |  |  |  |  | }
412 |  |  |  |  |
413 |  |  |  |  | sub render_stack
414 |  |  |  |  | {
415 |  |  |  |  | my ($var, $stack) = @_;
416 |  |  |  |  |
417 |  |  |  |  | return $stack->render($var);
418 |  |  |  |  | }
419 |  |  |  |  |
420 |  |  |  |  | sub cmp_methods
421 |  |  |  |  | {
422 |  |  |  |  | local $Test::Builder::Level = $Test::Builder::Level + 1;
423 |  |  |  |  | return cmp_deeply(shift, methods(@{shift()}), shift);
424 |  |  |  |  | }
425 |  |  |  |  |
426 |  |  |  |  | sub requireclass
427 |  |  |  |  | {
428 |  |  |  |  | require Test::Deep::Class;
429 |  |  |  |  |
430 |  |  |  |  | my $val = shift;
431 |  |  |  |  |
432 |  |  |  |  | return Test::Deep::Class->new(1, $val);
433 |  |  |  |  | }
434 |  |  |  |  |
435 |  |  |  |  | # docs and export say this is call useclass, doh!
436 |  |  |  |  |
437 | 1 | 5µs |  |  | *useclass = \&requireclass;
438 |  |  |  |  |
439 |  |  |  |  | sub noclass
440 |  |  |  |  | {
441 |  |  |  |  | require Test::Deep::Class;
442 |  |  |  |  |
443 |  |  |  |  | my $val = shift;
444 |  |  |  |  |
445 |  |  |  |  | return Test::Deep::Class->new(0, $val);
446 |  |  |  |  | }
447 |  |  |  |  |
448 |  |  |  |  | sub set
449 |  |  |  |  | {
450 |  |  |  |  | require Test::Deep::Set;
451 |  |  |  |  |
452 |  |  |  |  | return Test::Deep::Set->new(1, "", @_);
453 |  |  |  |  | }
454 |  |  |  |  |
455 |  |  |  |  | sub supersetof
456 |  |  |  |  | {
457 |  |  |  |  | require Test::Deep::Set;
458 |  |  |  |  |
459 |  |  |  |  | return Test::Deep::Set->new(1, "sup", @_);
460 |  |  |  |  | }
461 |  |  |  |  |
462 |  |  |  |  | sub subsetof
463 |  |  |  |  | {
464 |  |  |  |  | require Test::Deep::Set;
465 |  |  |  |  |
466 |  |  |  |  | return Test::Deep::Set->new(1, "sub", @_);
467 |  |  |  |  | }
468 |  |  |  |  |
469 |  |  |  |  | sub cmp_set
470 |  |  |  |  | {
471 |  |  |  |  | local $Test::Builder::Level = $Test::Builder::Level + 1;
472 |  |  |  |  | return cmp_deeply(shift, set(@{shift()}), shift);
473 |  |  |  |  | }
474 |  |  |  |  |
475 |  |  |  |  | sub bag
476 |  |  |  |  | {
477 |  |  |  |  | require Test::Deep::Set;
478 |  |  |  |  |
479 |  |  |  |  | return Test::Deep::Set->new(0, "", @_);
480 |  |  |  |  | }
481 |  |  |  |  |
482 |  |  |  |  | sub superbagof
483 |  |  |  |  | {
484 |  |  |  |  | require Test::Deep::Set;
485 |  |  |  |  |
486 |  |  |  |  | return Test::Deep::Set->new(0, "sup", @_);
487 |  |  |  |  | }
488 |  |  |  |  |
489 |  |  |  |  | sub subbagof
490 |  |  |  |  | {
491 |  |  |  |  | require Test::Deep::Set;
492 |  |  |  |  |
493 |  |  |  |  | return Test::Deep::Set->new(0, "sub", @_);
494 |  |  |  |  | }
495 |  |  |  |  |
496 |  |  |  |  | sub cmp_bag
497 |  |  |  |  | {
498 |  |  |  |  | local $Test::Builder::Level = $Test::Builder::Level + 1;
499 |  |  |  |  | my $ref = ref($_[1]) || "";
500 |  |  |  |  | confess "Argument 2 to cmp_bag is not an ARRAY ref (".render_val($_[1]).")"
501 |  |  |  |  | unless $ref eq "ARRAY";
502 |  |  |  |  | return cmp_deeply(shift, bag(@{shift()}), shift);
503 |  |  |  |  | }
504 |  |  |  |  |
505 |  |  |  |  | sub superhashof
506 |  |  |  |  | {
507 |  |  |  |  | require Test::Deep::Hash;
508 |  |  |  |  |
509 |  |  |  |  | my $val = shift;
510 |  |  |  |  |
511 |  |  |  |  | return Test::Deep::SuperHash->new($val);
512 |  |  |  |  | }
513 |  |  |  |  |
514 |  |  |  |  | sub subhashof
515 |  |  |  |  | {
516 |  |  |  |  | require Test::Deep::Hash;
517 |  |  |  |  |
518 |  |  |  |  | my $val = shift;
519 |  |  |  |  |
520 |  |  |  |  | return Test::Deep::SubHash->new($val);
521 |  |  |  |  | }
522 |  |  |  |  |
523 |  |  |  |  | sub builder
524 |  |  |  |  | {
525 |  |  |  |  | if (@_)
526 |  |  |  |  | {
527 |  |  |  |  | $Test = shift;
528 |  |  |  |  | }
529 |  |  |  |  | return $Test;
530 |  |  |  |  | }
531 |  |  |  |  |
532 | 1 | 132µs |  |  | 1;
533 |  |  |  |  |
534 |  |  |  |  | __END__