# Path: debugger/enums.py
# class TypeCategory(Enum):
#     """
#     Represents type of C/C++ type.
#     """
#     Any = -1
#     Array = 1
#     BlockPointer = 2
#     Builtin = 4
#     Class = 8
#     ComplexFloat = 16
#     ComplexInteger = 32
#     Enumeration = 64
#     Function = 128
#     Invalid = 0
#     MemberPointer = 256
#     ObjCInterface = 1024
#     ObjCObject = 512
#     ObjCObjectPointer = 2048
#     Other = -2147483648
#     Pointer = 4096
#     CString = 4097
#     Reference = 8192
#     Struct = 16384
#     Typedef = 32768
#     Union = 65536
#     Vector = 131072
#     String = 42
# 
#     def nice_name(self):
#         name_mappings = {
#             TypeCategory.Class: "class",
#             TypeCategory.Struct: "struct"
#         }
#         return name_mappings.get(self, str(self))
# 
# class BasicTypeCategory(Enum):
#     """
#     Represents type of a primitive C/C++ type.
#     """
#     Bool = 20
#     Char = 2
#     Char16 = 8
#     Char32 = 9
#     Double = 23
#     DoubleComplex = 26
#     Float = 22
#     FloatComplex = 25
#     Half = 21
#     Int = 12
#     Int128 = 18
#     Invalid = 0
#     Long = 14
#     LongDouble = 24
#     LongDoubleComplex = 27
#     LongLong = 16
#     NullPtr = 31
#     ObjCClass = 29
#     ObjCID = 28
#     ObjCSel = 30
#     Other = 32
#     Short = 10
#     SignedChar = 3
#     SignedWChar = 6
#     UnsignedChar = 4
#     UnsignedInt = 13
#     UnsignedInt128 = 19
#     UnsignedLong = 15
#     UnsignedLongLong = 17
#     UnsignedShort = 11
#     UnsignedWChar = 7
#     Void = 1
#     WChar = 5
# 
#     @staticmethod
#     def is_char(type):
#         """
#         @type type: BasicTypeCategory
#         @rtype: bool
#         """
#         return type in (BasicTypeCategory.Char,
#                         BasicTypeCategory.Char16,
#                         BasicTypeCategory.Char32,
#                         BasicTypeCategory.SignedChar,
#                         BasicTypeCategory.UnsignedChar,
#                         BasicTypeCategory.SignedWChar,
#                         BasicTypeCategory.UnsignedWChar,
#                         BasicTypeCategory.WChar)
# 
# Path: tests/conftest.py
# def setup_debugger(debugger, binary, lines, on_state_change=None,
#                    startup_info=None, cont=True, wait=True):
#     assert debugger.load_binary("src/{}".format(binary))
# 
#     test_exception = []
# 
#     if not isinstance(lines, Iterable):
#         lines = [lines]
# 
#     for line in lines:
#         assert debugger.breakpoint_manager.add_breakpoint(
#             "src/{}.cpp".format(binary), line)
# 
#     if on_state_change:
#         def on_stop(state, data):
#             if state == ProcessState.Stopped:
#                 try:
#                     on_state_change()
#                     if cont:
#                         debugger.exec_continue()
#                 except Exception as exc:
#                     test_exception.append(traceback.format_exc(exc))
#                     debugger.quit_program()
# 
#         debugger.on_process_state_changed.subscribe(on_stop)
# 
#     assert debugger.launch(startup_info)
# 
#     if wait:
#         debugger.wait_for_exit()
# 
#     if len(test_exception) > 0:
#         pytest.fail(test_exception[0], pytrace=False)


from debugger.enums import TypeCategory, BasicTypeCategory
from tests.conftest import setup_debugger

def test_types(debugger):
    def test_types_cb():
        check_type(debugger, "varInt", "int", TypeCategory.Builtin,
                   BasicTypeCategory.Int)
        check_type(debugger, "varUnsignedShort", "unsigned short",
                   TypeCategory.Builtin, BasicTypeCategory.UnsignedShort)
        check_type(debugger, "varFloat", "float", TypeCategory.Builtin,
                   BasicTypeCategory.Float)
        check_type(debugger, "varClassA", "classA", TypeCategory.Class)
        check_type(debugger, "varStructA", "structA", TypeCategory.Struct)
        check_type(debugger, "varUnionA", "unionA", TypeCategory.Union)
        check_type(debugger, "varEnumA", "enumA", TypeCategory.Enumeration)
        check_type(debugger, "varEnumB", "enumB", TypeCategory.Enumeration)
        type = check_type(debugger, "varVector",
                          lambda name: name.startswith("std::vector<int>"),
                          TypeCategory.Vector)
        assert type.child_type.name == "int"

        check_type(debugger, "varString", "std::string", TypeCategory.String)

        type = check_type(debugger, "varArray", "int [10]", TypeCategory.Array)
        assert type.count == 10
        assert type.child_type.name == "int"

        check_type(debugger, "varPointer", "int *", TypeCategory.Pointer)
        check_type(debugger, "varReference", "int &", TypeCategory.Reference)
        check_type(debugger, "varFunctionPointer", "void (*)(void)",
                   TypeCategory.Function)


