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

BUGS

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

SUPPORT

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

ACKNOWLEDGEMENTS

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

AUTHOR

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

SEE ALSO

392       perl(1).  IO::Capture; IO::Capture::Stdout; IO::Capture::Overview.
393       Test::Simple; Test::More.
394
395
396
397perl v5.36.0                      2022-07-22IO::Capture::Extended::Overview(3)
Impressum