1from clang.cindex import TranslationUnit
2
3import unittest
4
5
6class TestCodeCompletion(unittest.TestCase):
7    def check_completion_results(self, cr, expected):
8        self.assertIsNotNone(cr)
9        self.assertEqual(len(cr.diagnostics), 0)
10
11        completions = [str(c) for c in cr.results]
12
13        for c in expected:
14            self.assertIn(c, completions)
15
16    def test_code_complete(self):
17        files = [('fake.c', """
18/// Aaa.
19int test1;
20
21/// Bbb.
22void test2(void);
23
24void f() {
25
26}
27""")]
28
29        tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files,
30                options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
31
32        cr = tu.codeComplete('fake.c', 9, 1, unsaved_files=files, include_brief_comments=True)
33
34        expected = [
35          "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
36          "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
37          "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None"
38        ]
39        self.check_completion_results(cr, expected)
40
41    def test_code_complete_availability(self):
42        files = [('fake.cpp', """
43class P {
44protected:
45  int member;
46};
47
48class Q : public P {
49public:
50  using P::member;
51};
52
53void f(P x, Q y) {
54  x.; // member is inaccessible
55  y.; // member is accessible
56}
57""")]
58
59        tu = TranslationUnit.from_source('fake.cpp', ['-std=c++98'], unsaved_files=files)
60
61        cr = tu.codeComplete('fake.cpp', 12, 5, unsaved_files=files)
62
63        expected = [
64          "{'const', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
65          "{'volatile', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
66          "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
67          "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None",
68          "{'Q', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None"
69        ]
70        self.check_completion_results(cr, expected)
71
72        cr = tu.codeComplete('fake.cpp', 13, 5, unsaved_files=files)
73        expected = [
74            "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None",
75            "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None",
76            "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None",
77            "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None"
78        ]
79        self.check_completion_results(cr, expected)
80