# Path: chamber/utils/datastructures.py
# class ChoicesEnum(AbstractChoicesEnum, Enum):
#     pass
# 
# class ChoicesNumEnum(AbstractChoicesEnum, NumEnum):
#     pass
# 
# class Enum(AbstractEnum):
# 
#     def __init__(self, *items):
#         super().__init__(*(
#             item if isinstance(item, (list, tuple)) else (item, item)
#             for item in items
#         ))
# 
# class NumEnum(Enum):
# 
#     def __init__(self, *items):
#         used_ids = set()
# 
#         enum_items = []
#         i = 0
#         for item in items:
#             if len(item) == 2:
#                 key, i = item
#                 if not isinstance(i, int):
#                     raise ValueError('Choice value of item must by integer')
#             else:
#                 key = item
#                 i += 1
# 
#             if i in used_ids:
#                 raise ValueError('Index %s already exists, please renumber choices')
# 
#             used_ids.add(i)
#             enum_items.append((key, i))
#         super().__init__(*enum_items)
# 
# class OrderedSet(MutableSet):
# 
#     def __init__(self, *iterable):
#         self.end = end = []
#         end += [None, end, end]  # sentinel node for doubly linked list
#         self.map = {}  # key --> [key, prev, next]
#         if iterable is not None:
#             self |= iterable
# 
#     def __len__(self):
#         return len(self.map)
# 
#     def __contains__(self, key):
#         return key in self.map
# 
#     def add(self, key):
#         if key not in self.map:
#             end = self.end
#             curr = end[1]
#             curr[2] = end[1] = self.map[key] = [key, curr, end]
# 
#     def discard(self, key):
#         if key in self.map:
#             key, prev_item, next_item = self.map.pop(key)
#             prev_item[2] = next_item
#             next_item[1] = prev_item
# 
#     def __iter__(self):
#         end = self.end
#         curr = end[2]
#         while curr is not end:
#             yield curr[0]
#             curr = curr[2]
# 
#     def __reversed__(self):
#         end = self.end
#         curr = end[1]
#         while curr is not end:
#             yield curr[0]
#             curr = curr[1]
# 
#     def pop(self, last=True):
#         if not self:
#             raise KeyError('set is empty')
#         key = self.end[1][0] if last else self.end[2][0]
#         self.discard(key)
#         return key
# 
#     def __repr__(self):
#         if not self:
#             return '{}()'.format(self.__class__.__name__,)
#         else:
#             return '{}({})'.format(self.__class__.__name__, list(self))
# 
#     def __eq__(self, other):
#         if isinstance(other, OrderedSet):
#             return len(self) == len(other) and list(self) == list(other)
#         return set(self) == set(other)


from django.test import TestCase
from chamber.utils.datastructures import ChoicesEnum, ChoicesNumEnum, Enum, NumEnum, OrderedSet
from germanium.tools import assert_equal, assert_raises, assert_is_none, assert_in, assert_not_in
    def test_choices_num_enum_same_generated_numbers_should_raise_exception(self):
        with assert_raises(ValueError):
            ChoicesNumEnum(
                ('A', 'label a', 3), ('B', 'label b', 2), ('C', 'label c')
            )

    def test_choices_num_enum_invalid_num_raise_exception(self):
        with assert_raises(ValueError):
            ChoicesNumEnum(
                ('A', 'label a', 'e'), ('B', 'label b', 2)
            )

    def test_enum_key_should_have_right_format(self):
        with assert_raises(ValueError):
            Enum(
                1, 2
            )
        with assert_raises(ValueError):
            Enum(
                '1A', 'B'
            )
        with assert_raises(ValueError):
            Enum(
                'A-B', 'B'
            )
        Enum(
            'A_B_3', 'B'
        )

    def test_ordered_set_should_keep_order(self):

# Path: chamber/utils/datastructures.py
# class ChoicesEnum(AbstractChoicesEnum, Enum):
#     pass
# 
# class ChoicesNumEnum(AbstractChoicesEnum, NumEnum):
#     pass
# 
# class Enum(AbstractEnum):
# 
#     def __init__(self, *items):
#         super().__init__(*(
#             item if isinstance(item, (list, tuple)) else (item, item)
#             for item in items
#         ))
# 
# class NumEnum(Enum):
# 
#     def __init__(self, *items):
#         used_ids = set()
# 
#         enum_items = []
#         i = 0
#         for item in items:
#             if len(item) == 2:
#                 key, i = item
#                 if not isinstance(i, int):
#                     raise ValueError('Choice value of item must by integer')
#             else:
#                 key = item
#                 i += 1
# 
#             if i in used_ids:
#                 raise ValueError('Index %s already exists, please renumber choices')
# 
#             used_ids.add(i)
#             enum_items.append((key, i))
#         super().__init__(*enum_items)
# 
# class OrderedSet(MutableSet):
# 
#     def __init__(self, *iterable):
#         self.end = end = []
#         end += [None, end, end]  # sentinel node for doubly linked list
#         self.map = {}  # key --> [key, prev, next]
#         if iterable is not None:
#             self |= iterable
# 
#     def __len__(self):
#         return len(self.map)
# 
#     def __contains__(self, key):
#         return key in self.map
# 
#     def add(self, key):
#         if key not in self.map:
#             end = self.end
#             curr = end[1]
#             curr[2] = end[1] = self.map[key] = [key, curr, end]
# 
#     def discard(self, key):
#         if key in self.map:
#             key, prev_item, next_item = self.map.pop(key)
#             prev_item[2] = next_item
#             next_item[1] = prev_item
# 
#     def __iter__(self):
#         end = self.end
#         curr = end[2]
#         while curr is not end:
#             yield curr[0]
#             curr = curr[2]
# 
#     def __reversed__(self):
#         end = self.end
#         curr = end[1]
#         while curr is not end:
#             yield curr[0]
#             curr = curr[1]
# 
#     def pop(self, last=True):
#         if not self:
#             raise KeyError('set is empty')
#         key = self.end[1][0] if last else self.end[2][0]
#         self.discard(key)
#         return key
# 
#     def __repr__(self):
#         if not self:
#             return '{}()'.format(self.__class__.__name__,)
#         else:
#             return '{}({})'.format(self.__class__.__name__, list(self))
# 
#     def __eq__(self, other):
#         if isinstance(other, OrderedSet):
#             return len(self) == len(other) and list(self) == list(other)
#         return set(self) == set(other)


# Path: example/dj/apps/test_chamber/tests/utils/datastructures.py
from django.test import TestCase
from chamber.utils.datastructures import ChoicesEnum, ChoicesNumEnum, Enum, NumEnum, OrderedSet
from germanium.tools import assert_equal, assert_raises, assert_is_none, assert_in, assert_not_in

    def test_choices_num_enum_same_generated_numbers_should_raise_exception(self):
        with assert_raises(ValueError):
            ChoicesNumEnum(
                ('A', 'label a', 3), ('B', 'label b', 2), ('C', 'label c')
            )

    def test_choices_num_enum_invalid_num_raise_exception(self):
        with assert_raises(ValueError):
            ChoicesNumEnum(
                ('A', 'label a', 'e'), ('B', 'label b', 2)
            )

    def test_enum_key_should_have_right_format(self):
        with assert_raises(ValueError):
            Enum(
                1, 2
            )
        with assert_raises(ValueError):
            Enum(
                '1A', 'B'
            )
        with assert_raises(ValueError):
            Enum(
                'A-B', 'B'
            )
        Enum(
            'A_B_3', 'B'
        )

    def test_ordered_set_should_keep_order(self):

        ordered_set = OrderedSet(4, 5, 3)