dm-core 0.10.2 → 1.0.0.rc1

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