sundbp-extlib 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
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