1#!/usr/bin/env python 2# Copyright (c) 2012 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import idl_schema 7import unittest 8 9from json_parse import OrderedDict 10 11def getFunction(schema, name): 12 for item in schema['functions']: 13 if item['name'] == name: 14 return item 15 raise KeyError('Missing function %s' % name) 16 17 18def getParams(schema, name): 19 function = getFunction(schema, name) 20 return function['parameters'] 21 22 23def getReturns(schema, name): 24 function = getFunction(schema, name) 25 return function['returns'] 26 27 28def getType(schema, id): 29 for item in schema['types']: 30 if item['id'] == id: 31 return item 32 33 34class IdlSchemaTest(unittest.TestCase): 35 def setUp(self): 36 loaded = idl_schema.Load('test/idl_basics.idl') 37 self.assertEquals(1, len(loaded)) 38 self.assertEquals('idl_basics', loaded[0]['namespace']) 39 self.idl_basics = loaded[0] 40 self.maxDiff = None 41 42 def testSimpleCallbacks(self): 43 schema = self.idl_basics 44 expected = [{'type': 'function', 'name': 'cb', 'parameters':[]}] 45 self.assertEquals(expected, getParams(schema, 'function4')) 46 47 expected = [{'type': 'function', 'name': 'cb', 48 'parameters':[{'name': 'x', 'type': 'integer'}]}] 49 self.assertEquals(expected, getParams(schema, 'function5')) 50 51 expected = [{'type': 'function', 'name': 'cb', 52 'parameters':[{'name': 'arg', '$ref': 'MyType1'}]}] 53 self.assertEquals(expected, getParams(schema, 'function6')) 54 55 def testCallbackWithArrayArgument(self): 56 schema = self.idl_basics 57 expected = [{'type': 'function', 'name': 'cb', 58 'parameters':[{'name': 'arg', 'type': 'array', 59 'items':{'$ref': 'MyType2'}}]}] 60 self.assertEquals(expected, getParams(schema, 'function12')) 61 62 63 def testArrayOfCallbacks(self): 64 schema = idl_schema.Load('test/idl_function_types.idl')[0] 65 expected = [{'type': 'array', 'name': 'callbacks', 66 'items':{'type': 'function', 'name': 'MyCallback', 67 'parameters':[{'type': 'integer', 'name': 'x'}]}}] 68 self.assertEquals(expected, getParams(schema, 'whatever')) 69 70 def testLegalValues(self): 71 self.assertEquals({ 72 'x': {'name': 'x', 'type': 'integer', 'enum': [1,2], 73 'description': 'This comment tests "double-quotes".'}, 74 'y': {'name': 'y', 'type': 'string'}, 75 'z': {'name': 'z', 'type': 'string'}, 76 'a': {'name': 'a', 'type': 'string'}, 77 'b': {'name': 'b', 'type': 'string'}, 78 'c': {'name': 'c', 'type': 'string'}}, 79 getType(self.idl_basics, 'MyType1')['properties']) 80 81 def testMemberOrdering(self): 82 self.assertEquals( 83 ['x', 'y', 'z', 'a', 'b', 'c'], 84 getType(self.idl_basics, 'MyType1')['properties'].keys()) 85 86 def testEnum(self): 87 schema = self.idl_basics 88 expected = {'enum': [{'name': 'name1', 'description': 'comment1'}, 89 {'name': 'name2'}], 90 'description': 'Enum description', 91 'type': 'string', 'id': 'EnumType'} 92 self.assertEquals(expected, getType(schema, expected['id'])) 93 94 expected = [{'name': 'type', '$ref': 'EnumType'}, 95 {'type': 'function', 'name': 'cb', 96 'parameters':[{'name': 'type', '$ref': 'EnumType'}]}] 97 self.assertEquals(expected, getParams(schema, 'function13')) 98 99 expected = [{'items': {'$ref': 'EnumType'}, 'name': 'types', 100 'type': 'array'}] 101 self.assertEquals(expected, getParams(schema, 'function14')) 102 103 def testScopedArguments(self): 104 schema = self.idl_basics 105 expected = [{'name': 'value', '$ref': 'idl_other_namespace.SomeType'}] 106 self.assertEquals(expected, getParams(schema, 'function20')) 107 108 expected = [{'items': {'$ref': 'idl_other_namespace.SomeType'}, 109 'name': 'values', 110 'type': 'array'}] 111 self.assertEquals(expected, getParams(schema, 'function21')) 112 113 expected = [{'name': 'value', 114 '$ref': 'idl_other_namespace.sub_namespace.AnotherType'}] 115 self.assertEquals(expected, getParams(schema, 'function22')) 116 117 expected = [{'items': {'$ref': 'idl_other_namespace.sub_namespace.' 118 'AnotherType'}, 119 'name': 'values', 120 'type': 'array'}] 121 self.assertEquals(expected, getParams(schema, 'function23')) 122 123 def testNoCompile(self): 124 schema = self.idl_basics 125 func = getFunction(schema, 'function15') 126 self.assertTrue(func is not None) 127 self.assertTrue(func['nocompile']) 128 129 def testNoDocOnEnum(self): 130 schema = self.idl_basics 131 enum_with_nodoc = getType(schema, 'EnumTypeWithNoDoc') 132 self.assertTrue(enum_with_nodoc is not None) 133 self.assertTrue(enum_with_nodoc['nodoc']) 134 135 def testInternalNamespace(self): 136 idl_basics = self.idl_basics 137 self.assertEquals('idl_basics', idl_basics['namespace']) 138 self.assertTrue(idl_basics['internal']) 139 self.assertFalse(idl_basics['nodoc']) 140 141 def testReturnTypes(self): 142 schema = self.idl_basics 143 self.assertEquals({'name': 'function24', 'type': 'integer'}, 144 getReturns(schema, 'function24')) 145 self.assertEquals({'name': 'function25', '$ref': 'MyType1', 146 'optional': True}, 147 getReturns(schema, 'function25')) 148 self.assertEquals({'name': 'function26', 'type': 'array', 149 'items': {'$ref': 'MyType1'}}, 150 getReturns(schema, 'function26')) 151 self.assertEquals({'name': 'function27', '$ref': 'EnumType', 152 'optional': True}, 153 getReturns(schema, 'function27')) 154 self.assertEquals({'name': 'function28', 'type': 'array', 155 'items': {'$ref': 'EnumType'}}, 156 getReturns(schema, 'function28')) 157 self.assertEquals({'name': 'function29', '$ref': 158 'idl_other_namespace.SomeType', 159 'optional': True}, 160 getReturns(schema, 'function29')) 161 self.assertEquals({'name': 'function30', 'type': 'array', 162 'items': {'$ref': 'idl_other_namespace.SomeType'}}, 163 getReturns(schema, 'function30')) 164 165 def testChromeOSPlatformsNamespace(self): 166 schema = idl_schema.Load('test/idl_namespace_chromeos.idl')[0] 167 self.assertEquals('idl_namespace_chromeos', schema['namespace']) 168 expected = ['chromeos'] 169 self.assertEquals(expected, schema['platforms']) 170 171 def testAllPlatformsNamespace(self): 172 schema = idl_schema.Load('test/idl_namespace_all_platforms.idl')[0] 173 self.assertEquals('idl_namespace_all_platforms', schema['namespace']) 174 expected = ['chromeos', 'chromeos_touch', 'linux', 'mac', 'win'] 175 self.assertEquals(expected, schema['platforms']) 176 177 def testNonSpecificPlatformsNamespace(self): 178 schema = idl_schema.Load('test/idl_namespace_non_specific_platforms.idl')[0] 179 self.assertEquals('idl_namespace_non_specific_platforms', 180 schema['namespace']) 181 expected = None 182 self.assertEquals(expected, schema['platforms']) 183 184 def testSpecificImplementNamespace(self): 185 schema = idl_schema.Load('test/idl_namespace_specific_implement.idl')[0] 186 self.assertEquals('idl_namespace_specific_implement', 187 schema['namespace']) 188 expected = 'idl_namespace_specific_implement.idl' 189 self.assertEquals(expected, schema['compiler_options']['implemented_in']) 190 191 def testSpecificImplementOnChromeOSNamespace(self): 192 schema = idl_schema.Load( 193 'test/idl_namespace_specific_implement_chromeos.idl')[0] 194 self.assertEquals('idl_namespace_specific_implement_chromeos', 195 schema['namespace']) 196 expected_implemented_path = 'idl_namespace_specific_implement_chromeos.idl' 197 expected_platform = ['chromeos'] 198 self.assertEquals(expected_implemented_path, 199 schema['compiler_options']['implemented_in']) 200 self.assertEquals(expected_platform, schema['platforms']) 201 202 def testCallbackComment(self): 203 schema = self.idl_basics 204 self.assertEquals('A comment on a callback.', 205 getParams(schema, 'function16')[0]['description']) 206 self.assertEquals( 207 'A parameter.', 208 getParams(schema, 'function16')[0]['parameters'][0]['description']) 209 self.assertEquals( 210 'Just a parameter comment, with no comment on the callback.', 211 getParams(schema, 'function17')[0]['parameters'][0]['description']) 212 self.assertEquals( 213 'Override callback comment.', 214 getParams(schema, 'function18')[0]['description']) 215 216 def testFunctionComment(self): 217 schema = self.idl_basics 218 func = getFunction(schema, 'function3') 219 self.assertEquals(('This comment should appear in the documentation, ' 220 'despite occupying multiple lines.'), 221 func['description']) 222 self.assertEquals( 223 [{'description': ('So should this comment about the argument. ' 224 '<em>HTML</em> is fine too.'), 225 'name': 'arg', 226 '$ref': 'MyType1'}], 227 func['parameters']) 228 func = getFunction(schema, 'function4') 229 self.assertEquals( 230 '<p>This tests if "double-quotes" are escaped correctly.</p>' 231 '<p>It also tests a comment with two newlines.</p>', 232 func['description']) 233 234 def testReservedWords(self): 235 schema = idl_schema.Load('test/idl_reserved_words.idl')[0] 236 237 foo_type = getType(schema, 'Foo') 238 self.assertEquals([{'name': 'float'}, {'name': 'DOMString'}], 239 foo_type['enum']) 240 241 enum_type = getType(schema, 'enum') 242 self.assertEquals([{'name': 'callback'}, {'name': 'namespace'}], 243 enum_type['enum']) 244 245 dictionary = getType(schema, 'dictionary') 246 self.assertEquals('integer', dictionary['properties']['long']['type']) 247 248 mytype = getType(schema, 'MyType') 249 self.assertEquals('string', mytype['properties']['interface']['type']) 250 251 params = getParams(schema, 'static') 252 self.assertEquals('Foo', params[0]['$ref']) 253 self.assertEquals('enum', params[1]['$ref']) 254 255 def testObjectTypes(self): 256 schema = idl_schema.Load('test/idl_object_types.idl')[0] 257 258 foo_type = getType(schema, 'FooType') 259 self.assertEquals('object', foo_type['type']) 260 self.assertEquals('integer', foo_type['properties']['x']['type']) 261 self.assertEquals('object', foo_type['properties']['y']['type']) 262 self.assertEquals( 263 'any', 264 foo_type['properties']['y']['additionalProperties']['type']) 265 self.assertEquals('object', foo_type['properties']['z']['type']) 266 self.assertEquals( 267 'any', 268 foo_type['properties']['z']['additionalProperties']['type']) 269 self.assertEquals('Window', foo_type['properties']['z']['isInstanceOf']) 270 271 bar_type = getType(schema, 'BarType') 272 self.assertEquals('object', bar_type['type']) 273 self.assertEquals('any', bar_type['properties']['x']['type']) 274 275 def testObjectTypesInFunctions(self): 276 schema = idl_schema.Load('test/idl_object_types.idl')[0] 277 278 params = getParams(schema, 'objectFunction1') 279 self.assertEquals('object', params[0]['type']) 280 self.assertEquals('any', params[0]['additionalProperties']['type']) 281 self.assertEquals('ImageData', params[0]['isInstanceOf']) 282 283 params = getParams(schema, 'objectFunction2') 284 self.assertEquals('any', params[0]['type']) 285 286 def testObjectTypesWithOptionalFields(self): 287 schema = idl_schema.Load('test/idl_object_types.idl')[0] 288 289 baz_type = getType(schema, 'BazType') 290 self.assertEquals(True, baz_type['properties']['x']['optional']) 291 self.assertEquals('integer', baz_type['properties']['x']['type']) 292 self.assertEquals(True, baz_type['properties']['foo']['optional']) 293 self.assertEquals('FooType', baz_type['properties']['foo']['$ref']) 294 295 def testObjectTypesWithUnions(self): 296 schema = idl_schema.Load('test/idl_object_types.idl')[0] 297 298 union_type = getType(schema, 'UnionType') 299 expected = { 300 'type': 'object', 301 'id': 'UnionType', 302 'properties': { 303 'x': { 304 'name': 'x', 305 'optional': True, 306 'choices': [ 307 {'type': 'integer'}, 308 {'$ref': 'FooType'}, 309 ] 310 }, 311 'y': { 312 'name': 'y', 313 'choices': [ 314 {'type': 'string'}, 315 {'type': 'object', 316 'additionalProperties': {'type': 'any'}} 317 ] 318 }, 319 'z': { 320 'name': 'z', 321 'choices': [ 322 {'type': 'object', 'isInstanceOf': 'ImageData', 323 'additionalProperties': {'type': 'any'}}, 324 {'type': 'integer'} 325 ] 326 } 327 }, 328 } 329 330 self.assertEquals(expected, union_type) 331 332 def testUnionsWithModifiers(self): 333 schema = idl_schema.Load('test/idl_object_types.idl')[0] 334 335 union_type = getType(schema, 'ModifiedUnionType') 336 expected = { 337 'type': 'object', 338 'id': 'ModifiedUnionType', 339 'properties': { 340 'x': { 341 'name': 'x', 342 'nodoc': True, 343 'choices': [ 344 {'type': 'integer'}, 345 {'type': 'string'} 346 ] 347 } 348 } 349 } 350 351 self.assertEquals(expected, union_type) 352 353 def testUnionsWithFunctions(self): 354 schema = idl_schema.Load('test/idl_function_types.idl')[0] 355 356 union_params = getParams(schema, 'union_params') 357 expected = [{ 358 'name': 'x', 359 'choices': [ 360 {'type': 'integer'}, 361 {'type': 'string'} 362 ] 363 }] 364 365 self.assertEquals(expected, union_params) 366 367 def testUnionsWithCallbacks(self): 368 schema = idl_schema.Load('test/idl_function_types.idl')[0] 369 370 blah_params = getParams(schema, 'blah') 371 expected = [{ 372 'type': 'function', 'name': 'callback', 'parameters': [{ 373 'name': 'x', 374 'choices': [ 375 {'type': 'integer'}, 376 {'type': 'string'} 377 ]} 378 ] 379 }] 380 self.assertEquals(expected, blah_params) 381 382 badabish_params = getParams(schema, 'badabish') 383 expected = [{ 384 'type': 'function', 'name': 'callback', 'parameters': [{ 385 'name': 'x', 'optional': True, 'choices': [ 386 {'type': 'integer'}, 387 {'type': 'string'} 388 ] 389 }] 390 }] 391 392 self.assertEquals(expected, badabish_params) 393 394 395if __name__ == '__main__': 396 unittest.main() 397