I've had this hanging around for ages, but I'm not happy with it yet. I should really generalise it into some sort of Test::Filehandle. However it may be of use as a starting point:

#! /usr/bin/perl -w package Test::Output; use 5.005; use strict; use Sub::Uplevel; use Test::Builder; use IO::File; use Fcntl; use Symbol qw(qualify_to_ref gensym); use base qw(Exporter); use vars qw($VERSION @EXPORT); $VERSION = '0.01'; @EXPORT = qw(output_is output_isnt output_like output_unlike); sub _try_as_caller { my ($sub, $level) = @_; eval { uplevel $level, $sub }; return $@; }; my $Last_output; sub _get_output { my ($code, $fh, $level) = @_; $fh = qualify_to_ref($fh, caller); my $tmp = IO::File->new_tmpfile or die "no tmp file ($!)"; my $old = gensym; *$old = *$fh; local *$fh = $tmp; my $exception = _try_as_caller($code, $level); *$fh = *$old; die if $exception; seek $tmp, SEEK_SET, 0 or die "could not seek ($!)"; my $output = ''; my $n; while ($n = read $tmp, $output, 1024, length($output)) {}; die "could not read ($!)" unless defined($n); return($Last_output = $output); }; sub _test_output { my ($method, $code, $expected, $fh, $name) = @_; my $builder = Test::Builder->new; my $todo = $builder->exported_to; local $Test::Builder::Level = 2; $builder->$method(_get_output($code, $fh, 6), $expected, $name); }; sub output_is (&$*;$) { _test_output('is_eq', @_) }; sub output_isnt (&$*;$) { _test_output('isnt_eq',@_) }; sub output_like (&$*;$) { _test_output('like', @_) }; sub output_unlike (&$*;$) { _test_output('unlike', @_) }; sub last { $Last_output }; 1;

Use something like:

output_is { hello() } "hello world\n", STDOUT, "hello world"; output_isnt { hello() } "goodbye", STDOUT, "not goodbye"; output_unlike { hello() } qr/bye/, STDOUT, "didn't print bye +"; output_like { hello() } qr/hello/, STDOUT, "printed hello"; like(Test::Output->last, qr/world/, "... and world");

(yes, I know,  _get_output sucks ;-)


In reply to Re: Tests for 'printing' code by adrianh
in thread Tests for 'printing' code by dda

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.