Credit me
[gitmo/MooseX-AttributeHelpers.git] / t / 005_basic_list.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 35;
7 use Test::Exception;
8
9 BEGIN {
10     use_ok('MooseX::AttributeHelpers');   
11 }
12
13 {
14     package Stuff;
15     use Moose;
16
17     has '_options' => (
18         metaclass => 'Collection::List',
19         is        => 'ro',
20         isa       => 'ArrayRef[Int]',
21         init_arg  => 'options',
22         default   => sub { [] },
23         provides  => {
24             'count'    => 'num_options',
25             'empty'    => 'has_options',        
26             'map'      => 'map_options',
27             'grep'     => 'filter_options',
28             'find'     => 'find_option',
29             'elements' => 'options',
30             'join'     => 'join_options',
31             'get'      => 'get_option_at',
32             'first'    => 'get_first_option',
33             'last'     => 'get_last_option',
34             'sort'     => 'sorted_options',
35         },
36         curries   => {
37             'grep'     => {less_than_five => [ sub { $_ < 5 } ]},
38             'map'      => {up_by_one      => [ sub { $_ + 1 } ]},
39             'join'     => {dashify        => [ '-' ]},
40             'sort'     => {descending     => [ sub { $_[1] <=> $_[0] } ]},
41         }
42     );
43
44     has animals => (
45         is       => 'rw',
46         isa      => 'ArrayRef[Str]',
47         metaclass => 'Collection::List',
48         curries => {
49             grep =>  {
50                 double_length_of => sub {
51                     my ($self, $body, $arg) = @_;
52
53                     $body->($self, sub { length($_) == length($arg) * 2 });
54                 }
55             }
56         }
57     )
58 }
59
60 my $stuff = Stuff->new(options => [ 1 .. 10 ]);
61 isa_ok($stuff, 'Stuff');
62
63 can_ok($stuff, $_) for qw[
64     _options
65     num_options
66     has_options
67     map_options
68     filter_options
69     find_option
70     options
71     join_options
72     get_option_at
73     sorted_options
74 ];
75
76 is_deeply($stuff->_options, [1 .. 10], '... got options');
77
78 ok($stuff->has_options, '... we have options');
79 is($stuff->num_options, 10, '... got 2 options');
80 cmp_ok($stuff->get_option_at(0), '==', 1, '... get option 0');
81 cmp_ok($stuff->get_first_option, '==', 1, '... get first');
82 cmp_ok($stuff->get_last_option, '==', 10, '... get last');
83
84 is_deeply(
85 [ $stuff->filter_options(sub { $_[0] % 2 == 0 }) ],
86 [ 2, 4, 6, 8, 10 ],
87 '... got the right filtered values'
88 );
89
90 is_deeply(
91 [ $stuff->map_options(sub { $_[0] * 2 }) ],
92 [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ],
93 '... got the right mapped values'
94 );
95
96 is($stuff->find_option(sub { $_[0] % 2 == 0 }), 2, '.. found the right option');
97
98 is_deeply([ $stuff->options ], [1 .. 10], '... got the list of options');
99
100 is($stuff->join_options(':'), '1:2:3:4:5:6:7:8:9:10', '... joined the list of options by :');
101
102 is_deeply([ $stuff->sorted_options ], [sort (1..10)],
103           '... got sorted options (default sort order)');
104 is_deeply([ $stuff->sorted_options( sub { $_[1] <=> $_[0] } ) ], [sort { $b <=> $a } (1..10)],
105           '... got sorted options (descending sort order) ');
106
107 throws_ok { $stuff->sorted_options('foo') } qr/Argument must be a code reference/,
108     'error when sort receives a non-coderef argument';
109
110 # test the currying
111 is_deeply([ $stuff->less_than_five() ], [1 .. 4]);
112
113 is_deeply([ $stuff->up_by_one() ], [2 .. 11]);
114
115 is($stuff->dashify, '1-2-3-4-5-6-7-8-9-10');
116
117 $stuff->animals([ qw/cat duck horse cattle gorilla elephant flamingo kangaroo/ ]);
118
119 # 4 * 2 = 8
120 is_deeply(
121         [ sort $stuff->double_length_of('fish') ],
122         [ sort qw/elephant flamingo kangaroo/ ],
123         'returns all elements with double length of string "fish"'
124 );
125
126 is_deeply([$stuff->descending], [reverse 1 .. 10]);
127
128 ## test the meta
129
130 my $options = $stuff->meta->get_attribute('_options');
131 isa_ok($options, 'MooseX::AttributeHelpers::Collection::List');
132
133 is_deeply($options->provides, {
134     'map'      => 'map_options',
135     'grep'     => 'filter_options',
136     'find'     => 'find_option',
137     'count'    => 'num_options',
138     'empty'    => 'has_options',
139     'elements' => 'options',
140     'join'     => 'join_options',
141     'get'      => 'get_option_at',
142     'first'    => 'get_first_option',
143     'last'     => 'get_last_option',
144     'sort'     => 'sorted_options',
145 }, '... got the right provides mapping');
146
147 is($options->type_constraint->type_parameter, 'Int', '... got the right container type');
148
149 dies_ok {
150     $stuff->sort_in_place_options( undef );
151 } '... sort rejects arg of invalid type';
152