File Coverage

blib/lib/DTL/Fast/Expression/Operator/Binary/In.pm
Criterion Covered Total %
statement 31 48 64.5
branch 18 28 64.2
condition 18 32 56.2
subroutine 6 6 100.0
pod 0 1 0.0
total 73 115 63.4


line stmt bran cond sub pod time code
1             package DTL::Fast::Expression::Operator::Binary::In;
2 3     3   1386 use strict;
  3         7  
  3         74  
3 3     3   14 use utf8;
  3         5  
  3         17  
4 3     3   62 use warnings FATAL => 'all';
  3         6  
  3         135  
5 3     3   19 use parent 'DTL::Fast::Expression::Operator::Binary';
  3         6  
  3         16  
6              
7             $DTL::Fast::OPS_HANDLERS{in} = __PACKAGE__;
8              
9 3     3   534 use DTL::Fast::Expression::Operator::Binary::Eq;
  3         6  
  3         965  
10              
11             sub dispatch
12             {
13 13     13 0 27 my ( $self, $arg1, $arg2, $context) = @_;
14 13         29 my ($arg1_type, $arg2_type) = (ref $arg1, ref $arg2);
15 13         21 my $result = undef;
16              
17 13 100 100     88 if (not $arg2_type and not $arg1_type) # substring checking
    100 100        
    100 66        
    50 33        
    50 33        
18             {
19 4 100       12 $result = index($arg2, $arg1) > - 1 ? 1 : 0;
20             }
21             elsif (not $arg1_type and $arg2_type eq 'ARRAY') # operand in array
22             {
23 4         8 $result = 0;
24 4         8 foreach my $a2 (@$arg2)
25             {
26             # @todo: deep comparision, shouldn't it be optional?
27 8 100       18 if (DTL::Fast::Expression::Operator::Binary::Eq::dispatch($self, $arg1, $a2))
28             {
29 2         5 $result = 1;
30 2         3 last;
31             }
32             }
33             }
34             elsif (not $arg1_type and $arg2_type eq 'HASH') # exists synonim
35             {
36 4 100       10 $result = exists $arg2->{$arg1} ? 1 : 0;
37             }
38             elsif ($arg2_type eq 'ARRAY' and $arg1_type eq 'ARRAY') # second operand is an ARRAY
39             {
40 0         0 $result = 1;
41 0         0 foreach my $a1 (@$arg1)
42             {
43 0         0 my $found = 0;
44 0         0 foreach my $a2 (@$arg2)
45             {
46             # @todo: deep comparision, shouldn't it be optional?
47 0 0       0 if (DTL::Fast::Expression::Operator::Binary::Eq::dispatch($self, $a1, $a2))
48             {
49 0         0 $found = 1;
50 0         0 last;
51             }
52             }
53              
54 0 0       0 if (not $found)
55             {
56 0         0 $result = 0;
57 0         0 last;
58             }
59             }
60             }
61             elsif ($arg2_type eq 'HASH' and $arg1_type eq 'HASH') # hash contains hash
62             {
63 0         0 $result = 1;
64 0         0 foreach my $key1 (keys %$arg1)
65             {
66 0 0 0     0 if (
67             not exists $arg2->{$key1}
68             # @todo: deep comparision, shouldn't it be optional?
69             or not DTL::Fast::Expression::Operator::Binary::Eq::dispatch($self, $arg1->{$key1}, $arg2->{$key1})
70             )
71             {
72 0         0 $result = 0;
73 0         0 last;
74             }
75             }
76             }
77              
78             # `in` method implementation
79 13 50 66     38 if (
80             not defined $result
81             and UNIVERSAL::can($arg1, 'in')
82             )
83             {
84 0         0 $result = $arg1->in($arg2);
85             }
86              
87             # `contains` method implementation
88 13 50 66     49 if (
89             not defined $result
90             and UNIVERSAL::can($arg2, 'contains')
91             )
92             {
93 0         0 $result = $arg2->contains($arg1);
94             }
95              
96             # still nothing
97 13 100       47 if (not defined $result)
98             {
99 1   50     16 die $self->get_render_error(
      50        
      50        
      50        
100             $context,
101             sprintf("Don't know how to check that %s (%s) is in %s (%s)"
102             , $arg1 // 'undef'
103             , $arg1_type || 'SCALAR'
104             , $arg2 // 'undef'
105             , $arg2_type || 'SCALAR'
106             )
107             );
108             }
109              
110 12         45 return $result;
111             }
112              
113             1;