Initial packaging for Tizen
[profile/ivi/gobject-introspection.git] / tests / warn / warningtester.py
1 import difflib
2 import os
3 import os.path
4 import sys
5 from StringIO import StringIO
6 import __builtin__
7
8 path=os.getenv('UNINSTALLED_INTROSPECTION_SRCDIR', None)
9 assert path is not None
10 sys.path.insert(0, path)
11
12 # Not correct, but enough to get the tests going uninstalled
13 __builtin__.__dict__['DATADIR'] = path
14
15 from giscanner.annotationparser import AnnotationParser
16 from giscanner.ast import Include, Namespace
17 from giscanner.introspectablepass import IntrospectablePass
18 from giscanner.maintransformer import MainTransformer
19 from giscanner.message import MessageLogger
20 from giscanner.sourcescanner import SourceScanner
21 from giscanner.transformer import Transformer
22 from giscanner.scannermain import process_packages
23
24 currentdir = os.path.dirname(os.path.abspath(sys.argv[0]))
25 current_name = os.path.basename(currentdir)
26 path = os.path.abspath(os.path.join(currentdir, '..', ''))
27 top_srcdir = os.environ['UNINSTALLED_INTROSPECTION_SRCDIR']
28 top_builddir = os.environ['TOP_BUILDDIR']
29
30 class Options:
31     def __init__(self):
32         self.cpp_includes = []
33         self.cpp_defines = []
34         self.cpp_undefines = []
35         self.library_paths = []
36
37 def _diff(orig, new, short):
38     def _tolines(s):
39         return [s + '\n' for line in s.split('\n')]
40     lines = difflib.unified_diff(_tolines(orig),
41                                  _tolines(new))
42     if not lines:
43         return
44
45     diff = False
46     try:
47         first = lines.next()
48         diff = True
49     except StopIteration:
50         pass
51     else:
52         print 'ERROR: while comparing %s:' % (short, )
53         for line in list(lines)[2:]:
54             print '%s: %r' % (short, line[:-1])
55
56     return diff
57
58 def _extract_expected(filename):
59     fd = open(filename)
60     data = fd.read()
61
62     retval = []
63     for line in data.split('\n'):
64         if line.startswith('// EXPECT:'):
65             sort_key = None
66             if ":" in line:
67                 try:
68                     sort_key = int(line.split(":")[1])
69                 except ValueError:
70                     pass
71             retval.append((sort_key, line[10:]))
72     return retval
73
74 def check(args):
75     filename = args[0]
76
77     output = StringIO()
78     namespace = Namespace("Test", "1.0")
79     logger = MessageLogger.get(namespace=namespace,
80                                output=output)
81     logger.enable_warnings(True)
82     transformer = Transformer(namespace)
83     transformer.set_include_paths([os.path.join(top_srcdir, 'gir'), top_builddir])
84     transformer.register_include(Include.from_string("GObject-2.0"))
85
86     ss = SourceScanner()
87
88     options = Options()
89     exit_code = process_packages(options, ['gobject-2.0'])
90     if exit_code:
91         sys.exit(exit_code)
92     ss.set_cpp_options(options.cpp_includes,
93                        options.cpp_defines,
94                        options.cpp_undefines)
95     ss.parse_files([filename])
96     ss.parse_macros([filename])
97     transformer.parse(ss.get_symbols())
98
99     ap = AnnotationParser()
100     blocks = ap.parse(ss.get_comments())
101
102     main = MainTransformer(transformer, blocks)
103     main.transform()
104
105     final = IntrospectablePass(transformer, blocks)
106     final.validate()
107
108     raw = output.getvalue()
109     if raw.endswith('\n'):
110         raw = raw[:-1]
111     warnings = raw.split('\n')
112
113     failed_tests = 0
114     expected_warnings = _extract_expected(filename)
115     if '' in warnings:
116         warnings.remove('')
117     if len(expected_warnings) != len(warnings):
118         raise SystemExit(
119             "ERROR in %r: expected %d warnings, but got %d:\n"
120             "----\nexpected:\n%s\n----\ngot:\n%s\n----" % (
121             os.path.basename(filename),
122             len(expected_warnings), len(warnings),
123             '\n'.join([w[1] for w in expected_warnings]),
124             '\n'.join([w.split(':', 2)[2][1:] for w in warnings])))
125     for warning, (sort_key, expected) in zip(warnings, expected_warnings):
126         actual = warning.split(":", 1)[1]
127         if _diff(expected, actual, filename):
128             raise SystemExit("ERROR: tests %r failed" % (filename, ))
129
130 sys.exit(check(sys.argv[1:]))