File Coverage

lib/Cron/Toolkit/Pattern.pm
Criterion Covered Total %
statement 90 96 93.7
branch 47 60 78.3
condition 4 10 40.0
subroutine 14 15 93.3
pod 0 11 0.0
total 155 192 80.7


line stmt bran cond sub pod time code
1             package Cron::Toolkit::Pattern;
2 2     2   1102 use strict;
  2         5  
  2         78  
3 2     2   11 use warnings;
  2         23  
  2         124  
4 2     2   12 use Cron::Toolkit::Utils qw(:all);
  2         3  
  2         3385  
5              
6             sub new {
7 701     701 0 1902 my ($class, %args) = @_;
8             my $self = bless {
9             children => [],
10             field_type => $args{field_type}
11 701         2047 }, $class;
12 701 100       1708 $self->{value} = $args{value} if defined $args{value};
13              
14 701         1536 return $self;
15             }
16             sub add_child {
17 85     85 0 135 my ($self, $child) = @_;
18 85         91 push @{$self->{children}}, $child;
  85         181  
19             }
20              
21             sub children {
22 139     139 0 160 my ($self) = @_;
23 139         242 return $self->{children};
24             }
25              
26             sub has_children {
27 115     115 0 149 my $self = shift;
28 115 100       137 return scalar @{ $self->{children} } ? 1 : 0;
  115         1538  
29             }
30              
31             sub type {
32 0     0 0 0 my ($self, $value) = @_;
33 0 0       0 $self->{type} = $value if defined $value;
34 0         0 return $self->{type}; # Return the value (either set or current)
35             }
36              
37             sub field_type {
38 2044371     2044371 0 3006104 my ($self, $value) = @_;
39 2044371 50       3335784 $self->{field_type} = $value if defined $value;
40 2044371         4680328 return $self->{field_type};
41             }
42              
43             sub value {
44 1912797     1912797 0 2813897 my ($self, $value) = @_;
45 1912797 50       3230949 $self->{value} = $value if defined $value;
46 1912797         6744931 return $self->{value};
47             }
48              
49             sub lowest {
50 543     543 0 904 my ( $self, $tm ) = @_;
51              
52 543         637 my ( $min, $max ) = @{ $LIMITS{ $self->field_type } };
  543         1132  
53 543 50       993 $max = $tm->length_of_month if $self->field_type eq 'dom';
54              
55 543         1373 for my $v ( $min .. $max ) {
56 2778         3088 my $test_tm = $tm;
57 2778 50       4017 $test_tm = $test_tm->with_day_of_month($v) if $self->field_type eq 'dom';
58 2778 100       4944 return $v if $self->match($v);
59             }
60 0         0 return;
61             }
62              
63             sub highest {
64 543     543 0 908 my ( $self, $tm ) = @_;
65 543         661 my ( $min, $max ) = @{ $LIMITS{ $self->field_type } };
  543         1097  
66 543 50       975 $max = $tm->length_of_month if $self->field_type eq 'dom';
67              
68 543         3066 for my $v ( reverse $min .. $max ) {
69 22047         23172 my $test_tm = $tm;
70 22047 50       28176 $test_tm = $test_tm->with_day_of_month($v) if $self->field_type eq 'dom';
71 22047 100       33015 return $v if $self->match($v);
72             }
73 0         0 return;
74             }
75              
76             sub english_unit {
77 90     90 0 124 my $self = shift;
78 90 100       205 my $unit = $self->field_type =~ /^(dow|dom)$/ ? 'day' : $self->field_type;
79 90 0 33     195 $unit .= 's' if ($self->type eq 'single' && $self->value != 1 && $self->field_type ne 'year');
      33        
80 90         399 return $unit;
81             }
82              
83             sub english_value {
84 136     136 0 246 my ( $self ) = @_;
85 136         273 my $value = $self->{value};
86 136 50       353 die "missing value" unless defined $value;
87 136 100       333 return 'the ' . num_to_ordinal($value) if $self->field_type eq 'dom';
88 108 100       185 return $MONTH_NAMES{$value} if $self->field_type eq 'month';
89 79 100       141 return $DAY_NAMES{$value} if $self->field_type eq 'dow';
90 55         119 return $value;
91             }
92              
93             sub _dump_tree {
94 648     648   1030 my ($self, $indent) = @_;
95 648   50     1126 $indent //= '';
96              
97 648         1382 my $type = $self->type;
98              
99             # Simple leaf values — inline
100 648 100       1220 if ($type eq 'wildcard') { return '*'; }
  159         442  
101 489 100       976 if ($type eq 'unspecified') { return '?'; }
  82         234  
102 407 100       781 if ($type eq 'single') { return $self->{value}; }
  347         1451  
103 60 100 50     263 if ($type eq 'last') { return $self->{value} // 'L'; }
  10         70  
104 50 100       145 if ($type eq 'lastW') { return 'LW'; }
  1         3  
105 49 100       155 if ($type eq 'nearest_weekday') { return $self->{value}; }
  3         11  
106 46 100       121 if ($type eq 'nth') { return $self->{value}; }
  9         31  
107              
108 37         52 my @children = @{$self->{children}};
  37         104  
109 37 50       100 return '' unless @children;
110              
111 37         63 my $out = "";
112              
113 37 100       105 if ($type eq 'range') {
114 19         66 return $children[0]->_dump_tree($indent) . '-' . $children[1]->_dump_tree($indent);
115             }
116              
117 18 100       57 if ($type eq 'step') {
118 9         54 my $base = $children[0]->_dump_tree($indent . ' ');
119 9         22 $out .= $base . "\n";
120 9         27 $out .= "${indent}└─ /$children[1]{value}";
121 9         46 return $out;
122             }
123              
124 9 50       25 if ($type eq 'list') {
125 9         18 $out = "\n";
126 9         24 for my $i (0 .. $#children) {
127 27 100       51 my $prefix = ($i == $#children) ? '└─ ' : '├─ ';
128 27 100       55 my $next_indent = $indent . ($i == $#children ? ' ' : '│ ');
129 27         69 $out .= "${indent}$prefix" . $children[$i]->_dump_tree($next_indent) . "\n";
130             }
131 9         51 chomp $out;
132 9         46 return $out;
133             }
134              
135 0           return $type;
136             }
137              
138             1;