import unittest
from pile import Pile


class TestPile(unittest.TestCase):
    """
    Cette classe permet d'introduire des tests pour tester nos différentes méthodes.
    Pour créer des tests, il suffit de créer une méthode avec le nom du test et de
    tester différentes choses à l'intérieur.
    Le mot clef self permet d'avoir accès à des méthodes de test poussées.
    """

    def test_creation(self):
        une_pile = Pile()
        self.assertIsInstance(une_pile, Pile)  # Vérifie qu'une pile créée est bien de type Pile
        self.assertTrue(une_pile.est_vide())  # Vérifie qu'une pile créée est bien vide

    def test_fonctionnement_1(self):
        """
        Différents tests pour empiler (et dépiler) des éléments de même type
        """
        une_pile = Pile()

        une_pile.empiler(3)
        une_pile.empiler(7)
        une_pile.empiler(8)
        self.assertEqual(une_pile.depiler(), 8)
        self.assertEqual(une_pile.depiler(), 7)
        self.assertEqual(une_pile.depiler(), 3)

    def test_fonctionnement_2(self):
        """
        Différents tests pour empiler (et dépiler) des éléments de même type
        """
        une_pile = Pile()

        une_pile.empiler(3)
        self.assertEqual(une_pile.depiler(), 3)
        une_pile.empiler(7)
        self.assertEqual(une_pile.depiler(), 7)
        une_pile.empiler(8)
        self.assertEqual(une_pile.depiler(), 8)

    def test_fonctionnement_3(self):
        """
        Différents tests pour empiler (et dépiler) des éléments de même type
        """
        une_pile = Pile()

        une_pile.empiler(3)
        une_pile.empiler(7)
        self.assertEqual(une_pile.depiler(), 7)
        une_pile.empiler(8)
        self.assertEqual(une_pile.depiler(), 8)
        self.assertEqual(une_pile.depiler(), 3)

    def test_est_vide(self):
        """
        Vérifie le fonctionnement de la méthode est_vide() et du dépilement d'une pile vide
        """
        une_pile = Pile()

        self.assertTrue(une_pile.est_vide())
        une_pile.empiler(3)
        self.assertFalse(une_pile.est_vide())
        une_pile.empiler(7)
        self.assertFalse(une_pile.est_vide())
        une_pile.depiler()
        self.assertFalse(une_pile.est_vide())
        une_pile.depiler()
        self.assertTrue(une_pile.est_vide())

        with self.assertRaises(Exception):
            une_pile.depiler()

    def test_homogeneite(self):
        """
        Vérifie que l'homogénéité est bien respectée
        """
        une_pile = Pile()

        une_pile.empiler(3)
        with self.assertRaises(Exception):
            une_pile.empiler("A")
        une_pile.empiler(7)
        with self.assertRaises(Exception):
            une_pile.empiler([])
        une_pile.depiler()
        une_pile.depiler()
        self.assertTrue(une_pile.est_vide())


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