Commit | Line | Data |
b965d173 |
1 | package TAP::Parser::Source; |
2 | |
3 | use strict; |
f7c69158 |
4 | use vars qw($VERSION @ISA); |
b965d173 |
5 | |
f7c69158 |
6 | use TAP::Object (); |
7 | use TAP::Parser::IteratorFactory (); |
8 | |
9 | @ISA = qw(TAP::Object); |
b965d173 |
10 | |
11 | # Causes problem on MacOS and shouldn't be necessary anyway |
12 | #$SIG{CHLD} = sub { wait }; |
13 | |
14 | =head1 NAME |
15 | |
16 | TAP::Parser::Source - Stream output from some source |
17 | |
18 | =head1 VERSION |
19 | |
f7c69158 |
20 | Version 3.13 |
b965d173 |
21 | |
22 | =cut |
23 | |
f7c69158 |
24 | $VERSION = '3.13'; |
b965d173 |
25 | |
f7c69158 |
26 | =head1 SYNOPSIS |
b965d173 |
27 | |
f7c69158 |
28 | use TAP::Parser::Source; |
29 | my $source = TAP::Parser::Source->new; |
30 | my $stream = $source->source(['/usr/bin/ruby', 'mytest.rb'])->get_stream; |
b965d173 |
31 | |
f7c69158 |
32 | =head1 DESCRIPTION |
b965d173 |
33 | |
f7c69158 |
34 | Takes a command and hopefully returns a stream from it. |
b965d173 |
35 | |
36 | =head1 METHODS |
37 | |
38 | =head2 Class Methods |
39 | |
40 | =head3 C<new> |
41 | |
42 | my $source = TAP::Parser::Source->new; |
43 | |
44 | Returns a new C<TAP::Parser::Source> object. |
45 | |
46 | =cut |
47 | |
f7c69158 |
48 | # new() implementation supplied by TAP::Object |
49 | |
50 | sub _initialize { |
51 | my ( $self, $args ) = @_; |
52 | $self->{switches} = []; |
b965d173 |
53 | _autoflush( \*STDOUT ); |
54 | _autoflush( \*STDERR ); |
f7c69158 |
55 | return $self; |
b965d173 |
56 | } |
57 | |
58 | ############################################################################## |
59 | |
60 | =head2 Instance Methods |
61 | |
62 | =head3 C<source> |
63 | |
64 | my $source = $source->source; |
65 | $source->source(['./some_prog some_test_file']); |
66 | |
67 | # or |
68 | $source->source(['/usr/bin/ruby', 't/ruby_test.rb']); |
69 | |
70 | Getter/setter for the source. The source should generally consist of an array |
f7c69158 |
71 | reference of strings which, when executed via L<&IPC::Open3::open3|IPC::Open3>, |
72 | should return a filehandle which returns successive rows of TAP. C<croaks> if |
73 | it doesn't get an arrayref. |
b965d173 |
74 | |
75 | =cut |
76 | |
77 | sub source { |
78 | my $self = shift; |
79 | return $self->{source} unless @_; |
80 | unless ( 'ARRAY' eq ref $_[0] ) { |
81 | $self->_croak('Argument to &source must be an array reference'); |
82 | } |
83 | $self->{source} = shift; |
84 | return $self; |
85 | } |
86 | |
87 | ############################################################################## |
88 | |
89 | =head3 C<get_stream> |
90 | |
91 | my $stream = $source->get_stream; |
92 | |
f7c69158 |
93 | Returns a L<TAP::Parser::Iterator> stream of the output generated by executing |
94 | C<source>. C<croak>s if there was no command found. |
95 | |
96 | Must be passed an object that implements a C<make_iterator> method. |
97 | Typically this is a TAP::Parser instance. |
b965d173 |
98 | |
99 | =cut |
100 | |
101 | sub get_stream { |
f7c69158 |
102 | my ( $self, $factory ) = @_; |
b965d173 |
103 | my @command = $self->_get_command |
104 | or $self->_croak('No command found!'); |
105 | |
f7c69158 |
106 | return $factory->make_iterator( |
b965d173 |
107 | { command => \@command, |
108 | merge => $self->merge |
109 | } |
110 | ); |
111 | } |
112 | |
113 | sub _get_command { return @{ shift->source || [] } } |
114 | |
115 | ############################################################################## |
116 | |
b965d173 |
117 | =head3 C<merge> |
118 | |
119 | my $merge = $source->merge; |
120 | |
121 | Sets or returns the flag that dictates whether STDOUT and STDERR are merged. |
122 | |
123 | =cut |
124 | |
125 | sub merge { |
126 | my $self = shift; |
127 | return $self->{merge} unless @_; |
128 | $self->{merge} = shift; |
129 | return $self; |
130 | } |
131 | |
132 | # Turns on autoflush for the handle passed |
133 | sub _autoflush { |
134 | my $flushed = shift; |
135 | my $old_fh = select $flushed; |
136 | $| = 1; |
137 | select $old_fh; |
138 | } |
139 | |
b965d173 |
140 | 1; |
f7c69158 |
141 | |
142 | =head1 SUBCLASSING |
143 | |
144 | Please see L<TAP::Parser/SUBCLASSING> for a subclassing overview. |
145 | |
146 | =head2 Example |
147 | |
148 | package MyRubySource; |
149 | |
150 | use strict; |
151 | use vars '@ISA'; |
152 | |
153 | use Carp qw( croak ); |
154 | use TAP::Parser::Source; |
155 | |
156 | @ISA = qw( TAP::Parser::Source ); |
157 | |
158 | # expect $source->(['mytest.rb', 'cmdline', 'args']); |
159 | sub source { |
160 | my ($self, $args) = @_; |
161 | my ($rb_file) = @$args; |
162 | croak("error: Ruby file '$rb_file' not found!") unless (-f $rb_file); |
163 | return $self->SUPER::source(['/usr/bin/ruby', @$args]); |
164 | } |
165 | |
166 | =head1 SEE ALSO |
167 | |
168 | L<TAP::Object>, |
169 | L<TAP::Parser>, |
170 | L<TAP::Parser::Source::Perl>, |
171 | |
172 | =cut |
173 | |