Re: Testing output to STDOUT and STDERR

2004-02-10 Thread Andy Lester
> Hi, I also have a lot of stuff to bundle! I can even arrange to produce
> unbundled code so you can practice your bundling skills. You can make a
> reputation as "Lester the Bundler".

It's not like I need practice in make a distro.  I just wanna help along
the stuff that I think sounds useful...

xoa

-- 
Andy Lester => [EMAIL PROTECTED] => www.petdance.com => AIM:petdance


Re: Testing output to STDOUT and STDERR

2004-02-10 Thread khemir nadim

"Andy Lester" <[EMAIL PROTECTED]> wrote in message
news:[EMAIL PROTECTED]
> > Because:
> > a) I wasn't happy with the API
> > b) I'm a lazy SOB and couldn't find the time to sort it out
>
> I'll be glad to help with the second part.  Mail me the parts and I'll
> bundle it up all nice for ya.

Hi, I also have a lot of stuff to bundle! I can even arrange to produce
unbundled code so you can practice your bundling skills. You can make a
reputation as "Lester the Bundler".

;-)

Nadim.




Re: Testing output to STDOUT and STDERR

2004-02-10 Thread A. Pagaltzis
* Adriano R. Ferreira <[EMAIL PROTECTED]> [2004-02-09 01:56]:
> While writing tests for some of my code, I was faced with the issue
> of capturing what the code sends to STDOUT and STDERR. As I have not
> found a module to make it easy, I wrote a trivial code to do it. It
> is used like this:
> 
>   use Test::More tests => 2;
>   use Seize qw(seize release);
> 
>   my ($out, $err);
> 
>   seize \$out, \$err; # from here on, STDOUT and STDERR are seized
> 
>   print "1\n";
>   warn "2\n";
>   print "3\n";
>   eval { die "4\n"; }
> 
>   release; # here STDOUT and STDERR are released
> 
>   is($out, "1\n3\n");
>   is($err, "2\n3\n");
> 
> My doubt is if this deserves a module: maybe it would be better
> to use idioms commonly employed to this kind of task. Maybe
> there is some module I am overlooking that already does that.

For Perl 5.8 (and 5.6 with IO::String? I think it works there)
it's trivial:

use Test::More tests => 2;
use Carp;

sub string_fh {
open my $fh, '>', $_[0]
or croak "Couldn't open scalar as filehandle: $!\n";
return $fh;
}

my ($out, err);

{
local STDOUT, STDERR;
*STDOUT = string_fh \$out;
*STDERR = string_fh \$err;

print "1\n";
warn "2\n";
print "3\n";
eval { die "4\n"; }
}

is($out, "1\n3\n");
is($err, "2\n3\n");

I believe this is a lot more robust than a tie() solution as
well. But it isn't really modularizable due to the local() and
there's not much anyway to stick in a module. Another approach I
only have the time to sketch here:

use Test::More tests => 2;
use Carp;

sub redir_fh {
my ($fh, $mode, $file);

my $saved_fh;
# dup $fh in here

open $fh, $mode, $file
# not sure this msg makes sense..
or croak "Couldn't dup $fh to $file: $!\n";

return bless [ $fh, $saved_fh ], 'RestoreHandle';
}

sub RestoreHandle::DESTROY {
# use $self to dup the original FH back into the used one
}

my ($out, err);

{
my $s_out = redir_fh \*STDOUT, '>', \$out;
my $s_err = redir_fh \*STDERR, '>', \$err;

print "1\n";
warn "2\n";
print "3\n";
eval { die "4\n"; }

}
# $s_* went out of scope here..

is($out, "1\n3\n");
is($err, "2\n3\n");

which uses lexical variables to implement dynamic scoping. :)

-- 
Regards,
Aristotle
 
