summaryrefslogtreecommitdiff
path: root/t/20-modules/Type-Library/recursive-type-definitions.t
blob: b114f1ca689cffdeb5a4f40a0ca5d605628cafcb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
=pod

=encoding utf-8

=head1 PURPOSE

Tests that types may be defined recursively.

=head1 AUTHOR

Toby Inkster E<lt>tobyink@cpan.orgE<gt>.

=head1 COPYRIGHT AND LICENCE

This software is copyright (c) 2020-2023 by Toby Inkster.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut

use strict;
use warnings;
use Test::More;

BEGIN {
	package MyTypes;
	
	use Type::Library -base, -declare => 'MyHashRef';
	use Types::Standard -types;
	
	__PACKAGE__->add_type(
		name    => MyHashRef,
		parent  => HashRef[ Int | MyHashRef ],
	);
	
	$INC{'MyTypes.pm'} = __FILE__; # stop `use` from complaining
};

use MyTypes -types;

my %good1 = ( foo => 1, bar => 2 );
my %good2 = ( %good1, bat => {}, baz => { foo => 3 } );
my %good3 = ( %good2, quux => { quuux => { quuuux => 0, xyzzy => {} } } );

my %bad1 = ( %good1, bar => \1 );
my %bad2 = ( %good2, baz => { foo => \1 } );
my %bad3 = ( %good3, quux => { quuux => { quuuux => 0, xyzzy => \1 } } );

ok( MyHashRef->can_be_inlined );

ok( MyHashRef->check( {} ) );
ok( MyHashRef->check( \%good1 ) );
ok( MyHashRef->check( \%good2 ) );
ok( MyHashRef->check( \%good3 ) );
ok( ! MyHashRef->check( \%bad1 ) );
ok( ! MyHashRef->check( \%bad2 ) );
ok( ! MyHashRef->check( \%bad3 ) );
ok( ! MyHashRef->check( undef ) );
ok( ! MyHashRef->check( \1 ) );

#use B::Deparse;
#note( B::Deparse->new->coderef2text( \&MyTypes::is_MyHashRef ) );

BEGIN {
	package MyTypes2;
	
	use Type::Library -base, -declare => qw( StringArray StringHash StringContainer );
	use Types::Standard -types;
	
	__PACKAGE__->add_type(
		name    => StringArray,
		parent  => ArrayRef[ Str | StringArray | StringHash ],
	);
	
	__PACKAGE__->add_type(
		name    => StringHash,
		parent  => HashRef[ Str | StringArray | StringHash ],
	);
	
	__PACKAGE__->add_type(
		name    => StringContainer,
		parent  => StringHash | StringArray,
	);
	
	$INC{'MyTypes2.pm'} = __FILE__; # stop `use` from complaining
};

use MyTypes2 -types;

ok(   StringContainer->check({ foo => [], bar => ['a', 'b', { c => 'd' }], baz => 'e' }) );
ok( ! StringContainer->check({ foo => [], bar => ['a', 'b', { c => \42 }], baz => 'e' }) );

#use B::Deparse;
#note( B::Deparse->new->coderef2text( \&MyTypes2::is_StringContainer ) );

done_testing;