robsharp-extlib 0.9.15

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