Actually unshift curried args into @_
[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;
862b6081 11my $less;
12my $up;
13my $prod;
14
15my %handles = (
16 add_options => 'push',
17 add_options_with_speed =>
18 [ push => 'funrolls', 'funbuns' ],
19 remove_last_option => 'pop',
20 remove_first_option => 'shift',
21 insert_options => 'unshift',
22 prepend_prerequisites_along_with =>
23 [ unshift => 'first', 'second' ],
24 get_option_at => 'get',
25 set_option_at => 'set',
26 num_options => 'count',
27 options => 'elements',
28 has_no_options => 'is_empty',
29 clear_options => 'clear',
30 splice_options => 'splice',
31 sort_options_in_place => 'sort_in_place',
32 option_accessor => 'accessor',
33 descending_options =>
34 [ sort_in_place => ( $sort = sub { $_[1] <=> $_[0] } ) ],
35 map_options => 'map',
36 up_by_one => [ map => ( $up = sub { $_ + 1 } ) ],
37 filter_options => 'grep',
38 less_than_five => [ grep => ( $less = sub { $_ < 5 } ) ],
39 find_option => 'first',
40 join_options => 'join',
41 dashify => [ join => '-' ],
42 sorted_options => 'sort',
43 randomized_options => 'shuffle',
44 unique_options => 'uniq',
45 pairwise_options => [ natatime => 2 ],
46 reduce => 'reduce',
47 product => [ reduce => ( $prod = sub { $_[0] * $_[1] } ) ],
48);
d50fc84a 49
e3c07b19 50{
d50fc84a 51
e3c07b19 52 package Stuff;
53 use Moose;
54
862b6081 55 has '_options' => (
a40b446a 56 traits => ['Array'],
d50fc84a 57 is => 'ro',
58 isa => 'ArrayRef[Str]',
59 default => sub { [] },
862b6081 60 handles => \%handles,
e3c07b19 61 );
62}
63
862b6081 64{
65 my $stuff = Stuff->new( _options => [ 10, 12 ] );
66 isa_ok( $stuff, 'Stuff' );
e3c07b19 67
862b6081 68 can_ok( $stuff, $_ ) for sort keys %handles;
e3c07b19 69
862b6081 70 is_deeply( $stuff->_options, [ 10, 12 ], '... got options' );
e3c07b19 71
862b6081 72 ok( !$stuff->has_no_options, '... we have options' );
73 is( $stuff->num_options, 2, '... got 2 options' );
e3c07b19 74
862b6081 75 is( $stuff->remove_last_option, 12, '... removed the last option' );
76 is( $stuff->remove_first_option, 10, '... removed the last option' );
e3c07b19 77
862b6081 78 is_deeply( $stuff->_options, [], '... no options anymore' );
e3c07b19 79
862b6081 80 ok( $stuff->has_no_options, '... no options' );
81 is( $stuff->num_options, 0, '... got no options' );
e3c07b19 82
862b6081 83 lives_ok {
84 $stuff->add_options( 1, 2, 3 );
85 }
86 '... set the option okay';
e3c07b19 87
862b6081 88 is_deeply( $stuff->_options, [ 1, 2, 3 ], '... got options now' );
89 is_deeply(
90 [ $stuff->options ], [ 1, 2, 3 ],
91 '... got options now (with elements method)'
92 );
e3c07b19 93
862b6081 94 ok( !$stuff->has_no_options, '... has options' );
95 is( $stuff->num_options, 3, '... got 3 options' );
e3c07b19 96
862b6081 97 is( $stuff->get_option_at(0), 1, '... get option at index 0' );
98 is( $stuff->get_option_at(1), 2, '... get option at index 1' );
99 is( $stuff->get_option_at(2), 3, '... get option at index 2' );
e3c07b19 100
862b6081 101 lives_ok {
102 $stuff->set_option_at( 1, 100 );
103 }
104 '... set the option okay';
e3c07b19 105
862b6081 106 is( $stuff->get_option_at(1), 100, '... get option at index 1' );
e3c07b19 107
862b6081 108 lives_ok {
109 $stuff->add_options( 10, 15 );
110 }
111 '... set the option okay';
e3c07b19 112
862b6081 113 is_deeply(
114 $stuff->_options, [ 1, 100, 3, 10, 15 ],
115 '... got more options now'
116 );
e3c07b19 117
862b6081 118 is( $stuff->num_options, 5, '... got 5 options' );
e3c07b19 119
862b6081 120 is( $stuff->remove_last_option, 15, '... removed the last option' );
e3c07b19 121
862b6081 122 is( $stuff->num_options, 4, '... got 4 options' );
123 is_deeply(
124 $stuff->_options, [ 1, 100, 3, 10 ],
125 '... got diff options now'
126 );
e3c07b19 127
862b6081 128 lives_ok {
129 $stuff->insert_options( 10, 20 );
130 }
131 '... set the option okay';
e3c07b19 132
862b6081 133 is( $stuff->num_options, 6, '... got 6 options' );
134 is_deeply(
135 $stuff->_options, [ 10, 20, 1, 100, 3, 10 ],
136 '... got diff options now'
137 );
e3c07b19 138
862b6081 139 is( $stuff->get_option_at(0), 10, '... get option at index 0' );
140 is( $stuff->get_option_at(1), 20, '... get option at index 1' );
141 is( $stuff->get_option_at(3), 100, '... get option at index 3' );
e3c07b19 142
862b6081 143 is( $stuff->remove_first_option, 10, '... getting the first option' );
e3c07b19 144
862b6081 145 is( $stuff->num_options, 5, '... got 5 options' );
146 is( $stuff->get_option_at(0), 20, '... get option at index 0' );
e3c07b19 147
862b6081 148 $stuff->clear_options;
149 is_deeply( $stuff->_options, [], "... clear options" );
e3c07b19 150
862b6081 151 $stuff->add_options( 5, 1, 2, 3 );
152 $stuff->sort_options_in_place;
153 is_deeply(
154 $stuff->_options, [ 1, 2, 3, 5 ],
155 "... sort options in place (default sort order)"
156 );
59de9de4 157
862b6081 158 $stuff->sort_options_in_place( sub { $_[1] <=> $_[0] } );
159 is_deeply(
160 $stuff->_options, [ 5, 3, 2, 1 ],
161 "... sort options in place (descending order)"
162 );
59de9de4 163
862b6081 164 $stuff->clear_options();
165 $stuff->add_options( 5, 1, 2, 3 );
166 lives_ok {
167 $stuff->descending_options();
168 }
169 '... curried sort in place lives ok';
59de9de4 170
862b6081 171 is_deeply( $stuff->_options, [ 5, 3, 2, 1 ], "... sort currying" );
59de9de4 172
862b6081 173 throws_ok { $stuff->sort_options_in_place('foo') }
174 qr/Argument must be a code reference/,
175 'error when sort_in_place receives a non-coderef argument';
59de9de4 176
862b6081 177 $stuff->clear_options;
59de9de4 178
862b6081 179 lives_ok {
180 $stuff->add_options('tree');
181 }
182 '... set the options okay';
59de9de4 183
862b6081 184 lives_ok {
185 $stuff->add_options_with_speed( 'compatible', 'safe' );
186 }
187 '... add options with speed okay';
59de9de4 188
862b6081 189 is_deeply(
190 $stuff->_options, [qw/tree funrolls funbuns compatible safe/],
191 'check options after add_options_with_speed'
192 );
59de9de4 193
862b6081 194 lives_ok {
195 $stuff->prepend_prerequisites_along_with();
196 }
197 '... add prerequisite options okay';
198
199 $stuff->clear_options;
200 $stuff->add_options( 1, 2 );
59de9de4 201
862b6081 202 lives_ok {
203 $stuff->splice_options( 1, 0, 'foo' );
204 }
205 '... splice_options works';
59de9de4 206
862b6081 207 is_deeply(
208 $stuff->_options, [ 1, 'foo', 2 ],
209 'splice added expected option'
210 );
211
212 is(
213 $stuff->option_accessor( 1 => 'foo++' ), 'foo++',
214 'set using accessor method'
215 );
216 is( $stuff->option_accessor(1), 'foo++', 'get using accessor method' );
217
218 dies_ok {
219 $stuff->insert_options(undef);
220 }
221 '... could not add an undef where a string is expected';
222
223 dies_ok {
224 $stuff->set_option( 5, {} );
225 }
226 '... could not add a hash ref where a string is expected';
227
228 dies_ok {
229 Stuff->new( _options => [ undef, 10, undef, 20 ] );
230 }
231 '... bad constructor params';
232
233 dies_ok {
234 my $stuff = Stuff->new();
235 $stuff->add_options(undef);
236 }
237 '... rejects push of an invalid type';
238
239 dies_ok {
240 my $stuff = Stuff->new();
241 $stuff->insert_options(undef);
242 }
243 '... rejects unshift of an invalid type';
244
245 dies_ok {
246 my $stuff = Stuff->new();
247 $stuff->set_option_at( 0, undef );
248 }
249 '... rejects set of an invalid type';
250
251 dies_ok {
252 my $stuff = Stuff->new();
253 $stuff->sort_in_place_options(undef);
254 }
255 '... sort rejects arg of invalid type';
256
257 dies_ok {
258 my $stuff = Stuff->new();
259 $stuff->option_accessor();
260 }
261 '... accessor rejects 0 args';
262
263 dies_ok {
264 my $stuff = Stuff->new();
265 $stuff->option_accessor( 1, 2, 3 );
266 }
267 '... accessor rejects 3 args';
d50fc84a 268}
59de9de4 269
862b6081 270{
271 my $stuff = Stuff->new( _options => [ 1 .. 10 ] );
59de9de4 272
862b6081 273 is_deeply( $stuff->_options, [ 1 .. 10 ], '... got options' );
59de9de4 274
862b6081 275 ok( !$stuff->has_no_options, '... we have options' );
276 is( $stuff->num_options, 10, '... got 2 options' );
277 cmp_ok( $stuff->get_option_at(0), '==', 1, '... get option 0' );
e3c07b19 278
862b6081 279 is_deeply(
280 [ $stuff->filter_options( sub { $_ % 2 == 0 } ) ],
281 [ 2, 4, 6, 8, 10 ],
282 '... got the right filtered values'
283 );
59de9de4 284
862b6081 285 is_deeply(
286 [ $stuff->map_options( sub { $_ * 2 } ) ],
287 [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ],
288 '... got the right mapped values'
289 );
e3c07b19 290
862b6081 291 is(
292 $stuff->find_option( sub { $_ % 2 == 0 } ), 2,
293 '.. found the right option'
294 );
59de9de4 295
862b6081 296 is_deeply(
297 [ $stuff->options ], [ 1 .. 10 ],
298 '... got the list of options'
299 );
e3c07b19 300
862b6081 301 is(
302 $stuff->join_options(':'), '1:2:3:4:5:6:7:8:9:10',
303 '... joined the list of options by :'
304 );
e3c07b19 305
862b6081 306 is_deeply(
307 [ $stuff->sorted_options ], [ sort ( 1 .. 10 ) ],
308 '... got sorted options (default sort order)'
309 );
310 is_deeply(
311 [ $stuff->sorted_options( sub { $_[1] <=> $_[0] } ) ],
312 [ sort { $b <=> $a } ( 1 .. 10 ) ],
313 '... got sorted options (descending sort order) '
314 );
59de9de4 315
862b6081 316 throws_ok { $stuff->sorted_options('foo') }
317 qr/Argument must be a code reference/,
318 'error when sort receives a non-coderef argument';
319
320 is_deeply(
321 [ sort { $a <=> $b } $stuff->randomized_options ],
322 [ 1 .. 10 ],
323 'randomized_options returns all options'
324 );
325
326 my @pairs;
327 $stuff->pairwise_options( sub { push @pairs, [@_] } );
328 is_deeply(
329 \@pairs,
330 [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ], [ 9, 10 ] ],
331 'pairwise returns pairs as expected'
332 );
333
334 is_deeply(
335 [ $stuff->less_than_five() ], [ 1 .. 4 ],
336 'less_than_five returns 1..4'
337 );
59de9de4 338
862b6081 339 is_deeply(
340 [ $stuff->up_by_one() ], [ 2 .. 11 ],
341 'up_by_one returns 2..11'
342 );
343
344 is(
345 $stuff->dashify, '1-2-3-4-5-6-7-8-9-10',
346 'dashify returns options joined by dashes'
347 );
348
349 is(
350 $stuff->product, 3628800,
351 'product returns expected value'
352 );
353
354 my $other_stuff = Stuff->new( _options => [ 1, 1, 2, 3, 5 ] );
355 is_deeply(
356 [ $other_stuff->unique_options ], [ 1, 2, 3, 5 ],
357 'unique_options returns unique options'
358 );
d50fc84a 359}
d50fc84a 360
862b6081 361{
362 my $options = Stuff->meta->get_attribute('_options');
363 does_ok( $options, 'Moose::Meta::Attribute::Native::Trait::Array' );
364
365 is_deeply(
366 $options->handles, \%handles,
367 '... got the right handles mapping'
368 );
369
370 is(
371 $options->type_constraint->type_parameter, 'Str',
372 '... got the right container type'
373 );
374}
a28e50e4 375
376done_testing;