| #!/usr/bin/python |
| # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| # for details. All rights reserved. Use of this source code is governed by a |
| # BSD-style license that can be found in the LICENSE file. |
| |
| import idlparser |
| import logging.config |
| import sys |
| import unittest |
| |
| |
| class IDLParserTestCase(unittest.TestCase): |
| |
| def _run_test(self, syntax, content, expected): |
| """Utility for running a IDL parsing tests and comparing results. |
| |
| Program exits (sys.exit) if expected does not match actual. |
| |
| Args: |
| syntax -- IDL grammar to use (either idlparser.WEBKIT_SYNTAX, |
| WEBIDL_SYNTAX or FREMONTCUT_SYNTAX). If None, will run |
| multiple tests, each with a different syntax. |
| content -- input text for the parser. |
| expected -- expected parse result. |
| """ |
| |
| all_syntaxes = {idlparser.WEBIDL_SYNTAX: 'Web IDL', |
| idlparser.WEBKIT_SYNTAX: 'WebKit', |
| idlparser.FREMONTCUT_SYNTAX: 'FremontCut'} |
| |
| if syntax is None: |
| for syntax in all_syntaxes: |
| self._run_test(syntax, content, expected) |
| return |
| |
| if syntax not in all_syntaxes: |
| raise RuntimeError('Unexpected syntax %s' % syntax) |
| |
| actual = None |
| error = None |
| try: |
| parser = idlparser.IDLParser(syntax) |
| actual = parser.parse(content) |
| except SyntaxError, e: |
| error = e |
| pass |
| if actual != expected: |
| self.fail(''' |
| SYNTAX : %s |
| CONTENT : |
| %s |
| EXPECTED: |
| %s |
| ACTUAL : |
| %s |
| ERROR : %s''' % (all_syntaxes[syntax], content, expected, actual, error)) |
| |
| def test_empty_module(self): |
| self._run_test( |
| None, |
| 'module M {};', |
| [('Module', [('Id', 'M')])]) |
| |
| def test_empty_interface(self): |
| self._run_test( |
| None, |
| 'interface I {};', |
| [('Interface', [('Id', 'I')])]) |
| |
| def test_module_with_empty_interface(self): |
| self._run_test( |
| None, |
| 'module M { interface I {}; };', |
| [('Module', [('Id', 'M'), ('Interface', [('Id', 'I')])])]) |
| |
| # testing the gcc pre-processing |
| def test_gcc_preprocessing(self): |
| self._run_test( |
| idlparser.WEBKIT_SYNTAX, |
| ''' |
| #if 1 |
| module M1 {}; |
| #endif |
| #if 0 |
| module M2 {}; |
| #endif |
| ''', |
| [('Module', [('Id', 'M1')])]) |
| |
| def test_attribute_with_exceptoins(self): |
| self._run_test( |
| idlparser.WEBKIT_SYNTAX, |
| '''interface I { |
| attribute boolean A setter raises (E), getter raises (E); |
| };''', |
| [('Interface', [('Id', 'I'), ('Attribute', [('Type', [('BooleanType', None)]), ('Id', 'A'), ('SetRaises', [('ScopedName', 'E')]), ('GetRaises', [('ScopedName', 'E')])])])]) |
| |
| def test_interface_with_extended_attributes(self): |
| self._run_test( |
| idlparser.WEBKIT_SYNTAX, |
| 'interface [ExAt1, ExAt2] I {};', |
| [('Interface', [('ExtAttrs', [('ExtAttr', [('Id', 'ExAt1')]), ('ExtAttr', [('Id', 'ExAt2')])]), ('Id', 'I')])]) |
| |
| def test_implements_statement(self): |
| self._run_test( |
| idlparser.WEBIDL_SYNTAX, |
| 'X implements Y;', |
| [('ImplStmt', [('ImplStmtImplementor', ('ScopedName', 'X')), ('ImplStmtImplemented', ('ScopedName', 'Y'))])]) |
| |
| def test_operation(self): |
| self._run_test( |
| None, |
| 'interface I { boolean func(); };', |
| [('Interface', [('Id', 'I'), ('Operation', [('ReturnType', [('BooleanType', None)]), ('Id', 'func')])])]) |
| |
| def test_attribute_types(self): |
| self._run_test( |
| None, |
| '''interface I { |
| attribute boolean boolAttr; |
| attribute DOMString strAttr; |
| attribute SomeType someAttr; |
| };''', |
| [('Interface', [('Id', 'I'), ('Attribute', [('Type', [('BooleanType', None)]), ('Id', 'boolAttr')]), ('Attribute', [('Type', [('ScopedName', 'DOMString')]), ('Id', 'strAttr')]), ('Attribute', [('Type', [('ScopedName', 'SomeType')]), ('Id', 'someAttr')])])]) |
| |
| def test_constants(self): |
| self._run_test( |
| None, |
| '''interface I { |
| const long c1 = 0; |
| const long c2 = 1; |
| const long c3 = 0x01; |
| const long c4 = 10; |
| const boolean b1 = true; |
| const boolean b1 = false; |
| };''', |
| [('Interface', [('Id', 'I'), ('Const', [('Type', [('LongType', None)]), ('Id', 'c1'), ('ConstExpr', '0')]), ('Const', [('Type', [('LongType', None)]), ('Id', 'c2'), ('ConstExpr', '1')]), ('Const', [('Type', [('LongType', None)]), ('Id', 'c3'), ('ConstExpr', '0x01')]), ('Const', [('Type', [('LongType', None)]), ('Id', 'c4'), ('ConstExpr', '10')]), ('Const', [('Type', [('BooleanType', None)]), ('Id', 'b1'), ('ConstExpr', 'true')]), ('Const', [('Type', [('BooleanType', None)]), ('Id', 'b1'), ('ConstExpr', 'false')])])]) |
| |
| def test_inheritance(self): |
| self._run_test( |
| None, |
| ''' |
| interface Shape {}; |
| interface Rectangle : Shape {}; |
| interface Square : Rectangle, Shape {}; |
| ''', |
| [('Interface', [('Id', 'Shape')]), ('Interface', [('Id', 'Rectangle'), ('ParentInterface', [('InterfaceType', ('ScopedName', 'Shape'))])]), ('Interface', [('Id', 'Square'), ('ParentInterface', [('InterfaceType', ('ScopedName', 'Rectangle'))]), ('ParentInterface', [('InterfaceType', ('ScopedName', 'Shape'))])])]) |
| |
| def test_annotations(self): |
| self._run_test( |
| idlparser.FREMONTCUT_SYNTAX, |
| '@Ano1 @Ano2() @Ano3(x) @Ano4(x=1,y=2) interface I {};', |
| [('Interface', [('Annotation', [('Id', 'Ano1')]), ('Annotation', [('Id', 'Ano2')]), ('Annotation', [('Id', 'Ano3'), ('AnnotationArg', [('Id', 'x')])]), ('Annotation', [('Id', 'Ano4'), ('AnnotationArg', [('Id', 'x'), ('AnnotationArgValue', '1')]), ('AnnotationArg', [('Id', 'y'), ('AnnotationArgValue', '2')])]), ('Id', 'I')])]) |
| |
| |
| if __name__ == "__main__": |
| logging.config.fileConfig("logging.conf") |
| if __name__ == '__main__': |
| unittest.main() |