1IO::Capture::Extended::UOsveerrvCioenwt(r3i)buted Perl DIoOc:u:mCeanpttautrieo:n:Extended::Overview(3)
2
3
4

NAME

6       IO::Capture::Extended - Extend functionality of IO::Capture
7

SYNOPSIS

9       The programmer interface consists of two classes:
10
11   IO::Capture::Stdout::Extended
12           use IO::Capture::Stdout::Extended;
13
14           $capture = IO::Capture::Stdout::Extended->new();
15           $capture->start();
16           # some code that prints to STDOUT
17           $capture->stop();
18
19           # scalar context:  return number of print statements with 'fox'
20           $matches = $capture->grep_print_statements('fox');
21
22           # list context:  return list of print statements with 'fox'
23           @matches = $capture->grep_print_statements('fox');
24
25           # return number of print statements
26           $matches = $capture->statements;
27
28           # scalar context:  return number of pattern matches
29           $regex = qr/some regular expression/;
30           $matches = $capture->matches($regex);
31
32           # list context:  return list of pattern matches
33           @matches = $capture->matches($regex);
34
35           # return reference to array holding list of pattern matches
36           $matchesref = $capture->matches_ref($regex);
37
38           # scalar context:  return number of 'screen' lines printed
39           $screen_lines = $capture->all_screen_lines();
40
41           # list context:  return list of 'screen' lines printed
42           @all_screen_lines = $capture->all_screen_lines();
43
44   IO::Capture::Stderr::Extended
45           $capture = IO::Capture::Stderr::Extended->new();
46           $capture->start();
47           # some code that prints to STDERR
48           $capture->stop();
49
50       ... and then use all the methods defined above for
51       IO::Capture::Stdout::Extended.
52

DESCRIPTION

54       IO::Capture::Extended is a distribution consisting of two classes, each
55       of which is a collection of subroutines which are useful in extending
56       the functionality of CPAN modules IO::Capture::Stdout and
57       IO::Capture::Stderr, particularly when used in a testing context such
58       as that provided by Test::Simple, Test::More or other modules built on
59       Test::Builder.
60

USAGE

