1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
.\" -*- mode: troff; coding: utf-8 -*-
.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
.ie n \{\
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "TAP::Parser::SourceHandler 3perl"
.TH TAP::Parser::SourceHandler 3perl 2024-02-11 "perl v5.38.2" "Perl Programmers Reference Guide"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH NAME
TAP::Parser::SourceHandler \- Base class for different TAP source handlers
.SH VERSION
.IX Header "VERSION"
Version 3.44
.SH SYNOPSIS
.IX Header "SYNOPSIS"
.Vb 2
\& # abstract class \- don\*(Aqt use directly!
\& # see TAP::Parser::IteratorFactory for general usage
\&
\& # must be sub\-classed for use
\& package MySourceHandler;
\& use base \*(AqTAP::Parser::SourceHandler\*(Aq;
\& sub can_handle { return $confidence_level }
\& sub make_iterator { return $iterator }
\&
\& # see example below for more details
.Ve
.SH DESCRIPTION
.IX Header "DESCRIPTION"
This is an abstract base class for TAP::Parser::Source handlers / handlers.
.PP
A \f(CW\*(C`TAP::Parser::SourceHandler\*(C'\fR does whatever is necessary to produce & capture
a stream of TAP from the \fIraw\fR source, and package it up in a
TAP::Parser::Iterator for the parser to consume.
.PP
\&\f(CW\*(C`SourceHandlers\*(C'\fR must implement the \fIsource detection & handling\fR interface
used by TAP::Parser::IteratorFactory. At 2 methods, the interface is pretty
simple: "can_handle" and "make_source".
.PP
Unless you're writing a new TAP::Parser::SourceHandler, a plugin, or
subclassing TAP::Parser, you probably won't need to use this module directly.
.SH METHODS
.IX Header "METHODS"
.SS "Class Methods"
.IX Subsection "Class Methods"
\fR\f(CI\*(C`can_handle\*(C'\fR\fI\fR
.IX Subsection "can_handle"
.PP
\&\fIAbstract method\fR.
.PP
.Vb 1
\& my $vote = $class\->can_handle( $source );
.Ve
.PP
\&\f(CW$source\fR is a TAP::Parser::Source.
.PP
Returns a number between \f(CW0\fR & \f(CW1\fR reflecting how confidently the raw source
can be handled. For example, \f(CW0\fR means the source cannot handle it, \f(CW0.5\fR
means it may be able to, and \f(CW1\fR means it definitely can. See
"detect_source" in TAP::Parser::IteratorFactory for details on how this is used.
.PP
\fR\f(CI\*(C`make_iterator\*(C'\fR\fI\fR
.IX Subsection "make_iterator"
.PP
\&\fIAbstract method\fR.
.PP
.Vb 1
\& my $iterator = $class\->make_iterator( $source );
.Ve
.PP
\&\f(CW$source\fR is a TAP::Parser::Source.
.PP
Returns a new TAP::Parser::Iterator object for use by the TAP::Parser.
\&\f(CW\*(C`croak\*(C'\fRs on error.
.SH SUBCLASSING
.IX Header "SUBCLASSING"
Please see "SUBCLASSING" in TAP::Parser for a subclassing overview, and any
of the subclasses that ship with this module as an example. What follows is
a quick overview.
.PP
Start by familiarizing yourself with TAP::Parser::Source and
TAP::Parser::IteratorFactory. TAP::Parser::SourceHandler::RawTAP is
the easiest sub-class to use as an example.
.PP
It's important to point out that if you want your subclass to be automatically
used by TAP::Parser you'll have to and make sure it gets loaded somehow.
If you're using prove you can write an App::Prove plugin. If you're
using TAP::Parser or TAP::Harness directly (e.g. through a custom script,
ExtUtils::MakeMaker, or Module::Build) you can use the \f(CW\*(C`config\*(C'\fR option
which will cause "load_sources" in TAP::Parser::IteratorFactory to load your
subclass).
.PP
Don't forget to register your class with
"register_handler" in TAP::Parser::IteratorFactory.
.SS Example
.IX Subsection "Example"
.Vb 1
\& package MySourceHandler;
\&
\& use strict;
\&
\& use MySourceHandler; # see TAP::Parser::SourceHandler
\& use TAP::Parser::IteratorFactory;
\&
\& use base \*(AqTAP::Parser::SourceHandler\*(Aq;
\&
\& 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 \*(Aq.tap\*(Aq;
\& 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 =~ /\ed\e.\e.\ed/;
\& 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([ \*(Aqfoo\*(Aq, \*(Aqbar\*(Aq ]);
\& return $iterator;
\& }
\&
\& 1;
.Ve
.SH AUTHORS
.IX Header "AUTHORS"
TAPx Developers.
.PP
Source detection stuff added by Steve Purkis
.SH "SEE ALSO"
.IX Header "SEE ALSO"
TAP::Object,
TAP::Parser,
TAP::Parser::Source,
TAP::Parser::Iterator,
TAP::Parser::IteratorFactory,
TAP::Parser::SourceHandler::Executable,
TAP::Parser::SourceHandler::Perl,
TAP::Parser::SourceHandler::File,
TAP::Parser::SourceHandler::Handle,
TAP::Parser::SourceHandler::RawTAP
|