#!perl -w
# $Id: 00_regression.t,v 1.5 2008/07/25 13:25:47 drhyde Exp $
use strict;
use Test::More tests => 19;
use Sort::MultipleFields qw(mfsort mfsortmaker);
my $library = [
{ author => 'Hoyle', title => 'Black Cloud, The' },
{ author => 'Clarke', title => 'Rendezvous with Rama' },
{ author => 'Clarke', title => 'Prelude to Space' },
{ author => 'Clarke', title => 'Islands In The Sky' },
{ author => 'Asimov', title => 'Pebble in the Sky' },
{ author => 'Asimov', title => 'Foundation' },
{ author => 'Asimov', title => 'David Starr, Space Ranger' }
];
my $numbers = [map { { value => $_ } } qw(100 10 1 11)];
# shortcut aliases
is_deeply(
scalar(mfsort(sub { author => 'aSc' }, $library)),
scalar(mfsort(sub { author => 'ascEnding' }, @{$library})),
"asc == ascending (case-insensitively)"
);
is_deeply(
scalar(mfsort(sub { author => 'desC' }, $library)),
scalar(mfsort(sub { author => 'deScending' }, @{$library})),
"desc == descending (case-insensitively)"
);
is_deeply(
scalar(mfsort(sub { value => 'numasC' }, $numbers)),
scalar(mfsort(sub { value => 'nuMascending' }, $numbers)),
"numasc == numascending (case-insensitively)"
);
is_deeply(
scalar(mfsort(sub { value => 'numdesC' }, $numbers)),
scalar(mfsort(sub { value => 'nuMdescending' }, $numbers)),
"numdesc == numdescending (case-insensitively)"
);
# list/scalar input/output
my @foo = mfsort sub { author => 'desc' }, $library;
ok(@foo == 7, "returns a list in list context");
ok(ref(scalar(mfsort(sub { author => 'desc' }, $library))),
"returns a ref in scalar context");
is_deeply(
scalar(mfsort(sub { author => 'asc' }, $library)),
scalar(mfsort(sub { author => 'asc' }, @{$library})),
"Records can be listref or list, makes no difference"
);
# shortcuts sort correctly
is_deeply(
[map { $_->{author} } mfsort(sub { author => 'asc' }, $library)],
[reverse qw(Hoyle Clarke Clarke Clarke Asimov Asimov Asimov)],
'asc sorts text correctly'
);
is_deeply(
[map { $_->{author} } mfsort(sub { author => 'desc' }, $library)],
[qw(Hoyle Clarke Clarke Clarke Asimov Asimov Asimov)],
'desc sorts text correctly'
);
is_deeply(
[map { $_->{value} } mfsort(sub { value => 'asc' }, $numbers)],
[qw(1 10 100 11)],
"asc sorts numbers ASCIIbetically"
);
is_deeply(
[map { $_->{value} } mfsort(sub { value => 'desc' }, $numbers)],
[reverse qw(1 10 100 11)],
"desc sorts numbers ASCIIbetically"
);
is_deeply(
[map { $_->{value} } mfsort(sub { value => 'numasc' }, $numbers)],
[qw(1 10 11 100)],
"numasc sorts numerically"
);
is_deeply(
[map { $_->{value} } mfsort(sub { value => 'numdesc' }, $numbers)],
[reverse qw(1 10 11 100)],
"numdesc sorts numerically"
);
# sort function instead of shortcut
is_deeply(
[map { $_->{author} } mfsort(
# this should sort C, then H, then A
sub { author => sub {
return -1 if($_[0] =~ '^C');
return 1 if($_[1] =~ '^C');
return 1 if($_[0] =~ '^A');
return -1 if($_[1] =~ '^A');
return 0;
} },
$library
)],
[qw(Clarke Clarke Clarke Hoyle Asimov Asimov Asimov)],
'user-supplied sort function works'
);
is_deeply(
[mfsort sub { author => 'asc', title => 'asc' }, $library],
[
{ author => 'Asimov', title => 'David Starr, Space Ranger' },
{ author => 'Asimov', title => 'Foundation' },
{ author => 'Asimov', title => 'Pebble in the Sky' },
{ author => 'Clarke', title => 'Islands In The Sky' },
{ author => 'Clarke', title => 'Prelude to Space' },
{ author => 'Clarke', title => 'Rendezvous with Rama' },
{ author => 'Hoyle', title => 'Black Cloud, The' },
],
"two-field sort works"
);
is_deeply(
# sort by author, title, and reverse publication date
[mfsort sub { author => 'asc', title => 'asc', year => 'desc' }, [
# unsort the input ...
sort {
rand() < 0.5 ? -1 : 1
} map {
{ %{$_}, year => 2001 },
{ %{$_}, year => 2002 },
{ %{$_}, year => 2003 },
} @{$library}
]],
[
map {
{ %{$_}, year => 2003 },
{ %{$_}, year => 2002 },
{ %{$_}, year => 2001 },
} mfsort sub {
author => 'asc', title => 'asc'
}, $library
],
"three-field sort works"
);
my $crazysort = sub {
author => 'asc',
title => 'asc',
year => 'desc',
colour => sub {
my @in = map {
$_ eq 'red' ? 0 :
$_ eq 'orange' ? 1 :
$_ eq 'yellow' ? 2 :
$_ eq 'green' ? 3 :
$_ eq 'blue' ? 4 :
$_ eq 'indigo' ? 5 :
6
} @_;
$in[0] <=> $in[1];
}
};
my $crazyinput = [
sort {
rand() < 0.5 ? -1 : 1
} map {
{ %{$_}, year => 2001 },
{ %{$_}, year => 2002 },
{ %{$_}, year => 2003 },
} map {
my $in = $_;
map { { %{$in}, colour => $_ } }
qw(red orange yellow green blue indigo violet)
} @{$library}
];
my $crazyoutput = [
map {
my $in = $_;
map { { %{$in}, colour => $_ } }
qw(red orange yellow green blue indigo violet)
} map {
{ %{$_}, year => 2003 },
{ %{$_}, year => 2002 },
{ %{$_}, year => 2001 },
} mfsort sub {
author => 'asc', title => 'asc'
}, $library
];
is_deeply(
# sort by author, title, reverse publication date, and colour(!)
[mfsort \&{$crazysort}, $crazyinput],
$crazyoutput,
"four-field sort works, including a Mad Sort"
);
# sort function instead of shortcut
my $usersupplied = mfsortmaker(sub {
author => sub {
return -1 if($_[0] =~ '^C');
return 1 if($_[1] =~ '^C');
return 1 if($_[0] =~ '^A');
return -1 if($_[1] =~ '^A');
return 0;
}
});
is_deeply(
[map { $_->{author} } sort $usersupplied @{$library}],
[qw(Clarke Clarke Clarke Hoyle Asimov Asimov Asimov)],
'mfsortmaker works'
);
$crazysort = mfsortmaker($crazysort);
is_deeply(
# sort by author, title, reverse publication date, and colour(!)
[sort $crazysort @{$crazyinput}],
$crazyoutput,
"mfsortmaker even works for a really crazy sort spec"
);