File Coverage

blib/lib/Test/Specio.pm
Criterion Covered Total %
statement 147 156 94.2
branch 35 36 97.2
condition 10 10 100.0
subroutine 43 48 89.5
pod 4 4 100.0
total 239 254 94.0


line stmt bran cond sub pod time code
1             package Test::Specio;
2              
3 11     11   1222837 use strict;
  11         21  
  11         455  
4 11     11   111 use warnings;
  11         26  
  11         851  
5              
6             our $VERSION = '0.53';
7              
8 11     11   5765 use IO::File;
  11         113860  
  11         1511  
9 11     11   96 use Scalar::Util qw( blessed looks_like_number openhandle );
  11         22  
  11         678  
10 11     11   6380 use Specio::Library::Builtins;
  11         82  
  11         164  
11 11     11   6583 use Specio::Library::Numeric;
  11         50  
  11         175  
12 11     11   7129 use Specio::Library::Perl;
  11         49  
  11         201  
13 11     11   70 use Specio::Library::String;
  11         24  
  11         95  
14              
15             # Loading this will force subification to use Sub::Quote, which can expose
16             # some bugs.
17 11     11   7226 use Sub::Quote;
  11         83107  
  11         840  
18 11     11   1874 use Test::Fatal;
  11         3662  
  11         629  
19 11     11   68 use Test::More 0.96;
  11         226  
  11         106  
20 11     11   3918 use Try::Tiny;
  11         24  
  11         642  
21              
22 11     11   64 use Exporter qw( import );
  11         20  
  11         4937  
