You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_adapter.py 54KB

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