in reply to Strange CPANTS report

Bio::Phylo::IO::parse() is the subroutine that is FAILing. There's a lot going on in this subroutine. For example, I counted 8 different error messages that could be thrown in the course of calling the function:

sub parse { if ( $_[0] and $_[0] eq __PACKAGE__ or ref $_[0] eq __PACKAGE__ ) +{ shift; } my %opts; if ( ! @_ || scalar @_ % 2 ) { Bio::Phylo::Exceptions::OddHash->throw( error => 'Odd number of elements in hash assignment' ); } eval { %opts = @_; }; if ( $@ ) { Bio::Phylo::Exceptions::OddHash->throw( error => $@ ); } if ( ! $opts{'-format'} ) { Bio::Phylo::Exceptions::BadArgs->throw( error => 'no format specified.' ); } if ( ! grep ucfirst $opts{'-format'}, @parsers ) { Bio::Phylo::Exceptions::BadFormat->throw( error => 'no parser available for specified format.' ); } if ( ! $opts{'-file'} && ! $opts{'-string'} ) { Bio::Phylo::Exceptions::BadArgs->throw( error => 'no parseable data source specified.' ); } my $lib = 'Bio::Phylo::Parsers::' . ucfirst $opts{-format}; eval "require $lib"; if ( $@ ) { Bio::Phylo::Exceptions::ExtensionError->throw( error => $@ ); } my $parser = $lib->_new; if ( $opts{-file} && $parser->can('_from_handle') ) { eval { open FH, '<', $opts{-file}; }; if ( $! ) { Bio::Phylo::Exceptions::FileError->throw( error => $! ); } $opts{-handle} = *FH; return $parser->_from_handle(%opts); } elsif ( $opts{-string} && $parser->can('_from_string') ) { return $parser->_from_string(%opts); } elsif ( $opts{-string} && ! $parser->can('_from_string') ) { Bio::Phylo::Exceptions::BadArgs->throw( error => "$opts{-format} parser can't handle strings" ); } }

Your documentation says,

The parse method makes assumptions about the capabilities of Bio::Phylo::Parsers::* modules .... Exceptions are thrown if either assumption is violated.

If so, then the approach you should consider in testing parse() is to relax each of those eight assumptions in turn, allow the function to die inside an eval block, capture the error message and compare it with Test::More::like() to the error message you expect to receive.

Your documentation further states that parse() returns an object of the appropriate Bio::Phylo::* class. If so, then the final test called on the function should probably be done with Test::More::isa_ok() rather than merely ok().

But before writing all these tests, I'd recommend thinking about simplifying the structure of Bio::Phylo::IO::parse(). If it were simpler, it would be easier to test and it would be easier for you to isolate the cause of the failure on the cpan.tester's box.

Jim Keenan

Replies are listed 'Best First'.
Re^2: Strange CPANTS report
by rvosa (Curate) on Oct 04, 2005 at 20:20 UTC
    Yes, you're right, that method could definitely use some simplification. It sort of grew organically, so now it's time for some pruning. I'm not sure if it's necessarily the cause of the errors on imacat's machine, but some refactoring will certainly aid in tracking down whatever is causing build fails in the next release.

    Incidentally, thanks a lot for taking this so seriously, digging into the code, reading the docs - I really appreciate it.