Acme-FSM
view release on metacpan or search on metacpan
t/TestSuite.pm view on Meta::CPAN
=item I<$rc>
ARRAY;
storage for FSM return;
=item I<%st>
Status table;
=item I<$bb>
B<Acme::FSM> object;
An object is reZ<>B<connect>ed;
I<$bb{queue}> is created and set to empty ARRAY.
=item I<%opts>
A hash of options, those will be passed to constructor.
=back
I<STDOUT> and I<STDERR> are backed up in scalars;
those are saved in I<$main::stdout> and I<$main::stderr>.
I<STDERR> is output with B<AFSMTS_diag()> anyway.
However, it's trimmed to first 1024 bytes
(unless I<$t::TestSuite::NO_TRIM> is TRUE)
(it's not clear yet if those are 1024 bytes or characters).
Also, there's a timeout feature.
That timeout should be protected with TODO of B<Test::More>.
I<STDERR> is dumped too.
That timeout is implemented with B<alarm>ed B<eval>.
That B<eval> protects against B<die>s too.
=cut
sub AFSMTS_wrap ( ) {
open my $stdout_bak, q|>&|, \*STDOUT;
open my $stderr_bak, q|>&|, \*STDERR;
close STDOUT; open STDOUT, q|>|, \$main::stdout;
close STDERR; open STDERR, q|>|, \$main::stderr;
local $SIG{__DIE__} = sub {
alarm 0;
close STDOUT; open STDOUT, q|>&|, $stdout_bak;
close STDERR;
open STDERR, q|>&|, $stderr_bak };
do {
no warnings qw| once |;
$main::bb = Acme::FSM->connect( { %main::opts }, \%main::st ) };
$main::bb->{queue} = [ ];
my $rc = [ eval {
local $SIG{ALRM} = sub { die qq|ALRM\n| };
alarm 3;
$main::rc = [ $main::bb->process ];
alarm 0;
1 } ];
unless( @$rc ) {
# TODO:20121120224141:whynot: Make sure it's 1024 characters not bytes.
$main::stderr = substr $main::stderr || '', 0, 1024 unless $NO_TRIM;
$main::rc = [ $@ ] }
close STDERR; open STDERR, q|>&|, $stderr_bak;
close STDOUT; open STDOUT, q|>&|, $stdout_bak;
AFSMTS_diag $main::stderr }
=item B<AFSMTS_class_wrap()>
use t::Test::Suite qw/ :wraps /;
our( $rc, %st, $bb );
our( $stdout, $stderr );
AFSMTS_class_wrap @list;
Complete analogy of B<AFSMTS_wrap()> except B<process()> isn't called and
there's no timeout protection.
Also, there's I<$t::TestSuite::class_cheat>, what, if B<defined> is supposed
to be class name of B<A::F> descandant.
=cut
our $class_cheat;
sub AFSMTS_class_wrap ( @ ) {
open my $stdout_bak, q|>&|, \*STDOUT;
open my $stderr_bak, q|>&|, \*STDERR;
close STDOUT; open STDOUT, q|>|, \$main::stdout;
close STDERR; open STDERR, q|>|, \$main::stderr;
local $SIG{__DIE__} = sub {
close STDOUT; open STDOUT, q|>&|, $stdout_bak;
close STDERR; open STDERR, q|>&|, $stderr_bak;
AFSMTS_diag $main::stderr };
$main::bb = $class_cheat ?
eval qq|${class_cheat}->connect( \@_ )| :
Acme::FSM->connect( @_ );
close STDERR; open STDERR, q|>&|, $stderr_bak;
close STDOUT; open STDOUT, q|>&|, $stdout_bak;
AFSMTS_diag $main::stderr }
=item B<AFSMTS_object_wrap()>
use t::TestSuite qw/ :wraps /;
our( $rc, %st, $bb );
our( $stdout, $stderr );
AFSMTS_object_wrap $childof_A_F, @list;
Complete analogy of B<AFSMTS_wrap()> except B<process()> isn't called and
there's no timeout protection.
It's different from B<AFSMTS_class_wrap> that it goes with
object-construction.
That object goes as a first parameter, then comes list of items to process.
=cut
sub AFSMTS_object_wrap ( $@ ) {
my $obj = shift @_;
open my $stdout_bak, q|>&|, \*STDOUT;
open my $stderr_bak, q|>&|, \*STDERR;
( run in 0.539 second using v1.01-cache-2.11-cpan-7fcb06a456a )