Batch
=====

Regular cases
-------------

Batch object:

  >>> from zeam.utils.batch.batch import Batch
  >>> l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
  >>> b = Batch(l, count=4)

This verify the provided interface:

  >>> from zope.interface.verify import verifyObject
  >>> from zeam.utils.batch.interfaces import IBatch
  >>> verifyObject(IBatch, b)
  True

Now test access:

  >>> b[0]
  1
  >>> b[3]
  4
  >>> b[4]
  Traceback (most recent call last):
  ...
  IndexError: invalid index

  >>> for n in b:
  ...   print n
  1
  2
  3
  4

You can have the number of items you can iter on:

  >>> len(b)
  4

Test a batch with a start value:

  >>> b = Batch(l, start=4, count=4)

And access on it:

  >>> b[0]
  5
  >>> b[3]
  8
  >>> b[4]
  Traceback (most recent call last):
    ...
  IndexError: invalid index


Negative index are forbidden:

  >>> b[-1]
  Traceback (most recent call last):
    ...
  IndexError: invalid index

And test iterator on this one:

  >>> for n in b:
  ...   print n
  5
  6
  7
  8
  >>> len(b)
  4

Test batch methods:

  >>> b.first
  0
  >>> b.last
  8
  >>> for i in b.all():
  ...   print i
  (0, 1)
  (4, 2)
  (8, 3)
  >>> b.batch_length()
  3

Test end of list iteration:

  >>> b = Batch(l, start=8, count=4)
  >>> for n in b:
  ...   print n
  9
  0

In this case the length of the batch will be smaller:

  >>> len(b)
  2

If start is after count, well you should see nothing:

  >>> b = Batch(l, start=120, count=4)
  >>> for n in b:
  ...   print n

  >>> len(b)
  0


Test empty batch:

  >>> b = Batch([])
  >>> for n in b.all():
  ...   print n
  >>> b.first
  0
  >>> b.last
  0
  >>> b.batch_length()
  0

Special cases
-------------

Batch with one element:

  >>> b = Batch(['a',], count=10)
  >>> for n in b.all():
  ...   print n
  (0, 1)
  >>> b.first
  0
  >>> b.last
  0
  >>> b.batch_length()
  1
  >>> len(b)
  1

A batch with a n element, n being count + 1:

  >>> b = Batch(['a', 'b', 'c', 'd', 'e'], count=2)
  >>> for n in b.all():
  ...   print n
  (0, 1)
  (2, 2)
  (4, 3)
  >>> b.first
  0
  >>> b.last
  4
  >>> b.batch_length()
  3

Factory
-------

A batch that will be used by the iterator to wrapper each element:

  >>> b = Batch(['a', 'b', 'c', 'd', 'e'], count=2, factory=lambda x: x*2)
  >>> list(b)
  ['aa', 'bb']


Direct access should call the factory as well:

  >>> b[0]
  'aa'
  >>> b[1]
  'bb'
