xref: /openbsd-src/gnu/usr.bin/perl/lib/Class/Struct.t (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
155745691Smillert#!./perl -w
255745691Smillert
355745691SmillertBEGIN {
455745691Smillert	chdir 't' if -d 't';
555745691Smillert	@INC = '../lib';
655745691Smillert}
755745691Smillert
885009909Smillert#
985009909Smillert# A couple of simple classes to use as struct elements.
1085009909Smillert#
1155745691Smillertpackage aClass;
1255745691Smillertsub new { bless {}, shift }
1355745691Smillertsub meth { 42 }
1455745691Smillert
1555745691Smillertpackage RecClass;
1655745691Smillertsub new { bless {}, shift }
1755745691Smillert
1885009909Smillert#
1985009909Smillert# The first of our Class::Struct based objects.
2085009909Smillert#
2155745691Smillertpackage MyObj;
2255745691Smillertuse Class::Struct;
2355745691Smillertuse Class::Struct 'struct'; # test out both forms
2455745691Smillertuse Class::Struct SomeClass => { SomeElem => '$' };
2555745691Smillert
2655745691Smillertstruct( s => '$', a => '@', h => '%', c => 'aClass' );
2755745691Smillert
2885009909Smillert#
2985009909Smillert# The second Class::Struct objects:
3085009909Smillert# test the 'compile-time without package name' feature.
3185009909Smillert#
3285009909Smillertpackage MyOther;
3385009909Smillertuse Class::Struct s => '$', a => '@', h => '%', c => 'aClass';
3485009909Smillert
3585009909Smillert#
36*91f110e0Safresh1# test overriden accessors
37*91f110e0Safresh1#
38*91f110e0Safresh1package OverrideAccessor;
39*91f110e0Safresh1use Class::Struct;
40*91f110e0Safresh1
41*91f110e0Safresh1{
42*91f110e0Safresh1 no warnings qw(Class::Struct);
43*91f110e0Safresh1 struct( 'OverrideAccessor', { count => '$' } );
44*91f110e0Safresh1}
45*91f110e0Safresh1
46*91f110e0Safresh1sub count {
47*91f110e0Safresh1  my ($self,$count) = @_;
48*91f110e0Safresh1
49*91f110e0Safresh1  if ( @_ >= 2 ) {
50*91f110e0Safresh1    $self->{'OverrideAccessor::count'} = $count + 9;
51*91f110e0Safresh1  }
52*91f110e0Safresh1
53*91f110e0Safresh1  return $self->{'OverrideAccessor::count'};
54*91f110e0Safresh1}
55*91f110e0Safresh1
56*91f110e0Safresh1#
5785009909Smillert# back to main...
5885009909Smillert#
5985009909Smillertpackage main;
6085009909Smillert
61*91f110e0Safresh1use Test::More;
6285009909Smillert
6355745691Smillertmy $obj = MyObj->new;
6485009909Smillertisa_ok $obj, 'MyObj';
6555745691Smillert
6655745691Smillert$obj->s('foo');
6785009909Smillertis $obj->s(), 'foo';
6855745691Smillert
6985009909Smillertisa_ok $obj->a, 'ARRAY';
7055745691Smillert$obj->a(2, 'secundus');
7185009909Smillertis $obj->a(2), 'secundus';
7255745691Smillert
7355745691Smillert$obj->a([4,5,6]);
7485009909Smillertis $obj->a(1), 5;
7555745691Smillert
7685009909Smillertisa_ok $obj->h, 'HASH';
7785009909Smillert$obj->h('x', 10);
7885009909Smillertis $obj->h('x'), 10;
7955745691Smillert
8055745691Smillert$obj->h({h=>7,r=>8,f=>9});
8185009909Smillertis $obj->h('r'), 8;
8255745691Smillert
8385009909Smillertis $obj->c, undef;
8455745691Smillert
8585009909Smillert$obj = MyObj->new( c => aClass->new );
8685009909Smillertisa_ok $obj->c, 'aClass';
8785009909Smillertis $obj->c->meth(), 42;
8885009909Smillert
8985009909Smillert
9085009909Smillert$obj = MyOther->new;
9185009909Smillertisa_ok $obj, 'MyOther';
9285009909Smillert
9385009909Smillert$obj->s('foo');
9485009909Smillertis $obj->s(), 'foo';
9585009909Smillert
9685009909Smillertisa_ok $obj->a, 'ARRAY';
9785009909Smillert$obj->a(2, 'secundus');
9885009909Smillertis $obj->a(2), 'secundus';
9985009909Smillert
10085009909Smillert$obj->a([4,5,6]);
10185009909Smillertis $obj->a(1), 5;
10285009909Smillert
10385009909Smillertisa_ok $obj->h, 'HASH';
10485009909Smillert$obj->h('x', 10);
10585009909Smillertis $obj->h('x'), 10;
10685009909Smillert
10785009909Smillert$obj->h({h=>7,r=>8,f=>9});
10885009909Smillertis $obj->h('r'), 8;
10985009909Smillert
11085009909Smillertis $obj->c, undef;
11185009909Smillert
11285009909Smillert$obj = MyOther->new( c => aClass->new );
11385009909Smillertisa_ok $obj->c, 'aClass';
11485009909Smillertis $obj->c->meth(), 42;
11585009909Smillert
11685009909Smillert
11785009909Smillert
11885009909Smillertmy $obk = SomeClass->new();
11985009909Smillert$obk->SomeElem(123);
12085009909Smillertis $obk->SomeElem(), 123;
12185009909Smillert
12285009909Smillertmy $recobj = RecClass->new();
12385009909Smillertisa_ok $recobj, 'RecClass';
12455745691Smillert
125*91f110e0Safresh1my $override_obj = OverrideAccessor->new( count => 3 );
126*91f110e0Safresh1is $override_obj->count, 12;
127*91f110e0Safresh1
128*91f110e0Safresh1$override_obj->count( 1 );
129*91f110e0Safresh1is $override_obj->count, 10;
130*91f110e0Safresh1
131*91f110e0Safresh1
132*91f110e0Safresh1use Class::Struct Kapow => { z_zwap => 'Regexp', sploosh => 'MyObj' };
133*91f110e0Safresh1
134*91f110e0Safresh1is eval { main->new(); }, undef,
135*91f110e0Safresh1    'No new method injected into current package';
136*91f110e0Safresh1
137*91f110e0Safresh1my $obj3 = Kapow->new();
138*91f110e0Safresh1
139*91f110e0Safresh1isa_ok $obj3, 'Kapow';
140*91f110e0Safresh1is $obj3->z_zwap, undef, 'No z_zwap member by default';
141*91f110e0Safresh1is $obj3->sploosh, undef, 'No sploosh member by default';
142*91f110e0Safresh1$obj3->z_zwap(qr//);
143*91f110e0Safresh1isa_ok $obj3->z_zwap, 'Regexp', 'Can set z_zwap member';
144*91f110e0Safresh1$obj3->sploosh(MyObj->new(s => 'pie'));
145*91f110e0Safresh1isa_ok $obj3->sploosh, 'MyObj',
146*91f110e0Safresh1    'Can set sploosh member to object of correct class';
147*91f110e0Safresh1is $obj3->sploosh->s, 'pie', 'Can set sploosh member to correct object';
148*91f110e0Safresh1
149*91f110e0Safresh1my $obj4 = Kapow->new( z_zwap => qr//, sploosh => MyObj->new(a => ['Good']) );
150*91f110e0Safresh1
151*91f110e0Safresh1isa_ok $obj4, 'Kapow';
152*91f110e0Safresh1isa_ok $obj4->z_zwap, 'Regexp', 'Initialised z_zwap member';
153*91f110e0Safresh1isa_ok $obj4->sploosh, 'MyObj', 'Initialised sploosh member';
154*91f110e0Safresh1is_deeply $obj4->sploosh->a, ['Good'], 'with correct object';
155*91f110e0Safresh1
156*91f110e0Safresh1my $obj5 = Kapow->new( sploosh => { h => {perl => 'rules'} } );
157*91f110e0Safresh1
158*91f110e0Safresh1isa_ok $obj5, 'Kapow';
159*91f110e0Safresh1is $obj5->z_zwap, undef, 'No z_zwap member by default';
160*91f110e0Safresh1isa_ok $obj5->sploosh, 'MyObj', 'Initialised sploosh member from hash';
161*91f110e0Safresh1is_deeply $obj5->sploosh->h, { perl => 'rules'} , 'with correct object';
162*91f110e0Safresh1
163*91f110e0Safresh1is eval {
164*91f110e0Safresh1    package MyObj;
165*91f110e0Safresh1    struct( s => '$', a => '@', h => '%', c => 'aClass' );
166*91f110e0Safresh1}, undef, 'Calling struct a second time fails';
167*91f110e0Safresh1
168*91f110e0Safresh1like $@, qr/^function 'new' already defined in package MyObj/,
169*91f110e0Safresh1    'fails with the expected error';
170*91f110e0Safresh1
171*91f110e0Safresh1is eval { MyObj->new( a => {} ) }, undef,
172*91f110e0Safresh1    'Using a hash where an array reference is expected';
173*91f110e0Safresh1like $@, qr/^Initializer for a must be array reference/,
174*91f110e0Safresh1    'fails with the expected error';
175*91f110e0Safresh1
176*91f110e0Safresh1is eval { MyObj->new( h => [] ) }, undef,
177*91f110e0Safresh1    'Using an array where a hash reference is expected';
178*91f110e0Safresh1like $@, qr/^Initializer for h must be hash reference/,
179*91f110e0Safresh1    'fails with the expected error';
180*91f110e0Safresh1
181*91f110e0Safresh1is eval { Kapow->new( sploosh => { h => [perl => 'rules'] } ); }, undef,
182*91f110e0Safresh1    'Using an array where a hash reference is expected in an initialiser list';
183*91f110e0Safresh1like $@, qr/^Initializer for h must be hash reference/,
184*91f110e0Safresh1    'fails with the expected error';
185*91f110e0Safresh1
186*91f110e0Safresh1is eval { Kapow->new( sploosh => [ h => {perl => 'rules'} ] ); }, undef,
187*91f110e0Safresh1    "Using an array for a member object's initialiser list";
188*91f110e0Safresh1like $@, qr/^Initializer for sploosh must be hash or MyObj reference/,
189*91f110e0Safresh1    'fails with the expected error';
190*91f110e0Safresh1
191*91f110e0Safresh1is eval {
192*91f110e0Safresh1    package Crraack;
193*91f110e0Safresh1    use Class::Struct 'struct';
194*91f110e0Safresh1    struct( 'pow' => '@$%!' );
195*91f110e0Safresh1}, undef, 'Bad type fails';
196*91f110e0Safresh1like $@, qr/^'\@\$\%\!' is not a valid struct element type/,
197*91f110e0Safresh1    'with the expected error';
198*91f110e0Safresh1
199*91f110e0Safresh1is eval {
200*91f110e0Safresh1    $obj3->sploosh(MyOther->new(s => 3.14));
201*91f110e0Safresh1}, undef, 'Setting member to the wrong class of object fails';
202*91f110e0Safresh1like $@, qr/^sploosh argument is wrong class/,
203*91f110e0Safresh1    'with the expected error';
204*91f110e0Safresh1is $obj3->sploosh->s, 'pie', 'Object is unchanged';
205*91f110e0Safresh1
206*91f110e0Safresh1is eval {
207*91f110e0Safresh1    $obj3->sploosh(MyObj->new(s => 3.14), 'plop');
208*91f110e0Safresh1}, undef, 'Too many arguments to setter fails';
209*91f110e0Safresh1like $@, qr/^Too many args to sploosh/,
210*91f110e0Safresh1    'with the expected error';
211*91f110e0Safresh1is $obj3->sploosh->s, 'pie', 'Object is unchanged';
212*91f110e0Safresh1
213*91f110e0Safresh1is eval {
214*91f110e0Safresh1    package Blurp;
215*91f110e0Safresh1    use Class::Struct 'struct';
216*91f110e0Safresh1    struct( Blurp => {}, 'Bonus!' );
217*91f110e0Safresh1}, undef, 'hash based class with extra argument fails';
218*91f110e0Safresh1like $@, qr/\Astruct usage error.*\n.*\n/,
219*91f110e0Safresh1    'with the expected confession';
220*91f110e0Safresh1
221*91f110e0Safresh1is eval {
222*91f110e0Safresh1    package Zamm;
223*91f110e0Safresh1    use Class::Struct 'struct';
224*91f110e0Safresh1    struct( Zamm => [], 'Bonus!' );
225*91f110e0Safresh1}, undef, 'array based class with extra argument fails';
226*91f110e0Safresh1like $@, qr/\Astruct usage error.*\n.*\n/,
227*91f110e0Safresh1    'with the expected confession';
228*91f110e0Safresh1
229*91f110e0Safresh1is eval {
230*91f110e0Safresh1    package Thwapp;
231*91f110e0Safresh1    use Class::Struct 'struct';
232*91f110e0Safresh1    struct( Thwapp => ['Bonus!'] );
233*91f110e0Safresh1}, undef, 'array based class with extra constructor argument fails';
234*91f110e0Safresh1like $@, qr/\Astruct usage error.*\n.*\n/,
235*91f110e0Safresh1    'with the expected confession';
236*91f110e0Safresh1
237*91f110e0Safresh1is eval {
238*91f110e0Safresh1    package Rakkk;
239*91f110e0Safresh1    use Class::Struct 'struct';
240*91f110e0Safresh1    struct( z_zwap => 'Regexp', sploosh => 'MyObj', 'Bonus' );
241*91f110e0Safresh1}, undef, 'default array based class with extra constructor argument fails';
242*91f110e0Safresh1like $@, qr/\Astruct usage error.*\n.*\n/,
243*91f110e0Safresh1    'with the expected confession';
244*91f110e0Safresh1
245*91f110e0Safresh1is eval {
246*91f110e0Safresh1    package Awk;
247*91f110e0Safresh1    use parent -norequire, 'Urkkk';
248*91f110e0Safresh1    use Class::Struct 'struct';
249*91f110e0Safresh1    struct( beer => 'foamy' );
250*91f110e0Safresh1}, undef, '@ISA is not allowed';
251*91f110e0Safresh1like $@, qr/^struct class cannot be a subclass \(\@ISA not allowed\)/,
252*91f110e0Safresh1    'with the expected error';
253*91f110e0Safresh1
254*91f110e0Safresh1done_testing;
255