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 os 7 import unittest 8 9 from future import Future 10 from reference_resolver import ReferenceResolver 11 from test_object_store import TestObjectStore 12 from test_util import Server2Path 13 from third_party.json_schema_compiler.model import Namespace 14 15 16 _TEST_DATA = { 17 'baz': { 18 'namespace': 'baz', 19 'description': '', 20 'types': [ 21 { 22 'id': 'baz_t1', 23 'type': 'any', 24 }, 25 { 26 'id': 'baz_t2', 27 'type': 'any', 28 }, 29 { 30 'id': 'baz_t3', 31 'type': 'any', 32 } 33 ], 34 'functions': [ 35 { 36 'name': 'baz_f1', 37 'type': 'function' 38 }, 39 { 40 'name': 'baz_f2', 41 'type': 'function' 42 }, 43 { 44 'name': 'baz_f3', 45 'type': 'function' 46 } 47 ], 48 'events': [ 49 { 50 'name': 'baz_e1', 51 'type': 'function' 52 }, 53 { 54 'name': 'baz_e2', 55 'type': 'function' 56 }, 57 { 58 'name': 'baz_e3', 59 'type': 'function' 60 } 61 ], 62 'properties': { 63 'baz_p1': {'type': 'any'}, 64 'baz_p2': {'type': 'any'}, 65 'baz_p3': {'type': 'any'} 66 } 67 }, 68 'bar.bon': { 69 'namespace': 'bar.bon', 70 'description': '', 71 'types': [ 72 { 73 'id': 'bar_bon_t1', 74 'type': 'any', 75 }, 76 { 77 'id': 'bar_bon_t2', 78 'type': 'any', 79 }, 80 { 81 'id': 'bar_bon_t3', 82 'type': 'any', 83 } 84 ], 85 'functions': [ 86 { 87 'name': 'bar_bon_f1', 88 'type': 'function' 89 }, 90 { 91 'name': 'bar_bon_f2', 92 'type': 'function' 93 }, 94 { 95 'name': 'bar_bon_f3', 96 'type': 'function' 97 } 98 ], 99 'events': [ 100 { 101 'name': 'bar_bon_e1', 102 'type': 'function' 103 }, 104 { 105 'name': 'bar_bon_e2', 106 'type': 'function' 107 }, 108 { 109 'name': 'bar_bon_e3', 110 'type': 'function' 111 } 112 ], 113 'properties': { 114 'bar_bon_p1': {'type': 'any'}, 115 'bar_bon_p2': {'type': 'any'}, 116 'bar_bon_p3': {'type': 'any'} 117 } 118 }, 119 'bar': { 120 'namespace': 'bar', 121 'description': '', 122 'types': [ 123 { 124 'id': 'bar_t1', 125 'type': 'any', 126 'properties': { 127 'bar_t1_p1': { 128 'type': 'any' 129 } 130 } 131 }, 132 { 133 'id': 'bar_t2', 134 'type': 'any', 135 'properties': { 136 'bar_t2_p1': { 137 'type': 'any' 138 } 139 } 140 }, 141 { 142 'id': 'bar_t3', 143 'type': 'any', 144 }, 145 { 146 'id': 'bon', 147 'type': 'any' 148 } 149 ], 150 'functions': [ 151 { 152 'name': 'bar_f1', 153 'type': 'function' 154 }, 155 { 156 'name': 'bar_f2', 157 'type': 'function' 158 }, 159 { 160 'name': 'bar_f3', 161 'type': 'function' 162 } 163 ], 164 'events': [ 165 { 166 'name': 'bar_e1', 167 'type': 'function' 168 }, 169 { 170 'name': 'bar_e2', 171 'type': 'function' 172 }, 173 { 174 'name': 'bar_e3', 175 'type': 'function' 176 } 177 ], 178 'properties': { 179 'bar_p1': {'type': 'any'}, 180 'bar_p2': {'type': 'any'}, 181 'bar_p3': {'$ref': 'bar_t1'} 182 } 183 }, 184 'foo': { 185 'namespace': 'foo', 186 'description': '', 187 'types': [ 188 { 189 'id': 'foo_t1', 190 'type': 'any', 191 }, 192 { 193 'id': 'foo_t2', 194 'type': 'any', 195 }, 196 { 197 'id': 'foo_t3', 198 'type': 'any', 199 'events': [ 200 { 201 'name': 'foo_t3_e1', 202 'type': 'function' 203 } 204 ] 205 } 206 ], 207 'functions': [ 208 { 209 'name': 'foo_f1', 210 'type': 'function' 211 }, 212 { 213 'name': 'foo_f2', 214 'type': 'function' 215 }, 216 { 217 'name': 'foo_f3', 218 'type': 'function' 219 } 220 ], 221 'events': [ 222 { 223 'name': 'foo_e1', 224 'type': 'function' 225 }, 226 { 227 'name': 'foo_e2', 228 'type': 'function' 229 }, 230 { 231 'name': 'foo_e3', 232 'type': 'function' 233 } 234 ], 235 'properties': { 236 'foo_p1': {'$ref': 'foo_t3'}, 237 'foo_p2': {'type': 'any'}, 238 'foo_p3': {'type': 'any'} 239 } 240 } 241 } 242 243 244 class _FakePlatformBundle(object): 245 def __init__(self): 246 self.platforms = ('apps', 'extensions') 247 248 def GetAPIModels(self, platform): 249 if platform == 'apps': 250 return _FakeAPIModels(_TEST_DATA) 251 # Only includes some of the data in the 'extensions' APIModels. 252 # ReferenceResolver will have to look at other platforms to resolve 'foo'. 253 return _FakeAPIModels({ 254 'bar': _TEST_DATA['bar'], 255 'bar.bon': _TEST_DATA['bar.bon'], 256 'baz': _TEST_DATA['baz'] 257 }) 258 259 260 class _FakeAPIModels(object): 261 def __init__(self, apis): 262 self._apis = apis 263 264 def GetNames(self): 265 return self._apis.keys() 266 267 def GetModel(self, name): 268 return Future(value=Namespace(self._apis[name], 'fake/path.json')) 269 270 271 class ReferenceResolverTest(unittest.TestCase): 272 def setUp(self): 273 self._base_path = Server2Path('test_data', 'test_json') 274 275 def _ReadLocalFile(self, filename): 276 with open(os.path.join(self._base_path, filename), 'r') as f: 277 return f.read() 278 279 def testGetLink(self): 280 apps_resolver = ReferenceResolver( 281 _FakePlatformBundle().GetAPIModels('apps'), 282 TestObjectStore('apps/test')) 283 extensions_resolver = ReferenceResolver( 284 _FakePlatformBundle().GetAPIModels('extensions'), 285 TestObjectStore('extensions/test')) 286 287 self.assertEqual({ 288 'href': 'foo', 289 'text': 'foo', 290 'name': 'foo' 291 }, apps_resolver.GetLink('foo', namespace='baz')) 292 self.assertEqual({ 293 'href': 'foo#type-foo_t1', 294 'text': 'foo.foo_t1', 295 'name': 'foo_t1' 296 }, apps_resolver.GetLink('foo.foo_t1', namespace='baz')) 297 self.assertEqual({ 298 'href': 'baz#event-baz_e1', 299 'text': 'baz_e1', 300 'name': 'baz_e1' 301 }, apps_resolver.GetLink('baz.baz_e1', namespace='baz')) 302 self.assertEqual({ 303 'href': 'baz#event-baz_e1', 304 'text': 'baz_e1', 305 'name': 'baz_e1' 306 }, apps_resolver.GetLink('baz_e1', namespace='baz')) 307 self.assertEqual({ 308 'href': 'foo#method-foo_f1', 309 'text': 'foo.foo_f1', 310 'name': 'foo_f1' 311 }, apps_resolver.GetLink('foo.foo_f1', namespace='baz')) 312 self.assertEqual({ 313 'href': 'foo#property-foo_p3', 314 'text': 'foo.foo_p3', 315 'name': 'foo_p3' 316 }, apps_resolver.GetLink('foo.foo_p3', namespace='baz')) 317 self.assertEqual({ 318 'href': 'bar.bon#type-bar_bon_t3', 319 'text': 'bar.bon.bar_bon_t3', 320 'name': 'bar_bon_t3' 321 }, apps_resolver.GetLink('bar.bon.bar_bon_t3', namespace='baz')) 322 self.assertEqual({ 323 'href': 'bar.bon#property-bar_bon_p3', 324 'text': 'bar_bon_p3', 325 'name': 'bar_bon_p3' 326 }, apps_resolver.GetLink('bar_bon_p3', namespace='bar.bon')) 327 self.assertEqual({ 328 'href': 'bar.bon#property-bar_bon_p3', 329 'text': 'bar_bon_p3', 330 'name': 'bar_bon_p3' 331 }, apps_resolver.GetLink('bar.bon.bar_bon_p3', namespace='bar.bon')) 332 self.assertEqual({ 333 'href': 'bar#event-bar_e2', 334 'text': 'bar_e2', 335 'name': 'bar_e2' 336 }, apps_resolver.GetLink('bar.bar_e2', namespace='bar')) 337 self.assertEqual({ 338 'href': 'bar#type-bon', 339 'text': 'bon', 340 'name': 'bon' 341 }, apps_resolver.GetLink('bar.bon', namespace='bar')) 342 self.assertEqual({ 343 'href': 'foo#event-foo_t3-foo_t3_e1', 344 'text': 'foo_t3.foo_t3_e1', 345 'name': 'foo_t3_e1' 346 }, apps_resolver.GetLink('foo_t3.foo_t3_e1', namespace='foo')) 347 self.assertEqual({ 348 'href': 'foo#event-foo_t3-foo_t3_e1', 349 'text': 'foo_t3.foo_t3_e1', 350 'name': 'foo_t3_e1' 351 }, apps_resolver.GetLink('foo.foo_t3.foo_t3_e1', namespace='foo')) 352 self.assertEqual({ 353 'href': 'foo#event-foo_t3-foo_t3_e1', 354 'text': 'foo_t3.foo_t3_e1', 355 'name': 'foo_t3_e1' 356 }, apps_resolver.GetLink('foo.foo_p1.foo_t3_e1', namespace='foo')) 357 self.assertEqual({ 358 'href': 'bar#property-bar_t1-bar_t1_p1', 359 'text': 'bar.bar_t1.bar_t1_p1', 360 'name': 'bar_t1_p1' 361 }, apps_resolver.GetLink('bar.bar_p3.bar_t1_p1', namespace='foo')) 362 # Test extensions_resolver. 363 self.assertEqual({ 364 'href': 'bar#property-bar_t1-bar_t1_p1', 365 'text': 'bar.bar_t1.bar_t1_p1', 366 'name': 'bar_t1_p1' 367 }, extensions_resolver.GetLink('bar.bar_p3.bar_t1_p1', namespace='foo')) 368 self.assertEqual({ 369 'href': 'bar#property-bar_t1-bar_t1_p1', 370 'text': 'bar_t1.bar_t1_p1', 371 'name': 'bar_t1_p1' 372 }, apps_resolver.GetLink('bar_p3.bar_t1_p1', namespace='bar')) 373 self.assertEqual( 374 None, 375 apps_resolver.GetLink('bar.bar_p3.bar_t2_p1', namespace='bar')) 376 self.assertEqual( 377 None, 378 apps_resolver.GetLink('bar.bon.bar_e3', namespace='bar')) 379 self.assertEqual( 380 None, 381 apps_resolver.GetLink('bar_p3', namespace='baz.bon')) 382 self.assertEqual( 383 None, 384 apps_resolver.GetLink('falafel.faf', namespace='a')) 385 self.assertEqual( 386 None, 387 apps_resolver.GetLink('bar_p3', namespace='foo')) 388 # Exists in apps but not extensions. 389 self.assertEqual( 390 None, 391 extensions_resolver.GetLink('foo.foo_p3', namespace='baz')) 392 393 if __name__ == '__main__': 394 unittest.main() 395