# Path: diffprivlib/utils.py
# class Budget(tuple):
#     """Custom tuple subclass for privacy budgets of the form (epsilon, delta).
# 
#     The ``Budget`` class allows for correct comparison/ordering of privacy budget, ensuring that both epsilon and delta
#     satisfy the comparison (tuples are compared lexicographically).  Additionally, tuples are represented with added
#     verbosity, labelling epsilon and delta appropriately.
# 
#     Examples
#     --------
# 
#     >>> from diffprivlib.utils import Budget
#     >>> Budget(1, 0.5)
#     (epsilon=1, delta=0.5)
#     >>> Budget(2, 0) >= Budget(1, 0.5)
#     False
#     >>> (2, 0) >= (1, 0.5) # Tuples are compared with lexicographic ordering
#     True
# 
#     """
#     def __new__(cls, epsilon, delta):
#         from diffprivlib.validation import check_epsilon_delta
# 
#         check_epsilon_delta(epsilon, delta, allow_zero=True)
#         return tuple.__new__(cls, (epsilon, delta))
# 
#     def __gt__(self, other):
#         if self.__ge__(other) and not self.__eq__(other):
#             return True
#         return False
# 
#     def __ge__(self, other):
#         if self[0] >= other[0] and self[1] >= other[1]:
#             return True
#         return False
# 
#     def __lt__(self, other):
#         if self.__le__(other) and not self.__eq__(other):
#             return True
#         return False
# 
#     def __le__(self, other):
#         if self[0] <= other[0] and self[1] <= other[1]:
#             return True
#         return False
# 
#     def __repr__(self):
#         return f"(epsilon={self[0]}, delta={self[1]})"


from unittest import TestCase
from diffprivlib.utils import Budget

class TestBudget(TestCase):
    def test_tuple(self):
        self.assertIsInstance(Budget(0, 0), tuple)

    def test_correct_vals(self):
        self.assertIsNotNone(Budget(0, 0))
        self.assertIsNotNone(Budget(1, 0))
        self.assertIsNotNone(Budget(float("inf"), 1))
        self.assertIsNotNone(Budget(0, 0.1))
        self.assertIsNotNone(Budget(0, 1e-300))
        self.assertIsNotNone(Budget(1e300, 1e-300))

    def test_bad_vals(self):
        with self.assertRaises(ValueError):
            Budget(-1, 0)

        with self.assertRaises(ValueError):
            Budget(0, -0.1)

        with self.assertRaises(ValueError):
            Budget(0, 1.1)

        with self.assertRaises(TypeError):
            Budget("0", 0)

        with self.assertRaises(TypeError):
            Budget(complex(0, 1), 0)

    def test_comparisons(self):

# Path: diffprivlib/utils.py
# class Budget(tuple):
#     """Custom tuple subclass for privacy budgets of the form (epsilon, delta).
# 
#     The ``Budget`` class allows for correct comparison/ordering of privacy budget, ensuring that both epsilon and delta
#     satisfy the comparison (tuples are compared lexicographically).  Additionally, tuples are represented with added
#     verbosity, labelling epsilon and delta appropriately.
# 
#     Examples
#     --------
# 
#     >>> from diffprivlib.utils import Budget
#     >>> Budget(1, 0.5)
#     (epsilon=1, delta=0.5)
#     >>> Budget(2, 0) >= Budget(1, 0.5)
#     False
#     >>> (2, 0) >= (1, 0.5) # Tuples are compared with lexicographic ordering
#     True
# 
#     """
#     def __new__(cls, epsilon, delta):
#         from diffprivlib.validation import check_epsilon_delta
# 
#         check_epsilon_delta(epsilon, delta, allow_zero=True)
#         return tuple.__new__(cls, (epsilon, delta))
# 
#     def __gt__(self, other):
#         if self.__ge__(other) and not self.__eq__(other):
#             return True
#         return False
# 
#     def __ge__(self, other):
#         if self[0] >= other[0] and self[1] >= other[1]:
#             return True
#         return False
# 
#     def __lt__(self, other):
#         if self.__le__(other) and not self.__eq__(other):
#             return True
#         return False
# 
#     def __le__(self, other):
#         if self[0] <= other[0] and self[1] <= other[1]:
#             return True
#         return False
# 
#     def __repr__(self):
#         return f"(epsilon={self[0]}, delta={self[1]})"


# Path: tests/test_Budget.py
from unittest import TestCase
from diffprivlib.utils import Budget


class TestBudget(TestCase):
    def test_tuple(self):
        self.assertIsInstance(Budget(0, 0), tuple)

    def test_correct_vals(self):
        self.assertIsNotNone(Budget(0, 0))
        self.assertIsNotNone(Budget(1, 0))
        self.assertIsNotNone(Budget(float("inf"), 1))
        self.assertIsNotNone(Budget(0, 0.1))
        self.assertIsNotNone(Budget(0, 1e-300))
        self.assertIsNotNone(Budget(1e300, 1e-300))

    def test_bad_vals(self):
        with self.assertRaises(ValueError):
            Budget(-1, 0)

        with self.assertRaises(ValueError):
            Budget(0, -0.1)

        with self.assertRaises(ValueError):
            Budget(0, 1.1)

        with self.assertRaises(TypeError):
            Budget("0", 0)

        with self.assertRaises(TypeError):
            Budget(complex(0, 1), 0)

    def test_comparisons(self):

        self.assertTrue(Budget(2, 0.2) >= Budget(2, 0.2))