use strict; $^W++; use Class::Prototyped; use Data::Dumper; use Test; BEGIN { $|++; plan tests => 43; } $Data::Dumper::Sortkeys = 1; $Data::Dumper::Sortkeys = 1; package main; my $p = Class::Prototyped->new(); $p->reflect->addSlot('field_1' => 'field_1'); $p->reflect->addSlot([qw(field_2)] => 'field_2'); $p->reflect->addSlot([qw(field_3 FIELD)] => 'field_3'); $p->reflect->addSlot([qw(field_4 constant)] => 'field_4'); $p->reflect->addSlot([qw(field_5 constant 1)] => 'field_5'); $p->reflect->addSlot([qw(field_6 FIELD constant)] => 'field_6'); $p->reflect->addSlot([qw(field_7 FIELD constant 1)] => 'field_7'); $p->reflect->addSlot('method_1' => sub { print "method_1.\n";}); $p->reflect->addSlot([qw(method_2)] => sub { print "method_2.\n";}); $p->reflect->addSlot([qw(method_3 METHOD)] => sub { print "method_3.\n";}); $p->reflect->addSlot([qw(method_4 superable)] => sub { print "method_4.\n";}); $p->reflect->addSlot([qw(method_5 superable 1)] => sub { print "method_5.\n";}); $p->reflect->addSlot([qw(method_6 METHOD superable)] => sub { print "method_6.\n";}); $p->reflect->addSlot([qw(method_7 METHOD superable 1)] => sub { print "method_7.\n";}); my %slots = $p->reflect->getSlots(undef, 'rotated'); ok( join('|', sort keys %slots), join('|', sort map {("field_$_", "method_$_")} (1..7)) ); foreach my $i (1..3) { ok( Data::Dumper->Dump([$slots{"field_$i"}]), Data::Dumper->Dump([{attribs => {}, value => "field_$i", type => 'FIELD'}]) ); ok( Data::Dumper->Dump([$slots{"method_$i"}]), Data::Dumper->Dump([{attribs => {}, value => sub {}, type => 'METHOD'}]) ); } foreach my $i (4..7) { ok( Data::Dumper->Dump([$slots{"field_$i"}]), Data::Dumper->Dump([{attribs => {constant => 1}, value => "field_$i", type => 'FIELD'}]) ); ok( Data::Dumper->Dump([$slots{"method_$i"}]), Data::Dumper->Dump([{attribs => {superable => 1}, value => sub {}, type => 'METHOD'}]) ); } my $q = $p->clone(); $p->reflect->addSlot('parent_1*' => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_1*)) ); $p->reflect->addSlot([qw(parent_2*)] => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_1* parent_2*)) ); $p->reflect->addSlot([qw(parent_3* PARENT)] => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_1* parent_2* parent_3*)) ); $p->reflect->addSlot([qw(parent_4* promote)] => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_4* parent_1* parent_2* parent_3*)) ); $p->reflect->addSlot([qw(parent_5* promote 1)] => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_5* parent_4* parent_1* parent_2* parent_3*)) ); $p->reflect->addSlot([qw(parent_6* PARENT promote)] => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_6* parent_5* parent_4* parent_1* parent_2* parent_3*)) ); $p->reflect->addSlot([qw(parent_7* PARENT promote 1)] => $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_7* parent_6* parent_5* parent_4* parent_1* parent_2* parent_3*)) ); %slots = $p->reflect->getSlots(undef, 'rotated'); ok( join('|', sort keys %slots), join('|', sort map {("field_$_", "method_$_", "parent_$_*")} (1..7)) ); foreach my $i (1..7) { ok( Data::Dumper->Dump([$slots{"parent_$i*"}]), Data::Dumper->Dump([{attribs => {}, value => $q, type => 'PARENT'}]) ); } $p->reflect->addSlot(['field_d', description => 'This is a friendly to use field!'], 'friendly'); $p->reflect->addSlot(['method_d', description => 'This is a friendly to use method!'], sub {}); $p->reflect->addSlot(['parent_d*', description => 'This is a friendly to use parent!'], $q); ok( join('|', $p->reflect->slotNames('PARENT')), join('|', qw(parent_7* parent_6* parent_5* parent_4* parent_1* parent_2* parent_3* parent_d*)) ); ok( Data::Dumper->Dump([[$p->reflect->getSlots()]]), Data::Dumper->Dump([[ (map {(["parent_$_*", 'PARENT'] => $q)} qw(7 6 5 4 1 2 3)), (['parent_d*', 'PARENT', description => 'This is a friendly to use parent!'], $q), (map {(["field_$_", 'FIELD'] => "field_$_")} (1..3)), (map {(["field_$_", 'FIELD', 'constant', 1] => "field_$_")} (4..7)), (map {(["method_$_", 'METHOD'] => scalar($p->reflect->getSlot("method_$_")))} (1..3)), (map {(["method_$_", 'METHOD', 'superable', 1] => scalar($p->reflect->getSlot("method_$_")))} (4..7)), (['field_d', 'FIELD', description => 'This is a friendly to use field!'], 'friendly'), (['method_d', 'METHOD', description => 'This is a friendly to use method!'], sub {}), ]]) ); my $r = $p->clone(); ok( Data::Dumper->Dump([[$p->reflect->getSlots()]]), Data::Dumper->Dump([[$r->reflect->getSlots()]]) ); eval { $p->reflect->addSlot([qw(field_fail superable)], 'val'); }; ok( $@ =~ /FIELD slots cannot have the 'superable' attribute/ ); eval { $p->reflect->addSlot([qw(field_fail promote)], 'val'); }; ok( $@ =~ /FIELD slots cannot have the 'promote' attribute/ ); eval { $p->reflect->addSlot([qw(method_fail constant)], sub {}); }; ok( $@ =~ /METHOD slots cannot have the 'constant' attribute/ ); eval { $p->reflect->addSlot([qw(method_fail promote)], sub {}); }; ok( $@ =~ /METHOD slots cannot have the 'promote' attribute/ ); eval { $p->reflect->addSlot([qw(method_fail METHOD)], 'hi there'); }; ok( $@ =~ /method slots have to have CODE refs as values/ ); eval { $p->reflect->addSlot([qw(parent_fail* constant)], $q); }; ok( $@ =~ /PARENT slots cannot have the 'constant' attribute/ ); eval { $p->reflect->addSlot([qw(parent_fail* superable)], $q); }; ok( $@ =~ /PARENT slots cannot have the 'superable' attribute/ ); eval { $p->reflect->addSlot([qw(parent_fail PARENT)], $q); }; ok( $@ =~ /slots should end in \* if and only if the type is parent/ ); eval { $p->reflect->addSlot([qw(parent_fail* FIELD)], $q); }; ok( $@ =~ /slots should end in \* if and only if the type is parent/ ); eval { $p->reflect->addSlot([qw(parent_fail* METHOD)], sub {}); }; ok( $@ =~ /slots should end in \* if and only if the type is parent/ );