File Coverage

blib/lib/Venus/Assert.pm
Criterion Covered Total %
statement 366 417 87.7
branch 154 230 66.9
condition 44 69 63.7
subroutine 119 136 87.5
pod 51 55 92.7
total 734 907 80.9


line stmt bran cond sub pod time code
1             package Venus::Assert;
2              
3 12     12   287 use 5.018;
  12         44  
4              
5 12     12   77 use strict;
  12         23  
  12         317  
6 12     12   63 use warnings;
  12         27  
  12         436  
7              
8 12     12   91 use Venus::Class 'attr', 'base', 'with';
  12         30  
  12         110  
9              
10 12     12   7239 use Venus::Match;
  12         86  
  12         101  
11 12     12   125 use Venus::Type;
  12         24  
  12         152  
12              
13             base 'Venus::Kind::Utility';
14              
15             with 'Venus::Role::Buildable';
16              
17             use overload (
18 0     0   0 '&{}' => sub{$_[0]->validator},
19 12         128 fallback => 1,
20 12     12   90 );
  12         25  
21              
22             # ATTRIBUTES
23              
24             attr 'expects';
25             attr 'message';
26             attr 'name';
27              
28             # BUILDERS
29              
30             sub build_arg {
31 301     301 0 742 my ($self, $name) = @_;
32              
33             return {
34 301         1210 name => $name,
35             };
36             }
37              
38             sub build_self {
39 368     368 0 1083 my ($self, $data) = @_;
40              
41 368         683 my $name = 'Unknown';
42 368         593 my $message = 'Type assertion (%s) failed: received (%s), expected (%s)';
43              
44 368 100       1067 $self->name($name) if !$self->name;
45 368 50       1250 $self->message($message) if !$self->message;
46 368 50       1259 $self->expects([]) if !$self->expects;
47 368         1399 $self->conditions;
48              
49 368         818 return $self;
50             }
51              
52             # METHODS
53              
54             sub any {
55 101     101 1 172 my ($self) = @_;
56              
57 101     10   225 $self->constraints->when(sub{true})->then(sub{true});
  10         45  
  10         21  
58              
59 101         308 return $self;
60             }
61              
62             sub accept {
63 631     631 1 1254 my ($self, $name, @args) = @_;
64              
65 631 50       1187 if (!$name) {
66 0         0 return $self;
67             }
68 631 100       2221 if ($self->can($name)) {
69 627         1556 return $self->$name(@args);
70             }
71             else {
72 4         21 return $self->identity($name, @args);
73             }
74             }
75              
76             sub array {
77 7     7 1 16 my ($self, @code) = @_;
78              
79 7 50   5   49 $self->constraint('array', @code ? @code : sub{true});
  5         21  
80              
81 7         34 return $self;
82             }
83              
84             sub arrayref {
85 1     1 1 6 my ($self, @code) = @_;
86              
87 1         5 return $self->array(@code);
88             }
89              
90             sub attributes {
91 3     3 1 11 my ($self, @pairs) = @_;
92              
93             $self->object(sub{
94 6     6   9 my $check = 0;
95 6         29 my $value = $_->value;
96 6 50       32 return false if @pairs % 2;
97 6         22 for (my $i = 0; $i < @pairs;) {
98 8         35 my ($key, $data) = (map $pairs[$_], $i++, $i++);
99 8 50       27 my ($match, @args) = (ref $data) ? (@{$data}) : ($data);
  0         0  
100 8 100 100     64 $check++ if $value->can($key)
101             && $self->new->do($match, @args)->check($value->$key);
102             }
103 6 100       40 ((@pairs / 2) == $check) ? true : false
104 3         35 });
105              
106 3         43 return $self;
107             }
108              
109             sub assertion {
110 0     0 1 0 my ($self) = @_;
111              
112 0         0 my $assert = $self->SUPER::assertion;
113              
114 0         0 $assert->clear->expression('string');
115              
116 0         0 return $assert;
117             }
118              
119             sub boolean {
120 91     91 1 192 my ($self, @code) = @_;
121              
122 91 50   3   423 $self->constraint('boolean', @code ? @code : sub{true});
  3         17  
123              
124 91         344 return $self;
125             }
126              
127             sub check {
128 509     509 1 1215 my ($self, $data) = @_;
129              
130 509         2050 my $value = Venus::Type->new(value => $data);
131              
132 509     202   2667 my @args = (value => $value, on_none => sub{false});
  202         770  
133              
134 509         1513 return $self->constraints->renew(@args)->result;
135             }
136              
137             sub checker {
138 1     1 1 5 my ($self, $data) = @_;
139              
140 1 50       8 $self->expression($data) if $data;
141              
142 1         12 return $self->defer('check');
143             }
144              
145             sub clear {
146 93     93 1 158 my ($self) = @_;
147              
148 93         193 $self->constraints->clear;
149 93         223 $self->coercions->clear;
150              
151 93         323 return $self;
152             }
153              
154             sub code {
155 13     13 1 36 my ($self, @code) = @_;
156              
157 13 50   20   89 $self->constraint('code', @code ? @code : sub{true});
  20         83  
158              
159 13         117 return $self;
160             }
161              
162             sub coderef {
163 3     3 1 13 my ($self, @code) = @_;
164              
165 3         18 return $self->code(@code);
166             }
167              
168             sub coerce {
169 67     67 1 170 my ($self, $data) = @_;
170              
171 67         316 my $value = Venus::Type->new(value => $data);
172              
173 67     58   393 my @args = (value => $value, on_none => sub{$data});
  58         171  
174              
175 67         176 return $self->coercions->renew(@args)->result;
176             }
177              
178             sub coercion {
179 12     12 1 32 my ($self, $type, $code) = @_;
180              
181 12         46 $self->coercions->when('coded', $type)->then($code);
182              
183 12         235 return $self;
184             }
185              
186             sub coercions {
187 174     174 1 286 my ($self) = @_;
188              
189 174         630 my $match = Venus::Match->new;
190              
191 174 50 66     1384 return $self->{coercions} ||= $match if ref $self;
192              
193 0         0 return $match;
194             }
195              
196             sub conditions {
197 368     368 1 697 my ($self) = @_;
198              
199 368         590 return $self;
200             }
201              
202             sub constraint {
203 587     587 1 1161 my ($self, $type, $code) = @_;
204              
205 587         1361 $self->constraints->when('coded', $type)->then($code);
206              
207 587         1372 return $self;
208             }
209              
210             sub constraints {
211 1341     1341 1 2120 my ($self) = @_;
212              
213 1341         4126 my $match = Venus::Match->new;
214              
215 1341 50 66     9029 return $self->{constraints} ||= $match if ref $self;
216              
217 0         0 return $match;
218             }
219              
220             sub consumes {
221 1     1 0 5 my ($self, $role) = @_;
222              
223 1     0   9 my $where = $self->constraint('object', sub{true})->constraints->where;
  0         0  
224              
225 1     2   9 $where->when(sub{$_->value->DOES($role)})->then(sub{true});
  2         10  
  1         5  
226              
227 1         12 return $self;
228             }
229              
230             sub defined {
231 1     1 1 4 my ($self, @code) = @_;
232              
233 5     5   13 $self->constraints->when(sub{CORE::defined($_->value)})
234 1 50   4   5 ->then(@code ? @code : sub{true});
  4         15  
235              
236 1         17 return $self;
237             }
238              
239             sub either {
240 317     317 1 726 my ($self, @data) = @_;
241              
242 317         828 for (my $i = 0; $i < @data; $i++) {
243 623 100       1580 my ($match, @args) = (ref $data[$i]) ? (@{$data[$i]}) : ($data[$i]);
  127         394  
244 623         1442 $self->accept($match, @args);
245             }
246              
247 317         885 return $self;
248             }
249              
250             sub enum {
251 1     1 1 5 my ($self, @data) = @_;
252              
253 1         4 for my $item (@data) {
254 26 50   26   48 $self->constraints->when(sub{CORE::defined($_->value) && $_->value eq $item})
255 4     4   12 ->then(sub{true});
  4         13  
256             }
257              
258 1         12 return $self;
259             }
260              
261             sub expression {
262 196     196 1 406 my ($self, $data) = @_;
263              
264 196 50       397 return $self if !$data;
265              
266 196         1727 $data =
267             $data =~ s/\s*\n+\s*/ /gr =~ s/^\s+|\s+$//gr =~ s/\[\s+/[/gr =~ s/\s+\]/]/gr;
268              
269 196         695 $self->expects([$data]);
270              
271 196         609 my @parsed = $self->parse($data);
272              
273 196         742 $self->either(@parsed);
274              
275 196         721 return $self;
276             }
277              
278             sub float {
279 122     122 1 255 my ($self, @code) = @_;
280              
281 122 50   19   610 $self->constraint('float', @code ? @code : sub{true});
  19         60  
282              
283 122         481 return $self;
284             }
285              
286             sub format {
287 4     4 1 14 my ($self, $name, @code) = @_;
288              
289 4 50       12 if (!$name) {
290 0         0 return $self;
291             }
292 4 50       63 if (lc($name) eq 'array') {
    50          
    50          
    100          
    50          
    100          
    100          
    50          
    50          
    50          
    50          
293 0 0   0   0 return $self->coercion('array', @code ? (@code) : sub{$_->value});
  0         0  
294             }
295             elsif (lc($name) eq 'boolean') {
296 0 0   0   0 return $self->coercion('boolean', @code ? (@code) : sub{$_->value});
  0         0  
297             }
298             elsif (lc($name) eq 'code') {
299 0 0   0   0 return $self->coercion('code', @code ? (@code) : sub{$_->value});
  0         0  
300             }
301             elsif (lc($name) eq 'float') {
302 1 50   0   8 return $self->coercion('float', @code ? (@code) : sub{$_->value});
  0         0  
303             }
304             elsif (lc($name) eq 'hash') {
305 0 0   0   0 return $self->coercion('hash', @code ? (@code) : sub{$_->value});
  0         0  
306             }
307             elsif (lc($name) eq 'number') {
308 1 50   0   8 return $self->coercion('number', @code ? (@code) : sub{$_->value});
  0         0  
309             }
310             elsif (lc($name) eq 'object') {
311 1 50   0   8 return $self->coercion('object', @code ? (@code) : sub{$_->value});
  0         0  
312             }
313             elsif (lc($name) eq 'regexp') {
314 0 0   0   0 return $self->coercion('regexp', @code ? (@code) : sub{$_->value});
  0         0  
315             }
316             elsif (lc($name) eq 'scalar') {
317 0 0   0   0 return $self->coercion('scalar', @code ? (@code) : sub{$_->value});
  0         0  
318             }
319             elsif (lc($name) eq 'string') {
320 0 0   0   0 return $self->coercion('string', @code ? (@code) : sub{$_->value});
  0         0  
321             }
322             elsif (lc($name) eq 'undef') {
323 0 0   0   0 return $self->coercion('undef', @code ? (@code) : sub{$_->value});
  0         0  
324             }
325             else {
326             return $self->coercion('object', sub {
327 2 50   2   17 UNIVERSAL::isa($_->value, $name)
    100          
328             ? (@code ? $code[0]->($_->value) : $_->value)
329             : $_->value;
330 1         7 });
331             }
332             }
333              
334             sub hash {
335 2     2 1 10 my ($self, @code) = @_;
336              
337 2 50   2   25 $self->constraint('hash', @code ? @code : sub{true});
  2         22  
338              
339 2         26 return $self;
340             }
341              
342             sub hashkeys {
343 29     29 1 88 my ($self, @pairs) = @_;
344              
345             $self->constraints->when(sub{
346             CORE::defined($_->value) && UNIVERSAL::isa($_->value, 'HASH')
347 36 100 66 36   93 && (keys %{$_->value}) > 0
  32         79  
348             })->then(sub{
349 21     21   49 my $check = 0;
350 21         49 my $value = $_->value;
351 21 50       73 return false if @pairs % 2;
352 21         72 for (my $i = 0; $i < @pairs;) {
353 32         152 my ($key, $data) = (map $pairs[$_], $i++, $i++);
354 32 100       98 my ($match, @args) = (ref $data) ? (@{$data}) : ($data);
  14         42  
355 32 100       103 $check++ if $self->new->do($match, @args)->check($value->{$key});
356             }
357 21 100       159 ((@pairs / 2) == $check) ? true : false
358 29         74 });
359              
360 29         144 return $self;
361             }
362              
363             sub hashref {
364 1     1 1 5 my ($self, @code) = @_;
365              
366 1         5 return $self->hash(@code);
367             }
368              
369             sub identity {
370 5     5 1 20 my ($self, $name) = @_;
371              
372 5 100   7   35 $self->constraint('object', sub {$_->value->isa($name) ? true : false});
  7         37  
373              
374 5         55 return $self;
375             }
376              
377             sub inherits {
378 1     1 1 5 my ($self, $name) = @_;
379              
380 1 100   2   10 $self->constraint('object', sub {$_->value->isa($name) ? true : false});
  2         6  
381              
382 1         15 return $self;
383             }
384              
385             sub integrates {
386 1     1 1 5 my ($self, $name) = @_;
387              
388             $self->constraint('object', sub {
389 2 50   2   10 $_->value->can('does') ? ($_->value->does($name) ? true : false) : false
    100          
390 1         8 });
391              
392 1         11 return $self;
393             }
394              
395             sub maybe {
396 6     6 1 16 my ($self, $match, @args) = @_;
397              
398 6 50       30 $self->$match(@args) if $match;
399 6         30 $self->undef;
400              
401 6         27 return $self;
402             }
403              
404             sub number {
405 142     142 1 307 my ($self, @code) = @_;
406              
407 142 100   32   766 $self->constraint('number', @code ? @code : sub{true});
  32         144  
408              
409 142         601 return $self;
410             }
411              
412             sub object {
413 7     7 1 29 my ($self, @code) = @_;
414              
415 7 100   3   68 $self->constraint('object', @code ? @code : sub{true});
  3         15  
416              
417 7         55 return $self;
418             }
419              
420             sub package {
421 1     1 1 7 my ($self) = @_;
422              
423 1     0   7 my $where = $self->constraint('string', sub{true})->constraints->where;
  0         0  
424              
425 3     3   12 $where->when(sub{$_->value =~ /^[A-Z](?:(?:\w|::)*[a-zA-Z0-9])?$/})->then(sub{
426 3     3   1346 require Venus::Space;
427              
428 3         21 Venus::Space->new($_->value)->loaded
429 1         16 });
430              
431 1         16 return $self;
432             }
433              
434             sub parse {
435 220     220 1 484 my ($self, $expr) = @_;
436              
437 220   100     497 $expr ||= '';
438              
439 220         1622 $expr =
440             $expr =~ s/\s*\n+\s*/ /gr =~ s/^\s+|\s+$//gr =~ s/\[\s+/[/gr =~ s/\s+\]/]/gr;
441              
442 220         546 return _type_parse($expr);
443             }
444              
445             sub received {
446 31     31 0 78 my ($self, $data) = @_;
447              
448 31         167 require Scalar::Util;
449              
450 31 100       94 if (!defined $data) {
451 9         47 return '';
452             }
453              
454 22         77 my $blessed = Scalar::Util::blessed($data);
455 22   33     83 my $isvenus = $blessed && $data->isa('Venus::Core') && $data->can('does');
456              
457 22 100 66     123 if (!$blessed && !ref $data) {
458 13         80 return $data;
459             }
460 9 50 33     43 if ($blessed && ref($data) eq 'Regexp') {
461 0         0 return "$data";
462             }
463 9 50 33     29 if ($isvenus && $data->does('Venus::Role::Explainable')) {
464 0     0   0 return $self->dump(sub{$data->explain});
  0         0  
465             }
466 9 50 33     44 if ($isvenus && $data->does('Venus::Role::Valuable')) {
467 0     0   0 return $self->dump(sub{$data->value});
  0         0  
468             }
469 9 50 33     30 if ($isvenus && $data->does('Venus::Role::Dumpable')) {
470 0         0 return $data->dump;
471             }
472 9 50 33     28 if ($blessed && overload::Method($data, '""')) {
473 0         0 return "$data";
474             }
475 9 50 33     28 if ($blessed && $data->can('as_string')) {
476 0         0 return $data->as_string;
477             }
478 9 50 33     28 if ($blessed && $data->can('to_string')) {
479 0         0 return $data->to_string;
480             }
481 9 50 33     34 if ($blessed && $data->isa('Venus::Kind')) {
482 0         0 return $data->stringified;
483             }
484             else {
485 9     9   125 return $self->dump(sub{$data});
  9         65  
486             }
487             }
488              
489             sub reference {
490 1     1 1 5 my ($self, @code) = @_;
491              
492             $self->constraints
493 7 50   7   20 ->when(sub{CORE::defined($_->value) && ref($_->value)})
494 1 50   4   6 ->then(@code ? @code : sub{true});
  4         20  
495              
496 1         13 return $self;
497             }
498              
499             sub regexp {
500 1     1 1 4 my ($self, @code) = @_;
501              
502 1 50   1   12 $self->constraint('regexp', @code ? @code : sub{true});
  1         5  
503              
504 1         13 return $self;
505             }
506              
507             sub render {
508 23     23 1 56 my ($self, $into, $data) = @_;
509              
510 23         61 return _type_render($into, $data);
511             }
512              
513             sub routines {
514 1     1 1 4 my ($self, @data) = @_;
515              
516             $self->object->constraints->then(sub{
517 2     2   6 my $value = $_->value;
518 2 100       40 (@data == grep $value->can($_), @data) ? true : false
519 1         8 });
520              
521 1         11 return $self;
522             }
523              
524             sub scalar {
525 2     2 1 9 my ($self, @code) = @_;
526              
527 2 50   2   23 $self->constraint('scalar', @code ? @code : sub{true});
  2         13  
528              
529 2         24 return $self;
530             }
531              
532             sub scalarref {
533 1     1 1 5 my ($self, @code) = @_;
534              
535 1         6 return $self->scalar(@code);
536             }
537              
538             sub string {
539 161     161 1 305 my ($self, @code) = @_;
540              
541 161 50   99   993 $self->constraint('string', @code ? @code : sub{true});
  99         367  
542              
543 161         638 return $self;
544             }
545              
546             sub tuple {
547 1     1 1 5 my ($self, @data) = @_;
548              
549             $self->constraints->when(sub{
550             CORE::defined($_->value) && CORE::ref($_->value) eq 'ARRAY'
551 10 100 66 10   27 && @data == @{$_->value}
  6         15  
552             })->then(sub{
553 5     5   13 my $check = 0;
554 5         14 my $value = $_->value;
555 5 50       23 return false if @data != @$value;
556 5         17 for (my $i = 0; $i < @data; $i++) {
557 15 100       47 my ($match, @args) = (ref $data[$i]) ? (@{$data[$i]}) : ($data[$i]);
  5         14  
558 15 100       50 $check++ if $self->new->do($match, @args)->check($value->[$i]);
559             }
560 5 100       21 (@data == $check) ? true : false
561 1         6 });
562              
563 1         11 return $self;
564             }
565              
566             sub undef {
567 7     7 1 22 my ($self, @code) = @_;
568              
569 7 50   3   42 $self->constraint('undef', @code ? @code : sub{true});
  3         16  
570              
571 7         25 return $self;
572             }
573              
574             sub validate {
575 135     135 1 322 my ($self, $data) = @_;
576              
577 135         377 my $valid = $self->check($data);
578              
579 135 100       430 return $data if $valid;
580              
581 30         157 require Scalar::Util;
582              
583 30         121 my $identity = lc(Venus::Type->new(value => $data)->identify);
584 30   100     115 my $expected = (join ' OR ', @{$self->expects}) || 'indescribable constraints';
585 30         106 my $message = sprintf($self->message, $self->name, $identity, $expected);
586              
587 30         240 $self->throw('error_on_validate', $data)->error;
588              
589 0         0 return;
590             }
591              
592             sub validator {
593 1     1 1 6 my ($self, $data) = @_;
594              
595 1 50       10 $self->expression($data) if $data;
596              
597 1         6 return $self->defer('validate');
598             }
599              
600             sub value {
601 3     3 1 10 my ($self, @code) = @_;
602              
603             $self->constraints
604 9 50   9   66 ->when(sub{CORE::defined($_->value) && !ref($_->value)})
605 3 50   6   13 ->then(@code ? @code : sub{true});
  6         32  
606              
607 3         22 return $self;
608             }
609              
610             sub within {
611 6     6 1 30 my ($self, $type, @next) = @_;
612              
613 6 50       22 if (!$type) {
614 0         0 return $self;
615             }
616              
617 6         20 my $where = $self->new;
618              
619 6 100 100     79 if (lc($type) eq 'hash' || lc($type) eq 'hashref') {
    50 66        
620             $self->constraints->when(sub{
621             CORE::defined($_->value) && UNIVERSAL::isa($_->value, 'HASH')
622 28 100 100 28   70 && (keys %{$_->value}) > 0
  20         42  
623             })->then(sub{
624 16     16   60 my $value = $_->value;
625 16 50       96 UNIVERSAL::isa($value, 'HASH')
626             && CORE::values(%$value) == grep $where->check($_), CORE::values(%$value)
627 3         23 });
628             }
629             elsif (lc($type) eq 'array' || lc($type) eq 'arrayref') {
630             $self->constraints->when(sub{
631             CORE::defined($_->value) && UNIVERSAL::isa($_->value, 'ARRAY')
632 21 100 100 21   82 && @{$_->value} > 0
  12         30  
633             })->then(sub{
634 9     9   28 my $value = $_->value;
635 9 50       50 UNIVERSAL::isa($value, 'ARRAY')
636             && @$value == grep $where->check($_), @$value
637 3         19 });
638             }
639             else {
640 0         0 $self->throw('error_on_within', $type, @next)->error;
641             }
642              
643 6 100       62 $where->accept(map +(ref($_) ? @$_ : $_), $next[0]) if @next;
    100          
644              
645 6         50 return $where;
646             }
647              
648             sub yesno {
649 1     1 1 6 my ($self, @code) = @_;
650              
651             $self->constraints->when(sub{
652 8 100   8   25 CORE::defined($_->value) && $_->value =~ /^(?:1|y(?:es)?|0|n(?:o)?)$/i
653 1 50   6   6 })->then(@code ? @code : sub{true});
  6         19  
654              
655 1         17 return $self;
656             }
657              
658             # ERRORS
659              
660             sub error_on_validate {
661 31     31 1 81 my ($self, $data) = @_;
662              
663 31         151 require Venus::Type;
664              
665 31         258 my $legend = {
666             array => 'arrayref',
667             code => 'coderef',
668             hash => 'hashref',
669             regexp => 'regexpref',
670             scalar => 'scalarref',
671             scalar => 'scalarref',
672             };
673              
674 31         119 my $identity = Venus::Type->new(value => $data)->identify;
675 31   66     135 $identity = $legend->{lc($identity)} || lc($identity);
676              
677 31   100     103 my $expected = (join ' OR ', @{$self->expects}) || 'indescribable constraints';
678              
679 31         119 my $message = sprintf($self->message, $self->name, $identity, $expected);
680 31         118 $message .= "\n\nReceived:\n\n\"@{[$self->received($data)]}\"\n\n";
  31         127  
681              
682             return {
683 31         284 name => 'on.validate',
684             message => $message,
685             stash => {
686             identity => $identity,
687             variable => $data,
688             },
689             };
690             }
691              
692             sub error_on_within {
693 1     1 1 5 my ($self, $type, @args) = @_;
694              
695             return {
696 1         11 name => 'on.within',
697             message => "Invalid type (\"$type\") provided to the \"within\" method",
698             stash => {
699             self => $self,
700             type => $type,
701             args => [@args],
702             },
703             };
704             }
705              
706             # ROUTINES
707              
708             sub _type_parse {
709 483     483   1137 my @items = _type_parse_pipes(@_);
710              
711 483         1106 my $either = @items > 1;
712              
713 483         1247 @items = map _type_parse_nested($_), @items;
714              
715 483 100 100     3364 return wantarray && !$either ? @items : [$either ? ("either") : (), @items];
    100          
716             }
717              
718             sub _type_parse_lists {
719 133     133   276 my @items = @_;
720              
721 133         209 my $r0 = '[\"\'\[\]]';
722 133         190 my $r1 = '[^\"\'\[\]]';
723 133         208 my $r2 = _type_subexpr_type_2();
724 133         231 my $r3 = _type_subexpr_delimiter();
725              
726             return (
727             grep length,
728 133         225 map {split/,\s*(?=(?:$r1*$r0$r1*$r0)*$r1*$)(${r2}(?:${r3}[^,]*)?)?/}
  133         1721  
729             @items
730             );
731             }
732              
733             sub _type_parse_nested {
734 825     825   1653 my ($expr) = @_;
735              
736 825 100       1312 return ($expr) if $expr !~ _type_regexp(_type_subexpr_type_2());
737              
738 66         220 my @items = ($expr);
739              
740 66         365 @items = ($expr =~ /^(\w+)\s*\[\s*(.*)\s*\]+$/g);
741              
742 66         197 @items = map _type_parse_lists($_), @items;
743              
744 66 100       171 @items = map +(
745 261         431 $_ =~ qr/^@{[_type_subexpr_type_2()]},.*$/ ? _type_parse_lists($_) : $_
746             ),
747             @items;
748              
749 66         152 @items = map {s/^["']+|["']+$//gr} @items;
  263         1111  
750              
751 66         223 @items = map _type_parse($_), @items;
752              
753 66 100       278 return (@items > 1 ? [@items] : @items);
754             }
755              
756             sub _type_parse_pipes {
757 818     818   1458 my ($expr) = @_;
758              
759 818         1058 my @items;
760              
761             # i.e. tuple[number, string] | tuple[string, number]
762 818 100       1466 if
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    50          
    50          
    50          
763             (
764             _type_regexp_eval(
765             $expr, _type_regexp(_type_subexpr_type_2(), _type_subexpr_type_2())
766             )
767             )
768             {
769 3         8 @items = map _type_parse_tuples($_),
770             _type_regexp_eval($expr,
771             _type_regexp_groups(_type_subexpr_type_2(), _type_subexpr_type_2()));
772             }
773             # i.e. string | tuple[number, string]
774             elsif
775             (
776             _type_regexp_eval($expr,
777             _type_regexp(_type_subexpr_type_1(), _type_subexpr_type_2()))
778             )
779             {
780 4         14 @items = map _type_parse_tuples($_),
781             _type_regexp_eval($expr,
782             _type_regexp_groups(_type_subexpr_type_1(), _type_subexpr_type_2()));
783             }
784             # i.e. tuple[number, string] | string
785             elsif
786             (
787             _type_regexp_eval($expr,
788             _type_regexp(_type_subexpr_type_2(), _type_subexpr_type_1()))
789             )
790             {
791 3         10 @items = map _type_parse_tuples($_),
792             _type_regexp_eval($expr,
793             _type_regexp_groups(_type_subexpr_type_2(), _type_subexpr_type_1()));
794             }
795             # special condition: i.e. tuple[number, string]
796             elsif
797             (
798             _type_regexp_eval($expr, _type_regexp(_type_subexpr_type_2()))
799             )
800             {
801 49         147 @items = ($expr);
802             }
803             # i.e. "..." | tuple[number, string]
804             elsif
805             (
806             _type_regexp_eval($expr,
807             _type_regexp(_type_subexpr_type_3(), _type_subexpr_type_2()))
808             )
809             {
810 4         14 @items = _type_regexp_eval($expr,
811             _type_regexp_groups(_type_subexpr_type_3(), _type_subexpr_type_2()));
812 4         20 @items = (_type_parse_pipes($items[0]), _type_parse_tuples($items[1]));
813             }
814             # i.e. tuple[number, string] | "..."
815             elsif
816             (
817             _type_regexp_eval($expr,
818             _type_regexp(_type_subexpr_type_2(), _type_subexpr_type_3()))
819             )
820             {
821 3         12 @items = _type_regexp_eval($expr,
822             _type_regexp_groups(_type_subexpr_type_2(), _type_subexpr_type_3()));
823 3         18 @items = (_type_parse_tuples($items[0]), _type_parse_pipes($items[1]));
824             }
825             # i.e. Package::Name | "..."
826             elsif
827             (
828             _type_regexp_eval($expr,
829             _type_regexp(_type_subexpr_type_4(), _type_subexpr_type_3()))
830             )
831             {
832 325         691 @items = _type_regexp_eval($expr,
833             _type_regexp_groups(_type_subexpr_type_4(), _type_subexpr_type_3()));
834 325         1232 @items = ($items[0], _type_parse_pipes($items[1]));
835             }
836             # i.e. "..." | Package::Name
837             elsif
838             (
839             _type_regexp_eval($expr,
840             _type_regexp(_type_subexpr_type_3(), _type_subexpr_type_4()))
841             )
842             {
843 0         0 @items = _type_regexp_eval($expr,
844             _type_regexp_groups(_type_subexpr_type_3(), _type_subexpr_type_4()));
845 0         0 @items = (_type_parse_pipes($items[0]), $items[1]);
846             }
847             # i.e. string | "..."
848             elsif
849             (
850             _type_regexp_eval($expr,
851             _type_regexp(_type_subexpr_type_1(), _type_subexpr_type_3()))
852             )
853             {
854 0         0 @items = _type_regexp_eval($expr,
855             _type_regexp_groups(_type_subexpr_type_1(), _type_subexpr_type_3()));
856 0         0 @items = ($items[0], _type_parse_pipes($items[1]));
857             }
858             # i.e. "..." | string
859             elsif
860             (
861             _type_regexp_eval($expr,
862             _type_regexp(_type_subexpr_type_3(), _type_subexpr_type_1()))
863             )
864             {
865 0         0 @items = _type_regexp_eval($expr,
866             _type_regexp_groups(_type_subexpr_type_3(), _type_subexpr_type_1()));
867 0         0 @items = (_type_parse_pipes($items[0]), $items[1]);
868             }
869             # i.e. "..." | "..."
870             elsif
871             (
872             _type_regexp_eval($expr,
873             _type_regexp(_type_subexpr_type_3(), _type_subexpr_type_3()))
874             )
875             {
876 0         0 @items = map _type_parse_pipes($_),
877             _type_regexp_eval($expr,
878             _type_regexp_groups(_type_subexpr_type_3(), _type_subexpr_type_3()));
879             }
880             else {
881 427         1006 @items = ($expr);
882             }
883              
884 818         8746 return (@items);
885             }
886              
887             sub _type_parse_tuples {
888 27 100   27   73 map +(scalar(_type_regexp_eval($_,
889             _type_regexp(_type_subexpr_type_2(), _type_subexpr_type_2())))
890             ? (_type_parse_pipes($_))
891             : ($_)), @_
892             }
893              
894             sub _type_regexp {
895 8078     8078   9783 qr/^@{[_type_regexp_joined(@_)]}$/
  8078         12169  
896             }
897              
898             sub _type_regexp_eval {
899 7595     7595   36971 map {s/^\s+|\s+$//gr} ($_[0] =~ $_[1])
  1078         5166  
900             }
901              
902             sub _type_regexp_groups {
903 342     342   449 qr/^@{[_type_regexp_joined(_type_subexpr_groups(@_))]}$/
  342         699  
904             }
905              
906             sub _type_regexp_joined {
907 8420     8420   11823 join(_type_subexpr_delimiter(), @_)
908             }
909              
910             sub _type_render {
911 77     77   140 my ($into, $data) = @_;
912              
913 77 100       165 if (ref $data eq 'HASH') {
914             $data = join ', ', map +(qq("$_"), _type_render($into, $$data{$_})),
915 33         44 sort keys %{$data};
  33         185  
916 33         110 $data = "$into\[$data\]";
917             }
918              
919 77 100       141 if (ref $data eq 'ARRAY') {
920 1 50       6 $data = join ', ', map +(/^\w+$/ ? qq("$_") : $_), @{$data};
  1         15  
921 1         5 $data = "$into\[$data\]";
922             }
923              
924 77         234 return $data;
925             }
926              
927             sub _type_subexpr_delimiter {
928 8553     8553   173720 '\s*\|\s*'
929             }
930              
931             sub _type_subexpr_groups {
932 342     342   1502 map "($_)", @_
933             }
934              
935             sub _type_subexpr_type_1 {
936 2487     2487   4707 '\w+'
937             }
938              
939             sub _type_subexpr_type_2 {
940 6877     6877   13222 '\w+\s*\[.*\]+'
941             }
942              
943             sub _type_subexpr_type_3 {
944 4733     4733   8112 '.*'
945             }
946              
947             sub _type_subexpr_type_4 {
948 1504     1504   2742 '[A-Za-z][:\^\w]+\w*'
949             }
950              
951             1;
952              
953              
954              
955             =head1 NAME
956              
957             Venus::Assert - Assert Class
958              
959             =cut
960              
961             =head1 ABSTRACT
962              
963             Assert Class for Perl 5
964              
965             =cut
966              
967             =head1 SYNOPSIS
968              
969             package main;
970              
971             use Venus::Assert;
972              
973             my $assert = Venus::Assert->new('Example');
974              
975             # $assert->format(float => sub {sprintf('%.2f', $_->value)});
976              
977             # $assert->accept(float => sub {$_->value > 1});
978              
979             # $assert->check;
980              
981             =cut
982              
983             =head1 DESCRIPTION
984              
985             This package provides a mechanism for asserting type constraints and coercions
986             on data.
987              
988             =cut
989              
990             =head1 ATTRIBUTES
991              
992             This package has the following attributes:
993              
994             =cut
995              
996             =head2 expects
997              
998             expects(ArrayRef)
999              
1000             This attribute is read-write, accepts C<(ArrayRef)> values, and is optional.
1001              
1002             =cut
1003              
1004             =head2 message
1005              
1006             message(Str)
1007              
1008             This attribute is read-write, accepts C<(Str)> values, and is optional.
1009              
1010             =cut
1011              
1012             =head2 name
1013              
1014             name(Str)
1015              
1016             This attribute is read-write, accepts C<(Str)> values, and is optional.
1017              
1018             =cut
1019              
1020             =head1 INHERITS
1021              
1022             This package inherits behaviors from:
1023              
1024             L
1025              
1026             =cut
1027              
1028             =head1 INTEGRATES
1029              
1030             This package integrates behaviors from:
1031              
1032             L
1033              
1034             =cut
1035              
1036             =head1 METHODS
1037              
1038             This package provides the following methods:
1039              
1040             =cut
1041              
1042             =head2 accept
1043              
1044             accept(Str $name, Any @args) (Object)
1045              
1046             The accept method registers a constraint based on the built-in type or package
1047             name provided as the first argument. The built-in types are I<"array">,
1048             I<"boolean">, I<"code">, I<"float">, I<"hash">, I<"number">, I<"object">,
1049             I<"regexp">, I<"scalar">, I<"string">, or I<"undef">. Any name given that is
1050             not a built-in type is assumed to be a method (i.e. a method call) or an
1051             I<"object"> of the name provided. Additional arguments are assumed to be
1052             arguments for the dispatched method call. Optionally, you can provide a
1053             callback to further constrain/validate the provided value, returning truthy or
1054             falsy, for methods that support it.
1055              
1056             I>
1057              
1058             =over 4
1059              
1060             =item accept example 1
1061              
1062             # given: synopsis
1063              
1064             package main;
1065              
1066             $assert = $assert->accept('float');
1067              
1068             # bless(..., "Venus::Assert")
1069              
1070             # ...
1071              
1072             # $assert->check;
1073              
1074             # 0
1075              
1076             # $assert->check(1.01);
1077              
1078             # 1
1079              
1080             =back
1081              
1082             =over 4
1083              
1084             =item accept example 2
1085              
1086             # given: synopsis
1087              
1088             package main;
1089              
1090             $assert = $assert->accept('number');
1091              
1092             # bless(..., "Venus::Assert")
1093              
1094             # ...
1095              
1096             # $assert->check(1.01);
1097              
1098             # 0
1099              
1100             # $assert->check(1_01);
1101              
1102             # 1
1103              
1104             =back
1105              
1106             =over 4
1107              
1108             =item accept example 3
1109              
1110             # given: synopsis
1111              
1112             package Example1;
1113              
1114             sub new {
1115             bless {};
1116             }
1117              
1118             package Example2;
1119              
1120             sub new {
1121             bless {};
1122             }
1123              
1124             package main;
1125              
1126             $assert = $assert->accept('object');
1127              
1128             # bless(..., "Venus::Assert")
1129              
1130             # ...
1131              
1132             # $assert->check;
1133              
1134             # 0
1135              
1136             # $assert->check(qr//);
1137              
1138             # 0
1139              
1140             # $assert->check(Example1->new);
1141              
1142             # 1
1143              
1144             # $assert->check(Example2->new);
1145              
1146             # 1
1147              
1148             =back
1149              
1150             =over 4
1151              
1152             =item accept example 4
1153              
1154             # given: synopsis
1155              
1156             package Example1;
1157              
1158             sub new {
1159             bless {};
1160             }
1161              
1162             package Example2;
1163              
1164             sub new {
1165             bless {};
1166             }
1167              
1168             package main;
1169              
1170             $assert = $assert->accept('Example1');
1171              
1172             # bless(..., "Venus::Assert")
1173              
1174             # ...
1175              
1176             # $assert->check;
1177              
1178             # 0
1179              
1180             # $assert->check(qr//);
1181              
1182             # 0
1183              
1184             # $assert->check(Example1->new);
1185              
1186             # 1
1187              
1188             # $assert->check(Example2->new);
1189              
1190             # 0
1191              
1192             =back
1193              
1194             =cut
1195              
1196             =head2 any
1197              
1198             any() (Assert)
1199              
1200             The any method configures the object to accept any value and returns the
1201             invocant.
1202              
1203             I>
1204              
1205             =over 4
1206              
1207             =item any example 1
1208              
1209             # given: synopsis
1210              
1211             package main;
1212              
1213             $assert = $assert->any;
1214              
1215             # $assert->check;
1216              
1217             # true
1218              
1219             =back
1220              
1221             =cut
1222              
1223             =head2 array
1224              
1225             array(CodeRef $check) (Assert)
1226              
1227             The array method configures the object to accept array references and returns
1228             the invocant.
1229              
1230             I>
1231              
1232             =over 4
1233              
1234             =item array example 1
1235              
1236             # given: synopsis
1237              
1238             package main;
1239              
1240             $assert = $assert->array;
1241              
1242             # $assert->check([]);
1243              
1244             # true
1245              
1246             =back
1247              
1248             =cut
1249              
1250             =head2 arrayref
1251              
1252             arrayref(CodeRef $check) (Assert)
1253              
1254             The arrayref method configures the object to accept array references and
1255             returns the invocant.
1256              
1257             I>
1258              
1259             =over 4
1260              
1261             =item arrayref example 1
1262              
1263             # given: synopsis
1264              
1265             package main;
1266              
1267             $assert = $assert->arrayref;
1268              
1269             # $assert->check([]);
1270              
1271             # true
1272              
1273             =back
1274              
1275             =cut
1276              
1277             =head2 attributes
1278              
1279             attributes(Str | ArrayRef[Str] @pairs) (Assert)
1280              
1281             The attributes method configures the object to accept objects containing
1282             attributes whose values' match the attribute names and types specified, and
1283             returns the invocant.
1284              
1285             I>
1286              
1287             =over 4
1288              
1289             =item attributes example 1
1290              
1291             # given: synopsis
1292              
1293             package main;
1294              
1295             $assert = $assert->attributes;
1296              
1297             # $assert->check(Venus::Assert->new);
1298              
1299             # true
1300              
1301             =back
1302              
1303             =over 4
1304              
1305             =item attributes example 2
1306              
1307             # given: synopsis
1308              
1309             package main;
1310              
1311             $assert = $assert->attributes(name => 'string');
1312              
1313             # $assert->check(bless{});
1314              
1315             # false
1316              
1317             # $assert->check(Venus::Assert->new);
1318              
1319             # true
1320              
1321             =back
1322              
1323             =over 4
1324              
1325             =item attributes example 3
1326              
1327             # given: synopsis
1328              
1329             package Example3;
1330              
1331             use Venus::Class;
1332              
1333             attr 'name';
1334              
1335             package main;
1336              
1337             $assert = $assert->attributes(name => 'string', message => 'string');
1338              
1339             # $assert->check(bless{});
1340              
1341             # false
1342              
1343             # $assert->check(Venus::Assert->new);
1344              
1345             # true
1346              
1347             # $assert->check(Example3->new);
1348              
1349             # false
1350              
1351             =back
1352              
1353             =cut
1354              
1355             =head2 boolean
1356              
1357             boolean(CodeRef $check) (Assert)
1358              
1359             The boolean method configures the object to accept boolean values and returns
1360             the invocant.
1361              
1362             I>
1363              
1364             =over 4
1365              
1366             =item boolean example 1
1367              
1368             # given: synopsis
1369              
1370             package main;
1371              
1372             $assert = $assert->boolean;
1373              
1374             # $assert->check(false);
1375              
1376             # true
1377              
1378             =back
1379              
1380             =cut
1381              
1382             =head2 check
1383              
1384             check(Any $data) (Bool)
1385              
1386             The check method returns true or false if the data provided passes the
1387             registered constraints.
1388              
1389             I>
1390              
1391             =over 4
1392              
1393             =item check example 1
1394              
1395             # given: synopsis
1396              
1397             package main;
1398              
1399             $assert->constraint(float => sub { $_->value > 1 });
1400              
1401             my $check = $assert->check;
1402              
1403             # 0
1404              
1405             =back
1406              
1407             =over 4
1408              
1409             =item check example 2
1410              
1411             # given: synopsis
1412              
1413             package main;
1414              
1415             $assert->constraint(float => sub { $_->value > 1 });
1416              
1417             my $check = $assert->check('0.01');
1418              
1419             # 0
1420              
1421             =back
1422              
1423             =over 4
1424              
1425             =item check example 3
1426              
1427             # given: synopsis
1428              
1429             package main;
1430              
1431             $assert->constraint(float => sub { $_->value > 1 });
1432              
1433             my $check = $assert->check('1.01');
1434              
1435             # 1
1436              
1437             =back
1438              
1439             =over 4
1440              
1441             =item check example 4
1442              
1443             # given: synopsis
1444              
1445             package main;
1446              
1447             $assert->constraint(float => sub { $_->value > 1 });
1448              
1449             my $check = $assert->check(time);
1450              
1451             # 0
1452              
1453             =back
1454              
1455             =cut
1456              
1457             =head2 checker
1458              
1459             checker(Str $expr) (CodeRef)
1460              
1461             The checker method calls L with the type assertion signature
1462             provided and returns a coderef which calls the L method when called.
1463              
1464             I>
1465              
1466             =over 4
1467              
1468             =item checker example 1
1469              
1470             # given: synopsis
1471              
1472             package main;
1473              
1474             my $checker = $assert->checker('string');
1475              
1476             # sub { ... }
1477              
1478             # $checker->('hello');
1479              
1480             # true
1481              
1482             # $checker->(['goodbye']);
1483              
1484             # false
1485              
1486             =back
1487              
1488             =cut
1489              
1490             =head2 clear
1491              
1492             clear() (Assert)
1493              
1494             The clear method resets all match conditions for both constraints and coercions
1495             and returns the invocant.
1496              
1497             I>
1498              
1499             =over 4
1500              
1501             =item clear example 1
1502              
1503             # given: synopsis
1504              
1505             package main;
1506              
1507             $assert = $assert->clear;
1508              
1509             # bless(..., "Venus::Assert")
1510              
1511             =back
1512              
1513             =cut
1514              
1515             =head2 code
1516              
1517             code(CodeRef $check) (Assert)
1518              
1519             The code method configures the object to accept code references and returns
1520             the invocant.
1521              
1522             I>
1523              
1524             =over 4
1525              
1526             =item code example 1
1527              
1528             # given: synopsis
1529              
1530             package main;
1531              
1532             $assert = $assert->code;
1533              
1534             # $assert->check(sub{});
1535              
1536             # true
1537              
1538             =back
1539              
1540             =cut
1541              
1542             =head2 coderef
1543              
1544             coderef(CodeRef $check) (Assert)
1545              
1546             The coderef method configures the object to accept code references and returns
1547             the invocant.
1548              
1549             I>
1550              
1551             =over 4
1552              
1553             =item coderef example 1
1554              
1555             # given: synopsis
1556              
1557             package main;
1558              
1559             $assert = $assert->coderef;
1560              
1561             # $assert->check(sub{});
1562              
1563             # true
1564              
1565             =back
1566              
1567             =cut
1568              
1569             =head2 coerce
1570              
1571             coerce(Any $data) (Any)
1572              
1573             The coerce method returns the coerced data if the data provided matches any of
1574             the registered coercions.
1575              
1576             I>
1577              
1578             =over 4
1579              
1580             =item coerce example 1
1581              
1582             # given: synopsis
1583              
1584             package main;
1585              
1586             $assert->coercion(float => sub { sprintf('%.2f', $_->value) });
1587              
1588             my $coerce = $assert->coerce;
1589              
1590             # undef
1591              
1592             =back
1593              
1594             =over 4
1595              
1596             =item coerce example 2
1597              
1598             # given: synopsis
1599              
1600             package main;
1601              
1602             $assert->coercion(float => sub { sprintf('%.2f', $_->value) });
1603              
1604             my $coerce = $assert->coerce('1.01');
1605              
1606             # "1.01"
1607              
1608             =back
1609              
1610             =over 4
1611              
1612             =item coerce example 3
1613              
1614             # given: synopsis
1615              
1616             package main;
1617              
1618             $assert->coercion(float => sub { sprintf('%.2f', $_->value) });
1619              
1620             my $coerce = $assert->coerce('1.00001');
1621              
1622             # "1.00"
1623              
1624             =back
1625              
1626             =over 4
1627              
1628             =item coerce example 4
1629              
1630             # given: synopsis
1631              
1632             package main;
1633              
1634             $assert->coercion(float => sub { sprintf('%.2f', $_->value) });
1635              
1636             my $coerce = $assert->coerce('hello world');
1637              
1638             # "hello world"
1639              
1640             =back
1641              
1642             =cut
1643              
1644             =head2 coercion
1645              
1646             coercion(Str $type, CodeRef $code) (Object)
1647              
1648             The coercion method registers a coercion based on the type provided.
1649              
1650             I>
1651              
1652             =over 4
1653              
1654             =item coercion example 1
1655              
1656             # given: synopsis
1657              
1658             package main;
1659              
1660             $assert = $assert->coercion(float => sub { sprintf('%.2f', $_->value) });
1661              
1662             # bless(..., "Venus::Assert")
1663              
1664             =back
1665              
1666             =cut
1667              
1668             =head2 coercions
1669              
1670             coercions() (Match)
1671              
1672             The coercions method returns the registered coercions as a L object.
1673              
1674             I>
1675              
1676             =over 4
1677              
1678             =item coercions example 1
1679              
1680             # given: synopsis
1681              
1682             package main;
1683              
1684             my $coercions = $assert->coercions;
1685              
1686             # bless(..., "Venus::Match")
1687              
1688             =back
1689              
1690             =cut
1691              
1692             =head2 conditions
1693              
1694             conditions() (Assert)
1695              
1696             The conditions method is an object construction hook that allows subclasses to
1697             configure the object on construction setting up constraints and coercions and
1698             returning the invocant.
1699              
1700             I>
1701              
1702             =over 4
1703              
1704             =item conditions example 1
1705              
1706             # given: synopsis
1707              
1708             package main;
1709              
1710             $assert = $assert->conditions;
1711              
1712             =back
1713              
1714             =over 4
1715              
1716             =item conditions example 2
1717              
1718             package Example::Type::PositveNumber;
1719              
1720             use base 'Venus::Assert';
1721              
1722             sub conditions {
1723             my ($self) = @_;
1724              
1725             $self->number(sub {
1726             $_->value >= 0
1727             });
1728              
1729             return $self;
1730             }
1731              
1732             package main;
1733              
1734             my $assert = Example::Type::PositveNumber->new;
1735              
1736             # $assert->check(0);
1737              
1738             # true
1739              
1740             # $assert->check(1);
1741              
1742             # true
1743              
1744             # $assert->check(-1);
1745              
1746             # false
1747              
1748             =back
1749              
1750             =cut
1751              
1752             =head2 constraint
1753              
1754             constraint(Str $type, CodeRef $code) (Object)
1755              
1756             The constraint method registers a constraint based on the type provided.
1757              
1758             I>
1759              
1760             =over 4
1761              
1762             =item constraint example 1
1763              
1764             # given: synopsis
1765              
1766             package main;
1767              
1768             $assert = $assert->constraint(float => sub { $_->value > 1 });
1769              
1770             # bless(..., "Venus::Assert")
1771              
1772             =back
1773              
1774             =cut
1775              
1776             =head2 constraints
1777              
1778             constraints() (Match)
1779              
1780             The constraints method returns the registered constraints as a L
1781             object.
1782              
1783             I>
1784              
1785             =over 4
1786              
1787             =item constraints example 1
1788              
1789             # given: synopsis
1790              
1791             package main;
1792              
1793             my $constraints = $assert->constraints;
1794              
1795             # bless(..., "Venus::Match")
1796              
1797             =back
1798              
1799             =cut
1800              
1801             =head2 defined
1802              
1803             defined(CodeRef $check) (Assert)
1804              
1805             The defined method configures the object to accept any value that's not
1806             undefined and returns the invocant.
1807              
1808             I>
1809              
1810             =over 4
1811              
1812             =item defined example 1
1813              
1814             # given: synopsis
1815              
1816             package main;
1817              
1818             $assert = $assert->defined;
1819              
1820             # $assert->check(0);
1821              
1822             # true
1823              
1824             =back
1825              
1826             =cut
1827              
1828             =head2 either
1829              
1830             either(Str | ArrayRef[Str|ArrayRef] $dispatch) (Assert)
1831              
1832             The either method configures the object to accept "either" of the conditions
1833             provided, which may be a string or arrayref representing a method call, and
1834             returns the invocant.
1835              
1836             I>
1837              
1838             =over 4
1839              
1840             =item either example 1
1841              
1842             # given: synopsis
1843              
1844             package main;
1845              
1846             $assert = $assert->either('string');
1847              
1848             # $assert->check('1');
1849              
1850             # true
1851              
1852             # $assert->check(1);
1853              
1854             # false
1855              
1856             =back
1857              
1858             =over 4
1859              
1860             =item either example 2
1861              
1862             # given: synopsis
1863              
1864             package main;
1865              
1866             $assert = $assert->either('string', 'number');
1867              
1868             # $assert->check(true);
1869              
1870             # false
1871              
1872             # $assert->check('1');
1873              
1874             # true
1875              
1876             # $assert->check(1);
1877              
1878             # true
1879              
1880             =back
1881              
1882             =over 4
1883              
1884             =item either example 3
1885              
1886             # given: synopsis
1887              
1888             package main;
1889              
1890             $assert = $assert->either('number', 'boolean');
1891              
1892             # $assert->check(true);
1893              
1894             # true
1895              
1896             # $assert->check('1');
1897              
1898             # false
1899              
1900             # $assert->check(1);
1901              
1902             # true
1903              
1904             =back
1905              
1906             =cut
1907              
1908             =head2 enum
1909              
1910             enum(Any @data) (Assert)
1911              
1912             The enum method configures the object to accept any one of the provide options,
1913             and returns the invocant.
1914              
1915             I>
1916              
1917             =over 4
1918              
1919             =item enum example 1
1920              
1921             # given: synopsis
1922              
1923             package main;
1924              
1925             $assert = $assert->enum('s', 'm', 'l', 'xl');
1926              
1927             # $assert->check('s');
1928              
1929             # true
1930              
1931             # $assert->check('xs');
1932              
1933             # false
1934              
1935             =back
1936              
1937             =cut
1938              
1939             =head2 expression
1940              
1941             expression(Str $expr) (Assert)
1942              
1943             The expression method parses a string representation of an type assertion
1944             signature, registers the subexpressions using the L and L
1945             methods, and returns the invocant.
1946              
1947             I>
1948              
1949             =over 4
1950              
1951             =item expression example 1
1952              
1953             # given: synopsis
1954              
1955             package main;
1956              
1957             $assert = $assert->expression('string');
1958              
1959             # $assert->check('hello');
1960              
1961             # true
1962              
1963             # $assert->check(['goodbye']);
1964              
1965             # false
1966              
1967             =back
1968              
1969             =over 4
1970              
1971             =item expression example 2
1972              
1973             # given: synopsis
1974              
1975             package main;
1976              
1977             $assert = $assert->expression('string | coderef');
1978              
1979             # $assert->check('hello');
1980              
1981             # true
1982              
1983             # $assert->check(sub{'hello'});
1984              
1985             # true
1986              
1987             # $assert->check(['goodbye']);
1988              
1989             # false
1990              
1991             =back
1992              
1993             =over 4
1994              
1995             =item expression example 3
1996              
1997             # given: synopsis
1998              
1999             package main;
2000              
2001             $assert = $assert->expression('string | coderef | Venus::Assert');
2002              
2003             # $assert->check('hello');
2004              
2005             # true
2006              
2007             # $assert->check(sub{'hello'});
2008              
2009             # true
2010              
2011             # $assert->check($assert);
2012              
2013             # true
2014              
2015             # $assert->check(['goodbye']);
2016              
2017             # false
2018              
2019             =back
2020              
2021             =over 4
2022              
2023             =item expression example 4
2024              
2025             # given: synopsis
2026              
2027             package main;
2028              
2029             $assert = $assert->expression('Venus::Assert | within[arrayref, Venus::Assert]');
2030              
2031             # $assert->check('hello');
2032              
2033             # false
2034              
2035             # $assert->check(sub{'hello'});
2036              
2037             # false
2038              
2039             # $assert->check($assert);
2040              
2041             # true
2042              
2043             # $assert->check(['goodbye']);
2044              
2045             # false
2046              
2047             # $assert->check([$assert]);
2048              
2049             # true
2050              
2051             =back
2052              
2053             =over 4
2054              
2055             =item expression example 5
2056              
2057             # given: synopsis
2058              
2059             package main;
2060              
2061             $assert = $assert->expression('
2062             string
2063             | within[
2064             arrayref, within[
2065             hashref, string
2066             ]
2067             ]
2068             ');
2069              
2070             # $assert->check('hello');
2071              
2072             # true
2073              
2074             # $assert->check(sub{'hello'});
2075              
2076             # false
2077              
2078             # $assert->check($assert);
2079              
2080             # false
2081              
2082             # $assert->check([]);
2083              
2084             # false
2085              
2086             # $assert->check([{'test' => ['okay']}]);
2087              
2088             # false
2089              
2090             # $assert->check([{'test' => 'okay'}]);
2091              
2092             # true
2093              
2094             =back
2095              
2096             =cut
2097              
2098             =head2 float
2099              
2100             float(CodeRef $check) (Assert)
2101              
2102             The float method configures the object to accept floating-point values and
2103             returns the invocant.
2104              
2105             I>
2106              
2107             =over 4
2108              
2109             =item float example 1
2110              
2111             # given: synopsis
2112              
2113             package main;
2114              
2115             $assert = $assert->float;
2116              
2117             # $assert->check(1.23);
2118              
2119             # true
2120              
2121             =back
2122              
2123             =cut
2124              
2125             =head2 format
2126              
2127             format(Str $name, CodeRef $callback) (Object)
2128              
2129             The format method registers a coercion based on the built-in type or package
2130             name and callback provided. The built-in types are I<"array">, I<"boolean">,
2131             I<"code">, I<"float">, I<"hash">, I<"number">, I<"object">, I<"regexp">,
2132             I<"scalar">, I<"string">, or I<"undef">. Any name given that is not a built-in
2133             type is assumed to be an I<"object"> of the name provided.
2134              
2135             I>
2136              
2137             =over 4
2138              
2139             =item format example 1
2140              
2141             # given: synopsis
2142              
2143             package main;
2144              
2145             $assert = $assert->format('float', sub{int $_->value});
2146              
2147             # bless(..., "Venus::Assert")
2148              
2149             # ...
2150              
2151             # $assert->coerce;
2152              
2153             # undef
2154              
2155             # $assert->coerce(1.01);
2156              
2157             # 1
2158              
2159             =back
2160              
2161             =over 4
2162              
2163             =item format example 2
2164              
2165             # given: synopsis
2166              
2167             package main;
2168              
2169             $assert = $assert->format('number', sub{ sprintf('%.2f', $_->value) });
2170              
2171             # bless(..., "Venus::Assert")
2172              
2173             # ...
2174              
2175             # $assert->coerce(1.01);
2176              
2177             # 1.01
2178              
2179             # $assert->coerce(1_01);
2180              
2181             # 101.00
2182              
2183             =back
2184              
2185             =over 4
2186              
2187             =item format example 3
2188              
2189             # given: synopsis
2190              
2191             package Example1;
2192              
2193             sub new {
2194             bless {};
2195             }
2196              
2197             package Example2;
2198              
2199             sub new {
2200             bless {};
2201             }
2202              
2203             package main;
2204              
2205             $assert = $assert->format('object', sub{ ref $_->value });
2206              
2207             # bless(..., "Venus::Assert")
2208              
2209             # ...
2210              
2211             # $assert->coerce(qr//);
2212              
2213             # qr//
2214              
2215             # $assert->coerce(Example1->new);
2216              
2217             # "Example1"
2218              
2219             # $assert->coerce(Example2->new);
2220              
2221             # "Example2"
2222              
2223             =back
2224              
2225             =over 4
2226              
2227             =item format example 4
2228              
2229             # given: synopsis
2230              
2231             package Example1;
2232              
2233             sub new {
2234             bless {};
2235             }
2236              
2237             package Example2;
2238              
2239             sub new {
2240             bless {};
2241             }
2242              
2243             package main;
2244              
2245             $assert = $assert->format('Example1', sub{ ref $_->value });
2246              
2247             # bless(..., "Venus::Assert")
2248              
2249             # ...
2250              
2251             # $assert->coerce(qr//);
2252              
2253             # qr//
2254              
2255             # $assert->coerce(Example1->new);
2256              
2257             # "Example1"
2258              
2259             # $assert->coerce(Example2->new);
2260              
2261             # bless({}, "Example2")
2262              
2263             =back
2264              
2265             =cut
2266              
2267             =head2 hash
2268              
2269             hash(CodeRef $check) (Assert)
2270              
2271             The hash method configures the object to accept hash references and returns
2272             the invocant.
2273              
2274             I>
2275              
2276             =over 4
2277              
2278             =item hash example 1
2279              
2280             # given: synopsis
2281              
2282             package main;
2283              
2284             $assert = $assert->hash;
2285              
2286             # $assert->check({});
2287              
2288             # true
2289              
2290             =back
2291              
2292             =cut
2293              
2294             =head2 hashkeys
2295              
2296             hashkeys(Str | ArrayRef[Str] @pairs) (Assert)
2297              
2298             The hashkeys method configures the object to accept hash based values
2299             containing the keys whose values' match the specified types, and returns the
2300             invocant.
2301              
2302             I>
2303              
2304             =over 4
2305              
2306             =item hashkeys example 1
2307              
2308             # given: synopsis
2309              
2310             package main;
2311              
2312             $assert = $assert->hashkeys;
2313              
2314             # $assert->check({});
2315              
2316             # false
2317              
2318             # $assert->check({random => rand});
2319              
2320             # true
2321              
2322             =back
2323              
2324             =over 4
2325              
2326             =item hashkeys example 2
2327              
2328             # given: synopsis
2329              
2330             package main;
2331              
2332             $assert = $assert->hashkeys(random => 'float');
2333              
2334             # $assert->check({});
2335              
2336             # false
2337              
2338             # $assert->check({random => rand});
2339              
2340             # true
2341              
2342             # $assert->check({random => time});
2343              
2344             # false
2345              
2346             =back
2347              
2348             =over 4
2349              
2350             =item hashkeys example 3
2351              
2352             # given: synopsis
2353              
2354             package main;
2355              
2356             $assert = $assert->hashkeys(random => ['either', 'float', 'number']);
2357              
2358             # $assert->check({});
2359              
2360             # false
2361              
2362             # $assert->check({random => rand});
2363              
2364             # true
2365              
2366             # $assert->check({random => time});
2367              
2368             # true
2369              
2370             # $assert->check({random => 'okay'});
2371              
2372             # false
2373              
2374             # $assert->check(bless{random => rand});
2375              
2376             # true
2377              
2378             # $assert->check(bless{random => time});
2379              
2380             # true
2381              
2382             # $assert->check(bless{random => 'okay'});
2383              
2384             # false
2385              
2386             =back
2387              
2388             =cut
2389              
2390             =head2 hashref
2391              
2392             hashref(CodeRef $check) (Assert)
2393              
2394             The hashref method configures the object to accept hash references and returns
2395             the invocant.
2396              
2397             I>
2398              
2399             =over 4
2400              
2401             =item hashref example 1
2402              
2403             # given: synopsis
2404              
2405             package main;
2406              
2407             $assert = $assert->hashref;
2408              
2409             # $assert->check({});
2410              
2411             # true
2412              
2413             =back
2414              
2415             =cut
2416              
2417             =head2 identity
2418              
2419             identity(Str $name) (Assert)
2420              
2421             The identity method configures the object to accept objects of the type
2422             specified as the argument, and returns the invocant.
2423              
2424             I>
2425              
2426             =over 4
2427              
2428             =item identity example 1
2429              
2430             # given: synopsis
2431              
2432             package main;
2433              
2434             $assert = $assert->identity('Venus::Assert');
2435              
2436             # $assert->check(Venus::Assert->new);
2437              
2438             # true
2439              
2440             =back
2441              
2442             =cut
2443              
2444             =head2 inherits
2445              
2446             inherits(Str $name) (Assert)
2447              
2448             The inherits method configures the object to accept objects of the type
2449             specified as the argument, and returns the invocant. This method is a proxy for
2450             the L method.
2451              
2452             I>
2453              
2454             =over 4
2455              
2456             =item inherits example 1
2457              
2458             # given: synopsis
2459              
2460             package main;
2461              
2462             $assert = $assert->inherits('Venus::Assert');
2463              
2464             # $assert->check(Venus::Assert->new);
2465              
2466             # true
2467              
2468             =back
2469              
2470             =cut
2471              
2472             =head2 integrates
2473              
2474             integrates(Str $name) (Assert)
2475              
2476             The integrates method configures the object to accept objects that support the
2477             C<"does"> behavior and consumes the "role" specified as the argument, and
2478             returns the invocant.
2479              
2480             I>
2481              
2482             =over 4
2483              
2484             =item integrates example 1
2485              
2486             # given: synopsis
2487              
2488             package main;
2489              
2490             $assert = $assert->integrates('Venus::Role::Doable');
2491              
2492             # $assert->check(Venus::Assert->new);
2493              
2494             # true
2495              
2496             =back
2497              
2498             =cut
2499              
2500             =head2 maybe
2501              
2502             maybe(Str $type, Any @args) (Assert)
2503              
2504             The maybe method configures the object to accept the type provided as an
2505             argument, or undef, and returns the invocant.
2506              
2507             I>
2508              
2509             =over 4
2510              
2511             =item maybe example 1
2512              
2513             # given: synopsis
2514              
2515             package main;
2516              
2517             $assert = $assert->maybe('code');
2518              
2519             # $assert->check(sub{});
2520              
2521             # true
2522              
2523             # $assert->check(undef);
2524              
2525             # true
2526              
2527             =back
2528              
2529             =cut
2530              
2531             =head2 number
2532              
2533             number(CodeRef $check) (Assert)
2534              
2535             The number method configures the object to accept numberic values and returns
2536             the invocant.
2537              
2538             I>
2539              
2540             =over 4
2541              
2542             =item number example 1
2543              
2544             # given: synopsis
2545              
2546             package main;
2547              
2548             $assert = $assert->number;
2549              
2550             # $assert->check(0);
2551              
2552             # true
2553              
2554             =back
2555              
2556             =cut
2557              
2558             =head2 object
2559              
2560             object(CodeRef $check) (Assert)
2561              
2562             The object method configures the object to accept objects and returns the
2563             invocant.
2564              
2565             I>
2566              
2567             =over 4
2568              
2569             =item object example 1
2570              
2571             # given: synopsis
2572              
2573             package main;
2574              
2575             $assert = $assert->object;
2576              
2577             # $assert->check(bless{});
2578              
2579             # true
2580              
2581             =back
2582              
2583             =cut
2584              
2585             =head2 package
2586              
2587             package() (Assert)
2588              
2589             The package method configures the object to accept package names (which are
2590             loaded) and returns the invocant.
2591              
2592             I>
2593              
2594             =over 4
2595              
2596             =item package example 1
2597              
2598             # given: synopsis
2599              
2600             package main;
2601              
2602             $assert = $assert->package;
2603              
2604             # $assert->check('Venus');
2605              
2606             # true
2607              
2608             =back
2609              
2610             =cut
2611              
2612             =head2 parse
2613              
2614             parse(Str $expr) (Any)
2615              
2616             The parse method accepts a string representation of a type assertion signature
2617             and returns a data structure representing one or more method calls to be used
2618             for validating the assertion signature.
2619              
2620             I>
2621              
2622             =over 4
2623              
2624             =item parse example 1
2625              
2626             # given: synopsis
2627              
2628             package main;
2629              
2630             my $parsed = $assert->parse('');
2631              
2632             # ['']
2633              
2634             =back
2635              
2636             =over 4
2637              
2638             =item parse example 2
2639              
2640             # given: synopsis
2641              
2642             package main;
2643              
2644             my $parsed = $assert->parse('any');
2645              
2646             # ['any']
2647              
2648             =back
2649              
2650             =over 4
2651              
2652             =item parse example 3
2653              
2654             # given: synopsis
2655              
2656             package main;
2657              
2658             my $parsed = $assert->parse('string | number');
2659              
2660             # ['either', 'string', 'number']
2661              
2662             =back
2663              
2664             =over 4
2665              
2666             =item parse example 4
2667              
2668             # given: synopsis
2669              
2670             package main;
2671              
2672             my $parsed = $assert->parse('enum[up,down,left,right]');
2673              
2674             # [['enum', 'up', 'down', 'left', 'right']]
2675              
2676             =back
2677              
2678             =over 4
2679              
2680             =item parse example 5
2681              
2682             # given: synopsis
2683              
2684             package main;
2685              
2686             my $parsed = $assert->parse('number | float | boolean');
2687              
2688             # ['either', 'number', 'float', 'boolean']
2689              
2690             =back
2691              
2692             =over 4
2693              
2694             =item parse example 6
2695              
2696             # given: synopsis
2697              
2698             package main;
2699              
2700             my $parsed = $assert->parse('Example');
2701              
2702             # ['Example']
2703              
2704             =back
2705              
2706             =over 4
2707              
2708             =item parse example 7
2709              
2710             # given: synopsis
2711              
2712             package main;
2713              
2714             my $parsed = $assert->parse('coderef | Venus::Code');
2715              
2716             # ['either', 'coderef', 'Venus::Code']
2717              
2718             =back
2719              
2720             =over 4
2721              
2722             =item parse example 8
2723              
2724             # given: synopsis
2725              
2726             package main;
2727              
2728             my $parsed = $assert->parse('tuple[number, arrayref, coderef]');
2729              
2730             # [['tuple', 'number', 'arrayref', 'coderef']]
2731              
2732             =back
2733              
2734             =over 4
2735              
2736             =item parse example 9
2737              
2738             # given: synopsis
2739              
2740             package main;
2741              
2742             my $parsed = $assert->parse('tuple[number, within[arrayref, hashref], coderef]');
2743              
2744             # [['tuple', 'number', ['within', 'arrayref', 'hashref'], 'coderef']]
2745              
2746             =back
2747              
2748             =over 4
2749              
2750             =item parse example 10
2751              
2752             # given: synopsis
2753              
2754             package main;
2755              
2756             my $parsed = $assert->parse(
2757             'tuple[number, within[arrayref, hashref] | arrayref, coderef]'
2758             );
2759              
2760             # [
2761             # ['tuple', 'number',
2762             # ['either', ['within', 'arrayref', 'hashref'], 'arrayref'], 'coderef']
2763             # ]
2764              
2765              
2766              
2767              
2768             =back
2769              
2770             =over 4
2771              
2772             =item parse example 11
2773              
2774             # given: synopsis
2775              
2776             package main;
2777              
2778             my $parsed = $assert->parse(
2779             'hashkeys["id", number | float, "upvotes", within[arrayref, boolean]]'
2780             );
2781              
2782             # [[
2783             # 'hashkeys',
2784             # 'id',
2785             # ['either', 'number', 'float'],
2786             # 'upvotes',
2787             # ['within', 'arrayref', 'boolean']
2788             # ]]
2789              
2790             =back
2791              
2792             =cut
2793              
2794             =head2 reference
2795              
2796             reference(CodeRef $check) (Assert)
2797              
2798             The reference method configures the object to accept references and returns the
2799             invocant.
2800              
2801             I>
2802              
2803             =over 4
2804              
2805             =item reference example 1
2806              
2807             # given: synopsis
2808              
2809             package main;
2810              
2811             $assert = $assert->reference;
2812              
2813             # $assert->check(sub{});
2814              
2815             # true
2816              
2817             =back
2818              
2819             =cut
2820              
2821             =head2 regexp
2822              
2823             regexp(CodeRef $check) (Assert)
2824              
2825             The regexp method configures the object to accept regular expression objects
2826             and returns the invocant.
2827              
2828             I>
2829              
2830             =over 4
2831              
2832             =item regexp example 1
2833              
2834             # given: synopsis
2835              
2836             package main;
2837              
2838             $assert = $assert->regexp;
2839              
2840             # $assert->check(qr//);
2841              
2842             # true
2843              
2844             =back
2845              
2846             =cut
2847              
2848             =head2 render
2849              
2850             render(Str $into, Str $expression) (Str)
2851              
2852             The render method builds and returns a type expressions suitable for providing
2853             to L based on the data provided.
2854              
2855             I>
2856              
2857             =over 4
2858              
2859             =item render example 1
2860              
2861             # given: synopsis
2862              
2863             package main;
2864              
2865             $assert = $assert->render;
2866              
2867             # undef
2868              
2869             =back
2870              
2871             =over 4
2872              
2873             =item render example 2
2874              
2875             # given: synopsis
2876              
2877             package main;
2878              
2879             $assert = $assert->render(undef, 'string');
2880              
2881             # "string"
2882              
2883             =back
2884              
2885             =over 4
2886              
2887             =item render example 3
2888              
2889             # given: synopsis
2890              
2891             package main;
2892              
2893             $assert = $assert->render('routines', ['say', 'say_pretty']);
2894              
2895             # 'routines["say", "say_pretty"]'
2896              
2897             =back
2898              
2899             =over 4
2900              
2901             =item render example 4
2902              
2903             # given: synopsis
2904              
2905             package main;
2906              
2907             $assert = $assert->render('hashkeys', {id => 'number', name => 'string'});
2908              
2909             # 'hashkeys["id", number, "name", string]'
2910              
2911             =back
2912              
2913             =over 4
2914              
2915             =item render example 5
2916              
2917             # given: synopsis
2918              
2919             package main;
2920              
2921             $assert = $assert->render('hashkeys', {
2922             id => 'number',
2923             profile => {
2924             level => 'string',
2925             },
2926             });
2927              
2928             # 'hashkeys["id", number, "profile", hashkeys["level", string]]'
2929              
2930             =back
2931              
2932             =cut
2933              
2934             =head2 routines
2935              
2936             routines(Str @names) (Assert)
2937              
2938             The routines method configures the object to accept an object having all of the
2939             routines provided, and returns the invocant.
2940              
2941             I>
2942              
2943             =over 4
2944              
2945             =item routines example 1
2946              
2947             # given: synopsis
2948              
2949             package main;
2950              
2951             $assert = $assert->routines('new', 'print', 'say');
2952              
2953             # $assert->check(Venus::Assert->new);
2954              
2955             # true
2956              
2957             =back
2958              
2959             =cut
2960              
2961             =head2 scalar
2962              
2963             scalar(CodeRef $check) (Assert)
2964              
2965             The scalar method configures the object to accept scalar references and returns
2966             the invocant.
2967              
2968             I>
2969              
2970             =over 4
2971              
2972             =item scalar example 1
2973              
2974             # given: synopsis
2975              
2976             package main;
2977              
2978             $assert = $assert->scalar;
2979              
2980             # $assert->check(\1);
2981              
2982             # true
2983              
2984             =back
2985              
2986             =cut
2987              
2988             =head2 scalarref
2989              
2990             scalarref(CodeRef $check) (Assert)
2991              
2992             The scalarref method configures the object to accept scalar references and returns
2993             the invocant.
2994              
2995             I>
2996              
2997             =over 4
2998              
2999             =item scalarref example 1
3000              
3001             # given: synopsis
3002              
3003             package main;
3004              
3005             $assert = $assert->scalarref;
3006              
3007             # $assert->check(\1);
3008              
3009             # true
3010              
3011             =back
3012              
3013             =cut
3014              
3015             =head2 string
3016              
3017             string(CodeRef $check) (Assert)
3018              
3019             The string method configures the object to accept string values and returns the
3020             invocant.
3021              
3022             I>
3023              
3024             =over 4
3025              
3026             =item string example 1
3027              
3028             # given: synopsis
3029              
3030             package main;
3031              
3032             $assert = $assert->string;
3033              
3034             # $assert->check('');
3035              
3036             # true
3037              
3038             =back
3039              
3040             =cut
3041              
3042             =head2 tuple
3043              
3044             tuple(Str | ArrayRef[Str] @types) (Assert)
3045              
3046             The tuple method configures the object to accept array references which conform
3047             to a tuple specification, and returns the invocant. The value being evaluated
3048             must contain at-least one element to match.
3049              
3050             I>
3051              
3052             =over 4
3053              
3054             =item tuple example 1
3055              
3056             # given: synopsis
3057              
3058             package main;
3059              
3060             $assert = $assert->tuple('number', ['maybe', 'array'], 'code');
3061              
3062             # $assert->check([200, [], sub{}]);
3063              
3064             # true
3065              
3066             =back
3067              
3068             =cut
3069              
3070             =head2 undef
3071              
3072             undef(CodeRef $check) (Assert)
3073              
3074             The undef method configures the object to accept undefined values and returns
3075             the invocant.
3076              
3077             I>
3078              
3079             =over 4
3080              
3081             =item undef example 1
3082              
3083             # given: synopsis
3084              
3085             package main;
3086              
3087             $assert = $assert->undef;
3088              
3089             # $assert->check(undef);
3090              
3091             # true
3092              
3093             =back
3094              
3095             =cut
3096              
3097             =head2 validate
3098              
3099             validate(Any $data) (Any)
3100              
3101             The validate method returns the data provided if the data provided passes the
3102             registered constraints, or throws an exception.
3103              
3104             I>
3105              
3106             =over 4
3107              
3108             =item validate example 1
3109              
3110             # given: synopsis
3111              
3112             package main;
3113              
3114             $assert->constraint(float => sub { $_->value > 1 });
3115              
3116             my $result = $assert->validate;
3117              
3118             # Exception! (isa Venus::Assert::Error) (see error_on_validate)
3119              
3120             =back
3121              
3122             =over 4
3123              
3124             =item validate example 2
3125              
3126             # given: synopsis
3127              
3128             package main;
3129              
3130             $assert->constraint(float => sub { $_->value > 1 });
3131              
3132             my $result = $assert->validate('0.01');
3133              
3134             # Exception! (isa Venus::Assert::Error) (see error_on_validate)
3135              
3136             =back
3137              
3138             =over 4
3139              
3140             =item validate example 3
3141              
3142             # given: synopsis
3143              
3144             package main;
3145              
3146             $assert->constraint(float => sub { $_->value > 1 });
3147              
3148             my $result = $assert->validate('1.01');
3149              
3150             # "1.01"
3151              
3152             =back
3153              
3154             =over 4
3155              
3156             =item validate example 4
3157              
3158             # given: synopsis
3159              
3160             package main;
3161              
3162             $assert->constraint(float => sub { $_->value > 1 });
3163              
3164             my $result = $assert->validate(time);
3165              
3166             # Exception! (isa Venus::Assert::Error) (see error_on_validate)
3167              
3168             =back
3169              
3170             =cut
3171              
3172             =head2 validator
3173              
3174             validator(Str $expr) (CodeRef)
3175              
3176             The validator method returns a coderef that can be used as a value validator,
3177             which returns the data provided if the data provided passes the registered
3178             constraints, or throws an exception.
3179              
3180             I>
3181              
3182             =over 4
3183              
3184             =item validator example 1
3185              
3186             # given: synopsis
3187              
3188             package main;
3189              
3190             my $validator = $assert->validator('string');
3191              
3192             # sub { ... }
3193              
3194             # $validator->('hello');
3195              
3196             # "hello"
3197              
3198             # $validator->(['goodbye']);
3199              
3200             # Exception! (isa Venus::Error) (see error_on_validate)
3201              
3202             =back
3203              
3204             =cut
3205              
3206             =head2 value
3207              
3208             value(CodeRef $check) (Assert)
3209              
3210             The value method configures the object to accept defined, non-reference,
3211             values, and returns the invocant.
3212              
3213             I>
3214              
3215             =over 4
3216              
3217             =item value example 1
3218              
3219             # given: synopsis
3220              
3221             package main;
3222              
3223             $assert = $assert->value;
3224              
3225             # $assert->check(1_000_000);
3226              
3227             # true
3228              
3229             =back
3230              
3231             =cut
3232              
3233             =head2 within
3234              
3235             within(Str $type) (Assert)
3236              
3237             The within method configures the object, registering a constraint action as a
3238             sub-match operation, to accept array or hash based values, and returns a
3239             L instance for the sub-match operation (not the invocant). This
3240             operation can traverse blessed array or hash based values. The value being
3241             evaluated must contain at-least one element to match.
3242              
3243             I>
3244              
3245             =over 4
3246              
3247             =item within example 1
3248              
3249             # given: synopsis
3250              
3251             package main;
3252              
3253             my $within = $assert->within('array')->code;
3254              
3255             my $action = $assert;
3256              
3257             # $assert->check([]);
3258              
3259             # false
3260              
3261             # $assert->check([sub{}]);
3262              
3263             # true
3264              
3265             # $assert->check([{}]);
3266              
3267             # false
3268              
3269             # $assert->check(bless[]);
3270              
3271             # false
3272              
3273             # $assert->check(bless[sub{}]);
3274              
3275             # true
3276              
3277             =back
3278              
3279             =over 4
3280              
3281             =item within example 2
3282              
3283             # given: synopsis
3284              
3285             package main;
3286              
3287             my $within = $assert->within('hash')->code;
3288              
3289             my $action = $assert;
3290              
3291             # $assert->check({});
3292              
3293             # false
3294              
3295             # $assert->check({test => sub{}});
3296              
3297             # true
3298              
3299             # $assert->check({test => {}});
3300              
3301             # false
3302              
3303             # $assert->check({test => bless{}});
3304              
3305             # false
3306              
3307             # $assert->check({test => bless sub{}});
3308              
3309             # false
3310              
3311             =back
3312              
3313             =over 4
3314              
3315             =item within example 3
3316              
3317             # given: synopsis
3318              
3319             package main;
3320              
3321             my $within = $assert->within('hashref', 'code');
3322              
3323             my $action = $assert;
3324              
3325             # $assert->check({});
3326              
3327             # false
3328              
3329             # $assert->check({test => sub{}});
3330              
3331             # true
3332              
3333             # $assert->check({test => {}});
3334              
3335             # false
3336              
3337             # $assert->check({test => bless{}});
3338              
3339             # false
3340              
3341             # $assert->check({test => bless sub{}});
3342              
3343             # false
3344              
3345             =back
3346              
3347             =cut
3348              
3349             =head2 yesno
3350              
3351             yesno(CodeRef $check) (Assert)
3352              
3353             The yesno method configures the object to accept a string value that's either
3354             C<"yes"> or C<1>, C<"no"> or C<0>, and returns the invocant.
3355              
3356             I>
3357              
3358             =over 4
3359              
3360             =item yesno example 1
3361              
3362             # given: synopsis
3363              
3364             package main;
3365              
3366             $assert = $assert->yesno;
3367              
3368             # $assert->check(undef);
3369              
3370             # false
3371              
3372             # $assert->check(0);
3373              
3374             # true
3375              
3376             # $assert->check('No');
3377              
3378             # true
3379              
3380             # $assert->check('n');
3381              
3382             # true
3383              
3384             # $assert->check(1);
3385              
3386             # true
3387              
3388             # $assert->check('Yes');
3389              
3390             # true
3391              
3392             # $assert->check('y');
3393              
3394             # true
3395              
3396             # $assert->check('Okay');
3397              
3398             # false
3399              
3400             =back
3401              
3402             =cut
3403              
3404             =head1 ERRORS
3405              
3406             This package may raise the following errors:
3407              
3408             =cut
3409              
3410             =over 4
3411              
3412             =item error: C
3413              
3414             This package may raise an error_on_validate exception.
3415              
3416             B
3417              
3418             # given: synopsis;
3419              
3420             my @args = ("...");
3421              
3422             my $error = $assert->throw('error_on_validate', @args)->catch('error');
3423              
3424             # my $name = $error->name;
3425              
3426             # "on_validate"
3427              
3428             # my $message = $error->message;
3429              
3430             # "..."
3431              
3432             # my $identity = $error->stash('identity');
3433              
3434             # "string"
3435              
3436             =back
3437              
3438             =over 4
3439              
3440             =item error: C
3441              
3442             This package may raise an error_on_within exception.
3443              
3444             B
3445              
3446             # given: synopsis;
3447              
3448             my @args = ('coderef', 'string');
3449              
3450             my $error = $assert->throw('error_on_within', @args)->catch('error');
3451              
3452             # my $ = $error->name;
3453              
3454             # "on_within"
3455              
3456             # my $message = $error->message;
3457              
3458             # "Invalid type (\"$type\") palid ed to the \"within\" method"
3459              
3460             # my $self = $error->stash('self');
3461              
3462             # $assert
3463              
3464             # my $type = $error->stash('type'
3465              
3466             # "coderef"
3467              
3468             # my $args = $error->stash('args');
3469              
3470             # ["string"]
3471              
3472             =back
3473              
3474             =head1 AUTHORS
3475              
3476             Awncorp, C
3477              
3478             =cut
3479              
3480             =head1 LICENSE
3481              
3482             Copyright (C) 2000, Al Newkirk.
3483              
3484             This program is free software, you can redistribute it and/or modify it under
3485             the terms of the Apache license version 2.0.
3486              
3487             =cut