robsharp-extlib 0.9.15

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