blob: d3669249a1593269724658a270b7438e99e73942 [file] [log] [blame]
# 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.items():
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())