Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Test-Simple CPAN distribution.

Report information
The Basics
Id: 7289
Status: resolved
Priority: 0/
Queue: Test-Simple

People
Owner: Nobody in particular
Requestors: florian [...] cpan.org
nick [...] cleaton.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.48_02
Fixed in: (no value)



Subject: [PATCH] handle self-referential data structures
When comparing two equivalent self-referential data structures, the deep comparison functions in Test::More loop forever, e.g. my $a1 = [1, 2, 3]; push @$a1, $a1; my $a2 = [1, 2, 3]; push @$a2, $a2; is_deeply( $a1, $a2, 'foo' );
diff -Nurd Test-Simple-0.48_02.orig/lib/Test/More.pm Test-Simple-0.48_02/lib/Test/More.pm --- Test-Simple-0.48_02.orig/lib/Test/More.pm Mon Jul 19 08:11:49 2004 +++ Test-Simple-0.48_02/lib/Test/More.pm Sat Aug 7 17:38:59 2004 @@ -969,7 +969,7 @@ =cut -use vars qw(@Data_Stack); +use vars qw(@Data_Stack %Refs_Seen); my $DNE = bless [], 'Does::Not::Exist'; sub is_deeply { unless( @_ == 2 or @_ == 3 ) { @@ -991,6 +991,7 @@ } else { local @Data_Stack = (); + local %Refs_Seen = (); if( _deep_check($this, $that) ) { $ok = $Test->ok(1, $name); } @@ -1055,9 +1056,20 @@ =cut #'# -sub eq_array { +sub eq_array { + local %Refs_Seen; + _eq_array(@_); +} + +sub _eq_array { my($a1, $a2) = @_; return 1 if $a1 eq $a2; + if ($Refs_Seen{$a1}) { + return $Refs_Seen{$a1} eq $a2; + } + else { + $Refs_Seen{$a1} = "$a2"; + } my $ok = 1; my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2; @@ -1071,6 +1083,7 @@ last unless $ok; } + return $ok; } @@ -1090,12 +1103,12 @@ if( UNIVERSAL::isa($e1, 'ARRAY') and UNIVERSAL::isa($e2, 'ARRAY') ) { - $ok = eq_array($e1, $e2); + $ok = _eq_array($e1, $e2); } elsif( UNIVERSAL::isa($e1, 'HASH') and UNIVERSAL::isa($e2, 'HASH') ) { - $ok = eq_hash($e1, $e2); + $ok = _eq_hash($e1, $e2); } elsif( UNIVERSAL::isa($e1, 'REF') and UNIVERSAL::isa($e2, 'REF') ) @@ -1131,8 +1144,19 @@ =cut sub eq_hash { + local %Refs_Seen; + _eq_hash(@_); +} + +sub _eq_hash { my($a1, $a2) = @_; return 1 if $a1 eq $a2; + if ($Refs_Seen{$a1}) { + return $Refs_Seen{$a1} eq $a2; + } + else { + $Refs_Seen{$a1} = "$a2"; + } my $ok = 1; my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2; diff -Nurd Test-Simple-0.48_02.orig/t/refcycle.t Test-Simple-0.48_02/t/refcycle.t --- Test-Simple-0.48_02.orig/t/refcycle.t Thu Jan 1 02:00:00 1970 +++ Test-Simple-0.48_02/t/refcycle.t Sat Aug 7 17:40:26 2004 @@ -0,0 +1,32 @@ +#!perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; +use Test::More; + +plan tests => 3; + +my $a1 = [ 1, 2, 3 ]; +push @$a1, $a1; +my $a2 = [ 1, 2, 3 ]; +push @$a2, $a2; + +ok( eq_array ($a1, $a2) ); +ok( eq_set ($a1, $a2) ); + +my $h1 = { 1=>1, 2=>2, 3=>3 }; +$h1->{4} = $h1; +my $h2 = { 1=>1, 2=>2, 3=>3 }; +$h2->{4} = $h2; + +ok( eq_hash ($h1, $h2) );
Subject: is_deeply: out of memory error on circular references
I tried the attached code on AIX 4.3, Perl 5.8.0, Test::Simple 0.47 and on OS X 10.3.5, Perl 5.8.1-RC3, Test::Simple 0.48_02. The code results in an out of memory error. My ad hoc solution was to switch from is_deeply to Test::Differences for the particular tests. === #!/usr/bin/perl use warnings; use strict; package Container; sub new { bless {}, shift } package Object; sub new { my $self= bless {}, shift; $self->init; $self; } sub init { my $self = shift; $self->{child} = Container->new; $self->{child}{owner} = $self; } package Main; use Test::More tests => 1; my $this = Object->new; my $that = Object->new; is_deeply($this, $that, 'out of memory?'); ===
From: florian [...] cpan.org
[FLORIAN - Tue Aug 10 09:00:20 2004]: Show quoted text
> I tried the attached code on AIX 4.3, Perl 5.8.0, Test::Simple 0.47 > and on OS X 10.3.5, Perl 5.8.1-RC3, Test::Simple 0.48_02. > > The code results in an out of memory error.
Sorry that I missed that - I just saw that the patch posted in bug #7289 resolves this problem.