3
Tests for L{epsilon.view}.
6
from operator import getitem
8
from twisted.trial.unittest import TestCase
10
from epsilon.view import SlicedView
13
class SlicedViewTests(TestCase):
15
Tests for L{SlicedView}
17
def test_outOfBoundsPositiveStart(self):
19
Verify that the C{__getitem__} of a L{SlicedView} constructed with a
20
slice with a positive start value greater than the maximum allowed
21
index clips that start value to the end of the underlying sequence.
23
sequence = ['a', 'b', 'c']
24
view = SlicedView(sequence, slice(3, None))
25
self.assertRaises(IndexError, getitem, view, 0)
28
def test_outOfBoundsNegativeStart(self):
30
Verify that the C{__getitem__} of a L{SlicedView} constructed with a
31
slice with a negative start value greater than the maximum allowed
32
index clips that start value to the beginning of the underlying
35
sequence = ['a', 'b', 'c']
36
view = SlicedView(sequence, slice(-4, None))
37
self.assertEqual(view[0], 'a')
38
self.assertEqual(view[1], 'b')
39
self.assertEqual(view[2], 'c')
40
self.assertRaises(IndexError, getitem, view, 3)
43
def test_outOfBoundsPositiveStop(self):
45
Verify that the C{__getitem__} of a L{SlicedView} constructed with a
46
slice with a positve stop value greater than the maximum allowed index
47
clips that stop value to the end of the underlying sequence.
49
sequence = ['a', 'b', 'c']
50
view = SlicedView(sequence, slice(None, 4))
51
self.assertEqual(view[0], 'a')
52
self.assertEqual(view[1], 'b')
53
self.assertEqual(view[2], 'c')
54
self.assertRaises(IndexError, getitem, view, 3)
57
def test_outOfBoundsNegativeStop(self):
59
Verify that the C{__getitem__} of a L{SlicedView} constructed with a
60
slice with a negative stop value greater than the maximum allowed index
61
clips that stop value to the beginning of the underlying sequence.
63
sequence = ['a', 'b', 'c']
64
view = SlicedView(sequence, slice(None, -4))
65
self.assertRaises(IndexError, getitem, view, 0)
68
def test_positiveIndices(self):
70
Verify that the C{__getitem__} of a L{SlicedView} constructed with a
71
slice with no start or stop value behaves in the same way as the
72
underlying sequence with respect to indexing with positive values.
74
sequence = ['a', 'b', 'c']
75
view = SlicedView(sequence, slice(None))
76
self.assertEqual(view[0], 'a')
77
self.assertEqual(view[1], 'b')
78
self.assertEqual(view[2], 'c')
79
self.assertRaises(IndexError, getitem, view, 3)
82
def test_negativeIndices(self):
84
Similar to L{test_positiveIndices}, but for negative indices.
86
sequence = ['a', 'b', 'c']
87
view = SlicedView(sequence, slice(None))
88
self.assertEqual(view[-1], 'c')
89
self.assertEqual(view[-2], 'b')
90
self.assertEqual(view[-3], 'a')
91
self.assertRaises(IndexError, getitem, view, -4)
94
def test_length(self):
96
Verify that L{SlicedView.__len__} returns the length of the underlying
97
sequence when the SlicedView is constructed with no start or stop
100
sequence = ['a', 'b', 'c']
101
view = SlicedView(sequence, slice(None))
102
self.assertEqual(len(view), 3)
105
def test_lengthEmptySequence(self):
107
Verify that L{SlicedView.__len__} works with empty sequences.
110
view = SlicedView([], slice(None))
111
self.assertEqual(len(view), 0)
114
def test_positiveStartLength(self):
116
Similar to L{test_length}, but for a L{SlicedView} constructed with a
117
slice with a positive start value.
119
sequence = ['a', 'b', 'c']
120
view = SlicedView(sequence, slice(1, None))
121
self.assertEqual(len(view), 2)
124
def test_negativeStartLength(self):
126
Similar to L{test_length}, but for a L{SlicedView} constructed with a
127
slice with a negative start value.
129
sequence = ['a', 'b', 'c']
130
view = SlicedView(sequence, slice(-2, None))
131
self.assertEqual(len(view), 2)
134
def test_positiveStopLength(self):
136
Similar to L{test_length}, but for a L{SlicedView} constructed with a
137
slice with a positive stop value.
139
sequence = ['a', 'b', 'c']
140
view = SlicedView(sequence, slice(None, 2))
141
self.assertEqual(len(view), 2)
144
def test_negativeStopLength(self):
146
Similar to L{test_length}, but for a L{SlicedView} constructed with a
147
slice with a negative stop value.
149
sequence = ['a', 'b', 'c']
150
view = SlicedView(sequence, slice(None, -1))
151
self.assertEqual(len(view), 2)
154
def test_positiveStartPositiveStopLength(self):
156
Similar to L{test_length}, but for a L{SlicedView} constructed with a
157
slice with positive start and stop values.
159
sequence = ['a', 'b', 'c']
160
view = SlicedView(sequence, slice(1, 2))
161
self.assertEqual(len(view), 1)
164
def test_positiveStartNegativeStopLength(self):
166
Similar to L{test_length}, but for a L{SlicedView} constructed with a
167
slice with a positive start value and a negative stop value.
169
sequence = ['a', 'b', 'c']
170
view = SlicedView(sequence, slice(1, -1))
171
self.assertEqual(len(view), 1)
174
def test_negativeStartPositiveStopLength(self):
176
Similar to L{test_length}, but for a L{SlicedView} constructed with a
177
slice with a negative start value and a positive stop value.
179
sequence = ['a', 'b', 'c']
180
view = SlicedView(sequence, slice(-2, 2))
181
self.assertEqual(len(view), 1)
184
def test_negativeStartNegativeStopLength(self):
186
Similar to L{test_length}, but for a L{SlicedView} constructed with a
187
slice with negative start and stop values.
189
sequence = ['a', 'b', 'c']
190
view = SlicedView(sequence, slice(-2, -1))
191
self.assertEqual(len(view), 1)
194
def test_extendedSliceLength(self):
196
Verify that L{SlicedView.__len__} reports the correct length when a
199
sequence = ['a', 'b', 'c', 'd', 'e']
200
view = SlicedView(sequence, slice(1, -1, 2))
201
self.assertEqual(len(view), 2)
204
def test_positiveStartOnlyPositiveIndices(self):
206
Verify that the C{__getitem__} of a L{SlicedView} constructed with a
207
slice with only a positive start value returns elements at the
208
requested index plus the slice's start value for positive requested
211
sequence = ['a', 'b', 'c']
212
view = SlicedView(sequence, slice(1, None))
213
self.assertEqual(view[0], 'b')
214
self.assertEqual(view[1], 'c')
215
self.assertRaises(IndexError, getitem, view, 2)
218
def test_positiveStartOnlyNegativeIndices(self):
220
Similar to L{test_positiveStartOnlyPositiveIndices}, but cover
221
negative requested indices instead of positive ones.
223
sequence = ['a', 'b', 'c']
224
view = SlicedView(sequence, slice(1, None))
225
self.assertEqual(view[-1], 'c')
226
self.assertEqual(view[-2], 'b')
227
self.assertRaises(IndexError, getitem, view, -3)
230
def test_negativeStartOnlyPositiveIndices(self):
232
Similar to L{test_positiveStartOnlyPositiveIndices}, but for the case
233
of a negative slice start value.
235
sequence = ['a', 'b', 'c']
236
view = SlicedView(sequence, slice(-2, None))
237
self.assertEqual(view[0], 'b')
238
self.assertEqual(view[1], 'c')
239
self.assertRaises(IndexError, getitem, view, 2)
242
def test_negativeStartOnlyNegativeIndices(self):
244
Similar to L{test_negativeStartOnlyPositiveIndices}, but cover negative
245
requested indices instead of positive ones.
247
sequence = ['a', 'b', 'c']
248
view = SlicedView(sequence, slice(-2, None))
249
self.assertEqual(view[-1], 'c')
250
self.assertEqual(view[-2], 'b')
251
self.assertRaises(IndexError, getitem, view, -3)
254
def test_positiveStopOnlyPositiveIndices(self):
256
Verify that L{__getitem__} of L{SlicedView} constructed with a slice
257
with a positive stop value returns elements at the requested index for
258
indices less than the stop value and raises IndexError for positive
259
requested indices greater than or equal to the stop value.
261
sequence = ['a', 'b', 'c']
262
view = SlicedView(sequence, slice(None, 2))
263
self.assertEqual(view[0], 'a')
264
self.assertEqual(view[1], 'b')
265
self.assertRaises(IndexError, getitem, view, 2)
268
def test_positveStopOnlyNegativeIndices(self):
270
Similar to L{test_positiveStopOnlyPositiveIndices}, but cover negative
271
requested indices instead of positive ones.
273
sequence = ['a', 'b', 'c']
274
view = SlicedView(sequence, slice(None, 2))
275
self.assertEqual(view[-1], 'b')
276
self.assertEqual(view[-2], 'a')
277
self.assertRaises(IndexError, getitem, view, -3)
280
def test_negativeStopOnlyPositiveIndices(self):
282
Similar to L{test_positiveStopOnlyPositiveIndices}, but test a
283
L{SlicedView} created with a slice with a negative stop value.
285
sequence = ['a', 'b', 'c']
286
view = SlicedView(sequence, slice(None, -1))
287
self.assertEqual(view[0], 'a')
288
self.assertEqual(view[1], 'b')
289
self.assertRaises(IndexError, getitem, view, 2)
292
def test_negativeStopOnlyNegativeIndices(self):
294
Similar to L{test_negativeStopOnlyPositiveIndices}, but cover negative
295
requested indices instead of positive ones.
297
sequence = ['a', 'b', 'c']
298
view = SlicedView(sequence, slice(None, -1))
299
self.assertEqual(view[-1], 'b')
300
self.assertEqual(view[-2], 'a')
301
self.assertRaises(IndexError, getitem, view, -3)
304
def test_positiveStartPositiveStopPositiveIndices(self):
306
Verify that L{__getitem__} of L{SlicedView} constructed with a slice
307
with positive start and stop values returns elements at the requested
308
index plus the slice's start value for positive requested indices less
309
than the difference between the stop and start values and raises
310
IndexError for positive requested indices greater than or equal to that
313
sequence = ['a', 'b', 'c', 'd']
314
view = SlicedView(sequence, slice(1, 3))
315
self.assertEqual(view[0], 'b')
316
self.assertEqual(view[1], 'c')
317
self.assertRaises(IndexError, getitem, view, 2)
320
def test_positiveStartPositiveStopNegativeIndices(self):
322
Similar to L{test_positiveStartPositiveStopPositiveIndices}, but cover
323
negative requested indices instead of positive ones.
325
sequence = ['a', 'b', 'c', 'd']
326
view = SlicedView(sequence, slice(1, 3))
327
self.assertEqual(view[-1], 'c')
328
self.assertEqual(view[-2], 'b')
329
self.assertRaises(IndexError, getitem, view, -3)
332
def test_positiveStartNegativeStopPositiveIndices(self):
334
Verify that L{__getitem__} of a L{SlicedView} constructed with a slice
335
with a positive start and a negative stop value returns elements at the
336
requested index plus the slice's start value for positive requested
337
indices within the bounds defined by the stop value and raises an
338
IndexError for positive requested indices outside those bounds.
340
sequence = ['a', 'b', 'c']
341
view = SlicedView(sequence, slice(1, -1))
342
self.assertEqual(view[0], 'b')
343
self.assertRaises(IndexError, getitem, view, 1)
346
def test_positiveStartNegativeStopNegativeIndices(self):
348
Similar to L{test_positiveStartNegativeStopPositiveIndices}, but cover
349
negative requested indices instead of positive ones.
351
sequence = ['a', 'b', 'c']
352
view = SlicedView(sequence, slice(1, -1))
353
self.assertEqual(view[-1], 'b')
354
self.assertRaises(IndexError, getitem, view, -2)
357
def test_negativeStartPositiveStopPositiveIndices(self):
359
Similar to L{test_positiveStartNegativeStopPositiveIndices}, but for a
360
negative slice start and positive slice stop.
362
sequence = ['a', 'b', 'c']
363
view = SlicedView(sequence, slice(-2, 2))
364
self.assertEqual(view[0], 'b')
365
self.assertRaises(IndexError, getitem, view, 1)
368
def test_negativeStartPositiveStopNegativeIndices(self):
370
Similar to L{test_negativeStartPositiveStopPositiveIndices}, but cover
371
negative requested indices instead of positive ones.
373
sequence = ['a', 'b', 'c']
374
view = SlicedView(sequence, slice(-2, 2))
375
self.assertEqual(view[-1], 'b')
376
self.assertRaises(IndexError, getitem, view, -2)
379
def test_negativeStartNegativeStopPositiveIndices(self):
381
Similar to L{test_negativeStartPositiveStopPositiveIndices}, but for a
384
sequence = ['a', 'b', 'c']
385
view = SlicedView(sequence, slice(-2, -1))
386
self.assertEqual(view[0], 'b')
387
self.assertRaises(IndexError, getitem, view, 1)
390
def test_negativeStartNegativeStopNegativeIndices(self):
392
Similar to L{test_negativeStartPositiveStopPositiveIndices}, but cover
393
negative requested indices instead of positive ones.
395
sequence = ['a', 'b', 'c']
396
view = SlicedView(sequence, slice(-2, -1))
397
self.assertEqual(view[-1], 'b')
398
self.assertRaises(IndexError, getitem, view, -2)
401
def test_positiveStepPositiveIndices(self):
403
Verify that a positive step produces the correct results, skipping over
404
the appropriate elements.
406
sequence = ['a', 'b', 'c', 'd', 'e']
407
view = SlicedView(sequence, slice(1, -1, 2))
408
self.assertEqual(view[0], 'b')
409
self.assertEqual(view[1], 'd')
410
self.assertRaises(IndexError, getitem, view, 2)
413
def test_positiveStepNegativeIndices(self):
415
Verify that a negative step produces the correct results, skipping over
416
the appropriate elements.
418
sequence = ['a', 'b', 'c', 'd', 'e']
419
view = SlicedView(sequence, slice(1, -1, 2))
420
self.assertEqual(view[-1], 'd')
421
self.assertEqual(view[-2], 'b')
422
self.assertRaises(IndexError, getitem, view, -3)
425
def test_negativeStepPositiveIndices(self):
427
Verify that a negative step produces the correct results, skipping over
428
the appropriate elements.
430
sequence = ['a', 'b', 'c', 'd', 'e']
431
view = SlicedView(sequence, slice(-1, 1, -2))
432
self.assertEqual(view[0], 'e')
433
self.assertEqual(view[1], 'c')
434
self.assertRaises(IndexError, getitem, view, 2)
437
def test_negativeStepNegativeIndices(self):
439
Verify that a negative step produces the correct results, skipping over
440
the appropriate elements.
442
sequence = ['a', 'b', 'c', 'd', 'e']
443
view = SlicedView(sequence, slice(-1, 1, -2))
444
self.assertEqual(view[-1], 'c')
445
self.assertEqual(view[-2], 'e')
446
self.assertRaises(IndexError, getitem, view, -3)
449
def test_slice(self):
451
Verify a L{SlicedView} itself can be sliced.
453
sequence = ['a', 'b', 'c']
454
view = SlicedView(sequence, slice(1, None))
456
self.assertIdentical(viewView.sequence, view)
457
self.assertEqual(viewView.bounds, slice(1, None, None))