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   14838 use strict;
  32         51  
  32         751  
4 32     32   112 use warnings;
  32         40  
  32         722  
5              
6 32     32   11925 use TAP::Parser::Result::Bailout ();
  32         60  
  32         489  
7 32     32   11458 use TAP::Parser::Result::Comment ();
  32         1964  
  32         496  
8 32     32   12623 use TAP::Parser::Result::Plan ();
  32         57  
  32         504  
9 32     32   12072 use TAP::Parser::Result::Pragma ();
  32         72  
  32         463  
10 32     32   12886 use TAP::Parser::Result::Test ();
  32         50  
  32         614  
11 32     32   11533 use TAP::Parser::Result::Unknown ();
  32         48  
  32         466  
12 32     32   10966 use TAP::Parser::Result::Version ();
  32         50  
  32         445  
13 32     32   10947 use TAP::Parser::Result::YAML ();
  32         50  
  32         568  
14              
15 32     32   121 use base 'TAP::Object';
  32         36  
  32         7452  
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.38
33              
34             =cut
35              
36             our $VERSION = '3.38';
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 2806 my ( $proto, $token ) = @_;
66 1332         1662 my $type = $token->{type};
67 1332         2984 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 1431 my ( $class, $type ) = @_;
110              
111             # return target class:
112 1332 100       10155 return $CLASS_FOR{$type} if exists $CLASS_FOR{$type};
113              
114             # or complain:
115 1         12 require Carp;
116 1         230 Carp::croak("Could not determine class for result type '$type'");
117             }
118              
119             sub register_type {
120 1     1 1 1729 my ( $class, $type, $rclass ) = @_;
121              
122             # register it blindly, assume they know what they're doing
123 1         2 $CLASS_FOR{$type} = $rclass;
124 1         3 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