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