### ----------------------------------------------------
### -- Method::Protected
### -- Licenses: Artistic-2.0
### -- Authors: Elizabeth Mattijsen
### -- File: t/01-basic.rakutest
### ----------------------------------------------------
use Test;
use Method::Protected;

plan 4;

my @words = "a" … "zzz";

class Frobnicate {
    has %!hash;
    method pick() is protected { %!hash{@words.pick}++ }
    method hash() is protected { %!hash.clone          }
}

# Set up 3 threads massively updating a single hash
my $frobnicator = Frobnicate.new;
start { loop { $frobnicator.pick } }
start { loop { $frobnicator.pick } }
start { loop { $frobnicator.pick } }

# Wait until all words have been done at least once, without
# eating away all CPU
sleep .1 until $frobnicator.hash.elems == @words.elems;

pass "Survived hammering a hash with Frobnicate";

class Grabonize {
    has %!hash;
    proto method pick(|) is protected {*}
    multi method pick(Int) { %!hash{@words.pick}++ }
    multi method pick(Str) { %!hash{@words.pick}++ }
    multi method pick(Rat) { %!hash{@words.pick}++ }
    method it(str $key) is raw is protected { %!hash{$key} }
    method hash() is protected { %!hash.clone }
}

# Set up 3 threads massively updating a single hash
my $grabonizer = Grabonize.new;
start { loop { $grabonizer.pick(42)    } }
start { loop { $grabonizer.pick("foo") } }
start { loop { $grabonizer.pick(1.37)  } }

# Wait until all words have been done at least once, without
# eating away all CPU
sleep .1 until $grabonizer.hash.elems == @words.elems;

pass "Survived hammering a hash with Grabonize";

# Test containers on protected methods
my $value = $grabonizer.it("zzz")++;
is $grabonizer.it("zzz"), $value + 1, 'can we increment';

# Make sure adequate message when applied to methods in roles
throws-like { 'role A { method b is protected { } }'.EVAL },
  X::AdHoc,
  message => "Cannot apply 'is protected' to method 'b' in a role";

# vim: expandtab shiftwidth=4


