b809571cb10a123273d27daf167fad9584db3e5d
[gitmo/Moose.git] / t / 070_attribute_helpers / 203_trait_hash.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 46;
7 use Test::Exception;
8 use Test::Moose 'does_ok';
9
10 {
11     package Stuff;
12     use Moose;
13     use Moose::AttributeHelpers;
14
15     has 'options' => (
16         traits  => ['Collection::Hash'],
17         is      => 'ro',
18         isa     => 'HashRef[Str]',
19         default => sub { {} },
20         handles => {
21             'set_option'       => 'set',
22             'get_option'       => 'get',
23             'has_options'      => 'empty',
24             'num_options'      => 'count',
25             'clear_options'    => 'clear',
26             'delete_option'    => 'delete',
27             'has_option'       => 'exists',
28             'is_defined'       => 'defined',
29             'option_accessor'  => 'accessor',
30             'key_value'        => 'kv',
31             'options_elements' => 'elements',
32             'quantity'         => [ accessor => ['quantity'] ],
33         },
34     );
35 }
36
37 my $stuff = Stuff->new();
38 isa_ok( $stuff, 'Stuff' );
39
40 can_ok( $stuff, $_ ) for qw[
41     set_option
42     get_option
43     has_options
44     num_options
45     delete_option
46     clear_options
47     is_defined
48     has_option
49     quantity
50     option_accessor
51 ];
52
53 ok( !$stuff->has_options, '... we have no options' );
54 is( $stuff->num_options, 0, '... we have no options' );
55
56 is_deeply( $stuff->options, {}, '... no options yet' );
57 ok( !$stuff->has_option('foo'), '... we have no foo option' );
58
59 lives_ok {
60     $stuff->set_option( foo => 'bar' );
61 }
62 '... set the option okay';
63
64 ok( $stuff->is_defined('foo'), '... foo is defined' );
65
66 ok( $stuff->has_options, '... we have options' );
67 is( $stuff->num_options, 1, '... we have 1 option(s)' );
68 ok( $stuff->has_option('foo'), '... we have a foo option' );
69 is_deeply( $stuff->options, { foo => 'bar' }, '... got options now' );
70
71 lives_ok {
72     $stuff->set_option( bar => 'baz' );
73 }
74 '... set the option okay';
75
76 is( $stuff->num_options, 2, '... we have 2 option(s)' );
77 is_deeply( $stuff->options, { foo => 'bar', bar => 'baz' },
78     '... got more options now' );
79
80 is( $stuff->get_option('foo'), 'bar', '... got the right option' );
81
82 is_deeply( [ $stuff->get_option(qw(foo bar)) ], [qw(bar baz)],
83     "get multiple options at once" );
84
85 lives_ok {
86     $stuff->set_option( oink => "blah", xxy => "flop" );
87 }
88 '... set the option okay';
89
90 is( $stuff->num_options, 4, "4 options" );
91 is_deeply( [ $stuff->get_option(qw(foo bar oink xxy)) ],
92     [qw(bar baz blah flop)], "get multiple options at once" );
93
94 lives_ok {
95     $stuff->delete_option('bar');
96 }
97 '... deleted the option okay';
98
99 lives_ok {
100     $stuff->delete_option('oink');
101 }
102 '... deleted the option okay';
103
104 lives_ok {
105     $stuff->delete_option('xxy');
106 }
107 '... deleted the option okay';
108
109 is( $stuff->num_options, 1, '... we have 1 option(s)' );
110 is_deeply( $stuff->options, { foo => 'bar' }, '... got more options now' );
111
112 $stuff->clear_options;
113
114 is_deeply( $stuff->options, {}, "... cleared options" );
115
116 lives_ok {
117     $stuff->quantity(4);
118 }
119 '... options added okay with defaults';
120
121 is( $stuff->quantity, 4, 'reader part of curried accessor works' );
122
123 is_deeply( $stuff->options, { quantity => 4 }, '... returns what we expect' );
124
125 lives_ok {
126     Stuff->new( options => { foo => 'BAR' } );
127 }
128 '... good constructor params';
129
130 ## check some errors
131
132 dies_ok {
133     $stuff->set_option( bar => {} );
134 }
135 '... could not add a hash ref where an string is expected';
136
137 dies_ok {
138     Stuff->new( options => { foo => [] } );
139 }
140 '... bad constructor params';
141
142 ## test the meta
143
144 my $options = $stuff->meta->get_attribute('options');
145 does_ok( $options, 'Moose::AttributeHelpers::Trait::Collection::Hash' );
146
147 is_deeply(
148     $options->handles,
149     {
150         'set_option'       => 'set',
151         'get_option'       => 'get',
152         'has_options'      => 'empty',
153         'num_options'      => 'count',
154         'clear_options'    => 'clear',
155         'delete_option'    => 'delete',
156         'has_option'       => 'exists',
157         'is_defined'       => 'defined',
158         'option_accessor'  => 'accessor',
159         'key_value'        => 'kv',
160         'options_elements' => 'elements',
161         'quantity'         => [ accessor => ['quantity'] ],
162     },
163     '... got the right handles mapping'
164 );
165
166 is( $options->type_constraint->type_parameter, 'Str',
167     '... got the right container type' );
168
169 $stuff->set_option( oink => "blah", xxy => "flop" );
170 my @key_value = $stuff->key_value;
171 is_deeply(
172     \@key_value,
173     [ [ 'xxy', 'flop' ], [ 'quantity', 4 ], [ 'oink', 'blah' ] ],
174     '... got the right key value pairs'
175 );
176
177 my %options_elements = $stuff->options_elements;
178 is_deeply(
179     \%options_elements,
180     {
181         'oink'     => 'blah',
182         'quantity' => 4,
183         'xxy'      => 'flop'
184     },
185     '... got the right hash elements'
186 );