dm-core 0.10.2 → 1.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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