FSA-Rules

 view release on metacpan or  search on metacpan

t/base.t  view on Meta::CPAN

is $fsa->{foo}, 1, "... The code should now have been executed";
eval { $fsa->start };
ok $err = $@, '... Calling start on a running machine should die';
like $err, qr/Cannot start machine because it is already running/,
  '... And it should throw the proper exception';

# Try start() with a second state.
ok $fsa = $CLASS->new(
    foo => {
        do => sub { shift->machine->{foo}++ }
    },
    bar => {
        do => sub { shift->machine->{bar}++ }
    },
), "Construct with a single state with an enter action";

is $fsa->curr_state, undef, "... The current state should be undefined";
is $fsa->{foo}, undef, "... The 'foo' code should not have been executed";
is $fsa->{bar}, undef, "... The 'bar' code should not have been executed";
ok $state = $fsa->start, "... The start method should return the start state";
isa_ok $state, 'FSA::State';
is $state->name, 'foo', "... The name of the current state should be 'foo'";
is $fsa->curr_state, $state, "... The current state should be 'foo'";
is $fsa->{foo}, 1, "... The code should now have been executed";
is $fsa->{bar}, undef, "... The 'bar' code still should not have been executed";

# Try a bad switch state name.
eval {
    $CLASS->new(
        foo => { rules => [bad => 1] }
    )
};

ok $err = $@, "A bad state name in rules should fail";
like $err, qr/Unknown state "bad" referenced by state "foo"/,
  "... And give the appropriate error message";

# Try numbered states.
ok $fsa = $CLASS->new(
    0 => { rules => [ 1 => 1 ] },
    1 => {},
), "Construct with numbered states";
ok $state = $fsa->start, "... Call to start() should return state '0'";
isa_ok $state, 'FSA::State';
is $state->name, 0, "... The name of the current state should be '0'";
is $fsa->curr_state, $state, "... The current state should be '0'";

ok $state = $fsa->switch, "... Call to switch should return '1' state";
isa_ok $state, 'FSA::State';
is $state->name, 1, "... The name of the current state should be '1'";
is $fsa->curr_state, $state, "... The current state should be '1'";

# Try run().
ok $fsa = $CLASS->new(
    0 => { rules => [ 1 => [ 1, sub { shift->machine->{count}++ } ] ] },
    1 => { rules => [ 0 => [ 1, sub { $_[0]->done($_[0]->machine->{count} == 3 ) } ] ] },
), "Construct with simple states to run";

is $fsa->run, $fsa, "... Run should return the FSA object";
is $fsa->{count}, 3,
  "... And it should have run through the proper number of iterations.";
# Reset and try again.
$fsa->{count} = 0;
is $fsa->done(0), $fsa, "... We should be able to reset done";
ok $state = $fsa->curr_state,  "... We should be left in state '0'";
isa_ok $state, 'FSA::State';
is $state->name, 0, "... The name of the current state should be '0'";
is $fsa->run, $fsa, "... Run should still work.";
is $fsa->{count}, 3,
  "... And it should have run through the proper number of again.";

# Try done with a code refernce.
ok $fsa = $CLASS->new(
    0 => { rules => [ 1 => [ 1, sub { shift->machine->{count}++ } ] ] },
    1 => { rules => [ 0 => [ 1 ] ] },
), "Construct with simple states to test a done code ref";


is $fsa->done( sub { shift->{count} == 3 }), $fsa,
  "Set done to a code reference";
$fsa->{count} = 0;
is $fsa->run, $fsa, "... Run should still work.";
is $fsa->{count}, 3,
  "... And it should have run through the proper number of again.";

# Check for duplicate states.
eval { $CLASS->new( foo => {}, foo => {}) };
ok $err = $@, 'Attempt to specify the same state twice should throw an error';
like $err, qr/The state "foo" already exists/,
  '... And that exception should have the proper message';

# Try try_switch with parameters.
my %prevs = ( 1 => 'foo', 2 => 'bar');
ok $fsa = $CLASS->new(
    foo => {
        do => sub { shift->notes(test => 'foo') },
        rules => [
            bar => [ sub { $_[1]  eq 'bar' } ],
            foo => [ sub { $_[1]  eq 'foo' } ],
        ]
    },
    bar => {
        do => sub {
            my $state = shift;
            isa_ok $state->prev_state, 'FSA::State',
              "...state->prev_state should return a state object";
            is $state->prev_state->name, $prevs{++$state->{count}},
              "... state->prev_state should return the previous state";
        },
        rules => [
            foo => [ sub { $_[1]  eq 'foo' } ],
            bar => [ sub { $_[1]  eq 'bar' } ],
        ]
    }
), 'Construct with switch rules that expect parameters.';


ok my $foo = $fsa->start, "... It should start with 'foo'";
isa_ok $foo, 'FSA::State';
is $foo->name, 'foo', "... The name of the current state should be 'foo'";
is $fsa->curr_state, $foo, "... The current state should be 'foo'";



( run in 1.282 second using v1.01-cache-2.11-cpan-71847e10f99 )