| # Copyright 2016 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # pylint: disable=import-error,print-statement,relative-import,protected-access |
| |
| """Unit tests for code_generator_web_agent_api.py.""" |
| |
| import unittest |
| |
| from code_generator_web_agent_api import InterfaceContextBuilder |
| from code_generator_web_agent_api import MethodOverloadSplitter |
| from code_generator_web_agent_api import STRING_INCLUDE_PATH |
| from code_generator_web_agent_api import TypeResolver |
| from idl_definitions import IdlArgument |
| from idl_definitions import IdlAttribute |
| from idl_definitions import IdlOperation |
| from idl_types import IdlType |
| from idl_types import IdlNullableType |
| from idl_types import IdlUnionType |
| from idl_types import PRIMITIVE_TYPES |
| from idl_types import STRING_TYPES |
| |
| |
| # TODO(dglazkov): Convert to use actual objects, not stubs. |
| # See http://crbug.com/673214 for more details. |
| class IdlTestingHelper(object): |
| """A collection of stub makers and helper utils to make testing code |
| generation easy.""" |
| |
| def make_stub_idl_argument(self, name, idl_type, is_optional=False): |
| idl_argument = IdlArgument() |
| idl_argument.name = name |
| idl_argument.idl_type = idl_type |
| idl_argument.is_optional = is_optional |
| return idl_argument |
| |
| def make_stub_idl_attribute(self, name, return_type): |
| idl_attribute_stub = IdlAttribute() |
| idl_attribute_stub.name = name |
| idl_attribute_stub.idl_type = IdlType(return_type) |
| return idl_attribute_stub |
| |
| def make_stub_idl_operation(self, name, return_type): |
| idl_operation_stub = IdlOperation() |
| idl_operation_stub.name = name |
| idl_operation_stub.idl_type = IdlType(return_type) |
| return idl_operation_stub |
| |
| def make_stub_idl_type(self, base_type): |
| return IdlType(base_type) |
| |
| def make_stub_interfaces_info(self, classes_to_paths): |
| result = {} |
| for class_name, path in classes_to_paths.iteritems(): |
| result[class_name] = {'include_path': path} |
| return result |
| |
| |
| class TypeResolverTest(unittest.TestCase): |
| |
| def test_includes_from_type_should_filter_primitive_types(self): |
| helper = IdlTestingHelper() |
| type_resolver = TypeResolver({}) |
| for primitive_type in PRIMITIVE_TYPES: |
| idl_type = helper.make_stub_idl_type(primitive_type) |
| self.assertEqual( |
| type_resolver._includes_from_type(idl_type), set()) |
| |
| def test_includes_from_type_should_filter_void(self): |
| type_resolver = TypeResolver({}) |
| helper = IdlTestingHelper() |
| idl_type = helper.make_stub_idl_type('void') |
| self.assertEqual( |
| type_resolver._includes_from_type(idl_type), set()) |
| |
| def test_includes_from_type_should_handle_string(self): |
| type_resolver = TypeResolver({}) |
| helper = IdlTestingHelper() |
| for string_type in STRING_TYPES: |
| idl_type = helper.make_stub_idl_type(string_type) |
| self.assertEqual( |
| type_resolver._includes_from_type(idl_type), |
| set([STRING_INCLUDE_PATH])) |
| |
| |
| class MethodOverloadSplitterTest(unittest.TestCase): |
| |
| def test_enumerate_argument_types(self): |
| splitter = MethodOverloadSplitter(IdlOperation()) |
| nullable_and_primitive = IdlArgument() |
| nullable_and_primitive.idl_type = IdlNullableType(IdlType('double')) |
| with self.assertRaises(ValueError): |
| splitter._enumerate_argument_types(nullable_and_primitive) |
| |
| argument = IdlArgument() |
| foo_type = IdlType('Foo') |
| bar_type = IdlType('Bar') |
| |
| argument.idl_type = foo_type |
| self.assertEqual( |
| splitter._enumerate_argument_types(argument), [foo_type]) |
| |
| argument.is_optional = True |
| self.assertEqual( |
| splitter._enumerate_argument_types(argument), [None, foo_type]) |
| |
| argument.is_optional = False |
| argument.idl_type = IdlUnionType([foo_type, bar_type]) |
| self.assertEqual( |
| splitter._enumerate_argument_types(argument), [foo_type, bar_type]) |
| |
| argument.is_optional = True |
| self.assertEqual( |
| splitter._enumerate_argument_types(argument), |
| [None, foo_type, bar_type]) |
| |
| def test_update_argument_lists(self): |
| splitter = MethodOverloadSplitter(IdlOperation()) |
| foo_type = IdlType('Foo') |
| bar_type = IdlType('Bar') |
| baz_type = IdlType('Baz') |
| qux_type = IdlType('Qux') |
| |
| result = splitter._update_argument_lists([[]], [foo_type]) |
| self.assertEqual(result, [[foo_type]]) |
| |
| result = splitter._update_argument_lists([[]], [foo_type, bar_type]) |
| self.assertEqual(result, [[foo_type], [bar_type]]) |
| |
| existing_list = [[foo_type]] |
| result = splitter._update_argument_lists(existing_list, [bar_type]) |
| self.assertEqual(result, [[foo_type, bar_type]]) |
| |
| existing_list = [[foo_type]] |
| result = splitter._update_argument_lists(existing_list, |
| [None, bar_type]) |
| self.assertEqual(result, [[foo_type], [foo_type, bar_type]]) |
| |
| existing_list = [[foo_type]] |
| result = splitter._update_argument_lists(existing_list, |
| [bar_type, baz_type]) |
| self.assertEqual(result, [[foo_type, bar_type], [foo_type, baz_type]]) |
| |
| existing_list = [[foo_type], [qux_type]] |
| result = splitter._update_argument_lists(existing_list, |
| [bar_type, baz_type]) |
| self.assertEqual(result, [ |
| [foo_type, bar_type], |
| [foo_type, baz_type], |
| [qux_type, bar_type], |
| [qux_type, baz_type], |
| ]) |
| |
| existing_list = [[foo_type], [qux_type]] |
| result = splitter._update_argument_lists(existing_list, |
| [None, bar_type, baz_type]) |
| self.assertEqual(result, [ |
| [foo_type], |
| [foo_type, bar_type], |
| [foo_type, baz_type], |
| [qux_type], |
| [qux_type, bar_type], |
| [qux_type, baz_type], |
| ]) |
| |
| existing_list = [[foo_type, qux_type]] |
| result = splitter._update_argument_lists(existing_list, |
| [bar_type, baz_type]) |
| self.assertEqual(result, [ |
| [foo_type, qux_type, bar_type], |
| [foo_type, qux_type, baz_type], |
| ]) |
| |
| def test_split_into_overloads(self): |
| helper = IdlTestingHelper() |
| type_double = IdlType('double') |
| type_foo = IdlType('foo') |
| type_double_or_foo = IdlUnionType([type_double, type_foo]) |
| idl_operation = IdlOperation() |
| |
| idl_operation.arguments = [] |
| splitter = MethodOverloadSplitter(idl_operation) |
| result = splitter.split_into_overloads() |
| self.assertEqual(result, [[]]) |
| |
| idl_operation.arguments = [ |
| helper.make_stub_idl_argument(None, type_double, True) |
| ] |
| splitter = MethodOverloadSplitter(idl_operation) |
| result = splitter.split_into_overloads() |
| self.assertEqual(result, [[], [type_double]]) |
| |
| idl_operation.arguments = [ |
| helper.make_stub_idl_argument(None, type_double_or_foo) |
| ] |
| splitter = MethodOverloadSplitter(idl_operation) |
| result = splitter.split_into_overloads() |
| self.assertEqual(result, [[type_double], [type_foo]]) |
| |
| def test_split_add_event_listener(self): |
| """Tests how EventTarget.addEventListener is split into respective |
| overloads. From: |
| |
| void addEventListener( |
| DOMString type, |
| EventListener? listener, |
| optional (AddEventListenerOptions or boolean) options) |
| |
| produces: """ |
| |
| helper = IdlTestingHelper() |
| type_dom_string = IdlType('DOMString') |
| type_listener = IdlType('EventListener') |
| type_options = IdlType('AddEventListenerOptions') |
| type_boolean = IdlType('boolean') |
| type_union = IdlUnionType([type_options, type_boolean]) |
| idl_operation = IdlOperation() |
| idl_operation.arguments = [ |
| helper.make_stub_idl_argument('type', type_dom_string), |
| helper.make_stub_idl_argument('listener', type_listener), |
| helper.make_stub_idl_argument('options', type_union, |
| is_optional=True)] |
| splitter = MethodOverloadSplitter(idl_operation) |
| result = splitter.split_into_overloads() |
| self.assertEqual( |
| result, |
| [[type_dom_string, type_listener], |
| [type_dom_string, type_listener, type_options], |
| [type_dom_string, type_listener, type_boolean]]) |
| |
| |
| class InterfaceContextBuilderTest(unittest.TestCase): |
| |
| def test_empty(self): |
| builder = InterfaceContextBuilder('test', TypeResolver({})) |
| |
| self.assertEqual({'code_generator': 'test'}, builder.build()) |
| |
| def test_set_name(self): |
| helper = IdlTestingHelper() |
| builder = InterfaceContextBuilder( |
| 'test', TypeResolver(helper.make_stub_interfaces_info({ |
| 'foo': 'path_to_foo', |
| }))) |
| |
| builder.set_class_name('foo') |
| self.assertEqual({ |
| 'code_generator': 'test', |
| 'cpp_includes': set(['path_to_foo']), |
| 'class_name': { |
| 'snake_case': 'foo', |
| 'macro_case': 'FOO', |
| 'upper_camel_case': 'Foo' |
| }, |
| }, builder.build()) |
| |
| def test_set_inheritance(self): |
| helper = IdlTestingHelper() |
| builder = InterfaceContextBuilder( |
| 'test', TypeResolver(helper.make_stub_interfaces_info({ |
| 'foo': 'path_to_foo', |
| }))) |
| builder.set_inheritance('foo') |
| self.assertEqual({ |
| 'base_class': 'foo', |
| 'code_generator': 'test', |
| 'header_includes': set(['path_to_foo']), |
| }, builder.build()) |
| |
| builder = InterfaceContextBuilder('test', TypeResolver({})) |
| builder.set_inheritance(None) |
| self.assertEqual({ |
| 'code_generator': 'test', |
| 'header_includes': set(['platform/heap/Handle.h']), |
| }, builder.build()) |
| |
| def test_add_attribute(self): |
| helper = IdlTestingHelper() |
| builder = InterfaceContextBuilder( |
| 'test', TypeResolver(helper.make_stub_interfaces_info({ |
| 'foo': 'path_to_foo', |
| 'bar': 'path_to_bar' |
| }))) |
| |
| attribute = helper.make_stub_idl_attribute('foo', 'bar') |
| builder.add_attribute(attribute) |
| self.assertEqual({ |
| 'code_generator': 'test', |
| 'cpp_includes': set(['path_to_bar']), |
| 'attributes': [{'name': 'foo', 'type': 'bar'}], |
| }, builder.build()) |
| |
| def test_add_method(self): |
| helper = IdlTestingHelper() |
| builder = InterfaceContextBuilder( |
| 'test', TypeResolver(helper.make_stub_interfaces_info({ |
| 'foo': 'path_to_foo', |
| 'bar': 'path_to_bar', |
| 'garply': 'path_to_garply', |
| }))) |
| |
| operation = helper.make_stub_idl_operation('foo', 'bar') |
| builder.add_operation(operation) |
| self.assertEqual({ |
| 'code_generator': 'test', |
| 'cpp_includes': set(['path_to_bar']), |
| 'methods': [{ |
| 'arguments': [], |
| 'name': 'Foo', |
| 'type': 'bar' |
| }], |
| }, builder.build()) |
| |
| operation = helper.make_stub_idl_operation('quux', 'garply') |
| operation.arguments = [ |
| helper.make_stub_idl_argument('barBaz', IdlType('qux')) |
| ] |
| builder.add_operation(operation) |
| self.assertEqual({ |
| 'code_generator': 'test', |
| 'cpp_includes': set(['path_to_bar', 'path_to_garply']), |
| 'methods': [ |
| { |
| 'arguments': [], |
| 'name': 'Foo', |
| 'type': 'bar' |
| }, |
| { |
| 'arguments': [ |
| {'name': 'bar_baz', 'type': 'qux'} |
| ], |
| 'name': 'Quux', |
| 'type': 'garply' |
| } |
| ], |
| }, builder.build()) |