Profile of /usr/local/lib/perl5/5.10.1/Test/Deep.pm

← Index
NYTProf Performance Profile «block view•line view•sub view»
For 05.Domain_and_Item.t
Run on Tue May 4 17:21:41 2010
Reported on Tue May 4 17:22:21 2010

File | /usr/local/lib/perl5/5.10.1/Test/Deep.pm
Statements Executed | 950
Statement Execution Time | 4.51ms

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