File Coverage

blib/lib/Message/Match.pm
Criterion Covered Total %
statement 48 50 96.0
branch 23 28 82.1
condition 22 30 73.3
subroutine 6 6 100.0
pod 1 1 100.0
total 100 115 86.9


line stmt bran cond sub pod time code
1             package Message::Match;
2             {
3             $Message::Match::VERSION = '1.132270';
4             }
5              
6 2     2   21195 use strict;use warnings;
  2     2   4  
  2         47  
  2         9  
  2         4  
  2         70  
7             require Exporter;
8 2     2   10 use vars qw(@ISA @EXPORT_OK);
  2         6  
  2         1166  
9             @ISA = qw(Exporter);
10             @EXPORT_OK = qw(mmatch);
11              
12             sub mmatch {
13 30     30 1 3440 my ($message, $match) = @_;
14 30 100 100     388 die 'Message::Match::mmatch: two HASH references required'
      100        
      100        
      66        
      100        
15             if scalar @_ < 2 or
16             scalar @_ > 2 or
17             not ref $message or
18             not ref $match or
19             ref $message ne 'HASH' or
20             ref $match ne 'HASH';
21              
22 24         36 return _match($message, $match);
23             }
24              
25             sub _special {
26 5     5   6 my ($message, $match) = @_;
27 5         8 substr($match, 0, 8, '');
28 5 100       34 if($match =~ m{^/}) { #regex type
29 4         4 my $re;
30 4         281 eval "\$re = qr$match;"; #this is hideously inefficient
31             #but it is highly cacheable, later on
32 4 100       27 if($message =~ $re) {
33 2         11 return 1
34             } else {
35 2         15 return 0;
36             }
37             }
38 1         12 die "Message::Match::mmatch: special of unknown type passed: $match";
39             }
40              
41             sub _match {
42 56     56   77 my ($message, $match) = @_;
43 56         75 my $ref_message = ref $message; my $ref_match = ref $match;
  56         63  
44 56 50 66     134 if(not $ref_message and not $ref_match) { #scalar on both sides
45 21 100       49 if(substr($match, 0, 8) eq ' special') { #special handling
46 5         11 return _special($message, $match);
47             }
48 16         65 return $message eq $match; #otherwise, brain-dead comparison
49             }
50 35 50 33     84 if($ref_message eq 'JSON::PP::Boolean' and $ref_match eq 'JSON::PP::Boolean') {
51 0         0 return "$message" eq "$match";
52             }
53 35 100 66     131 if($ref_message eq 'HASH' and $ref_match eq 'HASH') {
54 31         76 foreach my $key (keys %$match) {
55 28         37 my $message = $message->{$key};
56 28         35 my $match = $match->{$key};
57 28 100       58 return 0 if not defined $message;
58 26 50       50 return 0 if not defined $match;
59 26 100       54 return 0 unless _match($message, $match);
60             }
61 24         98 return 1;
62             }
63 4 100 66     18 if($ref_message eq 'ARRAY' and not $ref_match) { #check for scalar inside the array
64 2         3 foreach my $item (@$message) {
65 5 100       17 return 1 if $item eq $match;
66             }
67 1         7 return 0;
68             }
69 2 50 33     11 if($ref_message eq 'ARRAY' and $ref_match eq 'ARRAY') { #check the entire array
70 2         3 foreach my $item (@$match) {
71 6         7 my $match = $item;
72 6         6 my $message = shift @{$message};
  6         52  
73 6 50       12 return 0 unless _match($message, $match);
74             }
75 2         6 return 1;
76             }
77 0           return 0; #anything we don't know about fails
78             }
79             1;
80             __END__