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