"If you can't laugh at yourself, you don't take life seriously enough."


Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Sam Vilain
On Tue, 10 Feb 2004 00:57, Orton, Yves wrote;

  > Its worth noting that this approach wont actually grab everything
  > on the tied filehandles.  There are enough ways to bypass the tie
  > that you have to do a lot more than that to get the majority, and
  > even then there is stuff that will still bypass it.

Yes, that is worth noting; but I'd consider all code that bypasses the
tie to be bugs or an inappropriate test case :-).

I'm just a little curious about the ways that this could happen; see
if you can add to this list.

  a) something grabs the file handle number via fileno(STDOUT) - or
 has a hardcoded `1' for STDOUT - and prints to that directly
 using stdio (now, wouldn't that have to be XS code?)

  b) something uses syswrite(STDOUT)

  c) something written via system("") prints to STDOUT

  d) something has already DUP'ed the file handle (ie open FOO,
 ">&STDOUT") and prints to it normally

  > Its very annoying actually that there isnt a reliable and clean
  > way to intercept STDOUT/STDERR properly. (IMO)

Other than fork and IPC, which bites and doesn't play well with the
test suites... try forking in the middle of a Test::Builder run.
-- 
Sam Vilain, sam /\T vilain |><>T net, PGP key ID: 0x05B52F13
(include my PGP key ID in personal replies to avoid spam filtering)

Activity is the politician's substitute for achievement.
 - anon.



Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Adrian Howard
On Monday, February 9, 2004, at 08:27  pm, Andy Lester wrote:

Because:
a) I wasn't happy with the API
b) I'm a lazy SOB and couldn't find the time to sort it out
I'll be glad to help with the second part.  Mail me the parts and I'll
bundle it up all nice for ya.
If you want to play it's at http://www.quietstars.com/perl/

However I still don't think that API is good, and Adriano's solution 
looks like something more generally useful - so I'm not sure that a 
nice bundle is a good idea :-)

Adrian



Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Andy Lester
> Because:
>   a) I wasn't happy with the API
>   b) I'm a lazy SOB and couldn't find the time to sort it out

I'll be glad to help with the second part.  Mail me the parts and I'll
bundle it up all nice for ya.

-- 
Andy Lester => [EMAIL PROTECTED] => www.petdance.com => AIM:petdance


Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Adrian Howard
On Monday, February 9, 2004, at 06:27  pm, Kineticode Billing wrote:

On Feb 9, 2004, at 10:20 AM, Adrian Howard wrote:
[snip]
Cool. Why isn't this on CPAN?
Because:
a) I wasn't happy with the API
b) I'm a lazy SOB and couldn't find the time to sort it out
The new year's resolution may have helped with (b), but Adriano's 
solution looks better anyway :-)

Adrian



Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Kineticode Billing
On Feb 9, 2004, at 10:20 AM, Adrian Howard wrote:

I did something similar with Test::Output

	http://www.quietstars.com/perl/Test-Output-0.01.tar.gz

which allows you to do things 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");

(rather than using a tied filehandle I just temporarily redirected it 
to a temporary file)
Cool. Why isn't this on CPAN?

I like the look of Adriano's solution more because it allows you to 
test things that mix output on different filehandles - which I can see 
being a handy feature.
Right.

Regards,

David



Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Adrian Howard
On Monday, February 9, 2004, at 02:14  am, David Wheeler wrote:
[snip]
Perhaps:

  stdout_is(print STDOUT "hello", "hello", 'print "hello" to STDOUT');
[snip]

I did something similar with Test::Output

	http://www.quietstars.com/perl/Test-Output-0.01.tar.gz

which allows you to do things 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");
(rather than using a tied filehandle I just temporarily redirected it 
to a temporary file)

I like the look of Adriano's solution more because it allows you to 
test things that mix output on different filehandles - which I can see 
being a handy feature.

Adrian



Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Adrian Howard
On Monday, February 9, 2004, at 02:08  am, Adriano R. Ferreira wrote:
[snip]
One of the things I am not confident at is the interplay with
modules like Test::More. Where they send their output: STDERR?
[snip]

Test::Builder dups the filehandles it uses, so as long as it gets 
loaded first you should be fine.

Adrian



RE: Testing output to STDOUT and STDERR

2004-02-09 Thread Orton, Yves
Title: RE: Testing output to STDOUT and STDERR





> Though, I must say that I prefer his API.  The above was really just a
> quick hack based on what I'd extracted out of the ePerl code base.
> 
> I'd call it something like IO::Capture if I were to CPAN it.
> IO::Seize isn't quite right, but "seize" is definitely a good Perlish
> name for the function.
> 
> Note that php has a built-in function to do just this.


Its worth noting that this approach wont actually grab everything on the tied filehandles.  There are enough ways to bypass the tie that you have to do a lot more than that to get the majority, and even then there is stuff that will still bypass it.

Its very annoying actually that there isnt a reliable and clean way to intercept STDOUT/STDERR properly. (IMO)


Yves








Re: Testing output to STDOUT and STDERR

2004-02-09 Thread Sam Vilain
On Mon, 09 Feb 2004 14:00, Andy Lester wrote;

  > > While writing tests for some of my code, I was faced with the issue
  > > of capturing what the code sends to STDOUT and STDERR. As I have not
  > > found a module to make it easy, I wrote a trivial code to do it. It
  > > is used like this:
  > I'm not sure what you're actually trying to test.  If you're testing
  > test modules, look at Test::Builder::Tester.

No, something that ties STDOUT so that code can print to it, and you
can test that the right thing was printed; I've had to do this before,
and ended up not going through the CPAN ropes for this module:

{
package Capture;

sub new {
my $class = shift;
my $self = { stdout => "" };
bless $self, $class;
return $self;
}

sub capture_print {
my $self = shift;
$self->{so} = tie(*STDOUT, __PACKAGE__, \$self->{stdout})
or die "failed to tie STDOUT; $!";
}

sub release_stdout {
my $self = shift;
delete $self->{so};
untie(*STDOUT);
return $self->{stdout};
}

sub TIEHANDLE {
my $class = shift;
my $ref = shift;
return bless({ stdout => $ref }, $class);
}

sub PRINT {
my $self = shift;
${$self->{stdout}} .= join('', map { defined $_?$_:""} @_); 
}

sub PRINTF {
my ($self) = shift;
print STDERR "OUCH @_\n";
my ($fmt) = shift;
${$self->{stdout}} .= sprintf($fmt, @_)
if (@_);
}

sub glob {
return \*STDOUT;
}
}

Though, I must say that I prefer his API.  The above was really just a
quick hack based on what I'd extracted out of the ePerl code base.

I'd call it something like IO::Capture if I were to CPAN it.
IO::Seize isn't quite right, but "seize" is definitely a good Perlish
name for the function.

Note that php has a built-in function to do just this.
-- 
Sam Vilain, sam /\T vilain |><>T net, PGP key ID: 0x05B52F13
(include my PGP key ID in personal replies to avoid spam filtering)

  Time is an illusion perpetrated by the manufacturers of space.
GRAFFITI





Re: Testing output to STDOUT and STDERR

2004-02-08 Thread David Wheeler
On Feb 8, 2004, at 5:52 PM, Adriano R. Ferreira wrote:

If it is worthy, there's a bunch of things I would appreciate some
feedback on:
* does it make sense the use of 'seize' and 'release' as above
  (I am not an English native speaker and I am not sure).
I like them. They're quirky.

* What would be a sensible name: IO::Seize, Test::Stdout?
The latter, I think.

* It is necessary that I understand better the interaction of the
  code being tested and how Test:: modules and Test::Harness works
If you're tie'ing off STDOUT and STDERR, it should be fine.

* It would be better to make it a real Test:: module?
Perhaps:

  stdout_is(print STDOUT "hello", "hello", 'print "hello" to STDOUT');

You might want to look at the TieOut module that comes with 
ExtUtils::MakeMaker. I myself have a version of it in the App::Info 
distribution, in t/lib:

  http://search.cpan.org/src/DWHEELER/App-Info-0.25/t/lib/TieOut.pm

Regards,

David



Re: Testing output to STDOUT and STDERR

2004-02-08 Thread Lincoln A. Baxter
On Sun, 2004-02-08 at 20:00, Andy Lester wrote:
> > While writing tests for some of my code, I was faced with the issue
> > of capturing what the code sends to STDOUT and STDERR. As I have not
> > found a module to make it easy, I wrote a trivial code to do it. It
> > is used like this:
> 
> I'm not sure what you're actually trying to test.  If you're testing
> test modules, look at Test::Builder::Tester.
> 
> xoa

I think he is trying to do what this should do on the command line but
which does not always work:

ksh$ perl -Mblib t/test.t 2>&1 > somefile

Where the 2>&1 does not succeed in concatentating 2 to 1. (probably
because 2 or 1 is the tty), in which case I am not sure this would work
either.

I think this could possibly be useful... post the code, or a link to the
code.  You might consider combine() and separate() instead of seize and
release?  Not really happy with these names either...

Lincoln




Re: Testing output to STDOUT and STDERR

2004-02-08 Thread Adriano R. Ferreira
The thing I want to test is the output of my piece of code to STDOUT
and STDERR. The kind of code I am writing is just like the output
of a compiler which outputs to STDOUT and sends warnings to STDERR.
Of course, there won't be warnings when the input is correct.
In the tests for this code, I would like not only to test the
successful cases but also the bad cases. So I found this need
to watch STDOUT and STDERR.
One of the things I am not confident at is the interplay with
modules like Test::More. Where they send their output: STDERR?
Adriano.

On Sun, 8 Feb 2004 19:00:02 -0600, Andy Lester <[EMAIL PROTECTED]> wrote:

While writing tests for some of my code, I was faced with the issue
of capturing what the code sends to STDOUT and STDERR. As I have not
found a module to make it easy, I wrote a trivial code to do it. It
is used like this:
I'm not sure what you're actually trying to test.  If you're testing
test modules, look at Test::Builder::Tester.
xoa

--
Oasis Comunicacao e Tecnologia Ltda.


Re: Testing output to STDOUT and STDERR

2004-02-08 Thread Andy Lester
> While writing tests for some of my code, I was faced with the issue
> of capturing what the code sends to STDOUT and STDERR. As I have not
> found a module to make it easy, I wrote a trivial code to do it. It
> is used like this:

I'm not sure what you're actually trying to test.  If you're testing
test modules, look at Test::Builder::Tester.

xoa

-- 
Andy Lester => [EMAIL PROTECTED] => www.petdance.com => AIM:petdance


Testing output to STDOUT and STDERR

2004-02-08 Thread Adriano R. Ferreira
While writing tests for some of my code, I was faced with the issue
of capturing what the code sends to STDOUT and STDERR. As I have not
found a module to make it easy, I wrote a trivial code to do it. It
is used like this:
use Test::More tests => 2;
use Seize qw(seize release);
	my ($out, $err);

	seize \$out, \$err; # from here on, STDOUT and STDERR are seized

print "1\n";
warn "2\n";
print "3\n";
eval { die "4\n"; }
	release; # here STDOUT and STDERR are released

is($out, "1\n3\n");
is($err, "2\n3\n");
My doubt is if this deserves a module: maybe it would be better to use
idioms commonly employed to this kind of task. Maybe there is some module
I am overlooking that already does that.
If it is worthy, there's a bunch of things I would appreciate some
feedback on:
* does it make sense the use of 'seize' and 'release' as above
  (I am not an English native speaker and I am not sure).
* What would be a sensible name: IO::Seize, Test::Stdout?
* It is necessary that I understand better the interaction of the
  code being tested and how Test:: modules and Test::Harness works
* It would be better to make it a real Test:: module?


--
Adriano