Skip to content

Commit

Permalink
Add basic "top stack" functionality. TB2 can now track the call stack…
Browse files Browse the repository at this point in the history
… and

report messages from the top of the stack.
  • Loading branch information
schwern committed Jan 5, 2009
1 parent cc2b1b4 commit e125e0e
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
80 changes: 80 additions & 0 deletions lib/Test/Builder2.pm
Expand Up @@ -2,11 +2,15 @@ package Test::Builder2;

use 5.006;
use Mouse;
use Carp qw(confess);

use Test::Builder2::History;
use Test::Builder2::Result;


sub assert { confess "Assert failed" unless $_[0] };


=head1 NAME
Test::Builder2 - 2nd Generation test library builder
Expand All @@ -21,6 +25,8 @@ Just a stub at this point to get things off the ground.
=head3 history
Contains the Test::Builder2::History object.
=cut

has history =>
Expand All @@ -30,25 +36,99 @@ has history =>

=head3 planned_tests
Number of tests planned.
=cut

has planned_tests =>
is => 'rw',
isa => 'Int',
default => 0;

=head3 top
=head3 top_stack
my @top = $tb->top;
my $top_stack = $tb->top_stack;
Stores the call level where the user's tests are written. This is
mostly useful for printing out diagnostic messages with the file and
line number of the test.
It is stored as a stack, so you can wrap tests around tests.
C<$top_stack> is a list of array ref to the return value from
C<caller(EXPR)>. C<<$tb->top>> is a convenience method which returns
C<<@{$top_stack->[0]}>>.
(Might change from the caller array to a hash)
=cut

has top_stack =>
is => 'ro',
isa => 'ArrayRef',
default => sub { [] };

sub top {
my $self = shift;

return @{$self->top_stack->[0]};
}


=head3 from_top
my $msg = $tb->from_top(@msg);
A convenience method. Attaches the traditional " at $file line $line"
to @msg using C<<$tb->top>>. @msg is joined with no delimiter.
=cut

sub from_top {
my $self = shift;

my @top = $self->top;
return join "", @_, " at $top[1] line $top[2]";
}

=head3 test_start
$tb->test_start;
Called just before a user written test function begins, it allows
before-test actions as well as knowing what the "top" of the call
stack is for the purposes of reporting test file and line numbers.
=cut

sub test_start {
my $self = shift;

push @{$self->top_stack}, [caller(1)];

return;
}

=head3 test_end
$tb->test_end(@test_result);
Like C<test_start> but for just after a user written test finishes.
Allows end-of-test actions and pops the call stack.
The C<@test_result> may be used by the end-of-test action.
=cut

sub test_end {
my $self = shift;
my @result = @_;

assert( pop @{$self->top_stack} );

return;
}

=head3 plan
Expand Down
34 changes: 34 additions & 0 deletions t/Builder2/top.t
@@ -0,0 +1,34 @@
#!/usr/bin/perl -w

use strict;
use warnings;

use Test::More tests => 4;
use Test::Builder2;

my $tb = Test::Builder2->new;

sub outer {
$tb->test_start;
my @ret = $tb->from_top("outer");
push @ret, inner(@_);
$tb->test_end;

return @ret;
}

sub inner {
$tb->test_start;
my $ret = $tb->from_top("inner");
$tb->test_end;

return $ret;
}

is_deeply( $tb->top_stack, [], "top_stack() empty" );

#line 29
is_deeply( [inner()], ["inner at $0 line 29"], "from_top() shallow" );
is_deeply( [outer()], ["outer at $0 line 30", "inner at $0 line 30"], "from_top() deep" );

is_deeply( $tb->top_stack, [], "top_stack() still empty" );

0 comments on commit e125e0e

Please sign in to comment.