| #!/usr/bin/env python3 |
| # Copyright 2012 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import idl_schema |
| import unittest |
| |
| from json_parse import OrderedDict |
| |
| |
| def getFunction(schema, name): |
| for item in schema['functions']: |
| if item['name'] == name: |
| return item |
| raise KeyError('Missing function %s' % name) |
| |
| |
| def getParams(schema, name): |
| function = getFunction(schema, name) |
| return function['parameters'] |
| |
| |
| def getReturnsAsync(schema, name): |
| function = getFunction(schema, name) |
| return function.get('returns_async', False) |
| |
| |
| def getReturns(schema, name): |
| function = getFunction(schema, name) |
| return function['returns'] |
| |
| |
| def getType(schema, id): |
| for item in schema['types']: |
| if item['id'] == id: |
| return item |
| |
| |
| class IdlSchemaTest(unittest.TestCase): |
| |
| def setUp(self): |
| loaded = idl_schema.Load('test/idl_basics.idl') |
| self.assertEqual(1, len(loaded)) |
| self.assertEqual('idl_basics', loaded[0]['namespace']) |
| self.idl_basics = loaded[0] |
| self.maxDiff = None |
| |
| def testNamespaceDescription(self): |
| # Tests the top level namespace description is cleaned up and joined |
| # together as expected. |
| schema = self.idl_basics |
| self.assertEqual( |
| 'Tests a variety of basic API definition features, ensuring things are' |
| ' parsed and processed as expected.', |
| schema['description'], |
| ) |
| |
| def testSimpleCallbacks(self): |
| schema = self.idl_basics |
| expected = {'name': 'cb', 'parameters': []} |
| self.assertEqual(expected, getReturnsAsync(schema, 'function4')) |
| |
| expected = {'name': 'cb', 'parameters': [{'name': 'x', 'type': 'integer'}]} |
| self.assertEqual(expected, getReturnsAsync(schema, 'function5')) |
| |
| expected = { |
| 'name': 'cb', |
| 'parameters': [{ |
| 'name': 'arg', |
| '$ref': 'MyType1' |
| }] |
| } |
| self.assertEqual(expected, getReturnsAsync(schema, 'function6')) |
| |
| def testCallbackWithArrayArgument(self): |
| schema = self.idl_basics |
| expected = { |
| 'name': |
| 'cb', |
| 'parameters': [{ |
| 'name': 'arg', |
| 'type': 'array', |
| 'items': { |
| '$ref': 'MyType2' |
| } |
| }] |
| } |
| self.assertEqual(expected, getReturnsAsync(schema, 'function12')) |
| |
| def testArrayOfCallbacks(self): |
| schema = idl_schema.Load('test/idl_function_types.idl')[0] |
| expected = [{ |
| 'type': 'array', |
| 'name': 'callbacks', |
| 'items': { |
| 'type': 'function', |
| 'name': 'MyCallback', |
| 'parameters': [{ |
| 'type': 'integer', |
| 'name': 'x' |
| }] |
| } |
| }] |
| self.assertEqual(expected, getParams(schema, 'whatever')) |
| |
| def testProperties(self): |
| self.assertEqual( |
| { |
| 'x': { |
| 'name': 'x', |
| 'type': 'integer', |
| 'description': 'This comment tests "double-quotes".' |
| }, |
| 'y': { |
| 'name': 'y', |
| 'type': 'string' |
| }, |
| 'z': { |
| 'name': 'z', |
| 'type': 'string' |
| }, |
| 'a': { |
| 'name': 'a', |
| 'type': 'string' |
| }, |
| 'b': { |
| 'name': 'b', |
| 'type': 'string' |
| }, |
| 'c': { |
| 'name': 'c', |
| 'type': 'string' |
| } |
| }, |
| getType(self.idl_basics, 'MyType1')['properties']) |
| |
| def testMemberOrdering(self): |
| self.assertEqual(['x', 'y', 'z', 'a', 'b', 'c'], |
| list( |
| getType(self.idl_basics, |
| 'MyType1')['properties'].keys())) |
| |
| def testEnum(self): |
| schema = self.idl_basics |
| expected = { |
| 'enum': [{ |
| 'name': 'name1', |
| 'description': 'comment1' |
| }, { |
| 'name': 'name2' |
| }], |
| 'description': 'Enum description', |
| 'type': 'string', |
| 'id': 'EnumType' |
| } |
| self.assertEqual(expected, getType(schema, expected['id'])) |
| |
| expected_params = [{'name': 'type', '$ref': 'EnumType'}] |
| expected_returns_async = { |
| 'name': 'cb', |
| 'parameters': [{ |
| 'name': 'type', |
| '$ref': 'EnumType' |
| }] |
| } |
| self.assertEqual(expected_params, getParams(schema, 'function13')) |
| self.assertEqual(expected_returns_async, |
| getReturnsAsync(schema, 'function13')) |
| |
| expected = [{ |
| 'items': { |
| '$ref': 'EnumType' |
| }, |
| 'name': 'types', |
| 'type': 'array' |
| }] |
| self.assertEqual(expected, getParams(schema, 'function14')) |
| |
| def testScopedArguments(self): |
| schema = self.idl_basics |
| expected = [{'name': 'value', '$ref': 'idl_other_namespace.SomeType'}] |
| self.assertEqual(expected, getParams(schema, 'function20')) |
| |
| expected = [{ |
| 'items': { |
| '$ref': 'idl_other_namespace.SomeType' |
| }, |
| 'name': 'values', |
| 'type': 'array' |
| }] |
| self.assertEqual(expected, getParams(schema, 'function21')) |
| |
| expected = [{ |
| 'name': 'value', |
| '$ref': 'idl_other_namespace.sub_namespace.AnotherType' |
| }] |
| self.assertEqual(expected, getParams(schema, 'function22')) |
| |
| expected = [{ |
| 'items': { |
| '$ref': 'idl_other_namespace.sub_namespace.' |
| 'AnotherType' |
| }, |
| 'name': 'values', |
| 'type': 'array' |
| }] |
| self.assertEqual(expected, getParams(schema, 'function23')) |
| |
| def testNoCompile(self): |
| schema = self.idl_basics |
| func = getFunction(schema, 'function15') |
| self.assertTrue(func is not None) |
| self.assertTrue(func['nocompile']) |
| |
| def testNoDocOnEnum(self): |
| schema = self.idl_basics |
| enum_with_nodoc = getType(schema, 'EnumTypeWithNoDoc') |
| self.assertTrue(enum_with_nodoc is not None) |
| self.assertTrue(enum_with_nodoc['nodoc']) |
| |
| def testNoDocOnEnumValue(self): |
| schema = self.idl_basics |
| expected = { |
| 'enum': [{ |
| 'name': 'name1' |
| }, { |
| 'name': 'name2', |
| 'nodoc': True, |
| 'description': 'comment2' |
| }, { |
| 'name': 'name3', |
| 'description': 'comment3' |
| }], |
| 'type': |
| 'string', |
| 'id': |
| 'EnumTypeWithNoDocValue', |
| 'description': |
| '' |
| } |
| self.assertEqual(expected, getType(schema, expected['id'])) |
| |
| def testReturnTypes(self): |
| schema = self.idl_basics |
| self.assertEqual({ |
| 'name': 'function24', |
| 'type': 'integer' |
| }, getReturns(schema, 'function24')) |
| self.assertEqual({ |
| 'name': 'function25', |
| '$ref': 'MyType1', |
| 'optional': True |
| }, getReturns(schema, 'function25')) |
| self.assertEqual( |
| { |
| 'name': 'function26', |
| 'type': 'array', |
| 'items': { |
| '$ref': 'MyType1' |
| } |
| }, getReturns(schema, 'function26')) |
| self.assertEqual( |
| { |
| 'name': 'function27', |
| '$ref': 'EnumType', |
| 'optional': True |
| }, getReturns(schema, 'function27')) |
| self.assertEqual( |
| { |
| 'name': 'function28', |
| 'type': 'array', |
| 'items': { |
| '$ref': 'EnumType' |
| } |
| }, getReturns(schema, 'function28')) |
| self.assertEqual( |
| { |
| 'name': 'function29', |
| '$ref': 'idl_other_namespace.SomeType', |
| 'optional': True |
| }, getReturns(schema, 'function29')) |
| self.assertEqual( |
| { |
| 'name': 'function30', |
| 'type': 'array', |
| 'items': { |
| '$ref': 'idl_other_namespace.SomeType' |
| } |
| }, getReturns(schema, 'function30')) |
| |
| def testIgnoresAdditionalPropertiesOnType(self): |
| self.assertTrue( |
| getType(self.idl_basics, |
| 'IgnoreAdditionalPropertiesType')['ignoreAdditionalProperties']) |
| |
| def testChromeOSPlatformsNamespace(self): |
| schema = idl_schema.Load('test/idl_namespace_chromeos.idl')[0] |
| self.assertEqual('idl_namespace_chromeos', schema['namespace']) |
| expected = ['chromeos'] |
| self.assertEqual(expected, schema['platforms']) |
| |
| def testAllPlatformsNamespace(self): |
| schema = idl_schema.Load('test/idl_namespace_all_platforms.idl')[0] |
| self.assertEqual('idl_namespace_all_platforms', schema['namespace']) |
| expected = ['chromeos', 'desktop_android', 'linux', 'mac', 'win'] |
| self.assertEqual(expected, schema['platforms']) |
| |
| def testNonSpecificPlatformsNamespace(self): |
| schema = idl_schema.Load('test/idl_namespace_non_specific_platforms.idl')[0] |
| self.assertEqual('idl_namespace_non_specific_platforms', |
| schema['namespace']) |
| expected = None |
| self.assertEqual(expected, schema['platforms']) |
| |
| def testGenerateErrorMessages(self): |
| schema = idl_schema.Load('test/idl_generate_error_messages.idl')[0] |
| self.assertEqual('idl_generate_error_messages', schema['namespace']) |
| self.assertTrue(schema['compiler_options'].get('generate_error_messages', |
| False)) |
| |
| schema = idl_schema.Load('test/idl_basics.idl')[0] |
| self.assertEqual('idl_basics', schema['namespace']) |
| self.assertFalse(schema['compiler_options'].get('generate_error_messages', |
| False)) |
| |
| def testSpecificImplementNamespace(self): |
| schema = idl_schema.Load('test/idl_namespace_specific_implement.idl')[0] |
| self.assertEqual('idl_namespace_specific_implement', schema['namespace']) |
| expected = 'idl_namespace_specific_implement.idl' |
| self.assertEqual(expected, schema['compiler_options']['implemented_in']) |
| |
| def testSpecificImplementOnChromeOSNamespace(self): |
| schema = idl_schema.Load( |
| 'test/idl_namespace_specific_implement_chromeos.idl')[0] |
| self.assertEqual('idl_namespace_specific_implement_chromeos', |
| schema['namespace']) |
| expected_implemented_path = 'idl_namespace_specific_implement_chromeos.idl' |
| expected_platform = ['chromeos'] |
| self.assertEqual(expected_implemented_path, |
| schema['compiler_options']['implemented_in']) |
| self.assertEqual(expected_platform, schema['platforms']) |
| |
| def testCallbackComment(self): |
| schema = self.idl_basics |
| self.assertEqual('A comment on a callback.', |
| getReturnsAsync(schema, 'function16')['description']) |
| self.assertEqual( |
| 'A parameter.', |
| getReturnsAsync(schema, 'function16')['parameters'][0]['description']) |
| self.assertEqual( |
| 'Just a parameter comment, with no comment on the callback.', |
| getReturnsAsync(schema, 'function17')['parameters'][0]['description']) |
| self.assertEqual('Override callback comment.', |
| getReturnsAsync(schema, 'function18')['description']) |
| |
| def testFunctionComment(self): |
| schema = self.idl_basics |
| func = getFunction(schema, 'function3') |
| self.assertEqual(('This comment should appear in the documentation, ' |
| 'despite occupying multiple lines.'), func['description']) |
| self.assertEqual([{ |
| 'description': ('So should this comment about the argument. ' |
| '<em>HTML</em> is fine too.'), |
| 'name': |
| 'arg', |
| '$ref': |
| 'MyType1' |
| }], func['parameters']) |
| func = getFunction(schema, 'function4') |
| self.assertEqual( |
| '<p>This tests if "double-quotes" are escaped correctly.</p>' |
| '<p>It also tests a comment with two newlines.</p>', |
| func['description']) |
| |
| def testReservedWords(self): |
| schema = idl_schema.Load('test/idl_reserved_words.idl')[0] |
| |
| foo_type = getType(schema, 'Foo') |
| self.assertEqual([{ |
| 'name': 'float' |
| }, { |
| 'name': 'DOMString' |
| }], foo_type['enum']) |
| |
| enum_type = getType(schema, 'enum') |
| self.assertEqual([{ |
| 'name': 'callback' |
| }, { |
| 'name': 'namespace' |
| }], enum_type['enum']) |
| |
| dictionary = getType(schema, 'dictionary') |
| self.assertEqual('integer', dictionary['properties']['long']['type']) |
| |
| mytype = getType(schema, 'MyType') |
| self.assertEqual('string', mytype['properties']['interface']['type']) |
| |
| params = getParams(schema, 'static') |
| self.assertEqual('Foo', params[0]['$ref']) |
| self.assertEqual('enum', params[1]['$ref']) |
| |
| def testObjectTypes(self): |
| schema = idl_schema.Load('test/idl_object_types.idl')[0] |
| |
| foo_type = getType(schema, 'FooType') |
| self.assertEqual('object', foo_type['type']) |
| self.assertEqual('integer', foo_type['properties']['x']['type']) |
| self.assertEqual('object', foo_type['properties']['y']['type']) |
| self.assertEqual( |
| 'any', foo_type['properties']['y']['additionalProperties']['type']) |
| self.assertEqual('object', foo_type['properties']['z']['type']) |
| self.assertEqual( |
| 'any', foo_type['properties']['z']['additionalProperties']['type']) |
| self.assertEqual('Window', foo_type['properties']['z']['isInstanceOf']) |
| |
| bar_type = getType(schema, 'BarType') |
| self.assertEqual('object', bar_type['type']) |
| self.assertEqual('any', bar_type['properties']['x']['type']) |
| |
| def testObjectTypesInFunctions(self): |
| schema = idl_schema.Load('test/idl_object_types.idl')[0] |
| |
| params = getParams(schema, 'objectFunction1') |
| self.assertEqual('object', params[0]['type']) |
| self.assertEqual('any', params[0]['additionalProperties']['type']) |
| self.assertEqual('ImageData', params[0]['isInstanceOf']) |
| |
| params = getParams(schema, 'objectFunction2') |
| self.assertEqual('any', params[0]['type']) |
| |
| def testObjectTypesWithOptionalFields(self): |
| schema = idl_schema.Load('test/idl_object_types.idl')[0] |
| |
| baz_type = getType(schema, 'BazType') |
| self.assertEqual(True, baz_type['properties']['x']['optional']) |
| self.assertEqual('integer', baz_type['properties']['x']['type']) |
| self.assertEqual(True, baz_type['properties']['foo']['optional']) |
| self.assertEqual('FooType', baz_type['properties']['foo']['$ref']) |
| |
| def testObjectTypesWithUnions(self): |
| schema = idl_schema.Load('test/idl_object_types.idl')[0] |
| |
| union_type = getType(schema, 'UnionType') |
| expected = { |
| 'type': 'object', |
| 'id': 'UnionType', |
| 'properties': { |
| 'x': { |
| 'name': 'x', |
| 'optional': True, |
| 'choices': [ |
| { |
| 'type': 'integer' |
| }, |
| { |
| '$ref': 'FooType' |
| }, |
| ] |
| }, |
| 'y': { |
| 'name': |
| 'y', |
| 'choices': [{ |
| 'type': 'string' |
| }, { |
| 'type': 'object', |
| 'additionalProperties': { |
| 'type': 'any' |
| } |
| }] |
| }, |
| 'z': { |
| 'name': |
| 'z', |
| 'choices': [{ |
| 'type': 'object', |
| 'isInstanceOf': 'ImageData', |
| 'additionalProperties': { |
| 'type': 'any' |
| } |
| }, { |
| 'type': 'integer' |
| }] |
| } |
| }, |
| } |
| |
| self.assertEqual(expected, union_type) |
| |
| def testUnionsWithModifiers(self): |
| schema = idl_schema.Load('test/idl_object_types.idl')[0] |
| |
| union_type = getType(schema, 'ModifiedUnionType') |
| expected = { |
| 'type': 'object', |
| 'id': 'ModifiedUnionType', |
| 'properties': { |
| 'x': { |
| 'name': 'x', |
| 'nodoc': True, |
| 'choices': [{ |
| 'type': 'integer' |
| }, { |
| 'type': 'string' |
| }] |
| } |
| } |
| } |
| |
| self.assertEqual(expected, union_type) |
| |
| def testSerializableFunctionType(self): |
| schema = idl_schema.Load('test/idl_object_types.idl')[0] |
| object_type = getType(schema, 'SerializableFunctionObject') |
| expected = { |
| 'type': 'object', |
| 'id': 'SerializableFunctionObject', |
| 'properties': { |
| 'func': { |
| 'name': 'func', |
| 'serializableFunction': True, |
| 'type': 'function', |
| 'parameters': [] |
| } |
| } |
| } |
| self.assertEqual(expected, object_type) |
| |
| def testUnionsWithFunctions(self): |
| schema = idl_schema.Load('test/idl_function_types.idl')[0] |
| |
| union_params = getParams(schema, 'union_params') |
| expected = [{ |
| 'name': 'x', |
| 'choices': [{ |
| 'type': 'integer' |
| }, { |
| 'type': 'string' |
| }] |
| }] |
| |
| self.assertEqual(expected, union_params) |
| |
| def testUnionsWithCallbacks(self): |
| schema = idl_schema.Load('test/idl_function_types.idl')[0] |
| |
| blah_params = getReturnsAsync(schema, 'blah') |
| expected = { |
| 'name': |
| 'callback', |
| 'parameters': [{ |
| 'name': 'x', |
| 'choices': [{ |
| 'type': 'integer' |
| }, { |
| 'type': 'string' |
| }] |
| }] |
| } |
| |
| badabish_params = getReturnsAsync(schema, 'badabish') |
| expected = { |
| 'name': |
| 'callback', |
| 'parameters': [{ |
| 'name': 'x', |
| 'optional': True, |
| 'choices': [{ |
| 'type': 'integer' |
| }, { |
| 'type': 'string' |
| }] |
| }] |
| } |
| |
| self.assertEqual(expected, badabish_params) |
| |
| def testFunctionWithoutPromiseSupport(self): |
| schema = idl_schema.Load('test/idl_function_types.idl')[0] |
| |
| expected_params = [] |
| expected_returns_async = { |
| 'name': 'callback', |
| 'parameters': [{ |
| 'name': 'x', |
| 'type': 'integer' |
| }], |
| 'does_not_support_promises': 'Test' |
| } |
| params = getParams(schema, 'non_promise_supporting') |
| returns_async = getReturnsAsync(schema, 'non_promise_supporting') |
| |
| self.assertEqual(expected_params, params) |
| self.assertEqual(expected_returns_async, returns_async) |
| |
| def testFunctionWithoutPromiseSupportAndParams(self): |
| schema = idl_schema.Load('test/idl_function_types.idl')[0] |
| |
| expected_params = [{ |
| 'name': 'z', |
| 'type': 'integer' |
| }, { |
| 'name': 'y', |
| 'choices': [{ |
| 'type': 'integer' |
| }, { |
| 'type': 'string' |
| }] |
| }] |
| expected_returns_async = { |
| 'name': 'callback', |
| 'parameters': [{ |
| 'name': 'x', |
| 'type': 'integer' |
| }], |
| 'does_not_support_promises': 'Test' |
| } |
| params = getParams(schema, 'non_promise_supporting_with_params') |
| returns_async = getReturnsAsync(schema, |
| 'non_promise_supporting_with_params') |
| |
| self.assertEqual(expected_params, params) |
| self.assertEqual(expected_returns_async, returns_async) |
| |
| def testProperties(self): |
| schema = idl_schema.Load('test/idl_properties.idl')[0] |
| self.assertEqual( |
| OrderedDict([ |
| ('first', |
| OrderedDict([ |
| ('description', 'Integer property.'), |
| ('type', 'integer'), |
| ('value', 42), |
| ])), |
| ('second', |
| OrderedDict([ |
| ('description', 'Double property.'), |
| ('type', 'number'), |
| ('value', 42.1), |
| ])), |
| ('third', |
| OrderedDict([ |
| ('description', 'String property.'), |
| ('type', 'string'), |
| ('value', 'hello world'), |
| ])), |
| ('fourth', |
| OrderedDict([ |
| ('description', 'Unvalued property.'), |
| ('type', 'integer'), |
| ])), |
| ]), schema.get('properties')) |
| |
| def testManifestKeys(self): |
| schema = self.idl_basics |
| # Test a smattering of the manifest key generation. We don't make this |
| # exhaustive so we don't have to update it each time we add a new key in the |
| # test file. |
| manifest_keys = schema.get('manifest_keys') |
| self.assertEqual( |
| manifest_keys['key_str'], |
| OrderedDict([('description', 'String manifest key.'), |
| ('name', 'key_str'), ('type', 'string')])) |
| self.assertEqual(manifest_keys['key_ref'], |
| OrderedDict([('name', 'key_ref'), ('$ref', 'MyType2')])), |
| self.assertEqual( |
| manifest_keys['choice_with_arrays'], |
| OrderedDict([('name', 'choice_with_arrays'), |
| ('$ref', 'ChoiceWithArraysType')])), |
| self.assertEqual( |
| manifest_keys['choice_with_optional'], |
| OrderedDict([('name', 'choice_with_optional'), |
| ('$ref', 'ChoiceWithOptionalType')])) |
| |
| def testNoManifestKeys(self): |
| schema = idl_schema.Load('test/idl_properties.idl')[0] |
| self.assertIsNone(schema.get('manifest_keys')) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |