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 6 import idl_schema 7 import unittest 8 9 from json_parse import OrderedDict 10 11 def 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 18 def getParams(schema, name): 19 function = getFunction(schema, name) 20 return function['parameters'] 21 22 23 def getReturns(schema, name): 24 function = getFunction(schema, name) 25 return function['returns'] 26 27 28 def getType(schema, id): 29 for item in schema['types']: 30 if item['id'] == id: 31 return item 32 33 34 class 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(('This tests if "double-quotes" are escaped correctly.' 230 '<br/><br/> It also tests a comment with two newlines.'), 231 func['description']) 232 233 def testReservedWords(self): 234 schema = idl_schema.Load('test/idl_reserved_words.idl')[0] 235 236 foo_type = getType(schema, 'Foo') 237 self.assertEquals([{'name': 'float'}, {'name': 'DOMString'}], 238 foo_type['enum']) 239 240 enum_type = getType(schema, 'enum') 241 self.assertEquals([{'name': 'callback'}, {'name': 'namespace'}], 242 enum_type['enum']) 243 244 dictionary = getType(schema, 'dictionary') 245 self.assertEquals('integer', dictionary['properties']['long']['type']) 246 247 mytype = getType(schema, 'MyType') 248 self.assertEquals('string', mytype['properties']['interface']['type']) 249 250 params = getParams(schema, 'static') 251 self.assertEquals('Foo', params[0]['$ref']) 252 self.assertEquals('enum', params[1]['$ref']) 253 254 def testObjectTypes(self): 255 schema = idl_schema.Load('test/idl_object_types.idl')[0] 256 257 foo_type = getType(schema, 'FooType') 258 self.assertEquals('object', foo_type['type']) 259 self.assertEquals('integer', foo_type['properties']['x']['type']) 260 self.assertEquals('object', foo_type['properties']['y']['type']) 261 self.assertEquals( 262 'any', 263 foo_type['properties']['y']['additionalProperties']['type']) 264 self.assertEquals('object', foo_type['properties']['z']['type']) 265 self.assertEquals( 266 'any', 267 foo_type['properties']['z']['additionalProperties']['type']) 268 self.assertEquals('Window', foo_type['properties']['z']['isInstanceOf']) 269 270 bar_type = getType(schema, 'BarType') 271 self.assertEquals('object', bar_type['type']) 272 self.assertEquals('any', bar_type['properties']['x']['type']) 273 274 def testObjectTypesInFunctions(self): 275 schema = idl_schema.Load('test/idl_object_types.idl')[0] 276 277 params = getParams(schema, 'objectFunction1') 278 self.assertEquals('object', params[0]['type']) 279 self.assertEquals('any', params[0]['additionalProperties']['type']) 280 self.assertEquals('ImageData', params[0]['isInstanceOf']) 281 282 params = getParams(schema, 'objectFunction2') 283 self.assertEquals('any', params[0]['type']) 284 285 def testObjectTypesWithOptionalFields(self): 286 schema = idl_schema.Load('test/idl_object_types.idl')[0] 287 288 baz_type = getType(schema, 'BazType') 289 self.assertEquals(True, baz_type['properties']['x']['optional']) 290 self.assertEquals('integer', baz_type['properties']['x']['type']) 291 self.assertEquals(True, baz_type['properties']['foo']['optional']) 292 self.assertEquals('FooType', baz_type['properties']['foo']['$ref']) 293 294 def testObjectTypesWithUnions(self): 295 schema = idl_schema.Load('test/idl_object_types.idl')[0] 296 297 union_type = getType(schema, 'UnionType') 298 expected = { 299 'type': 'object', 300 'id': 'UnionType', 301 'properties': { 302 'x': { 303 'name': 'x', 304 'optional': True, 305 'choices': [ 306 {'type': 'integer'}, 307 {'$ref': 'FooType'}, 308 ] 309 }, 310 'y': { 311 'name': 'y', 312 'choices': [ 313 {'type': 'string'}, 314 {'type': 'object', 315 'additionalProperties': {'type': 'any'}} 316 ] 317 }, 318 'z': { 319 'name': 'z', 320 'choices': [ 321 {'type': 'object', 'isInstanceOf': 'ImageData', 322 'additionalProperties': {'type': 'any'}}, 323 {'type': 'integer'} 324 ] 325 } 326 }, 327 } 328 329 self.assertEquals(expected, union_type) 330 331 def testUnionsWithModifiers(self): 332 schema = idl_schema.Load('test/idl_object_types.idl')[0] 333 334 union_type = getType(schema, 'ModifiedUnionType') 335 expected = { 336 'type': 'object', 337 'id': 'ModifiedUnionType', 338 'properties': { 339 'x': { 340 'name': 'x', 341 'nodoc': True, 342 'choices': [ 343 {'type': 'integer'}, 344 {'type': 'string'} 345 ] 346 } 347 } 348 } 349 350 self.assertEquals(expected, union_type) 351 352 def testUnionsWithFunctions(self): 353 schema = idl_schema.Load('test/idl_function_types.idl')[0] 354 355 union_params = getParams(schema, 'union_params') 356 expected = [{ 357 'name': 'x', 358 'choices': [ 359 {'type': 'integer'}, 360 {'type': 'string'} 361 ] 362 }] 363 364 self.assertEquals(expected, union_params) 365 366 def testUnionsWithCallbacks(self): 367 schema = idl_schema.Load('test/idl_function_types.idl')[0] 368 369 blah_params = getParams(schema, 'blah') 370 expected = [{ 371 'type': 'function', 'name': 'callback', 'parameters': [{ 372 'name': 'x', 373 'choices': [ 374 {'type': 'integer'}, 375 {'type': 'string'} 376 ]} 377 ] 378 }] 379 self.assertEquals(expected, blah_params) 380 381 badabish_params = getParams(schema, 'badabish') 382 expected = [{ 383 'type': 'function', 'name': 'callback', 'parameters': [{ 384 'name': 'x', 'optional': True, 'choices': [ 385 {'type': 'integer'}, 386 {'type': 'string'} 387 ] 388 }] 389 }] 390 391 self.assertEquals(expected, badabish_params) 392 393 394 if __name__ == '__main__': 395 unittest.main() 396