use Dios;
use Test::More;

plan tests => 3;

class Typeful  {
    has         Int  $int_attr is ro : StdAll;
    has  Array[Num]  $aon_attr is ro : StdAll;

    method direct_assignment {
        ::ok  eval { $int_attr = 1;           1; } => 'Int attr assigned correctly';
        ::ok !eval { $int_attr = 'str';       1; } => 'Int attr assignment failed as expected';

        ::ok  eval { $aon_attr = [1,2,3];     1; } => 'AoN attr assigned correctly';
        ::ok !eval { $aon_attr = [1,2,'str']; 1; } => 'AoN attr assignment failed as expected';
    }
}

my $obj = Typeful->new({ int_attr => 1, aon_attr => [1,2,3]});


subtest 'int_attr tests' => sub {

    ::is $obj->get_int_attr, 1
        => 'Int attr set correctly';

    ::ok !eval{ $obj = Typeful->new({ int_attr => [] }) ; 1; }
        => 'Non-int int_attr failed as expected';

    ::ok +(eval{ $obj->set_int_attr(42) ; 1; } // diag $@)
        => 'Int set_int_attr succeeded as expected';

    ::ok !eval{ $obj->set_int_attr('a') ; 1; }
        => 'Non-int set_int_attr failed as expected';

};


subtest 'aon_attr tests' => sub {

    ::is_deeply $obj->get_aon_attr, [1,2,3] => 'aon attr set correctly';

    ::ok !eval{ $obj = Typeful->new({ int_attr => 1, aon_attr => 'a' }) ; 1; }
        => 'Non-array aon_attr failed as expected';

    ::ok !eval{ $obj = Typeful->new({ int_attr => 1, aon_attr => ['a'] }) ; 1; }
        => 'Non-num aon_attr failed as expected';

    ::ok +(eval{ $obj->set_aon_attr([1,2,3]); 1 } // diag $@)
        => 'aon set_aon_attr succeeded as expected';

    ::ok !eval{ $obj->set_aon_attr(['a']) ; 1; }
        => 'Non-num set_aon_attr failed as expected';

};

subtest 'Direct assignment' => sub {
    $obj->direct_assignment();
};

done_testing;

