1#!perl
2
3use strict ("subs", "vars", "refs");
4use warnings ("all");
5BEGIN { $ENV{LIST_MOREUTILS_PP} = 0; }
6END { delete $ENV{LIST_MOREUTILS_PP} } # for VMS
7use List::MoreUtils (":all");
8use lib ("t/lib");
9
10
11use Test::More;
12use Test::LMU;
13
14my @list = reverse 0 .. 10000;
15my ($min, $max) = minmax @list;
16is($min, 0);
17is($max, 10000);
18
19# Even number of elements
20push @list, 10001;
21($min, $max) = minmax @list;
22is($min, 0);
23is($max, 10001);
24$list[0] = 17;
25
26# Some floats
27@list = (0, -1.1, 3.14, 1 / 7, 10000, -10 / 3);
28($min, $max) = minmax @list;
29
30# Floating-point comparison cunningly avoided
31is(sprintf("%.2f", $min), "-3.33");
32is($max,                  10000);
33
34# Test with a single negative list value
35my $input = -1;
36($min, $max) = minmax $input;
37is($min, -1);
38is($max, -1);
39
40# COW causes missing max when optimization for 1 argument is applied
41@list = grep { defined $_ } map { my ($min, $max) = minmax(sprintf("%.3g", rand)); ($min, $max) } (0 .. 19);
42is(scalar @list, 40, "minmax swallows max on COW");
43
44# Confirm output are independant copies of input
45$input = 1;
46is($min, -1);
47is($max, -1);
48$min = 2;
49is($max, -1);
50
51# prove overrun
52my $uvmax    = ~0;
53my $ivmax    = $uvmax >> 1;
54my $ivmin    = (0 - $ivmax) - 1;
55my @low_ints = map { $ivmin + $_ } (0 .. 10);
56($min, $max) = minmax @low_ints;
57is($min, $ivmin,      "minmax finds ivmin");
58is($max, $ivmin + 10, "minmax finds ivmin + 10");
59
60my @high_ints = map { $ivmax - $_ } (0 .. 10);
61($min, $max) = minmax @high_ints;
62is($min, $ivmax - 10, "minmax finds ivmax-10");
63is($max, $ivmax,      "minmax finds ivmax");
64
65my @mixed_ints = map { ($ivmin + $_, $ivmax - $_) } (0 .. 10);
66($min, $max) = minmax @mixed_ints;
67is($min, $ivmin, "minmax finds ivmin");
68is($max, $ivmax, "minmax finds ivmax");
69
70my @high_uints = map { $uvmax - $_ } (0 .. 10);
71($min, $max) = minmax @high_uints;
72is($min, $uvmax - 10, "minmax finds uvmax-10");
73is($max, $uvmax,      "minmax finds uvmax");
74
75my @mixed_nums = map { ($ivmin + $_, $uvmax - $_) } (0 .. 10);
76($min, $max) = minmax @mixed_nums;
77is($min, $ivmin, "minmax finds ivmin");
78is($max, $uvmax, "minmax finds uvmax");
79
80leak_free_ok(
81    minmax => sub {
82        @list = (0, -1.1, 3.14, 1 / 7, 10000, -10 / 3);
83        ($min, $max) = minmax @list;
84    }
85);
86
87done_testing;
88
89
90