File Coverage

blib/lib/Wikibase/Datatype/Utils.pm
Criterion Covered Total %
statement 88 88 100.0
branch 36 36 100.0
condition n/a
subroutine 18 18 100.0
pod 7 7 100.0
total 149 149 100.0


line stmt bran cond sub pod time code
1             package Wikibase::Datatype::Utils;
2              
3 300     300   1261393 use base qw(Exporter);
  300         695  
  300         43604  
4 300     300   2127 use strict;
  300         4615  
  300         8930  
5 300     300   1658 use warnings;
  300         757  
  300         16544  
6              
7 300     300   309794 use DateTime;
  300         205519823  
  300         20885  
8 300     300   56496 use Error::Pure qw(err);
  300         1002530  
  300         24657  
9 300     300   10084 use List::Util 1.33 qw(none);
  300         10241  
  300         24870  
10 300     300   245706 use Wikibase::Datatype::Languages qw(all_language_codes all_term_language_codes);
  300         2752  
  300         14636  
11 300     300   55642 use Readonly;
  300         958  
  300         432893  
12              
13             Readonly::Array our @EXPORT_OK => qw(check_datetime check_entity check_language
14             check_language_term check_lexeme check_property check_sense);
15              
16             our $SKIP_CHECK_LANG => 0;
17             our $SKIP_CHECK_TERM_LANG => 0;
18             our @LANGUAGE_CODES => ();
19             our @TERM_LANGUAGE_CODES => ();
20              
21             our $VERSION = 0.39;
22              
23             sub check_datetime {
24 58     58 1 265696 my ($self, $key) = @_;
25              
26 58 100       630 if ($self->{$key} !~ m/^([\+\-]\d+)\-(\d{2})\-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/ms) {
27             err "Parameter '$key' has bad date time.",
28 1         6 'Value', $self->{$key},
29             ;
30             }
31 57         686 my ($year, $month, $day, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6);
32 57 100       275 if ($month > 12) {
33             err "Parameter '$key' has bad date time month value.",
34 1         6 'value' => $self->{$key},
35             ;
36             }
37 56 100       214 if ($month > 0) {
38 52         519 my $dt = DateTime->new(
39             'day' => 1,
40             'month' => $month,
41             'year' => int($year),
42             )->add(months => 1)->subtract(days => 1);;
43 52 100       177296 if ($day > $dt->day) {
44             err "Parameter '$key' has bad date time day value.",
45 1         14 'value' => $self->{$key},
46             ;
47             }
48             } else {
49 4 100       11 if ($day != 0) {
50             err "Parameter '$key' has bad date time day value.",
51 1         7 'value' => $self->{$key},
52             ;
53             }
54             }
55 54 100       861 if ($hour != 0) {
56             err "Parameter '$key' has bad date time hour value.",
57 2         11 'value' => $self->{$key},
58             ;
59             }
60 52 100       184 if ($min != 0) {
61             err "Parameter '$key' has bad date time minute value.",
62 1         5 'value' => $self->{$key},
63             ;
64             }
65 51 100       160 if ($sec != 0) {
66             err "Parameter '$key' has bad date time second value.",
67 1         6 'value' => $self->{$key},
68             ;
69             }
70              
71 50         183 return;
72             }
73              
74             sub check_entity {
75 259     259 1 312227 my ($self, $key) = @_;
76              
77 259         997 _check_item_with_char($self, $key, 'Q');
78              
79 255         654 return;
80             }
81              
82             sub check_language {
83 104     104 1 355717 my ($self, $key) = @_;
84              
85 104 100       450 if (! $SKIP_CHECK_LANG) {
86 100         227 my @language_codes;
87             my $error_message;
88 100 100       360 if (@LANGUAGE_CODES) {
89 4         11 @language_codes = @LANGUAGE_CODES;
90 4         10 $error_message = "Language code '".$self->{$key}."' isn't user defined language code.";
91             } else {
92 96         570 @language_codes = all_language_codes();
93 96         227360 $error_message = "Language code '".$self->{$key}."' isn't code supported by Wikibase.";
94             }
95 100 100   32895   1736 if (none { $_ eq $self->{$key} } @language_codes) {
  32895         60779  
96 6         28 err $error_message;
97             }
98             }
99              
100 98         891 return;
101             }
102              
103             sub check_language_term {
104 41     41 1 340707 my ($self, $key) = @_;
105              
106 41 100       137 if (! $SKIP_CHECK_TERM_LANG) {
107 39         78 my @term_language_codes;
108             my $error_message;
109 39 100       126 if (@TERM_LANGUAGE_CODES) {
110 2         7 @term_language_codes = @TERM_LANGUAGE_CODES;
111 2         6 $error_message = "Language code '".$self->{$key}."' isn't user defined terms language code.";
112             } else {
113 37         164 @term_language_codes = all_term_language_codes();
114 37         82572 $error_message = "Language code '".$self->{$key}."' isn't code supported for terms by Wikibase.";
115             }
116 39 100   12068   590 if (none { $_ eq $self->{$key} } @term_language_codes) {
  12068         21534  
117 5         37 err $error_message;
118             }
119             }
120              
121 36         255 return;
122             }
123              
124             sub check_lexeme {
125 10     10 1 217027 my ($self, $key) = @_;
126              
127 10         66 _check_item_with_char($self, $key, 'L');
128              
129 8         36 return;
130             }
131              
132             sub check_property {
133 248     248 1 304328 my ($self, $key) = @_;
134              
135 248         1110 _check_item_with_char($self, $key, 'P');
136              
137 244         618 return;
138             }
139              
140             sub check_sense {
141 7     7 1 297351 my ($self, $key) = @_;
142              
143 7 100       51 if (! defined $self->{$key}) {
144 1         4 return;
145             }
146              
147 6 100       80 if ($self->{$key} !~ m/^L\d+\-S\d+$/ms) {
148 2         16 err "Parameter '$key' must begin with 'L' and number, dash, S and number after it.";
149             }
150              
151 4         27 return;
152             }
153              
154             sub _check_item_with_char {
155 517     517   1395 my ($self, $key, $char) = @_;
156              
157 517 100       2021 if (! defined $self->{$key}) {
158 27         67 return;
159             }
160              
161 490 100       15268 if ($self->{$key} !~ m/^$char\d+$/ms) {
162 10         70 err "Parameter '$key' must begin with '$char' and number after it.";
163             }
164              
165 480         1748 return;
166             }
167              
168             1;
169              
170             __END__
171              
172             =pod
173              
174             =encoding utf8
175              
176             =head1 NAME
177              
178             Wikibase::Datatype::Utils - Wikibase datatype utilities.
179              
180             =head1 SYNOPSIS
181              
182             use Wikibase::Datatype::Utils qw(check_datetime check_entity check_language check_language_term check_lexeme check_property check_sense);
183              
184             check_datetime($self, $key);
185             check_entity($self, $key);
186             check_language($self, $key);
187             check_language_term($self, $key);
188             check_lexeme($self, $key);
189             check_property($self, $key);
190             check_sense($self, $key);
191              
192             =head1 DESCRIPTION
193              
194             Datatype utilities for checking of data objects.
195              
196             =head1 VARIABLES
197              
198             =head2 C<$SKIP_CHECK_LANG>
199              
200             Boolean variable to skip check of right language.
201              
202             Default value is 0, checking is working.
203              
204             =head2 C<$SKIP_CHECK_TERM_LANG>
205              
206             Boolean variable to skip check of right term language.
207              
208             Default value is 0, checking is working.
209              
210             =head2 C<@LANGUAGE_CODES>
211              
212             List of supported language codes defined by user.
213              
214             Default value is (), checking official language codes.
215              
216             =head2 C<@TERM_LANGUAGE_CODES>
217              
218             List of supported term language codes defined by user.
219              
220             Default value is (), checking official term language codes.
221              
222             =head1 SUBROUTINES
223              
224             =head2 C<check_datetime>
225              
226             check_datetime($self, $key);
227              
228             Check parameter defined by C<$key> if it's datetime for Wikibase.
229             Format of value is variation of ISO 8601 with some changes (like 00 as valid month).
230              
231             Returns undef.
232              
233             =head2 C<check_entity>
234              
235             check_entity($self, $key);
236              
237             Check parameter defined by C<$key> if it's entity (/^Q\d+/).
238              
239             Returns undef.
240              
241             =head2 C<check_language>
242              
243             check_language($self, $key);
244              
245             Check parameter defined by C<$key> if it's ISO 639-1 language code and if language exists.
246              
247             Returns undef.
248              
249             =head2 C<check_language_term>
250              
251             check_language_term($self, $key);
252              
253             Check parameter defined by C<$key> if it's language code for L<Wikibase::Datatype::Term> and if language exists.
254              
255             Returns undef.
256              
257             =head2 C<check_lexeme>
258              
259             check_lexeme($self, $key);
260              
261             Check parameter defined by C<$key> if it's entity (/^L\d+/).
262              
263             Returns undef.
264              
265             =head2 C<check_property>
266              
267             check_property($self, $key);
268              
269             Check parameter defined by C<$key> if it's property (/^P\d+/).
270              
271             Returns undef.
272              
273             =head2 C<check_sense>
274              
275             check_sense($self, $key);
276              
277             Check parameter defined by C<$key> if it's property (/^L\d+\-S\d+$/).
278              
279             Returns undef.
280              
281             =head1 ERRORS
282              
283             check_datetime():
284             Parameter '%s' has bad date time.
285             Value: %s
286             Parameter '%s' has bad date time day value.
287             Value: %s
288             Parameter '%s' has bad date time hour value.
289             Value: %s
290             Parameter '%s' has bad date time minute value.
291             Value: %s
292             Parameter '%s' has bad date time month value.
293             Value: %s
294             Parameter '%s' has bad date time second value.
295             Value: %s
296              
297             check_entity():
298             Parameter '%s' must begin with 'Q' and number after it.";
299              
300             check_language():
301             Language code '%s' isn't code supported by Wikibase.
302             Language code '%s' isn't user defined language code."
303              
304             check_language_term():
305             Language code '%s' isn't code supported for terms by Wikibase.
306             Language code '%s' isn't user defined terms language code.
307              
308             check_lexeme():
309             Parameter '%s' must begin with 'L' and number after it.";
310              
311             check_property():
312             Parameter '%s' must begin with 'P' and number after it.";
313              
314             check_sense():
315             Parameter '%s' must begin with 'L' and number, dash, S and number after it.
316              
317             =head1 EXAMPLE1
318              
319             =for comment filename=check_datetime_success.pl
320              
321             use strict;
322             use warnings;
323              
324             use Wikibase::Datatype::Utils qw(check_datetime);
325              
326             my $self = {
327             'key' => '+0134-11-00T00:00:00Z',
328             'precision' => 10
329             };
330             check_datetime($self, 'key');
331              
332             # Print out.
333             print "ok\n";
334              
335             # Output:
336             # ok
337              
338             =head1 EXAMPLE2
339              
340             =for comment filename=check_datetime_fail.pl
341              
342             use strict;
343             use warnings;
344              
345             use Wikibase::Datatype::Utils qw(check_datetime);
346              
347             $Error::Pure::TYPE = 'Error';
348              
349             my $self = {
350             'key' => '+0134-34-00T00:01:00Z',
351             };
352             check_datetime($self, 'key');
353              
354             # Print out.
355             print "ok\n";
356              
357             # Output:
358             # #Error [/../Wikibase/Datatype/Utils.pm:?] Parameter 'key' has bad date time month value.
359              
360             =head1 EXAMPLE3
361              
362             =for comment filename=check_entity_success.pl
363              
364             use strict;
365             use warnings;
366              
367             use Wikibase::Datatype::Utils qw(check_entity);
368              
369             my $self = {
370             'key' => 'Q123',
371             };
372             check_entity($self, 'key');
373              
374             # Print out.
375             print "ok\n";
376              
377             # Output:
378             # ok
379              
380             =head1 EXAMPLE4
381              
382             =for comment filename=check_entity_fail.pl
383              
384             use strict;
385             use warnings;
386              
387             use Error::Pure;
388             use Wikibase::Datatype::Utils qw(check_entity);
389              
390             $Error::Pure::TYPE = 'Error';
391              
392             my $self = {
393             'key' => 'bad_entity',
394             };
395             check_entity($self, 'key');
396              
397             # Print out.
398             print "ok\n";
399              
400             # Output like:
401             # #Error [/../Wikibase/Datatype/Utils.pm:?] Parameter 'key' must begin with 'Q' and number after it.
402              
403             =head1 EXAMPLE5
404              
405             =for comment filename=check_lexeme_success.pl
406              
407             use strict;
408             use warnings;
409              
410             use Wikibase::Datatype::Utils qw(check_lexeme);
411              
412             my $self = {
413             'key' => 'L123',
414             };
415             check_lexeme($self, 'key');
416              
417             # Print out.
418             print "ok\n";
419              
420             # Output:
421             # ok
422              
423             =head1 EXAMPLE6
424              
425             =for comment filename=check_lexeme_fail.pl
426              
427             use strict;
428             use warnings;
429              
430             use Error::Pure;
431             use Wikibase::Datatype::Utils qw(check_lexeme);
432              
433             $Error::Pure::TYPE = 'Error';
434              
435             my $self = {
436             'key' => 'bad_entity',
437             };
438             check_lexeme($self, 'key');
439              
440             # Print out.
441             print "ok\n";
442              
443             # Output like:
444             # #Error [/../Wikibase/Datatype/Utils.pm:?] Parameter 'key' must begin with 'L' and number after it.
445              
446             =head1 EXAMPLE7
447              
448             =for comment filename=check_property_success.pl
449              
450             use strict;
451             use warnings;
452              
453             use Wikibase::Datatype::Utils qw(check_property);
454              
455             my $self = {
456             'key' => 'P123',
457             };
458             check_property($self, 'key');
459              
460             # Print out.
461             print "ok\n";
462              
463             # Output:
464             # ok
465              
466             =head1 EXAMPLE8
467              
468             =for comment filename=check_property_fail.pl
469              
470             use strict;
471             use warnings;
472              
473             use Error::Pure;
474             use Wikibase::Datatype::Utils qw(check_property);
475              
476             $Error::Pure::TYPE = 'Error';
477              
478             my $self = {
479             'key' => 'bad_property',
480             };
481             check_property($self, 'key');
482              
483             # Print out.
484             print "ok\n";
485              
486             # Output like:
487             # #Error [/../Wikibase/Datatype/Utils.pm:?] Parameter 'key' must begin with 'P' and number after it.
488              
489             =head1 EXAMPLE9
490              
491             =for comment filename=check_sense_success.pl
492              
493             use strict;
494             use warnings;
495              
496             use Wikibase::Datatype::Utils qw(check_sense);
497              
498             my $self = {
499             'key' => 'L34727-S1',
500             };
501             check_sense($self, 'key');
502              
503             # Print out.
504             print "ok\n";
505              
506             # Output:
507             # ok
508              
509             =head1 EXAMPLE10
510              
511             =for comment filename=check_sense_fail.pl
512              
513             use strict;
514             use warnings;
515              
516             use Error::Pure;
517             use Wikibase::Datatype::Utils qw(check_sense);
518              
519             $Error::Pure::TYPE = 'Error';
520              
521             my $self = {
522             'key' => 'bad_sense',
523             };
524             check_sense($self, 'key');
525              
526             # Print out.
527             print "ok\n";
528              
529             # Output like:
530             # #Error [/../Wikibase/Datatype/Utils.pm:?] Parameter 'key' must begin with 'L' and number, dash, S and number after it.
531              
532             =head1 DEPENDENCIES
533              
534             L<DateTime>,
535             L<Exporter>,
536             L<Error::Pure>,
537             L<List::Util>,
538             L<Readonly>.
539              
540             =head1 SEE ALSO
541              
542             =over
543              
544             =item L<Wikibase::Datatype>
545              
546             Wikibase datatypes.
547              
548             =item L<Mo::utils>
549              
550             Mo utilities.
551              
552             =item L<Mo::utils::Language>
553              
554             Mo language utilities.
555              
556             =back
557              
558             =head1 REPOSITORY
559              
560             L<https://github.com/michal-josef-spacek/Wikibase-Datatype>
561              
562             =head1 AUTHOR
563              
564             Michal Josef Špaček L<mailto:skim@cpan.org>
565              
566             L<http://skim.cz>
567              
568             =head1 LICENSE AND COPYRIGHT
569              
570             © 2020-2025 Michal Josef Špaček
571              
572             BSD 2-Clause License
573              
574             =head1 VERSION
575              
576             0.39
577              
578             =cut