62   Requirements
63       IO::Capture distribution, available from CPAN
64       <http://search.cpan.org/~reynolds/IO-Capture-0.05/>.  Use version 0.05
65       or later to take advantage of important bug fixes.  The IO::Capture
66       distribution includes base class IO::Capture,  IO::Capture::Stdout,
67       IO::Capture::Stderr  and other packages.  It also includes useful
68       documentation in IO::Capture::Overview.
69
70   General Comments
71       The IO::Capture::Stdout::Extended and IO::Capture::Stdout::Extended
72       methods are designed to provide return values which work nicely as
73       arguments to Test::More functions such as ok(), is() and like().  The
74       examples below illustrate that objective.  Suggestions are welcome for
75       additional methods which would fulfill that objective.
76
77   Individual Methods
78       Note:  Since IO::Capture::Extended is structured so as to make exactly
79       the same methods available for IO::Capture::Stdout::Extended and
80       IO::Capture::Stderr::Extended, whenver there appears below a reference
81       to, e.g., IO::Capture::Stdout::Extended::grep_print_statements(), you
82       should assume that the remarks apply equally to
83       IO::Capture::Stderr::Extended::grep_print_statements().  Wherever
84       reference is made to STDOUT, the remarks apply to STDERR as well.
85
86       grep_print_statements()
87
88       •   Scalar Context
89
90           Problem:  You wish to test a function that prints to STDOUT.  You
91           can predict the number of "print" statements that match a pattern
92           and wish to test that prediction.  (The example below is adapted
93           from IO::Capture::Overview.)
94
95               sub print_fox {
96                   print "The quick brown fox jumped over ...";
97                   print "garden wall";
98                   print "The quick red fox jumped over ...";
99                   print "garden wall";
100               }
101
102               $capture->start;
103               print_fox();
104               $capture->stop;
105               $matches = $capture->grep_print_statements('fox');
106               is($capture->grep_print_statements('fox'), 2,
107                   "correct no. of print statements grepped");
108
109           Solution:  Precede the function call with a call to the
110           IO::Capture::Stdout::Extended start() method and follow it with a
111           call to the stop() method.  Call "grep_print_statements".  Use its
112           return value as one of two arguments to Test::More::is().  Use your
113           prediction as the other argument.  Add a useful comment to is().
114
115           Potential Pitfall:  The number of print statements captured between
116           IO::Capture::Stdout::Extended::start() and stop() is not
117           necessarily the number of lines that would appear to be printed to
118           standard output by a given block of code.  If your subroutine or
119           other code block prints partial lines -- i.e., lines lacking "\n"
120           newline characters -- the number of print statements will be
121           greater than the number of ''screen lines.''  This is illustrated
122           by the following:
123
124               sub print_fox_long {
125                   print "The quick brown fox jumped over ...";
126                   print "a less adept fox\n";
127                   print "The quick red fox jumped over ...";
128                   print "the garden wall\n";
129               }
130
131               $capture->start;
132               print_fox_long();
133               $capture->stop;
134               $matches = $capture->grep_print_statements("fox");
135               is($capture->grep_print_statements("fox"), 3,
136                   "correct no. of print statements grepped");
137
138           The number of "print" statements matching "fox" is three -- even
139           though the number of lines on the screen which appear on STDOUT
140           containing "fox" is only two.
141
142       •   List Context
143
144           Problem:  As above, you wish to test a function that prints to
145           STDOUT.  This time, you can predict the content of "print"
146           statements that match a pattern and wish to test that prediction.
147
148               %matches = map { $_, 1 } $capture->grep_print_statements('fox');
149               is(keys %matches, 2, "correct no. of print statements grepped");
150               ok($matches{'The quick brown fox jumped over ...'},
151                   'print statement correctly grepped');
152               ok($matches{'The quick red fox jumped over ...'},
153                   'print statement correctly grepped');
154
155           Solution:  As above, call "grep_print_statements", but map its
156           output to a 'seen-hash'.  You can then use the number of keys in
157           that seen-hash as an argument to Test::More::is().  You can use
158           ok() to test whether the keys of that hash are as predicted.
159
160       statements()
161
162       Problem:  You've written a function which prints to STDOUT.  You can
163       make a prediction as to the number of screen lines which should be
164       printed.  You want to test that prediction with Test::More::is().
165
166           sub print_greek {
167               local $_;
168               print "$_\n" for (qw| alpha beta gamma delta |);
169           }
170
171           $capture->start();
172           print_greek();
173           $capture->stop();
174           is($capture->statements, 4,
175               "number of print statements is correct");
176
177       Solution:  Precede the function call with a call to the
178       IO::Capture::Stdout start() method and follow it with a call to the
179       stop() method.  Call IO::Capture::Stdout::Extended::statements() and
180       use its return value as the first argument to is().  Use your
181       prediction as the second argument to is().  Be sure to write a useful
182       comment for your test.
183
184       Potential Pitfall:  The number of print statements returned by
185       "statements" is not necessarily the number of lines that would appear
186       to be printed to standard output by a given block of code.  If your
187       subroutine or other code block prints partial lines -- i.e., lines
188       lacking "\n" newline characters -- the number of print statements will
189       be greater than the number of ''screen lines.''  This is illustrated by
190       the following:
191
192           sub print_greek_long {
193               local $_;
194               for (qw| alpha beta gamma delta |) {
195                   print $_;
196                   print "\n";
197               }
198           }
199
200           $capture->start();
201           print_greek_long();
202           $capture->stop();
203           is($capture->statements, 8,
204               "number of print statements is correct");
205
206       This pitfall can be avoided by using all_screen_lines() below.
207
208       all_screen_lines()
209
210       •   Scalar Context
211
212           Returns the number of lines which would normally be counted by eye
213           on STDOUT.  This number is not necessarily equal to the number of
214           print() statements found in the captured output.  This method
215           avoids the 'pitfall' found when using statements() above.
216
217               $capture->start();
218               print_greek_long();
219               $capture->stop();
220               $screen_lines = $capture->all_screen_lines;
221               is($screen_lines, 4, "correct no. of lines printed to screen");
222
223       •   List Context
224
225           Returns an array holding lines as normally viewed on STDOUT.  The
226           size of this array is not necessarily equal to the number of
227           print() statements found in the captured output.  This method
228           avoids the 'pitfall' found when using statements() above.
229
230               $capture->start();
231               print_greek_long();
232               $capture->stop();
233               @all_screen_lines = $capture->all_screen_lines;
234               is($all_screen_lines[0],
235                   "alpha",
236                   "line correctly printed to screen");
237               is($all_screen_lines[1],
238                   "beta",
239                   "line correctly printed to screen");
240
241           Any newline ("\n") appearing at the end of a screen line is not
242           included in the list of lines returned by this method, i.e., the
243           lines are chomped.
244
245       matches()
246
247       •   Scalar Context
248
249           Problem:  You've written a function which, much like the ''mail
250           merge'' function in word processing programs, extracts data from
251           some data source, merges the data with text in a standard form, and
252           prints the result to STDOUT.  You make a prediction as to the
253           number of forms which are printed to STDOUT and wish to confirm
254           that prediction.
255
256               my @week = (
257                   [ qw| Monday     Lundi    Lunes     | ],
258                   [ qw| Tuesday    Mardi    Martes    | ],
259                   [ qw| Wednesday  Mercredi Miercoles | ],
260                   [ qw| Thursday   Jeudi    Jueves    | ],
261                   [ qw| Friday     Vendredi Viernes   | ],
262                   [ qw| Saturday   Samedi   Sabado    | ],
263                   [ qw| Sunday     Dimanche Domingo   | ],
264               );
265
266               sub print_week {
267                   my $weekref = shift;
268                   my @week = @{$weekref};
269                   for (my $day=0; $day<=$#week; $day++) {
270                       print "English:  $week[$day][0]\n";
271                       print "French:   $week[$day][1]\n";
272                       print "Spanish:  $week[$day][2]\n";
273                       print "\n";
274                   }
275               }
276
277               $capture->start();
278               print_week(\@week);
279               $capture->stop();
280               $regex = qr/English:.*?French:.*?Spanish:/s;
281
282               is($capture->matches($regex), 7,
283                   "correct number of forms printed to screen");
284
285           Solution:  Precede the function call with a call to the
286           IO::Capture::Stdout start() method and follow it with a call to the
287           stop() method.  Write a Perl regular expression and assign it to a
288           variable using the "qr//" notation.  (Remember to use the "/s"
289           modifier if the text you are testing crosses screen lines.)  Pass
290           the regex variable to IO::Capture::Stdout::Extended::matches() and
291           use the return value of that method call as one argument to
292           Test::More::is().  Use your prediction as the second argument to
293           is().  Be sure to write a useful comment for your test.
294
295       •   List Context
296
297           Problem:  As above, you've written a function which, much like the
298           ''mail merge'' function in word processing programs, extracts data
299           from some data source, merges the data with text in a standard
300           form, and prints the result to STDOUT.  This time, however, you
301           wish to do a quick test on the results by examining a sample form.
302
303               $capture->start();
304               print_week(\@week); # as defined above
305               $capture->stop();
306
307               @matches = $capture->matches($regex);
308               $predicted = "English:  Monday\nFrench:   Lundi\nSpanish:";
309               is($matches[0], $predicted, "first form matches test portion");
310
311           Solution:  Same as above, but capture the output of matches() in a
312           list or array.  Write a string which predicts typical contents of
313           one instance of your merged form. Use the contents of one form (one
314           element in the list output) and the prediction string as arguments
315           to is().  Be sure to write a useful comment for your test.
316
317           Problem: As above, but now you wish to make sure that a form was
318           generated for each required field in the data source.
319
320               $regex = qr/French:\s+(.*?)\n/s;
321               @predicted = qw| Lundi Mardi Mercredi Jeudi
322                   Vendredi Samedi Dimanche |;
323               ok(eq_array( [ $capture->matches($regex) ], \@predicted ),
324                   "all predicted matches found");
325
326           Solution:  Similar to above, but this time you predict which data
327           points are going to be present in the output.  Store that
328           prediction in a list or array.  Take references to (a) the array
329           holding that prediction; and (b) the result of
330           "$capture-"matches($regex)>.  Pass those two references to
331           Test::More's utility function "eq_array", which will return a true
332           value if the underlying arrays are identical element-by-element.
333           Pass that value in turn to <ok()>.  As always, be sure to write a
334           useful comment for your test.
335
336       matches_ref()
337
338       Problem:  Same as the first ''List Context'' example above, but now you
339       would prefer to work with a method that returns an array reference
340       rather than all the elements in a list.
341
342           $matchesref = $capture->matches_ref($regex);
343           is(${$matchesref}[0], $predicted, "first form matches test portion");
344
345       Solution: Call IO::Capture::Stdout::Extended::matches_ref() instead of
346       "matches".  You will have to rephrase your test in terms of an element
347       of a dereferenced array.
348

