File Coverage

blib/lib/Test/Bits.pm
Criterion Covered Total %
statement 62 62 100.0
branch 26 26 100.0
condition 8 9 88.8
subroutine 11 11 100.0
pod 0 1 0.0
total 107 109 98.1


line stmt bran cond sub pod time code
1             package Test::Bits;
2             {
3             $Test::Bits::VERSION = '0.02';
4             }
5             BEGIN {
6 1     1   35662 $Test::Bits::AUTHORITY = 'cpan:DROLSKY';
7             }
8              
9 1     1   7 use strict;
  1         2  
  1         30  
10 1     1   3 use warnings;
  1         2  
  1         33  
11              
12 1     1   1017 use List::AllUtils qw( all any min );
  1         2900  
  1         107  
13 1     1   7 use Scalar::Util qw( blessed reftype );
  1         2  
  1         83  
14              
15 1     1   870 use parent qw( Test::Builder::Module );
  1         285  
  1         6  
16              
17             our @EXPORT = qw( bits_is );
18              
19             our $Builder;
20              
21             my $UsageErrorBase
22             = 'bits_is() should be passed a scalar of binary data and an array reference of numbers.';
23              
24              
25             sub bits_is ($$;$) {
26 15     15 0 22037 my $got = shift;
27 15         20 my $expect = shift;
28 15         18 my $name = shift;
29              
30 15         58 local $Builder = __PACKAGE__->builder();
31              
32 15         85 _check_got($got);
33 12         22 _check_expect($expect);
34              
35 5         23 $got = [ map { ord($_) } split //, $got ];
  10         18  
36              
37 5         9 my $got_length = @{$got};
  5         7  
38 5         5 my $expect_length = @{$expect};
  5         6  
39              
40 5         5 my @errors;
41 5 100       14 push @errors,
42             'The two pieces of binary data are not the same length'
43             . " (got $got_length, expected $expect_length)."
44             unless $got_length eq $expect_length;
45              
46 5         17 my $length = min( $got_length, $expect_length );
47              
48 5         13 for my $i ( 0 .. $length - 1 ) {
49 10 100       23 next if $got->[$i] == $expect->[$i];
50              
51 3         20 push @errors,
52             sprintf(
53             "Binary data begins differing at byte $i.\n"
54             . " Got: %08b\n"
55             . " Expect: %08b",
56             $got->[$i],
57             $expect->[$i],
58             );
59              
60 3         21 last;
61             }
62              
63 5 100       10 if (@errors) {
64 3         15 $Builder->ok( 0, $name );
65 3         299 $Builder->diag( join "\n", @errors );
66             }
67             else {
68 2         17 $Builder->ok( 1, $name );
69             }
70              
71 5         359 return;
72             }
73              
74             sub _check_got {
75 15     15   17 my $got = shift;
76              
77 15         22 local $Test::Builder::Level = $Test::Builder::Level + 1;
78              
79 15         17 my $error;
80 15 100       40 if ( !defined $got ) {
    100          
81 1         3 $error
82             = $UsageErrorBase . ' You passed an undef as the first argument';
83             }
84             elsif ( ref $got ) {
85 1         9 $error
86             = $UsageErrorBase
87             . ' You passed a '
88             . reftype($got)
89             . ' reference as the first argument';
90             }
91             else {
92 13 100   32   93 if ( any { ord($_) > 255 } split //, $got ) {
  32         59  
93 1         3 $error = $UsageErrorBase
94             . ' You passed a string with UTF-8 data as the first argument';
95             }
96             }
97              
98 15 100       75 $Builder->croak($error)
99             if $error;
100             }
101              
102             sub _check_expect {
103 12     12   13 my $expect = shift;
104              
105 12         15 local $Test::Builder::Level = $Test::Builder::Level + 1;
106              
107 12         11 my $error;
108 12 100       46 if ( !defined $expect ) {
    100          
    100          
109 1         2 $error
110             = $UsageErrorBase . ' You passed an undef as the second argument';
111             }
112             elsif ( !ref $expect ) {
113 1         3 $error = $UsageErrorBase
114             . ' You passed a plain scalar as the second argument';
115             }
116             elsif ( reftype($expect) eq 'ARRAY' ) {
117 9 100       26 unless (
118             all {
119 23 100 100 23   355 defined $_
      100        
      66        
120             && !ref $_
121             && $_ =~ /^\d+$/
122             && $_ >= 0
123             && $_ <= 255;
124             }
125 9         19 @{$expect}
126             ) {
127              
128 4         8 $error = $UsageErrorBase
129             . q{ The second argument contains a value which isn't a number from 0-255};
130             }
131             }
132             else {
133 1         8 $error
134             = $UsageErrorBase
135             . ' You passed a '
136             . reftype($expect)
137             . ' reference as the second argument';
138             }
139              
140 12 100       66 $Builder->croak($error)
141             if $error;
142             }
143              
144             1;
145              
146             # ABSTRACT: Provides a bits_is() subroutine for testing binary data
147              
148             __END__