1import unittest
2import tempfile
3import os
4
5from giscanner.sourcescanner import SourceScanner
6
7
8class Test(unittest.TestCase):
9
10    def _parse_files(self, code, header=True):
11        scanner = SourceScanner()
12        tmp_fd, tmp_name = tempfile.mkstemp(suffix=".h" if header else ".c")
13        fileobj = os.fdopen(tmp_fd, 'wb')
14        with fileobj:
15            fileobj.write(code.encode("utf-8"))
16        scanner.parse_files([tmp_name])
17        os.unlink(tmp_name)
18        return scanner
19
20    def test_length_consistency(self):
21        scanner = self._parse_files("""
22/**
23 * Spam:
24 */
25typedef struct _spam Spam;
26
27/**
28 * Eggs:
29 */
30typedef struct _eggs Eggs;
31""")
32
33        self.assertEqual(len(list(scanner.get_symbols())), 2)
34        self.assertEqual(len(list(scanner.get_symbols())), 2)
35        self.assertEqual(len(list(scanner.get_comments())), 2)
36        self.assertEqual(len(list(scanner.get_comments())), 2)
37        self.assertFalse(scanner.get_errors())
38
39    def test_parser_error(self):
40        scanner = self._parse_files("""
41void foo() {
42    a =
43}""")
44
45        errors = scanner.get_errors()
46        self.assertEqual(len(errors), 1)
47        self.assertTrue("syntax error" in errors[0])
48
49    def test_ignore_pragma(self):
50        """Pragma directive and __pragma keyword are ignored"""
51        scanner = self._parse_files("""
52#pragma warning(push)
53void test(void) {
54    __pragma(warning(push))
55    __pragma(warning(disable:6246))
56    __pragma(warning(pop))
57}
58#pragma warning(pop)
59""")
60        self.assertFalse(scanner.get_errors())
61
62    def test_ignore_typeof(self):
63        # https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/71
64        scanner = self._parse_files("""
65/**
66* foo:
67*/
68void foo(int bar) {
69    bar = ((__typeof__(bar)) (foo) (bar));
70}
71""")
72        self.assertEqual(len(list(scanner.get_comments())), 1)
73        self.assertFalse(scanner.get_errors())
74
75    def test_empty_decl(self):
76        # https://gitlab.gnome.org/GNOME/gobject-introspection/issues/216
77        scanner = self._parse_files(";int foo;")
78        self.assertEqual(len(list(scanner.get_symbols())), 1)
79        self.assertFalse(scanner.get_errors())
80
81    def test_bool_no_include(self):
82        # https://gitlab.gnome.org/GNOME/gobject-introspection/issues/247
83        scanner = self._parse_files("bool foo;")
84        self.assertFalse(scanner.get_errors())
85
86
87if __name__ == '__main__':
88    unittest.main()
89