File Coverage

blib/lib/Mo/utils.pm
Criterion Covered Total %
statement 152 152 100.0
branch 84 84 100.0
condition 18 18 100.0
subroutine 29 29 100.0
pod 19 19 100.0
total 302 302 100.0


line stmt bran cond sub pod time code
1             package Mo::utils;
2              
3 21     21   441342 use base qw(Exporter);
  21         41  
  21         2583  
4 21     21   130 use strict;
  21         139  
  21         556  
5 21     21   116 use warnings;
  21         60  
  21         1281  
6              
7 21     21   9389 use Error::Pure qw(err);
  21         40463  
  21         441  
8 21     21   1586 use List::Util qw(none);
  21         39  
  21         2824  
9 21     21   123 use Readonly;
  21         34  
  21         903  
10 21     21   122 use Scalar::Util qw(blessed looks_like_number);
  21         34  
  21         50475  
11              
12             Readonly::Array our @EXPORT_OK => qw(check_angle check_array check_array_object
13             check_array_required check_bool check_code check_isa check_length
14             check_length_fix check_number check_number_id check_number_min
15             check_number_of_items check_number_range check_regexp check_required
16             check_string check_string_begin check_strings);
17              
18             our $VERSION = 0.32;
19              
20             sub check_angle {
21 9     9 1 246122 my ($self, $key) = @_;
22              
23 9         30 check_number_range($self, $key, 0, 360);
24              
25 6         13 return;
26             }
27              
28             sub check_array {
29 13     13 1 313079 my ($self, $key) = @_;
30              
31 13 100       47 if (! exists $self->{$key}) {
32 1         4 return;
33             }
34              
35 12 100       49 if (ref $self->{$key} ne 'ARRAY') {
36 6         18 my $ref = ref $self->{$key};
37             err "Parameter '".$key."' must be a array.",
38 6 100       69 'Value', $self->{$key},
39             'Reference', ($ref eq '' ? 'SCALAR' : $ref),
40             ;
41             }
42              
43 6         14 return;
44             }
45              
46             sub check_array_object {
47 5     5 1 334547 my ($self, $key, $class, $class_name) = @_;
48              
49 5 100       24 if (! exists $self->{$key}) {
50 1         4 return;
51             }
52              
53 4         16 check_array($self, $key);
54              
55 3         5 foreach my $obj (@{$self->{$key}}) {
  3         10  
56 3         11 _check_object($obj, $class,
57             '%s isn\'t \'%s\' object.',
58             [$class_name, $class],
59             );
60             }
61              
62 1         13 return;
63             }
64              
65             sub check_array_required {
66 5     5 1 356172 my ($self, $key) = @_;
67              
68 5 100       30 if (! exists $self->{$key}) {
69 1         7 err "Parameter '$key' is required.";
70             }
71              
72 4         14 check_array($self, $key);
73              
74 2 100       3 if (! @{$self->{$key}}) {
  2         8  
75 1         11 err "Parameter '".$key."' with array must have at least one item.";
76             }
77              
78 1         4 return;
79             }
80              
81             sub check_bool {
82 6     6 1 416867 my ($self, $key) = @_;
83              
84 6 100       23 _check_key($self, $key) && return;
85              
86 4 100 100     48 if ($self->{$key} !~ m/^\d+$/ms || ($self->{$key} != 0 && $self->{$key} != 1)) {
      100        
87             err "Parameter '$key' must be a bool (0/1).",
88 2         13 'Value', $self->{$key},
89             ;
90             }
91              
92 2         8 return;
93             }
94              
95             sub check_code {
96 4     4 1 281171 my ($self, $key) = @_;
97              
98 4 100       14 _check_key($self, $key) && return;
99              
100 2 100       7 if (ref $self->{$key} ne 'CODE') {
101             err "Parameter '$key' must be a code.",
102 1         8 'Value', $self->{$key},
103             ;
104             }
105              
106 1         2 return;
107             }
108              
109             sub check_isa {
110 7     7 1 265939 my ($self, $key, $class) = @_;
111              
112 7 100       16 _check_key($self, $key) && return;
113 5         37 _check_object($self->{$key}, $class,
114             'Parameter \'%s\' must be a \'%s\' object.',
115             [$key, $class],
116             );
117              
118 1         3 return;
119             }
120              
121             sub check_length {
122 5     5 1 397717 my ($self, $key, $max_length) = @_;
123              
124 5 100       23 _check_key($self, $key) && return;
125              
126 3 100       11 if (length $self->{$key} > $max_length) {
127             err "Parameter '$key' has length greater than '$max_length'.",
128 1         9 'Value', $self->{$key},
129             ;
130             }
131              
132 2         6 return;
133             }
134              
135             sub check_length_fix {
136 5     5 1 374841 my ($self, $key, $length) = @_;
137              
138 5 100       17 _check_key($self, $key) && return;
139              
140 3 100       10 if (length $self->{$key} != $length) {
141             err "Parameter '$key' has length different than '$length'.",
142 2         13 'Value', $self->{$key},
143             ;
144             }
145              
146 1         3 return;
147             }
148              
149             sub check_number {
150 26     26 1 245971 my ($self, $key) = @_;
151              
152 26 100       47 _check_key($self, $key) && return;
153              
154 24 100       87 if (! looks_like_number($self->{$key})) {
155             err "Parameter '$key' must be a number.",
156 4         30 'Value', $self->{$key},
157             ;
158             }
159              
160 20         32 return;
161             }
162              
163             sub check_number_id {
164 7     7 1 388792 my ($self, $key) = @_;
165              
166 7 100       22 _check_key($self, $key) && return;
167              
168 5 100 100     43 if ($self->{$key} !~ m/^\d+$/ms || $self->{$key} == 0) {
169             err "Parameter '$key' must be a natural number.",
170 4         22 'Value', $self->{$key},
171             ;
172             }
173              
174 1         4 return;
175             }
176              
177             sub check_number_min {
178 6     6 1 272695 my ($self, $key, $min) = @_;
179              
180 6 100       15 _check_key($self, $key) && return;
181              
182 4         13 check_number($self, $key);
183              
184 3 100       8 if ($self->{$key} < $min) {
185             err "Parameter '".$key."' must be greater than $min.",
186 1         8 'Value', $self->{$key},
187             ;
188             }
189              
190 2         5 return;
191             }
192              
193             sub check_number_of_items {
194 2     2 1 397868 my ($self, $list_method, $item_method, $object_name, $item_name) = @_;
195              
196 2         6 my $item_hr = {};
197 2         3 foreach my $item (@{$self->$list_method}) {
  2         23  
198 4         320 $item_hr->{$item->$item_method} += 1;
199             }
200              
201 2         189 foreach my $item (keys %{$item_hr}) {
  2         8  
202 3 100       28 if ($item_hr->{$item} > 1) {
203 1         8 err "$object_name for $item_name '$item' has multiple values."
204             }
205             }
206              
207 1         6 return;
208             }
209              
210             sub check_number_range {
211 16     16 1 250955 my ($self, $key, $min, $max) = @_;
212              
213 16 100       44 _check_key($self, $key) && return;
214              
215 12         34 check_number($self, $key);
216              
217 10 100 100     60 if ($self->{$key} < $min || $self->{$key} > $max) {
218             err "Parameter '".$key."' must be a number between $min and $max.",
219 4         22 'Value', $self->{$key},
220             ;
221             }
222              
223 6         24 return;
224             }
225              
226             sub check_regexp {
227 4     4 1 409630 my ($self, $key, $regexp) = @_;
228              
229 4 100       15 _check_key($self, $key) && return;
230              
231 3 100       10 if (! defined $regexp) {
232 1         8 err "Parameter '$key' must have defined regexp.";
233             }
234 2 100       49 if ($self->{$key} !~ m/^$regexp/ms) {
235             err "Parameter '$key' does not match the specified regular expression.",
236 1         10 'String', $self->{$key},
237             'Regexp', $regexp,
238             ;
239             }
240              
241 1         4 return;
242             }
243              
244             sub check_required {
245 3     3 1 423299 my ($self, $key) = @_;
246              
247 3 100 100     24 if (! exists $self->{$key} || ! defined $self->{$key}) {
248 2         11 err "Parameter '$key' is required.";
249             }
250              
251 1         4 return;
252             }
253              
254             sub check_string {
255 4     4 1 318384 my ($self, $key, $string) = @_;
256              
257 4 100       16 _check_key($self, $key) && return;
258              
259 3 100       12 if ($self->{$key} ne $string) {
260             err "Parameter '$key' must have expected value.",
261 2         13 'Value', $self->{$key},
262             'Expected value', $string,
263             ;
264             }
265              
266 1         4 return;
267             }
268              
269             sub check_string_begin {
270 4     4 1 362545 my ($self, $key, $string_base) = @_;
271              
272 4 100       13 _check_key($self, $key) && return;
273              
274 3 100       8 if (! defined $string_base) {
275 1         5 err "Parameter '$key' must have defined string base.";
276             }
277 2 100       40 if ($self->{$key} !~ m/^$string_base/) {
278             err "Parameter '$key' must begin with defined string base.",
279 1         11 'String', $self->{$key},
280             'String base', $string_base,
281             ;
282             }
283              
284 1         4 return;
285             }
286              
287             sub check_strings {
288 6     6 1 394606 my ($self, $key, $strings_ar) = @_;
289              
290 6 100       21 _check_key($self, $key) && return;
291              
292 5 100       14 if (! defined $strings_ar) {
293 1         6 err "Parameter '$key' must have strings definition.";
294             }
295 4 100       15 if (ref $strings_ar ne 'ARRAY') {
296 1         6 err "Parameter '$key' must have right string definition.";
297             }
298 3 100   5   15 if (none { $self->{$key} eq $_ } @{$strings_ar}) {
  5         15  
  3         14  
299             err "Parameter '$key' must be one of defined strings.",
300             'String', $self->{$key},
301 1         5 'Possible strings', "'".(join "', '", @{$strings_ar})."'",
  1         11  
302             ;
303             }
304              
305 2         11 return;
306             }
307              
308             sub _check_key {
309 100     100   185 my ($self, $key) = @_;
310              
311 100 100 100     508 if (! exists $self->{$key} || ! defined $self->{$key}) {
312 24         122 return 1;
313             }
314              
315 76         190 return 0;
316             }
317              
318             sub _check_object {
319 8     8   16 my ($value, $class, $message, $message_params_ar) = @_;
320              
321 8 100       21 if (! blessed($value)) {
322 4         7 my $err_message = sprintf $message, @{$message_params_ar};
  4         15  
323 4 100       29 err $err_message,
    100          
324              
325             # Only, if value is scalar.
326             (ref $value eq '') ? (
327             'Value', $value,
328             ) : (),
329              
330             # Only if value is reference.
331             (ref $value ne '') ? (
332             'Reference', (ref $value),
333             ) : (),
334             }
335              
336 4 100       35 if (! $value->isa($class)) {
337 2         10 my $err_message = sprintf $message, @{$message_params_ar};
  2         10  
338 2         9 err $err_message,
339             'Reference', (ref $value),
340             ;
341             }
342              
343 2         6 return;
344             }
345              
346             1;
347              
348             __END__