test_adapter.py 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. ##############################################################################
  2. #
  3. # Copyright (c) 2003 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################################################
  14. """Adapter registry tests
  15. """
  16. import unittest
  17. def _makeInterfaces():
  18. from zope.interface import Interface
  19. class IB0(Interface): pass
  20. class IB1(IB0): pass
  21. class IB2(IB0): pass
  22. class IB3(IB2, IB1): pass
  23. class IB4(IB1, IB2): pass
  24. class IF0(Interface): pass
  25. class IF1(IF0): pass
  26. class IR0(Interface): pass
  27. class IR1(IR0): pass
  28. return IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1
  29. class BaseAdapterRegistryTests(unittest.TestCase):
  30. def _getTargetClass(self):
  31. from zope.interface.adapter import BaseAdapterRegistry
  32. class _CUT(BaseAdapterRegistry):
  33. class LookupClass(object):
  34. _changed = _extendors = ()
  35. def __init__(self, reg):
  36. pass
  37. def changed(self, orig):
  38. self._changed += (orig,)
  39. def add_extendor(self, provided):
  40. self._extendors += (provided,)
  41. def remove_extendor(self, provided):
  42. self._extendors = tuple([x for x in self._extendors
  43. if x != provided])
  44. for name in BaseAdapterRegistry._delegated:
  45. setattr(_CUT.LookupClass, name, object())
  46. return _CUT
  47. def _makeOne(self):
  48. return self._getTargetClass()()
  49. def test_lookup_delegation(self):
  50. CUT = self._getTargetClass()
  51. registry = CUT()
  52. for name in CUT._delegated:
  53. self.assertTrue(
  54. getattr(registry, name) is getattr(registry._v_lookup, name))
  55. def test__generation_on_first_creation(self):
  56. registry = self._makeOne()
  57. # Bumped to 1 in BaseAdapterRegistry.__init__
  58. self.assertEqual(registry._generation, 1)
  59. def test__generation_after_calling_changed(self):
  60. registry = self._makeOne()
  61. orig = object()
  62. registry.changed(orig)
  63. # Bumped to 1 in BaseAdapterRegistry.__init__
  64. self.assertEqual(registry._generation, 2)
  65. self.assertEqual(registry._v_lookup._changed, (registry, orig,))
  66. def test__generation_after_changing___bases__(self):
  67. class _Base(object): pass
  68. registry = self._makeOne()
  69. registry.__bases__ = (_Base,)
  70. self.assertEqual(registry._generation, 2)
  71. def test_register(self):
  72. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  73. registry = self._makeOne()
  74. registry.register([IB0], IR0, '', 'A1')
  75. self.assertEqual(registry.registered([IB0], IR0, ''), 'A1')
  76. self.assertEqual(len(registry._adapters), 2) #order 0 and order 1
  77. self.assertEqual(registry._generation, 2)
  78. def test_register_with_invalid_name(self):
  79. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  80. registry = self._makeOne()
  81. with self.assertRaises(ValueError):
  82. registry.register([IB0], IR0, object(), 'A1')
  83. def test_register_with_value_None_unregisters(self):
  84. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  85. registry = self._makeOne()
  86. registry.register([None], IR0, '', 'A1')
  87. registry.register([None], IR0, '', None)
  88. self.assertEqual(len(registry._adapters), 0)
  89. def test_register_with_same_value(self):
  90. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  91. registry = self._makeOne()
  92. _value = object()
  93. registry.register([None], IR0, '', _value)
  94. _before = registry._generation
  95. registry.register([None], IR0, '', _value)
  96. self.assertEqual(registry._generation, _before) # skipped changed()
  97. def test_registered_empty(self):
  98. registry = self._makeOne()
  99. self.assertEqual(registry.registered([None], None, ''), None)
  100. def test_registered_non_empty_miss(self):
  101. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  102. registry = self._makeOne()
  103. registry.register([IB1], None, '', 'A1')
  104. self.assertEqual(registry.registered([IB2], None, ''), None)
  105. def test_registered_non_empty_hit(self):
  106. registry = self._makeOne()
  107. registry.register([None], None, '', 'A1')
  108. self.assertEqual(registry.registered([None], None, ''), 'A1')
  109. def test_unregister_empty(self):
  110. registry = self._makeOne()
  111. registry.unregister([None], None, '') #doesn't raise
  112. self.assertEqual(registry.registered([None], None, ''), None)
  113. def test_unregister_non_empty_miss_on_required(self):
  114. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  115. registry = self._makeOne()
  116. registry.register([IB1], None, '', 'A1')
  117. registry.unregister([IB2], None, '') #doesn't raise
  118. self.assertEqual(registry.registered([IB1], None, ''), 'A1')
  119. def test_unregister_non_empty_miss_on_name(self):
  120. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  121. registry = self._makeOne()
  122. registry.register([IB1], None, '', 'A1')
  123. registry.unregister([IB1], None, 'nonesuch') #doesn't raise
  124. self.assertEqual(registry.registered([IB1], None, ''), 'A1')
  125. def test_unregister_with_value_not_None_miss(self):
  126. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  127. registry = self._makeOne()
  128. orig = object()
  129. nomatch = object()
  130. registry.register([IB1], None, '', orig)
  131. registry.unregister([IB1], None, '', nomatch) #doesn't raise
  132. self.assertTrue(registry.registered([IB1], None, '') is orig)
  133. def test_unregister_hit_clears_empty_subcomponents(self):
  134. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  135. registry = self._makeOne()
  136. one = object()
  137. another = object()
  138. registry.register([IB1, IB2], None, '', one)
  139. registry.register([IB1, IB3], None, '', another)
  140. self.assertTrue(IB2 in registry._adapters[2][IB1])
  141. self.assertTrue(IB3 in registry._adapters[2][IB1])
  142. registry.unregister([IB1, IB3], None, '', another)
  143. self.assertTrue(IB2 in registry._adapters[2][IB1])
  144. self.assertFalse(IB3 in registry._adapters[2][IB1])
  145. def test_unsubscribe_empty(self):
  146. registry = self._makeOne()
  147. registry.unsubscribe([None], None, '') #doesn't raise
  148. self.assertEqual(registry.registered([None], None, ''), None)
  149. def test_unsubscribe_hit(self):
  150. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  151. registry = self._makeOne()
  152. orig = object()
  153. registry.subscribe([IB1], None, orig)
  154. registry.unsubscribe([IB1], None, orig) #doesn't raise
  155. self.assertEqual(len(registry._subscribers), 0)
  156. def test_unsubscribe_after_multiple(self):
  157. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  158. registry = self._makeOne()
  159. first = object()
  160. second = object()
  161. third = object()
  162. fourth = object()
  163. registry.subscribe([IB1], None, first)
  164. registry.subscribe([IB1], None, second)
  165. registry.subscribe([IB1], IR0, third)
  166. registry.subscribe([IB1], IR0, fourth)
  167. registry.unsubscribe([IB1], IR0, fourth)
  168. registry.unsubscribe([IB1], IR0, third)
  169. registry.unsubscribe([IB1], None, second)
  170. registry.unsubscribe([IB1], None, first)
  171. self.assertEqual(len(registry._subscribers), 0)
  172. def test_unsubscribe_w_None_after_multiple(self):
  173. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  174. registry = self._makeOne()
  175. first = object()
  176. second = object()
  177. third = object()
  178. registry.subscribe([IB1], None, first)
  179. registry.subscribe([IB1], None, second)
  180. registry.unsubscribe([IB1], None)
  181. self.assertEqual(len(registry._subscribers), 0)
  182. def test_unsubscribe_non_empty_miss_on_required(self):
  183. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  184. registry = self._makeOne()
  185. registry.subscribe([IB1], None, 'A1')
  186. self.assertEqual(len(registry._subscribers), 2)
  187. registry.unsubscribe([IB2], None, '') #doesn't raise
  188. self.assertEqual(len(registry._subscribers), 2)
  189. def test_unsubscribe_non_empty_miss_on_value(self):
  190. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  191. registry = self._makeOne()
  192. registry.subscribe([IB1], None, 'A1')
  193. self.assertEqual(len(registry._subscribers), 2)
  194. registry.unsubscribe([IB1], None, 'A2') #doesn't raise
  195. self.assertEqual(len(registry._subscribers), 2)
  196. def test_unsubscribe_with_value_not_None_miss(self):
  197. IB0, IB1, IB2, IB3, IB4, IF0, IF1, IR0, IR1 = _makeInterfaces()
  198. registry = self._makeOne()
  199. orig = object()
  200. nomatch = object()
  201. registry.subscribe([IB1], None, orig)
  202. registry.unsubscribe([IB1], None, nomatch) #doesn't raise
  203. self.assertEqual(len(registry._subscribers), 2)
  204. class LookupBaseFallbackTests(unittest.TestCase):
  205. def _getTargetClass(self):
  206. from zope.interface.adapter import LookupBaseFallback
  207. return LookupBaseFallback
  208. def _makeOne(self, uc_lookup=None, uc_lookupAll=None,
  209. uc_subscriptions=None):
  210. if uc_lookup is None:
  211. def uc_lookup(self, required, provided, name):
  212. pass
  213. if uc_lookupAll is None:
  214. def uc_lookupAll(self, required, provided):
  215. raise NotImplementedError()
  216. if uc_subscriptions is None:
  217. def uc_subscriptions(self, required, provided):
  218. raise NotImplementedError()
  219. class Derived(self._getTargetClass()):
  220. _uncached_lookup = uc_lookup
  221. _uncached_lookupAll = uc_lookupAll
  222. _uncached_subscriptions = uc_subscriptions
  223. return Derived()
  224. def test_lookup_w_invalid_name(self):
  225. def _lookup(self, required, provided, name):
  226. self.fail("This should never be called")
  227. lb = self._makeOne(uc_lookup=_lookup)
  228. with self.assertRaises(ValueError):
  229. lb.lookup(('A',), 'B', object())
  230. def test_lookup_miss_no_default(self):
  231. _called_with = []
  232. def _lookup(self, required, provided, name):
  233. _called_with.append((required, provided, name))
  234. return None
  235. lb = self._makeOne(uc_lookup=_lookup)
  236. found = lb.lookup(('A',), 'B', 'C')
  237. self.assertTrue(found is None)
  238. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  239. def test_lookup_miss_w_default(self):
  240. _called_with = []
  241. _default = object()
  242. def _lookup(self, required, provided, name):
  243. _called_with.append((required, provided, name))
  244. return None
  245. lb = self._makeOne(uc_lookup=_lookup)
  246. found = lb.lookup(('A',), 'B', 'C', _default)
  247. self.assertTrue(found is _default)
  248. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  249. def test_lookup_not_cached(self):
  250. _called_with = []
  251. a, b, c = object(), object(), object()
  252. _results = [a, b, c]
  253. def _lookup(self, required, provided, name):
  254. _called_with.append((required, provided, name))
  255. return _results.pop(0)
  256. lb = self._makeOne(uc_lookup=_lookup)
  257. found = lb.lookup(('A',), 'B', 'C')
  258. self.assertTrue(found is a)
  259. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  260. self.assertEqual(_results, [b, c])
  261. def test_lookup_cached(self):
  262. _called_with = []
  263. a, b, c = object(), object(), object()
  264. _results = [a, b, c]
  265. def _lookup(self, required, provided, name):
  266. _called_with.append((required, provided, name))
  267. return _results.pop(0)
  268. lb = self._makeOne(uc_lookup=_lookup)
  269. found = lb.lookup(('A',), 'B', 'C')
  270. found = lb.lookup(('A',), 'B', 'C')
  271. self.assertTrue(found is a)
  272. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  273. self.assertEqual(_results, [b, c])
  274. def test_lookup_not_cached_multi_required(self):
  275. _called_with = []
  276. a, b, c = object(), object(), object()
  277. _results = [a, b, c]
  278. def _lookup(self, required, provided, name):
  279. _called_with.append((required, provided, name))
  280. return _results.pop(0)
  281. lb = self._makeOne(uc_lookup=_lookup)
  282. found = lb.lookup(('A', 'D'), 'B', 'C')
  283. self.assertTrue(found is a)
  284. self.assertEqual(_called_with, [(('A', 'D'), 'B', 'C')])
  285. self.assertEqual(_results, [b, c])
  286. def test_lookup_cached_multi_required(self):
  287. _called_with = []
  288. a, b, c = object(), object(), object()
  289. _results = [a, b, c]
  290. def _lookup(self, required, provided, name):
  291. _called_with.append((required, provided, name))
  292. return _results.pop(0)
  293. lb = self._makeOne(uc_lookup=_lookup)
  294. found = lb.lookup(('A', 'D'), 'B', 'C')
  295. found = lb.lookup(('A', 'D'), 'B', 'C')
  296. self.assertTrue(found is a)
  297. self.assertEqual(_called_with, [(('A', 'D'), 'B', 'C')])
  298. self.assertEqual(_results, [b, c])
  299. def test_lookup_not_cached_after_changed(self):
  300. _called_with = []
  301. a, b, c = object(), object(), object()
  302. _results = [a, b, c]
  303. def _lookup(self, required, provided, name):
  304. _called_with.append((required, provided, name))
  305. return _results.pop(0)
  306. lb = self._makeOne(uc_lookup=_lookup)
  307. found = lb.lookup(('A',), 'B', 'C')
  308. lb.changed(lb)
  309. found = lb.lookup(('A',), 'B', 'C')
  310. self.assertTrue(found is b)
  311. self.assertEqual(_called_with,
  312. [(('A',), 'B', 'C'), (('A',), 'B', 'C')])
  313. self.assertEqual(_results, [c])
  314. def test_lookup1_w_invalid_name(self):
  315. def _lookup(self, required, provided, name):
  316. self.fail("This should never be called")
  317. lb = self._makeOne(uc_lookup=_lookup)
  318. with self.assertRaises(ValueError):
  319. lb.lookup1('A', 'B', object())
  320. def test_lookup1_miss_no_default(self):
  321. _called_with = []
  322. def _lookup(self, required, provided, name):
  323. _called_with.append((required, provided, name))
  324. return None
  325. lb = self._makeOne(uc_lookup=_lookup)
  326. found = lb.lookup1('A', 'B', 'C')
  327. self.assertTrue(found is None)
  328. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  329. def test_lookup1_miss_w_default(self):
  330. _called_with = []
  331. _default = object()
  332. def _lookup(self, required, provided, name):
  333. _called_with.append((required, provided, name))
  334. return None
  335. lb = self._makeOne(uc_lookup=_lookup)
  336. found = lb.lookup1('A', 'B', 'C', _default)
  337. self.assertTrue(found is _default)
  338. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  339. def test_lookup1_miss_w_default_negative_cache(self):
  340. _called_with = []
  341. _default = object()
  342. def _lookup(self, required, provided, name):
  343. _called_with.append((required, provided, name))
  344. return None
  345. lb = self._makeOne(uc_lookup=_lookup)
  346. found = lb.lookup1('A', 'B', 'C', _default)
  347. self.assertTrue(found is _default)
  348. found = lb.lookup1('A', 'B', 'C', _default)
  349. self.assertTrue(found is _default)
  350. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  351. def test_lookup1_not_cached(self):
  352. _called_with = []
  353. a, b, c = object(), object(), object()
  354. _results = [a, b, c]
  355. def _lookup(self, required, provided, name):
  356. _called_with.append((required, provided, name))
  357. return _results.pop(0)
  358. lb = self._makeOne(uc_lookup=_lookup)
  359. found = lb.lookup1('A', 'B', 'C')
  360. self.assertTrue(found is a)
  361. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  362. self.assertEqual(_results, [b, c])
  363. def test_lookup1_cached(self):
  364. _called_with = []
  365. a, b, c = object(), object(), object()
  366. _results = [a, b, c]
  367. def _lookup(self, required, provided, name):
  368. _called_with.append((required, provided, name))
  369. return _results.pop(0)
  370. lb = self._makeOne(uc_lookup=_lookup)
  371. found = lb.lookup1('A', 'B', 'C')
  372. found = lb.lookup1('A', 'B', 'C')
  373. self.assertTrue(found is a)
  374. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  375. self.assertEqual(_results, [b, c])
  376. def test_lookup1_not_cached_after_changed(self):
  377. _called_with = []
  378. a, b, c = object(), object(), object()
  379. _results = [a, b, c]
  380. def _lookup(self, required, provided, name):
  381. _called_with.append((required, provided, name))
  382. return _results.pop(0)
  383. lb = self._makeOne(uc_lookup=_lookup)
  384. found = lb.lookup1('A', 'B', 'C')
  385. lb.changed(lb)
  386. found = lb.lookup1('A', 'B', 'C')
  387. self.assertTrue(found is b)
  388. self.assertEqual(_called_with,
  389. [(('A',), 'B', 'C'), (('A',), 'B', 'C')])
  390. self.assertEqual(_results, [c])
  391. def test_adapter_hook_w_invalid_name(self):
  392. req, prv = object(), object()
  393. lb = self._makeOne()
  394. with self.assertRaises(ValueError):
  395. lb.adapter_hook(prv, req, object())
  396. def test_adapter_hook_miss_no_default(self):
  397. req, prv = object(), object()
  398. lb = self._makeOne()
  399. found = lb.adapter_hook(prv, req, '')
  400. self.assertTrue(found is None)
  401. def test_adapter_hook_miss_w_default(self):
  402. req, prv, _default = object(), object(), object()
  403. lb = self._makeOne()
  404. found = lb.adapter_hook(prv, req, '', _default)
  405. self.assertTrue(found is _default)
  406. def test_adapter_hook_hit_factory_returns_None(self):
  407. _f_called_with = []
  408. def _factory(context):
  409. _f_called_with.append(context)
  410. return None
  411. def _lookup(self, required, provided, name):
  412. return _factory
  413. req, prv, _default = object(), object(), object()
  414. lb = self._makeOne(uc_lookup=_lookup)
  415. adapted = lb.adapter_hook(prv, req, 'C', _default)
  416. self.assertTrue(adapted is _default)
  417. self.assertEqual(_f_called_with, [req])
  418. def test_adapter_hook_hit_factory_returns_adapter(self):
  419. _f_called_with = []
  420. _adapter = object()
  421. def _factory(context):
  422. _f_called_with.append(context)
  423. return _adapter
  424. def _lookup(self, required, provided, name):
  425. return _factory
  426. req, prv, _default = object(), object(), object()
  427. lb = self._makeOne(uc_lookup=_lookup)
  428. adapted = lb.adapter_hook(prv, req, 'C', _default)
  429. self.assertTrue(adapted is _adapter)
  430. self.assertEqual(_f_called_with, [req])
  431. def test_queryAdapter(self):
  432. _f_called_with = []
  433. _adapter = object()
  434. def _factory(context):
  435. _f_called_with.append(context)
  436. return _adapter
  437. def _lookup(self, required, provided, name):
  438. return _factory
  439. req, prv, _default = object(), object(), object()
  440. lb = self._makeOne(uc_lookup=_lookup)
  441. adapted = lb.queryAdapter(req, prv, 'C', _default)
  442. self.assertTrue(adapted is _adapter)
  443. self.assertEqual(_f_called_with, [req])
  444. def test_lookupAll_uncached(self):
  445. _called_with = []
  446. _results = [object(), object(), object()]
  447. def _lookupAll(self, required, provided):
  448. _called_with.append((required, provided))
  449. return tuple(_results)
  450. lb = self._makeOne(uc_lookupAll=_lookupAll)
  451. found = lb.lookupAll('A', 'B')
  452. self.assertEqual(found, tuple(_results))
  453. self.assertEqual(_called_with, [(('A',), 'B')])
  454. def test_lookupAll_cached(self):
  455. _called_with = []
  456. _results = [object(), object(), object()]
  457. def _lookupAll(self, required, provided):
  458. _called_with.append((required, provided))
  459. return tuple(_results)
  460. lb = self._makeOne(uc_lookupAll=_lookupAll)
  461. found = lb.lookupAll('A', 'B')
  462. found = lb.lookupAll('A', 'B')
  463. self.assertEqual(found, tuple(_results))
  464. self.assertEqual(_called_with, [(('A',), 'B')])
  465. def test_subscriptions_uncached(self):
  466. _called_with = []
  467. _results = [object(), object(), object()]
  468. def _subscriptions(self, required, provided):
  469. _called_with.append((required, provided))
  470. return tuple(_results)
  471. lb = self._makeOne(uc_subscriptions=_subscriptions)
  472. found = lb.subscriptions('A', 'B')
  473. self.assertEqual(found, tuple(_results))
  474. self.assertEqual(_called_with, [(('A',), 'B')])
  475. def test_subscriptions_cached(self):
  476. _called_with = []
  477. _results = [object(), object(), object()]
  478. def _subscriptions(self, required, provided):
  479. _called_with.append((required, provided))
  480. return tuple(_results)
  481. lb = self._makeOne(uc_subscriptions=_subscriptions)
  482. found = lb.subscriptions('A', 'B')
  483. found = lb.subscriptions('A', 'B')
  484. self.assertEqual(found, tuple(_results))
  485. self.assertEqual(_called_with, [(('A',), 'B')])
  486. class LookupBaseTests(LookupBaseFallbackTests):
  487. def _getTargetClass(self):
  488. from zope.interface.adapter import LookupBase
  489. return LookupBase
  490. def test_optimizations(self):
  491. from zope.interface.adapter import LookupBaseFallback
  492. try:
  493. import zope.interface._zope_interface_coptimizations
  494. except ImportError:
  495. self.assertIs(self._getTargetClass(), LookupBaseFallback)
  496. else:
  497. self.assertIsNot(self._getTargetClass(), LookupBaseFallback)
  498. class VerifyingBaseFallbackTests(unittest.TestCase):
  499. def _getTargetClass(self):
  500. from zope.interface.adapter import VerifyingBaseFallback
  501. return VerifyingBaseFallback
  502. def _makeOne(self, registry, uc_lookup=None, uc_lookupAll=None,
  503. uc_subscriptions=None):
  504. if uc_lookup is None:
  505. def uc_lookup(self, required, provided, name):
  506. raise NotImplementedError()
  507. if uc_lookupAll is None:
  508. def uc_lookupAll(self, required, provided):
  509. raise NotImplementedError()
  510. if uc_subscriptions is None:
  511. def uc_subscriptions(self, required, provided):
  512. raise NotImplementedError()
  513. class Derived(self._getTargetClass()):
  514. _uncached_lookup = uc_lookup
  515. _uncached_lookupAll = uc_lookupAll
  516. _uncached_subscriptions = uc_subscriptions
  517. def __init__(self, registry):
  518. super(Derived, self).__init__()
  519. self._registry = registry
  520. derived = Derived(registry)
  521. derived.changed(derived) # init. '_verify_ro' / '_verify_generations'
  522. return derived
  523. def _makeRegistry(self, depth):
  524. class WithGeneration(object):
  525. _generation = 1
  526. class Registry:
  527. def __init__(self, depth):
  528. self.ro = [WithGeneration() for i in range(depth)]
  529. return Registry(depth)
  530. def test_lookup(self):
  531. _called_with = []
  532. a, b, c = object(), object(), object()
  533. _results = [a, b, c]
  534. def _lookup(self, required, provided, name):
  535. _called_with.append((required, provided, name))
  536. return _results.pop(0)
  537. reg = self._makeRegistry(3)
  538. lb = self._makeOne(reg, uc_lookup=_lookup)
  539. found = lb.lookup(('A',), 'B', 'C')
  540. found = lb.lookup(('A',), 'B', 'C')
  541. self.assertTrue(found is a)
  542. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  543. self.assertEqual(_results, [b, c])
  544. reg.ro[1]._generation += 1
  545. found = lb.lookup(('A',), 'B', 'C')
  546. self.assertTrue(found is b)
  547. self.assertEqual(_called_with,
  548. [(('A',), 'B', 'C'), (('A',), 'B', 'C')])
  549. self.assertEqual(_results, [c])
  550. def test_lookup1(self):
  551. _called_with = []
  552. a, b, c = object(), object(), object()
  553. _results = [a, b, c]
  554. def _lookup(self, required, provided, name):
  555. _called_with.append((required, provided, name))
  556. return _results.pop(0)
  557. reg = self._makeRegistry(3)
  558. lb = self._makeOne(reg, uc_lookup=_lookup)
  559. found = lb.lookup1('A', 'B', 'C')
  560. found = lb.lookup1('A', 'B', 'C')
  561. self.assertTrue(found is a)
  562. self.assertEqual(_called_with, [(('A',), 'B', 'C')])
  563. self.assertEqual(_results, [b, c])
  564. reg.ro[1]._generation += 1
  565. found = lb.lookup1('A', 'B', 'C')
  566. self.assertTrue(found is b)
  567. self.assertEqual(_called_with,
  568. [(('A',), 'B', 'C'), (('A',), 'B', 'C')])
  569. self.assertEqual(_results, [c])
  570. def test_adapter_hook(self):
  571. a, b, _c = [object(), object(), object()]
  572. def _factory1(context):
  573. return a
  574. def _factory2(context):
  575. return b
  576. def _factory3(context):
  577. self.fail("This should never be called")
  578. _factories = [_factory1, _factory2, _factory3]
  579. def _lookup(self, required, provided, name):
  580. return _factories.pop(0)
  581. req, prv, _default = object(), object(), object()
  582. reg = self._makeRegistry(3)
  583. lb = self._makeOne(reg, uc_lookup=_lookup)
  584. adapted = lb.adapter_hook(prv, req, 'C', _default)
  585. self.assertTrue(adapted is a)
  586. adapted = lb.adapter_hook(prv, req, 'C', _default)
  587. self.assertTrue(adapted is a)
  588. reg.ro[1]._generation += 1
  589. adapted = lb.adapter_hook(prv, req, 'C', _default)
  590. self.assertTrue(adapted is b)
  591. def test_queryAdapter(self):
  592. a, b, _c = [object(), object(), object()]
  593. def _factory1(context):
  594. return a
  595. def _factory2(context):
  596. return b
  597. def _factory3(context):
  598. self.fail("This should never be called")
  599. _factories = [_factory1, _factory2, _factory3]
  600. def _lookup(self, required, provided, name):
  601. return _factories.pop(0)
  602. req, prv, _default = object(), object(), object()
  603. reg = self._makeRegistry(3)
  604. lb = self._makeOne(reg, uc_lookup=_lookup)
  605. adapted = lb.queryAdapter(req, prv, 'C', _default)
  606. self.assertTrue(adapted is a)
  607. adapted = lb.queryAdapter(req, prv, 'C', _default)
  608. self.assertTrue(adapted is a)
  609. reg.ro[1]._generation += 1
  610. adapted = lb.adapter_hook(prv, req, 'C', _default)
  611. self.assertTrue(adapted is b)
  612. def test_lookupAll(self):
  613. _results_1 = [object(), object(), object()]
  614. _results_2 = [object(), object(), object()]
  615. _results = [_results_1, _results_2]
  616. def _lookupAll(self, required, provided):
  617. return tuple(_results.pop(0))
  618. reg = self._makeRegistry(3)
  619. lb = self._makeOne(reg, uc_lookupAll=_lookupAll)
  620. found = lb.lookupAll('A', 'B')
  621. self.assertEqual(found, tuple(_results_1))
  622. found = lb.lookupAll('A', 'B')
  623. self.assertEqual(found, tuple(_results_1))
  624. reg.ro[1]._generation += 1
  625. found = lb.lookupAll('A', 'B')
  626. self.assertEqual(found, tuple(_results_2))
  627. def test_subscriptions(self):
  628. _results_1 = [object(), object(), object()]
  629. _results_2 = [object(), object(), object()]
  630. _results = [_results_1, _results_2]
  631. def _subscriptions(self, required, provided):
  632. return tuple(_results.pop(0))
  633. reg = self._makeRegistry(3)
  634. lb = self._makeOne(reg, uc_subscriptions=_subscriptions)
  635. found = lb.subscriptions('A', 'B')
  636. self.assertEqual(found, tuple(_results_1))
  637. found = lb.subscriptions('A', 'B')
  638. self.assertEqual(found, tuple(_results_1))
  639. reg.ro[1]._generation += 1
  640. found = lb.subscriptions('A', 'B')
  641. self.assertEqual(found, tuple(_results_2))
  642. class VerifyingBaseTests(VerifyingBaseFallbackTests):
  643. def _getTargetClass(self):
  644. from zope.interface.adapter import VerifyingBase
  645. return VerifyingBase
  646. def test_optimizations(self):
  647. from zope.interface.adapter import VerifyingBaseFallback
  648. try:
  649. import zope.interface._zope_interface_coptimizations
  650. except ImportError:
  651. self.assertIs(self._getTargetClass(), VerifyingBaseFallback)
  652. else:
  653. self.assertIsNot(self._getTargetClass(), VerifyingBaseFallback)
  654. class AdapterLookupBaseTests(unittest.TestCase):
  655. def _getTargetClass(self):
  656. from zope.interface.adapter import AdapterLookupBase
  657. return AdapterLookupBase
  658. def _makeOne(self, registry):
  659. return self._getTargetClass()(registry)
  660. def _makeSubregistry(self, *provided):
  661. class Subregistry:
  662. def __init__(self):
  663. self._adapters = []
  664. self._subscribers = []
  665. return Subregistry()
  666. def _makeRegistry(self, *provided):
  667. class Registry:
  668. def __init__(self, provided):
  669. self._provided = provided
  670. self.ro = []
  671. return Registry(provided)
  672. def test_ctor_empty_registry(self):
  673. registry = self._makeRegistry()
  674. alb = self._makeOne(registry)
  675. self.assertEqual(alb._extendors, {})
  676. def test_ctor_w_registry_provided(self):
  677. from zope.interface import Interface
  678. from zope.interface.interface import InterfaceClass
  679. IFoo = InterfaceClass('IFoo')
  680. IBar = InterfaceClass('IBar', IFoo)
  681. registry = self._makeRegistry(IFoo, IBar)
  682. alb = self._makeOne(registry)
  683. self.assertEqual(sorted(alb._extendors.keys()),
  684. sorted([IBar, IFoo, Interface]))
  685. self.assertEqual(alb._extendors[IFoo], [IFoo])
  686. self.assertEqual(alb._extendors[IBar], [IBar])
  687. self.assertEqual(sorted(alb._extendors[Interface]),
  688. sorted([IFoo, IBar]))
  689. def test_changed_empty_required(self):
  690. # ALB.changed expects to call a mixed in changed.
  691. class Mixin(object):
  692. def changed(self, *other):
  693. pass
  694. class Derived(self._getTargetClass(), Mixin):
  695. pass
  696. registry = self._makeRegistry()
  697. alb = Derived(registry)
  698. alb.changed(alb)
  699. def test_changed_w_required(self):
  700. # ALB.changed expects to call a mixed in changed.
  701. class Mixin(object):
  702. def changed(self, *other):
  703. pass
  704. class Derived(self._getTargetClass(), Mixin):
  705. pass
  706. class FauxWeakref(object):
  707. _unsub = None
  708. def __init__(self, here):
  709. self._here = here
  710. def __call__(self):
  711. if self._here:
  712. return self
  713. def unsubscribe(self, target):
  714. self._unsub = target
  715. gone = FauxWeakref(False)
  716. here = FauxWeakref(True)
  717. registry = self._makeRegistry()
  718. alb = Derived(registry)
  719. alb._required[gone] = 1
  720. alb._required[here] = 1
  721. alb.changed(alb)
  722. self.assertEqual(len(alb._required), 0)
  723. self.assertEqual(gone._unsub, None)
  724. self.assertEqual(here._unsub, alb)
  725. def test_init_extendors_after_registry_update(self):
  726. from zope.interface import Interface
  727. from zope.interface.interface import InterfaceClass
  728. IFoo = InterfaceClass('IFoo')
  729. IBar = InterfaceClass('IBar', IFoo)
  730. registry = self._makeRegistry()
  731. alb = self._makeOne(registry)
  732. registry._provided = [IFoo, IBar]
  733. alb.init_extendors()
  734. self.assertEqual(sorted(alb._extendors.keys()),
  735. sorted([IBar, IFoo, Interface]))
  736. self.assertEqual(alb._extendors[IFoo], [IFoo])
  737. self.assertEqual(alb._extendors[IBar], [IBar])
  738. self.assertEqual(sorted(alb._extendors[Interface]),
  739. sorted([IFoo, IBar]))
  740. def test_add_extendor(self):
  741. from zope.interface import Interface
  742. from zope.interface.interface import InterfaceClass
  743. IFoo = InterfaceClass('IFoo')
  744. IBar = InterfaceClass('IBar', IFoo)
  745. registry = self._makeRegistry()
  746. alb = self._makeOne(registry)
  747. alb.add_extendor(IFoo)
  748. alb.add_extendor(IBar)
  749. self.assertEqual(sorted(alb._extendors.keys()),
  750. sorted([IBar, IFoo, Interface]))
  751. self.assertEqual(alb._extendors[IFoo], [IFoo])
  752. self.assertEqual(alb._extendors[IBar], [IBar])
  753. self.assertEqual(sorted(alb._extendors[Interface]),
  754. sorted([IFoo, IBar]))
  755. def test_remove_extendor(self):
  756. from zope.interface import Interface
  757. from zope.interface.interface import InterfaceClass
  758. IFoo = InterfaceClass('IFoo')
  759. IBar = InterfaceClass('IBar', IFoo)
  760. registry = self._makeRegistry(IFoo, IBar)
  761. alb = self._makeOne(registry)
  762. alb.remove_extendor(IFoo)
  763. self.assertEqual(sorted(alb._extendors.keys()),
  764. sorted([IFoo, IBar, Interface]))
  765. self.assertEqual(alb._extendors[IFoo], [])
  766. self.assertEqual(alb._extendors[IBar], [IBar])
  767. self.assertEqual(sorted(alb._extendors[Interface]),
  768. sorted([IBar]))
  769. # test '_subscribe' via its callers, '_uncached_lookup', etc.
  770. def test__uncached_lookup_empty_ro(self):
  771. from zope.interface.interface import InterfaceClass
  772. IFoo = InterfaceClass('IFoo')
  773. IBar = InterfaceClass('IBar', IFoo)
  774. registry = self._makeRegistry()
  775. alb = self._makeOne(registry)
  776. result = alb._uncached_lookup((IFoo,), IBar)
  777. self.assertEqual(result, None)
  778. self.assertEqual(len(alb._required), 1)
  779. self.assertTrue(IFoo.weakref() in alb._required)
  780. def test__uncached_lookup_order_miss(self):
  781. from zope.interface.interface import InterfaceClass
  782. IFoo = InterfaceClass('IFoo')
  783. IBar = InterfaceClass('IBar', IFoo)
  784. registry = self._makeRegistry(IFoo, IBar)
  785. subr = self._makeSubregistry()
  786. registry.ro.append(subr)
  787. alb = self._makeOne(registry)
  788. result = alb._uncached_lookup((IFoo,), IBar)
  789. self.assertEqual(result, None)
  790. def test__uncached_lookup_extendors_miss(self):
  791. from zope.interface.interface import InterfaceClass
  792. IFoo = InterfaceClass('IFoo')
  793. IBar = InterfaceClass('IBar', IFoo)
  794. registry = self._makeRegistry()
  795. subr = self._makeSubregistry()
  796. subr._adapters = [{}, {}] #utilities, single adapters
  797. registry.ro.append(subr)
  798. alb = self._makeOne(registry)
  799. subr._v_lookup = alb
  800. result = alb._uncached_lookup((IFoo,), IBar)
  801. self.assertEqual(result, None)
  802. def test__uncached_lookup_components_miss_wrong_iface(self):
  803. from zope.interface.interface import InterfaceClass
  804. IFoo = InterfaceClass('IFoo')
  805. IBar = InterfaceClass('IBar', IFoo)
  806. IQux = InterfaceClass('IQux')
  807. registry = self._makeRegistry(IFoo, IBar)
  808. subr = self._makeSubregistry()
  809. irrelevant = object()
  810. subr._adapters = [ #utilities, single adapters
  811. {},
  812. {IFoo: {IQux: {'': irrelevant},
  813. }},
  814. ]
  815. registry.ro.append(subr)
  816. alb = self._makeOne(registry)
  817. subr._v_lookup = alb
  818. result = alb._uncached_lookup((IFoo,), IBar)
  819. self.assertEqual(result, None)
  820. def test__uncached_lookup_components_miss_wrong_name(self):
  821. from zope.interface.interface import InterfaceClass
  822. IFoo = InterfaceClass('IFoo')
  823. IBar = InterfaceClass('IBar', IFoo)
  824. registry = self._makeRegistry(IFoo, IBar)
  825. subr = self._makeSubregistry()
  826. irrelevant = object()
  827. wrongname = object()
  828. subr._adapters = [ #utilities, single adapters
  829. {},
  830. {IFoo: {IBar: {'wrongname': wrongname},
  831. }},
  832. ]
  833. registry.ro.append(subr)
  834. alb = self._makeOne(registry)
  835. subr._v_lookup = alb
  836. result = alb._uncached_lookup((IFoo,), IBar)
  837. self.assertEqual(result, None)
  838. def test__uncached_lookup_simple_hit(self):
  839. from zope.interface.interface import InterfaceClass
  840. IFoo = InterfaceClass('IFoo')
  841. IBar = InterfaceClass('IBar', IFoo)
  842. registry = self._makeRegistry(IFoo, IBar)
  843. subr = self._makeSubregistry()
  844. _expected = object()
  845. subr._adapters = [ #utilities, single adapters
  846. {},
  847. {IFoo: {IBar: {'': _expected}}},
  848. ]
  849. registry.ro.append(subr)
  850. alb = self._makeOne(registry)
  851. subr._v_lookup = alb
  852. result = alb._uncached_lookup((IFoo,), IBar)
  853. self.assertTrue(result is _expected)
  854. def test__uncached_lookup_repeated_hit(self):
  855. from zope.interface.interface import InterfaceClass
  856. IFoo = InterfaceClass('IFoo')
  857. IBar = InterfaceClass('IBar', IFoo)
  858. registry = self._makeRegistry(IFoo, IBar)
  859. subr = self._makeSubregistry()
  860. _expected = object()
  861. subr._adapters = [ #utilities, single adapters
  862. {},
  863. {IFoo: {IBar: {'': _expected}}},
  864. ]
  865. registry.ro.append(subr)
  866. alb = self._makeOne(registry)
  867. subr._v_lookup = alb
  868. result = alb._uncached_lookup((IFoo,), IBar)
  869. result2 = alb._uncached_lookup((IFoo,), IBar)
  870. self.assertTrue(result is _expected)
  871. self.assertTrue(result2 is _expected)
  872. def test_queryMultiAdaptor_lookup_miss(self):
  873. from zope.interface.declarations import implementer
  874. from zope.interface.interface import InterfaceClass
  875. IFoo = InterfaceClass('IFoo')
  876. IBar = InterfaceClass('IBar', IFoo)
  877. @implementer(IFoo)
  878. class Foo(object):
  879. pass
  880. foo = Foo()
  881. registry = self._makeRegistry()
  882. subr = self._makeSubregistry()
  883. subr._adapters = [ #utilities, single adapters
  884. {},
  885. {},
  886. ]
  887. registry.ro.append(subr)
  888. alb = self._makeOne(registry)
  889. alb.lookup = alb._uncached_lookup # provided by derived
  890. subr._v_lookup = alb
  891. _default = object()
  892. result = alb.queryMultiAdapter((foo,), IBar, default=_default)
  893. self.assertTrue(result is _default)
  894. def test_queryMultiAdaptor_factory_miss(self):
  895. from zope.interface.declarations import implementer
  896. from zope.interface.interface import InterfaceClass
  897. IFoo = InterfaceClass('IFoo')
  898. IBar = InterfaceClass('IBar', IFoo)
  899. @implementer(IFoo)
  900. class Foo(object):
  901. pass
  902. foo = Foo()
  903. registry = self._makeRegistry(IFoo, IBar)
  904. subr = self._makeSubregistry()
  905. _expected = object()
  906. _called_with = []
  907. def _factory(context):
  908. _called_with.append(context)
  909. return None
  910. subr._adapters = [ #utilities, single adapters
  911. {},
  912. {IFoo: {IBar: {'': _factory}}},
  913. ]
  914. registry.ro.append(subr)
  915. alb = self._makeOne(registry)
  916. alb.lookup = alb._uncached_lookup # provided by derived
  917. subr._v_lookup = alb
  918. _default = object()
  919. result = alb.queryMultiAdapter((foo,), IBar, default=_default)
  920. self.assertTrue(result is _default)
  921. self.assertEqual(_called_with, [foo])
  922. def test_queryMultiAdaptor_factory_hit(self):
  923. from zope.interface.declarations import implementer
  924. from zope.interface.interface import InterfaceClass
  925. IFoo = InterfaceClass('IFoo')
  926. IBar = InterfaceClass('IBar', IFoo)
  927. @implementer(IFoo)
  928. class Foo(object):
  929. pass
  930. foo = Foo()
  931. registry = self._makeRegistry(IFoo, IBar)
  932. subr = self._makeSubregistry()
  933. _expected = object()
  934. _called_with = []
  935. def _factory(context):
  936. _called_with.append(context)
  937. return _expected
  938. subr._adapters = [ #utilities, single adapters
  939. {},
  940. {IFoo: {IBar: {'': _factory}}},
  941. ]
  942. registry.ro.append(subr)
  943. alb = self._makeOne(registry)
  944. alb.lookup = alb._uncached_lookup # provided by derived
  945. subr._v_lookup = alb
  946. _default = object()
  947. result = alb.queryMultiAdapter((foo,), IBar, default=_default)
  948. self.assertTrue(result is _expected)
  949. self.assertEqual(_called_with, [foo])
  950. def test__uncached_lookupAll_empty_ro(self):
  951. from zope.interface.interface import InterfaceClass
  952. IFoo = InterfaceClass('IFoo')
  953. IBar = InterfaceClass('IBar', IFoo)
  954. registry = self._makeRegistry()
  955. alb = self._makeOne(registry)
  956. result = alb._uncached_lookupAll((IFoo,), IBar)
  957. self.assertEqual(result, ())
  958. self.assertEqual(len(alb._required), 1)
  959. self.assertTrue(IFoo.weakref() in alb._required)
  960. def test__uncached_lookupAll_order_miss(self):
  961. from zope.interface.interface import InterfaceClass
  962. IFoo = InterfaceClass('IFoo')
  963. IBar = InterfaceClass('IBar', IFoo)
  964. registry = self._makeRegistry(IFoo, IBar)
  965. subr = self._makeSubregistry()
  966. registry.ro.append(subr)
  967. alb = self._makeOne(registry)
  968. subr._v_lookup = alb
  969. result = alb._uncached_lookupAll((IFoo,), IBar)
  970. self.assertEqual(result, ())
  971. def test__uncached_lookupAll_extendors_miss(self):
  972. from zope.interface.interface import InterfaceClass
  973. IFoo = InterfaceClass('IFoo')
  974. IBar = InterfaceClass('IBar', IFoo)
  975. registry = self._makeRegistry()
  976. subr = self._makeSubregistry()
  977. subr._adapters = [{}, {}] #utilities, single adapters
  978. registry.ro.append(subr)
  979. alb = self._makeOne(registry)
  980. subr._v_lookup = alb
  981. result = alb._uncached_lookupAll((IFoo,), IBar)
  982. self.assertEqual(result, ())
  983. def test__uncached_lookupAll_components_miss(self):
  984. from zope.interface.interface import InterfaceClass
  985. IFoo = InterfaceClass('IFoo')
  986. IBar = InterfaceClass('IBar', IFoo)
  987. IQux = InterfaceClass('IQux')
  988. registry = self._makeRegistry(IFoo, IBar)
  989. subr = self._makeSubregistry()
  990. irrelevant = object()
  991. subr._adapters = [ #utilities, single adapters
  992. {},
  993. {IFoo: {IQux: {'': irrelevant}}},
  994. ]
  995. registry.ro.append(subr)
  996. alb = self._makeOne(registry)
  997. subr._v_lookup = alb
  998. result = alb._uncached_lookupAll((IFoo,), IBar)
  999. self.assertEqual(result, ())
  1000. def test__uncached_lookupAll_simple_hit(self):
  1001. from zope.interface.interface import InterfaceClass
  1002. IFoo = InterfaceClass('IFoo')
  1003. IBar = InterfaceClass('IBar', IFoo)
  1004. registry = self._makeRegistry(IFoo, IBar)
  1005. subr = self._makeSubregistry()
  1006. _expected = object()
  1007. _named = object()
  1008. subr._adapters = [ #utilities, single adapters
  1009. {},
  1010. {IFoo: {IBar: {'': _expected, 'named': _named}}},
  1011. ]
  1012. registry.ro.append(subr)
  1013. alb = self._makeOne(registry)
  1014. subr._v_lookup = alb
  1015. result = alb._uncached_lookupAll((IFoo,), IBar)
  1016. self.assertEqual(sorted(result), [('', _expected), ('named', _named)])
  1017. def test_names(self):
  1018. from zope.interface.interface import InterfaceClass
  1019. IFoo = InterfaceClass('IFoo')
  1020. IBar = InterfaceClass('IBar', IFoo)
  1021. registry = self._makeRegistry(IFoo, IBar)
  1022. subr = self._makeSubregistry()
  1023. _expected = object()
  1024. _named = object()
  1025. subr._adapters = [ #utilities, single adapters
  1026. {},
  1027. {IFoo: {IBar: {'': _expected, 'named': _named}}},
  1028. ]
  1029. registry.ro.append(subr)
  1030. alb = self._makeOne(registry)
  1031. alb.lookupAll = alb._uncached_lookupAll
  1032. subr._v_lookup = alb
  1033. result = alb.names((IFoo,), IBar)
  1034. self.assertEqual(sorted(result), ['', 'named'])
  1035. def test__uncached_subscriptions_empty_ro(self):
  1036. from zope.interface.interface import InterfaceClass
  1037. IFoo = InterfaceClass('IFoo')
  1038. IBar = InterfaceClass('IBar', IFoo)
  1039. registry = self._makeRegistry()
  1040. alb = self._makeOne(registry)
  1041. result = alb._uncached_subscriptions((IFoo,), IBar)
  1042. self.assertEqual(result, [])
  1043. self.assertEqual(len(alb._required), 1)
  1044. self.assertTrue(IFoo.weakref() in alb._required)
  1045. def test__uncached_subscriptions_order_miss(self):
  1046. from zope.interface.interface import InterfaceClass
  1047. IFoo = InterfaceClass('IFoo')
  1048. IBar = InterfaceClass('IBar', IFoo)
  1049. registry = self._makeRegistry(IFoo, IBar)
  1050. subr = self._makeSubregistry()
  1051. registry.ro.append(subr)
  1052. alb = self._makeOne(registry)
  1053. subr._v_lookup = alb
  1054. result = alb._uncached_subscriptions((IFoo,), IBar)
  1055. self.assertEqual(result, [])
  1056. def test__uncached_subscriptions_extendors_miss(self):
  1057. from zope.interface.interface import InterfaceClass
  1058. IFoo = InterfaceClass('IFoo')
  1059. IBar = InterfaceClass('IBar', IFoo)
  1060. registry = self._makeRegistry()
  1061. subr = self._makeSubregistry()
  1062. subr._subscribers = [{}, {}] #utilities, single adapters
  1063. registry.ro.append(subr)
  1064. alb = self._makeOne(registry)
  1065. subr._v_lookup = alb
  1066. result = alb._uncached_subscriptions((IFoo,), IBar)
  1067. self.assertEqual(result, [])
  1068. def test__uncached_subscriptions_components_miss_wrong_iface(self):
  1069. from zope.interface.interface import InterfaceClass
  1070. IFoo = InterfaceClass('IFoo')
  1071. IBar = InterfaceClass('IBar', IFoo)
  1072. IQux = InterfaceClass('IQux')
  1073. registry = self._makeRegistry(IFoo, IBar)
  1074. subr = self._makeSubregistry()
  1075. irrelevant = object()
  1076. subr._subscribers = [ #utilities, single adapters
  1077. {},
  1078. {IFoo: {IQux: {'': irrelevant}}},
  1079. ]
  1080. registry.ro.append(subr)
  1081. alb = self._makeOne(registry)
  1082. subr._v_lookup = alb
  1083. result = alb._uncached_subscriptions((IFoo,), IBar)
  1084. self.assertEqual(result, [])
  1085. def test__uncached_subscriptions_components_miss_wrong_name(self):
  1086. from zope.interface.interface import InterfaceClass
  1087. IFoo = InterfaceClass('IFoo')
  1088. IBar = InterfaceClass('IBar', IFoo)
  1089. registry = self._makeRegistry(IFoo, IBar)
  1090. subr = self._makeSubregistry()
  1091. wrongname = object()
  1092. subr._subscribers = [ #utilities, single adapters
  1093. {},
  1094. {IFoo: {IBar: {'wrongname': wrongname}}},
  1095. ]
  1096. registry.ro.append(subr)
  1097. alb = self._makeOne(registry)
  1098. subr._v_lookup = alb
  1099. result = alb._uncached_subscriptions((IFoo,), IBar)
  1100. self.assertEqual(result, [])
  1101. def test__uncached_subscriptions_simple_hit(self):
  1102. from zope.interface.interface import InterfaceClass
  1103. IFoo = InterfaceClass('IFoo')
  1104. IBar = InterfaceClass('IBar', IFoo)
  1105. registry = self._makeRegistry(IFoo, IBar)
  1106. subr = self._makeSubregistry()
  1107. class Foo(object):
  1108. def __lt__(self, other):
  1109. return True
  1110. _exp1, _exp2 = Foo(), Foo()
  1111. subr._subscribers = [ #utilities, single adapters
  1112. {},
  1113. {IFoo: {IBar: {'': (_exp1, _exp2)}}},
  1114. ]
  1115. registry.ro.append(subr)
  1116. alb = self._makeOne(registry)
  1117. subr._v_lookup = alb
  1118. result = alb._uncached_subscriptions((IFoo,), IBar)
  1119. self.assertEqual(sorted(result), sorted([_exp1, _exp2]))
  1120. def test_subscribers_wo_provided(self):
  1121. from zope.interface.declarations import implementer
  1122. from zope.interface.interface import InterfaceClass
  1123. IFoo = InterfaceClass('IFoo')
  1124. IBar = InterfaceClass('IBar', IFoo)
  1125. @implementer(IFoo)
  1126. class Foo(object):
  1127. pass
  1128. foo = Foo()
  1129. registry = self._makeRegistry(IFoo, IBar)
  1130. registry = self._makeRegistry(IFoo, IBar)
  1131. subr = self._makeSubregistry()
  1132. _called = {}
  1133. def _factory1(context):
  1134. _called.setdefault('_factory1', []).append(context)
  1135. def _factory2(context):
  1136. _called.setdefault('_factory2', []).append(context)
  1137. subr._subscribers = [ #utilities, single adapters
  1138. {},
  1139. {IFoo: {None: {'': (_factory1, _factory2)}}},
  1140. ]
  1141. registry.ro.append(subr)
  1142. alb = self._makeOne(registry)
  1143. alb.subscriptions = alb._uncached_subscriptions
  1144. subr._v_lookup = alb
  1145. result = alb.subscribers((foo,), None)
  1146. self.assertEqual(result, ())
  1147. self.assertEqual(_called, {'_factory1': [foo], '_factory2': [foo]})
  1148. def test_subscribers_w_provided(self):
  1149. from zope.interface.declarations import implementer
  1150. from zope.interface.interface import InterfaceClass
  1151. IFoo = InterfaceClass('IFoo')
  1152. IBar = InterfaceClass('IBar', IFoo)
  1153. @implementer(IFoo)
  1154. class Foo(object):
  1155. pass
  1156. foo = Foo()
  1157. registry = self._makeRegistry(IFoo, IBar)
  1158. registry = self._makeRegistry(IFoo, IBar)
  1159. subr = self._makeSubregistry()
  1160. _called = {}
  1161. _exp1, _exp2 = object(), object()
  1162. def _factory1(context):
  1163. _called.setdefault('_factory1', []).append(context)
  1164. return _exp1
  1165. def _factory2(context):
  1166. _called.setdefault('_factory2', []).append(context)
  1167. return _exp2
  1168. def _side_effect_only(context):
  1169. _called.setdefault('_side_effect_only', []).append(context)
  1170. return None
  1171. subr._subscribers = [ #utilities, single adapters
  1172. {},
  1173. {IFoo: {IBar: {'': (_factory1, _factory2, _side_effect_only)}}},
  1174. ]
  1175. registry.ro.append(subr)
  1176. alb = self._makeOne(registry)
  1177. alb.subscriptions = alb._uncached_subscriptions
  1178. subr._v_lookup = alb
  1179. result = alb.subscribers((foo,), IBar)
  1180. self.assertEqual(result, [_exp1, _exp2])
  1181. self.assertEqual(_called,
  1182. {'_factory1': [foo],
  1183. '_factory2': [foo],
  1184. '_side_effect_only': [foo],
  1185. })
  1186. class AdapterRegistryTests(unittest.TestCase):
  1187. def _getTargetClass(self):
  1188. from zope.interface.adapter import AdapterRegistry
  1189. return AdapterRegistry
  1190. def _makeOne(self, *args, **kw):
  1191. return self._getTargetClass()(*args, **kw)
  1192. def test_ctor_no_bases(self):
  1193. ar = self._makeOne()
  1194. self.assertEqual(len(ar._v_subregistries), 0)
  1195. def test_ctor_w_bases(self):
  1196. base = self._makeOne()
  1197. sub = self._makeOne([base])
  1198. self.assertEqual(len(sub._v_subregistries), 0)
  1199. self.assertEqual(len(base._v_subregistries), 1)
  1200. self.assertTrue(sub in base._v_subregistries)
  1201. # test _addSubregistry / _removeSubregistry via only caller, _setBases
  1202. def test__setBases_removing_existing_subregistry(self):
  1203. before = self._makeOne()
  1204. after = self._makeOne()
  1205. sub = self._makeOne([before])
  1206. sub.__bases__ = [after]
  1207. self.assertEqual(len(before._v_subregistries), 0)
  1208. self.assertEqual(len(after._v_subregistries), 1)
  1209. self.assertTrue(sub in after._v_subregistries)
  1210. def test__setBases_wo_stray_entry(self):
  1211. before = self._makeOne()
  1212. stray = self._makeOne()
  1213. after = self._makeOne()
  1214. sub = self._makeOne([before])
  1215. sub.__dict__['__bases__'].append(stray)
  1216. sub.__bases__ = [after]
  1217. self.assertEqual(len(before._v_subregistries), 0)
  1218. self.assertEqual(len(after._v_subregistries), 1)
  1219. self.assertTrue(sub in after._v_subregistries)
  1220. def test__setBases_w_existing_entry_continuing(self):
  1221. before = self._makeOne()
  1222. after = self._makeOne()
  1223. sub = self._makeOne([before])
  1224. sub.__bases__ = [before, after]
  1225. self.assertEqual(len(before._v_subregistries), 1)
  1226. self.assertEqual(len(after._v_subregistries), 1)
  1227. self.assertTrue(sub in before._v_subregistries)
  1228. self.assertTrue(sub in after._v_subregistries)
  1229. def test_changed_w_subregistries(self):
  1230. base = self._makeOne()
  1231. class Derived(object):
  1232. _changed = None
  1233. def changed(self, originally_changed):
  1234. self._changed = originally_changed
  1235. derived1, derived2 = Derived(), Derived()
  1236. base._addSubregistry(derived1)
  1237. base._addSubregistry(derived2)
  1238. orig = object()
  1239. base.changed(orig)
  1240. self.assertTrue(derived1._changed is orig)
  1241. self.assertTrue(derived2._changed is orig)
  1242. class Test_utils(unittest.TestCase):
  1243. def test__convert_None_to_Interface_w_None(self):
  1244. from zope.interface.adapter import _convert_None_to_Interface
  1245. from zope.interface.interface import Interface
  1246. self.assertTrue(_convert_None_to_Interface(None) is Interface)
  1247. def test__convert_None_to_Interface_w_other(self):
  1248. from zope.interface.adapter import _convert_None_to_Interface
  1249. other = object()
  1250. self.assertTrue(_convert_None_to_Interface(other) is other)
  1251. def test__normalize_name_str(self):
  1252. import sys
  1253. from zope.interface.adapter import _normalize_name
  1254. STR = b'str'
  1255. if sys.version_info[0] < 3:
  1256. self.assertEqual(_normalize_name(STR), unicode(STR))
  1257. else:
  1258. self.assertEqual(_normalize_name(STR), str(STR, 'ascii'))
  1259. def test__normalize_name_unicode(self):
  1260. from zope.interface.adapter import _normalize_name
  1261. USTR = u'ustr'
  1262. self.assertEqual(_normalize_name(USTR), USTR)
  1263. def test__normalize_name_other(self):
  1264. from zope.interface.adapter import _normalize_name
  1265. for other in 1, 1.0, (), [], {}, object():
  1266. self.assertRaises(TypeError, _normalize_name, other)
  1267. # _lookup, _lookupAll, and _subscriptions tested via their callers
  1268. # (AdapterLookupBase.{lookup,lookupAll,subscriptions}).