144 lines · python
1import os2 3from clang.cindex import Config, TranslationUnit4 5if "CLANG_LIBRARY_PATH" in os.environ:6 Config.set_library_path(os.environ["CLANG_LIBRARY_PATH"])7 8import unittest9from pathlib import Path10 11 12class TestCodeCompletion(unittest.TestCase):13 def check_completion_results(self, cr, expected):14 self.assertIsNotNone(cr)15 self.assertEqual(len(cr.diagnostics), 0)16 17 completions = [str(c) for c in cr.results]18 19 for c in expected:20 self.assertIn(c, completions)21 22 def test_code_complete(self):23 files = [24 (25 "fake.c",26 """27/// Aaa.28int test1;29 30/// Bbb.31void test2(void);32 33void f() {34 35}36""",37 )38 ]39 40 tu = TranslationUnit.from_source(41 "fake.c",42 ["-std=c99"],43 unsaved_files=files,44 options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION,45 )46 47 cr = tu.codeComplete(48 "fake.c", 9, 1, unsaved_files=files, include_brief_comments=True49 )50 51 expected = [52 "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",53 "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",54 "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: ",55 ]56 self.check_completion_results(cr, expected)57 58 def test_code_complete_pathlike(self):59 files = [60 (61 Path("fake.c"),62 """63/// Aaa.64int test1;65 66/// Bbb.67void test2(void);68 69void f() {70 71}72""",73 )74 ]75 76 tu = TranslationUnit.from_source(77 Path("fake.c"),78 ["-std=c99"],79 unsaved_files=files,80 options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION,81 )82 83 cr = tu.codeComplete(84 Path("fake.c"),85 9,86 1,87 unsaved_files=files,88 include_brief_comments=True,89 )90 91 expected = [92 "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",93 "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",94 "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: ",95 ]96 self.check_completion_results(cr, expected)97 98 def test_code_complete_availability(self):99 files = [100 (101 "fake.cpp",102 """103class P {104protected:105 int member;106};107 108class Q : public P {109public:110 using P::member;111};112 113void f(P x, Q y) {114 x.; // member is inaccessible115 y.; // member is accessible116}117""",118 )119 ]120 121 tu = TranslationUnit.from_source(122 "fake.cpp", ["-std=c++98"], unsaved_files=files123 )124 125 cr = tu.codeComplete("fake.cpp", 12, 5, unsaved_files=files)126 127 expected = [128 "{'const', TypedText} || Priority: 50 || Availability: Available || Brief comment: ",129 "{'volatile', TypedText} || Priority: 50 || Availability: Available || Brief comment: ",130 "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: ",131 "{'P', TypedText} || Priority: 50 || Availability: Available || Brief comment: ",132 "{'Q', TypedText} || Priority: 50 || Availability: Available || Brief comment: ",133 ]134 self.check_completion_results(cr, expected)135 136 cr = tu.codeComplete("fake.cpp", 13, 5, unsaved_files=files)137 expected = [138 "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: ",139 "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: ",140 "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: ",141 "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: ",142 ]143 self.check_completion_results(cr, expected)144