blob: 78b327daa72cd836bf29aed38737c28fbcc899f5 [file] [log] [blame]
Daniel Dunbara7a354e2010-01-30 23:59:02 +00001from clang.cindex import *
Gregory Szorc0e20a092012-03-10 22:19:05 +00002from .util import get_tu
Daniel Dunbara7a354e2010-01-30 23:59:02 +00003
Michal Gorny084e43b2017-11-10 16:44:12 +00004import unittest
5
6
Daniel Dunbara7a354e2010-01-30 23:59:02 +00007# FIXME: We need support for invalid translation units to test better.
8
Daniel Dunbara7a354e2010-01-30 23:59:02 +00009
Michal Gorny084e43b2017-11-10 16:44:12 +000010class TestDiagnostics(unittest.TestCase):
11 def test_diagnostic_warning(self):
12 tu = get_tu('int f0() {}\n')
13 self.assertEqual(len(tu.diagnostics), 1)
14 self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning)
15 self.assertEqual(tu.diagnostics[0].location.line, 1)
16 self.assertEqual(tu.diagnostics[0].location.column, 11)
17 self.assertEqual(tu.diagnostics[0].spelling,
18 'control reaches end of non-void function')
Daniel Dunbara7a354e2010-01-30 23:59:02 +000019
Michal Gorny084e43b2017-11-10 16:44:12 +000020 def test_diagnostic_note(self):
21 # FIXME: We aren't getting notes here for some reason.
22 tu = get_tu('#define A x\nvoid *A = 1;\n')
23 self.assertEqual(len(tu.diagnostics), 1)
24 self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning)
25 self.assertEqual(tu.diagnostics[0].location.line, 2)
26 self.assertEqual(tu.diagnostics[0].location.column, 7)
27 self.assertIn('incompatible', tu.diagnostics[0].spelling)
28# self.assertEqual(tu.diagnostics[1].severity, Diagnostic.Note)
29# self.assertEqual(tu.diagnostics[1].location.line, 1)
30# self.assertEqual(tu.diagnostics[1].location.column, 11)
31# self.assertEqual(tu.diagnostics[1].spelling, 'instantiated from')
Tobias Grosser5153e792011-02-05 17:53:51 +000032
Michal Gorny084e43b2017-11-10 16:44:12 +000033 def test_diagnostic_fixit(self):
34 tu = get_tu('struct { int f0; } x = { f0 : 1 };')
35 self.assertEqual(len(tu.diagnostics), 1)
36 self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning)
37 self.assertEqual(tu.diagnostics[0].location.line, 1)
38 self.assertEqual(tu.diagnostics[0].location.column, 26)
39 self.assertRegexpMatches(tu.diagnostics[0].spelling,
40 'use of GNU old-style.*')
41 self.assertEqual(len(tu.diagnostics[0].fixits), 1)
42 self.assertEqual(tu.diagnostics[0].fixits[0].range.start.line, 1)
43 self.assertEqual(tu.diagnostics[0].fixits[0].range.start.column, 26)
44 self.assertEqual(tu.diagnostics[0].fixits[0].range.end.line, 1)
45 self.assertEqual(tu.diagnostics[0].fixits[0].range.end.column, 30)
46 self.assertEqual(tu.diagnostics[0].fixits[0].value, '.f0 = ')
Tobias Grosser9fc76f22012-02-05 11:41:58 +000047
Michal Gorny084e43b2017-11-10 16:44:12 +000048 def test_diagnostic_range(self):
49 tu = get_tu('void f() { int i = "a" + 1; }')
50 self.assertEqual(len(tu.diagnostics), 1)
51 self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning)
52 self.assertEqual(tu.diagnostics[0].location.line, 1)
53 self.assertEqual(tu.diagnostics[0].location.column, 16)
54 self.assertRegexpMatches(tu.diagnostics[0].spelling,
55 'incompatible pointer to.*')
56 self.assertEqual(len(tu.diagnostics[0].fixits), 0)
57 self.assertEqual(len(tu.diagnostics[0].ranges), 1)
58 self.assertEqual(tu.diagnostics[0].ranges[0].start.line, 1)
59 self.assertEqual(tu.diagnostics[0].ranges[0].start.column, 20)
60 self.assertEqual(tu.diagnostics[0].ranges[0].end.line, 1)
61 self.assertEqual(tu.diagnostics[0].ranges[0].end.column, 27)
62 with self.assertRaises(IndexError):
63 tu.diagnostics[0].ranges[1].start.line
Tobias Grosser9fc76f22012-02-05 11:41:58 +000064
Michal Gorny084e43b2017-11-10 16:44:12 +000065 def test_diagnostic_category(self):
66 """Ensure that category properties work."""
67 tu = get_tu('int f(int i) { return 7; }', all_warnings=True)
68 self.assertEqual(len(tu.diagnostics), 1)
69 d = tu.diagnostics[0]
Tobias Grosser9fc76f22012-02-05 11:41:58 +000070
Michal Gorny084e43b2017-11-10 16:44:12 +000071 self.assertEqual(d.severity, Diagnostic.Warning)
72 self.assertEqual(d.location.line, 1)
73 self.assertEqual(d.location.column, 11)
Tobias Grosser9fc76f22012-02-05 11:41:58 +000074
Michal Gorny084e43b2017-11-10 16:44:12 +000075 self.assertEqual(d.category_number, 2)
76 self.assertEqual(d.category_name, 'Semantic Issue')
Tobias Grosser9fc76f22012-02-05 11:41:58 +000077
Michal Gorny084e43b2017-11-10 16:44:12 +000078 def test_diagnostic_option(self):
79 """Ensure that category option properties work."""
80 tu = get_tu('int f(int i) { return 7; }', all_warnings=True)
81 self.assertEqual(len(tu.diagnostics), 1)
82 d = tu.diagnostics[0]
Saleem Abdulrasoolacc98ca2016-04-30 21:14:01 +000083
Michal Gorny084e43b2017-11-10 16:44:12 +000084 self.assertEqual(d.option, '-Wunused-parameter')
85 self.assertEqual(d.disable_option, '-Wno-unused-parameter')
Saleem Abdulrasoolacc98ca2016-04-30 21:14:01 +000086
Michal Gorny084e43b2017-11-10 16:44:12 +000087 def test_diagnostic_children(self):
88 tu = get_tu('void f(int x) {} void g() { f(); }')
89 self.assertEqual(len(tu.diagnostics), 1)
90 d = tu.diagnostics[0]
Jonathan Coef3ecda62017-09-06 07:33:32 +000091
Michal Gorny084e43b2017-11-10 16:44:12 +000092 children = d.children
93 self.assertEqual(len(children), 1)
94 self.assertEqual(children[0].severity, Diagnostic.Note)
95 self.assertRegexpMatches(children[0].spelling,
96 '.*declared here')
97 self.assertEqual(children[0].location.line, 1)
98 self.assertEqual(children[0].location.column, 1)
Jonathan Coef3ecda62017-09-06 07:33:32 +000099
Michal Gorny084e43b2017-11-10 16:44:12 +0000100 def test_diagnostic_string_repr(self):
101 tu = get_tu('struct MissingSemicolon{}')
102 self.assertEqual(len(tu.diagnostics), 1)
103 d = tu.diagnostics[0]
104
105 self.assertEqual(repr(d), '<Diagnostic severity 3, location <SourceLocation file \'t.c\', line 1, column 26>, spelling "expected \';\' after struct">')