| Daniel Dunbar | a7a354e | 2010-01-30 23:59:02 +0000 | [diff] [blame] | 1 | from clang.cindex import * |
| Gregory Szorc | 0e20a09 | 2012-03-10 22:19:05 +0000 | [diff] [blame] | 2 | from .util import get_tu |
| Daniel Dunbar | a7a354e | 2010-01-30 23:59:02 +0000 | [diff] [blame] | 3 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 4 | import unittest |
| 5 | |
| 6 | |
| Daniel Dunbar | a7a354e | 2010-01-30 23:59:02 +0000 | [diff] [blame] | 7 | # FIXME: We need support for invalid translation units to test better. |
| 8 | |
| Daniel Dunbar | a7a354e | 2010-01-30 23:59:02 +0000 | [diff] [blame] | 9 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 10 | class 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 Dunbar | a7a354e | 2010-01-30 23:59:02 +0000 | [diff] [blame] | 19 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 20 | 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 Grosser | 5153e79 | 2011-02-05 17:53:51 +0000 | [diff] [blame] | 32 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 33 | 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 Grosser | 9fc76f2 | 2012-02-05 11:41:58 +0000 | [diff] [blame] | 47 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 48 | 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 Grosser | 9fc76f2 | 2012-02-05 11:41:58 +0000 | [diff] [blame] | 64 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 65 | 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 Grosser | 9fc76f2 | 2012-02-05 11:41:58 +0000 | [diff] [blame] | 70 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 71 | self.assertEqual(d.severity, Diagnostic.Warning) |
| 72 | self.assertEqual(d.location.line, 1) |
| 73 | self.assertEqual(d.location.column, 11) |
| Tobias Grosser | 9fc76f2 | 2012-02-05 11:41:58 +0000 | [diff] [blame] | 74 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 75 | self.assertEqual(d.category_number, 2) |
| 76 | self.assertEqual(d.category_name, 'Semantic Issue') |
| Tobias Grosser | 9fc76f2 | 2012-02-05 11:41:58 +0000 | [diff] [blame] | 77 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 78 | 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 Abdulrasool | acc98ca | 2016-04-30 21:14:01 +0000 | [diff] [blame] | 83 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 84 | self.assertEqual(d.option, '-Wunused-parameter') |
| 85 | self.assertEqual(d.disable_option, '-Wno-unused-parameter') |
| Saleem Abdulrasool | acc98ca | 2016-04-30 21:14:01 +0000 | [diff] [blame] | 86 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 87 | 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 Coe | f3ecda6 | 2017-09-06 07:33:32 +0000 | [diff] [blame] | 91 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 92 | 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 Coe | f3ecda6 | 2017-09-06 07:33:32 +0000 | [diff] [blame] | 99 | |
| Michal Gorny | 084e43b | 2017-11-10 16:44:12 +0000 | [diff] [blame^] | 100 | 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">') |