File Coverage

blib/lib/Test/Specio.pm
Criterion Covered Total %
statement 146 155 94.1
branch 35 36 97.2
condition 10 10 100.0
subroutine 42 47 89.3
pod 3 3 100.0
total 236 251 94.0


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