### ----------------------------------------------------
### -- Test::Describe
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Correa de Oliveira <fernandocorrea@gmail.com>
### -- File: t/01-basic.rakutest
### ----------------------------------------------------
#!/usr/bin/env raku

use Test::Describe;

shared-example "first-example", {
    it "testing first example", { .&expect.to: be-eq 42 }
}

describe Int, {
    define "bla", 42;
    define "ble", { 13 };

    it-behaves-like "first-example", :42subject;

    it "ble", -> :$bla, :&ble {
        is $bla, 42;
        ok ble
    }

    it "bli", -> :&ble {
        ok ble
    }

    describe "Int again", {
        it "bli", -> :&ble {
            ok ble
        }
    }

    describe 42, {
        it "is not prime", {
            .&expect.to: be(42);
            expect(.is-prime).to: be-false;
        }
    }

    describe "matchers", {
        it "be-eq", {
            expect(42).to: be-eq 42;
            expect(42).not-to: be-eq 13;
        }
        context "change", {
            it "var", {
                my $a = 42;
                expect({ $a = 13 }).to: change $a
            }
            it "not var", {
                my $a = 42;
                expect({ $a = 42 }).not-to: change $a
            }
            it "var", {
                my $a = 42;
                expect({ $a = 13 }).to: change $a, "is-prime"
            }
            it "not var", {
                my $a = 42;
                expect({ $a = 42 }).not-to: change $a, "is-prime"
            }
        }
        it "has method", {
            expect(Int).to: have-method("is-prime")
        }
    }

    describe "Int once more", {
        define "bla", 3.14;
        define "bli", 111;
        it "bli", -> :$bla, :$*bli {
            is $bla, 3.14;
            test-bli
        }
    }

    describe "define chain", {
        define multiple-v => -> Str :$v, Int :$n { $v x $n }
        define v => "bla", n => 5;

        it "default", -> :$v, :$n, :&multiple-v {
            expect($v).to: be-str-eq "bla";
            expect($n).to: be-eq 5;
            expect(multiple-v).to: be-str-eq "blablablablabla";
        }

        it "dynamic", -> :&multiple-v {
            expect(multiple-v :v<ble>).to: be-str-eq "blebleblebleble";
            expect(multiple-v :2n).to: be-str-eq "blabla";
            expect(multiple-v :v<ble>, :2n).to: be-str-eq "bleble";
        }

        context "change v", {
            define v => "a";
            it -> :&multiple-v {
                expect(multiple-v).to: be-str-eq "aaaaa";
            }
        }

        context "change n", {
            define n => 3;
            it -> :&multiple-v {
                expect(multiple-v).to: be-str-eq "blablabla";
            }
        }

        context "change both", {
            define v => "a", n => 3;
            it -> :&multiple-v {
                expect(multiple-v).to: be-str-eq "aaa";
            }
        }

        it "default", {
            expect($:v).to: be-str-eq "bla";
            expect($:n).to: be-eq 5;
            expect(&:multiple-v()).to: be-str-eq "blablablablabla";
        }

        it "dynamic", {
            expect(&:multiple-v(:v<ble>)).to: be-str-eq "blebleblebleble";
            expect(&:multiple-v(:2n)).to: be-str-eq "blabla";
            expect(&:multiple-v(:v<ble>, :2n)).to: be-str-eq "bleble";
        }

        context "change v", {
            define "v", "a";
            it {
                expect(&:multiple-v()).to: be-str-eq "aaaaa";
            }
        }

        context "change n", {
            define "n", 3;
            it {
                expect(&:multiple-v()).to: be-str-eq "blablabla";
            }
        }

        context "change both", {
            define "v", "a";
            define "n", 3;
            it {
                expect(&:multiple-v()).to: be-str-eq "aaa";
            }
        }

        context { $:v x $:n }, {
            it {
                .().&expect.to: be-str-eq "blablablablabla";
                .(:v<a>).&expect.to: be-str-eq "aaaaa";
                .(:2n).&expect.to: be-str-eq "blabla";
                .(:v<e>, :3n).&expect.to: be-str-eq "eee";
            }
        }
    }
}

sub test-bli {
    is $*bli, 111
}


