```{index} single: TAP::Parser::SourceHandler ``` # TAP::Parser::SourceHandler Base class for different TAP source handlers ## VERSION Version 3.52 ## SYNOPSIS ```perl ## abstract class - don't use directly! ## see TAP::Parser::IteratorFactory for general usage ## must be sub-classed for use package MySourceHandler; use base 'TAP::Parser::SourceHandler'; sub can_handle { return $confidence_level } sub make_iterator { return $iterator } ## see example below for more details ``` ## DESCRIPTION This is an abstract base class for [TAP::Parser::Source](Source.md) handlers / handlers. A `TAP::Parser::SourceHandler` does whatever is necessary to produce & capture a stream of TAP from the _raw_ source, and package it up in a [TAP::Parser::Iterator](Iterator.md) for the parser to consume. `SourceHandlers` must implement the _source detection & handling_ interface used by [TAP::Parser::IteratorFactory](IteratorFactory.md). At 2 methods, the interface is pretty simple: "can\_handle" and "make\_source". Unless you're writing a new [TAP::Parser::SourceHandler](SourceHandler.md), a plugin, or subclassing [TAP::Parser](../Parser.md), you probably won't need to use this module directly. ## METHODS ### Class Methods #### `can_handle` _Abstract method_. ```perl my $vote = $class->can_handle( $source ); ``` `$source` is a [TAP::Parser::Source](Source.md). Returns a number between `0` & `1` reflecting how confidently the raw source can be handled. For example, `0` means the source cannot handle it, `0.5` means it may be able to, and `1` means it definitely can. See ["detect\_source" in TAP::Parser::IteratorFactory](IteratorFactory.md) for details on how this is used. #### `make_iterator` _Abstract method_. ```perl my $iterator = $class->make_iterator( $source ); ``` `$source` is a [TAP::Parser::Source](Source.md). Returns a new [TAP::Parser::Iterator](Iterator.md) object for use by the [TAP::Parser](../Parser.md). `croak`s on error. ## SUBCLASSING Please see ["SUBCLASSING" in TAP::Parser](../Parser.md) for a subclassing overview, and any of the subclasses that ship with this module as an example. What follows is a quick overview. Start by familiarizing yourself with [TAP::Parser::Source](Source.md) and [TAP::Parser::IteratorFactory](IteratorFactory.md). [TAP::Parser::SourceHandler::RawTAP](SourceHandler/RawTAP.md) is the easiest sub-class to use as an example. It's important to point out that if you want your subclass to be automatically used by [TAP::Parser](../Parser.md) you'll have to and make sure it gets loaded somehow. If you're using [prove](https://metacpan.org/pod/prove) you can write an [App::Prove](../../App/Prove.md) plugin. If you're using [TAP::Parser](../Parser.md) or [TAP::Harness](../Harness.md) directly (e.g. through a custom script, [ExtUtils::MakeMaker](../../ExtUtils/MakeMaker.md), or [Module::Build](https://metacpan.org/pod/Module::Build)) you can use the `config` option which will cause ["load\_sources" in TAP::Parser::IteratorFactory](IteratorFactory.md) to load your subclass). Don't forget to register your class with ["register\_handler" in TAP::Parser::IteratorFactory](IteratorFactory.md). ### Example ```perl package MySourceHandler; use strict; use MySourceHandler; # see TAP::Parser::SourceHandler use TAP::Parser::IteratorFactory; use base 'TAP::Parser::SourceHandler'; TAP::Parser::IteratorFactory->register_handler( __PACKAGE__ ); sub can_handle { my ( $class, $src ) = @_; my $meta = $src->meta; my $config = $src->config_for( $class ); if ($config->{accept_all}) { return 1.0; } elsif (my $file = $meta->{file}) { return 0.0 unless $file->{exists}; return 1.0 if $file->{lc_ext} eq '.tap'; return 0.9 if $file->{shebang} && $file->{shebang} =~ /^#!.+tap/; return 0.5 if $file->{text}; return 0.1 if $file->{binary}; } elsif ($meta->{scalar}) { return 0.8 if $$raw_source_ref =~ /\d\.\.\d/; return 0.6 if $meta->{has_newlines}; } elsif ($meta->{array}) { return 0.8 if $meta->{size} < 5; return 0.6 if $raw_source_ref->[0] =~ /foo/; return 0.5; } elsif ($meta->{hash}) { return 0.6 if $raw_source_ref->{foo}; return 0.2; } return 0; } sub make_iterator { my ($class, $source) = @_; # this is where you manipulate the source and # capture the stream of TAP in an iterator # either pick a TAP::Parser::Iterator::* or write your own... my $iterator = TAP::Parser::Iterator::Array->new([ 'foo', 'bar' ]); return $iterator; } 1; ``` ## AUTHORS TAPx Developers. Source detection stuff added by Steve Purkis ## SEE ALSO [TAP::Object](../Object.md), [TAP::Parser](../Parser.md), [TAP::Parser::Source](Source.md), [TAP::Parser::Iterator](Iterator.md), [TAP::Parser::IteratorFactory](IteratorFactory.md), [TAP::Parser::SourceHandler::Executable](SourceHandler/Executable.md), [TAP::Parser::SourceHandler::Perl](SourceHandler/Perl.md), [TAP::Parser::SourceHandler::File](SourceHandler/File.md), [TAP::Parser::SourceHandler::Handle](SourceHandler/Handle.md), [TAP::Parser::SourceHandler::RawTAP](SourceHandler/RawTAP.md) ## Modules - [`TAP::Parser::SourceHandler::Executable`](SourceHandler/Executable.md) - Stream output from an executable TAP source - [`TAP::Parser::SourceHandler::File`](SourceHandler/File.md) - Stream TAP from a text file. - [`TAP::Parser::SourceHandler::Handle`](SourceHandler/Handle.md) - Stream TAP from an IO::Handle or a GLOB. - [`TAP::Parser::SourceHandler::Perl`](SourceHandler/Perl.md) - Stream TAP from a Perl executable - [`TAP::Parser::SourceHandler::RawTAP`](SourceHandler/RawTAP.md) - Stream output from raw TAP in a scalar/array ref. ```{toctree} :hidden: :maxdepth: 1 SourceHandler/Executable SourceHandler/File SourceHandler/Handle SourceHandler/Perl SourceHandler/RawTAP ```