23              
24             our $ZERO = 0;
25             our $ONE = 1;
26             our $INT = 100;
27             our $NEG_INT = -100;
28             our $NUM = 42.42;
29             our $NEG_NUM = -42.42;
30              
31             our $EMPTY_STRING = q{};
32             our $STRING = 'foo';
33             our $NUM_IN_STRING = 'has 42 in it';
34             our $INT_WITH_NL1 = "1\n";
35             our $INT_WITH_NL2 = "\n1";
36              
37             our $SCALAR_REF = do {
38             ## no critic (Variables::ProhibitUnusedVariables)
39             \( my $var );
40             };
41             our $SCALAR_REF_REF = \$SCALAR_REF;
42             our $ARRAY_REF = [];
43             our $HASH_REF = {};
44             our $CODE_REF = sub { };
45              
46             our $GLOB_REF = \*GLOB;
47              
48             our $FH;
49             ## no critic (InputOutput::RequireBriefOpen)
50             open $FH, '<', $INC{'Test/Specio.pm'}
51             or die "Could not open $INC{'Test/Specio.pm'} for the test";
52              
53             our $FH_OBJECT = IO::File->new( $INC{'Test/Specio.pm'}, 'r' )
54             or die "Could not open $INC{'Test/Specio.pm'} for the test";
55              
56             our $REGEX = qr/../;
57             our $REGEX_OBJ = bless qr/../, 'BlessedQR';
58             our $FAKE_REGEX = bless {}, 'Regexp';
59              
60             our $OBJECT = bless {}, 'FakeObject';
61              
62             our $UNDEF = undef;
63              
64             ## no critic (Modules::ProhibitMultiplePackages)
65             {
66             package _T::Thing;
67              
68       0     sub foo { }
69             }
70              
71             our $CLASS_NAME = '_T::Thing';
72              
73             {
74             package _T::BoolOverload;
75              
76             use overload
77 388     388   586 'bool' => sub { ${ $_[0] } },
  388         1409  
78 11     11   79 fallback => 0;
  11         31  
  11         127  
79              
80             sub new {
81 22     22   36 my $bool = $_[1];
82 22         47 bless \$bool, __PACKAGE__;
83             }
84             }
85              
86             our $BOOL_OVERLOAD_TRUE = _T::BoolOverload->new(1);
87             our $BOOL_OVERLOAD_FALSE = _T::BoolOverload->new(0);
88              
89             {
90             package _T::StrOverload;
91              
92             use overload
93 305     305   9501 q{""} => sub { ${ $_[0] } },
  305         2034  
94 11     11   2378 fallback => 0;
  11         19  
  11         89  
95              
96             sub new {
97 33     33   74 my $str = $_[1];
98 33         91 bless \$str, __PACKAGE__;
99             }
100             }
101              
102             our $STR_OVERLOAD_EMPTY = _T::StrOverload->new(q{});
103             our $STR_OVERLOAD_FULL = _T::StrOverload->new('full');
104             our $STR_OVERLOAD_CLASS_NAME = _T::StrOverload->new('_T::StrOverload');
105              
106             {
107             package _T::NumOverload;
108              
109             use overload
110 0     0   0 '0+' => sub { ${ $_[0] } },
  0         0  
111 100     100   14190 '+' => sub { ${ $_[0] } + $_[1] },
  100         1247  
112 11     11   2383 fallback => 0;
  11         20  
  11         141  
113              
114             sub new {
115 55     55   87 my $num = $_[1];
116 55         137 bless \$num, __PACKAGE__;
117             }
118             }
119              
120             our $NUM_OVERLOAD_ZERO = _T::NumOverload->new( 0);
121             our $NUM_OVERLOAD_ONE = _T::NumOverload->new( 1);
122             our $NUM_OVERLOAD_NEG = _T::NumOverload->new(-42);
123             our $NUM_OVERLOAD_DECIMAL = _T::NumOverload->new(42.42);
124             our $NUM_OVERLOAD_NEG_DECIMAL = _T::NumOverload->new(42.42);
125              
126             {
127             package _T::CodeOverload;
128              
129             use overload
130 0     0   0 '&{}' => sub { ${ $_[0] } },
  0         0  
131 11     11   2565 fallback => 0;
  11         36  
  11         93  
132              
133             sub new {
134 11     11   19 my $code = $_[1];
135 11         29 bless \$code, __PACKAGE__;
136             }
137             }
138              
139             our $CODE_OVERLOAD = _T::CodeOverload->new( sub { } );
140              
141             {
142             package _T::RegexOverload;
143              
144             use overload
145 0     0   0 'qr' => sub { ${ $_[0] } },
  0         0  
146 11     11   2044 fallback => 0;
  11         23  
  11         58  
147              
148             sub new {
149 11     11   19 my $regex = $_[1];
150 11         38 bless \$regex, __PACKAGE__;
151             }
152             }
153              
154             our $REGEX_OVERLOAD = _T::RegexOverload->new(qr/foo/);
155              
156             {
157             package _T::GlobOverload;
158              
159             use overload
160 11     11   1820 '*{}' => sub { ${ $_[0] } },
  11         94  
161 11     11   2132 fallback => 0;
  11         23  
  11         91  
162              
163             sub new {
164 18     18   4001986 my $glob = $_[1];
165 18         71 bless \$glob, __PACKAGE__;
166             }
167             }
168              
169             {
170             package _T::ScalarOverload;
171              
172             use overload
173 0     0   0 '${}' => sub { $_[0][0] },
174 11     11   1842 fallback => 0;
  11         24  
  11         67  
175              
176             sub new {
177 11     11   30 my $scalar = $_[1];
178 11         59 bless [$scalar], __PACKAGE__;
179             }
180             }
181              
182             our $SCALAR_OVERLOAD = _T::ScalarOverload->new('x');
183              
184             {
185             package _T::ArrayOverload;
186              
187             use overload
188 66     66   2281 '@{}' => sub { $_[0]{array} },
189 11     11   1952 fallback => 0;
  11         22  
  11         64  
190              
191             sub new {
192 11     11   19 my $array = $_[1];
193 11         62 bless { array => $array }, __PACKAGE__;
194             }
195             }
196              
197             our $ARRAY_OVERLOAD = _T::ArrayOverload->new( [ 1, 2, 3 ] );
198              
199             {
200             package _T::HashOverload;
201              
202             use overload
203 227     227   4452 '%{}' => sub { $_[0][0] },
204 11     11   1908 fallback => 0;
  11         17  
  11         85  
205              
206             sub new {
207 21     21   34 my $hash = $_[1];
208              
209             # We use an array-based object so we make sure we test hash
210             # overloading as opposed to just treating the object as a hash.
211 21         148 bless [$hash], __PACKAGE__;
212             }
213             }
214              
215             our $HASH_OVERLOAD = _T::HashOverload->new( { x => 42, y => 84 } );
216              
217             my @vars;
218              
219             BEGIN {
220 11 50   11   3545 open my $fh, '<', $INC{'Test/Specio.pm'} or die $!;
221 11         392 while (<$fh>) {
222 17424 100       78437 push @vars, $1 if /^our (\$[A-Z0-9_]+)(?: +=|;)/;
223             }
224             }
225              
226             our @EXPORT_OK = (
227             @vars,
228             qw( builtins_tests create_BAR_handle_code describe test_constraint )
229             );
230             our %EXPORT_TAGS = ( vars => \@vars );
231              
232             sub create_BAR_handle_code {
233              
234             # This used to be $^X, but that caused a test failure for someone
235             # (https://github.com/houseabsolute/Specio/issues/25). Then I tried __FILE__, but that doesn't work
236             # in cases where the file containing __FILE__ is eval'd, which we do in
237             # `xt/author/no-ref-util.t`. So now I'm just grabbing the first file in %INC.
238 9     9 1 1236 return <<'EOF';
239             my $file = $INC{ ( keys %INC )[0] };
240             open BAR, '<', $file or die "Could not open $file for the test";
241             EOF
242             }
243              
244             sub builtins_tests {
245 2     2 1 19 my $GLOB = shift;
246 2         6 my $GLOB_OVERLOAD = shift;
247 2         5 my $GLOB_OVERLOAD_FH = shift;
248              
249             return {
250 2         317 Item => {
251             accept => [
252             $ZERO,
253             $ONE,
254             $BOOL_OVERLOAD_TRUE,
255             $BOOL_OVERLOAD_FALSE,
256             $INT,
257             $NEG_INT,
258             $NUM,
259             $NEG_NUM,
260             $NUM_OVERLOAD_ZERO,
261             $NUM_OVERLOAD_ONE,
262             $NUM_OVERLOAD_NEG,
263             $NUM_OVERLOAD_NEG_DECIMAL,
264             $NUM_OVERLOAD_DECIMAL,
265             $EMPTY_STRING,
266             $STRING,
267             $NUM_IN_STRING,
268             $STR_OVERLOAD_EMPTY,
269             $STR_OVERLOAD_FULL,
270             $INT_WITH_NL1,
271             $INT_WITH_NL2,
272             $SCALAR_REF,
273             $SCALAR_REF_REF,
274             $SCALAR_OVERLOAD,
275             $ARRAY_REF,
276             $ARRAY_OVERLOAD,
277             $HASH_REF,
278             $HASH_OVERLOAD,
279             $CODE_REF,
280             $CODE_OVERLOAD,
281             $GLOB,
282             $GLOB_REF,
283             $GLOB_OVERLOAD,
284             $GLOB_OVERLOAD_FH,
285             $FH,
286             $FH_OBJECT,
287             $REGEX,
288             $REGEX_OBJ,
289             $REGEX_OVERLOAD,
290             $FAKE_REGEX,
291             $OBJECT,
292             $UNDEF,
293             ],
294             },
295             Defined => {
296             accept => [
297             $ZERO,
298             $ONE,
299             $BOOL_OVERLOAD_TRUE,
300             $BOOL_OVERLOAD_FALSE,
301             $INT,
302             $NEG_INT,
303             $NUM,
304             $NEG_NUM,
305             $NUM_OVERLOAD_ZERO,
306             $NUM_OVERLOAD_ONE,
307             $NUM_OVERLOAD_NEG,
308             $NUM_OVERLOAD_NEG_DECIMAL,
309             $NUM_OVERLOAD_DECIMAL,
310             $EMPTY_STRING,
311             $STRING,
312             $NUM_IN_STRING,
313             $STR_OVERLOAD_EMPTY,
314             $STR_OVERLOAD_FULL,
315             $INT_WITH_NL1,
316             $INT_WITH_NL2,
317             $SCALAR_REF,
318             $SCALAR_REF_REF,
319             $SCALAR_OVERLOAD,
320             $ARRAY_REF,
321             $ARRAY_OVERLOAD,
322             $HASH_REF,
323             $HASH_OVERLOAD,
324             $CODE_REF,
325             $CODE_OVERLOAD,
326             $GLOB,
327             $GLOB_REF,
328             $GLOB_OVERLOAD,
329             $GLOB_OVERLOAD_FH,
330             $FH,
331             $FH_OBJECT,
332             $REGEX,
333             $REGEX_OBJ,
334             $REGEX_OVERLOAD,
335             $FAKE_REGEX,
336             $OBJECT,
337             ],
338             reject => [
339             $UNDEF,
340             ],
341             },
342             Undef => {
343             accept => [
344             $UNDEF,
345             ],
346             reject => [
347             $ZERO,
348             $ONE,
349             $BOOL_OVERLOAD_TRUE,
350             $BOOL_OVERLOAD_FALSE,
351             $INT,
352             $NEG_INT,
353             $NUM,
354             $NEG_NUM,
355             $NUM_OVERLOAD_ZERO,
356             $NUM_OVERLOAD_ONE,
357             $NUM_OVERLOAD_NEG,
358             $NUM_OVERLOAD_NEG_DECIMAL,
359             $NUM_OVERLOAD_DECIMAL,
360             $EMPTY_STRING,
361             $STRING,
362             $NUM_IN_STRING,
363             $STR_OVERLOAD_EMPTY,
364             $STR_OVERLOAD_FULL,
365             $INT_WITH_NL1,
366             $INT_WITH_NL2,
367             $SCALAR_REF,
368             $SCALAR_REF_REF,
369             $SCALAR_OVERLOAD,
370             $ARRAY_REF,
371             $ARRAY_OVERLOAD,
372             $HASH_REF,
373             $HASH_OVERLOAD,
374             $CODE_REF,
375             $CODE_OVERLOAD,
376             $GLOB,
377             $GLOB_REF,
378             $GLOB_OVERLOAD,
379             $GLOB_OVERLOAD_FH,
380             $FH,
381             $FH_OBJECT,
382             $REGEX,
383             $REGEX_OBJ,
384             $REGEX_OVERLOAD,
385             $FAKE_REGEX,
386             $OBJECT,
387             ],
388             },
389             Bool => {
390             accept => [
391             $ZERO,
392             $ONE,
393             $BOOL_OVERLOAD_TRUE,
394             $BOOL_OVERLOAD_FALSE,
395             $EMPTY_STRING,
396             $UNDEF,
397             ],
398             reject => [
399             $INT,
400             $NEG_INT,
401             $NUM,
402             $NEG_NUM,
403             $NUM_OVERLOAD_ZERO,
404             $NUM_OVERLOAD_ONE,
405             $NUM_OVERLOAD_NEG,
406             $NUM_OVERLOAD_NEG_DECIMAL,
407             $NUM_OVERLOAD_DECIMAL,
408             $STRING,
409             $NUM_IN_STRING,
410             $STR_OVERLOAD_EMPTY,
411             $STR_OVERLOAD_FULL,
412             $INT_WITH_NL1,
413             $INT_WITH_NL2,
414             $SCALAR_REF,
415             $SCALAR_REF_REF,
416             $SCALAR_OVERLOAD,
417             $ARRAY_REF,
418             $ARRAY_OVERLOAD,
419             $HASH_REF,
420             $HASH_OVERLOAD,
421             $CODE_REF,
422             $CODE_OVERLOAD,
423             $GLOB,
424             $GLOB_REF,
425             $GLOB_OVERLOAD,
426             $GLOB_OVERLOAD_FH,
427             $FH,
428             $FH_OBJECT,
429             $REGEX,
430             $REGEX_OBJ,
431             $REGEX_OVERLOAD,
432             $FAKE_REGEX,
433             $OBJECT,
434             ],
435             },
436             Maybe => {
437             accept => [
438             $ZERO,
439             $ONE,
440             $BOOL_OVERLOAD_TRUE,
441             $BOOL_OVERLOAD_FALSE,
442             $INT,
443             $NEG_INT,
444             $NUM,
445             $NEG_NUM,
446             $NUM_OVERLOAD_ZERO,
447             $NUM_OVERLOAD_ONE,
448             $NUM_OVERLOAD_NEG,
449             $NUM_OVERLOAD_NEG_DECIMAL,
450             $NUM_OVERLOAD_DECIMAL,
451             $EMPTY_STRING,
452             $STRING,
453             $NUM_IN_STRING,
454             $STR_OVERLOAD_EMPTY,
455             $STR_OVERLOAD_FULL,
456             $INT_WITH_NL1,
457             $INT_WITH_NL2,
458             $SCALAR_REF,
459             $SCALAR_REF_REF,
460             $SCALAR_OVERLOAD,
461             $ARRAY_REF,
462             $ARRAY_OVERLOAD,
463             $HASH_REF,
464             $HASH_OVERLOAD,
465             $CODE_REF,
466             $CODE_OVERLOAD,
467             $GLOB,
468             $GLOB_REF,
469             $GLOB_OVERLOAD,
470             $GLOB_OVERLOAD_FH,
471             $FH,
472             $FH_OBJECT,
473             $REGEX,
474             $REGEX_OBJ,
475             $REGEX_OVERLOAD,
476             $FAKE_REGEX,
477             $OBJECT,
478             $UNDEF,
479             ],
480             },
481             Value => {
482             accept => [
483             $ZERO,
484             $ONE,
485             $INT,
486             $NEG_INT,
487             $NUM,
488             $NEG_NUM,
489             $EMPTY_STRING,
490             $STRING,
491             $NUM_IN_STRING,
492             $INT_WITH_NL1,
493             $INT_WITH_NL2,
494             $GLOB,
495             ],
496             reject => [
497             $BOOL_OVERLOAD_TRUE,
498             $BOOL_OVERLOAD_FALSE,
499             $STR_OVERLOAD_EMPTY,
500             $STR_OVERLOAD_FULL,
501             $NUM_OVERLOAD_ZERO,
502             $NUM_OVERLOAD_ONE,
503             $NUM_OVERLOAD_NEG,
504             $NUM_OVERLOAD_NEG_DECIMAL,
505             $NUM_OVERLOAD_DECIMAL,
506             $SCALAR_REF,
507             $SCALAR_REF_REF,
508             $SCALAR_OVERLOAD,
509             $ARRAY_REF,
510             $ARRAY_OVERLOAD,
511             $HASH_REF,
512             $HASH_OVERLOAD,
513             $CODE_REF,
514             $CODE_OVERLOAD,
515             $GLOB_REF,
516             $GLOB_OVERLOAD,
517             $GLOB_OVERLOAD_FH,
518             $FH,
519             $FH_OBJECT,
520             $REGEX,
521             $REGEX_OBJ,
522             $REGEX_OVERLOAD,
523             $FAKE_REGEX,
524             $OBJECT,
525             $UNDEF,
526             ],
527             },
528             Ref => {
529             accept => [
530             $BOOL_OVERLOAD_TRUE,
531             $BOOL_OVERLOAD_FALSE,
532             $STR_OVERLOAD_EMPTY,
533             $STR_OVERLOAD_FULL,
534             $NUM_OVERLOAD_ZERO,
535             $NUM_OVERLOAD_ONE,
536             $NUM_OVERLOAD_NEG,
537             $NUM_OVERLOAD_NEG_DECIMAL,
538             $NUM_OVERLOAD_DECIMAL,
539             $SCALAR_REF,
540             $SCALAR_REF_REF,
541             $SCALAR_OVERLOAD,
542             $ARRAY_REF,
543             $ARRAY_OVERLOAD,
544             $HASH_REF,
545             $HASH_OVERLOAD,
546             $CODE_REF,
547             $CODE_OVERLOAD,
548             $GLOB_REF,
549             $GLOB_OVERLOAD,
550             $GLOB_OVERLOAD_FH,
551             $FH,
552             $FH_OBJECT,
553             $REGEX,
554             $REGEX_OBJ,
555             $REGEX_OVERLOAD,
556             $FAKE_REGEX,
557             $OBJECT,
558             ],
559             reject => [
560             $ZERO,
561             $ONE,
562             $INT,
563             $NEG_INT,
564             $NUM,
565             $NEG_NUM,
566             $EMPTY_STRING,
567             $STRING,
568             $NUM_IN_STRING,
569             $INT_WITH_NL1,
570             $INT_WITH_NL2,
571             $GLOB,
572             $UNDEF,
573             ],
574             },
575             Num => {
576             accept => [
577             $ZERO,
578             $ONE,
579             $INT,
580             $NEG_INT,
581             $NUM,
582             $NEG_NUM,
583             $NUM_OVERLOAD_ZERO,
584             $NUM_OVERLOAD_ONE,
585             $NUM_OVERLOAD_NEG,
586             $NUM_OVERLOAD_NEG_DECIMAL,
587             $NUM_OVERLOAD_DECIMAL,
588             qw(
589             1e10
590             1e-10
591             1.23456e10
592             1.23456e-10
593             1e10
594             1e-10
595             1.23456e10
596             1.23456e-10
597             -1e10
598             -1e-10
599             -1.23456e10
600             -1.23456e-10
601             -1e10
602             -1e-10
603             -1.23456e10
604             -1.23456e-10
605             -1e+10
606             1E10
607             ),
608             ],
609             reject => [
610             $BOOL_OVERLOAD_TRUE,
611             $BOOL_OVERLOAD_FALSE,
612             $EMPTY_STRING,
613             $STRING,
614             $NUM_IN_STRING,
615             $STR_OVERLOAD_EMPTY,
616             $STR_OVERLOAD_FULL,
617             $SCALAR_REF,
618             $SCALAR_REF_REF,
619             $SCALAR_OVERLOAD,
620             $ARRAY_REF,
621             $ARRAY_OVERLOAD,
622             $HASH_REF,
623             $HASH_OVERLOAD,
624             $CODE_REF,
625             $CODE_OVERLOAD,
626             $GLOB,
627             $GLOB_REF,
628             $GLOB_OVERLOAD,
629             $GLOB_OVERLOAD_FH,
630             $FH,
631             $FH_OBJECT,
632             $INT_WITH_NL1,
633             $INT_WITH_NL2,
634             $REGEX,
635             $REGEX_OBJ,
636             $REGEX_OVERLOAD,
637             $FAKE_REGEX,
638             $OBJECT,
639             $UNDEF,
640             ],
641             },
642             Int => {
643             accept => [
644             $ZERO,
645             $ONE,
646             $INT,
647             $NEG_INT,
648             $NUM_OVERLOAD_ZERO,
649             $NUM_OVERLOAD_ONE,
650             $NUM_OVERLOAD_NEG,
651             qw(
652             1e20
653             1e100
654             -1e10
655             -1e+10
656             1E20
657             ),
658             ],
659             reject => [
660             $BOOL_OVERLOAD_TRUE,
661             $BOOL_OVERLOAD_FALSE,
662             $NUM,
663             $NEG_NUM,
664             $NUM_OVERLOAD_NEG_DECIMAL,
665             $NUM_OVERLOAD_DECIMAL,
666             $EMPTY_STRING,
667             $STRING,
668             $NUM_IN_STRING,
669             $STR_OVERLOAD_EMPTY,
670             $STR_OVERLOAD_FULL,
671             $INT_WITH_NL1,
672             $INT_WITH_NL2,
673             $SCALAR_REF,
674             $SCALAR_REF_REF,
675             $SCALAR_OVERLOAD,
676             $ARRAY_REF,
677             $ARRAY_OVERLOAD,
678             $HASH_REF,
679             $HASH_OVERLOAD,
680             $CODE_REF,
681             $CODE_OVERLOAD,
682             $GLOB,
683             $GLOB_REF,
684             $GLOB_OVERLOAD,
685             $GLOB_OVERLOAD_FH,
686             $FH,
687             $FH_OBJECT,
688             $REGEX,
689             $REGEX_OBJ,
690             $REGEX_OVERLOAD,
691             $FAKE_REGEX,
692             $OBJECT,
693             $UNDEF,
694             qw(
695             1e-10
696             -1e-10
697             1.23456e10
698             1.23456e-10
699             -1.23456e10
700             -1.23456e-10
701             -1.23456e+10
702             ),
703             ],
704             },
705             Str => {
706             accept => [
707             $ZERO,
708             $ONE,
709             $INT,
710             $NEG_INT,
711             $NUM,
712             $NEG_NUM,
713             $EMPTY_STRING,
714             $STRING,
715             $NUM_IN_STRING,
716             $STR_OVERLOAD_EMPTY,
717             $STR_OVERLOAD_FULL,
718             $INT_WITH_NL1,
719             $INT_WITH_NL2,
720             ],
721             reject => [
722             $BOOL_OVERLOAD_TRUE,
723             $BOOL_OVERLOAD_FALSE,
724             $NUM_OVERLOAD_ZERO,
725             $NUM_OVERLOAD_ONE,
726             $NUM_OVERLOAD_NEG,
727             $NUM_OVERLOAD_NEG_DECIMAL,
728             $NUM_OVERLOAD_DECIMAL,
729             $SCALAR_REF,
730             $SCALAR_REF_REF,
731             $SCALAR_OVERLOAD,
732             $ARRAY_REF,
733             $ARRAY_OVERLOAD,
734             $HASH_REF,
735             $HASH_OVERLOAD,
736             $CODE_REF,
737             $CODE_OVERLOAD,
738             $GLOB,
739             $GLOB_REF,
740             $GLOB_OVERLOAD,
741             $GLOB_OVERLOAD_FH,
742             $FH,
743             $FH_OBJECT,
744             $REGEX,
745             $REGEX_OBJ,
746             $REGEX_OVERLOAD,
747             $FAKE_REGEX,
748             $OBJECT,
749             $UNDEF,
750             ],
751             },
752             ScalarRef => {
753             accept => [
754             $SCALAR_REF,
755             $SCALAR_REF_REF,
756             $SCALAR_OVERLOAD,
757             ],
758             reject => [
759             $ZERO,
760             $ONE,
761             $BOOL_OVERLOAD_TRUE,
762             $BOOL_OVERLOAD_FALSE,
763             $INT,
764             $NEG_INT,
765             $NUM,
766             $NEG_NUM,
767             $NUM_OVERLOAD_ZERO,
768             $NUM_OVERLOAD_ONE,
769             $NUM_OVERLOAD_NEG,
770             $NUM_OVERLOAD_NEG_DECIMAL,
771             $NUM_OVERLOAD_DECIMAL,
772             $EMPTY_STRING,
773             $STRING,
774             $NUM_IN_STRING,
775             $STR_OVERLOAD_EMPTY,
776             $STR_OVERLOAD_FULL,
777             $INT_WITH_NL1,
778             $INT_WITH_NL2,
779             $ARRAY_REF,
780             $ARRAY_OVERLOAD,
781             $HASH_REF,
782             $HASH_OVERLOAD,
783             $CODE_REF,
784             $CODE_OVERLOAD,
785             $GLOB,
786             $GLOB_REF,
787             $GLOB_OVERLOAD,
788             $GLOB_OVERLOAD_FH,
789             $FH,
790             $FH_OBJECT,
791             $REGEX,
792             $REGEX_OBJ,
793             $REGEX_OVERLOAD,
794             $FAKE_REGEX,
795             $OBJECT,
796             $UNDEF,
797             ],
798             },
799             ArrayRef => {
800             accept => [
801             $ARRAY_REF,
802             $ARRAY_OVERLOAD,
803             ],
804             reject => [
805             $ZERO,
806             $ONE,
807             $BOOL_OVERLOAD_TRUE,
808             $BOOL_OVERLOAD_FALSE,
809             $INT,
810             $NEG_INT,
811             $NUM,
812             $NEG_NUM,
813             $NUM_OVERLOAD_ZERO,
814             $NUM_OVERLOAD_ONE,
815             $NUM_OVERLOAD_NEG,
816             $NUM_OVERLOAD_NEG_DECIMAL,
817             $NUM_OVERLOAD_DECIMAL,
818             $EMPTY_STRING,
819             $STRING,
820             $NUM_IN_STRING,
821             $STR_OVERLOAD_EMPTY,
822             $STR_OVERLOAD_FULL,
823             $INT_WITH_NL1,
824             $INT_WITH_NL2,
825             $SCALAR_REF,
826             $SCALAR_REF_REF,
827             $SCALAR_OVERLOAD,
828             $HASH_REF,
829             $HASH_OVERLOAD,
830             $CODE_REF,
831             $CODE_OVERLOAD,
832             $GLOB,
833             $GLOB_REF,
834             $GLOB_OVERLOAD,
835             $GLOB_OVERLOAD_FH,
836             $FH,
837             $FH_OBJECT,
838             $REGEX,
839             $REGEX_OBJ,
840             $REGEX_OVERLOAD,
841             $FAKE_REGEX,
842             $OBJECT,
843             $UNDEF,
844             ],
845             },
846             HashRef => {
847             accept => [
848             $HASH_REF,
849             $HASH_OVERLOAD,
850             ],
851             reject => [
852             $ZERO,
853             $ONE,
854             $BOOL_OVERLOAD_TRUE,
855             $BOOL_OVERLOAD_FALSE,
856             $INT,
857             $NEG_INT,
858             $NUM,
859             $NEG_NUM,
860             $NUM_OVERLOAD_ZERO,
861             $NUM_OVERLOAD_ONE,
862             $NUM_OVERLOAD_NEG,
863             $NUM_OVERLOAD_NEG_DECIMAL,
864             $NUM_OVERLOAD_DECIMAL,
865             $EMPTY_STRING,
866             $STRING,
867             $NUM_IN_STRING,
868             $STR_OVERLOAD_EMPTY,
869             $STR_OVERLOAD_FULL,
870             $INT_WITH_NL1,
871             $INT_WITH_NL2,
872             $SCALAR_REF,
873             $SCALAR_REF_REF,
874             $SCALAR_OVERLOAD,
875             $ARRAY_REF,
876             $ARRAY_OVERLOAD,
877             $CODE_REF,
878             $CODE_OVERLOAD,
879             $GLOB,
880             $GLOB_REF,
881             $GLOB_OVERLOAD,
882             $GLOB_OVERLOAD_FH,
883             $FH,
884             $FH_OBJECT,
885             $REGEX,
886             $REGEX_OBJ,
887             $REGEX_OVERLOAD,
888             $FAKE_REGEX,
889             $OBJECT,
890             $UNDEF,
891             ],
892             },
893             CodeRef => {
894             accept => [
895             $CODE_REF,
896             $CODE_OVERLOAD,
897             ],
898             reject => [
899             $ZERO,
900             $ONE,
901             $BOOL_OVERLOAD_TRUE,
902             $BOOL_OVERLOAD_FALSE,
903             $INT,
904             $NEG_INT,
905             $NUM,
906             $NEG_NUM,
907             $NUM_OVERLOAD_ZERO,
908             $NUM_OVERLOAD_ONE,
909             $NUM_OVERLOAD_NEG,
910             $NUM_OVERLOAD_NEG_DECIMAL,
911             $NUM_OVERLOAD_DECIMAL,
912             $EMPTY_STRING,
913             $STRING,
914             $NUM_IN_STRING,
915             $STR_OVERLOAD_EMPTY,
916             $STR_OVERLOAD_FULL,
917             $INT_WITH_NL1,
918             $INT_WITH_NL2,
919             $SCALAR_REF,
920             $SCALAR_REF_REF,
921             $SCALAR_OVERLOAD,
922             $ARRAY_REF,
923             $ARRAY_OVERLOAD,
924             $HASH_REF,
925             $HASH_OVERLOAD,
926             $GLOB,
927             $GLOB_REF,
928             $GLOB_OVERLOAD,
929             $GLOB_OVERLOAD_FH,
930             $FH,
931             $FH_OBJECT,
932             $REGEX,
933             $REGEX_OBJ,
934             $REGEX_OVERLOAD,
935             $FAKE_REGEX,
936             $OBJECT,
937             $UNDEF,
938             ],
939             },
940             RegexpRef => {
941             accept => [
942             $REGEX,
943             $REGEX_OBJ,
944             $REGEX_OVERLOAD,
945             ],
946             reject => [
947             $ZERO,
948             $ONE,
949             $BOOL_OVERLOAD_TRUE,
950             $BOOL_OVERLOAD_FALSE,
951             $INT,
952             $NEG_INT,
953             $NUM,
954             $NEG_NUM,
955             $NUM_OVERLOAD_ZERO,
956             $NUM_OVERLOAD_ONE,
957             $NUM_OVERLOAD_NEG,
958             $NUM_OVERLOAD_NEG_DECIMAL,
959             $NUM_OVERLOAD_DECIMAL,
960             $EMPTY_STRING,
961             $STRING,
962             $NUM_IN_STRING,
963             $STR_OVERLOAD_EMPTY,
964             $STR_OVERLOAD_FULL,
965             $INT_WITH_NL1,
966             $INT_WITH_NL2,
967             $SCALAR_REF,
968             $SCALAR_REF_REF,
969             $SCALAR_OVERLOAD,
970             $ARRAY_REF,
971             $ARRAY_OVERLOAD,
972             $HASH_REF,
973             $HASH_OVERLOAD,
974             $CODE_REF,
975             $CODE_OVERLOAD,
976             $GLOB,
977             $GLOB_REF,
978             $GLOB_OVERLOAD,
979             $GLOB_OVERLOAD_FH,
980             $FH,
981             $FH_OBJECT,
982             $OBJECT,
983             $UNDEF,
984             $FAKE_REGEX,
985             ],
986             },
987             GlobRef => {
988             accept => [
989             $GLOB_REF,
990             $GLOB_OVERLOAD,
991             $GLOB_OVERLOAD_FH,
992             $FH,
993             ],
994             reject => [
995             $ZERO,
996             $ONE,
997             $BOOL_OVERLOAD_TRUE,
998             $BOOL_OVERLOAD_FALSE,
999             $INT,
1000             $NEG_INT,
1001             $NUM,
1002             $NEG_NUM,
1003             $NUM_OVERLOAD_ZERO,
1004             $NUM_OVERLOAD_ONE,
1005             $NUM_OVERLOAD_NEG,
1006             $NUM_OVERLOAD_NEG_DECIMAL,
1007             $NUM_OVERLOAD_DECIMAL,
1008             $EMPTY_STRING,
1009             $STRING,
1010             $NUM_IN_STRING,
1011             $STR_OVERLOAD_EMPTY,
1012             $STR_OVERLOAD_FULL,
1013             $INT_WITH_NL1,
1014             $INT_WITH_NL2,
1015             $SCALAR_REF,
1016             $SCALAR_REF_REF,
1017             $SCALAR_OVERLOAD,
1018             $ARRAY_REF,
1019             $ARRAY_OVERLOAD,
1020             $HASH_REF,
1021             $HASH_OVERLOAD,
1022             $CODE_REF,
1023             $CODE_OVERLOAD,
1024             $GLOB,
1025             $FH_OBJECT,
1026             $OBJECT,
1027             $REGEX,
1028             $REGEX_OBJ,
1029             $REGEX_OVERLOAD,
1030             $FAKE_REGEX,
1031             $UNDEF,
1032             ],
1033             },
1034             FileHandle => {
1035             accept => [
1036             $FH,
1037             $FH_OBJECT,
1038             $GLOB_OVERLOAD_FH,
1039             ],
1040             reject => [
1041             $ZERO,
1042             $ONE,
1043             $BOOL_OVERLOAD_TRUE,
1044             $BOOL_OVERLOAD_FALSE,
1045             $INT,
1046             $NEG_INT,
1047             $NUM,
1048             $NEG_NUM,
1049             $NUM_OVERLOAD_ZERO,
1050             $NUM_OVERLOAD_ONE,
1051             $NUM_OVERLOAD_NEG,
1052             $NUM_OVERLOAD_NEG_DECIMAL,
1053             $NUM_OVERLOAD_DECIMAL,
1054             $EMPTY_STRING,
1055             $STRING,
1056             $NUM_IN_STRING,
1057             $STR_OVERLOAD_EMPTY,
1058             $STR_OVERLOAD_FULL,
1059             $INT_WITH_NL1,
1060             $INT_WITH_NL2,
1061             $SCALAR_REF,
1062             $SCALAR_REF_REF,
1063             $SCALAR_OVERLOAD,
1064             $ARRAY_REF,
1065             $ARRAY_OVERLOAD,
1066             $HASH_REF,
1067             $HASH_OVERLOAD,
1068             $CODE_REF,
1069             $CODE_OVERLOAD,
1070             $GLOB,
1071             $GLOB_REF,
1072             $GLOB_OVERLOAD,
1073             $OBJECT,
1074             $REGEX,
1075             $REGEX_OBJ,
1076             $REGEX_OVERLOAD,
1077             $FAKE_REGEX,
1078             $UNDEF,
1079             ],
1080             },
1081             Object => {
1082             accept => [
1083             $BOOL_OVERLOAD_TRUE,
1084             $BOOL_OVERLOAD_FALSE,
1085             $STR_OVERLOAD_EMPTY,
1086             $STR_OVERLOAD_FULL,
1087             $NUM_OVERLOAD_ZERO,
1088             $NUM_OVERLOAD_ONE,
1089             $NUM_OVERLOAD_NEG,
1090             $NUM_OVERLOAD_NEG_DECIMAL,
1091             $NUM_OVERLOAD_DECIMAL,
1092             $CODE_OVERLOAD,
1093             $FH_OBJECT,
1094             $REGEX,
1095             $REGEX_OBJ,
1096             $REGEX_OVERLOAD,
1097             $FAKE_REGEX,
1098             $GLOB_OVERLOAD,
1099             $GLOB_OVERLOAD_FH,
1100             $SCALAR_OVERLOAD,
1101             $ARRAY_OVERLOAD,
1102             $HASH_OVERLOAD,
1103             $OBJECT,
1104             ],
1105             reject => [
1106             $ZERO,
1107             $ONE,
1108             $INT,
1109             $NEG_INT,
1110             $NUM,
1111             $NEG_NUM,
1112             $EMPTY_STRING,
1113             $STRING,
1114             $NUM_IN_STRING,
1115             $INT_WITH_NL1,
1116             $INT_WITH_NL2,
1117             $SCALAR_REF,
1118             $SCALAR_REF_REF,
1119             $ARRAY_REF,
1120             $HASH_REF,
1121             $CODE_REF,
1122             $GLOB,
1123             $GLOB_REF,
1124             $FH,
1125             $UNDEF,
1126             ],
1127             },
1128             ClassName => {
1129             accept => [
1130             $CLASS_NAME,
1131             $STR_OVERLOAD_CLASS_NAME,
1132             ],
1133             reject => [
1134             $ZERO,
1135             $ONE,
1136             $BOOL_OVERLOAD_TRUE,
1137             $BOOL_OVERLOAD_FALSE,
1138             $INT,
1139             $NEG_INT,
1140             $NUM,
1141             $NEG_NUM,
1142             $NUM_OVERLOAD_ZERO,
1143             $NUM_OVERLOAD_ONE,
1144             $NUM_OVERLOAD_NEG,
1145             $NUM_OVERLOAD_NEG_DECIMAL,
1146             $NUM_OVERLOAD_DECIMAL,
1147             $EMPTY_STRING,
1148             $STRING,
1149             $NUM_IN_STRING,
1150             $STR_OVERLOAD_EMPTY,
1151             $STR_OVERLOAD_FULL,
1152             $INT_WITH_NL1,
1153             $INT_WITH_NL2,
1154             $SCALAR_REF,
1155             $SCALAR_REF_REF,
1156             $SCALAR_OVERLOAD,
1157             $ARRAY_REF,
1158             $ARRAY_OVERLOAD,
1159             $HASH_REF,
1160             $HASH_OVERLOAD,
1161             $CODE_REF,
1162             $CODE_OVERLOAD,
1163             $GLOB,
1164             $GLOB_REF,
1165             $GLOB_OVERLOAD,
1166             $GLOB_OVERLOAD_FH,
1167             $FH,
1168             $FH_OBJECT,
1169             $REGEX,
1170             $REGEX_OBJ,
1171             $REGEX_OVERLOAD,
1172             $FAKE_REGEX,
1173             $OBJECT,
1174             $UNDEF,
1175             ],
1176             },
1177             };
1178             }
1179              
1180             sub test_constraint {
1181 74     74 1 1697410 my $type = shift;
1182 74         214 my $tests = shift;
1183 74   100     999 my $describer = shift || \&describe;
1184              
1185 74         264 local $Test::Builder::Level = $Test::Builder::Level + 1;
1186              
1187 74 100       486 $type = t($type) unless blessed $type;
1188              
1189             subtest(
1190             ( $type->name || '<anon>' ),
1191             sub {
1192             try {
1193 74         4661 my $not_inlined = $type->_constraint_with_parents;
1194              
1195 74         167 my $inlined;
1196 74 100       321 if ( $type->can_be_inlined ) {
1197 70         581 $inlined = $type->_generated_inline_sub;
1198             }
1199              
1200 74 100       5722 for my $accept ( @{ $tests->{accept} || [] } ) {
  74         486  
1201 602         1823496 my $described = $describer->($accept);
1202             subtest(
1203             "accepts $described",
1204             sub {
1205 602         909633 ok(
1206             $type->value_is_valid($accept),
1207             'using ->value_is_valid'
1208             );
1209             is(
1210 602         47586 exception { $type->($accept) },
1211             undef,
1212 602         371208 'using subref overloading'
1213             );
1214 602         544028 ok(
1215             $not_inlined->($accept),
1216             'using non-inlined constraint'
1217             );
1218 602 100       364892 if ($inlined) {
1219 572         2472 ok(
1220             $inlined->($accept),
1221             'using inlined constraint'
1222             );
1223             }
1224             }
1225 602         5394 );
1226             }
1227              
1228 74 100       226184 for my $reject ( @{ $tests->{reject} || [] } ) {
  74         483  
1229 2237         7013307 my $described = $describer->($reject);
1230             subtest(
1231             "rejects $described",
1232             sub {
1233 2237         3403959 ok(
1234             !$type->value_is_valid($reject),
1235             'using ->value_is_valid'
1236             );
1237              
1238             # I don't love this test, but there's no way to know the
1239             # exact content of each type's validation failure
1240             # exception. We can, however, reasonably assume (I think)
1241             # that the exception thrown will include a trace starting
1242             # with Specio::Exception.
1243             like(
1244 2237         184838 exception { $type->($reject) },
1245 2237         1380574 qr/\QTrace begun at Specio::Exception->new/,
1246             'using subref overloading'
1247             );
1248 2237 100       1592649 if ($inlined) {
1249 2053         11348 ok(
1250             !$inlined->($reject),
1251             'using inlined constraint'
1252             );
1253             }
1254             }
1255 2237         20916 );
1256             }
1257             }
1258             catch {
1259 0         0 fail('No exception in test_constraint');
1260 0         0 diag($_);
1261 74     74   114958 };
1262             }
1263 74   100     478 );
1264             }
1265              
1266             sub describe {
1267 5256     5256 1 786412 my $val = shift;
1268              
1269 5256 100       17752 return 'undef' unless defined $val;
1270              
1271 5157 100       14790 if ( !ref $val ) {
1272 2372 100       10945 return q{''} if $val eq q{};
1273              
1274 2168 100 100     26245 return looks_like_number($val)
1275             && $val !~ /\n/ ? $val : Specio::Helpers::perlstring($val);
1276             }
1277              
1278 2785 100 100     16841 return 'open filehandle'
1279             if openhandle $val && !blessed $val;
1280              
1281 2688 100       8402 if ( blessed $val ) {
1282 2071         5759 my $desc = ( ref $val ) . ' object';
1283 2071 100       24749 if ( $val->isa('_T::StrOverload') ) {
    100          
    100          
1284 204         1408 $desc .= ' (' . describe("$val") . ')';
1285             }
1286             elsif ( $val->isa('_T::BoolOverload') ) {
1287 194 100       1353 $desc .= ' (' . ( $val ? 'true' : 'false' ) . ')';
1288             }
1289             elsif ( $val->isa('_T::NumOverload') ) {
1290 485         984 $desc .= ' (' . describe( ${$val} ) . ')';
  485         2325  
1291             }
1292              
1293 2071         9146 return $desc;
1294             }
1295             else {
1296 617         3407 return ( ref $val ) . ' reference';
1297             }
1298             }
1299              
1300             1;
1301              
1302             # ABSTRACT: Test helpers for Specio
1303              
1304             __END__
1305              
1306             =pod
1307              
1308             =encoding UTF-8
1309              
1310             =head1 NAME
1311              
1312             Test::Specio - Test helpers for Specio
1313              
1314             =head1 VERSION
1315              
1316             version 0.53
1317              
1318             =head1 SYNOPSIS
1319              
1320             use Test::Specio qw( test_constraint :vars );
1321              
1322             test_constraint(
1323             t('Foo'), {
1324             accept => [ 'foo', 'bar' ],
1325             reject => [ 42, {}, $EMPTY_STRING, $HASH_REF ],
1326             }
1327             );
1328              
1329             =head1 DESCRIPTION
1330              
1331             This package provides some helper functions and variables for testing Specio
1332             types.
1333              
1334             =head1 EXPORTS
1335              
1336             This module provides the following exports:
1337              
1338             =head2 test_constraint( $type, $tests, [ $describer ] )
1339              
1340             This subroutine accepts two arguments. The first should be a Specio type
1341             object. The second is hashref which can contain the keys C<accept> and
1342             C<reject>. Each key should contain an arrayref of values which the type accepts
1343             or rejects.
1344              
1345             The third argument is optional. This is a sub reference which will be called to
1346             generate a description of the value being tested. This defaults to calling this
1347             package's C<describe> sub, but you can provide your own.
1348              
1349             =head2 describe($value)
1350              
1351             Given a value, this subroutine returns a string describing that value in a
1352             useful way for test output. It know about the various classes used for the
1353             variables exported by this package and will do something intelligent when such
1354             a variable.
1355              
1356             =head2 builtins_tests( $GLOB, $GLOB_OVERLOAD, $GLOB_OVERLOAD_FH )
1357              
1358             This subroutine returns a hashref containing test variables for all builtin
1359             types. The hashref has a form like this:
1360              
1361             {
1362             Bool => {
1363             accept => [
1364             $ZERO,
1365             $ONE,
1366             $BOOL_OVERLOAD_TRUE,
1367             $BOOL_OVERLOAD_FALSE,
1368             ...,
1369             ],
1370             reject => [
1371             $INT,
1372             $NEG_INT,
1373             $NUM,
1374             $NEG_NUM,
1375             ...,
1376             $OBJECT,
1377             ],
1378             },
1379             Maybe => {...},
1380             }
1381              
1382             You need to pass in a glob, an object which overloads globification, and an
1383             object which overloads globification to return an open filehandle. See below
1384             for more details on how to create these things.
1385              
1386             =head2 create_BAR_handle_code()
1387              
1388             Returns a string you can C<eval> to create a bar filehandle named C<BAR>. This
1389             should be used like this:
1390              
1391             local *BAR;
1392             {
1393             local $@;
1394             eval create_BAR_handle_code();
1395             die $@ if $@;
1396             }
1397              
1398             =head2 Variables
1399              
1400             This module also exports many variables containing values which are useful for
1401             testing constraints. Note that references are always empty unless stated
1402             otherwise. You can import these variables individually or import all of them
1403             with the C<:vars> import tag.
1404              
1405             =over 4
1406              
1407             =item * C<$ZERO>
1408              
1409             =item * C<$ONE>
1410              
1411             =item * C<$INT>
1412              
1413             An arbitrary positive integer.
1414              
1415             =item * C<$NEG_INT>
1416              
1417             An arbitrary negative integer.
1418              
1419             =item * C<$NUM>
1420              
1421             An arbitrary positive non-integer number.
1422              
1423             =item * C<$NEG_NUM>
1424              
1425             An arbitrary negative non-integer number.
1426              
1427             =item * C<$EMPTY_STRING>
1428              
1429             =item * C<$STRING>
1430              
1431             An arbitrary non-empty string.
1432              
1433             =item * C<$NUM_IN_STRING>
1434              
1435             An arbitrary string which contains a number.
1436              
1437             =item * C<$INT_WITH_NL1>
1438              
1439             An string containing an integer followed by a newline.
1440              
1441             =item * C<$INT_WITH_NL2>
1442              
1443             An string containing a newline followed by an integer.
1444              
1445             =item * C<$SCALAR_REF>
1446              
1447             =item * C<$SCALAR_REF_REF>
1448              
1449             A reference containing a reference to a scalar.
1450              
1451             =item * C<$ARRAY_REF>
1452              
1453             =item * C<$HASH_REF>
1454              
1455             =item * C<$CODE_REF>
1456              
1457             =item * C<$GLOB_REF>
1458              
1459             =item * C<$FH>
1460              
1461             An opened filehandle.
1462              
1463             =item * C<$FH_OBJECT>
1464              
1465             An opened L<IO::File> object.
1466              
1467             =item * C<$REGEX>
1468              
1469             A regex created with C<qr//>.
1470              
1471             =item * C<$REGEX_OBJ>
1472              
1473             A regex created with C<qr//> that was then blessed into class.
1474              
1475             =item * C<$FAKE_REGEX>
1476              
1477             A non-regex blessed into the C<Regexp> class which Perl uses internally for
1478             C<qr//> objects.
1479              
1480             =item * C<$OBJECT>
1481              
1482             An arbitrary object.
1483              
1484             =item * C<$UNDEF>
1485              
1486             =item * C<$CLASS_NAME>
1487              
1488             A string containing a loaded package name.
1489              
1490             =item * C<$BOOL_OVERLOAD_TRUE>
1491              
1492             An object which overloads boolification to return true.
1493              
1494             =item * C<$BOOL_OVERLOAD_FALSE>
1495              
1496             An object which overloads boolification to return false.
1497              
1498             =item * C<$STR_OVERLOAD_EMPTY>
1499              
1500             An object which overloads stringification to return an empty string.
1501              
1502             =item * C<$STR_OVERLOAD_FULL>
1503              
1504             An object which overloads stringification to return a non-empty string.
1505              
1506             =item * C<$STR_OVERLOAD_CLASS_NAME>
1507              
1508             An object which overloads stringification to return a loaded package name.
1509              
1510             =item * C<$NUM_OVERLOAD_ZERO>
1511              
1512             =item * C<$NUM_OVERLOAD_ONE>
1513              
1514             =item * C<$NUM_OVERLOAD_NEG>
1515              
1516             =item * C<$NUM_OVERLOAD_DECIMAL>
1517              
1518             =item * C<$NUM_OVERLOAD_NEG_DECIMAL>
1519              
1520             =item * C<$CODE_OVERLOAD>
1521              
1522             =item * C<$SCALAR_OVERLOAD>
1523              
1524             An object which overloads scalar dereferencing to return a non-empty string.
1525              
1526             =item * C<$ARRAY_OVERLOAD>
1527              
1528             An object which overloads array dereferencing to return a non-empty array.
1529              
1530             =item * C<$HASH_OVERLOAD>
1531              
1532             An object which overloads hash dereferencing to return a non-empty hash.
1533              
1534             =back
1535              
1536             =head2 Globs and the _T::GlobOverload package
1537              
1538             To create a glob you can pass around for tests, use this code:
1539              
1540             my $GLOB = do {
1541             no warnings 'once';
1542             *SOME_GLOB;
1543             };
1544              
1545             The C<_T::GlobOverload> package is defined when you load C<Test::Specio> so you
1546             can create your own glob overloading objects. Such objects cannot be exported
1547             because the glob they return does not transfer across packages properly.
1548              
1549             You can create such a variable like this:
1550              
1551             local *FOO;
1552             my $GLOB_OVERLOAD = _T::GlobOverload->new( \*FOO );
1553              
1554             If you want to create a glob overloading object that returns a filehandle, do
1555             this:
1556              
1557             local *BAR;
1558             open BAR, '<', $some_file or die $!;
1559             my $GLOB_OVERLOAD_FH = _T::GlobOverload->new( \*BAR );
1560              
1561             =head1 SUPPORT
1562              
1563             Bugs may be submitted at L<https://github.com/houseabsolute/Specio/issues>.
1564              
1565             =head1 SOURCE
1566              
1567             The source code repository for Specio can be found at L<https://github.com/houseabsolute/Specio>.
1568              
1569             =head1 AUTHOR
1570              
1571             Dave Rolsky <autarch@urth.org>
1572              
1573             =head1 COPYRIGHT AND LICENSE
1574              
1575             This software is Copyright (c) 2012 - 2025 by Dave Rolsky.
1576              
1577             This is free software, licensed under:
1578              
1579             The Artistic License 2.0 (GPL Compatible)
1580              
1581             The full text of the license can be found in the
1582             F<LICENSE> file included with this distribution.
1583              
1584             =cut