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