|
1 | 1 | import unittest
|
| 2 | +from pathlib import Path |
2 | 3 |
|
3 | 4 | from clang.cindex import (
|
4 | 5 | AccessSpecifier,
|
|
12 | 13 | TemplateArgumentKind,
|
13 | 14 | TLSKind,
|
14 | 15 | TokenKind,
|
| 16 | + TranslationUnit, |
15 | 17 | TypeKind,
|
16 | 18 | )
|
17 | 19 |
|
@@ -44,8 +46,53 @@ def test_from_id(self):
|
44 | 46 |
|
45 | 47 | def test_duplicate_ids(self):
|
46 | 48 | """Check that no two kinds have the same id"""
|
47 |
| - # for enum in self.enums: |
48 | 49 | for enum in self.enums:
|
49 | 50 | num_declared_variants = len(enum._member_map_.keys())
|
50 | 51 | num_unique_variants = len(list(enum))
|
51 | 52 | self.assertEqual(num_declared_variants, num_unique_variants)
|
| 53 | + |
| 54 | + def test_all_variants(self): |
| 55 | + """Check that all libclang enum values are also defined in cindex""" |
| 56 | + cenum_to_pythonenum = { |
| 57 | + "CX_CXXAccessSpecifier": AccessSpecifier, |
| 58 | + "CXAvailabilityKind": AvailabilityKind, |
| 59 | + "CXBinaryOperatorKind": BinaryOperator, |
| 60 | + "CXCursorKind": CursorKind, |
| 61 | + "CXCursor_ExceptionSpecificationKind": ExceptionSpecificationKind, |
| 62 | + "CXLinkageKind": LinkageKind, |
| 63 | + "CXRefQualifierKind": RefQualifierKind, |
| 64 | + "CX_StorageClass": StorageClass, |
| 65 | + "CXTemplateArgumentKind": TemplateArgumentKind, |
| 66 | + "CXTLSKind": TLSKind, |
| 67 | + "CXTokenKind": TokenKind, |
| 68 | + "CXTypeKind": TypeKind, |
| 69 | + } |
| 70 | + |
| 71 | + indexheader = ( |
| 72 | + Path(__file__).parent.parent.parent.parent.parent |
| 73 | + / "include/clang-c/Index.h" |
| 74 | + ) |
| 75 | + tu = TranslationUnit.from_source(indexheader, ["-x", "c++"]) |
| 76 | + |
| 77 | + enum_variant_map = {} |
| 78 | + # For all enums in self.enums, extract all enum variants defined in Index.h |
| 79 | + for cursor in tu.cursor.walk_preorder(): |
| 80 | + type_class = cenum_to_pythonenum.get(cursor.type.spelling) |
| 81 | + if ( |
| 82 | + cursor.kind == CursorKind.ENUM_CONSTANT_DECL |
| 83 | + and type_class in self.enums |
| 84 | + ): |
| 85 | + if type_class not in enum_variant_map: |
| 86 | + enum_variant_map[type_class] = [] |
| 87 | + enum_variant_map[type_class].append(cursor.enum_value) |
| 88 | + |
| 89 | + for enum in self.enums: |
| 90 | + with self.subTest(enum): |
| 91 | + python_kinds = set([kind.value for kind in enum]) |
| 92 | + c_kinds = set(enum_variant_map[enum]) |
| 93 | + missing_python_kinds = c_kinds - python_kinds |
| 94 | + self.assertEqual( |
| 95 | + missing_python_kinds, |
| 96 | + set(), |
| 97 | + f"Please ensure these variants are defined inside {enum} in cindex.py.", |
| 98 | + ) |
0 commit comments