#!/usr/bin/env perl

use 5.008;

use strict;
use warnings;

use Test::More;

use Test::Approximate;

set_dop(3);

my @cases = # DOP = 3
  map  { [122.9 * 10**$_, 123 * 10**$_ ] }
  sort { $a <=> $b } 0, map { $_, -$_ }  1, 2, 3, 4, 10, 20, 40, 80;
my $fmt_isnt = my $fmt_is = "case %-0g ~ %-0g";
$fmt_isnt =~ s/~/!~/;

note "positive matches (DOP = 3)";

for my $case (@cases) {
    my ($actual, $expected) = @$case;
    is_approx $actual, $expected, sprintf $fmt_is, $actual, $expected;
}

note "negative matches (DOP = 3)";

for my $case (@cases) {
    my ($actual, $expected) = @$case;
    $_ *= -1 for $actual, $expected;
    is_approx $actual, $expected, sprintf $fmt_is, $actual, $expected;
}

note "positive mismatches (DOP = 3)";

for my $case (@cases) {
    my ($actual, $expected) = @$case;
    $actual *= 1.01;
    isnt_approx $actual, $expected, sprintf $fmt_isnt, $actual, $expected;
}

note "negative mismatches (DOP = 3)";

for my $case (@cases) {
    my ($actual, $expected) = @$case;
    $_ *= -1 for $actual, $expected;
    $actual *= 1.01;
    isnt_approx $actual, $expected, sprintf $fmt_isnt, $actual, $expected;
}

note "more precision (DOP = 8)";

set_dop(8);

is_approx 1234.56784, 1234.5678, "Match against high value";

isnt_approx 1234.56786, 1234.5678, "Mis-match against high value";
isnt_approx 1234.56774, 1234.5678, "Mis-match against low value";

note "rounding error bug";

set_dop(8);

isnt_approx 1234.56775000, 1234.5678, "Looks ok, but doesn't match";
is_approx 1234.56775001, 1234.5678, "Doesn't look ok, but matched";

note "zeros (DOP = 2)";

set_dop(2);

isnt_approx 0.010, 0, "0.010 doesn't match 0";
is_approx   0.001, 0, "0.001 does match 0";

isnt_approx -0.010, 0, "-0.010 doesn't match 0";
is_approx   -0.001, 0, "-0.001 does match 0";

isnt_approx -0.01, 0.01, "-0.01 doesn't match 0.01";

done_testing;
