Home | History | Annotate | Download | only in json_schema_compiler
      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 from cpp_namespace_environment import CppNamespaceEnvironment
      7 from cpp_type_generator import CppTypeGenerator
      8 from json_schema import CachedLoad
      9 import model
     10 import unittest
     11 
     12 from collections import defaultdict
     13 
     14 class _FakeSchemaLoader(object):
     15   def __init__(self, model):
     16     self._model = model
     17 
     18   def ResolveType(self, type_name, default):
     19     parts = type_name.rsplit('.', 1)
     20     if len(parts) == 1:
     21       return default if type_name in default.types else None
     22     return self._model.namespaces[parts[0]]
     23 
     24 class CppTypeGeneratorTest(unittest.TestCase):
     25   def setUp(self):
     26     self.models = defaultdict(model.Model)
     27 
     28     self.forbidden_json = CachedLoad('test/forbidden.json')
     29     self.forbidden = self.models['forbidden'].AddNamespace(
     30         self.forbidden_json[0], 'path/to/forbidden.json')
     31     self.permissions_json = CachedLoad('test/permissions.json')
     32     self.permissions = self.models['permissions'].AddNamespace(
     33         self.permissions_json[0], 'path/to/permissions.json')
     34     self.windows_json = CachedLoad('test/windows.json')
     35     self.windows = self.models['windows'].AddNamespace(self.windows_json[0],
     36                                                        'path/to/window.json')
     37     self.tabs_json = CachedLoad('test/tabs.json')
     38     self.tabs = self.models['tabs'].AddNamespace(self.tabs_json[0],
     39                                                  'path/to/tabs.json')
     40     self.browser_action_json = CachedLoad('test/browser_action.json')
     41     self.browser_action = self.models['browser_action'].AddNamespace(
     42         self.browser_action_json[0], 'path/to/browser_action.json')
     43     self.font_settings_json = CachedLoad('test/font_settings.json')
     44     self.font_settings = self.models['font_settings'].AddNamespace(
     45         self.font_settings_json[0], 'path/to/font_settings.json')
     46     self.dependency_tester_json = CachedLoad('test/dependency_tester.json')
     47     self.dependency_tester = self.models['dependency_tester'].AddNamespace(
     48         self.dependency_tester_json[0], 'path/to/dependency_tester.json')
     49     self.content_settings_json = CachedLoad('test/content_settings.json')
     50     self.content_settings = self.models['content_settings'].AddNamespace(
     51         self.content_settings_json[0], 'path/to/content_settings.json')
     52 
     53   def testGenerateIncludesAndForwardDeclarations(self):
     54     m = model.Model()
     55     m.AddNamespace(self.windows_json[0],
     56                    'path/to/windows.json',
     57                    environment=CppNamespaceEnvironment('%(namespace)s'))
     58     m.AddNamespace(self.tabs_json[0],
     59                    'path/to/tabs.json',
     60                    environment=CppNamespaceEnvironment('%(namespace)s'))
     61     manager = CppTypeGenerator(m, _FakeSchemaLoader(m))
     62 
     63     self.assertEquals('', manager.GenerateIncludes().Render())
     64     self.assertEquals('#include "path/to/tabs.h"',
     65                       manager.GenerateIncludes(include_soft=True).Render())
     66     self.assertEquals(
     67         'namespace tabs {\n'
     68         'struct Tab;\n'
     69         '}  // namespace tabs',
     70         manager.GenerateForwardDeclarations().Render())
     71 
     72     m = model.Model()
     73     m.AddNamespace(self.windows_json[0],
     74                    'path/to/windows.json',
     75                    environment=CppNamespaceEnvironment(
     76                        'foo::bar::%(namespace)s'))
     77     m.AddNamespace(self.tabs_json[0],
     78                    'path/to/tabs.json',
     79                    environment=CppNamespaceEnvironment(
     80                        'foo::bar::%(namespace)s'))
     81     manager = CppTypeGenerator(m, _FakeSchemaLoader(m))
     82     self.assertEquals(
     83         'namespace foo {\n'
     84         'namespace bar {\n'
     85         'namespace tabs {\n'
     86         'struct Tab;\n'
     87         '}  // namespace tabs\n'
     88         '}  // namespace bar\n'
     89         '}  // namespace foo',
     90         manager.GenerateForwardDeclarations().Render())
     91     manager = CppTypeGenerator(self.models.get('permissions'),
     92                                _FakeSchemaLoader(m))
     93     self.assertEquals('', manager.GenerateIncludes().Render())
     94     self.assertEquals('', manager.GenerateIncludes().Render())
     95     self.assertEquals('', manager.GenerateForwardDeclarations().Render())
     96     manager = CppTypeGenerator(self.models.get('content_settings'),
     97                                _FakeSchemaLoader(m))
     98     self.assertEquals('', manager.GenerateIncludes().Render())
     99 
    100   def testGenerateIncludesAndForwardDeclarationsDependencies(self):
    101     m = model.Model()
    102     # Insert 'font_settings' before 'browser_action' in order to test that
    103     # CppTypeGenerator sorts them properly.
    104     m.AddNamespace(self.font_settings_json[0], 'path/to/font_settings.json')
    105     m.AddNamespace(self.browser_action_json[0], 'path/to/browser_action.json')
    106     dependency_tester = m.AddNamespace(self.dependency_tester_json[0],
    107                                        'path/to/dependency_tester.json')
    108     manager = CppTypeGenerator(m,
    109                                _FakeSchemaLoader(m),
    110                                default_namespace=dependency_tester)
    111     self.assertEquals('#include "path/to/browser_action.h"\n'
    112                       '#include "path/to/font_settings.h"',
    113                       manager.GenerateIncludes().Render())
    114     self.assertEquals('', manager.GenerateForwardDeclarations().Render())
    115 
    116   def testGetCppTypeSimple(self):
    117     manager = CppTypeGenerator(self.models.get('tabs'), _FakeSchemaLoader(None))
    118     self.assertEquals(
    119         'int',
    120         manager.GetCppType(self.tabs.types['Tab'].properties['id'].type_))
    121     self.assertEquals(
    122         'std::string',
    123         manager.GetCppType(self.tabs.types['Tab'].properties['status'].type_))
    124     self.assertEquals(
    125         'bool',
    126         manager.GetCppType(self.tabs.types['Tab'].properties['selected'].type_))
    127 
    128   def testStringAsType(self):
    129     manager = CppTypeGenerator(self.models.get('font_settings'),
    130                                _FakeSchemaLoader(None))
    131     self.assertEquals(
    132         'std::string',
    133         manager.GetCppType(self.font_settings.types['FakeStringType']))
    134 
    135   def testArrayAsType(self):
    136     manager = CppTypeGenerator(self.models.get('browser_action'),
    137                                _FakeSchemaLoader(None))
    138     self.assertEquals(
    139         'std::vector<int>',
    140         manager.GetCppType(self.browser_action.types['ColorArray']))
    141 
    142   def testGetCppTypeArray(self):
    143     manager = CppTypeGenerator(self.models.get('windows'),
    144                                 _FakeSchemaLoader(None))
    145     self.assertEquals(
    146         'std::vector<linked_ptr<Window> >',
    147         manager.GetCppType(
    148             self.windows.functions['getAll'].callback.params[0].type_))
    149     manager = CppTypeGenerator(self.models.get('permissions'),
    150                                _FakeSchemaLoader(None))
    151     self.assertEquals(
    152         'std::vector<std::string>',
    153         manager.GetCppType(
    154             self.permissions.types['Permissions'].properties['origins'].type_))
    155 
    156   def testGetCppTypeLocalRef(self):
    157     manager = CppTypeGenerator(self.models.get('tabs'), _FakeSchemaLoader(None))
    158     self.assertEquals(
    159         'Tab',
    160         manager.GetCppType(self.tabs.functions['get'].callback.params[0].type_))
    161 
    162   def testGetCppTypeIncludedRef(self):
    163     m = model.Model()
    164     m.AddNamespace(self.windows_json[0],
    165                    'path/to/windows.json',
    166                    environment=CppNamespaceEnvironment('%(namespace)s'))
    167     m.AddNamespace(self.tabs_json[0],
    168                    'path/to/tabs.json',
    169                    environment=CppNamespaceEnvironment('%(namespace)s'))
    170     manager = CppTypeGenerator(m, _FakeSchemaLoader(m))
    171     self.assertEquals(
    172         'std::vector<linked_ptr<tabs::Tab> >',
    173         manager.GetCppType(
    174             self.windows.types['Window'].properties['tabs'].type_))
    175 
    176   def testGetCppTypeWithPadForGeneric(self):
    177     manager = CppTypeGenerator(self.models.get('permissions'),
    178                                _FakeSchemaLoader(None))
    179     self.assertEquals('std::vector<std::string>',
    180         manager.GetCppType(
    181             self.permissions.types['Permissions'].properties['origins'].type_,
    182             is_in_container=False))
    183     self.assertEquals('linked_ptr<std::vector<std::string> >',
    184         manager.GetCppType(
    185             self.permissions.types['Permissions'].properties['origins'].type_,
    186             is_in_container=True))
    187     self.assertEquals('bool',
    188         manager.GetCppType(
    189             self.permissions.functions['contains'].callback.params[0].type_,
    190         is_in_container=True))
    191 
    192 if __name__ == '__main__':
    193   unittest.main()
    194