from unittest import TestCase
from datastructures import *

class TestStack(TestCase):
    def test_init_and_delete(self):
        s = AdtStack()
        self.assertEqual(None, s.top)
        s.push(35)
        self.assertNotEqual(None, s.top)
        s.__del__()
        self.assertEqual(None, s.top)

    def test_empty(self):
        s = AdtStack()
        self.assertTrue(s.is_empty())
        s.push("abc")
        self.assertFalse(s.is_empty())
        s.push("def")
        s.push("ghi")
        self.assertFalse(s.is_empty())
        s.__del__()
        self.assertTrue(s.is_empty())

    def test_push(self):
        s = AdtStack()
        s.push(25)
        with self.assertRaises(TypeError):
            s.push("abc")
        with self.assertRaises(TypeError):
            s.push("1")
        s.push(100)
        s.push(245)
        s.push(89)
        self.assertFalse(s.is_empty())

    def test_pop_and_return(self):
        s = AdtStack()
        s.push(5)
        s.push(10)
        s.push(15)
        s.push(20)
        self.assertEqual(20, s.pop_and_return())
        self.assertEqual(15, s.pop_and_return())
        self.assertEqual(10, s.pop_and_return())
        self.assertEqual(5, s.pop_and_return())
        with self.assertRaises(StopIteration):
            s.pop_and_return()
        self.assertTrue(s.is_empty())
        with self.assertRaises(StopIteration):
            s.pop_and_return()

    def test_pop_and_return_2(self):
        s = AdtStack()
        s.push(5)
        s.push(10)
        s.pop()
        s.push(45)
        s.push(15)
        self.assertEqual(15, s.pop_and_return())
        self.assertEqual(45, s.pop_and_return())
        s.push(20)
        s.pop()
        s.pop()
        s.pop()
        s.push(35)
        s.push(55)
        s.push(75)
        s.pop()
        self.assertEqual(55, s.pop_and_return())
        self.assertEqual(35, s.pop_and_return())
        with self.assertRaises(StopIteration):
            s.pop_and_return()
        self.assertTrue(s.is_empty())

    def test_peek(self):
        s = AdtStack()
        self.assertEqual(None, s.peek())
        s.push(5)
        self.assertEqual(5, s.peek())
        s.push(10)
        self.assertEqual(10, s.peek())
        s.pop()
        self.assertEqual(5, s.peek())
        s.push(45)
        self.assertEqual(45, s.peek())
        self.assertEqual(45, s.peek())
        s.push(15)
        self.assertEqual(15, s.peek())
        s.pop_and_return()
        self.assertEqual(45, s.peek())
        s.pop_and_return()
        self.assertEqual(5, s.peek())
        s.push(20)
        self.assertEqual(20, s.peek())
        s.pop()
        self.assertEqual(5, s.peek())
        s.pop()
        self.assertEqual(None, s.peek())
        s.pop()
        self.assertEqual(None, s.peek())
        s.push(35)
        self.assertEqual(35, s.peek())
        s.push(55)
        self.assertEqual(55, s.peek())
        s.push(75)
        self.assertEqual(75, s.peek())
        s.pop()
        self.assertEqual(55, s.peek())
