1c37d1614SMichal Gornyimport os
2c37d1614SMichal Gornyfrom clang.cindex import Config
3c37d1614SMichal Gornyif 'CLANG_LIBRARY_PATH' in os.environ:
4c37d1614SMichal Gorny    Config.set_library_path(os.environ['CLANG_LIBRARY_PATH'])
5c37d1614SMichal Gorny
698f93adeSDmitri Gribenkofrom clang.cindex import TranslationUnit
798f93adeSDmitri Gribenko
8084e43bfSMichal Gornyimport unittest
9248cf965SMichal Gornyfrom .util import skip_if_no_fspath
10248cf965SMichal Gornyfrom .util import str_to_path
11084e43bfSMichal Gorny
12084e43bfSMichal Gorny
13084e43bfSMichal Gornyclass TestCodeCompletion(unittest.TestCase):
14084e43bfSMichal Gorny    def check_completion_results(self, cr, expected):
15084e43bfSMichal Gorny        self.assertIsNotNone(cr)
16084e43bfSMichal Gorny        self.assertEqual(len(cr.diagnostics), 0)
177c52cc4cSBenjamin Kramer
187c52cc4cSBenjamin Kramer        completions = [str(c) for c in cr.results]
197c52cc4cSBenjamin Kramer
207c52cc4cSBenjamin Kramer        for c in expected:
21084e43bfSMichal Gorny            self.assertIn(c, completions)
227c52cc4cSBenjamin Kramer
23084e43bfSMichal Gorny    def test_code_complete(self):
2498f93adeSDmitri Gribenko        files = [('fake.c', """
2598f93adeSDmitri Gribenko/// Aaa.
2698f93adeSDmitri Gribenkoint test1;
2798f93adeSDmitri Gribenko
2898f93adeSDmitri Gribenko/// Bbb.
2998f93adeSDmitri Gribenkovoid test2(void);
3098f93adeSDmitri Gribenko
3198f93adeSDmitri Gribenkovoid f() {
3298f93adeSDmitri Gribenko
3398f93adeSDmitri Gribenko}
3498f93adeSDmitri Gribenko""")]
3598f93adeSDmitri Gribenko
3698f93adeSDmitri Gribenko        tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files,
3798f93adeSDmitri Gribenko                options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
3898f93adeSDmitri Gribenko
3998f93adeSDmitri Gribenko        cr = tu.codeComplete('fake.c', 9, 1, unsaved_files=files, include_brief_comments=True)
4098f93adeSDmitri Gribenko
4198f93adeSDmitri Gribenko        expected = [
4298f93adeSDmitri Gribenko          "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
4398f93adeSDmitri Gribenko          "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
44*209b1380SIlya Biryukov          "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None"
4598f93adeSDmitri Gribenko        ]
46084e43bfSMichal Gorny        self.check_completion_results(cr, expected)
4798f93adeSDmitri Gribenko
48248cf965SMichal Gorny    @skip_if_no_fspath
49248cf965SMichal Gorny    def test_code_complete_pathlike(self):
50248cf965SMichal Gorny        files = [(str_to_path('fake.c'), """
51248cf965SMichal Gorny/// Aaa.
52248cf965SMichal Gornyint test1;
53248cf965SMichal Gorny
54248cf965SMichal Gorny/// Bbb.
55248cf965SMichal Gornyvoid test2(void);
56248cf965SMichal Gorny
57248cf965SMichal Gornyvoid f() {
58248cf965SMichal Gorny
59248cf965SMichal Gorny}
60248cf965SMichal Gorny""")]
61248cf965SMichal Gorny
62248cf965SMichal Gorny        tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-std=c99'], unsaved_files=files,
63248cf965SMichal Gorny                options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
64248cf965SMichal Gorny
65248cf965SMichal Gorny        cr = tu.codeComplete(str_to_path('fake.c'), 9, 1, unsaved_files=files, include_brief_comments=True)
66248cf965SMichal Gorny
67248cf965SMichal Gorny        expected = [
68248cf965SMichal Gorny          "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
69248cf965SMichal Gorny          "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
70*209b1380SIlya Biryukov          "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None"
71248cf965SMichal Gorny        ]
72248cf965SMichal Gorny        self.check_completion_results(cr, expected)
73248cf965SMichal Gorny
74084e43bfSMichal Gorny    def test_code_complete_availability(self):
757c52cc4cSBenjamin Kramer        files = [('fake.cpp', """
767c52cc4cSBenjamin Kramerclass P {
777c52cc4cSBenjamin Kramerprotected:
787c52cc4cSBenjamin Kramer  int member;
797c52cc4cSBenjamin Kramer};
8098f93adeSDmitri Gribenko
817c52cc4cSBenjamin Kramerclass Q : public P {
827c52cc4cSBenjamin Kramerpublic:
837c52cc4cSBenjamin Kramer  using P::member;
847c52cc4cSBenjamin Kramer};
857c52cc4cSBenjamin Kramer
867c52cc4cSBenjamin Kramervoid f(P x, Q y) {
877c52cc4cSBenjamin Kramer  x.; // member is inaccessible
887c52cc4cSBenjamin Kramer  y.; // member is accessible
897c52cc4cSBenjamin Kramer}
907c52cc4cSBenjamin Kramer""")]
917c52cc4cSBenjamin Kramer
927c52cc4cSBenjamin Kramer        tu = TranslationUnit.from_source('fake.cpp', ['-std=c++98'], unsaved_files=files)
937c52cc4cSBenjamin Kramer
947c52cc4cSBenjamin Kramer        cr = tu.codeComplete('fake.cpp', 12, 5, unsaved_files=files)
957c52cc4cSBenjamin Kramer
967c52cc4cSBenjamin Kramer        expected = [
97248319dbSMichal Gorny          "{'const', TypedText} || Priority: 50 || Availability: Available || Brief comment: None",
98248319dbSMichal Gorny          "{'volatile', TypedText} || Priority: 50 || Availability: Available || Brief comment: None",
997c52cc4cSBenjamin Kramer          "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None",
100248319dbSMichal Gorny          "{'P', TypedText} || Priority: 50 || Availability: Available || Brief comment: None",
101248319dbSMichal Gorny          "{'Q', TypedText} || Priority: 50 || Availability: Available || Brief comment: None"
1027c52cc4cSBenjamin Kramer        ]
103084e43bfSMichal Gorny        self.check_completion_results(cr, expected)
1047c52cc4cSBenjamin Kramer
1057c52cc4cSBenjamin Kramer        cr = tu.codeComplete('fake.cpp', 13, 5, unsaved_files=files)
1067c52cc4cSBenjamin Kramer        expected = [
1077c52cc4cSBenjamin Kramer            "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None",
108fe5ae8e4SMichal Gorny            "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None",
1097c52cc4cSBenjamin Kramer            "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None",
110fe5ae8e4SMichal Gorny            "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None"
1117c52cc4cSBenjamin Kramer        ]
112084e43bfSMichal Gorny        self.check_completion_results(cr, expected)
113