File Coverage

blib/lib/Schedule/Activity/NodeFilter.pm
Criterion Covered Total %
statement 87 90 96.6
branch 46 50 92.0
condition 16 30 53.3
subroutine 8 8 100.0
pod 0 5 0.0
total 157 183 85.7


line stmt bran cond sub pod time code
1             package Schedule::Activity::NodeFilter;
2              
3 2     2   4799 use strict;
  2         3  
  2         70  
4 2     2   10 use warnings;
  2         5  
  2         125  
5 2     2   455 use Ref::Util qw/is_plain_hashref is_ref/;
  2         1992  
  2         2277  
6              
7             our $VERSION='0.3.0';
8              
9             my %property=map {$_=>undef} qw/f attr op value boolean filters mod/;
10             my %matcher=(
11             boolean=>\&matchBoolean,
12             elapsed=>\&matchElapsed,
13             value =>\&matchValue,
14             avg =>\&matchValue,
15             );
16              
17             sub new {
18 69     69 0 293824 my ($ref,%opt)=@_;
19 69   33     228 my $class=is_ref($ref)||$ref;
20 69         224 my %self=map {$_=>$opt{$_}} grep {exists($opt{$_})} keys(%property);
  257         551  
  483         790  
21 69 100 100     217 if($self{attr}) { $self{f}//='value' }
  64         181  
22 69 100       143 if($self{boolean}) { $self{f}='boolean'; $self{boolean}=lc($self{boolean}) }
  4         9  
  4         10  
23 69 100       216 if(!defined($matcher{$self{f}})) { die "Invalid filter function $self{f}" }
  1         16  
24 68         276 return bless(\%self,$class);
25             }
26              
27             sub matches {
28 34133     34133 0 94147 my ($self,$tm,%attributes)=@_;
29 34133         80577 return &{$matcher{$$self{f}}}($self,$tm,%attributes);
  34133         95275  
30             }
31              
32             sub matchBoolean {
33 18     18 0 30 my ($self,$tm,%attributes)=@_;
34 18 100       36 if($$self{boolean} eq 'and') {
35 5         6 my $res=1;
36 5         5 foreach my $filter (@{$$self{filters}}) {
  5         7  
37 10 100 66     19 if(is_plain_hashref($filter)) { $res&&=__PACKAGE__->new(%$filter)->matches($tm,%attributes) }
  8         21  
38 2   33     6 else { $res&&=$filter->matches($tm,%attributes) }
39 10 100       24 if(!$res) { return 0 }
  1         6  
40             }
41 4         19 return $res;
42             }
43 13 100       26 if($$self{boolean} eq 'or') {
44 6         6 my $res=0;
45 6         6 foreach my $filter (@{$$self{filters}}) {
  6         9  
46 10 100 66     16 if(is_plain_hashref($filter)) { $res||=__PACKAGE__->new(%$filter)->matches($tm,%attributes) }
  9         33  
47 1   33     6 else { $res||=$filter->matches($tm,%attributes) }
48 10 100       24 if($res) { return 1 }
  5         20  
49             }
50 1         5 return $res;
51             }
52 7 100       15 if($$self{boolean} eq 'nand') {
53 6         8 my $res=0;
54 6         8 foreach my $filter (@{$$self{filters}}) {
  6         9  
55 10 100 66     18 if(is_plain_hashref($filter)) { $res||=!__PACKAGE__->new(%$filter)->matches($tm,%attributes) }
  8         26  
56 2   33     6 else { $res||=!$filter->matches($tm,%attributes) }
57 10 100       27 if($res) { return 1 }
  3         11  
58             }
59 3         13 return $res;
60             }
61 1         8 return 0;
62             }
63              
64             sub matchElapsed {
65 35     35 0 77 my ($self,$tm,%attributes)=@_;
66 35   50     94 my $v=$attributes{$$self{attr}}//{};
67 35         85 $v=$$v{tmmax};
68 35 100 66     161 if(defined($v)&&($tm>=$v)) {
69 22         41 $v=$tm-$v;
70             return __PACKAGE__
71             ->new(f=>'value',attr=>'timecheck',op=>$$self{op},value=>$$self{value},mod=>$$self{mod})
72 22         96 ->matches(undef,timecheck=>{value=>$v});
73             }
74 13         37 return 0;
75             }
76              
77             sub matchValue {
78 34080     34080 0 87321 my ($self,$tm,%attributes)=@_;
79 34080   50     95756 my $v=$attributes{$$self{attr}}//{};
80 34080 100       87958 if ($$self{f} eq 'value') { $v=$$v{value} }
  24050 50       44241  
81 10030         24832 elsif($$self{f} eq 'avg') { $v=$$v{avg} }
82 0         0 else { die "Not yet available $$self{f}" }
83 34080 50       80545 if(defined($$self{value})) {
84 34080 50       71929 if(!defined($v)) { return 0 }
  0         0  
85 34080 100       76562 if(defined($$self{mod})) {
86 1248 100       1518 if($v<0) { $v+=(1+int(-$v/$$self{mod}))*$$self{mod} }
  306         428  
87 1248         1615 $v=$v-int($v/$$self{mod})*$$self{mod};
88             }
89 34080 100       79559 if($$self{op} eq 'eq') { return $v==$$self{value} }
  3507         18074  
90 30573 100       71264 if($$self{op} eq 'ne') { return $v!=$$self{value} }
  3482         17934  
91 27091 100       59555 if($$self{op} eq 'lt') { return $v< $$self{value} }
  1254         2092  
92 25837 100       58945 if($$self{op} eq 'le') { return $v<=$$self{value} }
  3         29  
93 25834 100       56866 if($$self{op} eq 'gt') { return $v> $$self{value} }
  6         66  
94 25828 50       58503 if($$self{op} eq 'ge') { return $v>=$$self{value} }
  25828         133204  
95             }
96 0           return 0;
97             }
98              
99             1;
100              
101             __END__