### ----------------------------------------------------
### -- Test::Describe
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Correa de Oliveira <fernandocorrea@gmail.com>
### -- File: t/04-change.rakutest
### ----------------------------------------------------
use Test::Describe::Match::Change;
use Test::Describe;

describe Test::Describe::Match::Change, {
    define from        => 1;
    define to          => 2;
    context "using \$value as value", {
        my $value;
        define new         => { $:described-class.new: :$value }
        define new-from    => { $:described-class.new(:$value).from: $:from }
        define new-from-to => { $:described-class.new(:$value).from($:from).to: $:to }
        before { $value = 1 }

        it ".new", -> :&new, :$described-class {
            expect(new).to: be-of-type $described-class;
            expect(new.value.()).to: be $value
        }

        it ".new.test no change", -> :&new {
            expect(new.test.({;})).to: be-false;
            expect(new.msg.({;})).to: be "\$value has not changed";
        }

        it ".new.test change", -> :&new {
            expect(new.test.({ $value++ })).to: be-true;
            expect(new.hint.({;})).to:
                smart-match(/:s "from" ":" "1"/)
                .and: smart-match(/:s "to" ":" "2"/)
            ;
        }

        it ".new.from.test no change", -> :new-from(&new) {
            expect(new.test.({;})).to: be-false;
            expect(new.msg.({;})).to: be "\$value has not changed";
        }

        it ".new.from.test change", -> :new-from(&new) {
            expect(new.test.({ $value++ })).to: be-true;
            expect(new.hint.({;})).to:
                smart-match(/:s "from" ":" "1"/)
                .and: smart-match(/:s "to" ":" "2"/)
            ;
        }

        it ".new.from.test wrong from", -> :new-from(&new) {
            $value++;
            expect(new.test.({ $value++ })).to: be-false;
            expect(new.msg.({;})).to: be "\$value wasn't 1 before changing";
            #expect(new.hint.({;})).to:
            #    smart-match(/:s "from" ":" "2"/)
            #    .and: smart-match(/:s "to" ":" "3"/)
            #;
        }

        it ".new.from.to.test no change", -> :new-from-to(&new) {
            expect(new.test.({;})).to: be-false;
            expect(new.msg.({;})).to: be "\$value has not changed";
        }

        it ".new.from.to.test change", -> :new-from-to(&new) {
            expect(new.test.({ $value++ })).to: be-true;
            expect(new.hint.({;})).to:
                smart-match(/:s "from" ":" "1"/)
                .and: smart-match(/:s "to" ":" "2"/)
            ;
        }

        it ".new.from.to.test wrong from", -> :new-from-to(&new) {
            $value++;
            expect(new.test.({ $value++ })).to: be-false;
            expect(new.msg.({;})).to: be "\$value wasn't 1 before changing";
            expect(new.hint.({;})).to:
                smart-match(/:s "from" ":" "1"/)
                .and: smart-match(/:s "to" ":" "2"/)
            ;
        }

        it ".new.from.to.test wrong to", -> :new-from-to(&new) {
            expect(new.test.({ $value += 2 })).to: be-false;
            expect(new.msg.({;})).to: be "\$value wasn't 2 after changing";
            expect(new.hint.({;})).to:
                smart-match(/:s "from" ":" "1"/)
                .and: smart-match(/:s "to" ":" "2"/)
            ;
        }
    }

    context "using \$another-value as value", {
        my $another-value;
        define new => { $:described-class.new: :value($another-value) }
        before { $another-value = 1 }

        it ".new.test no change", -> :&new {
            expect(new.test.({;})).to: be-false;
            expect(new.msg.({;})).to: be "\$another-value has not changed";
        }
    }

    context "using \$an-obj.attr as value", {
        my $an-obj;
        define new => { $:described-class.new: :value($an-obj), :attr<is-prime> }
        before { $an-obj = 3 }

        it ".new.test no change", -> :&new {
            expect(new.test.({;})).to: be-false;
            expect(new.msg.({;})).to: be "\$an-obj.is-prime has not changed";
        }
    }
}


