#!/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()