""" Tests for Stack """

import unittest
from stack import Stack


class TestEmptyStack(unittest.TestCase):
    """ Test behaviour of an empty stack """

    def setUp(self):
        """ Set up an empty stack """
        self.stack = Stack()

    def tearDown(self):
        """ Clean up """
        self.stack = None

    def testIsEmpty(self):
        """ Test is_empty() on an empty stack """
        # self.assertEqual(self.stack.is_empty(), True)  # specific to unittest
        assert self.stack.is_empty(), \
            'is_empty returned False on an empty stack'

    def testAdd(self):
        """ Test adding to an empty stack """
        self.stack.add('cats')
        assert self.stack.remove() == 'cats', \
            'wrong item on the top of the stack'


class TestManyItemStack(unittest.TestCase):
    """ Test behaviour of a stack with many items """

    def setUp(self):
        """ Set up an empty stack """
        self.stack = Stack()

    def tearDown(self):
        """ Clean up """
        self.stack = None

    def testAddingRemovingMultiple(self):
        """ Test adding and removing multiple elements """

        for item in range(20):
            self.stack.add(item)
            assert not self.stack.is_empty(), \
                'is_empty() returned True on a non-empty Stack!'

        expected = 19
        while not self.stack.is_empty():
            actual = self.stack.remove()
            assert actual == expected, \
                ('Something wrong on top of the Stack! Expected ' +
                 str(expected) + ', got ' + str(actual) + '.')
            expected -= 1

if __name__ == '__main__':
    unittest.main(exit=False)
