Standardize use of Test::Exception before converting to Test::Fatal
[gitmo/Moose.git] / t / 070_native_traits / 010_trait_array.t
CommitLineData
e3c07b19 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
8b9641b8 6use lib 't/lib';
7
a7821be5 8use Moose ();
bbeb5798 9use Moose::Util::TypeConstraints;
8b9641b8 10use NoInlineAttribute;
a28e50e4 11use Test::More;
53a4d826 12use Test::Exception;
37ecda0d 13use Test::Moose;
d50fc84a 14
e3c07b19 15{
a7821be5 16 my %handles = (
17 count => 'count',
18 elements => 'elements',
19 is_empty => 'is_empty',
20 push => 'push',
21 push_curried =>
22 [ push => 42, 84 ],
23 unshift => 'unshift',
24 unshift_curried =>
25 [ unshift => 42, 84 ],
26 pop => 'pop',
27 shift => 'shift',
28 get => 'get',
29 get_curried => [ get => 1 ],
30 set => 'set',
31 set_curried_1 => [ set => 1 ],
32 set_curried_2 => [ set => ( 1, 98 ) ],
33 accessor => 'accessor',
34 accessor_curried_1 => [ accessor => 1 ],
35 accessor_curried_2 => [ accessor => ( 1, 90 ) ],
36 clear => 'clear',
37 delete => 'delete',
38 delete_curried => [ delete => 1 ],
39 insert => 'insert',
40 insert_curried => [ insert => ( 1, 101 ) ],
41 splice => 'splice',
42 splice_curried_1 => [ splice => 1 ],
43 splice_curried_2 => [ splice => 1, 2 ],
44 splice_curried_all => [ splice => 1, 2, ( 3, 4, 5 ) ],
45 sort => 'sort',
46 sort_curried => [ sort => ( sub { $_[1] <=> $_[0] } ) ],
47 sort_in_place => 'sort_in_place',
48 sort_in_place_curried =>
49 [ sort_in_place => ( sub { $_[1] <=> $_[0] } ) ],
50 map => 'map',
51 map_curried => [ map => ( sub { $_ + 1 } ) ],
52 grep => 'grep',
53 grep_curried => [ grep => ( sub { $_ < 5 } ) ],
54 first => 'first',
55 first_curried => [ first => ( sub { $_ % 2 } ) ],
56 join => 'join',
57 join_curried => [ join => '-' ],
58 shuffle => 'shuffle',
59 uniq => 'uniq',
60 reduce => 'reduce',
61 reduce_curried => [ reduce => ( sub { $_[0] * $_[1] } ) ],
62 natatime => 'natatime',
63 natatime_curried => [ natatime => 2 ],
e3c07b19 64 );
a7821be5 65
66 my $name = 'Foo1';
67
68 sub build_class {
69 my %attr = @_;
70
71 my $class = Moose::Meta::Class->create(
72 $name++,
73 superclasses => ['Moose::Object'],
74 );
75
8b9641b8 76 my @traits = 'Array';
77 push @traits, 'NoInlineAttribute'
78 if delete $attr{no_inline};
79
a7821be5 80 $class->add_attribute(
81 _values => (
8b9641b8 82 traits => \@traits,
a7821be5 83 is => 'rw',
84 isa => 'ArrayRef[Int]',
85 default => sub { [] },
86 handles => \%handles,
87 clearer => '_clear_values',
88 %attr,
89 ),
90 );
91
92 return ( $class->name, \%handles );
93 }
e3c07b19 94}
95
862b6081 96{
88e88a7b 97 package Overloader;
98
99 use overload
100 '&{}' => sub { ${ $_[0] } },
101 bool => sub {1};
102
103 sub new {
104 bless \$_[1], $_[0];
105 }
106}
107
108{
a7821be5 109 run_tests(build_class);
110 run_tests( build_class( lazy => 1, default => sub { [ 42, 84 ] } ) );
cf0da4e2 111 run_tests( build_class( trigger => sub { } ) );
8b9641b8 112 run_tests( build_class( no_inline => 1 ) );
bbeb5798 113
114 # Will force the inlining code to check the entire arrayref when it is modified.
115 subtype 'MyArrayRef', as 'ArrayRef', where { 1 };
116
117 run_tests( build_class( isa => 'MyArrayRef' ) );
118
119 coerce 'MyArrayRef', from 'ArrayRef', via { $_ };
120
121 run_tests( build_class( isa => 'MyArrayRef', coerce => 1 ) );
a7821be5 122}
e3c07b19 123
a7821be5 124sub run_tests {
125 my ( $class, $handles ) = @_;
e3c07b19 126
a7821be5 127 can_ok( $class, $_ ) for sort keys %{$handles};
e3c07b19 128
a7821be5 129 with_immutable {
130 my $obj = $class->new( _values => [ 10, 12, 42 ] );
e3c07b19 131
a7821be5 132 is_deeply(
133 $obj->_values, [ 10, 12, 42 ],
134 'values can be set in constructor'
135 );
e3c07b19 136
a7821be5 137 ok( !$obj->is_empty, 'values is not empty' );
138 is( $obj->count, 3, 'count returns 3' );
e3c07b19 139
53a4d826 140 throws_ok { $obj->count(22) }
a7821be5 141 qr/Cannot call count with any arguments/,
e3181911 142 'throws an error when passing an argument passed to count';
e3c07b19 143
53a4d826 144 lives_ok { $obj->push( 1, 2, 3 ) }
a7821be5 145 'pushed three new values and lived';
e3c07b19 146
53a4d826 147 lives_ok { $obj->push() } 'call to push without arguments lives';
e3c07b19 148
53a4d826 149 lives_and {
7f5ec80d 150 is( $obj->unshift( 101, 22 ), 8,
151 'unshift returns size of the new array' );
53a4d826 152 }
a7821be5 153 'unshifted two values and lived';
e3c07b19 154
e32b7489 155 is_deeply(
156 $obj->_values, [ 101, 22, 10, 12, 42, 1, 2, 3 ],
157 'unshift changed the value of the array in the object'
158 );
159
53a4d826 160 lives_ok { $obj->unshift() }
a7821be5 161 'call to unshift without arguments lives';
e3c07b19 162
a7821be5 163 is( $obj->pop, 3, 'pop returns the last value in the array' );
910684ee 164
a7821be5 165 is_deeply(
166 $obj->_values, [ 101, 22, 10, 12, 42, 1, 2 ],
167 'pop changed the value of the array in the object'
168 );
910684ee 169
53a4d826 170 throws_ok { $obj->pop(42) }
a7821be5 171 qr/Cannot call pop with any arguments/,
172 'call to pop with arguments dies';
910684ee 173
a7821be5 174 is( $obj->shift, 101, 'shift returns the first value' );
910684ee 175
53a4d826 176 throws_ok { $obj->shift(42) }
a7821be5 177 qr/Cannot call shift with any arguments/,
178 'call to shift with arguments dies';
e3c07b19 179
a7821be5 180 is_deeply(
181 $obj->_values, [ 22, 10, 12, 42, 1, 2 ],
182 'shift changed the value of the array in the object'
183 );
e3c07b19 184
a7821be5 185 is_deeply(
186 [ $obj->elements ], [ 22, 10, 12, 42, 1, 2 ],
187 'call to elements returns values as a list'
188 );
e3c07b19 189
53a4d826 190 throws_ok { $obj->elements(22) }
a7821be5 191 qr/Cannot call elements with any arguments/,
e3181911 192 'throws an error when passing an argument passed to elements';
e3c07b19 193
a7821be5 194 $obj->_values( [ 1, 2, 3 ] );
e3c07b19 195
a7821be5 196 is( $obj->get(0), 1, 'get values at index 0' );
197 is( $obj->get(1), 2, 'get values at index 1' );
198 is( $obj->get(2), 3, 'get values at index 2' );
199 is( $obj->get_curried, 2, 'get_curried returns value at index 1' );
e3c07b19 200
53a4d826 201 throws_ok { $obj->get() }
a7821be5 202 qr/Cannot call get without at least 1 argument/,
203 'throws an error when get is called without any arguments';
e3c07b19 204
53a4d826 205 throws_ok { $obj->get( {} ) }
e3181911 206 qr/The index passed to get must be an integer/,
a7821be5 207 'throws an error when get is called with an invalid argument';
e3c07b19 208
53a4d826 209 throws_ok { $obj->get(2.2) }
e3181911 210 qr/The index passed to get must be an integer/,
a7821be5 211 'throws an error when get is called with an invalid argument';
e3c07b19 212
53a4d826 213 throws_ok { $obj->get('foo') }
e3181911 214 qr/The index passed to get must be an integer/,
a7821be5 215 'throws an error when get is called with an invalid argument';
e3c07b19 216
53a4d826 217 throws_ok { $obj->get_curried(2) }
a7821be5 218 qr/Cannot call get with more than 1 argument/,
219 'throws an error when get_curried is called with an argument';
e3c07b19 220
53a4d826 221 lives_and {
7f5ec80d 222 is( $obj->set( 1, 100 ), 100, 'set returns new value' );
53a4d826 223 }
7f5ec80d 224 'set value at index 1 lives';
e3c07b19 225
a7821be5 226 is( $obj->get(1), 100, 'get value at index 1 returns new value' );
e3c07b19 227
7f5ec80d 228
53a4d826 229 throws_ok { $obj->set( 1, 99, 42 ) }
a7821be5 230 qr/Cannot call set with more than 2 arguments/,
231 'throws an error when set is called with three arguments';
59de9de4 232
53a4d826 233 lives_ok { $obj->set_curried_1(99) } 'set_curried_1 lives';
59de9de4 234
a7821be5 235 is( $obj->get(1), 99, 'get value at index 1 returns new value' );
59de9de4 236
53a4d826 237 throws_ok { $obj->set_curried_1( 99, 42 ) }
a7821be5 238 qr/Cannot call set with more than 2 arguments/,
239 'throws an error when set_curried_1 is called with two arguments';
59de9de4 240
53a4d826 241 lives_ok { $obj->set_curried_2 } 'set_curried_2 lives';
59de9de4 242
a7821be5 243 is( $obj->get(1), 98, 'get value at index 1 returns new value' );
59de9de4 244
53a4d826 245 throws_ok { $obj->set_curried_2(42) }
a7821be5 246 qr/Cannot call set with more than 2 arguments/,
247 'throws an error when set_curried_2 is called with one argument';
59de9de4 248
a7821be5 249 is(
250 $obj->accessor(1), 98,
251 'accessor with one argument returns value at index 1'
252 );
59de9de4 253
53a4d826 254 lives_and {
7f5ec80d 255 is( $obj->accessor( 1 => 97 ), 97, 'accessor returns new value' );
53a4d826 256 }
7f5ec80d 257 'accessor as writer lives';
59de9de4 258
a7821be5 259 is(
260 $obj->get(1), 97,
261 'accessor set value at index 1'
262 );
862b6081 263
53a4d826 264 throws_ok { $obj->accessor( 1, 96, 42 ) }
a7821be5 265 qr/Cannot call accessor with more than 2 arguments/,
266 'throws an error when accessor is called with three arguments';
59de9de4 267
a7821be5 268 is(
269 $obj->accessor_curried_1, 97,
270 'accessor_curried_1 returns expected value when called with no arguments'
271 );
59de9de4 272
53a4d826 273 lives_ok { $obj->accessor_curried_1(95) }
a7821be5 274 'accessor_curried_1 as writer lives';
862b6081 275
a7821be5 276 is(
277 $obj->get(1), 95,
278 'accessor_curried_1 set value at index 1'
279 );
862b6081 280
53a4d826 281 throws_ok { $obj->accessor_curried_1( 96, 42 ) }
a7821be5 282 qr/Cannot call accessor with more than 2 arguments/,
283 'throws an error when accessor_curried_1 is called with two arguments';
862b6081 284
53a4d826 285 lives_ok { $obj->accessor_curried_2 }
a7821be5 286 'accessor_curried_2 as writer lives';
862b6081 287
a7821be5 288 is(
289 $obj->get(1), 90,
290 'accessor_curried_2 set value at index 1'
291 );
862b6081 292
53a4d826 293 throws_ok { $obj->accessor_curried_2(42) }
a7821be5 294 qr/Cannot call accessor with more than 2 arguments/,
295 'throws an error when accessor_curried_2 is called with one argument';
862b6081 296
53a4d826 297 lives_ok { $obj->clear } 'clear lives';
862b6081 298
a7821be5 299 ok( $obj->is_empty, 'values is empty after call to clear' );
862b6081 300
a7821be5 301 $obj->set( 0 => 42 );
862b6081 302
53a4d826 303 throws_ok { $obj->clear(50) }
a7821be5 304 qr/Cannot call clear with any arguments/,
305 'throws an error when clear is called with an argument';
862b6081 306
a7821be5 307 ok(
308 !$obj->is_empty,
309 'values is not empty after failed call to clear'
310 );
59de9de4 311
53a4d826 312 throws_ok { $obj->is_empty(50) }
8b9641b8 313 qr/Cannot call is_empty with any arguments/,
314 'throws an error when is_empty is called with an argument';
315
a7821be5 316 $obj->clear;
7f5ec80d 317 is(
318 $obj->push( 1, 5, 10, 42 ), 4,
319 'pushed 4 elements, got number of elements in the array back'
320 );
59de9de4 321
53a4d826 322 lives_and {
7f5ec80d 323 is( $obj->delete(2), 10, 'delete returns deleted value' );
53a4d826 324 }
7f5ec80d 325 'delete lives';
59de9de4 326
a7821be5 327 is_deeply(
328 $obj->_values, [ 1, 5, 42 ],
329 'delete removed the specified element'
330 );
e3c07b19 331
53a4d826 332 throws_ok { $obj->delete( 2, 3 ) }
a7821be5 333 qr/Cannot call delete with more than 1 argument/,
334 'throws an error when delete is called with two arguments';
59de9de4 335
53a4d826 336 lives_ok { $obj->delete_curried } 'delete_curried lives';
910684ee 337
a7821be5 338 is_deeply(
339 $obj->_values, [ 1, 42 ],
340 'delete removed the specified element'
341 );
910684ee 342
53a4d826 343 throws_ok { $obj->delete_curried(2) }
a7821be5 344 qr/Cannot call delete with more than 1 argument/,
345 'throws an error when delete_curried is called with one argument';
e3c07b19 346
53a4d826 347 lives_ok { $obj->insert( 1, 21 ) } 'insert lives';
910684ee 348
a7821be5 349 is_deeply(
350 $obj->_values, [ 1, 21, 42 ],
351 'insert added the specified element'
352 );
910684ee 353
53a4d826 354 throws_ok { $obj->insert( 1, 22, 44 ) }
a7821be5 355 qr/Cannot call insert with more than 2 arguments/,
356 'throws an error when insert is called with three arguments';
59de9de4 357
53a4d826 358 lives_and {
7f5ec80d 359 is_deeply(
360 [ $obj->splice( 1, 0, 2, 3 ) ],
361 [],
362 'return value of splice is empty list when not removing elements'
363 );
53a4d826 364 }
7f5ec80d 365 'splice lives';
910684ee 366
a7821be5 367 is_deeply(
368 $obj->_values, [ 1, 2, 3, 21, 42 ],
369 'splice added the specified elements'
370 );
910684ee 371
53a4d826 372 lives_and {
7f5ec80d 373 is_deeply(
374 [ $obj->splice( 1, 2, 99 ) ],
375 [ 2, 3 ],
376 'splice returns list of removed values'
377 );
53a4d826 378 }
7f5ec80d 379 'splice lives';
e3c07b19 380
a7821be5 381 is_deeply(
7f5ec80d 382 $obj->_values, [ 1, 99, 21, 42 ],
a7821be5 383 'splice added the specified elements'
384 );
e3c07b19 385
53a4d826 386 throws_ok { $obj->splice() }
a7821be5 387 qr/Cannot call splice without at least 1 argument/,
388 'throws an error when splice is called with no arguments';
910684ee 389
53a4d826 390 throws_ok { $obj->splice( 1, 'foo', ) }
e3181911 391 qr/The length argument passed to splice must be an integer/,
392 'throws an error when splice is called with an invalid length';
393
53a4d826 394 lives_ok { $obj->splice_curried_1( 2, 101 ) }
a7821be5 395 'splice_curried_1 lives';
910684ee 396
a7821be5 397 is_deeply(
7f5ec80d 398 $obj->_values, [ 1, 101, 42 ],
a7821be5 399 'splice added the specified elements'
400 );
59de9de4 401
53a4d826 402 lives_ok { $obj->splice_curried_2(102) } 'splice_curried_2 lives';
862b6081 403
a7821be5 404 is_deeply(
7f5ec80d 405 $obj->_values, [ 1, 102 ],
a7821be5 406 'splice added the specified elements'
407 );
862b6081 408
53a4d826 409 lives_ok { $obj->splice_curried_all } 'splice_curried_all lives';
862b6081 410
a7821be5 411 is_deeply(
412 $obj->_values, [ 1, 3, 4, 5 ],
413 'splice added the specified elements'
414 );
59de9de4 415
7f5ec80d 416 is_deeply(
417 scalar $obj->splice( 1, 2 ),
418 4,
419 'splice in scalar context returns last element removed'
420 );
421
422 is_deeply(
423 scalar $obj->splice( 1, 0, 42 ),
424 undef,
425 'splice in scalar context returns undef when no elements are removed'
426 );
427
a7821be5 428 $obj->_values( [ 3, 9, 5, 22, 11 ] );
862b6081 429
a7821be5 430 is_deeply(
431 [ $obj->sort ], [ 11, 22, 3, 5, 9 ],
432 'sort returns sorted values'
433 );
862b6081 434
a7821be5 435 is_deeply(
436 [ $obj->sort( sub { $_[0] <=> $_[1] } ) ], [ 3, 5, 9, 11, 22 ],
437 'sort returns values sorted by provided function'
438 );
910684ee 439
53a4d826 440 throws_ok { $obj->sort(1) }
e3181911 441 qr/The argument passed to sort must be a code reference/,
442 'throws an error when passing a non coderef to sort';
910684ee 443
53a4d826 444 throws_ok {
a7821be5 445 $obj->sort( sub { }, 27 );
53a4d826 446 }
a7821be5 447 qr/Cannot call sort with more than 1 argument/,
e3181911 448 'throws an error when passing two arguments to sort';
910684ee 449
a7821be5 450 $obj->_values( [ 3, 9, 5, 22, 11 ] );
862b6081 451
a7821be5 452 $obj->sort_in_place;
d50fc84a 453
a7821be5 454 is_deeply(
455 $obj->_values, [ 11, 22, 3, 5, 9 ],
456 'sort_in_place sorts values'
457 );
862b6081 458
a7821be5 459 $obj->sort_in_place( sub { $_[0] <=> $_[1] } );
862b6081 460
a7821be5 461 is_deeply(
462 $obj->_values, [ 3, 5, 9, 11, 22 ],
463 'sort_in_place with function sorts values'
464 );
465
53a4d826 466 throws_ok {
e3181911 467 $obj->sort_in_place( 27 );
53a4d826 468 }
e3181911 469 qr/The argument passed to sort_in_place must be a code reference/,
470 'throws an error when passing a non coderef to sort_in_place';
471
53a4d826 472 throws_ok {
a7821be5 473 $obj->sort_in_place( sub { }, 27 );
53a4d826 474 }
a7821be5 475 qr/Cannot call sort_in_place with more than 1 argument/,
e3181911 476 'throws an error when passing two arguments to sort_in_place';
a7821be5 477
478 $obj->_values( [ 3, 9, 5, 22, 11 ] );
479
480 $obj->sort_in_place_curried;
481
482 is_deeply(
483 $obj->_values, [ 22, 11, 9, 5, 3 ],
484 'sort_in_place_curried sorts values'
485 );
486
53a4d826 487 throws_ok { $obj->sort_in_place_curried(27) }
a7821be5 488 qr/Cannot call sort_in_place with more than 1 argument/,
e3181911 489 'throws an error when passing one argument passed to sort_in_place_curried';
a7821be5 490
491 $obj->_values( [ 1 .. 5 ] );
492
493 is_deeply(
494 [ $obj->map( sub { $_ + 1 } ) ],
495 [ 2 .. 6 ],
496 'map returns the expected values'
497 );
498
53a4d826 499 throws_ok { $obj->map }
a7821be5 500 qr/Cannot call map without at least 1 argument/,
e3181911 501 'throws an error when passing no arguments to map';
a7821be5 502
53a4d826 503 throws_ok {
a7821be5 504 $obj->map( sub { }, 2 );
53a4d826 505 }
a7821be5 506 qr/Cannot call map with more than 1 argument/,
e3181911 507 'throws an error when passing two arguments to map';
a7821be5 508
53a4d826 509 throws_ok { $obj->map( {} ) }
e3181911 510 qr/The argument passed to map must be a code reference/,
511 'throws an error when passing a non coderef to map';
a7821be5 512
513 $obj->_values( [ 1 .. 5 ] );
514
515 is_deeply(
516 [ $obj->map_curried ],
517 [ 2 .. 6 ],
518 'map_curried returns the expected values'
519 );
520
53a4d826 521 throws_ok {
a7821be5 522 $obj->map_curried( sub { } );
53a4d826 523 }
a7821be5 524 qr/Cannot call map with more than 1 argument/,
e3181911 525 'throws an error when passing one argument passed to map_curried';
a7821be5 526
527 $obj->_values( [ 2 .. 9 ] );
528
529 is_deeply(
530 [ $obj->grep( sub { $_ < 5 } ) ],
531 [ 2 .. 4 ],
532 'grep returns the expected values'
533 );
534
53a4d826 535 throws_ok { $obj->grep }
a7821be5 536 qr/Cannot call grep without at least 1 argument/,
e3181911 537 'throws an error when passing no arguments to grep';
a7821be5 538
53a4d826 539 throws_ok {
a7821be5 540 $obj->grep( sub { }, 2 );
53a4d826 541 }
a7821be5 542 qr/Cannot call grep with more than 1 argument/,
e3181911 543 'throws an error when passing two arguments to grep';
a7821be5 544
53a4d826 545 throws_ok { $obj->grep( {} ) }
e3181911 546 qr/The argument passed to grep must be a code reference/,
547 'throws an error when passing a non coderef to grep';
a7821be5 548
88e88a7b 549 my $overloader = Overloader->new( sub { $_ < 5 } );
550 is_deeply(
551 [ $obj->grep($overloader) ],
552 [ 2 .. 4 ],
553 'grep works with obj that overload code dereferencing'
554 );
555
a7821be5 556 is_deeply(
557 [ $obj->grep_curried ],
558 [ 2 .. 4 ],
559 'grep_curried returns the expected values'
560 );
561
53a4d826 562 throws_ok {
a7821be5 563 $obj->grep_curried( sub { } );
53a4d826 564 }
a7821be5 565 qr/Cannot call grep with more than 1 argument/,
e3181911 566 'throws an error when passing one argument passed to grep_curried';
a7821be5 567
568 $obj->_values( [ 2, 4, 22, 99, 101, 6 ] );
569
570 is(
571 $obj->first( sub { $_ % 2 } ),
572 99,
573 'first returns expected value'
574 );
575
53a4d826 576 throws_ok { $obj->first }
a7821be5 577 qr/Cannot call first without at least 1 argument/,
e3181911 578 'throws an error when passing no arguments to first';
a7821be5 579
53a4d826 580 throws_ok {
a7821be5 581 $obj->first( sub { }, 2 );
53a4d826 582 }
a7821be5 583 qr/Cannot call first with more than 1 argument/,
e3181911 584 'throws an error when passing two arguments to first';
a7821be5 585
53a4d826 586 throws_ok { $obj->first( {} ) }
e3181911 587 qr/The argument passed to first must be a code reference/,
588 'throws an error when passing a non coderef to first';
a7821be5 589
590 is(
591 $obj->first_curried,
592 99,
593 'first_curried returns expected value'
594 );
595
53a4d826 596 throws_ok {
a7821be5 597 $obj->first_curried( sub { } );
53a4d826 598 }
a7821be5 599 qr/Cannot call first with more than 1 argument/,
e3181911 600 'throws an error when passing one argument passed to first_curried';
a7821be5 601
602 $obj->_values( [ 1 .. 4 ] );
603
604 is(
605 $obj->join('-'), '1-2-3-4',
606 'join returns expected result'
607 );
608
5394a1c7 609 is(
610 $obj->join(q{}), '1234',
611 'join returns expected result when joining with empty string'
612 );
613
53a4d826 614 throws_ok { $obj->join }
a7821be5 615 qr/Cannot call join without at least 1 argument/,
e3181911 616 'throws an error when passing no arguments to join';
a7821be5 617
53a4d826 618 throws_ok { $obj->join( '-', 2 ) }
a7821be5 619 qr/Cannot call join with more than 1 argument/,
e3181911 620 'throws an error when passing two arguments to join';
a7821be5 621
53a4d826 622 throws_ok { $obj->join( {} ) }
e3181911 623 qr/The argument passed to join must be a string/,
624 'throws an error when passing a non string to join';
a7821be5 625
626 is_deeply(
627 [ sort $obj->shuffle ],
628 [ 1 .. 4 ],
629 'shuffle returns all values (cannot check for a random order)'
630 );
631
53a4d826 632 throws_ok { $obj->shuffle(2) }
a7821be5 633 qr/Cannot call shuffle with any arguments/,
e3181911 634 'throws an error when passing an argument passed to shuffle';
a7821be5 635
636 $obj->_values( [ 1 .. 4, 2, 5, 3, 7, 3, 3, 1 ] );
637
638 is_deeply(
639 [ $obj->uniq ],
640 [ 1 .. 4, 5, 7 ],
641 'uniq returns expected values (in original order)'
642 );
643
53a4d826 644 throws_ok { $obj->uniq(2) }
a7821be5 645 qr/Cannot call uniq with any arguments/,
e3181911 646 'throws an error when passing an argument passed to uniq';
a7821be5 647
648 $obj->_values( [ 1 .. 5 ] );
649
650 is(
651 $obj->reduce( sub { $_[0] * $_[1] } ),
652 120,
653 'reduce returns expected value'
654 );
655
53a4d826 656 throws_ok { $obj->reduce }
a7821be5 657 qr/Cannot call reduce without at least 1 argument/,
e3181911 658 'throws an error when passing no arguments to reduce';
a7821be5 659
53a4d826 660 throws_ok {
a7821be5 661 $obj->reduce( sub { }, 2 );
53a4d826 662 }
a7821be5 663 qr/Cannot call reduce with more than 1 argument/,
e3181911 664 'throws an error when passing two arguments to reduce';
a7821be5 665
53a4d826 666 throws_ok { $obj->reduce( {} ) }
e3181911 667 qr/The argument passed to reduce must be a code reference/,
668 'throws an error when passing a non coderef to reduce';
a7821be5 669
670 is(
671 $obj->reduce_curried,
672 120,
673 'reduce_curried returns expected value'
674 );
675
53a4d826 676 throws_ok {
a7821be5 677 $obj->reduce_curried( sub { } );
53a4d826 678 }
a7821be5 679 qr/Cannot call reduce with more than 1 argument/,
e3181911 680 'throws an error when passing one argument passed to reduce_curried';
a7821be5 681
682 $obj->_values( [ 1 .. 6 ] );
683
684 my $it = $obj->natatime(2);
685 my @nat;
686 while ( my @v = $it->() ) {
687 push @nat, \@v;
688 }
689
690 is_deeply(
691 [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ],
692 \@nat,
693 'natatime returns expected iterator'
694 );
695
696 @nat = ();
697 $obj->natatime( 2, sub { push @nat, [@_] } );
698
699 is_deeply(
700 [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ],
701 \@nat,
702 'natatime with function returns expected value'
703 );
704
53a4d826 705 throws_ok { $obj->natatime( {} ) }
e3181911 706 qr/The n value passed to natatime must be an integer/,
707 'throws an error when passing a non integer to natatime';
a7821be5 708
53a4d826 709 throws_ok { $obj->natatime( 2, {} ) }
e3181911 710 qr/The second argument passed to natatime must be a code reference/,
711 'throws an error when passing a non code ref to natatime';
a7821be5 712
04bcce6a 713 $it = $obj->natatime_curried();
714 @nat = ();
a098a4a3 715 while ( my @v = $it->() ) {
716 push @nat, \@v;
717 }
718
719 is_deeply(
720 [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ],
721 \@nat,
722 'natatime_curried returns expected iterator'
723 );
724
725 @nat = ();
726 $obj->natatime_curried( sub { push @nat, [@_] } );
727
728 is_deeply(
729 [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ],
730 \@nat,
731 'natatime_curried with function returns expected value'
732 );
733
53a4d826 734 throws_ok { $obj->natatime_curried( {} ) }
e3181911 735 qr/The second argument passed to natatime must be a code reference/,
736 'throws an error when passing a non code ref to natatime_curried';
a098a4a3 737
a7821be5 738 if ( $class->meta->get_attribute('_values')->is_lazy ) {
739 my $obj = $class->new;
740
741 is( $obj->count, 2, 'count is 2 (lazy init)' );
742
743 $obj->_clear_values;
744
a098a4a3 745 is_deeply(
746 [ $obj->elements ], [ 42, 84 ],
747 'elements contains default with lazy init'
748 );
a7821be5 749
750 $obj->_clear_values;
751
752 $obj->push(2);
753
754 is_deeply(
755 $obj->_values, [ 42, 84, 2 ],
756 'push works with lazy init'
757 );
758
759 $obj->_clear_values;
760
761 $obj->unshift( 3, 4 );
762
763 is_deeply(
764 $obj->_values, [ 3, 4, 42, 84 ],
765 'unshift works with lazy init'
766 );
767 }
768 }
769 $class;
862b6081 770}
a28e50e4 771
772done_testing;