BUGS

350       As Paul Johnson says, ''Did I mention that this is alpha code?''.
351

SUPPORT

353       Contact the author or post to the perl-qa mailing list.
354

ACKNOWLEDGEMENTS

356       Thanks go first and foremost to the two authors of the IO::Capture
357       distribution, Mark Reynolds and Jon Morgan.  Mark Reynolds was
358       responsive to this module's author's suggestions for bug fixes and
359       additional tests.  The documentation found in IO::Capture::Overview was
360       particularly helpful in showing me how to extend IO::Capture's
361       functionality.  This distribution is maintained independently but will
362       be updated as needed if and when IO::Capture is revised.
363
364       The methods in IO::Capture::Extended are offered to the Perl community
365       in gratitude for being turned on to IO::Capture by David Cantrell on
366       the perl.qa mailing list in February 2005
367       (<http://www.nntp.perl.org/group/perl.qa/3567>).
368
369       Other contributors to that discussion thread whose suggestions are
370       reflected in this module were David H. Adler, David Golden, Michael G.
371       Schwern and Tels.  Fergal Daly also made suggestions in separate
372       communications.
373
374       The structure for this module was created with my own hacked-up version
375       of R. Geoffrey Avery's modulemaker utility, based on his CPAN module
376       ExtUtils::ModuleMaker.
377

AUTHOR

379       James E Keenan.  CPAN ID: JKEENAN.  jkeenan [at] cpan [dot] org.
380
382       Copyright 2005-15 James E Keenan.
383
384       This program is free software; you can redistribute it and/or modify it
385       under the same terms as Perl itself.
386
387       The full text of the license can be found in the LICENSE file included
388       with this module.
389

SEE ALSO

391       perl(1).  IO::Capture; IO::Capture::Stdout; IO::Capture::Overview.
392       Test::Simple; Test::More.
393
394
395
396perl v5.38.0                      2023-07-20IO::Capture::Extended::Overview(3)
Impressum