From: Nicholas Clark Date: Mon, 18 Apr 2011 11:12:37 +0000 (+0100) Subject: Test that unallocated gaps within arrays have zero size. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit%2FDevel-Size.git;a=commitdiff_plain;h=1d6fef943eaa10527312a01e19d4b7ae4044c16d Test that unallocated gaps within arrays have zero size. This gets to be a bit more complex than it would first seem, as Test::More's is_deeply() gets the length of arrays using $#array syntax, and that operation allocates structures within the array prior to 5.12. We can't use stringification, as we need to test undefs, so roll our own minimal test subroutine. --- diff --git a/t/recurse.t b/t/recurse.t index 08524b1..4bebab2 100644 --- a/t/recurse.t +++ b/t/recurse.t @@ -6,11 +6,10 @@ # total_size([]) will NOT return the size of the ref + the array, it will only # return the size of the array alone! -use Test::More tests => 3 + 4 *12; +use Test::More tests => 16 + 4 *12; use strict; use Devel::Size ':all'; - ############################################################################# # verify that pointer sizes in array slots are sensible: # create an array with 4 slots, 2 of them used @@ -184,3 +183,51 @@ for my $size (2, 3, 7, 100) is ($full_hash, $element_size + $hash_size, 'properly handles undef/non-undef inside arrays'); } # end for different sizes + +sub cmp_array_ro { + my($got, $want, $desc) = @_; + local $Test::Builder::Level = $Test::Builder::Level + 1; + is(@$got, @$want, "$desc (same element count)"); + my $i = @$want; + while ($i--) { + is($got->[$i], $want->[$i], "$desc (element $i)"); + } +} + +{ + my $undef; + my $undef_size = total_size($undef); + cmp_ok($undef_size, '>', 0, 'non-zero size for NULL'); + + my $iv_size = total_size(1); + cmp_ok($iv_size, '>', 0, 'non-zero size for IV'); + + # Force the array to allocate storage for elements. + # This avoids making the assumption that just because it doesn't happen + # initially now, it won't stay that way forever. + my @array = 42; + my $array_1_size = total_size(\@array); + cmp_ok($array_1_size, '>', 0, 'non-zero size for array with 1 element'); + + $array[2] = 6 * 9; + + my @copy = @array; + + # This might be making too many assumptions about the current implementation + my $array_2_size = total_size(\@array); + is($array_2_size, $array_1_size + $iv_size, + "gaps in arrays don't allocate scalars"); + + # Avoid using is_deeply() as that will read $#array, which is a write + # action prior to 5.12. (Different writes on 5.10 and 5.8-and-earlier, but + # a write either way, allocating memory. + cmp_array_ro(\@array, \@copy, 'two arrays compare the same'); + + # A write action: + $array[1] = undef; + + is(total_size(\@array), $array_2_size + $undef_size, + "assigning undef to a gap in an array allocates a scalar"); + + cmp_array_ro(\@array, \@copy, 'two arrays compare the same'); +}