Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

heusserm (4461)

heusserm
  (email not shown publicly)
http://www.xndev.com/
AOL IM: MatthewHeusser (Add Buddy, Send Message)

Matt Heusser is JAPH and an XP-Er [xprogramming.com]. (The Methodology, not the Operating System.) Right now, he's doing a lot of Test Driven Development in Perl.

Journal of heusserm (4461)

Tuesday August 19, 2003
10:39 AM

Test::More::STDIO ?

[ #14203 ]
So, you have some functions that print some things to STDIO - perhaps CGI Functions. But you are writing tests, and you see a buncha gobbly-good HTML amoung your "oks". What's worse, you want to test that HTML. (For example, when you search on "Stuff", you want to make sure the table that is returned has rows, so you have a regex to check for that.)

This morning, Jeff Klein proposed the following code snippet to me to get HTML back as a string:

sub capture (&) {
use IO::String;
my $strfh = IO::String->new;
my $oldfh = select($strfh);
shift->();
select($oldfh);
return ${ $strfh->string_ref };
}


Here's it in use:
my $blnOK;
my $str = capture { $blnOK = print_page() };
ok($blnOK);
ok($str =~ /whatever/);


Thoughts to improve this? Are there are other functions like this that are needed, or is there a place that this function "belongs"? (I know it needs to be cleaned up.)

I covet your comments ...
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Rather than fiddling with select(), you might want to say local *STDOUT = IO::String->new or something like it so that STDOUT gets restored even when the code itself dies.

    Hmmm, I'm not sure that does exactly the same thing, but it might be worth a try...

    -Dom

  •            use SelectSaver;

               {
                  my $saver = new SelectSaver(FILEHANDLE);
                  # FILEHANDLE is selected
               }
               # previous handle is selected

    Not sure if you can use IO::String->new() in there, but it could be worth looking at

  • Your solution of using select() will only work for this:

            print "foo";

    but not for this:

            print STDOUT "foo";

    nor for anything but the currently selected filehandle.

    A more general solution is in TieOut.pm of which copies are scattered around in t/lib directories of various modules, a little invention of chromatic's. Here's one. http://search.cpan.org/src/MSCHWERN/ExtUtils-MakeMaker-6.16/t/lib/. Here's an example of its use. http://search.cpan.org/
    • I don't think your proposed solution works in all cases under perl 5.6.1.

      For example:

      $r = *STDOUT;
      print $r "foo\n";

      or

      print stdout "foo\n";

      (Tying STDOUT won't tie stdout)

      Of course, that's fixed in 5.8, but we're not using 5.8.

      sigh.

      (Most of this from Jeff Klein, who has hubris, but is too lazy to get his own account on use.perl.org ...)

  • As an alternative approach, how about forking and piping to yourself?

    --
    J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers