sundbp-extlib 0.9.14

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