| #!/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 database | |
| import idlparser | |
| import logging.config | |
| import os | |
| import os.path | |
| import shutil | |
| import tempfile | |
| import unittest | |
| from databasebuilder import * | |
| class DatabaseBuilderTestCase(unittest.TestCase): | |
| def _create_input(self, idl_file_name, content): | |
| file_name = os.path.join(self._input_dir, idl_file_name) | |
| f = open(file_name, 'w') | |
| f.write(content) | |
| f.close() | |
| return file_name | |
| def _assert_interface_exists(self, path): | |
| file_path = os.path.join(self._database_dir, path) | |
| self.assertTrue(os.path.exists(file_path)) | |
| def _assert_content_equals(self, path, expected_content): | |
| def clean(content): | |
| return ' '.join(filter(len, map(str.strip, content.split('\n')))) | |
| file_path = os.path.join(self._database_dir, path) | |
| self.assertTrue(os.path.exists(file_path)) | |
| f = open(file_path, 'r') | |
| actual_content = f.read() | |
| f.close() | |
| if clean(actual_content) != clean(expected_content): | |
| msg = ''' | |
| FILE: %s | |
| EXPECTED: | |
| %s | |
| ACTUAL: | |
| %s | |
| ''' % (file_path, expected_content, actual_content) | |
| self.fail(msg) | |
| def setUp(self): | |
| working_dir = tempfile.mkdtemp() | |
| self._database_dir = os.path.join(working_dir, 'database') | |
| self.assertFalse(os.path.exists(self._database_dir)) | |
| self._input_dir = os.path.join(working_dir, 'inputdir') | |
| os.makedirs(self._input_dir) | |
| self._db = database.Database(self._database_dir) | |
| self.assertTrue(os.path.exists(self._database_dir)) | |
| self._builder = DatabaseBuilder(self._db) | |
| def tearDown(self): | |
| shutil.rmtree(self._database_dir) | |
| def test_basic_import(self): | |
| file_name = self._create_input('input.idl', ''' | |
| module M { | |
| interface I { | |
| attribute int a; | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_interface_exists('I.idl') | |
| def test_splitting(self): | |
| file_name = self._create_input('input.idl', ''' | |
| module M { | |
| interface I { | |
| readonly attribute int a; | |
| int o(in int x, in optional int y); | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| interface I { | |
| /* Attributes */ | |
| getter attribute int a; | |
| /* Operations */ | |
| int o(in int x); | |
| int o(in int x, in int y); | |
| };''') | |
| def test_renames(self): | |
| file_name = self._create_input('input.idl', ''' | |
| module M { | |
| [Constructor(in T x)] interface I { | |
| T op(T x); | |
| readonly attribute N::T attr; | |
| }; | |
| };''') | |
| options = DatabaseBuilderOptions(type_rename_map={'I': 'i', 'T': 't'}) | |
| self._builder.import_idl_file(file_name, options) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('i.idl', ''' | |
| [Constructor(in t x)] interface i { | |
| /* Attributes */ | |
| getter attribute t attr; | |
| /* Operations */ | |
| t op(in t x); | |
| };''') | |
| def test_type_defs(self): | |
| file_name = self._create_input('input.idl', ''' | |
| module M { | |
| typedef T S; | |
| interface I : S { | |
| S op(S x); | |
| readonly attribute S attr; | |
| }; | |
| };''') | |
| options = DatabaseBuilderOptions() | |
| self._builder.import_idl_file(file_name, options) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| interface I : | |
| T { | |
| /* Attributes */ | |
| getter attribute T attr; | |
| /* Operations */ | |
| T op(in T x); | |
| };''') | |
| def test_merge(self): | |
| file_name1 = self._create_input('input1.idl', ''' | |
| module M { | |
| interface I { | |
| const int CONST_BOTH = 0; | |
| const int CONST_ONLY_FIRST = 0; | |
| const int CONST_BOTH_DIFFERENT_VALUE = 0; | |
| readonly attribute int attr_only_first; | |
| readonly attribute int attr_both; | |
| readonly attribute int attr_both_readonly_difference; | |
| readonly attribute int attr_both_int_long_difference; | |
| int op_only_first(); | |
| int op_both(int a); | |
| int op_both_optionals_difference(int a, | |
| in optional int b); | |
| int op_both_arg_rename(int arg); | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name1, | |
| DatabaseBuilderOptions(source='1st', | |
| idl_syntax=idlparser.FREMONTCUT_SYNTAX)) | |
| file_name2 = self._create_input('input2.idl', ''' | |
| module M { | |
| interface I { | |
| const int CONST_BOTH = 0; | |
| const int CONST_ONLY_SECOND = 0; | |
| const int CONST_BOTH_DIFFERENT_VALUE = 1; | |
| readonly attribute int attr_only_second; | |
| readonly attribute int attr_both; | |
| readonly attribute long attr_both_int_long_difference; | |
| attribute int attr_both_readonly_difference; | |
| int op_only_second(); | |
| int op_both(int a); | |
| int op_both_optionals_difference(int a, | |
| optional boolean b); | |
| int op_both_arg_rename(int betterName); | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name2, | |
| DatabaseBuilderOptions(source='2nd', | |
| idl_syntax=idlparser.FREMONTCUT_SYNTAX)) | |
| self._builder.set_same_signatures({'int': 'long'}) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| @1st(module=M) @2nd(module=M) interface I { | |
| /* Constants */ | |
| @1st @2nd const int CONST_BOTH = 0; | |
| @1st const int CONST_BOTH_DIFFERENT_VALUE = 0; | |
| @2nd const int CONST_BOTH_DIFFERENT_VALUE = 1; | |
| @1st const int CONST_ONLY_FIRST = 0; | |
| @2nd const int CONST_ONLY_SECOND = 0; | |
| /* Attributes */ | |
| @1st @2nd getter attribute int attr_both; | |
| @1st @2nd getter attribute int attr_both_int_long_difference; | |
| @1st @2nd getter attribute int attr_both_readonly_difference; | |
| @2nd setter attribute int attr_both_readonly_difference; | |
| @1st getter attribute int attr_only_first; | |
| @2nd getter attribute int attr_only_second; | |
| /* Operations */ | |
| @1st @2nd int op_both(in t a); | |
| @1st @2nd int op_both_arg_rename(in t betterName); | |
| @1st @2nd int op_both_optionals_difference(in t a); | |
| @1st int op_both_optionals_difference(in t a, in int b); | |
| @2nd int op_both_optionals_difference(in t a, in boolean b); | |
| @1st int op_only_first(); | |
| @2nd int op_only_second(); | |
| };''') | |
| def test_mergeDartName(self): | |
| file_name1 = self._create_input('input1.idl', ''' | |
| module M { | |
| interface I { | |
| [ImplementationFunction=foo] int member(in int a); | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name1, | |
| DatabaseBuilderOptions(source='1st', | |
| idl_syntax=idlparser.FREMONTCUT_SYNTAX)) | |
| file_name2 = self._create_input('input2.idl', ''' | |
| module M { | |
| interface I { | |
| [DartName=bar] int member(in int a); | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name2, | |
| DatabaseBuilderOptions(source='2nd', | |
| idl_syntax=idlparser.FREMONTCUT_SYNTAX)) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| @1st(module=M) @2nd(module=M) interface I { | |
| /* Operations */ | |
| @1st @2nd [DartName=bar, ImplementationFunction=foo] int member(in int a); | |
| };''') | |
| def test_supplemental(self): | |
| file_name = self._create_input('input1.idl', ''' | |
| module M { | |
| interface I { | |
| readonly attribute int a; | |
| }; | |
| [Supplemental] interface I { | |
| readonly attribute int b; | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name, | |
| DatabaseBuilderOptions(source='Src')) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| @Src(module=M) [Supplemental] interface I { | |
| /* Attributes */ | |
| @Src getter attribute int a; | |
| @Src getter attribute int b; | |
| };''') | |
| def test_impl_stmt(self): | |
| file_name = self._create_input('input.idl', ''' | |
| module M { | |
| interface I {}; | |
| I implements J; | |
| };''') | |
| self._builder.import_idl_file(file_name, | |
| DatabaseBuilderOptions(source='Src')) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| @Src(module=M) interface I : | |
| @Src J { | |
| };''') | |
| def test_obsolete(self): | |
| file_name1 = self._create_input('input1.idl', ''' | |
| module M { | |
| interface I { | |
| readonly attribute int keep; | |
| readonly attribute int obsolete; // Would be removed | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name1, | |
| DatabaseBuilderOptions(source='src')) | |
| file_name2 = self._create_input('input2.idl', ''' | |
| module M { | |
| interface I { | |
| readonly attribute int keep; | |
| readonly attribute int new; | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name2, | |
| DatabaseBuilderOptions(source='src', | |
| obsolete_old_declarations=True)) | |
| self._builder.merge_imported_interfaces([]) | |
| self._db.Save() | |
| self._assert_content_equals('I.idl', ''' | |
| @src(module=M) interface I { | |
| /* Attributes */ | |
| @src getter attribute int keep; | |
| @src getter attribute int new; | |
| };''') | |
| def test_annotation_normalization(self): | |
| file_name = self._create_input('input.idl', ''' | |
| module M { | |
| interface I : J{ | |
| const int C = 0; | |
| readonly attribute int a; | |
| int op(); | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name, | |
| DatabaseBuilderOptions(source='Src', source_attributes={'x': 'y'})) | |
| self._builder.merge_imported_interfaces([]) | |
| interface = self._db.GetInterface('I') | |
| interface.parents[0].annotations['Src']['x'] = 'u' | |
| interface.constants[0].annotations['Src']['z'] = 'w' | |
| interface.attributes[0].annotations['Src']['x'] = 'u' | |
| self._db.Save() | |
| # Before normalization | |
| self._assert_content_equals('I.idl', ''' | |
| @Src(module=M, x=y) | |
| interface I : @Src(x=u) J { | |
| /* Constants */ | |
| @Src(x=y, z=w) const int C = 0; | |
| /* Attributes */ | |
| @Src(x=u) getter attribute int a; | |
| /* Operations */ | |
| @Src(x=y) int op(); | |
| };''') | |
| # Normalize | |
| self._builder.normalize_annotations(['Src']) | |
| self._db.Save() | |
| # After normalization | |
| self._assert_content_equals('I.idl', ''' | |
| @Src(module=M, x=y) | |
| interface I : @Src(x=u) J { | |
| /* Constants */ | |
| @Src(z=w) const int C = 0; | |
| /* Attributes */ | |
| @Src(x=u) getter attribute int a; | |
| /* Operations */ | |
| @Src int op(); | |
| };''') | |
| def test_fix_displacements(self): | |
| file_name1 = self._create_input('input1.idl', ''' | |
| module M { | |
| interface I {}; | |
| interface J : I { | |
| readonly attribute int attr; | |
| }; | |
| };''') | |
| self._builder.import_idl_file(file_name1, | |
| DatabaseBuilderOptions(source='1st')) | |
| file_name2 = self._create_input('input2.idl', ''' | |
| module M { | |
| interface I { | |
| readonly attribute int attr; | |
| }; | |
| interface J : I {}; | |
| };''') | |
| self._builder.import_idl_file(file_name2, | |
| DatabaseBuilderOptions(source='2nd')) | |
| self._builder.merge_imported_interfaces([]) | |
| self._builder.fix_displacements('2nd') | |
| self._db.Save() | |
| self._assert_content_equals('J.idl', ''' | |
| @1st(module=M) @2nd(module=M) interface J : | |
| @1st @2nd I { | |
| /* Attributes */ | |
| @1st | |
| @2nd(via=I) | |
| getter attribute int attr; | |
| };''') | |
| if __name__ == "__main__": | |
| logging.config.fileConfig("logging.conf") | |
| if __name__ == '__main__': | |
| unittest.main() |