1898184e3Ssthenpackage TAP::Parser::SourceHandler; 2898184e3Ssthen 3898184e3Ssthenuse strict; 46fb12b70Safresh1use warnings; 5898184e3Ssthen 6898184e3Ssthenuse TAP::Parser::Iterator (); 76fb12b70Safresh1use base 'TAP::Object'; 8898184e3Ssthen 9898184e3Ssthen=head1 NAME 10898184e3Ssthen 11898184e3SsthenTAP::Parser::SourceHandler - Base class for different TAP source handlers 12898184e3Ssthen 13898184e3Ssthen=head1 VERSION 14898184e3Ssthen 15*3d61058aSafresh1Version 3.48 16898184e3Ssthen 17898184e3Ssthen=cut 18898184e3Ssthen 19*3d61058aSafresh1our $VERSION = '3.48'; 20898184e3Ssthen 21898184e3Ssthen=head1 SYNOPSIS 22898184e3Ssthen 23898184e3Ssthen # abstract class - don't use directly! 24898184e3Ssthen # see TAP::Parser::IteratorFactory for general usage 25898184e3Ssthen 26898184e3Ssthen # must be sub-classed for use 27898184e3Ssthen package MySourceHandler; 286fb12b70Safresh1 use base 'TAP::Parser::SourceHandler'; 29898184e3Ssthen sub can_handle { return $confidence_level } 30898184e3Ssthen sub make_iterator { return $iterator } 31898184e3Ssthen 32898184e3Ssthen # see example below for more details 33898184e3Ssthen 34898184e3Ssthen=head1 DESCRIPTION 35898184e3Ssthen 36898184e3SsthenThis is an abstract base class for L<TAP::Parser::Source> handlers / handlers. 37898184e3Ssthen 38898184e3SsthenA C<TAP::Parser::SourceHandler> does whatever is necessary to produce & capture 39898184e3Ssthena stream of TAP from the I<raw> source, and package it up in a 40898184e3SsthenL<TAP::Parser::Iterator> for the parser to consume. 41898184e3Ssthen 42898184e3SsthenC<SourceHandlers> must implement the I<source detection & handling> interface 43898184e3Ssthenused by L<TAP::Parser::IteratorFactory>. At 2 methods, the interface is pretty 44898184e3Ssthensimple: L</can_handle> and L</make_source>. 45898184e3Ssthen 46898184e3SsthenUnless you're writing a new L<TAP::Parser::SourceHandler>, a plugin, or 47898184e3Ssthensubclassing L<TAP::Parser>, you probably won't need to use this module directly. 48898184e3Ssthen 49898184e3Ssthen=head1 METHODS 50898184e3Ssthen 51898184e3Ssthen=head2 Class Methods 52898184e3Ssthen 53898184e3Ssthen=head3 C<can_handle> 54898184e3Ssthen 55898184e3SsthenI<Abstract method>. 56898184e3Ssthen 57898184e3Ssthen my $vote = $class->can_handle( $source ); 58898184e3Ssthen 59898184e3SsthenC<$source> is a L<TAP::Parser::Source>. 60898184e3Ssthen 61898184e3SsthenReturns a number between C<0> & C<1> reflecting how confidently the raw source 62898184e3Ssthencan be handled. For example, C<0> means the source cannot handle it, C<0.5> 63898184e3Ssthenmeans it may be able to, and C<1> means it definitely can. See 64898184e3SsthenL<TAP::Parser::IteratorFactory/detect_source> for details on how this is used. 65898184e3Ssthen 66898184e3Ssthen=cut 67898184e3Ssthen 68898184e3Ssthensub can_handle { 69898184e3Ssthen my ( $class, $args ) = @_; 70898184e3Ssthen $class->_croak( 71898184e3Ssthen "Abstract method 'can_handle' not implemented for $class!"); 72898184e3Ssthen return; 73898184e3Ssthen} 74898184e3Ssthen 75898184e3Ssthen=head3 C<make_iterator> 76898184e3Ssthen 77898184e3SsthenI<Abstract method>. 78898184e3Ssthen 79898184e3Ssthen my $iterator = $class->make_iterator( $source ); 80898184e3Ssthen 81898184e3SsthenC<$source> is a L<TAP::Parser::Source>. 82898184e3Ssthen 83898184e3SsthenReturns a new L<TAP::Parser::Iterator> object for use by the L<TAP::Parser>. 84898184e3SsthenC<croak>s on error. 85898184e3Ssthen 86898184e3Ssthen=cut 87898184e3Ssthen 88898184e3Ssthensub make_iterator { 89898184e3Ssthen my ( $class, $args ) = @_; 90898184e3Ssthen $class->_croak( 91898184e3Ssthen "Abstract method 'make_iterator' not implemented for $class!"); 92898184e3Ssthen return; 93898184e3Ssthen} 94898184e3Ssthen1; 95898184e3Ssthen 96898184e3Ssthen__END__ 97898184e3Ssthen 98898184e3Ssthen=head1 SUBCLASSING 99898184e3Ssthen 100898184e3SsthenPlease see L<TAP::Parser/SUBCLASSING> for a subclassing overview, and any 101898184e3Ssthenof the subclasses that ship with this module as an example. What follows is 102898184e3Ssthena quick overview. 103898184e3Ssthen 104898184e3SsthenStart by familiarizing yourself with L<TAP::Parser::Source> and 105898184e3SsthenL<TAP::Parser::IteratorFactory>. L<TAP::Parser::SourceHandler::RawTAP> is 1066fb12b70Safresh1the easiest sub-class to use as an example. 107898184e3Ssthen 108898184e3SsthenIt's important to point out that if you want your subclass to be automatically 109898184e3Ssthenused by L<TAP::Parser> you'll have to and make sure it gets loaded somehow. 110898184e3SsthenIf you're using L<prove> you can write an L<App::Prove> plugin. If you're 111898184e3Ssthenusing L<TAP::Parser> or L<TAP::Harness> directly (e.g. through a custom script, 112898184e3SsthenL<ExtUtils::MakeMaker>, or L<Module::Build>) you can use the C<config> option 113898184e3Ssthenwhich will cause L<TAP::Parser::IteratorFactory/load_sources> to load your 114898184e3Ssthensubclass). 115898184e3Ssthen 116898184e3SsthenDon't forget to register your class with 117898184e3SsthenL<TAP::Parser::IteratorFactory/register_handler>. 118898184e3Ssthen 119898184e3Ssthen=head2 Example 120898184e3Ssthen 121898184e3Ssthen package MySourceHandler; 122898184e3Ssthen 123898184e3Ssthen use strict; 124898184e3Ssthen 125898184e3Ssthen use MySourceHandler; # see TAP::Parser::SourceHandler 126898184e3Ssthen use TAP::Parser::IteratorFactory; 127898184e3Ssthen 1286fb12b70Safresh1 use base 'TAP::Parser::SourceHandler'; 129898184e3Ssthen 130898184e3Ssthen TAP::Parser::IteratorFactory->register_handler( __PACKAGE__ ); 131898184e3Ssthen 132898184e3Ssthen sub can_handle { 133898184e3Ssthen my ( $class, $src ) = @_; 134898184e3Ssthen my $meta = $src->meta; 135898184e3Ssthen my $config = $src->config_for( $class ); 136898184e3Ssthen 137898184e3Ssthen if ($config->{accept_all}) { 138898184e3Ssthen return 1.0; 139898184e3Ssthen } elsif (my $file = $meta->{file}) { 140898184e3Ssthen return 0.0 unless $file->{exists}; 141898184e3Ssthen return 1.0 if $file->{lc_ext} eq '.tap'; 142898184e3Ssthen return 0.9 if $file->{shebang} && $file->{shebang} =~ /^#!.+tap/; 143898184e3Ssthen return 0.5 if $file->{text}; 144898184e3Ssthen return 0.1 if $file->{binary}; 145898184e3Ssthen } elsif ($meta->{scalar}) { 146898184e3Ssthen return 0.8 if $$raw_source_ref =~ /\d\.\.\d/; 147898184e3Ssthen return 0.6 if $meta->{has_newlines}; 148898184e3Ssthen } elsif ($meta->{array}) { 149898184e3Ssthen return 0.8 if $meta->{size} < 5; 150898184e3Ssthen return 0.6 if $raw_source_ref->[0] =~ /foo/; 151898184e3Ssthen return 0.5; 152898184e3Ssthen } elsif ($meta->{hash}) { 153898184e3Ssthen return 0.6 if $raw_source_ref->{foo}; 154898184e3Ssthen return 0.2; 155898184e3Ssthen } 156898184e3Ssthen 157898184e3Ssthen return 0; 158898184e3Ssthen } 159898184e3Ssthen 160898184e3Ssthen sub make_iterator { 161898184e3Ssthen my ($class, $source) = @_; 162898184e3Ssthen # this is where you manipulate the source and 163898184e3Ssthen # capture the stream of TAP in an iterator 164898184e3Ssthen # either pick a TAP::Parser::Iterator::* or write your own... 165898184e3Ssthen my $iterator = TAP::Parser::Iterator::Array->new([ 'foo', 'bar' ]); 166898184e3Ssthen return $iterator; 167898184e3Ssthen } 168898184e3Ssthen 169898184e3Ssthen 1; 170898184e3Ssthen 171898184e3Ssthen=head1 AUTHORS 172898184e3Ssthen 173898184e3SsthenTAPx Developers. 174898184e3Ssthen 175898184e3SsthenSource detection stuff added by Steve Purkis 176898184e3Ssthen 177898184e3Ssthen=head1 SEE ALSO 178898184e3Ssthen 179898184e3SsthenL<TAP::Object>, 180898184e3SsthenL<TAP::Parser>, 181898184e3SsthenL<TAP::Parser::Source>, 182898184e3SsthenL<TAP::Parser::Iterator>, 183898184e3SsthenL<TAP::Parser::IteratorFactory>, 184898184e3SsthenL<TAP::Parser::SourceHandler::Executable>, 185898184e3SsthenL<TAP::Parser::SourceHandler::Perl>, 186898184e3SsthenL<TAP::Parser::SourceHandler::File>, 187898184e3SsthenL<TAP::Parser::SourceHandler::Handle>, 188898184e3SsthenL<TAP::Parser::SourceHandler::RawTAP> 189898184e3Ssthen 190898184e3Ssthen=cut 191898184e3Ssthen 192