line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Object::HashBase::Test; |
2
|
2
|
|
|
2
|
|
383
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
54
|
|
3
|
2
|
|
|
2
|
|
12
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
59
|
|
4
|
|
|
|
|
|
|
|
5
|
2
|
|
|
2
|
|
13
|
use vars qw/$NO_RUN/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
300
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
BEGIN { |
8
|
2
|
100
|
|
2
|
|
11
|
if ($NO_RUN) { |
9
|
1
|
|
|
0
|
|
4
|
*ok = sub { }; |
10
|
1
|
|
|
11
|
|
3
|
*is = sub { }; |
11
|
1
|
|
|
0
|
|
2
|
*is_deeply = sub { }; |
12
|
1
|
|
|
0
|
|
3
|
*like = sub { }; |
13
|
1
|
|
|
0
|
|
153
|
*done_testing = sub { }; |
14
|
|
|
|
|
|
|
} |
15
|
|
|
|
|
|
|
else { |
16
|
1
|
|
|
|
|
494
|
require Test::More; |
17
|
1
|
|
|
|
|
55509
|
Test::More->import; |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
return 1 if $NO_RUN; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our $VERSION = '0.006'; |
24
|
|
|
|
|
|
|
# <-- START --> |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub warnings(&) { |
27
|
1
|
|
|
1
|
0
|
3
|
my $code = shift; |
28
|
1
|
|
|
|
|
2
|
my @warnings; |
29
|
1
|
|
|
1
|
|
4
|
local $SIG{__WARN__} = sub { push @warnings => @_ }; |
|
1
|
|
|
|
|
43
|
|
30
|
1
|
|
|
|
|
3
|
$code->(); |
31
|
1
|
|
|
|
|
244
|
return \@warnings; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub exception(&) { |
35
|
2
|
|
|
2
|
0
|
4
|
my $code = shift; |
36
|
2
|
|
|
|
|
9
|
local ($@, $!, $SIG{__DIE__}); |
37
|
2
|
|
|
|
|
3
|
my $ok = eval { $code->(); 1 }; |
|
2
|
|
|
|
|
5
|
|
|
0
|
|
|
|
|
0
|
|
38
|
2
|
|
50
|
|
|
63
|
my $error = $@ || 'SQUASHED ERROR'; |
39
|
2
|
50
|
|
|
|
16
|
return $ok ? undef : $error; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
BEGIN { |
43
|
2
|
|
|
2
|
|
9
|
$INC{'Object/HashBase/Test/HBase.pm'} = __FILE__; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
package |
46
|
|
|
|
|
|
|
Object::HashBase::Test::HBase; |
47
|
2
|
|
|
2
|
|
682
|
use Object::HashBase qw/foo bar baz/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
8
|
|
48
|
|
|
|
|
|
|
|
49
|
2
|
|
|
|
|
18
|
Object::HashBase::Test::is(FOO, 'foo', "FOO CONSTANT"); |
50
|
2
|
|
|
|
|
331
|
Object::HashBase::Test::is(BAR, 'bar', "BAR CONSTANT"); |
51
|
2
|
|
|
|
|
284
|
Object::HashBase::Test::is(BAZ, 'baz', "BAZ CONSTANT"); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
BEGIN { |
55
|
|
|
|
|
|
|
package |
56
|
|
|
|
|
|
|
Object::HashBase::Test::HBaseSub; |
57
|
2
|
|
|
2
|
|
294
|
use base 'Object::HashBase::Test::HBase'; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
234
|
|
58
|
2
|
|
|
2
|
|
10
|
use Object::HashBase qw/apple pear/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
6
|
|
59
|
|
|
|
|
|
|
|
60
|
2
|
|
|
2
|
|
10
|
Object::HashBase::Test::is(FOO, 'foo', "FOO CONSTANT"); |
61
|
2
|
|
|
|
|
250
|
Object::HashBase::Test::is(BAR, 'bar', "BAR CONSTANT"); |
62
|
2
|
|
|
|
|
241
|
Object::HashBase::Test::is(BAZ, 'baz', "BAZ CONSTANT"); |
63
|
2
|
|
|
|
|
240
|
Object::HashBase::Test::is(APPLE, 'apple', "APPLE CONSTANT"); |
64
|
2
|
|
|
|
|
244
|
Object::HashBase::Test::is(PEAR, 'pear', "PEAR CONSTANT"); |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
my $one = Object::HashBase::Test::HBase->new(foo => 'a', bar => 'b', baz => 'c'); |
68
|
|
|
|
|
|
|
is($one->foo, 'a', "Accessor"); |
69
|
|
|
|
|
|
|
is($one->bar, 'b', "Accessor"); |
70
|
|
|
|
|
|
|
is($one->baz, 'c', "Accessor"); |
71
|
|
|
|
|
|
|
$one->set_foo('x'); |
72
|
|
|
|
|
|
|
is($one->foo, 'x', "Accessor set"); |
73
|
|
|
|
|
|
|
$one->set_foo(undef); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
is_deeply( |
76
|
|
|
|
|
|
|
$one, |
77
|
|
|
|
|
|
|
{ |
78
|
|
|
|
|
|
|
foo => undef, |
79
|
|
|
|
|
|
|
bar => 'b', |
80
|
|
|
|
|
|
|
baz => 'c', |
81
|
|
|
|
|
|
|
}, |
82
|
|
|
|
|
|
|
'hash' |
83
|
|
|
|
|
|
|
); |
84
|
|
|
|
|
|
|
|
85
|
0
|
|
|
|
|
0
|
BEGIN { |
86
|
|
|
|
|
|
|
package |
87
|
|
|
|
|
|
|
Object::HashBase::Test::Const::Test; |
88
|
2
|
|
|
2
|
|
340
|
use Object::HashBase qw/foo/; |
|
2
|
|
|
0
|
|
4
|
|
|
2
|
|
|
|
|
6
|
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub do_it { |
91
|
2
|
|
|
2
|
|
3
|
if (FOO()) { |
92
|
2
|
|
|
|
|
10
|
return 'const'; |
93
|
|
|
|
|
|
|
} |
94
|
0
|
|
|
|
|
0
|
return 'not const' |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
my $pkg = 'Object::HashBase::Test::Const::Test'; |
99
|
|
|
|
|
|
|
is($pkg->do_it, 'const', "worked as expected"); |
100
|
|
|
|
|
|
|
{ |
101
|
|
|
|
|
|
|
local $SIG{__WARN__} = sub { }; |
102
|
1
|
|
|
1
|
|
4
|
*Object::HashBase::Test::Const::Test::FOO = sub { 0 }; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
ok(!$pkg->FOO, "overrode const sub"); |
105
|
|
|
|
|
|
|
is($pkg->do_it, 'const', "worked as expected, const was constant"); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
BEGIN { |
108
|
2
|
|
|
2
|
|
8
|
$INC{'Object/HashBase/Test/HBase/Wrapped.pm'} = __FILE__; |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
package |
111
|
|
|
|
|
|
|
Object::HashBase::Test::HBase::Wrapped; |
112
|
2
|
|
|
2
|
|
17
|
use Object::HashBase qw/foo bar dup/; |
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
7
|
|
113
|
|
|
|
|
|
|
|
114
|
2
|
|
|
|
|
8
|
my $foo = __PACKAGE__->can('foo'); |
115
|
2
|
|
|
2
|
|
10
|
no warnings 'redefine'; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
119
|
|
116
|
|
|
|
|
|
|
*foo = sub { |
117
|
4
|
|
|
4
|
|
6
|
my $self = shift; |
118
|
4
|
|
|
|
|
12
|
$self->set_bar(1); |
119
|
4
|
|
|
|
|
9
|
$self->$foo(@_); |
120
|
2
|
|
|
|
|
84
|
}; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
0
|
|
|
|
|
0
|
BEGIN { |
124
|
2
|
|
|
2
|
|
121
|
$INC{'Object/HashBase/Test/HBase/Wrapped/Inherit.pm'} = __FILE__; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
package |
127
|
|
|
|
|
|
|
Object::HashBase::Test::HBase::Wrapped::Inherit; |
128
|
2
|
|
|
2
|
|
10
|
use base 'Object::HashBase::Test::HBase::Wrapped'; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
175
|
|
129
|
2
|
|
|
2
|
|
14
|
use Object::HashBase qw/baz dup/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
9
|
|
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
my $o = Object::HashBase::Test::HBase::Wrapped::Inherit->new(foo => 1); |
133
|
|
|
|
|
|
|
my $foo = $o->foo; |
134
|
|
|
|
|
|
|
is($o->bar, 1, 'parent attribute sub not overridden'); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
{ |
137
|
|
|
|
|
|
|
package |
138
|
|
|
|
|
|
|
Foo; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
sub new; |
141
|
|
|
|
|
|
|
|
142
|
2
|
|
|
2
|
|
11
|
use Object::HashBase qw/foo bar baz/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
6
|
|
143
|
|
|
|
|
|
|
|
144
|
1
|
|
|
1
|
|
3
|
sub new { 'foo' }; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
is(Foo->new, 'foo', "Did not override existing 'new' method"); |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
BEGIN { |
150
|
2
|
|
|
2
|
|
7
|
$INC{'Object/HashBase/Test/HBase2.pm'} = __FILE__; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
package |
153
|
|
|
|
|
|
|
Object::HashBase::Test::HBase2; |
154
|
2
|
|
|
2
|
|
10
|
use Object::HashBase qw/foo -bar ^baz/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
6
|
|
155
|
|
|
|
|
|
|
|
156
|
2
|
|
|
|
|
6
|
Object::HashBase::Test::is(FOO, 'foo', "FOO CONSTANT"); |
157
|
2
|
|
|
|
|
258
|
Object::HashBase::Test::is(BAR, 'bar', "BAR CONSTANT"); |
158
|
2
|
|
|
|
|
245
|
Object::HashBase::Test::is(BAZ, 'baz', "BAZ CONSTANT"); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
my $ro = Object::HashBase::Test::HBase2->new(foo => 'foo', bar => 'bar', baz => 'baz'); |
162
|
|
|
|
|
|
|
is($ro->foo, 'foo', "got foo"); |
163
|
|
|
|
|
|
|
is($ro->bar, 'bar', "got bar"); |
164
|
|
|
|
|
|
|
is($ro->baz, 'baz', "got baz"); |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
is($ro->set_foo('xxx'), 'xxx', "Can set foo"); |
167
|
|
|
|
|
|
|
is($ro->foo, 'xxx', "got foo"); |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
like(exception { $ro->set_bar('xxx') }, qr/'bar' is read-only/, "Cannot set bar"); |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
my $warnings = warnings { is($ro->set_baz('xxx'), 'xxx', 'set baz') }; |
172
|
|
|
|
|
|
|
like($warnings->[0], qr/set_baz\(\) is deprecated/, "Deprecation warning"); |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
is_deeply( |
177
|
|
|
|
|
|
|
[Object::HashBase::attr_list('Object::HashBase::Test::HBase::Wrapped::Inherit')], |
178
|
|
|
|
|
|
|
[qw/foo bar dup baz/], |
179
|
|
|
|
|
|
|
"Got a list of attributes in order starting from base class, duplicates removed", |
180
|
|
|
|
|
|
|
); |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
my $x = Object::HashBase::Test::HBase::Wrapped::Inherit->new(foo => 1, baz => 2); |
183
|
|
|
|
|
|
|
is($x->foo, 1, "set foo via pairs"); |
184
|
|
|
|
|
|
|
is($x->baz, 2, "set baz via pairs"); |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# Now with hashref |
187
|
|
|
|
|
|
|
my $y = Object::HashBase::Test::HBase::Wrapped::Inherit->new({foo => 1, baz => 2}); |
188
|
|
|
|
|
|
|
is($y->foo, 1, "set foo via hashref"); |
189
|
|
|
|
|
|
|
is($y->baz, 2, "set baz via hashref"); |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Now with hashref |
192
|
|
|
|
|
|
|
my $z = Object::HashBase::Test::HBase::Wrapped::Inherit->new([ |
193
|
|
|
|
|
|
|
1, # foo |
194
|
|
|
|
|
|
|
2, # bar |
195
|
|
|
|
|
|
|
3, # dup |
196
|
|
|
|
|
|
|
4, # baz |
197
|
|
|
|
|
|
|
]); |
198
|
|
|
|
|
|
|
is($z->foo, 1, "set foo via arrayref"); |
199
|
|
|
|
|
|
|
is($z->baz, 4, "set baz via arrayref"); |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
like( |
202
|
|
|
|
|
|
|
exception { Object::HashBase::Test::HBase::Wrapped::Inherit->new([1 .. 10]) }, |
203
|
|
|
|
|
|
|
qr/Too many arguments for Object::HashBase::Test::HBase::Wrapped::Inherit constructor/, |
204
|
|
|
|
|
|
|
"Too many args in array form" |
205
|
|
|
|
|
|
|
); |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
my $CAN_COUNT = 0; |
209
|
|
|
|
|
|
|
my $CAN_COUNT2 = 0; |
210
|
|
|
|
|
|
|
my $INIT_COUNT = 0; |
211
|
0
|
|
|
|
|
0
|
BEGIN { |
212
|
2
|
|
|
2
|
|
7
|
$INC{'Object/HashBase/Test/HBase3.pm'} = __FILE__; |
213
|
|
|
|
|
|
|
package |
214
|
|
|
|
|
|
|
Object::HashBase::Test::HBase3; |
215
|
2
|
|
|
2
|
|
569
|
use Object::HashBase qw/foo/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
7
|
|
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub can { |
218
|
1
|
|
|
1
|
0
|
2
|
my $self = shift; |
219
|
1
|
|
|
|
|
1
|
$CAN_COUNT++; |
220
|
1
|
|
|
|
|
8
|
$self->SUPER::can(@_); |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
2
|
|
|
|
|
275
|
$INC{'Object/HashBase/Test/HBase4.pm'} = __FILE__; |
224
|
|
|
|
|
|
|
package |
225
|
|
|
|
|
|
|
Object::HashBase::Test::HBase4; |
226
|
2
|
|
|
2
|
|
15
|
use Object::HashBase qw/foo/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
7
|
|
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub can { |
229
|
1
|
|
|
1
|
0
|
2
|
my $self = shift; |
230
|
1
|
|
|
|
|
2
|
$CAN_COUNT2++; |
231
|
1
|
|
|
|
|
7
|
$self->SUPER::can(@_); |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
2
|
|
|
2
|
0
|
4
|
sub init { $INIT_COUNT++ } |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
is($CAN_COUNT, 0, "->can has not been called yet"); |
238
|
|
|
|
|
|
|
my $it = Object::HashBase::Test::HBase3->new; |
239
|
|
|
|
|
|
|
is($CAN_COUNT, 1, "->can has been called once to check for init"); |
240
|
|
|
|
|
|
|
$it = Object::HashBase::Test::HBase3->new; |
241
|
|
|
|
|
|
|
is($CAN_COUNT, 1, "->can was not called again, we cached it"); |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
is($CAN_COUNT2, 0, "->can has not been called yet"); |
244
|
|
|
|
|
|
|
is($INIT_COUNT, 0, "->init has not been called yet"); |
245
|
|
|
|
|
|
|
$it = Object::HashBase::Test::HBase4->new; |
246
|
|
|
|
|
|
|
is($CAN_COUNT2, 1, "->can has been called once to check for init"); |
247
|
|
|
|
|
|
|
is($INIT_COUNT, 1, "->init has been called once"); |
248
|
|
|
|
|
|
|
$it = Object::HashBase::Test::HBase4->new; |
249
|
|
|
|
|
|
|
is($CAN_COUNT2, 1, "->can was not called again, we cached it"); |
250
|
|
|
|
|
|
|
is($INIT_COUNT, 2, "->init has been called again"); |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
done_testing; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
1; |