Help language development. Donate to The Perl Foundation

AttrX::Mooish cpan:VRURG last updated on 2020-03-26

t/040-errors.t6
use Test;
use AttrX::Mooish;

plan 5;
throws-like
    q<my class Foo1 { has $.bar is rw is mooish(:filter); }; Foo1.new.bar = 123; >,
    X::Method::NotFound,
    message => "No such method 'filter-bar' for invocant of type 'Foo1'",
    "missing filter method"
    ;

throws-like
    q<my class Foo1 { has $.bar is rw is mooish(:trigger); }; Foo1.new.bar = 123; >,
    X::Method::NotFound,
    message => "No such method 'trigger-bar' for invocant of type 'Foo1'",
    "missing trigger method"
    ;

subtest "Base Errors" => {
    plan 3;
    my $inst;

    throws-like q{my class Foo1 { has $.bar is mooish(:lazy(pi)); }},
            X::TypeCheck::MooishOption, "bad option value";

    my class Foo2 {
        has $.bar is mooish(:lazy);
    }

    throws-like { $inst = Foo2.new; my $v = $inst.bar; },
        X::Method::NotFound,
        message => q<No such method 'build-bar' for invocant of type 'Foo2'>,
        "missing builder";

    my class Foo4 {
        has Str $.bar is rw is mooish(:lazy) where *.starts-with("a");

        method build-bar { "default value" }
    }

    throws-like { $inst = Foo4.new; my $v = $inst.bar },
        X::TypeCheck,
        message => q<Type check failed in assignment to $!bar; expected <anon> but got Str ("default value")>,
        "value from builder don't conform 'where' constraint";

        #CATCH { note "Got exception ", $_.WHO; $_.throw}
}

subtest "Nils", {
    plan 1;

    my $inst;

    my class Foo {
        has %.foo is mooish(:lazy);

        method build-foo { }
    }

    $inst = Foo.new;

    throws-like { $inst.foo },
                X::Hash::Store::OddNumber,
                :message(rx:s/^Odd number of elements found where hash initializer expected\:/),
                "hash build returns Nil";
}

subtest "Not Allowed" => {
    plan 2;

    my class Foo {
        has $.foo is mooish(:lazy, :clearer, :filter);
        has $.bar is mooish(:lazy, :clearer, :trigger);

        method build-foo { 42 }

        method filter-foo(|) {
            self.clear-foo; # Boo!
        }

        method build-bar { pi }
        method trigger-bar(|) {
            self.clear-bar
        }
    }

    throws-like
        { my $v = Foo.new.foo; },
        X::NotAllowed,
        "clear called in a filter while building throws",
        :op<clear>,
        :cause('attribute $!foo is still building');

    throws-like
        { my $v = Foo.new.bar; },
        X::NotAllowed,
        "clear called in a trigger while building throws",
        :op<clear>,
        :cause('attribute $!bar is still building');
}

done-testing;
# vim: ft=perl6