blob: 7467b3edee7a1f9598ff9d4135b472c22b2a370c [file] [log] [blame]
#!/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 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()