File Coverage

blib/lib/TAP/Parser/ResultFactory.pm
Criterion Covered Total %
statement 43 43 100.0
branch 2 2 100.0
condition n/a
subroutine 14 14 100.0
pod 3 3 100.0
total 62 62 100.0


line stmt bran cond sub pod time code
1             package TAP::Parser::ResultFactory;
2              
3 32     32   19278 use strict;
  32         61  
  32         739  
4 32     32   108 use warnings;
  32         36  
  32         638  
5              
6 32     32   12079 use TAP::Parser::Result::Bailout ();
  32         58  
  32         497  
7 32     32   12133 use TAP::Parser::Result::Comment ();
  32         811  
  32         516  
8 32     32   12249 use TAP::Parser::Result::Plan ();
  32         57  
  32         577  
9 32     32   12880 use TAP::Parser::Result::Pragma ();
  32         70  
  32         577  
10 32     32   13357 use TAP::Parser::Result::Test ();
  32         54  
  32         664  
11 32     32   11949 use TAP::Parser::Result::Unknown ();
  32         56  
  32         484  
12 32     32   11783 use TAP::Parser::Result::Version ();
  32         60  
  32         478  
13 32     32   11833 use TAP::Parser::Result::YAML ();
  32         54  
  32         527  
14              
15 32     32   126 use base 'TAP::Object';
  32         29  
  32         7725  
16              
17             ##############################################################################
18              
19             =head1 NAME
20              
21             TAP::Parser::ResultFactory - Factory for creating TAP::Parser output objects
22              
23             =head1 SYNOPSIS
24              
25             use TAP::Parser::ResultFactory;
26             my $token = {...};
27             my $factory = TAP::Parser::ResultFactory->new;
28             my $result = $factory->make_result( $token );
29              
30             =head1 VERSION
31              
32             Version 3.39
33              
34             =cut
35              
36             our $VERSION = '3.39';
37              
38             =head2 DESCRIPTION
39              
40             This is a simple factory class which returns a L subclass
41             representing the current bit of test data from TAP (usually a single line).
42             It is used primarily by L. Unless you're subclassing,
43             you probably won't need to use this module directly.
44              
45             =head2 METHODS
46              
47             =head2 Class Methods
48              
49             =head3 C
50              
51             Creates a new factory class.
52             I You currently don't need to instantiate a factory in order to use it.
53              
54             =head3 C
55              
56             Returns an instance the appropriate class for the test token passed in.
57              
58             my $result = TAP::Parser::ResultFactory->make_result($token);
59              
60             Can also be called as an instance method.
61              
62             =cut
63              
64             sub make_result {
65 1332     1332 1 2437 my ( $proto, $token ) = @_;
66 1332         1656 my $type = $token->{type};
67 1332         2896 return $proto->class_for($type)->new($token);
68             }
69              
70             =head3 C
71              
72             Takes one argument: C<$type>. Returns the class for this $type, or Cs
73             with an error.
74              
75             =head3 C
76              
77             Takes two arguments: C<$type>, C<$class>
78              
79             This lets you override an existing type with your own custom type, or register
80             a completely new type, eg:
81              
82             # create a custom result type:
83             package MyResult;
84             use strict;
85             use base 'TAP::Parser::Result';
86              
87             # register with the factory:
88             TAP::Parser::ResultFactory->register_type( 'my_type' => __PACKAGE__ );
89              
90             # use it:
91             my $r = TAP::Parser::ResultFactory->( { type => 'my_type' } );
92              
93             Your custom type should then be picked up automatically by the L.
94              
95             =cut
96              
97             our %CLASS_FOR = (
98             plan => 'TAP::Parser::Result::Plan',
99             pragma => 'TAP::Parser::Result::Pragma',
100             test => 'TAP::Parser::Result::Test',
101             comment => 'TAP::Parser::Result::Comment',
102             bailout => 'TAP::Parser::Result::Bailout',
103             version => 'TAP::Parser::Result::Version',
104             unknown => 'TAP::Parser::Result::Unknown',
105             yaml => 'TAP::Parser::Result::YAML',
106             );
107              
108             sub class_for {
109 1332     1332 1 1552 my ( $class, $type ) = @_;
110              
111             # return target class:
112 1332 100       9143 return $CLASS_FOR{$type} if exists $CLASS_FOR{$type};
113              
114             # or complain:
115 1         12 require Carp;
116 1         258 Carp::croak("Could not determine class for result type '$type'");
117             }
118              
119             sub register_type {
120 1     1 1 1836 my ( $class, $type, $rclass ) = @_;
121              
122             # register it blindly, assume they know what they're doing
123 1         4 $CLASS_FOR{$type} = $rclass;
124 1         4 return $class;
125             }
126              
127             1;
128              
129             =head1 SUBCLASSING
130              
131             Please see L for a subclassing overview.
132              
133             There are a few things to bear in mind when creating your own
134             C:
135              
136             =over 4
137              
138             =item 1
139              
140             The factory itself is never instantiated (this I change in the future).
141             This means that C<_initialize> is never called.
142              
143             =item 2
144              
145             Cnew> is never called, $tokens are reblessed.
146             This I change in a future version!
147              
148             =item 3
149              
150             L subclasses will register themselves with
151             L directly:
152              
153             package MyFooResult;
154             TAP::Parser::ResultFactory->register_type( foo => __PACKAGE__ );
155              
156             Of course, it's up to you to decide whether or not to ignore them.
157              
158             =back
159              
160             =head2 Example
161              
162             package MyResultFactory;
163              
164             use strict;
165              
166             use MyResult;
167              
168             use base 'TAP::Parser::ResultFactory';
169              
170             # force all results to be 'MyResult'
171             sub class_for {
172             return 'MyResult';
173             }
174              
175             1;
176              
177             =head1 SEE ALSO
178              
179             L,
180             L,
181             L
182              
183             =cut