• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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