array-hooked 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+
2
+ class ::Array::Hooked < ::Array
3
+ end
4
+
5
+ class ::HookedArray < ::Array::Hooked
6
+ end
@@ -0,0 +1,27 @@
1
+
2
+ basepath = 'hooked'
3
+
4
+ files = [
5
+
6
+ 'array_interface'
7
+
8
+ ]
9
+
10
+ second_basepath = '../hooked_array'
11
+
12
+ second_files = [
13
+
14
+ 'array_interface'
15
+
16
+ ]
17
+
18
+
19
+ files.each do |this_file|
20
+ require_relative( File.join( basepath, this_file ) + '.rb' )
21
+ end
22
+ second_files.each do |this_file|
23
+ require_relative( File.join( second_basepath, this_file ) + '.rb' )
24
+ end
25
+
26
+ require_relative( basepath + '.rb' )
27
+ require_relative( second_basepath + '.rb' )
@@ -0,0 +1,2 @@
1
+
2
+ require_relative '../array-hooked.rb'
@@ -0,0 +1,6 @@
1
+
2
+ class ::HookedArray < ::Array::Hooked
3
+
4
+ include ::HookedArray::Interface
5
+
6
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module ::HookedArray::Interface
3
+
4
+ instances_identify_as!( ::HookedArray )
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ # Initialize with reference a configuration instance.
11
+ # @param [Object] object Object that HookedArray instance is attached to, primarily useful for
12
+ # reference from hooks.
13
+ # @param [Array<Object>] args Parameters passed through super to Array#initialize.
14
+ # @return [true,false] Whether receiver identifies as object.
15
+ def initialize( configuration_instance = nil, *args )
16
+
17
+ @configuration_instance = configuration_instance
18
+
19
+ super( *args )
20
+
21
+ end
22
+
23
+ ############################
24
+ # configuration_instance #
25
+ ############################
26
+
27
+ attr_accessor :configuration_instance
28
+
29
+ end
@@ -0,0 +1,758 @@
1
+
2
+ require_relative '../../lib/array-hooked.rb'
3
+
4
+ describe ::Array::Hooked do
5
+
6
+ ################
7
+ # initialize #
8
+ ################
9
+
10
+ it 'can add initialize with an ancestor, inheriting its values and linking to it as a child' do
11
+
12
+ hooked_array = ::Array::Hooked.new
13
+
14
+ hooked_array.instance_variable_get( :@parent_composite_object ).should == nil
15
+ hooked_array.should == [ ]
16
+ hooked_array.push( :A, :B, :C, :D )
17
+
18
+ end
19
+
20
+ #########
21
+ # []= #
22
+ #########
23
+
24
+ it 'can add elements' do
25
+
26
+ hooked_array = ::Array::Hooked.new
27
+
28
+ hooked_array[ 0 ] = :A
29
+ hooked_array.should == [ :A ]
30
+
31
+ hooked_array[ 1 ] = :B
32
+ hooked_array.should == [ :A, :B ]
33
+
34
+ hooked_array[ 0 ] = :D
35
+ hooked_array.should == [ :D, :B ]
36
+
37
+ end
38
+
39
+ ############
40
+ # insert #
41
+ ############
42
+
43
+ it 'can insert elements' do
44
+
45
+ hooked_array = ::Array::Hooked.new
46
+
47
+ hooked_array.insert( 3, :D )
48
+ hooked_array.should == [ nil, nil, nil, :D ]
49
+
50
+ hooked_array.insert( 1, :B )
51
+ hooked_array.should == [ nil, :B, nil, nil, :D ]
52
+
53
+ hooked_array.insert( 2, :C )
54
+ hooked_array.should == [ nil, :B, :C, nil, nil, :D ]
55
+
56
+ end
57
+
58
+ ##########
59
+ # push #
60
+ # << #
61
+ ##########
62
+
63
+ it 'can add elements' do
64
+
65
+ hooked_array = ::Array::Hooked.new
66
+
67
+ hooked_array << :A
68
+ hooked_array.should == [ :A ]
69
+
70
+ hooked_array << :B
71
+ hooked_array.should == [ :A, :B ]
72
+
73
+ end
74
+
75
+ ############
76
+ # concat #
77
+ # + #
78
+ ############
79
+
80
+ it 'can add elements' do
81
+
82
+ # NOTE: this breaks + by causing it to modify the array like +=
83
+ # The alternative was worse.
84
+
85
+ hooked_array = ::Array::Hooked.new
86
+
87
+ hooked_array.concat( [ :A ] )
88
+ hooked_array.should == [ :A ]
89
+
90
+ hooked_array += [ :B ]
91
+ hooked_array.should == [ :A, :B ]
92
+
93
+ end
94
+
95
+ ####################
96
+ # delete_objects #
97
+ ####################
98
+
99
+ it 'can delete multiple elements' do
100
+
101
+ hooked_array = ::Array::Hooked.new
102
+
103
+ hooked_array += [ :A, :B ]
104
+ hooked_array.should == [ :A, :B ]
105
+
106
+ hooked_array.delete_objects( :A, :B )
107
+ hooked_array.should == [ ]
108
+
109
+ end
110
+
111
+ #######
112
+ # - #
113
+ #######
114
+
115
+ it 'can exclude elements' do
116
+
117
+ hooked_array = ::Array::Hooked.new
118
+
119
+ hooked_array.push( :A )
120
+ hooked_array.should == [ :A ]
121
+
122
+ hooked_array -= [ :A ]
123
+ hooked_array.should == [ ]
124
+
125
+ hooked_array.push( :B )
126
+ hooked_array.should == [ :B ]
127
+
128
+ end
129
+
130
+ ############
131
+ # delete #
132
+ ############
133
+
134
+ it 'can delete elements' do
135
+
136
+ hooked_array = ::Array::Hooked.new
137
+
138
+ hooked_array.push( :A )
139
+ hooked_array.should == [ :A ]
140
+
141
+ hooked_array.delete( :A )
142
+ hooked_array.should == [ ]
143
+
144
+ hooked_array.push( :B )
145
+ hooked_array.should == [ :B ]
146
+
147
+ end
148
+
149
+ ###############
150
+ # delete_at #
151
+ ###############
152
+
153
+ it 'can delete by indexes' do
154
+
155
+ hooked_array = ::Array::Hooked.new
156
+
157
+ hooked_array.push( :A )
158
+ hooked_array.should == [ :A ]
159
+
160
+ hooked_array.delete_at( 0 )
161
+ hooked_array.should == [ ]
162
+
163
+ hooked_array.push( :B )
164
+ hooked_array.should == [ :B ]
165
+
166
+ end
167
+
168
+ #######################
169
+ # delete_at_indexes #
170
+ #######################
171
+
172
+ it 'can delete by indexes' do
173
+
174
+ hooked_array = ::Array::Hooked.new
175
+
176
+ hooked_array.push( :A, :B, :C )
177
+ hooked_array.should == [ :A, :B, :C ]
178
+
179
+ hooked_array.delete_at_indexes( 0, 1 )
180
+ hooked_array.should == [ :C ]
181
+
182
+ end
183
+
184
+ ###############
185
+ # delete_if #
186
+ ###############
187
+
188
+ it 'can delete by block' do
189
+
190
+ hooked_array = ::Array::Hooked.new
191
+
192
+ hooked_array.push( :A, :B, :C )
193
+ hooked_array.should == [ :A, :B, :C ]
194
+ hooked_array.delete_if do |object|
195
+ object != :C
196
+ end
197
+ hooked_array.should == [ :C ]
198
+
199
+ hooked_array.delete_if.is_a?( Enumerator ).should == true
200
+
201
+ end
202
+
203
+ #############
204
+ # keep_if #
205
+ #############
206
+
207
+ it 'can keep by block' do
208
+
209
+ hooked_array = ::Array::Hooked.new
210
+
211
+ hooked_array.push( :A, :B, :C )
212
+ hooked_array.should == [ :A, :B, :C ]
213
+ hooked_array.keep_if do |object|
214
+ object == :C
215
+ end
216
+ hooked_array.should == [ :C ]
217
+
218
+ end
219
+
220
+ ##############
221
+ # compact! #
222
+ ##############
223
+
224
+ it 'can compact' do
225
+
226
+ hooked_array = ::Array::Hooked.new
227
+
228
+ hooked_array.push( :A, nil, :B, nil, :C, nil )
229
+ hooked_array.should == [ :A, nil, :B, nil, :C, nil ]
230
+ hooked_array.compact!
231
+ hooked_array.should == [ :A, :B, :C ]
232
+
233
+ end
234
+
235
+ ##############
236
+ # flatten! #
237
+ ##############
238
+
239
+ it 'can flatten' do
240
+
241
+ hooked_array = ::Array::Hooked.new
242
+
243
+ hooked_array.push( :A, [ :F_A, :F_B ], :B, [ :F_C ], :C, [ :F_D ], [ :F_E ] )
244
+ hooked_array.should == [ :A, [ :F_A, :F_B ], :B, [ :F_C ], :C, [ :F_D ], [ :F_E ] ]
245
+ hooked_array.flatten!
246
+ hooked_array.should == [ :A, :F_A, :F_B, :B, :F_C, :C, :F_D, :F_E ]
247
+
248
+ end
249
+
250
+ #############
251
+ # reject! #
252
+ #############
253
+
254
+ it 'can reject' do
255
+
256
+ hooked_array = ::Array::Hooked.new
257
+
258
+ hooked_array.push( :A, :B, :C )
259
+ hooked_array.should == [ :A, :B, :C ]
260
+ hooked_array.reject! do |object|
261
+ object != :C
262
+ end
263
+ hooked_array.should == [ :C ]
264
+
265
+ end
266
+
267
+ #############
268
+ # replace #
269
+ #############
270
+
271
+ it 'can replace self' do
272
+
273
+ hooked_array = ::Array::Hooked.new
274
+
275
+ hooked_array.push( :A, :B, :C )
276
+ hooked_array.should == [ :A, :B, :C ]
277
+ hooked_array.replace( [ :D, :E, :F ] )
278
+ hooked_array.should == [ :D, :E, :F ]
279
+
280
+ end
281
+
282
+ ##############
283
+ # reverse! #
284
+ ##############
285
+
286
+ it 'can reverse self' do
287
+
288
+ hooked_array = ::Array::Hooked.new
289
+
290
+ hooked_array.push( :A, :B, :C )
291
+ hooked_array.should == [ :A, :B, :C ]
292
+ hooked_array.reverse!
293
+ hooked_array.should == [ :C, :B, :A ]
294
+
295
+ end
296
+
297
+ #############
298
+ # rotate! #
299
+ #############
300
+
301
+ it 'can rotate self' do
302
+
303
+ hooked_array = ::Array::Hooked.new
304
+
305
+ hooked_array.push( :A, :B, :C )
306
+ hooked_array.should == [ :A, :B, :C ]
307
+
308
+ hooked_array.rotate!
309
+ hooked_array.should == [ :B, :C, :A ]
310
+
311
+ hooked_array.rotate!( -1 )
312
+ hooked_array.should == [ :A, :B, :C ]
313
+
314
+ end
315
+
316
+ #############
317
+ # select! #
318
+ #############
319
+
320
+ it 'can keep by select' do
321
+
322
+ hooked_array = ::Array::Hooked.new
323
+
324
+ hooked_array.push( :A, :B, :C )
325
+ hooked_array.should == [ :A, :B, :C ]
326
+ hooked_array.select! do |object|
327
+ object == :C
328
+ end
329
+ hooked_array.should == [ :C ]
330
+
331
+ hooked_array.select!.is_a?( Enumerator ).should == true
332
+
333
+ end
334
+
335
+ ##############
336
+ # shuffle! #
337
+ ##############
338
+
339
+ it 'can shuffle self' do
340
+
341
+ hooked_array = ::Array::Hooked.new
342
+
343
+ hooked_array.push( :A, :B, :C )
344
+ hooked_array.should == [ :A, :B, :C ]
345
+
346
+ prior_version = hooked_array.dup
347
+ attempts = [ ]
348
+ 50.times do
349
+ hooked_array.shuffle!
350
+ attempts.push( hooked_array == prior_version )
351
+ prior_version = hooked_array.dup
352
+ end
353
+ attempts_correct = attempts.select { |member| member == false }.count
354
+ ( attempts_correct >= 10 ).should == true
355
+ first_shuffle_version = hooked_array
356
+
357
+ end
358
+
359
+ ##############
360
+ # collect! #
361
+ # map! #
362
+ ##############
363
+
364
+ it 'can replace by collect/map' do
365
+
366
+ hooked_array = ::Array::Hooked.new
367
+
368
+ hooked_array.push( :A, :B, :C )
369
+ hooked_array.should == [ :A, :B, :C ]
370
+ hooked_array.collect! do |object|
371
+ :C
372
+ end
373
+ hooked_array.should == [ :C, :C, :C ]
374
+
375
+ hooked_array.collect!.is_a?( Enumerator ).should == true
376
+
377
+ end
378
+
379
+ ###########
380
+ # sort! #
381
+ ###########
382
+
383
+ it 'can replace by collect/map' do
384
+
385
+ hooked_array = ::Array::Hooked.new
386
+
387
+ hooked_array.push( :A, :B, :C )
388
+ hooked_array.should == [ :A, :B, :C ]
389
+ hooked_array.sort! do |a, b|
390
+ if a < b
391
+ 1
392
+ elsif a > b
393
+ -1
394
+ elsif a == b
395
+ 0
396
+ end
397
+ end
398
+ hooked_array.should == [ :C, :B, :A ]
399
+
400
+ hooked_array.sort!
401
+ hooked_array.should == [ :A, :B, :C ]
402
+
403
+ end
404
+
405
+ ##############
406
+ # sort_by! #
407
+ ##############
408
+
409
+ it 'can replace by collect/map' do
410
+
411
+ hooked_array = ::Array::Hooked.new
412
+
413
+ hooked_array.push( :A, :B, :C )
414
+ hooked_array.should == [ :A, :B, :C ]
415
+ hooked_array.sort_by! do |object|
416
+ case object
417
+ when :A
418
+ :B
419
+ when :B
420
+ :A
421
+ when :C
422
+ :C
423
+ end
424
+ end
425
+ hooked_array.should == [ :B, :A, :C ]
426
+
427
+ hooked_array.sort_by!.is_a?( Enumerator ).should == true
428
+
429
+ end
430
+
431
+ ###########
432
+ # uniq! #
433
+ ###########
434
+
435
+ it 'can remove non-unique elements' do
436
+
437
+ hooked_array = ::Array::Hooked.new
438
+
439
+ hooked_array.push( :A, :B, :C, :C, :C, :B, :A )
440
+ hooked_array.should == [ :A, :B, :C, :C, :C, :B, :A ]
441
+ hooked_array.uniq!
442
+ hooked_array.should == [ :A, :B, :C ]
443
+
444
+ end
445
+
446
+ #############
447
+ # unshift #
448
+ #############
449
+
450
+ it 'can unshift onto the first element' do
451
+
452
+ hooked_array = ::Array::Hooked.new
453
+
454
+ hooked_array += :A
455
+ hooked_array.should == [ :A ]
456
+
457
+ hooked_array.unshift( :B )
458
+ hooked_array.should == [ :B, :A ]
459
+
460
+ end
461
+
462
+ #########
463
+ # pop #
464
+ #########
465
+
466
+ it 'can pop the final element' do
467
+
468
+ hooked_array = ::Array::Hooked.new
469
+
470
+ hooked_array += :A
471
+ hooked_array.should == [ :A ]
472
+
473
+ hooked_array.pop.should == :A
474
+ hooked_array.should == [ ]
475
+
476
+ hooked_array += :B
477
+ hooked_array.should == [ :B ]
478
+
479
+ end
480
+
481
+ ###########
482
+ # shift #
483
+ ###########
484
+
485
+ it 'can shift the first element' do
486
+
487
+ hooked_array = ::Array::Hooked.new
488
+
489
+ hooked_array += :A
490
+ hooked_array.should == [ :A ]
491
+
492
+ hooked_array.shift.should == :A
493
+ hooked_array.should == [ ]
494
+
495
+ hooked_array += :B
496
+ hooked_array.should == [ :B ]
497
+
498
+ end
499
+
500
+ ############
501
+ # slice! #
502
+ ############
503
+
504
+ it 'can slice elements' do
505
+
506
+ hooked_array = ::Array::Hooked.new
507
+
508
+ hooked_array += :A
509
+ hooked_array.should == [ :A ]
510
+
511
+ hooked_array.slice!( 0, 1 ).should == [ :A ]
512
+ hooked_array.should == [ ]
513
+
514
+ hooked_array += :B
515
+ hooked_array.should == [ :B ]
516
+
517
+ end
518
+
519
+ ###########
520
+ # clear #
521
+ ###########
522
+
523
+ it 'can clear, causing present elements to be excluded' do
524
+
525
+ hooked_array = ::Array::Hooked.new
526
+
527
+ hooked_array += :A
528
+ hooked_array.should == [ :A ]
529
+
530
+ hooked_array.clear
531
+ hooked_array.should == [ ]
532
+
533
+ hooked_array += :B
534
+ hooked_array.should == [ :B ]
535
+
536
+ end
537
+
538
+ ##################
539
+ # pre_set_hook #
540
+ ##################
541
+
542
+ it 'has a hook that is called before setting a value; return value is used in place of object' do
543
+
544
+ class ::Array::Hooked::SubMockPreSet < ::Array::Hooked
545
+
546
+ def pre_set_hook( index, object, is_insert = false )
547
+ return :some_other_value
548
+ end
549
+
550
+ end
551
+
552
+ hooked_array = ::Array::Hooked::SubMockPreSet.new
553
+
554
+ hooked_array.push( :some_value )
555
+
556
+ hooked_array.should == [ :some_other_value ]
557
+
558
+ end
559
+
560
+ ###################
561
+ # post_set_hook #
562
+ ###################
563
+
564
+ it 'has a hook that is called after setting a value' do
565
+
566
+ class ::Array::Hooked::SubMockPostSet < ::Array::Hooked
567
+
568
+ def post_set_hook( index, object, is_insert = false )
569
+ return :some_other_value
570
+ end
571
+
572
+ end
573
+
574
+ hooked_array = ::Array::Hooked::SubMockPostSet.new
575
+
576
+ hooked_array.push( :some_value ).should == [ :some_other_value ]
577
+
578
+ hooked_array.should == [ :some_value ]
579
+
580
+ end
581
+
582
+ ##################
583
+ # pre_get_hook #
584
+ ##################
585
+
586
+ it 'has a hook that is called before getting a value; if return value is false, get does not occur' do
587
+
588
+ class ::Array::Hooked::SubMockPreGet < ::Array::Hooked
589
+
590
+ def pre_get_hook( index )
591
+ return false
592
+ end
593
+
594
+ end
595
+
596
+ hooked_array = ::Array::Hooked::SubMockPreGet.new
597
+
598
+ hooked_array.push( :some_value )
599
+ hooked_array[ 0 ].should == nil
600
+
601
+ hooked_array.should == [ :some_value ]
602
+
603
+ end
604
+
605
+ ###################
606
+ # post_get_hook #
607
+ ###################
608
+
609
+ it 'has a hook that is called after getting a value' do
610
+
611
+ class ::Array::Hooked::SubMockPostGet < ::Array::Hooked
612
+
613
+ def post_get_hook( index, object )
614
+ return :some_other_value
615
+ end
616
+
617
+ end
618
+
619
+ hooked_array = ::Array::Hooked::SubMockPostGet.new
620
+
621
+ hooked_array.push( :some_value )
622
+ hooked_array[ 0 ].should == :some_other_value
623
+
624
+ hooked_array.should == [ :some_value ]
625
+
626
+ end
627
+
628
+ #####################
629
+ # pre_delete_hook #
630
+ #####################
631
+
632
+ it 'has a hook that is called before deleting an index; if return value is false, delete does not occur' do
633
+
634
+ class ::Array::Hooked::SubMockPreDelete < ::Array::Hooked
635
+
636
+ def pre_delete_hook( index )
637
+ return false
638
+ end
639
+
640
+ end
641
+
642
+ hooked_array = ::Array::Hooked::SubMockPreDelete.new
643
+
644
+ hooked_array.push( :some_value )
645
+ hooked_array.delete_at( 0 )
646
+
647
+ hooked_array.should == [ :some_value ]
648
+
649
+ end
650
+
651
+ ######################
652
+ # post_delete_hook #
653
+ ######################
654
+
655
+ it 'has a hook that is called after deleting an index' do
656
+
657
+ class ::Array::Hooked::SubMockPostDelete < ::Array::Hooked
658
+
659
+ def post_delete_hook( index, object )
660
+ return :some_other_value
661
+ end
662
+
663
+ end
664
+
665
+ hooked_array = ::Array::Hooked::SubMockPostDelete.new
666
+
667
+ hooked_array.push( :some_value )
668
+ hooked_array.delete_at( 0 ).should == :some_other_value
669
+
670
+ hooked_array.should == [ ]
671
+
672
+ end
673
+
674
+ ########################
675
+ # child_pre_set_hook #
676
+ ########################
677
+
678
+ it 'has a hook that is called before setting a value that has been passed by a parent; return value is used in place of object' do
679
+
680
+ class ::Array::Hooked::SubMockChildPreSet < ::Array::Hooked
681
+
682
+ def child_pre_set_hook( index, object, is_insert = false )
683
+ return :some_other_value
684
+ end
685
+
686
+ end
687
+
688
+ hooked_array = ::Array::Hooked::SubMockChildPreSet.new
689
+ hooked_array.push( :some_value )
690
+
691
+ end
692
+
693
+ #########################
694
+ # child_post_set_hook #
695
+ #########################
696
+
697
+ it 'has a hook that is called after setting a value passed by a parent' do
698
+
699
+ class ::Array::Hooked::SubMockChildPostSet < ::Array::Hooked
700
+
701
+ def child_post_set_hook( index, object, is_insert = false )
702
+ push( :some_other_value )
703
+ end
704
+
705
+ end
706
+
707
+ hooked_array = ::Array::Hooked::SubMockChildPostSet.new
708
+ hooked_array.push( :some_value )
709
+
710
+ hooked_array.should == [ :some_value ]
711
+
712
+ end
713
+
714
+ ###########################
715
+ # child_pre_delete_hook #
716
+ ###########################
717
+
718
+ it 'has a hook that is called before deleting an index that has been passed by a parent; if return value is false, delete does not occur' do
719
+
720
+ class ::Array::Hooked::SubMockChildPreDelete < ::Array::Hooked
721
+
722
+ def child_pre_delete_hook( index )
723
+ false
724
+ end
725
+
726
+ end
727
+
728
+ hooked_array = ::Array::Hooked::SubMockChildPreDelete.new
729
+ hooked_array.push( :some_value )
730
+ hooked_array.delete( :some_value )
731
+
732
+ hooked_array.should == [ ]
733
+
734
+ end
735
+
736
+ ############################
737
+ # child_post_delete_hook #
738
+ ############################
739
+
740
+ it 'has a hook that is called after deleting an index passed by a parent' do
741
+
742
+ class ::Array::Hooked::SubMockChildPostDelete < ::Array::Hooked
743
+
744
+ def child_post_delete_hook( index, object )
745
+ delete( :some_other_value )
746
+ end
747
+
748
+ end
749
+
750
+ hooked_array = ::Array::Hooked::SubMockChildPostDelete.new
751
+ hooked_array.push( :some_value )
752
+ hooked_array.delete( :some_value )
753
+
754
+ hooked_array.should == [ ]
755
+
756
+ end
757
+
758
+ end