File Coverage

blib/lib/Assert/Refute/T/Numeric.pm
Criterion Covered Total %
statement 30 30 100.0
branch 15 18 83.3
condition 6 12 50.0
subroutine 9 9 100.0
pod n/a
total 60 69 86.9


line stmt bran cond sub pod time code
1             package Assert::Refute::T::Numeric;
2              
3 1     1   441 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         44  
5             our $VERSION = '0.1501';
6              
7             =head1 NAME
8              
9             Assert::Refute::T::Numeric - Numeric tests for Assert::Refute suite.
10              
11             =head1 SYNOPSIS
12              
13             Somewhere in your unit-test:
14              
15             use Test::More;
16             use Assert::Refute::T::Numeric; # must come *after* Test::More
17              
18             is_between 4 * atan2( 1, 1 ), 3.1415, 3.1416, "Pi number as expected";
19              
20             within_delta sqrt(sqrt(sqrt(10)))**8, 10, 1e-9, "floating point round-trip";
21              
22             within_relative 2**20, 1_000_000, 0.1, "10% precision for 1 mbyte";
23              
24             done_testing;
25              
26             Same for production code:
27              
28             use Assert::Refute;
29             use Assert::Refute::T::Numeric;
30              
31             my $rotate = My::Rotation::Matrix->new( ... );
32             try_refute {
33             within_delta $rotate->determinant, 1, 1e-6, "Rotation keeps distance";
34             };
35              
36             my $total = calculate_price();
37             try_refute {
38             is_between $total, 1, 100, "Price within reasonable limits";
39             };
40              
41             =cut
42              
43 1     1   6 use Carp;
  1         1  
  1         66  
44 1     1   6 use Scalar::Util qw(looks_like_number);
  1         2  
  1         50  
45 1     1   7 use parent qw(Exporter);
  1         2  
  1         6  
46              
47 1     1   49 use Assert::Refute::Build;
  1         2  
  1         428  
48              
49             =head2 is_between $x, $lower, $upper, [$message]
50              
51             Note that $x comes first and I between boundaries.
52              
53             =cut
54              
55             build_refute is_between => sub {
56 7     7   16 my ($x, $min, $max) = @_;
57              
58 7 50 33     30 croak "Non-numeric boundaries: ".to_scalar($min, 0).",".to_scalar($max, 0)
59             unless looks_like_number $min and looks_like_number $max;
60              
61 7 100       20 return "Not a number: ".to_scalar($x, 0)
62             unless looks_like_number $x;
63              
64 5 100 100     29 return $min <= $x && $x <= $max ? '' : "$x is not in [$min, $max]";
65             }, args => 3, export => 1;
66              
67             =head2 within_delta $x, $expected, $delta, [$message]
68              
69             Test that $x differs from $expected value by no more than $delta.
70              
71             =cut
72              
73             build_refute within_delta => sub {
74 4     4   8 my ($x, $exp, $delta) = @_;
75              
76 4 50 33     22 croak "Non-numeric boundaries: ".to_scalar($exp, 0)."+-".to_scalar($delta, 0)
77             unless looks_like_number $exp and looks_like_number $delta;
78              
79 4 100       14 return "Not a number: ".to_scalar($x, 0)
80             unless looks_like_number $x;
81              
82 2 100       21 return abs($x - $exp) <= $delta ? '' : "$x is not in [$exp +- $delta]";
83             }, args => 3, export => 1;
84              
85             =head2 within_relative $x, $expected, $delta, [$message]
86              
87             Test that $x differs from $expected value by no more than $expected * $delta.
88              
89             =cut
90              
91             build_refute within_relative => sub {
92 4     4   9 my ($x, $exp, $delta) = @_;
93              
94 4 50 33     21 croak "Non-numeric boundaries: ".to_scalar($exp, 0)."+-".to_scalar($delta, 0)
95             unless looks_like_number $exp and looks_like_number $delta;
96              
97 4 100       14 return "Not a number: ".to_scalar($x, 0)
98             unless looks_like_number $x;
99              
100 2 100       18 return abs($x - $exp) <= abs($exp * $delta)
101             ? ''
102             : "$x differs from $exp by more than ".$exp*$delta;
103             }, args => 3, export => 1;
104              
105             =head1 SEE ALSO
106              
107             L.
108              
109             =head1 LICENSE AND COPYRIGHT
110              
111             This module is part of L suite.
112              
113             Copyright 2017-2018 Konstantin S. Uvarin. C<< >>
114              
115             This program is free software; you can redistribute it and/or modify it
116             under the terms of the the Artistic License (2.0). You may obtain a
117             copy of the full license at:
118              
119             L
120              
121             =cut
122              
123             1;