Class-Enumeration
view release on metacpan or search on metacpan
lib/Class/Enumeration.pod view on Meta::CPAN
use warnings;
package TurnstileState;
use parent 'Class::Enumeration';
# Define list of enum objects
my @values;
sub values { no critic ( ProhibitBuiltinHomonyms )
my $ordinal = 0;
@values = map { __PACKAGE__->_new( $ordinal++, $_ ) } qw( Locked Unlocked )
unless @values;
@values
}
1
=head1 CAVEAT
This class is abstract. It defines and partially implements the API
of enum classes. It should not be used directly. You should use the
t/TurnstileState.t view on Meta::CPAN
plan tests => 10;
for my $self ( $class->values ) {
note my $name = $self->name;
cmp_ok "$self", 'eq', $name, 'Check default stringification';
isa_ok $self, $class;
isa_ok $self, 'Class::Enumeration';
cmp_ok $self, '==', $class->value_of( $self->name ), 'Get enum object reference by name'
}
is_deeply [ $class->names ], [ qw( Locked Unlocked ) ], 'Get names of enum objects';
dies_ok { $class->value_of( 'Initial' ) } 'No such enum object for the given name'
};
subtest 'Access enum attributes' => sub {
plan tests => 4;
my $self = $class->value_of( 'Locked' );
cmp_ok $self->name, 'eq', 'Locked', 'Get name';
cmp_ok $self->ordinal, '==', 0, 'Get ordinal';
$self = $class->value_of( 'Unlocked' );
cmp_ok $self->name, 'eq', 'Unlocked', 'Get name';
cmp_ok $self->ordinal, '==', 1, 'Get ordinal'
}
t/TurnstileStateMachine.t view on Meta::CPAN
plan tests => 10;
for my $self ( $class->values ) {
note my $name = $self->name;
cmp_ok "$self", 'eq', $name, 'Check default stringification';
isa_ok $self, $class;
isa_ok $self, 'Class::Enumeration';
cmp_ok $self, '==', $class->value_of( $self->name ), 'Get enum object reference by name'
}
is_deeply [ $class->names ], [ qw( Locked Unlocked ) ], 'Get names of enum objects';
dies_ok { $class->value_of( 'Initial' ) } 'No such enum object for the given name'
};
subtest 'Access enum attributes' => sub {
plan tests => 4;
my $self = $class->value_of( 'Locked' );
cmp_ok $self->name, 'eq', 'Locked', 'Get name';
cmp_ok $self->ordinal, '==', 0, 'Get ordinal';
$self = $class->value_of( 'Unlocked' );
cmp_ok $self->name, 'eq', 'Unlocked', 'Get name';
cmp_ok $self->ordinal, '==', 1, 'Get ordinal'
};
subtest 'Trigger state transitions' => sub {
plan tests => 7;
# Set initial state
isa_ok my $state = Locked, $class;
dies_ok { $state->do_something( 'foo' ) } 'Wrong input';
cmp_ok $state->do_something( 'push' ), '==', Locked, 'Still locked';
cmp_ok $state->do_something( 'coin' ), '==', Unlocked, 'Now unlocked';
dies_ok { $state->do_something( 'foo' ) } 'Wrong input';
cmp_ok $state->do_something( 'coin' ), '==', Unlocked, 'Still unlocked';
cmp_ok $state->do_something( 'push' ), '==', Locked, 'Locked again'
}
t/lib/TurnstileState.pm view on Meta::CPAN
package TurnstileState;
# On purpose do not use Class::Enumeration::Builder
use parent 'Class::Enumeration';
my @values;
sub values { ## no critic ( ProhibitBuiltinHomonyms )
unless ( @values ) {
my $ordinal = 0;
@values = map { __PACKAGE__->_new( $ordinal++, $_ ) } qw( Locked Unlocked )
}
@values
}
1
t/lib/TurnstileStateMachine.pm view on Meta::CPAN
## no critic ( ProhibitMultiplePackages )
use strict;
use warnings;
# https://en.wikipedia.org/wiki/Finite-state_machine
package TurnstileStateMachine;
use Exporter qw( import );
use Class::Enumeration::Builder { export => 1 }, qw( Locked Unlocked );
package TurnstileStateMachine::Locked;
use Carp qw( croak );
sub do_something {
my ( $self, $input ) = @_;
return __PACKAGE__->value_of( 'Unlocked' ) if $input eq 'coin';
return $self if $input eq 'push';
croak "Wrong input '$input', stooped";
}
package TurnstileStateMachine::Unlocked;
use Carp qw( croak );
sub do_something {
my ( $self, $input ) = @_;
return __PACKAGE__->value_of( 'Locked' ) if $input eq 'push';
return $self if $input eq 'coin';
croak "Wrong input '$input', stooped";
}
( run in 1.087 second using v1.01-cache-2.11-cpan-39bf76dae61 )