Work in progress on inlining native traits methods.
[gitmo/Moose.git] / t / 070_native_traits / 202_trait_array.t
CommitLineData
e3c07b19 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
a28e50e4 6use Test::More;
e3c07b19 7use Test::Exception;
8use Test::Moose 'does_ok';
9
18281451 10my $sort;
d50fc84a 11
e3c07b19 12{
d50fc84a 13
e3c07b19 14 package Stuff;
15 use Moose;
16
17 has 'options' => (
a40b446a 18 traits => ['Array'],
d50fc84a 19 is => 'ro',
20 isa => 'ArrayRef[Str]',
21 default => sub { [] },
0d103ac9 22 handles => {
23 'add_options' => 'push',
24 'remove_last_option' => 'pop',
25 'remove_first_option' => 'shift',
26 'insert_options' => 'unshift',
27 'get_option_at' => 'get',
28 'set_option_at' => 'set',
29 'num_options' => 'count',
1853a27e 30 'has_no_options' => 'is_empty',
0d103ac9 31 'clear_options' => 'clear',
32 'splice_options' => 'splice',
33 'sort_options_in_place' => 'sort_in_place',
34 'option_accessor' => 'accessor',
f7fd22b6 35 'all_options' => 'elements',
36 'first_option' => 'first',
37 'mapped_options' => 'map',
18281451 38 'add_options_with_speed' =>
3c573ca4 39 [ 'push' => 'funrolls', 'funbuns' ],
0d103ac9 40 'prepend_prerequisites_along_with' =>
3c573ca4 41 [ 'unshift' => 'first', 'second' ],
0d103ac9 42 'descending_options' =>
3c573ca4 43 [ 'sort_in_place' => ($sort = sub { $_[1] <=> $_[0] }) ],
e3c07b19 44 }
45 );
46}
47
d50fc84a 48my $stuff = Stuff->new( options => [ 10, 12 ] );
49isa_ok( $stuff, 'Stuff' );
e3c07b19 50
d50fc84a 51can_ok( $stuff, $_ ) for qw[
e3c07b19 52 add_options
53 remove_last_option
54 remove_first_option
55 insert_options
56 get_option_at
57 set_option_at
58 num_options
59 clear_options
af44c00c 60 has_no_options
59de9de4 61 sort_options_in_place
62 option_accessor
e3c07b19 63];
64
d50fc84a 65is_deeply( $stuff->options, [ 10, 12 ], '... got options' );
e3c07b19 66
af44c00c 67ok( !$stuff->has_no_options, '... we have options' );
d50fc84a 68is( $stuff->num_options, 2, '... got 2 options' );
e3c07b19 69
d50fc84a 70is( $stuff->remove_last_option, 12, '... removed the last option' );
71is( $stuff->remove_first_option, 10, '... removed the last option' );
e3c07b19 72
d50fc84a 73is_deeply( $stuff->options, [], '... no options anymore' );
e3c07b19 74
af44c00c 75ok( $stuff->has_no_options, '... no options' );
d50fc84a 76is( $stuff->num_options, 0, '... got no options' );
e3c07b19 77
78lives_ok {
d50fc84a 79 $stuff->add_options( 1, 2, 3 );
80}
81'... set the option okay';
e3c07b19 82
d50fc84a 83is_deeply( $stuff->options, [ 1, 2, 3 ], '... got options now' );
f7fd22b6 84is_deeply( [ $stuff->all_options ], [ 1, 2, 3 ], '... got options now (with elements method)' );
85is( $stuff->first_option, 1, '... got first option' );
86is_deeply( [ $stuff->mapped_options( sub { $_ * 10 } ) ], [ 10, 20, 30 ],
87 '... got mapped options' );
e3c07b19 88
af44c00c 89ok( !$stuff->has_no_options, '... has options' );
d50fc84a 90is( $stuff->num_options, 3, '... got 3 options' );
e3c07b19 91
d50fc84a 92is( $stuff->get_option_at(0), 1, '... get option at index 0' );
93is( $stuff->get_option_at(1), 2, '... get option at index 1' );
94is( $stuff->get_option_at(2), 3, '... get option at index 2' );
e3c07b19 95
96lives_ok {
d50fc84a 97 $stuff->set_option_at( 1, 100 );
98}
99'... set the option okay';
e3c07b19 100
d50fc84a 101is( $stuff->get_option_at(1), 100, '... get option at index 1' );
e3c07b19 102
103lives_ok {
d50fc84a 104 $stuff->add_options( 10, 15 );
105}
106'... set the option okay';
e3c07b19 107
d50fc84a 108is_deeply( $stuff->options, [ 1, 100, 3, 10, 15 ],
109 '... got more options now' );
e3c07b19 110
d50fc84a 111is( $stuff->num_options, 5, '... got 5 options' );
e3c07b19 112
d50fc84a 113is( $stuff->remove_last_option, 15, '... removed the last option' );
e3c07b19 114
d50fc84a 115is( $stuff->num_options, 4, '... got 4 options' );
116is_deeply( $stuff->options, [ 1, 100, 3, 10 ], '... got diff options now' );
e3c07b19 117
118lives_ok {
d50fc84a 119 $stuff->insert_options( 10, 20 );
120}
121'... set the option okay';
e3c07b19 122
d50fc84a 123is( $stuff->num_options, 6, '... got 6 options' );
124is_deeply( $stuff->options, [ 10, 20, 1, 100, 3, 10 ],
125 '... got diff options now' );
e3c07b19 126
d50fc84a 127is( $stuff->get_option_at(0), 10, '... get option at index 0' );
128is( $stuff->get_option_at(1), 20, '... get option at index 1' );
129is( $stuff->get_option_at(3), 100, '... get option at index 3' );
e3c07b19 130
d50fc84a 131is( $stuff->remove_first_option, 10, '... getting the first option' );
e3c07b19 132
d50fc84a 133is( $stuff->num_options, 5, '... got 5 options' );
134is( $stuff->get_option_at(0), 20, '... get option at index 0' );
e3c07b19 135
136$stuff->clear_options;
137is_deeply( $stuff->options, [], "... clear options" );
138
d50fc84a 139$stuff->add_options( 5, 1, 2, 3 );
59de9de4 140$stuff->sort_options_in_place;
d50fc84a 141is_deeply( $stuff->options, [ 1, 2, 3, 5 ],
142 "... sort options in place (default sort order)" );
59de9de4 143
144$stuff->sort_options_in_place( sub { $_[1] <=> $_[0] } );
d50fc84a 145is_deeply( $stuff->options, [ 5, 3, 2, 1 ],
146 "... sort options in place (descending order)" );
59de9de4 147
148$stuff->clear_options();
d50fc84a 149$stuff->add_options( 5, 1, 2, 3 );
59de9de4 150lives_ok {
d50fc84a 151 $stuff->descending_options();
152}
153'... curried sort in place lives ok';
59de9de4 154
d50fc84a 155is_deeply( $stuff->options, [ 5, 3, 2, 1 ], "... sort currying" );
59de9de4 156
d50fc84a 157throws_ok { $stuff->sort_options_in_place('foo') }
158qr/Argument must be a code reference/,
59de9de4 159 'error when sort_in_place receives a non-coderef argument';
160
161$stuff->clear_options;
162
163lives_ok {
164 $stuff->add_options('tree');
d50fc84a 165}
166'... set the options okay';
59de9de4 167
168lives_ok {
d50fc84a 169 $stuff->add_options_with_speed( 'compatible', 'safe' );
170}
171'... add options with speed okay';
59de9de4 172
d50fc84a 173is_deeply(
174 $stuff->options, [qw/tree funrolls funbuns compatible safe/],
175 'check options after add_options_with_speed'
176);
59de9de4 177
178lives_ok {
179 $stuff->prepend_prerequisites_along_with();
d50fc84a 180}
181'... add prerequisite options okay';
59de9de4 182
183$stuff->clear_options;
184$stuff->add_options( 1, 2 );
185
186lives_ok {
187 $stuff->splice_options( 1, 0, 'foo' );
d50fc84a 188}
189'... splice_options works';
59de9de4 190
191is_deeply(
192 $stuff->options, [ 1, 'foo', 2 ],
193 'splice added expected option'
194);
195
d50fc84a 196is( $stuff->option_accessor( 1 => 'foo++' ), 'foo++' );
197is( $stuff->option_accessor(1), 'foo++' );
59de9de4 198
e3c07b19 199## check some errors
200
59de9de4 201#dies_ok {
202# $stuff->insert_options(undef);
203#} '... could not add an undef where a string is expected';
204#
205#dies_ok {
206# $stuff->set_option(5, {});
207#} '... could not add a hash ref where a string is expected';
208
e3c07b19 209dies_ok {
d50fc84a 210 Stuff->new( options => [ undef, 10, undef, 20 ] );
211}
212'... bad constructor params';
e3c07b19 213
214dies_ok {
59de9de4 215 my $stuff = Stuff->new();
216 $stuff->add_options(undef);
d50fc84a 217}
218'... rejects push of an invalid type';
59de9de4 219
220dies_ok {
221 my $stuff = Stuff->new();
e3c07b19 222 $stuff->insert_options(undef);
d50fc84a 223}
224'... rejects unshift of an invalid type';
e3c07b19 225
226dies_ok {
59de9de4 227 my $stuff = Stuff->new();
228 $stuff->set_option_at( 0, undef );
d50fc84a 229}
230'... rejects set of an invalid type';
e3c07b19 231
232dies_ok {
59de9de4 233 my $stuff = Stuff->new();
d50fc84a 234 $stuff->sort_in_place_options(undef);
235}
236'... sort rejects arg of invalid type';
59de9de4 237
238dies_ok {
239 my $stuff = Stuff->new();
240 $stuff->option_accessor();
d50fc84a 241}
242'... accessor rejects 0 args';
59de9de4 243
244dies_ok {
245 my $stuff = Stuff->new();
d50fc84a 246 $stuff->option_accessor( 1, 2, 3 );
247}
248'... accessor rejects 3 args';
e3c07b19 249
250## test the meta
251
252my $options = $stuff->meta->get_attribute('options');
c466e58f 253does_ok( $options, 'Moose::Meta::Attribute::Native::Trait::Array' );
d50fc84a 254
255is_deeply(
f7fd22b6 256 $options->handles, {
257 'add_options' => 'push',
258 'remove_last_option' => 'pop',
259 'remove_first_option' => 'shift',
260 'insert_options' => 'unshift',
261 'get_option_at' => 'get',
262 'set_option_at' => 'set',
263 'num_options' => 'count',
264 'has_no_options' => 'is_empty',
265 'clear_options' => 'clear',
266 'splice_options' => 'splice',
267 'sort_options_in_place' => 'sort_in_place',
268 'option_accessor' => 'accessor',
269 'all_options' => 'elements',
270 'first_option' => 'first',
271 'mapped_options' => 'map',
3c573ca4 272 'add_options_with_speed' => [ 'push' => 'funrolls', 'funbuns' ],
d50fc84a 273 'prepend_prerequisites_along_with' =>
3c573ca4 274 [ 'unshift' => 'first', 'second' ],
275 'descending_options' => [ 'sort_in_place' => $sort ],
d50fc84a 276 },
277 '... got the right handles mapping'
278);
279
280is( $options->type_constraint->type_parameter, 'Str',
281 '... got the right container type' );
a28e50e4 282
283done_testing;