from unittest import TestCase
import sys
from random import randint

from nose.tools import raises

from softwaretesting import fixedsizequeue


MAXINT = sys.maxint
MININT = -sys.maxint - 1


class TestFixedSizeQueue(TestCase):
def setUp(self):
self.size = 10
self.items = [randint(MININT, MAXINT) for item in range(self.size)]
self.q = fixedsizequeue.FixedsizeQueue(self.size)
return

def test_enqueue(self):
"""
The enqueue takes a single integer and returns True if added.
"""

self.q.reset()
self.assertFalse(self.q.full())
for index, item in enumerate(self.items):
self.assertTrue(self.q.enqueue(item))
self.assertEqual(index + 1, self.q.size)
self.assertEqual(item, self.q.data[index])
self.assertEqual((index + 1) % len(self.items), self.q.tail)
self.assertFalse(self.q.empty())
self.assertTrue(self.q.full())
return

def test_dequeue(self):
"""
The dequeue returns the oldest item or None.
"""

self.q.reset()
self.assertIsNone(self.q.dequeue())
self.assertEqual(0, self.q.size)
for item in self.items:
self.q.enqueue(item)

for expected in self.items:
actual = self.q.dequeue()
self.assertEqual(expected, actual)
self.assertTrue(self.q.empty())
self.assertEqual(0, self.q.head)
return

def test_reset(self):
"""
The reset resets the pointers and count
"""

self.q.enqueue(9)
self.q.enqueue(8)
self.q.dequeue()
self.q.reset()
self.assertTrue(self.q.empty())
self.assertEqual(0, self.q.size)
self.assertEqual(0, self.q.tail)
self.assertEqual(0, self.q.head)
return

def test_empty(self):
"""
If the queue is empty dequeue returns False and does nothing.
"""

q = fixedsizequeue.FixedsizeQueue(3)
self.assertTrue(q.empty())
q.enqueue(randint(MININT, MAXINT))
self.assertFalse(q.empty())
q.dequeue()
self.assertTrue(q.empty())
return

def test_overfull(self):
"""
The array doesn't add items once full
"""

self.q.reset()

for item in self.items:
self.q.enqueue(item)
self.assertEqual(0, self.q.tail)
self.assertTrue(self.q.full())
self.assertEqual(len(self.items), self.q.size)
self.assertFalse(self.q.enqueue(1))
self.assertEqual(len(self.items), self.q.size)
self.assertEqual(self.q.size, self.q.max)

for item in self.items:
self.assertEqual(item, self.q.dequeue())
self.assertTrue(self.q.empty())

return

@raises(TypeError)
def test_non_int(self):
"""
The array has to be homogeneous.
"""

self.q.enqueue(1.0)
return
# end class TestFixedSizeQueue