Game-TextPacMonster

 view release on metacpan or  search on metacpan

inc/Test/MockObject.pm  view on Meta::CPAN

#line 1
package Test::MockObject;
BEGIN {
  $Test::MockObject::VERSION = '1.20110612';
}

use strict;
use warnings;

use Scalar::Util qw( blessed refaddr reftype weaken );

sub import
{
    my $self = shift;
    return unless grep /^-debug/, @_;
    eval "use UNIVERSAL::isa 'verbose'";
    eval "use UNIVERSAL::can '-always_warn'";
}

use Test::Builder;

my $Test = Test::Builder->new();
my (%calls, %subs);

sub new
{
    my ($class, $type) = @_;
    $type ||= {};
    bless $type, $class;
}

sub mock
{
    my ($self, $name, $sub) = @_;
    $sub ||= sub {};

    # leading dash means unlog, otherwise do log
    _set_log( $self, $name, ( $name =~ s/^-// ? 0 : 1 ) );
    _subs( $self )->{$name} = $sub;

    $self;
}

sub set_isa
{
    my ($self, @supers) = @_;
    my $supers          = _isas( $self );
    $supers->{$_}       = 1 for @supers;
}

sub set_always
{
    my ($self, $name, $value) = @_;
    $self->mock( $name, sub { $value } );
}

sub set_true
{
    my $self = shift;

    for my $name ( @_ )
    {
        $self->mock( $name, sub { 1 } );
    }

    return $self;
}

sub set_false
{

inc/Test/MockObject.pm  view on Meta::CPAN

sub call_args_pos
{
    my ($self, $subpos, $argpos) = @_;
    my $args = $self->_call( $subpos, 1 ) or return;
    $argpos-- if $argpos > 0;
    return $args->[$argpos];
}

sub next_call
{
    my ($self, $num)  = @_;
    $num            ||= 1;

    my $calls = _calls( $self );
    return unless @$calls >= $num;

    my ($call) = (splice(@$calls, 0, $num))[-1];
    return wantarray() ? @$call : $call->[0];
}

sub AUTOLOAD
{
    our $AUTOLOAD;

    my $self = shift;
    my $sub;
    {
        local $1;
        ($sub) = $AUTOLOAD =~ /::(\w+)\z/;
    }
    return if $sub eq 'DESTROY';

    $self->dispatch_mocked_method( $sub, @_ );
}

sub dispatch_mocked_method
{
    my $self = $_[0];
    my $sub  = splice( @_, 1, 1 );

    my $subs = _subs( $self );
    if (exists $subs->{$sub})
    {
        $self->log_call( $sub, @_ );
        goto &{ $subs->{$sub} };
    }
    else
    {
        require Carp;
        Carp::carp("Un-mocked method '$sub()' called");
    }

    return;
}

sub log_call
{
    my ($self, $sub, @call_args) = @_;
    return unless _logs( $self, $sub );

    # prevent circular references with weaken
    for my $arg ( @call_args )
    {
        next unless ref $arg;
        weaken( $arg ) if refaddr( $arg ) eq refaddr( $self );
    }

    push @{ _calls( $self ) }, [ $sub, \@call_args ];
}

sub called_ok
{
    my ($self, $sub, $name) = @_;
    $name ||= "object called '$sub'";
    $Test->ok( $self->called($sub), $name );
}

sub called_pos_ok
{
    my ($self, $pos, $sub, $name) = @_;
    $name ||= "object called '$sub' at position $pos";
    my $called = $self->call_pos($pos, $sub);
    unless ($Test->ok( (defined $called and $called eq $sub), $name ))
    {
        $called = 'undef' unless defined $called;
        $Test->diag("Got:\n\t'$called'\nExpected:\n\t'$sub'\n");
    }
}

sub called_args_string_is
{
    my ($self, $pos, $sep, $expected, $name) = @_;
    $name ||= "object sent expected args to sub at position $pos";
    $Test->is_eq( $self->call_args_string( $pos, $sep ), $expected, $name );
}

sub called_args_pos_is
{
    my ($self, $pos, $argpos, $arg, $name) = @_;
    $name ||= "object sent expected arg '$arg' to sub at position $pos";
    $Test->is_eq( $self->call_args_pos( $pos, $argpos ), $arg, $name );
}

sub fake_module
{
    my ($class, $modname, %subs) = @_;

    if ($class->check_class_loaded( $modname ) and ! keys %subs)
    {
        require Carp;
        Carp::croak( "No mocked subs for loaded module '$modname'" );
    }

    $modname =~ s!::!/!g;
    $INC{ $modname . '.pm' } = 1;

    no warnings 'redefine';
    {
        no strict 'refs';
        ${ $modname . '::' }{VERSION} ||= -1;
    }

    for my $sub (keys %subs)
    {
        my $type = reftype( $subs{ $sub } ) || '';



( run in 2.548 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )