| #!/usr/bin/env python3 | |
| # 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 idlnode | |
| import idlparser | |
| import logging.config | |
| import sys | |
| import unittest | |
| class IDLNodeTestCase(unittest.TestCase): | |
| def _run_test(self, syntax, content, expected): | |
| """Utility run tests and prints extra contextual information. | |
| 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. | |
| """ | |
| if syntax is None: | |
| self._run_test(idlparser.WEBIDL_SYNTAX, content, expected) | |
| self._run_test(idlparser.WEBKIT_SYNTAX, content, expected) | |
| self._run_test(idlparser.FREMONTCUT_SYNTAX, content, expected) | |
| return | |
| actual = None | |
| error = None | |
| ast = None | |
| parseResult = None | |
| try: | |
| parser = idlparser.IDLParser(syntax) | |
| ast = parser.parse(content) | |
| node = idlnode.IDLFile(ast) | |
| actual = node.to_dict() if node else None | |
| except SyntaxError as e: | |
| error = e | |
| pass | |
| if actual == expected: | |
| return | |
| else: | |
| msg = ''' | |
| SYNTAX : %s | |
| CONTENT : | |
| %s | |
| EXPECTED: | |
| %s | |
| ACTUAL : | |
| %s | |
| ERROR : %s | |
| AST : | |
| %s | |
| ''' % (syntax, content, expected, actual, error, ast) | |
| self.fail(msg) | |
| def test_empty_module(self): | |
| self._run_test(None, 'module TestModule {};', | |
| {'modules': [{ | |
| 'id': 'TestModule' | |
| }]}) | |
| def test_empty_interface(self): | |
| self._run_test( | |
| None, 'module TestModule { interface Interface1 {}; };', { | |
| 'modules': [{ | |
| 'interfaces': [{ | |
| 'javascript_binding_name': 'Interface1', | |
| 'doc_js_name': 'Interface1', | |
| 'id': 'Interface1' | |
| }], | |
| 'id': | |
| 'TestModule' | |
| }] | |
| }) | |
| def test_gcc_preprocessor(self): | |
| self._run_test(idlparser.WEBKIT_SYNTAX, | |
| '#if 1\nmodule TestModule {};\n#endif\n', | |
| {'modules': [{ | |
| 'id': 'TestModule' | |
| }]}) | |
| def test_extended_attributes(self): | |
| self._run_test( | |
| idlparser.WEBKIT_SYNTAX, | |
| 'module M { interface [ExAt1, ExAt2] I {};};', { | |
| 'modules': [{ | |
| 'interfaces': [{ | |
| 'javascript_binding_name': 'I', | |
| 'doc_js_name': 'I', | |
| 'ext_attrs': { | |
| 'ExAt1': None, | |
| 'ExAt2': None | |
| }, | |
| 'id': 'I' | |
| }], | |
| 'id': | |
| 'M' | |
| }] | |
| }) | |
| def test_implements_statement(self): | |
| self._run_test( | |
| idlparser.WEBIDL_SYNTAX, 'module M { X implements Y; };', { | |
| 'modules': [{ | |
| 'implementsStatements': [{ | |
| 'implementor': { | |
| 'id': 'X' | |
| }, | |
| 'implemented': { | |
| 'id': 'Y' | |
| } | |
| }], | |
| 'id': | |
| 'M' | |
| }] | |
| }) | |
| def test_attributes(self): | |
| self._run_test( | |
| idlparser.WEBIDL_SYNTAX, '''interface I { | |
| attribute long a1; | |
| readonly attribute DOMString a2; | |
| attribute any a3; | |
| };''', { | |
| 'interfaces': [{ | |
| 'javascript_binding_name': | |
| 'I', | |
| 'attributes': [{ | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'a1', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'DOMString' | |
| }, | |
| 'is_read_only': True, | |
| 'id': 'a2', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'any' | |
| }, | |
| 'id': 'a3', | |
| 'doc_js_interface_name': 'I' | |
| }], | |
| 'id': | |
| 'I', | |
| 'doc_js_name': | |
| 'I' | |
| }] | |
| }) | |
| def test_operations(self): | |
| self._run_test( | |
| idlparser.WEBIDL_SYNTAX, '''interface I { | |
| [ExAttr] t1 op1(); | |
| t2 op2(in int arg1, in long arg2); | |
| getter any item(in long index); | |
| };''', { | |
| 'interfaces': [{ | |
| 'operations': | |
| [{ | |
| 'doc_js_interface_name': 'I', | |
| 'type': { | |
| 'id': 't1' | |
| }, | |
| 'ext_attrs': { | |
| 'ExAttr': None | |
| }, | |
| 'id': 'op1' | |
| }, | |
| { | |
| 'doc_js_interface_name': | |
| 'I', | |
| 'type': { | |
| 'id': 't2' | |
| }, | |
| 'id': | |
| 'op2', | |
| 'arguments': [{ | |
| 'type': { | |
| 'id': 'int' | |
| }, | |
| 'id': 'arg1' | |
| }, { | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'arg2' | |
| }] | |
| }, | |
| { | |
| 'specials': ['getter'], | |
| 'doc_js_interface_name': 'I', | |
| 'type': { | |
| 'id': 'any' | |
| }, | |
| 'id': 'item', | |
| 'arguments': [{ | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'index' | |
| }] | |
| }, | |
| { | |
| 'is_stringifier': True, | |
| 'type': { | |
| 'id': 'name' | |
| }, | |
| 'doc_js_interface_name': 'I' | |
| }], | |
| 'javascript_binding_name': | |
| 'I', | |
| 'id': | |
| 'I', | |
| 'doc_js_name': | |
| 'I' | |
| }] | |
| }) | |
| 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 = false; | |
| const boolean b2 = true; | |
| };''', { | |
| 'interfaces': [{ | |
| 'javascript_binding_name': | |
| 'I', | |
| 'doc_js_name': | |
| 'I', | |
| 'id': | |
| 'I', | |
| 'constants': [{ | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'c1', | |
| 'value': '0', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'c2', | |
| 'value': '1', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'c3', | |
| 'value': '0x01', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'long' | |
| }, | |
| 'id': 'c4', | |
| 'value': '10', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'boolean' | |
| }, | |
| 'id': 'b1', | |
| 'value': 'false', | |
| 'doc_js_interface_name': 'I' | |
| }, | |
| { | |
| 'type': { | |
| 'id': 'boolean' | |
| }, | |
| 'id': 'b2', | |
| 'value': 'true', | |
| 'doc_js_interface_name': 'I' | |
| }] | |
| }] | |
| }) | |
| def test_annotations(self): | |
| self._run_test( | |
| idlparser.FREMONTCUT_SYNTAX, | |
| '@Ano1 @Ano2() @Ano3(x=1) @Ano4(x,y=2) interface I {};', { | |
| 'interfaces': [{ | |
| 'javascript_binding_name': 'I', | |
| 'doc_js_name': 'I', | |
| 'id': 'I', | |
| 'annotations': { | |
| 'Ano4': { | |
| 'y': '2', | |
| 'x': None | |
| }, | |
| 'Ano1': {}, | |
| 'Ano2': {}, | |
| 'Ano3': { | |
| 'x': '1' | |
| } | |
| } | |
| }] | |
| }) | |
| self._run_test( | |
| idlparser.FREMONTCUT_SYNTAX, '''interface I : @Ano1 J { | |
| @Ano2 attribute int someAttr; | |
| @Ano3 void someOp(); | |
| @Ano3 const int someConst = 0; | |
| };''', { | |
| 'interfaces': [{ | |
| 'operations': [{ | |
| 'annotations': { | |
| 'Ano3': {} | |
| }, | |
| 'type': { | |
| 'id': 'void' | |
| }, | |
| 'id': 'someOp', | |
| 'doc_js_interface_name': 'I' | |
| }], | |
| 'javascript_binding_name': | |
| 'I', | |
| 'parents': [{ | |
| 'type': { | |
| 'id': 'J' | |
| }, | |
| 'annotations': { | |
| 'Ano1': {} | |
| } | |
| }], | |
| 'attributes': [{ | |
| 'annotations': { | |
| 'Ano2': {} | |
| }, | |
| 'type': { | |
| 'id': 'int' | |
| }, | |
| 'id': 'someAttr', | |
| 'doc_js_interface_name': 'I' | |
| }], | |
| 'doc_js_name': | |
| 'I', | |
| 'id': | |
| 'I', | |
| 'constants': [{ | |
| 'annotations': { | |
| 'Ano3': {} | |
| }, | |
| 'type': { | |
| 'id': 'int' | |
| }, | |
| 'id': 'someConst', | |
| 'value': '0', | |
| 'doc_js_interface_name': 'I' | |
| }] | |
| }] | |
| }) | |
| def test_inheritance(self): | |
| self._run_test( | |
| None, | |
| 'interface Shape {}; interface Rectangle : Shape {}; interface Square : Rectangle, Shape {};', | |
| { | |
| 'interfaces': [{ | |
| 'javascript_binding_name': 'Shape', | |
| 'doc_js_name': 'Shape', | |
| 'id': 'Shape' | |
| }, | |
| { | |
| 'javascript_binding_name': 'Rectangle', | |
| 'doc_js_name': 'Rectangle', | |
| 'parents': [{ | |
| 'type': { | |
| 'id': 'Shape' | |
| } | |
| }], | |
| 'id': 'Rectangle' | |
| }, | |
| { | |
| 'javascript_binding_name': | |
| 'Square', | |
| 'doc_js_name': | |
| 'Square', | |
| 'parents': [{ | |
| 'type': { | |
| 'id': 'Rectangle' | |
| } | |
| }, { | |
| 'type': { | |
| 'id': 'Shape' | |
| } | |
| }], | |
| 'id': | |
| 'Square' | |
| }] | |
| }) | |
| if __name__ == "__main__": | |
| logging.config.fileConfig("logging.conf") | |
| if __name__ == '__main__': | |
| unittest.main() |