File Coverage

blib/lib/Test/BinaryData.pm
Criterion Covered Total %
statement 74 75 98.6
branch 20 26 76.9
condition 12 16 75.0
subroutine 8 8 100.0
pod 1 1 100.0
total 115 126 91.2


line stmt bran cond sub pod time code
1 1     1   30069 use strict;
  1         3  
  1         79  
2 1     1   6 use warnings;
  1         2  
  1         46  
3             package Test::BinaryData;
4             {
5             $Test::BinaryData::VERSION = '0.014';
6             }
7             # ABSTRACT: compare two things, give hex dumps if they differ
8              
9 1     1   27 use 5.006;
  1         4  
  1         42  
10              
11              
12 1     1   5 use Carp ();
  1         13  
  1         20  
13 1     1   5 use Test::Builder;
  1         2  
  1         875  
14             require Exporter;
15             @Test::BinaryData::ISA = qw(Exporter);
16             @Test::BinaryData::EXPORT = qw(is_binary);
17              
18             sub import {
19 1     1   9 my($self) = shift;
20 1         3 my $pack = caller;
21              
22 1         4 my $Test = Test::Builder->new;
23              
24 1         63 $Test->exported_to($pack);
25 1 50       27 $Test->plan(@_) if @_;
26              
27 1         178 $self->export_to_level(1, $self, @Test::BinaryData::EXPORT);
28             }
29              
30              
31             sub _widths {
32 10     10   21 my ($total) = @_;
33              
34 10         20 $total = $total
35             - 2 # the "# " that begins each diagnostics line
36             - 3 # the " ! " or " = " line between got / expected
37             - 2 # the space between hex/ascii representations
38             ;
39              
40 10         28 my $sixth = int($total / 6);
41 10         36 return ($sixth * 2, $sixth);
42             }
43              
44             sub is_binary {
45 10     10 1 35209 my ($have, $want, $comment, $arg) = @_;
46              
47 10         47 my $Test = Test::Builder->new;
48              
49 10   100     84 $arg ||= {};
50              
51 10 50       43 unless (defined $arg->{columns}) {
52 10 50 50     121 if (($ENV{COLUMNS}||'') =~ /\A\d+\z/ and $ENV{COLUMNS} > 0) {
      33        
53 10         53 $arg->{columns} = $ENV{COLUMNS} - 1;
54             } else {
55 0         0 $arg->{columns} = 79;
56             }
57             }
58              
59 10 50       30 Carp::croak 'minimum columns is 44' if $arg->{columns} < 44;
60              
61 10         33 my ($hw, $aw) = _widths($arg->{columns});
62              
63 10 100       35 if (ref $want) {
64 1         3 $want = join q{}, map { chr hex } map { unpack "(a2)*", $_ } @$want;
  12         20  
  6         19  
65             }
66              
67 10         292 my $have_is_wide = grep { ord > 255 } split //, $have;
  1523         2422  
68 10         329 my $want_is_wide = grep { ord > 255 } split //, $want;
  1553         2539  
69              
70 10 100 66     175 if ($have_is_wide or $want_is_wide) {
71 1         9 $Test->ok(0, $comment);
72              
73 1 50       131 $Test->diag("value for 'have' contains wide bytes") if $have_is_wide;
74 1 50       34 $Test->diag("value for 'want' contains wide bytes") if $want_is_wide;
75              
76 1         27 return;
77             }
78              
79 9 100       28 if ($have eq $want) {
80 2         26 return $Test->ok(1, $comment);
81             }
82              
83 7         64 $Test->ok(0, $comment);
84              
85 7         1087 my $max_length = (sort map { length($_) } $have, $want)[1];
  14         74  
86              
87             $Test->diag(
88             sprintf "%-${hw}s %-${aw}s %-${hw}s %-${aw}s",
89 7         37 map {; "$_ (hex)", "$_" } qw(have want)
  14         151  
90             );
91              
92 7         272 my $seen_diffs = 0;
93 7         29 CHUNK: for (my $pos = 0; $pos < $max_length; $pos += $aw) {
94 80 100 100     263 if ($arg->{max_diffs} and $seen_diffs == $arg->{max_diffs}) {
95 2         10 $Test->diag("...");
96 2         59 last CHUNK;
97             }
98              
99 78         151 my $g_substr = substr($have, $pos, $aw);
100 78         125 my $e_substr = substr($want, $pos, $aw);
101              
102 78         133 my $eq = $g_substr eq $e_substr;
103              
104 891         2247 my $g_hex =
105             join q{},
106 78         220 map { sprintf '%02x', ord(substr($g_substr, $_, 1)) }
107             0 .. length($g_substr) - 1;
108              
109 907         2333 my $e_hex =
110             join q{},
111 78         291 map { sprintf '%02x', ord(substr($e_substr, $_, 1)) }
112             0 .. length($e_substr) - 1;
113              
114 78         256 for my $str ($g_substr, $e_substr) {
115 156         327 for my $pos (0 .. length($str) - 1) {
116 1798         2508 my $c = substr($str, $pos, 1);
117 1798 100 100     8198 substr($str, $pos, 1, q{.}) if ord($c) < 0x20 or ord($c) > 0x7e;
118             }
119             }
120              
121 78         430 $_ = sprintf "%-${aw}s", $_ for ($g_substr, $e_substr);
122 78         902 $_ .= q{-} x ($hw - length($_)) for ($g_hex, $e_hex);
123              
124 78 100       560 $Test->diag(
125             "$g_hex $g_substr",
126             ($eq ? q{ = } : q{ ! }),
127             "$e_hex $e_substr"
128             );
129              
130 78 100       3730 $seen_diffs++ unless $eq;
131             }
132              
133 7         44 return;
134             }
135              
136              
137             1;
138              
139             __END__