#!/usr/bin/perl use strict; use warnings; use Test::More tests => 29; BEGIN { use_ok('MooseX::AttributeHelpers'); } package Subject; use Moose::Role; use MooseX::AttributeHelpers; has observers => ( metaclass => 'Collection::Array', is => 'ro', isa => 'ArrayRef[Observer]', auto_deref => 1, default => sub { [] }, provides => { 'push' => 'add_observer', count => 'count_observers' } ); sub notify { my ($self) = @_; foreach my $observer ( $self->observers() ) { $observer->update($self); } } ############################################################################### package Observer; use Moose::Role; requires 'update'; ############################################################################### package Counter; use Moose; use MooseX::AttributeHelpers; with 'Subject'; has count => ( metaclass => 'Counter', is => 'ro', isa => 'Int', default => 0, provides => { inc => 'inc_counter', dec => 'dec_counter', } ); after 'inc_counter','dec_counter' => sub { my ($self) = @_; $self->notify(); }; ############################################################################### package Display; use Test::More; use Moose; with 'Observer'; sub update { my ( $self, $subject ) = @_; like $subject->count, qr{^-?\d+$}, 'Observed number ' . $subject->count; } ############################################################################### package main; my $count = Counter->new(); ok($count->can('add_observer'), 'add_observer method added'); ok($count->can('count_observers'), 'count_observers method added'); ok($count->can('inc_counter'), 'inc_counter method added'); ok($count->can('dec_counter'), 'dec_counter method added'); $count->add_observer( Display->new() ); is($count->count_observers, 1, 'Only one observer'); is($count->count, 0, 'Default to zero'); $count->inc_counter; is($count->count, 1, 'Increment to one '); $count->inc_counter for (1 .. 6); is($count->count, 7, 'Increment up to seven'); $count->dec_counter; is($count->count, 6, 'Decrement to 6'); $count->dec_counter for (1 .. 5); is($count->count, 1, 'Decrement to 1'); $count->dec_counter for (1 .. 2); is($count->count, -1, 'Negative numbers'); $count->inc_counter; is($count->count, 0, 'Back to zero');