File Coverage

blib/lib/Test/LimitDecimalPlaces.pm
Criterion Covered Total %
statement 82 82 100.0
branch 24 24 100.0
condition 8 12 66.6
subroutine 15 15 100.0
pod 4 4 100.0
total 133 137 97.0


line stmt bran cond sub pod time code
1             package Test::LimitDecimalPlaces;
2              
3 10     10   234350 use warnings;
  10         26  
  10         359  
4 10     10   131 use strict;
  10         116  
  10         322  
5 10     10   54 use Carp;
  10         21  
  10         690  
6 10     10   51 use Exporter;
  10         19  
  10         347  
7 10     10   57 use Test::Builder;
  10         17  
  10         299  
8              
9 10     10   72 use vars qw/ $VERSION @EXPORT @ISA /;
  10         70  
  10         1156  
10              
11             BEGIN {
12 10     10   37 $VERSION = '0.01';
13 10         147 @ISA = qw/ Exporter /;
14 10         19345 @EXPORT = qw/ limit_ok limit_ok_by limit_not_ok limit_not_ok_by /;
15             }
16              
17             my $TestBuilder = Test::Builder->new;
18             my $default_num_of_digits = 7;
19              
20             sub import {
21 14     14   2430 my $self = shift;
22 14         50 my $pack = caller;
23 14         219 my $found = grep /num_of_digits/, @_;
24              
25 14 100       150 if ($found) {
26 5         21 my ( $key, $value ) = splice @_, 0, 2;
27              
28 5 100       32 if ( $value < 0 ) {
29 1         31 croak 'Value of limit number of digits must be a number greater than or equal to zero.';
30             }
31 4 100       19 unless ( $key eq 'num_of_digits' ) {
32 1         9 croak 'Test::LimitDecimalPlaces option must be specified first.';
33             }
34 3         9 $default_num_of_digits = $value;
35             }
36              
37 12         70 $TestBuilder->exported_to($pack);
38 12         144 $TestBuilder->plan(@_);
39 12         5857 $self->export_to_level( 1, $self, $_ ) for @EXPORT;
40             }
41              
42             sub _construct_err_msg {
43 23     23   48 my ( $x, $y, $num_of_digits ) = @_;
44              
45             return
46 23         198 sprintf( "%.${num_of_digits}f", $x ) . ' and '
47             . sprintf( "%.${num_of_digits}f", $y )
48             . ' are not equal by limiting decimal places is ' . $num_of_digits;
49             }
50              
51             sub _check {
52 91     91   135 my ( $x, $y, $num_of_digits ) = @_;
53              
54 91         113 my $is_array = 0;
55              
56 91 100       230 croak 'Value of limit number of digits must be a number '
57             . 'greater than or equal to zero.' if ( $num_of_digits < 0 );
58 90         102 $num_of_digits = int($num_of_digits);
59              
60 90         262 my ($ok, $diag) = (1, '');
61              
62 90 100 66     432 if (ref $x eq 'ARRAY' || ref $y eq 'ARRAY') {
63 12         16 $is_array = 1;
64 12 100       40 unless (scalar(@$x) == scalar(@$y)) {
65 3         6 $ok = 0;
66 3         13 $diag = "Got length of an array is " . scalar(@$x) .
67             ", but expected length of an array is " . scalar(@$y);
68 3         10 return ($ok, $diag);
69             }
70             }
71              
72 87 100       168 if ($is_array) {
73 9         28 for my $i ( 0 .. $#$x ) {
74 44         121 ($ok, $diag) = _check($x->[$i], $y->[$i], $num_of_digits);
75 44 100       117 unless ($ok) {
76 5         40 $diag .= ', number of element is ' . $i . ' in array';
77 5         11 last;
78             }
79             }
80             } else {
81 78         823 $ok = (
82             sprintf( "%.${num_of_digits}f", $x ) ==
83             sprintf( "%.${num_of_digits}f", $y ) );
84 78 100       207 $diag = _construct_err_msg( $x, $y, $num_of_digits ) unless ($ok);
85             }
86              
87 87         276 return ( $ok, $diag );
88             }
89              
90             sub _flip {
91 22     22   40 my ( $state, $x, $y, $num_of_digits, $is_array ) = @_;
92              
93 22         32 $state = !$state;
94 22         44 my $diag;
95 22 100       49 unless ($state) {
96 12 100       55 if ($is_array) {
97 1         2 $diag = 'Both of arrays are the same.';
98             } else {
99 11         26 $diag = _construct_err_msg( $x, $y, $num_of_digits );
100 11         50 $diag =~ s/ not//;
101             }
102             }
103              
104 22         75 return ( $state, $diag );
105             }
106              
107             sub limit_ok_by($$$;$) {
108 25     25 1 3008 my ( $x, $y, $num_of_digits, $test_name ) = @_;
109              
110 25         64 my ( $ok, $diag ) = _check( $x, $y, $num_of_digits, $test_name );
111 24   66     94 return $TestBuilder->ok( $ok, $test_name ) || $TestBuilder->diag($diag);
112             }
113              
114             sub limit_ok($$;$) {
115 16     16 1 9217 my ( $x, $y, $test_name ) = @_;
116              
117             {
118 16         21 local $Test::Builder::Level = $Test::Builder::Level + 1;
  16         29  
119 16         42 limit_ok_by( $x, $y, $default_num_of_digits, $test_name );
120             }
121             }
122              
123             sub limit_not_ok_by($$$;$) {
124 22     22 1 6939 my ( $x, $y, $num_of_digits, $test_name ) = @_;
125              
126 22         30 my $is_array = 0;
127 22 100 66     163 $is_array = 1 if (ref $x eq 'ARRAY' || ref $y eq 'ARRAY' );
128              
129 22         79 my ( $ok, $diag ) = _check( $x, $y, $num_of_digits, $test_name );
130 22         91 ( $ok, $diag ) = _flip( $ok, $x, $y, $num_of_digits, $is_array );
131 22   66     96 return $TestBuilder->ok( $ok, $test_name ) || $TestBuilder->diag($diag);
132             }
133              
134             sub limit_not_ok($$;$) {
135 15     15 1 9161 my ( $x, $y, $test_name ) = @_;
136              
137             {
138 15         27 local $Test::Builder::Level = $Test::Builder::Level + 1;
  15         29  
139 15         35 limit_not_ok_by( $x, $y, $default_num_of_digits, $test_name );
140             }
141             }
142              
143             1;
144             __END__