Update Test-Harness to CPAN version 3.39
[perl.git] / cpan / Test-Harness / lib / TAP / Parser / ResultFactory.pm
1 package TAP::Parser::ResultFactory;
2
3 use strict;
4 use warnings;
5
6 use TAP::Parser::Result::Bailout ();
7 use TAP::Parser::Result::Comment ();
8 use TAP::Parser::Result::Plan    ();
9 use TAP::Parser::Result::Pragma  ();
10 use TAP::Parser::Result::Test    ();
11 use TAP::Parser::Result::Unknown ();
12 use TAP::Parser::Result::Version ();
13 use TAP::Parser::Result::YAML    ();
14
15 use base 'TAP::Object';
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<TAP::Parser::Result> subclass
41 representing the current bit of test data from TAP (usually a single line).
42 It is used primarily by L<TAP::Parser::Grammar>.  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<new>
50
51 Creates a new factory class.
52 I<Note:> You currently don't need to instantiate a factory in order to use it.
53
54 =head3 C<make_result>
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     my ( $proto, $token ) = @_;
66     my $type = $token->{type};
67     return $proto->class_for($type)->new($token);
68 }
69
70 =head3 C<class_for>
71
72 Takes one argument: C<$type>.  Returns the class for this $type, or C<croak>s
73 with an error.
74
75 =head3 C<register_type>
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<TAP::Parser>.
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     my ( $class, $type ) = @_;
110
111     # return target class:
112     return $CLASS_FOR{$type} if exists $CLASS_FOR{$type};
113
114     # or complain:
115     require Carp;
116     Carp::croak("Could not determine class for result type '$type'");
117 }
118
119 sub register_type {
120     my ( $class, $type, $rclass ) = @_;
121
122     # register it blindly, assume they know what they're doing
123     $CLASS_FOR{$type} = $rclass;
124     return $class;
125 }
126
127 1;
128
129 =head1 SUBCLASSING
130
131 Please see L<TAP::Parser/SUBCLASSING> for a subclassing overview.
132
133 There are a few things to bear in mind when creating your own
134 C<ResultFactory>:
135
136 =over 4
137
138 =item 1
139
140 The factory itself is never instantiated (this I<may> change in the future).
141 This means that C<_initialize> is never called.
142
143 =item 2
144
145 C<TAP::Parser::Result-E<gt>new> is never called, $tokens are reblessed.
146 This I<will> change in a future version!
147
148 =item 3
149
150 L<TAP::Parser::Result> subclasses will register themselves with
151 L<TAP::Parser::ResultFactory> 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<TAP::Parser>,
180 L<TAP::Parser::Result>,
181 L<TAP::Parser::Grammar>
182
183 =cut