X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fop%2Fsort.t;h=c7d2891654f61db8bea0de81de15d87e0b747fce;hb=a1824f2aba8e109cac73756dc271522cdd4a8200;hp=9095871a295df7211352e865b0ca1ccfc38719da;hpb=20822f61cc01ab34be1e17db483aceb9d5ec8fb7;p=p5sagit%2Fp5-mst-13.2.git diff --git a/t/op/sort.t b/t/op/sort.t index 9095871..c7d2891 100755 --- a/t/op/sort.t +++ b/t/op/sort.t @@ -5,13 +5,7 @@ BEGIN { @INC = '../lib'; } use warnings; -print "1..57\n"; - -# XXX known to leak scalars -{ - no warnings 'uninitialized'; - $ENV{PERL_DESTRUCT_LEVEL} = 0 unless $ENV{PERL_DESTRUCT_LEVEL} > 3; -} +print "1..115\n"; # these shouldn't hang { @@ -321,3 +315,294 @@ sub cxt_six { sort test_if_scalar 1,2 } print "# x = '@b'\n"; print !$def ? "ok 57\n" : "not ok 57\n"; } + +# Bug 19991001.003 +{ + sub routine { "one", "two" }; + @a = sort(routine(1)); + print "@a" eq "one two" ? "ok 58\n" : "not ok 58\n"; +} + + +my $test = 59; +sub ok { + print "not " unless $_[0] eq $_[1]; + print "ok $test - $_[2]\n"; + print "#[$_[0]] ne [$_[1]]\n" unless $_[0] eq $_[1]; + $test++; +} + +# check for in-place optimisation of @a = sort @a +{ + my ($r1,$r2,@a); + our @g; + @g = (3,2,1); $r1 = \$g[2]; @g = sort @g; $r2 = \$g[0]; + ok "$r1-@g", "$r2-1 2 3", "inplace sort of global"; + + @a = qw(b a c); $r1 = \$a[1]; @a = sort @a; $r2 = \$a[0]; + ok "$r1-@a", "$r2-a b c", "inplace sort of lexical"; + + @g = (2,3,1); $r1 = \$g[1]; @g = sort { $b <=> $a } @g; $r2 = \$g[0]; + ok "$r1-@g", "$r2-3 2 1", "inplace reversed sort of global"; + + @g = (2,3,1); + $r1 = \$g[1]; @g = sort { $a<$b?1:$a>$b?-1:0 } @g; $r2 = \$g[0]; + ok "$r1-@g", "$r2-3 2 1", "inplace custom sort of global"; + + sub mysort { $b cmp $a }; + @a = qw(b c a); $r1 = \$a[1]; @a = sort mysort @a; $r2 = \$a[0]; + ok "$r1-@a", "$r2-c b a", "inplace sort with function of lexical"; + + use Tie::Array; + my @t; + tie @t, 'Tie::StdArray'; + + @t = qw(b c a); @t = sort @t; + ok "@t", "a b c", "inplace sort of tied array"; + + @t = qw(b c a); @t = sort mysort @t; + ok "@t", "c b a", "inplace sort of tied array with function"; + + # [perl #29790] don't optimise @a = ('a', sort @a) ! + + @g = (3,2,1); @g = ('0', sort @g); + ok "@g", "0 1 2 3", "un-inplace sort of global"; + @g = (3,2,1); @g = (sort(@g),'4'); + ok "@g", "1 2 3 4", "un-inplace sort of global 2"; + + @a = qw(b a c); @a = ('x', sort @a); + ok "@a", "x a b c", "un-inplace sort of lexical"; + @a = qw(b a c); @a = ((sort @a), 'x'); + ok "@a", "a b c x", "un-inplace sort of lexical 2"; + + @g = (2,3,1); @g = ('0', sort { $b <=> $a } @g); + ok "@g", "0 3 2 1", "un-inplace reversed sort of global"; + @g = (2,3,1); @g = ((sort { $b <=> $a } @g),'4'); + ok "@g", "3 2 1 4", "un-inplace reversed sort of global 2"; + + @g = (2,3,1); @g = ('0', sort { $a<$b?1:$a>$b?-1:0 } @g); + ok "@g", "0 3 2 1", "un-inplace custom sort of global"; + @g = (2,3,1); @g = ((sort { $a<$b?1:$a>$b?-1:0 } @g),'4'); + ok "@g", "3 2 1 4", "un-inplace custom sort of global 2"; + + @a = qw(b c a); @a = ('x', sort mysort @a); + ok "@a", "x c b a", "un-inplace sort with function of lexical"; + @a = qw(b c a); @a = ((sort mysort @a),'x'); + ok "@a", "c b a x", "un-inplace sort with function of lexical 2"; +} + +# Test optimisations of reversed sorts. As we now guarantee stability by +# default, # optimisations which do not provide this are bogus. + +{ + package Oscalar; + use overload (qw("" stringify 0+ numify fallback 1)); + + sub new { + bless [$_[1], $_[2]], $_[0]; + } + + sub stringify { $_[0]->[0] } + + sub numify { $_[0]->[1] } +} + +sub generate { + my $count = 0; + map {new Oscalar $_, $count++} qw(A A A B B B C C C); +} + +my @input = &generate; +my @output = sort @input; +ok join(" ", map {0+$_} @output), "0 1 2 3 4 5 6 7 8", "Simple stable sort"; + +@input = &generate; +@input = sort @input; +ok join(" ", map {0+$_} @input), "0 1 2 3 4 5 6 7 8", + "Simple stable in place sort"; + +# This won't be very interesting +@input = &generate; +@output = sort {$a <=> $b} @input; +ok "@output", "A A A B B B C C C", 'stable $a <=> $b sort'; + +@input = &generate; +@output = sort {$a cmp $b} @input; +ok join(" ", map {0+$_} @output), "0 1 2 3 4 5 6 7 8", 'stable $a cmp $b sort'; + +@input = &generate; +@input = sort {$a cmp $b} @input; +ok join(" ", map {0+$_} @input), "0 1 2 3 4 5 6 7 8", + 'stable $a cmp $b in place sort'; + +@input = &generate; +@output = sort {$b cmp $a} @input; +ok join(" ", map {0+$_} @output), "6 7 8 3 4 5 0 1 2", 'stable $b cmp $a sort'; + +@input = &generate; +@input = sort {$b cmp $a} @input; +ok join(" ", map {0+$_} @input), "6 7 8 3 4 5 0 1 2", + 'stable $b cmp $a in place sort'; + +@input = &generate; +@output = reverse sort @input; +ok join(" ", map {0+$_} @output), "8 7 6 5 4 3 2 1 0", "Reversed stable sort"; + +@input = &generate; +@input = reverse sort @input; +ok join(" ", map {0+$_} @input), "8 7 6 5 4 3 2 1 0", + "Reversed stable in place sort"; + +@input = &generate; +my $output = reverse sort @input; +ok $output, "CCCBBBAAA", "Reversed stable sort in scalar context"; + + +@input = &generate; +@output = reverse sort {$a cmp $b} @input; +ok join(" ", map {0+$_} @output), "8 7 6 5 4 3 2 1 0", + 'reversed stable $a cmp $b sort'; + +@input = &generate; +@input = reverse sort {$a cmp $b} @input; +ok join(" ", map {0+$_} @input), "8 7 6 5 4 3 2 1 0", + 'revesed stable $a cmp $b in place sort'; + +@input = &generate; +$output = reverse sort @input; +ok $output, "CCCBBBAAA", 'Reversed stable $a cmp $b sort in scalar context'; + +@input = &generate; +@output = reverse sort {$b cmp $a} @input; +ok join(" ", map {0+$_} @output), "2 1 0 5 4 3 8 7 6", + 'reversed stable $b cmp $a sort'; + +@input = &generate; +@input = reverse sort {$b cmp $a} @input; +ok join(" ", map {0+$_} @input), "2 1 0 5 4 3 8 7 6", + 'revesed stable $b cmp $a in place sort'; + +@input = &generate; +$output = reverse sort {$b cmp $a} @input; +ok $output, "AAABBBCCC", 'Reversed stable $b cmp $a sort in scalar context'; + +sub sortr { + reverse sort @_; +} + +@output = sortr &generate; +ok join(" ", map {0+$_} @output), "8 7 6 5 4 3 2 1 0", + 'reversed stable sort return list context'; +$output = sortr &generate; +ok $output, "CCCBBBAAA", + 'reversed stable sort return scalar context'; + +sub sortcmpr { + reverse sort {$a cmp $b} @_; +} + +@output = sortcmpr &generate; +ok join(" ", map {0+$_} @output), "8 7 6 5 4 3 2 1 0", + 'reversed stable $a cmp $b sort return list context'; +$output = sortcmpr &generate; +ok $output, "CCCBBBAAA", + 'reversed stable $a cmp $b sort return scalar context'; + +sub sortcmprba { + reverse sort {$b cmp $a} @_; +} + +@output = sortcmprba &generate; +ok join(" ", map {0+$_} @output), "2 1 0 5 4 3 8 7 6", + 'reversed stable $b cmp $a sort return list context'; +$output = sortcmprba &generate; +ok $output, "AAABBBCCC", +'reversed stable $b cmp $a sort return scalar context'; + +# And now with numbers + +sub generate1 { + my $count = 'A'; + map {new Oscalar $count++, $_} 0, 0, 0, 1, 1, 1, 2, 2, 2; +} + +# This won't be very interesting +@input = &generate1; +@output = sort {$a cmp $b} @input; +ok "@output", "A B C D E F G H I", 'stable $a cmp $b sort'; + +@input = &generate1; +@output = sort {$a <=> $b} @input; +ok "@output", "A B C D E F G H I", 'stable $a <=> $b sort'; + +@input = &generate1; +@input = sort {$a <=> $b} @input; +ok "@input", "A B C D E F G H I", 'stable $a <=> $b in place sort'; + +@input = &generate1; +@output = sort {$b <=> $a} @input; +ok "@output", "G H I D E F A B C", 'stable $b <=> $a sort'; + +@input = &generate1; +@input = sort {$b <=> $a} @input; +ok "@input", "G H I D E F A B C", 'stable $b <=> $a in place sort'; + +# These two are actually doing string cmp on 0 1 and 2 +@input = &generate1; +@output = reverse sort @input; +ok "@output", "I H G F E D C B A", "Reversed stable sort"; + +@input = &generate1; +@input = reverse sort @input; +ok "@input", "I H G F E D C B A", "Reversed stable in place sort"; + +@input = &generate1; +$output = reverse sort @input; +ok $output, "IHGFEDCBA", "Reversed stable sort in scalar context"; + +@input = &generate1; +@output = reverse sort {$a <=> $b} @input; +ok "@output", "I H G F E D C B A", 'reversed stable $a <=> $b sort'; + +@input = &generate1; +@input = reverse sort {$a <=> $b} @input; +ok "@input", "I H G F E D C B A", 'revesed stable $a <=> $b in place sort'; + +@input = &generate1; +$output = reverse sort {$a <=> $b} @input; +ok $output, "IHGFEDCBA", 'reversed stable $a <=> $b sort in scalar context'; + +@input = &generate1; +@output = reverse sort {$b <=> $a} @input; +ok "@output", "C B A F E D I H G", 'reversed stable $b <=> $a sort'; + +@input = &generate1; +@input = reverse sort {$b <=> $a} @input; +ok "@input", "C B A F E D I H G", 'revesed stable $b <=> $a in place sort'; + +@input = &generate1; +$output = reverse sort {$b <=> $a} @input; +ok $output, "CBAFEDIHG", 'reversed stable $b <=> $a sort in scalar context'; + + +sub sortnumr { + reverse sort {$a <=> $b} @_; +} + +@output = sortnumr &generate1; +ok "@output", "I H G F E D C B A", + 'reversed stable $a <=> $b sort return list context'; +$output = sortnumr &generate1; +ok $output, "IHGFEDCBA", + 'reversed stable $a <=> $b sort return scalar context'; + +sub sortnumrba { + reverse sort {$b <=> $a} @_; +} + +@output = sortnumrba &generate1; +ok "@output", "C B A F E D I H G", + 'reversed stable $b <=> $a sort return list context'; +$output = sortnumrba &generate1; +ok $output, "CBAFEDIHG", +'reversed stable $b <=> $a sort return scalar context';