extlib 0.9.8 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of extlib might be problematic. Click here for more details.

Files changed (54) hide show
  1. data/History.txt +22 -0
  2. data/LICENSE +1 -1
  3. data/README +0 -0
  4. data/Rakefile +17 -12
  5. data/lib/extlib.rb +1 -1
  6. data/lib/extlib/blank.rb +51 -21
  7. data/lib/extlib/boolean.rb +1 -1
  8. data/lib/extlib/class.rb +12 -12
  9. data/lib/extlib/datetime.rb +20 -2
  10. data/lib/extlib/dictionary.rb +2 -2
  11. data/lib/extlib/hash.rb +57 -34
  12. data/lib/extlib/inflection.rb +0 -1
  13. data/lib/extlib/lazy_array.rb +327 -36
  14. data/lib/extlib/logger.rb +8 -8
  15. data/lib/extlib/mash.rb +45 -45
  16. data/lib/extlib/module.rb +1 -1
  17. data/lib/extlib/nil.rb +1 -1
  18. data/lib/extlib/numeric.rb +1 -1
  19. data/lib/extlib/object.rb +8 -21
  20. data/lib/extlib/object_space.rb +3 -3
  21. data/lib/extlib/pathname.rb +10 -0
  22. data/lib/extlib/pooling.rb +9 -17
  23. data/lib/extlib/rubygems.rb +7 -7
  24. data/lib/extlib/simple_set.rb +35 -8
  25. data/lib/extlib/string.rb +85 -42
  26. data/lib/extlib/struct.rb +10 -1
  27. data/lib/extlib/symbol.rb +11 -7
  28. data/lib/extlib/time.rb +31 -9
  29. data/lib/extlib/version.rb +1 -1
  30. data/lib/extlib/virtual_file.rb +1 -1
  31. data/spec/blank_spec.rb +85 -0
  32. data/spec/class_spec.rb +141 -0
  33. data/spec/datetime_spec.rb +22 -0
  34. data/spec/hash_spec.rb +537 -0
  35. data/spec/hook_spec.rb +1198 -0
  36. data/spec/inflection/plural_spec.rb +564 -0
  37. data/spec/inflection/singular_spec.rb +497 -0
  38. data/spec/inflection_extras_spec.rb +93 -0
  39. data/spec/lazy_array_spec.rb +1869 -0
  40. data/spec/mash_spec.rb +286 -0
  41. data/spec/module_spec.rb +58 -0
  42. data/spec/object_space_spec.rb +9 -0
  43. data/spec/object_spec.rb +114 -0
  44. data/spec/pooling_spec.rb +499 -0
  45. data/spec/simple_set_spec.rb +57 -0
  46. data/spec/spec_helper.rb +7 -0
  47. data/spec/string_spec.rb +220 -0
  48. data/spec/struct_spec.rb +12 -0
  49. data/spec/symbol_spec.rb +8 -0
  50. data/spec/time_spec.rb +22 -0
  51. data/spec/try_dup_spec.rb +45 -0
  52. data/spec/virtual_file_spec.rb +21 -0
  53. metadata +51 -26
  54. data/README.txt +0 -3
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe Extlib::Inflection do
4
+ describe "#classify" do
5
+ it 'classifies data_mapper as DataMaper' do
6
+ Extlib::Inflection.classify('data_mapper').should == 'DataMapper'
7
+ end
8
+
9
+ it "singularizes string first: classifies data_mappers as egg_and_hams as EggAndHam" do
10
+ Extlib::Inflection.classify('egg_and_hams').should == 'EggAndHam'
11
+ end
12
+ end
13
+
14
+ describe "#camelize" do
15
+ it 'camelizes data_mapper as DataMapper' do
16
+ Extlib::Inflection.camelize('data_mapper').should == 'DataMapper'
17
+ end
18
+
19
+ it "camelizes merb as Merb" do
20
+ Extlib::Inflection.camelize('merb').should == 'Merb'
21
+ end
22
+
23
+ it "camelizes data_mapper/resource as DataMapper::Resource" do
24
+ Extlib::Inflection.camelize('data_mapper/resource').should == 'DataMapper::Resource'
25
+ end
26
+
27
+ it "camelizes data_mapper/associations/one_to_many as DataMapper::Associations::OneToMany" do
28
+ Extlib::Inflection.camelize('data_mapper/associations/one_to_many').should == 'DataMapper::Associations::OneToMany'
29
+ end
30
+ end
31
+
32
+ describe "#underscore" do
33
+ it 'underscores DataMapper as data_mapper' do
34
+ Extlib::Inflection.underscore('DataMapper').should == 'data_mapper'
35
+ end
36
+
37
+ it 'underscores Merb as merb' do
38
+ Extlib::Inflection.underscore('Merb').should == 'merb'
39
+ end
40
+
41
+ it 'underscores DataMapper::Resource as data_mapper/resource' do
42
+ Extlib::Inflection.underscore('DataMapper::Resource').should == 'data_mapper/resource'
43
+ end
44
+
45
+ it 'underscores Merb::BootLoader::Rackup as merb/boot_loader/rackup' do
46
+ Extlib::Inflection.underscore('Merb::BootLoader::Rackup').should == 'merb/boot_loader/rackup'
47
+ end
48
+ end
49
+
50
+ describe "#humanize" do
51
+ it 'replaces _ with space: humanizes employee_salary as Employee salary' do
52
+ Extlib::Inflection.humanize('employee_salary').should == 'Employee salary'
53
+ end
54
+
55
+ it "strips _id endings: humanizes author_id as Author" do
56
+ Extlib::Inflection.humanize('author_id').should == 'Author'
57
+ end
58
+ end
59
+
60
+ describe "#demodulize" do
61
+ it 'demodulizes module name: DataMapper::Inflector => Inflector' do
62
+ Extlib::Inflection.demodulize('DataMapper::Inflector').should == 'Inflector'
63
+ end
64
+
65
+ it 'demodulizes module name: A::B::C::D::E => E' do
66
+ Extlib::Inflection.demodulize('A::B::C::D::E').should == 'E'
67
+ end
68
+ end
69
+
70
+ describe "#tableize" do
71
+ it 'pluralizes last word in snake_case strings: fancy_category => fancy_categories' do
72
+ Extlib::Inflection.tableize('fancy_category').should == 'fancy_categories'
73
+ end
74
+
75
+ it 'underscores CamelCase strings before pluralization: FancyCategory => fancy_categories' do
76
+ Extlib::Inflection.tableize('FancyCategory').should == 'fancy_categories'
77
+ end
78
+
79
+ it 'replaces :: with underscores: Fancy::Category => fancy_categories' do
80
+ Extlib::Inflection.tableize('Fancy::Category').should == 'fancy_categories'
81
+ end
82
+ end
83
+
84
+ describe "#foreign_key" do
85
+ it 'adds _id to downcased string: Message => message_id' do
86
+ Extlib::Inflection.foreign_key('Message').should == 'message_id'
87
+ end
88
+
89
+ it "demodulizes string first: Admin::Post => post_id" do
90
+ Extlib::Inflection.foreign_key('Admin::Post').should == 'post_id'
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,1869 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ module LazyArraySpec
4
+ module GroupMethods
5
+ def self.extended(base)
6
+ base.class_inheritable_accessor :loaded, :subject_block, :action_block
7
+ end
8
+
9
+ def subject(&block)
10
+ self.subject_block = block
11
+ end
12
+
13
+ def action(&block)
14
+ self.action_block = block
15
+ end
16
+
17
+ def should_respond_to(method)
18
+ unless loaded
19
+ it { subject.should respond_to(method) }
20
+ end
21
+ end
22
+
23
+ def should_return_expected_value(&block)
24
+ it 'should return expected value' do
25
+ action.should eql(instance_eval(&block))
26
+ end
27
+ end
28
+
29
+ def should_return_subject
30
+ should_return_kind_of(LazyArray)
31
+
32
+ it 'should return self' do
33
+ action.should equal(subject)
34
+ end
35
+ end
36
+
37
+ def should_return_kind_of(klass)
38
+ it { action.should be_a_kind_of(klass) }
39
+ end
40
+
41
+ def should_return_copy
42
+ it 'should not return self' do
43
+ action.should_not equal(subject)
44
+ end
45
+
46
+ it 'should eql self' do
47
+ action.should eql(subject.entries)
48
+ end
49
+ end
50
+
51
+ def should_return_true
52
+ it 'should return true' do
53
+ action.should be_true
54
+ end
55
+ end
56
+
57
+ def should_return_false
58
+ it 'should return false' do
59
+ action.should be_false
60
+ end
61
+ end
62
+
63
+ def should_return_nil
64
+ it 'should return nil' do
65
+ action.should be_nil
66
+ end
67
+ end
68
+
69
+ def should_raise_error(klass, message = nil)
70
+ it { lambda { action }.should raise_error(klass, message) }
71
+ end
72
+
73
+ def should_clear_subject
74
+ it 'should clear self' do
75
+ lambda { action }.should change(subject, :empty?).from(false).to(true)
76
+ end
77
+ end
78
+
79
+ def should_yield_to_each_entry
80
+ it 'should yield to each entry' do
81
+ lambda { action }.should change(@accumulator, :entries).from([]).to(subject.entries)
82
+ end
83
+ end
84
+
85
+ def should_not_change_subject
86
+ it 'should not change self' do
87
+ # XXX: the following does not work with Array#delete_if, even when nothing removed (ruby bug?)
88
+ #subject.freeze
89
+ #lambda { action }.should_not raise_error(RUBY_VERSION >= '1.9.0' ? RuntimeError : TypeError)
90
+ lambda { action }.should_not change(subject, :entries)
91
+ end
92
+ end
93
+
94
+ def should_be_a_kicker
95
+ unless loaded
96
+ it 'should be a kicker' do
97
+ lambda { action }.should change(subject, :loaded?).from(false).to(true)
98
+ end
99
+ end
100
+ end
101
+
102
+ def should_not_be_a_kicker
103
+ unless loaded
104
+ it 'should not be a kicker' do
105
+ subject.should_not be_loaded
106
+ lambda { action }.should_not change(subject, :loaded?)
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ module Methods
113
+ def subject
114
+ @subject ||= instance_eval(&self.class.subject_block)
115
+ end
116
+
117
+ def action
118
+ instance_eval(&self.class.action_block)
119
+ end
120
+ end
121
+ end
122
+
123
+ [ false, true ].each do |loaded|
124
+ describe LazyArray do
125
+ extend LazyArraySpec::GroupMethods
126
+ include LazyArraySpec::Methods
127
+
128
+ self.loaded = loaded
129
+
130
+ # message describing the object state
131
+ state = "(#{'not ' unless loaded}loaded)"
132
+
133
+ before do
134
+ @nancy = 'nancy'
135
+ @bessie = 'bessie'
136
+ @steve = 'steve'
137
+
138
+ @lazy_array = LazyArray.new
139
+ @lazy_array.load_with { |la| la.push(@nancy, @bessie) }
140
+
141
+ @other = LazyArray.new
142
+ @other.load_with { |la| la.push(@steve) }
143
+
144
+ @lazy_array.entries if loaded
145
+ end
146
+
147
+ subject { @lazy_array }
148
+
149
+ describe 'when frozen', state do
150
+ before { subject.freeze }
151
+
152
+ it 'should still be able to kick' do
153
+ lambda { subject.entries }.should_not raise_error
154
+ end
155
+
156
+ it 'should not allow any modifications' do
157
+ lambda { subject << @steve }.should raise_error(RUBY_VERSION >= '1.9.0' ? RuntimeError : TypeError)
158
+ end
159
+ end
160
+
161
+ [ :add, :<< ].each do |method|
162
+ should_respond_to(method)
163
+
164
+ describe "##{method}" do
165
+ action { subject.send(method, @steve) }
166
+
167
+ should_return_subject
168
+ should_not_be_a_kicker
169
+
170
+ it 'should append an entry' do
171
+ subject.send(method, @steve).should == [ @nancy, @bessie, @steve ]
172
+ end
173
+ end
174
+ end
175
+
176
+ should_respond_to(:any?)
177
+
178
+ describe '#any?', state do
179
+ describe 'when the subject has entries that are not loaded' do
180
+ action { subject.any? }
181
+
182
+ should_return_true
183
+ should_be_a_kicker
184
+ should_not_change_subject
185
+ end
186
+
187
+ describe 'when the subject has entries that are prepended' do
188
+ subject { LazyArray.new.unshift(@nancy) }
189
+
190
+ action { subject.any? }
191
+
192
+ should_return_true
193
+ should_not_be_a_kicker
194
+ should_not_change_subject
195
+ end
196
+
197
+ describe 'when the subject has entries that are appended' do
198
+ subject { LazyArray.new << @nancy }
199
+
200
+ action { subject.any? }
201
+
202
+ should_return_true
203
+ should_not_be_a_kicker
204
+ should_not_change_subject
205
+ end
206
+
207
+ describe 'when the subject has no entries' do
208
+ subject { LazyArray.new }
209
+
210
+ action { subject.any? }
211
+
212
+ should_return_false
213
+ should_be_a_kicker
214
+ should_not_change_subject
215
+ end
216
+ end
217
+
218
+ should_respond_to(:at)
219
+
220
+ describe '#at', state do
221
+ describe 'with positive index' do
222
+ action { subject.at(0) }
223
+
224
+ should_return_expected_value { @nancy }
225
+ should_be_a_kicker
226
+ should_not_change_subject
227
+ end
228
+
229
+ describe 'with positive index', 'after prepending to the LazyArray' do
230
+ before { subject.unshift(@steve) }
231
+
232
+ action { subject.at(0) }
233
+
234
+ should_return_expected_value { @steve }
235
+ should_not_be_a_kicker
236
+ should_not_change_subject
237
+ end
238
+
239
+ describe 'with negative index' do
240
+ action { subject.at(-1) }
241
+
242
+ should_return_expected_value { @bessie }
243
+ should_be_a_kicker
244
+ should_not_change_subject
245
+ end
246
+
247
+ describe 'with negative index', 'after appending to the LazyArray' do
248
+ before { subject.push(@steve) }
249
+
250
+ action { subject.at(-1) }
251
+
252
+ should_return_expected_value { @steve }
253
+ should_not_be_a_kicker
254
+ should_not_change_subject
255
+ end
256
+
257
+ describe 'with an index not within the LazyArray' do
258
+ action { subject.at(2) }
259
+
260
+ should_return_nil
261
+ should_be_a_kicker
262
+ should_not_change_subject
263
+ end
264
+ end
265
+
266
+ should_respond_to(:clear)
267
+
268
+ describe '#clear', state do
269
+ action { subject.clear }
270
+
271
+ should_return_subject
272
+ should_be_a_kicker # only marks as loadd, does not lazy load
273
+ should_clear_subject
274
+ end
275
+
276
+ [ :collect!, :map! ].each do |method|
277
+ it { @lazy_array.should respond_to(method) }
278
+
279
+ describe "##{method}", state do
280
+ before { @accumulator = [] }
281
+
282
+ action { subject.send(method) { |e| @accumulator << e; @steve } }
283
+
284
+ should_return_subject
285
+ should_yield_to_each_entry
286
+ should_be_a_kicker
287
+
288
+ it 'should update with the block results' do
289
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @steve, @steve ])
290
+ end
291
+ end
292
+ end
293
+
294
+ should_respond_to(:concat)
295
+
296
+ describe '#concat', state do
297
+ action { subject.concat(@other) }
298
+
299
+ should_return_subject
300
+ should_not_be_a_kicker
301
+
302
+ it 'should concatenate other Enumerable' do
303
+ subject.concat(@other).should == [ @nancy, @bessie, @steve ]
304
+ end
305
+ end
306
+
307
+ should_respond_to(:delete)
308
+
309
+ describe '#delete', state do
310
+ describe 'with an object within the LazyArray', state do
311
+ action { subject.delete(@nancy) }
312
+
313
+ should_return_expected_value { @nancy }
314
+ should_be_a_kicker
315
+
316
+ it 'should remove the matching entry' do
317
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie ])
318
+ end
319
+ end
320
+
321
+ describe 'with an object not within the LazyArray', 'without a default block' do
322
+ action { subject.delete(@steve) }
323
+
324
+ should_return_nil
325
+ should_not_change_subject
326
+ should_be_a_kicker
327
+ end
328
+
329
+ describe 'with an object not within the LazyArray', 'with a default block' do
330
+ action { subject.delete(@steve) { @steve } }
331
+
332
+ should_return_expected_value { @steve }
333
+ should_not_change_subject
334
+ should_be_a_kicker
335
+ end
336
+ end
337
+
338
+ should_respond_to(:delete_at)
339
+
340
+ describe '#delete_at', state do
341
+ describe 'with a positive index' do
342
+ action { subject.delete_at(0) }
343
+
344
+ should_return_expected_value { @nancy }
345
+ should_be_a_kicker
346
+
347
+ it 'should remove the matching entry' do
348
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie ])
349
+ end
350
+ end
351
+
352
+ describe 'with a positive index', 'after prepending to the LazyArray' do
353
+ before { subject.unshift(@steve) }
354
+
355
+ action { subject.delete_at(0) }
356
+
357
+ should_return_expected_value { @steve }
358
+ should_not_be_a_kicker
359
+
360
+ it 'should remove the matching entry' do
361
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @nancy, @bessie ])
362
+ end
363
+ end
364
+
365
+ describe 'with a negative index' do
366
+ action { subject.delete_at(-1) }
367
+
368
+ should_return_expected_value { @bessie }
369
+ should_be_a_kicker
370
+
371
+ it 'should remove the matching entry' do
372
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy ])
373
+ end
374
+ end
375
+
376
+ describe 'with a negative index', 'after appending to the LazyArray' do
377
+ before { subject.push(@steve) }
378
+
379
+ action { subject.delete_at(-1) }
380
+
381
+ should_return_expected_value { @steve }
382
+ should_not_be_a_kicker
383
+
384
+ it 'should remove the matching entry' do
385
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie ])
386
+ end
387
+ end
388
+
389
+ describe 'with an index not within the LazyArray' do
390
+ action { subject.delete_at(2) }
391
+
392
+ should_return_nil
393
+ should_not_change_subject
394
+ should_be_a_kicker
395
+ end
396
+ end
397
+
398
+ should_respond_to(:delete_if)
399
+
400
+ describe '#delete_if', state do
401
+ before { @accumulator = [] }
402
+
403
+ describe 'with a block that matches an entry' do
404
+ action { subject.delete_if { |e| @accumulator << e; true } }
405
+
406
+ should_return_subject
407
+ should_yield_to_each_entry
408
+ should_not_be_a_kicker
409
+
410
+ it 'should update with the block results' do
411
+ lambda { action }.should change(subject, :empty?).from(false).to(true)
412
+ end
413
+ end
414
+
415
+ describe 'with a block that does not match an entry' do
416
+ action { subject.delete_if { |e| @accumulator << e; false } }
417
+
418
+ should_return_subject
419
+ should_yield_to_each_entry
420
+ should_not_be_a_kicker
421
+ should_not_change_subject
422
+ end
423
+ end
424
+
425
+ should_respond_to(:dup)
426
+
427
+ describe '#dup', state do
428
+ action { subject.dup }
429
+
430
+ should_return_kind_of(LazyArray)
431
+ should_return_copy
432
+ should_not_be_a_kicker
433
+
434
+ if loaded
435
+ it 'should be loaded if subject loaded' do
436
+ action.should be_loaded
437
+ end
438
+ end
439
+ end
440
+
441
+ should_respond_to(:each)
442
+
443
+ describe '#each', state do
444
+ before { @accumulator = [] }
445
+
446
+ action { subject.each { |e| @accumulator << e } }
447
+
448
+ should_return_subject
449
+ should_yield_to_each_entry
450
+ should_be_a_kicker
451
+ should_not_change_subject
452
+ end
453
+
454
+ should_respond_to(:each_index)
455
+
456
+ describe '#each_index', state do
457
+ before { @accumulator = [] }
458
+
459
+ action { subject.each_index { |i| @accumulator << i } }
460
+
461
+ should_return_subject
462
+ should_be_a_kicker
463
+ should_not_change_subject
464
+
465
+ it 'should yield to each index' do
466
+ lambda { action }.should change(@accumulator, :entries).from([]).to([ 0, 1 ])
467
+ end
468
+ end
469
+
470
+ should_respond_to(:each_with_index)
471
+
472
+ describe '#each_with_index', state do
473
+ before { @accumulator = [] }
474
+
475
+ action { subject.each_with_index { |*args| @accumulator << args } }
476
+
477
+ should_return_subject
478
+ should_be_a_kicker
479
+ should_not_change_subject
480
+
481
+ it 'should yield to each entry and index' do
482
+ lambda { action }.should change(@accumulator, :entries).from([]).to([ [ @nancy, 0 ], [ @bessie, 1 ] ])
483
+ end
484
+ end
485
+
486
+ should_respond_to(:empty?)
487
+
488
+ describe '#empty?', state do
489
+ describe 'when the subject has entries that are not loaded' do
490
+ action { subject.empty? }
491
+
492
+ should_return_false
493
+ should_be_a_kicker
494
+ should_not_change_subject
495
+ end
496
+
497
+ describe 'when the subject has entries that are prepended' do
498
+ subject { LazyArray.new.unshift(@nancy) }
499
+
500
+ action { subject.empty? }
501
+
502
+ should_return_false
503
+ should_not_be_a_kicker
504
+ should_not_change_subject
505
+ end
506
+
507
+ describe 'when the subject has entries that are appended' do
508
+ subject { LazyArray.new << @nancy }
509
+
510
+ action { subject.empty? }
511
+
512
+ should_return_false
513
+ should_not_be_a_kicker
514
+ should_not_change_subject
515
+ end
516
+
517
+ describe 'when the subject has no entries' do
518
+ subject { LazyArray.new }
519
+
520
+ action { subject.empty? }
521
+
522
+ should_return_true
523
+ should_be_a_kicker
524
+ should_not_change_subject
525
+ end
526
+ end
527
+
528
+ should_respond_to(:eql?)
529
+
530
+ describe '#eql?', state do
531
+ describe 'with an Enumerable containing the same entries' do
532
+ action { subject.eql?([ @nancy, @bessie ]) }
533
+
534
+ should_return_true
535
+ should_be_a_kicker
536
+ should_not_change_subject
537
+ end
538
+
539
+ describe 'with an Enumerable containing different entries' do
540
+ action { subject.eql?(@other) }
541
+
542
+ should_return_false
543
+ should_be_a_kicker
544
+ should_not_change_subject
545
+ end
546
+ end
547
+
548
+ should_respond_to(:fetch)
549
+
550
+ describe '#fetch', state do
551
+ describe 'with positive index' do
552
+ action { subject.fetch(0) }
553
+
554
+ should_return_expected_value { @nancy }
555
+ should_be_a_kicker
556
+ should_not_change_subject
557
+ end
558
+
559
+ describe 'with positive index', 'after prepending to the LazyArray' do
560
+ before { subject.unshift(@steve) }
561
+
562
+ action { subject.fetch(0) }
563
+
564
+ should_return_expected_value { @steve }
565
+ should_not_be_a_kicker
566
+ should_not_change_subject
567
+ end
568
+
569
+ describe 'with negative index' do
570
+ action { subject.fetch(-1) }
571
+
572
+ should_return_expected_value { @bessie }
573
+ should_be_a_kicker
574
+ should_not_change_subject
575
+ end
576
+
577
+ describe 'with negative index', 'after appending to the LazyArray' do
578
+ before { subject.push(@steve) }
579
+
580
+ action { subject.fetch(-1) }
581
+
582
+ should_return_expected_value { @steve }
583
+ should_not_be_a_kicker
584
+ should_not_change_subject
585
+ end
586
+
587
+ describe 'with an index not within the LazyArray' do
588
+ action { subject.fetch(2) }
589
+
590
+ should_raise_error(IndexError)
591
+ end
592
+
593
+ describe 'with an index not within the LazyArray and default' do
594
+ action { subject.fetch(2, @steve) }
595
+
596
+ should_return_expected_value { @steve }
597
+ should_be_a_kicker
598
+ should_not_change_subject
599
+ end
600
+
601
+ describe 'with an index not within the LazyArray and default block' do
602
+ action { subject.fetch(2) { @steve } }
603
+
604
+ should_return_expected_value { @steve }
605
+ should_be_a_kicker
606
+ should_not_change_subject
607
+ end
608
+ end
609
+
610
+ should_respond_to(:freeze)
611
+
612
+ describe '#freeze', state do
613
+ action { subject.freeze }
614
+
615
+ should_return_subject
616
+ should_not_be_a_kicker
617
+
618
+ it { lambda { action }.should change(subject, :frozen?).from(false).to(true) }
619
+ end
620
+
621
+ should_respond_to(:first)
622
+
623
+ describe '#first', state do
624
+ describe 'with no arguments' do
625
+ action { subject.first }
626
+
627
+ should_return_expected_value { @nancy }
628
+ should_be_a_kicker
629
+ should_not_change_subject
630
+ end
631
+
632
+ describe 'with no arguments', 'after prepending to the LazyArray' do
633
+ before { subject.unshift(@steve) }
634
+
635
+ action { subject.first }
636
+
637
+ should_return_expected_value { @steve }
638
+ should_not_be_a_kicker
639
+ should_not_change_subject
640
+ end
641
+
642
+ describe 'with length specified' do
643
+ action { subject.first(1) }
644
+
645
+ it { action.should == [ @nancy ] }
646
+
647
+ should_be_a_kicker
648
+ should_not_change_subject
649
+ end
650
+
651
+ describe 'with length specified', 'after prepending to the LazyArray' do
652
+ before { subject.unshift(@steve) }
653
+
654
+ action { subject.first(1) }
655
+
656
+ it { action.should == [ @steve ] }
657
+
658
+ should_not_be_a_kicker
659
+ should_not_change_subject
660
+ end
661
+ end
662
+
663
+ should_respond_to(:include?)
664
+
665
+ describe '#include?', state do
666
+ describe 'with an included entry' do
667
+ action { subject.include?(@nancy) }
668
+
669
+ should_return_true
670
+ should_be_a_kicker
671
+ should_not_change_subject
672
+ end
673
+
674
+ describe 'with an included entry', 'after prepending to the LazyArray' do
675
+ before { subject.unshift(@steve) }
676
+
677
+ action { subject.include?(@steve) }
678
+
679
+ should_return_true
680
+ should_not_be_a_kicker
681
+ should_not_change_subject
682
+ end
683
+
684
+ describe 'with an included entry', 'after appending to the LazyArray' do
685
+ before { subject.push(@steve) }
686
+
687
+ action { subject.include?(@steve) }
688
+
689
+ should_return_true
690
+ should_not_be_a_kicker
691
+ should_not_change_subject
692
+ end
693
+
694
+ describe 'with an entry not included' do
695
+ action { subject.include?(@steve) }
696
+
697
+ should_return_false
698
+ should_be_a_kicker
699
+ should_not_change_subject
700
+ end
701
+ end
702
+
703
+ should_respond_to(:index)
704
+
705
+ describe '#index', state do
706
+ describe 'with an included entry' do
707
+ action { subject.index(@nancy) }
708
+
709
+ should_return_expected_value { 0 }
710
+ should_be_a_kicker
711
+ should_not_change_subject
712
+ end
713
+
714
+ describe 'with an included entry', 'after prepending to the LazyArray' do
715
+ before { subject.unshift(@steve) }
716
+
717
+ action { subject.index(@steve) }
718
+
719
+ should_return_expected_value { 0 }
720
+ should_not_be_a_kicker
721
+ should_not_change_subject
722
+ end
723
+
724
+ describe 'with an included entry', 'after appending to the LazyArray' do
725
+ before { subject.push(@steve) }
726
+
727
+ action { subject.index(@steve) }
728
+
729
+ should_return_expected_value { 2 }
730
+ should_be_a_kicker # need to kick because first index could be in lazy array
731
+ should_not_change_subject
732
+ end
733
+
734
+ describe 'with an entry not included' do
735
+ action { subject.index(@steve) }
736
+
737
+ should_return_nil
738
+ should_be_a_kicker
739
+ should_not_change_subject
740
+ end
741
+ end
742
+
743
+ should_respond_to(:insert)
744
+
745
+ describe '#insert', state do
746
+ describe 'with an index of 0' do
747
+ action { subject.insert(0, @steve) }
748
+
749
+ should_return_subject
750
+ should_not_be_a_kicker
751
+
752
+ it 'should insert the entries before the index' do
753
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @steve, @nancy, @bessie ])
754
+ end
755
+ end
756
+
757
+ describe 'with an positive index greater than the head size' do
758
+ action { subject.insert(1, @steve) }
759
+
760
+ should_return_subject
761
+ should_be_a_kicker
762
+
763
+ it 'should insert the entries before the index' do
764
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @steve, @bessie ])
765
+ end
766
+ end
767
+
768
+ describe 'with an index of -1' do
769
+ action { subject.insert(-1, @steve) }
770
+
771
+ should_return_subject
772
+ should_not_be_a_kicker
773
+
774
+ it 'should insert the entries before the index' do
775
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, @steve ])
776
+ end
777
+ end
778
+
779
+ describe 'with a negative index greater than the tail size' do
780
+ action { subject.insert(-2, @steve) }
781
+
782
+ should_return_subject
783
+ should_be_a_kicker
784
+
785
+ it 'should insert the entries before the index' do
786
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @steve, @bessie ])
787
+ end
788
+ end
789
+
790
+ describe 'with a positive index 1 greater than the maximum index of the LazyArray' do
791
+ action { subject.insert(2, @steve) }
792
+
793
+ should_return_subject
794
+ should_be_a_kicker
795
+
796
+ it 'should insert the entries before the index' do
797
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, @steve ])
798
+ end
799
+ end
800
+
801
+ describe 'with a positive index not within the LazyArray' do
802
+ action { subject.insert(3, @steve) }
803
+
804
+ should_return_subject
805
+ should_be_a_kicker
806
+
807
+ it 'should insert the entries before the index, expanding the LazyArray' do
808
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, nil, @steve ])
809
+ end
810
+ end
811
+
812
+ describe 'with a negative index 1 greater than the maximum index of the LazyArray' do
813
+ action { subject.insert(-3, @steve) }
814
+
815
+ should_return_subject
816
+ should_be_a_kicker
817
+
818
+ it 'should insert the entries before the index, expanding the LazyArray' do
819
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @steve, @nancy, @bessie ])
820
+ end
821
+ end
822
+
823
+ describe 'with a negative index not within the LazyArray' do
824
+ action { subject.insert(-4, @steve) }
825
+
826
+ should_raise_error(IndexError)
827
+ end
828
+ end
829
+
830
+ should_respond_to(:kind_of?)
831
+
832
+ describe '#kind_of' do
833
+ describe 'when provided a class that is a superclass' do
834
+ action { subject.kind_of?(Object) }
835
+
836
+ should_return_true
837
+ should_not_be_a_kicker
838
+ should_not_change_subject
839
+ end
840
+
841
+ describe 'when provided a class that is a proxy class superclass' do
842
+ action { subject.kind_of?(Array) }
843
+
844
+ should_return_true
845
+ should_not_be_a_kicker
846
+ should_not_change_subject
847
+ end
848
+
849
+ describe 'when provided a class that is not a superclass' do
850
+ action { subject.kind_of?(Hash) }
851
+
852
+ should_return_false
853
+ should_not_be_a_kicker
854
+ should_not_change_subject
855
+ end
856
+ end
857
+
858
+ should_respond_to(:last)
859
+
860
+ describe '#last', state do
861
+ describe 'with no arguments' do
862
+ action { subject.last }
863
+
864
+ should_return_expected_value { @bessie }
865
+ should_be_a_kicker
866
+ should_not_change_subject
867
+ end
868
+
869
+ describe 'with no arguments', 'after appending to the LazyArray' do
870
+ before { subject.push(@steve) }
871
+
872
+ action { subject.last }
873
+
874
+ should_return_expected_value { @steve }
875
+ should_not_be_a_kicker
876
+ should_not_change_subject
877
+ end
878
+
879
+ describe 'with length specified' do
880
+ action { subject.last(1) }
881
+
882
+ it { action.should == [ @bessie ] }
883
+
884
+ should_be_a_kicker
885
+ should_not_change_subject
886
+ end
887
+
888
+ describe 'with length specified', 'after appending to the LazyArray' do
889
+ before { subject.push(@steve) }
890
+
891
+ action { subject.last(1) }
892
+
893
+ it { action.should == [ @steve ] }
894
+
895
+ should_not_be_a_kicker
896
+ should_not_change_subject
897
+ end
898
+ end
899
+
900
+ should_respond_to(:loaded?)
901
+
902
+ describe '#loaded?' do
903
+ if loaded
904
+ describe 'when loaded' do
905
+ action { subject.loaded? }
906
+
907
+ should_return_true
908
+ should_not_change_subject
909
+ end
910
+ else
911
+ describe 'when not loaded' do
912
+ action { subject.loaded? }
913
+
914
+ should_return_false
915
+ should_not_change_subject
916
+ end
917
+ end
918
+ end
919
+
920
+ should_respond_to(:pop)
921
+
922
+ describe '#pop', state do
923
+ describe 'without appending to the LazyArray' do
924
+ action { subject.pop }
925
+
926
+ should_return_expected_value { @bessie }
927
+ should_be_a_kicker
928
+
929
+ it 'should remove the last entry' do
930
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy ])
931
+ end
932
+ end
933
+
934
+ describe 'after appending to the LazyArray' do
935
+ before { subject.push(@steve) }
936
+
937
+ action { subject.pop }
938
+
939
+ should_return_expected_value { @steve }
940
+ should_not_be_a_kicker
941
+
942
+ it 'should remove the last entry' do
943
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie ])
944
+ end
945
+ end
946
+ end
947
+
948
+ should_respond_to(:push)
949
+
950
+ describe '#push', state do
951
+ action { subject.push(@steve, @steve) }
952
+
953
+ should_return_subject
954
+ should_not_be_a_kicker
955
+
956
+ it 'should append entries' do
957
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, @steve, @steve ])
958
+ end
959
+ end
960
+
961
+ should_respond_to(:reject!)
962
+
963
+ describe '#reject!', state do
964
+ before { @accumulator = [] }
965
+
966
+ describe 'with a block that matches an entry' do
967
+ action { subject.reject! { |e| @accumulator << e; true } }
968
+
969
+ should_return_subject
970
+ should_yield_to_each_entry
971
+ should_be_a_kicker
972
+
973
+ it 'should update with the block results' do
974
+ lambda { action }.should change(subject, :empty?).from(false).to(true)
975
+ end
976
+ end
977
+
978
+ describe 'with a block that does not match an entry' do
979
+ action { subject.reject! { |e| @accumulator << e; false } }
980
+
981
+ should_return_nil
982
+ should_yield_to_each_entry
983
+ should_be_a_kicker
984
+ should_not_change_subject
985
+ end
986
+ end
987
+
988
+ should_respond_to(:replace)
989
+
990
+ describe '#replace' do
991
+ action { subject.replace(@other) }
992
+
993
+ should_return_subject
994
+ should_be_a_kicker
995
+
996
+ it 'should replace with other Enumerable' do
997
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @steve ])
998
+ end
999
+ end
1000
+
1001
+ should_respond_to(:reverse)
1002
+
1003
+ describe '#reverse', state do
1004
+ action { subject.reverse }
1005
+
1006
+ should_return_kind_of(LazyArray)
1007
+ should_not_be_a_kicker
1008
+ should_not_change_subject
1009
+
1010
+ it 'should return a reversed LazyArray' do
1011
+ action.should eql([ @bessie, @nancy ])
1012
+ end
1013
+ end
1014
+
1015
+ should_respond_to(:reverse!)
1016
+
1017
+ describe '#reverse!', state do
1018
+ action { subject.reverse! }
1019
+
1020
+ should_return_subject
1021
+ should_not_be_a_kicker
1022
+
1023
+ it 'should return a reversed LazyArray' do
1024
+ action.should eql([ @bessie, @nancy ])
1025
+ end
1026
+ end
1027
+
1028
+ should_respond_to(:reverse_each)
1029
+
1030
+ describe '#reverse_each', state do
1031
+ before { @accumulator = [] }
1032
+
1033
+ action { subject.reverse_each { |e| @accumulator << e } }
1034
+
1035
+ should_return_subject
1036
+ should_be_a_kicker
1037
+ should_not_change_subject
1038
+
1039
+ it 'should yield to each entry' do
1040
+ lambda { action }.should change(@accumulator, :entries).from([]).to([ @bessie, @nancy ])
1041
+ end
1042
+ end
1043
+
1044
+ should_respond_to(:rindex)
1045
+
1046
+ describe '#rindex', state do
1047
+ describe 'with an included entry' do
1048
+ action { subject.rindex(@nancy) }
1049
+
1050
+ should_return_expected_value { 0 }
1051
+ should_be_a_kicker # rindex always a kicker
1052
+ should_not_change_subject
1053
+ end
1054
+
1055
+ describe 'with an included entry', 'after prepending to the LazyArray' do
1056
+ before { subject.unshift(@steve) }
1057
+
1058
+ action { subject.rindex(@steve) }
1059
+
1060
+ should_return_expected_value { 0 }
1061
+ should_be_a_kicker # rindex always a kicker
1062
+ should_not_change_subject
1063
+ end
1064
+
1065
+ describe 'with an included entry', 'after appending to the LazyArray' do
1066
+ before { subject.push(@steve) }
1067
+
1068
+ action { subject.rindex(@steve) }
1069
+
1070
+ should_return_expected_value { 2 }
1071
+ should_be_a_kicker # rindex always a kicker
1072
+ should_not_change_subject
1073
+ end
1074
+
1075
+ describe 'with an entry not included' do
1076
+ action { subject.rindex(@steve) }
1077
+
1078
+ should_return_nil
1079
+ should_be_a_kicker # rindex always a kicker
1080
+ should_not_change_subject
1081
+ end
1082
+ end
1083
+
1084
+ should_respond_to(:shift)
1085
+
1086
+ describe '#shift', state do
1087
+ describe 'without prepending to the LazyArray' do
1088
+ action { subject.shift }
1089
+
1090
+ should_return_expected_value { @nancy }
1091
+ should_be_a_kicker
1092
+
1093
+ it 'should remove the last entry' do
1094
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie ])
1095
+ end
1096
+ end
1097
+
1098
+ describe 'after prepending to the LazyArray' do
1099
+ before { subject.unshift(@steve) }
1100
+
1101
+ action { subject.shift }
1102
+
1103
+ should_return_expected_value { @steve }
1104
+ should_not_be_a_kicker
1105
+
1106
+ it 'should remove the last entry' do
1107
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @nancy, @bessie ])
1108
+ end
1109
+ end
1110
+ end
1111
+
1112
+ [ :slice, :[] ].each do |method|
1113
+ should_respond_to(method)
1114
+
1115
+ describe "##{method}", state do
1116
+ describe 'with a positive index' do
1117
+ action { subject.send(method, 0) }
1118
+
1119
+ should_return_expected_value { @nancy }
1120
+ should_be_a_kicker
1121
+ should_not_change_subject
1122
+ end
1123
+
1124
+ describe 'with a positive index', 'after prepending to the LazyArray' do
1125
+ before { subject.unshift(@steve) }
1126
+
1127
+ action { subject.send(method, 0) }
1128
+
1129
+ should_return_expected_value { @steve }
1130
+ should_not_be_a_kicker
1131
+ should_not_change_subject
1132
+ end
1133
+
1134
+ describe 'with a positive index and length' do
1135
+ action { subject.send(method, 0, 1) }
1136
+
1137
+ should_return_kind_of(Array)
1138
+ should_return_expected_value { [ @nancy ] }
1139
+ should_be_a_kicker
1140
+ should_not_change_subject
1141
+ end
1142
+
1143
+ describe 'with a positive index and length', 'after prepending to the LazyArray' do
1144
+ before { subject.unshift(@steve) }
1145
+
1146
+ action { subject.send(method, 0, 1) }
1147
+
1148
+ should_return_kind_of(Array)
1149
+ should_return_expected_value { [ @steve ] }
1150
+ should_not_be_a_kicker
1151
+ should_not_change_subject
1152
+ end
1153
+
1154
+ describe 'with a positive range' do
1155
+ action { subject.send(method, 0..0) }
1156
+
1157
+ should_return_kind_of(Array)
1158
+ should_return_expected_value { [ @nancy ] }
1159
+ should_be_a_kicker
1160
+ should_not_change_subject
1161
+ end
1162
+
1163
+ describe 'with a positive range', 'after prepending to the LazyArray' do
1164
+ before { subject.unshift(@steve) }
1165
+
1166
+ action { subject.send(method, 0..0) }
1167
+
1168
+ should_return_kind_of(Array)
1169
+ should_return_expected_value { [ @steve ] }
1170
+ should_not_be_a_kicker
1171
+ should_not_change_subject
1172
+ end
1173
+
1174
+ describe 'with a negative index' do
1175
+ action { subject.send(method, -1) }
1176
+
1177
+ should_return_expected_value { @bessie }
1178
+ should_be_a_kicker
1179
+ should_not_change_subject
1180
+ end
1181
+
1182
+ describe 'with a negative index', 'after appending to the LazyArray' do
1183
+ before { subject.push(@steve) }
1184
+
1185
+ action { subject.send(method, -1) }
1186
+
1187
+ should_return_expected_value { @steve }
1188
+ should_not_be_a_kicker
1189
+ should_not_change_subject
1190
+ end
1191
+
1192
+ describe 'with a negative index and length' do
1193
+ action { subject.send(method, -1, 1) }
1194
+
1195
+ should_return_kind_of(Array)
1196
+ should_return_expected_value { [ @bessie ] }
1197
+ should_be_a_kicker
1198
+ should_not_change_subject
1199
+ end
1200
+
1201
+ describe 'with a negative index and length', 'after appending to the LazyArray' do
1202
+ before { subject.push(@steve) }
1203
+
1204
+ action { subject.send(method, -1, 1) }
1205
+
1206
+ should_return_kind_of(Array)
1207
+ should_return_expected_value { [ @steve ] }
1208
+ should_not_be_a_kicker
1209
+ should_not_change_subject
1210
+ end
1211
+
1212
+ describe 'with a negative range' do
1213
+ action { subject.send(method, -1..-1) }
1214
+
1215
+ should_return_kind_of(Array)
1216
+ should_return_expected_value { [ @bessie ] }
1217
+ should_be_a_kicker
1218
+ should_not_change_subject
1219
+ end
1220
+
1221
+ describe 'with a negative range', 'after appending to the LazyArray' do
1222
+ before { subject.push(@steve) }
1223
+
1224
+ action { subject.send(method, -1..-1) }
1225
+
1226
+ should_return_kind_of(Array)
1227
+ should_return_expected_value { [ @steve ] }
1228
+ should_not_be_a_kicker
1229
+ should_not_change_subject
1230
+ end
1231
+
1232
+ describe 'with an index not within the LazyArray' do
1233
+ action { subject.send(method, 2) }
1234
+
1235
+ should_return_nil
1236
+ should_be_a_kicker
1237
+ should_not_change_subject
1238
+ end
1239
+
1240
+ describe 'with an index and length not within the LazyArray' do
1241
+ action { subject.send(method, 2, 1) }
1242
+
1243
+ should_return_kind_of(Array)
1244
+ should_return_expected_value { [] }
1245
+ should_be_a_kicker
1246
+ should_not_change_subject
1247
+ end
1248
+
1249
+ describe 'with a range not within the LazyArray' do
1250
+ action { subject.send(method, 2..2) }
1251
+
1252
+ should_return_kind_of(Array)
1253
+ should_return_expected_value { [] }
1254
+ should_be_a_kicker
1255
+ should_not_change_subject
1256
+ end
1257
+
1258
+ describe 'with invalid arguments' do
1259
+ action { subject.send(method, 1, 1..1) }
1260
+
1261
+ should_raise_error(ArgumentError)
1262
+ end
1263
+ end
1264
+ end
1265
+
1266
+ should_respond_to(:slice!)
1267
+
1268
+ describe '#slice!', state do
1269
+ describe 'with a positive index' do
1270
+ action { subject.slice!(0) }
1271
+
1272
+ should_return_expected_value { @nancy }
1273
+ should_be_a_kicker
1274
+
1275
+ it 'should remove the matching entry' do
1276
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie ])
1277
+ end
1278
+ end
1279
+
1280
+ describe 'with a positive index', 'after prepending to the LazyArray' do
1281
+ before { subject.unshift(@steve) }
1282
+
1283
+ action { subject.slice!(0) }
1284
+
1285
+ should_return_expected_value { @steve }
1286
+ should_not_be_a_kicker
1287
+
1288
+ it 'should remove the matching entry' do
1289
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @nancy, @bessie ])
1290
+ end
1291
+ end
1292
+
1293
+ describe 'with a positive index and length' do
1294
+ action { subject.slice!(0, 1) }
1295
+
1296
+ should_return_kind_of(Array)
1297
+ should_return_expected_value { [ @nancy ] }
1298
+ should_be_a_kicker
1299
+
1300
+ it 'should remove the matching entries' do
1301
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie ])
1302
+ end
1303
+ end
1304
+
1305
+ describe 'with a positive index and length', 'after prepending to the LazyArray' do
1306
+ before { subject.unshift(@steve) }
1307
+
1308
+ action { subject.slice!(0, 1) }
1309
+
1310
+ should_return_kind_of(Array)
1311
+ should_return_expected_value { [ @steve ] }
1312
+ should_not_be_a_kicker
1313
+
1314
+ it 'should remove the matching entries' do
1315
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @nancy, @bessie ])
1316
+ end
1317
+ end
1318
+
1319
+ describe 'with a positive range' do
1320
+ action { subject.slice!(0..0) }
1321
+
1322
+ should_return_kind_of(Array)
1323
+ should_return_expected_value { [ @nancy ] }
1324
+ should_be_a_kicker
1325
+
1326
+ it 'should remove the matching entries' do
1327
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie ])
1328
+ end
1329
+ end
1330
+
1331
+ describe 'with a positive range', 'after prepending to the LazyArray' do
1332
+ before { subject.unshift(@steve) }
1333
+
1334
+ action { subject.slice!(0..0) }
1335
+
1336
+ should_return_kind_of(Array)
1337
+ should_return_expected_value { [ @steve ] }
1338
+ should_not_be_a_kicker
1339
+
1340
+ it 'should remove the matching entry' do
1341
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @nancy, @bessie ])
1342
+ end
1343
+ end
1344
+
1345
+ describe 'with a negative index' do
1346
+ action { subject.slice!(-1) }
1347
+
1348
+ should_return_expected_value { @bessie }
1349
+ should_be_a_kicker
1350
+
1351
+ it 'should remove the matching entries' do
1352
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy ])
1353
+ end
1354
+ end
1355
+
1356
+ describe 'with a negative index', 'after appending to the LazyArray' do
1357
+ before { subject.push(@steve) }
1358
+
1359
+ action { subject.slice!(-1) }
1360
+
1361
+ should_return_expected_value { @steve }
1362
+ should_not_be_a_kicker
1363
+
1364
+ it 'should remove the matching entries' do
1365
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie ])
1366
+ end
1367
+ end
1368
+
1369
+ describe 'with a negative index and length' do
1370
+ action { subject.slice!(-1, 1) }
1371
+
1372
+ should_return_kind_of(Array)
1373
+ should_return_expected_value { [ @bessie ] }
1374
+ should_be_a_kicker
1375
+
1376
+ it 'should remove the matching entries' do
1377
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy ])
1378
+ end
1379
+ end
1380
+
1381
+ describe 'with a negative index and length', 'after appending to the LazyArray' do
1382
+ before { subject.push(@steve) }
1383
+
1384
+ action { subject.slice!(-1, 1) }
1385
+
1386
+ should_return_kind_of(Array)
1387
+ should_return_expected_value { [ @steve ] }
1388
+ should_not_be_a_kicker
1389
+
1390
+ it 'should remove the matching entries' do
1391
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie ])
1392
+ end
1393
+ end
1394
+
1395
+ describe 'with a negative range' do
1396
+ action { subject.slice!(-1..-1) }
1397
+
1398
+ should_return_kind_of(Array)
1399
+ should_return_expected_value { [ @bessie ] }
1400
+ should_be_a_kicker
1401
+
1402
+ it 'should remove the matching entries' do
1403
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy ])
1404
+ end
1405
+ end
1406
+
1407
+ describe 'with a negative range', 'after appending to the LazyArray' do
1408
+ before { subject.push(@steve) }
1409
+
1410
+ action { subject.slice!(-1..-1) }
1411
+
1412
+ should_return_kind_of(Array)
1413
+ should_return_expected_value { [ @steve ] }
1414
+ should_not_be_a_kicker
1415
+
1416
+ it 'should remove the matching entries' do
1417
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie ])
1418
+ end
1419
+ end
1420
+
1421
+ describe 'with an index not within the LazyArray' do
1422
+ action { subject.slice!(2) }
1423
+
1424
+ should_return_nil
1425
+ should_be_a_kicker
1426
+ should_not_change_subject
1427
+ end
1428
+
1429
+ describe 'with an index and length not within the LazyArray' do
1430
+ action { subject.slice!(2, 1) }
1431
+
1432
+ should_return_kind_of(Array)
1433
+ should_return_expected_value { [] }
1434
+ should_be_a_kicker
1435
+ should_not_change_subject
1436
+ end
1437
+
1438
+ describe 'with a range not within the LazyArray' do
1439
+ action { subject.slice!(2..2) }
1440
+
1441
+ should_return_kind_of(Array)
1442
+ should_return_expected_value { [] }
1443
+ should_be_a_kicker
1444
+ should_not_change_subject
1445
+ end
1446
+ end
1447
+
1448
+ should_respond_to(:sort!)
1449
+
1450
+ describe '#sort!', state do
1451
+ describe 'without a block' do
1452
+ action { subject.sort! }
1453
+
1454
+ should_return_subject
1455
+ should_be_a_kicker
1456
+
1457
+ it 'should sort the LazyArray inline using default sort order' do
1458
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie, @nancy ])
1459
+ end
1460
+ end
1461
+
1462
+ describe 'without a block' do
1463
+ action { subject.sort! { |a,b| a <=> b } }
1464
+
1465
+ should_return_subject
1466
+ should_be_a_kicker
1467
+
1468
+ it 'should sort the LazyArray inline using block' do
1469
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @bessie, @nancy ])
1470
+ end
1471
+ end
1472
+ end
1473
+
1474
+ [ :splice, :[]= ].each do |method|
1475
+ should_respond_to(method)
1476
+
1477
+ describe "##{method}", state do
1478
+ before do
1479
+ @jon = 'jon'
1480
+ end
1481
+
1482
+ describe 'with a positive index and entry' do
1483
+ action { subject.send(method, 0, @jon) }
1484
+
1485
+ should_return_expected_value { @jon }
1486
+ should_be_a_kicker
1487
+
1488
+ it 'should change the matching entry' do
1489
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @jon, @bessie ])
1490
+ end
1491
+ end
1492
+
1493
+ describe 'with a positive index', 'after prepending to the LazyArray' do
1494
+ before { subject.unshift(@steve) }
1495
+
1496
+ action { subject.send(method, 0, @jon) }
1497
+
1498
+ should_return_expected_value { @jon }
1499
+ should_not_be_a_kicker
1500
+
1501
+ it 'should change the matching entry' do
1502
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @jon, @nancy, @bessie ])
1503
+ end
1504
+ end
1505
+
1506
+ describe 'with a positive index and length' do
1507
+ action { subject.send(method, 0, 1, [ @jon ]) }
1508
+
1509
+ should_return_kind_of(Array)
1510
+ should_return_expected_value { [ @jon ] }
1511
+ should_be_a_kicker
1512
+
1513
+ it 'should change the matching entries' do
1514
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @jon, @bessie ])
1515
+ end
1516
+ end
1517
+
1518
+ describe 'with a positive index and length', 'after prepending to the LazyArray' do
1519
+ before { subject.unshift(@steve) }
1520
+
1521
+ action { subject.send(method, 0, 1, [ @jon ]) }
1522
+
1523
+ should_return_kind_of(Array)
1524
+ should_return_expected_value { [ @jon ] }
1525
+ should_not_be_a_kicker
1526
+
1527
+ it 'should change the matching entries' do
1528
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @jon, @nancy, @bessie ])
1529
+ end
1530
+ end
1531
+
1532
+ describe 'with a positive range' do
1533
+ action { subject.send(method, 0..0, [ @jon ]) }
1534
+
1535
+ should_return_kind_of(Array)
1536
+ should_return_expected_value { [ @jon ] }
1537
+ should_be_a_kicker
1538
+
1539
+ it 'should change the matching entries' do
1540
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @jon, @bessie ])
1541
+ end
1542
+ end
1543
+
1544
+ describe 'with a positive range', 'after prepending to the LazyArray' do
1545
+ before { subject.unshift(@steve) }
1546
+
1547
+ action { subject.send(method, 0..0, [ @jon ]) }
1548
+
1549
+ should_return_kind_of(Array)
1550
+ should_return_expected_value { [ @jon ] }
1551
+ should_not_be_a_kicker
1552
+
1553
+ it 'should change the matching entry' do
1554
+ lambda { action }.should change(subject, :entries).from([ @steve, @nancy, @bessie ]).to([ @jon, @nancy, @bessie ])
1555
+ end
1556
+ end
1557
+
1558
+ describe 'with a negative index' do
1559
+ action { subject.send(method, -1, @jon) }
1560
+
1561
+ should_return_expected_value { @jon }
1562
+ should_be_a_kicker
1563
+
1564
+ it 'should change the matching entries' do
1565
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @jon ])
1566
+ end
1567
+ end
1568
+
1569
+ describe 'with a negative index', 'after appending to the LazyArray' do
1570
+ before { subject.push(@steve) }
1571
+
1572
+ action { subject.send(method, -1, @jon) }
1573
+
1574
+ should_return_expected_value { @jon }
1575
+ should_not_be_a_kicker
1576
+
1577
+ it 'should change the matching entries' do
1578
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie, @jon ])
1579
+ end
1580
+ end
1581
+
1582
+ describe 'with a negative index and length' do
1583
+ action { subject.send(method, -1, 1, [ @jon ]) }
1584
+
1585
+ should_return_kind_of(Array)
1586
+ should_return_expected_value { [ @jon ] }
1587
+ should_be_a_kicker
1588
+
1589
+ it 'should change the matching entries' do
1590
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @jon ])
1591
+ end
1592
+ end
1593
+
1594
+ describe 'with a negative index and length', 'after appending to the LazyArray' do
1595
+ before { subject.push(@steve) }
1596
+
1597
+ action { subject.send(method, -1, 1, [ @jon ]) }
1598
+
1599
+ should_return_kind_of(Array)
1600
+ should_return_expected_value { [ @jon ] }
1601
+ should_not_be_a_kicker
1602
+
1603
+ it 'should change the matching entries' do
1604
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie, @jon ])
1605
+ end
1606
+ end
1607
+
1608
+ describe 'with a negative range' do
1609
+ action { subject.send(method, -1..-1, [ @jon ]) }
1610
+
1611
+ should_return_kind_of(Array)
1612
+ should_return_expected_value { [ @jon ] }
1613
+ should_be_a_kicker
1614
+
1615
+ it 'should change the matching entries' do
1616
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @jon ])
1617
+ end
1618
+ end
1619
+
1620
+ describe 'with a negative range', 'after appending to the LazyArray' do
1621
+ before { subject.push(@steve) }
1622
+
1623
+ action { subject.send(method, -1..-1, [ @jon ]) }
1624
+
1625
+ should_return_kind_of(Array)
1626
+ should_return_expected_value { [ @jon ] }
1627
+ should_not_be_a_kicker
1628
+
1629
+ it 'should change the matching entries' do
1630
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie, @steve ]).to([ @nancy, @bessie, @jon ])
1631
+ end
1632
+ end
1633
+
1634
+ describe 'with a positive index 1 greater than the maximum index of the LazyArray' do
1635
+ action { subject.send(method, 2, @jon) }
1636
+
1637
+ should_return_expected_value { @jon }
1638
+ should_be_a_kicker
1639
+
1640
+ it 'should change the matching entries' do
1641
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, @jon ])
1642
+ end
1643
+ end
1644
+
1645
+ describe 'with a positive index not within the LazyArray' do
1646
+ action { subject.send(method, 3, @jon) }
1647
+
1648
+ should_return_expected_value { @jon }
1649
+ should_be_a_kicker
1650
+
1651
+ it 'should change the matching entries' do
1652
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, nil, @jon ])
1653
+ end
1654
+ end
1655
+
1656
+ describe 'with a negative index not within the LazyArray' do
1657
+ action { subject.send(method, -3, @jon) }
1658
+
1659
+ should_raise_error(IndexError)
1660
+ end
1661
+
1662
+ describe 'with a positive index and length 1 greater than the maximum index of the LazyArray' do
1663
+ action { subject.send(method, 2, 1, [ @jon ]) }
1664
+
1665
+ should_return_kind_of(Array)
1666
+ should_return_expected_value { [ @jon ] }
1667
+ should_be_a_kicker
1668
+
1669
+ it 'should change the matching entries' do
1670
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, @jon ])
1671
+ end
1672
+ end
1673
+
1674
+ describe 'with a positive index and length not within the LazyArray' do
1675
+ action { subject.send(method, 3, 1, [ @jon ]) }
1676
+
1677
+ should_return_kind_of(Array)
1678
+ should_return_expected_value { [ @jon ] }
1679
+ should_be_a_kicker
1680
+
1681
+ it 'should change the matching entries' do
1682
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, nil, @jon ])
1683
+ end
1684
+ end
1685
+
1686
+ describe 'with a negative index and length not within the LazyArray ' do
1687
+ action { subject.send(method, -3, 1, [ @jon ]) }
1688
+
1689
+ should_raise_error(IndexError)
1690
+ end
1691
+
1692
+ describe 'with a positive range 1 greater than the maximum index of the LazyArray' do
1693
+ action { subject.send(method, 2..2, [ @jon ]) }
1694
+
1695
+ should_return_kind_of(Array)
1696
+ should_return_expected_value { [ @jon ] }
1697
+ should_be_a_kicker
1698
+
1699
+ it 'should change the matching entries' do
1700
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, @jon ])
1701
+ end
1702
+ end
1703
+
1704
+ describe 'with a positive range not within the LazyArray' do
1705
+ action { subject.send(method, 3..3, [ @jon ]) }
1706
+
1707
+ should_return_kind_of(Array)
1708
+ should_return_expected_value { [ @jon ] }
1709
+ should_be_a_kicker
1710
+
1711
+ it 'should change the matching entries' do
1712
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @nancy, @bessie, nil, @jon ])
1713
+ end
1714
+ end
1715
+
1716
+ describe 'with a negative range not within the LazyArray' do
1717
+ action { subject.send(method, -3..-3, [ @jon ]) }
1718
+
1719
+ should_raise_error(RangeError)
1720
+ end
1721
+ end
1722
+ end
1723
+
1724
+ should_respond_to(:to_a)
1725
+
1726
+ describe '#to_a', state do
1727
+ action { subject.to_a }
1728
+
1729
+ should_return_kind_of(Array)
1730
+ should_return_copy
1731
+ should_be_a_kicker
1732
+ end
1733
+
1734
+ should_respond_to(:unshift)
1735
+
1736
+ describe '#unshift', state do
1737
+ action { subject.unshift(@steve, @steve) }
1738
+
1739
+ should_return_subject
1740
+ should_not_be_a_kicker
1741
+
1742
+ it 'should prepend entries' do
1743
+ lambda { action }.should change(subject, :entries).from([ @nancy, @bessie ]).to([ @steve, @steve, @nancy, @bessie ])
1744
+ end
1745
+ end
1746
+
1747
+ should_respond_to(:values_at)
1748
+
1749
+ describe '#values_at', state do
1750
+ describe 'with a positive index' do
1751
+ action { subject.values_at(0) }
1752
+
1753
+ should_return_kind_of(Array)
1754
+ should_return_expected_value { [ @nancy ] }
1755
+ should_be_a_kicker
1756
+ should_not_change_subject
1757
+ end
1758
+
1759
+ describe 'with a positive index', 'after prepending to the LazyArray' do
1760
+ before { subject.unshift(@steve) }
1761
+
1762
+ action { subject.values_at(0) }
1763
+
1764
+ should_return_kind_of(Array)
1765
+ should_return_expected_value { [ @steve ] }
1766
+ should_not_be_a_kicker
1767
+ should_not_change_subject
1768
+ end
1769
+
1770
+ describe 'with a positive range' do
1771
+ action { subject.values_at(0..0) }
1772
+
1773
+ should_return_kind_of(Array)
1774
+ should_return_expected_value { [ @nancy ] }
1775
+ should_be_a_kicker
1776
+ should_not_change_subject
1777
+ end
1778
+
1779
+ describe 'with a positive range', 'after prepending to the LazyArray' do
1780
+ before { subject.unshift(@steve) }
1781
+
1782
+ action { subject.values_at(0..0) }
1783
+
1784
+ should_return_kind_of(Array)
1785
+ should_return_expected_value { [ @steve ] }
1786
+ should_not_be_a_kicker
1787
+ should_not_change_subject
1788
+ end
1789
+
1790
+ describe 'with a negative index' do
1791
+ action { subject.values_at(-1) }
1792
+
1793
+ should_return_kind_of(Array)
1794
+ should_return_expected_value { [ @bessie ] }
1795
+ should_be_a_kicker
1796
+ should_not_change_subject
1797
+ end
1798
+
1799
+ describe 'with a negative index', 'after appending to the LazyArray' do
1800
+ before { subject.push(@steve) }
1801
+
1802
+ action { subject.values_at(-1) }
1803
+
1804
+ should_return_kind_of(Array)
1805
+ should_return_expected_value { [ @steve ] }
1806
+ should_not_be_a_kicker
1807
+ should_not_change_subject
1808
+ end
1809
+
1810
+ describe 'with a negative range' do
1811
+ action { subject.values_at(-1..-1) }
1812
+
1813
+ should_return_kind_of(Array)
1814
+ should_return_expected_value { [ @bessie ] }
1815
+ should_be_a_kicker
1816
+ should_not_change_subject
1817
+ end
1818
+
1819
+ describe 'with a negative range', 'after appending to the LazyArray' do
1820
+ before { subject.push(@steve) }
1821
+
1822
+ action { subject.values_at(-1..-1) }
1823
+
1824
+ should_return_kind_of(Array)
1825
+ should_return_expected_value { [ @steve ] }
1826
+ should_not_be_a_kicker
1827
+ should_not_change_subject
1828
+ end
1829
+
1830
+ describe 'with an index not within the LazyArray' do
1831
+ action { subject.values_at(2) }
1832
+
1833
+ should_return_kind_of(Array)
1834
+ should_return_expected_value { [ nil ] }
1835
+ should_be_a_kicker
1836
+ should_not_change_subject
1837
+ end
1838
+
1839
+ describe 'with a range not within the LazyArray' do
1840
+ action { subject.values_at(2..2) }
1841
+
1842
+ should_return_kind_of(Array)
1843
+ should_return_expected_value { [ nil ] }
1844
+ should_be_a_kicker
1845
+ should_not_change_subject
1846
+ end
1847
+ end
1848
+
1849
+ describe 'a method mixed into Array' do
1850
+ before :all do
1851
+ Enumerable.class_eval do
1852
+ def lazy_spec
1853
+ true
1854
+ end
1855
+ end
1856
+ end
1857
+
1858
+ it 'should delegate to the Array' do
1859
+ subject.lazy_spec.should be_true
1860
+ end
1861
+ end
1862
+
1863
+ describe 'an unknown method' do
1864
+ action { subject.unknown }
1865
+
1866
+ should_raise_error(NoMethodError)
1867
+ end
1868
+ end
1869
+ end