1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#!/usr/bin/perl
use v5.14;
use warnings;
use Test2::V0;
use Scalar::Util qw( refaddr );
use Struct::Dumb;
struct Point => [qw( x y )];
my $point = Point(10, 20);
ok( ref $point, '$point is a ref' );
isa_ok( $point, 'Struct::Dumb::Struct' );
can_ok( $point, "x" );
is( $point->x, 10, '$point->x is 10' );
$point->y = 30;
is( $point->y, 30, '$point->y is 30 after mutation' );
like( dies { $point->z },
qr/^main::Point does not have a 'z' field at \S+ line \d+\.?\n/,
'$point->z throws exception' );
like( dies { $point->z = 40 },
qr/^main::Point does not have a 'z' field at \S+ line \d+\.?\n/,
'$point->z :lvalue throws exception' );
like( dies { Point(30) },
qr/^usage: main::Point\(\$x, \$y\) at \S+ line \d+\.?\n/,
'Point(30) throws usage exception' );
like( dies { @{ Point(0, 0) } },
qr/^Cannot use main::Point as an ARRAY reference at \S+ line \d+\.?\n/,
'Array deref throws exception' );
SKIP: {
skip "Instances are not ARRAYs", 1 unless Scalar::Util::reftype( Point(1, 1) ) eq "ARRAY";
ok( !( local $@ = dies {
no warnings 'redefine';
local *Point::_forbid_arrayification = sub {};
@{ Point(2, 2) };
} ),
'Array deref succeeds with locally-overridden forbid function' ) or
diag( "Exception was $@" );
}
like( dies { $point->x(50) },
qr/^main::Point->x invoked with arguments at \S+ line \d+\.?\n/,
'Accessor with arguments throws exception' );
ok( !( local $@ = dies { !! Point(0, 0) } ),
'Point is boolean true' ) or diag( "Exception was $@" );
is( $point + 0, refaddr $point,
'Point numifies to its reference address' );
like( "$point", qr/^main::Point=Struct::Dumb\(0x[0-9a-fA-F]+\)$/,
'Point stringifies to something sensible' );
is( Struct::Dumb::dumper_info( $point ),
{
named => F(),
fields => [qw( x y )],
values => [ 10, 30 ],
},
'Struct::Dumb::dumper_info returns metadata and field values' );
done_testing;
|