# Path: debugger/enums.py
# class TypeCategory(Enum):
#     """
#     Represents type of C/C++ type.
#     """
#     Any = -1
#     Array = 1
#     BlockPointer = 2
#     Builtin = 4
#     Class = 8
#     ComplexFloat = 16
#     ComplexInteger = 32
#     Enumeration = 64
#     Function = 128
#     Invalid = 0
#     MemberPointer = 256
#     ObjCInterface = 1024
#     ObjCObject = 512
#     ObjCObjectPointer = 2048
#     Other = -2147483648
#     Pointer = 4096
#     CString = 4097
#     Reference = 8192
#     Struct = 16384
#     Typedef = 32768
#     Union = 65536
#     Vector = 131072
#     String = 42
# 
#     def nice_name(self):
#         name_mappings = {
#             TypeCategory.Class: "class",
#             TypeCategory.Struct: "struct"
#         }
#         return name_mappings.get(self, str(self))
# 
# class BasicTypeCategory(Enum):
#     """
#     Represents type of a primitive C/C++ type.
#     """
#     Bool = 20
#     Char = 2
#     Char16 = 8
#     Char32 = 9
#     Double = 23
#     DoubleComplex = 26
#     Float = 22
#     FloatComplex = 25
#     Half = 21
#     Int = 12
#     Int128 = 18
#     Invalid = 0
#     Long = 14
#     LongDouble = 24
#     LongDoubleComplex = 27
#     LongLong = 16
#     NullPtr = 31
#     ObjCClass = 29
#     ObjCID = 28
#     ObjCSel = 30
#     Other = 32
#     Short = 10
#     SignedChar = 3
#     SignedWChar = 6
#     UnsignedChar = 4
#     UnsignedInt = 13
#     UnsignedInt128 = 19
#     UnsignedLong = 15
#     UnsignedLongLong = 17
#     UnsignedShort = 11
#     UnsignedWChar = 7
#     Void = 1
#     WChar = 5
# 
#     @staticmethod
#     def is_char(type):
#         """
#         @type type: BasicTypeCategory
#         @rtype: bool
#         """
#         return type in (BasicTypeCategory.Char,
#                         BasicTypeCategory.Char16,
#                         BasicTypeCategory.Char32,
#                         BasicTypeCategory.SignedChar,
#                         BasicTypeCategory.UnsignedChar,
#                         BasicTypeCategory.SignedWChar,
#                         BasicTypeCategory.UnsignedWChar,
#                         BasicTypeCategory.WChar)
# 
# Path: tests/conftest.py
# def setup_debugger(debugger, binary, lines, on_state_change=None,
#                    startup_info=None, cont=True, wait=True):
#     assert debugger.load_binary("src/{}".format(binary))
# 
#     test_exception = []
# 
#     if not isinstance(lines, Iterable):
#         lines = [lines]
# 
#     for line in lines:
#         assert debugger.breakpoint_manager.add_breakpoint(
#             "src/{}.cpp".format(binary), line)
# 
#     if on_state_change:
#         def on_stop(state, data):
#             if state == ProcessState.Stopped:
#                 try:
#                     on_state_change()
#                     if cont:
#                         debugger.exec_continue()
#                 except Exception as exc:
#                     test_exception.append(traceback.format_exc(exc))
#                     debugger.quit_program()
# 
#         debugger.on_process_state_changed.subscribe(on_stop)
# 
#     assert debugger.launch(startup_info)
# 
#     if wait:
#         debugger.wait_for_exit()
# 
#     if len(test_exception) > 0:
#         pytest.fail(test_exception[0], pytrace=False)


# Path: tests/test_mi_type.py
from debugger.enums import TypeCategory, BasicTypeCategory
from tests.conftest import setup_debugger


def test_types(debugger):
    def test_types_cb():
        check_type(debugger, "varInt", "int", TypeCategory.Builtin,
                   BasicTypeCategory.Int)
        check_type(debugger, "varUnsignedShort", "unsigned short",
                   TypeCategory.Builtin, BasicTypeCategory.UnsignedShort)
        check_type(debugger, "varFloat", "float", TypeCategory.Builtin,
                   BasicTypeCategory.Float)
        check_type(debugger, "varClassA", "classA", TypeCategory.Class)
        check_type(debugger, "varStructA", "structA", TypeCategory.Struct)
        check_type(debugger, "varUnionA", "unionA", TypeCategory.Union)
        check_type(debugger, "varEnumA", "enumA", TypeCategory.Enumeration)
        check_type(debugger, "varEnumB", "enumB", TypeCategory.Enumeration)
        type = check_type(debugger, "varVector",
                          lambda name: name.startswith("std::vector<int>"),
                          TypeCategory.Vector)
        assert type.child_type.name == "int"

        check_type(debugger, "varString", "std::string", TypeCategory.String)

        type = check_type(debugger, "varArray", "int [10]", TypeCategory.Array)
        assert type.count == 10
        assert type.child_type.name == "int"

        check_type(debugger, "varPointer", "int *", TypeCategory.Pointer)
        check_type(debugger, "varReference", "int &", TypeCategory.Reference)
        check_type(debugger, "varFunctionPointer", "void (*)(void)",
                   TypeCategory.Function)


    setup_debugger(debugger, TEST_FILE, TEST_LINE, test_types_cb)