test_constants.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Unit tests for L{twisted.python.constants}.
  5. """
  6. from __future__ import division, absolute_import
  7. import warnings
  8. from twisted.trial.unittest import TestCase
  9. with warnings.catch_warnings():
  10. warnings.simplefilter("ignore", category=DeprecationWarning)
  11. from twisted.python.constants import (
  12. NamedConstant, Names, ValueConstant, Values, FlagConstant, Flags
  13. )
  14. class NamedConstantTests(TestCase):
  15. """
  16. Tests for the L{twisted.python.constants.NamedConstant} class which is used
  17. to represent individual values.
  18. """
  19. def setUp(self):
  20. """
  21. Create a dummy container into which constants can be placed.
  22. """
  23. class foo(Names):
  24. pass
  25. self.container = foo
  26. def test_name(self):
  27. """
  28. The C{name} attribute of a L{NamedConstant} refers to the value passed
  29. for the C{name} parameter to C{_realize}.
  30. """
  31. name = NamedConstant()
  32. name._realize(self.container, "bar", None)
  33. self.assertEqual("bar", name.name)
  34. def test_representation(self):
  35. """
  36. The string representation of an instance of L{NamedConstant} includes
  37. the container the instances belongs to as well as the instance's name.
  38. """
  39. name = NamedConstant()
  40. name._realize(self.container, "bar", None)
  41. self.assertEqual("<foo=bar>", repr(name))
  42. def test_equality(self):
  43. """
  44. A L{NamedConstant} instance compares equal to itself.
  45. """
  46. name = NamedConstant()
  47. name._realize(self.container, "bar", None)
  48. self.assertTrue(name == name)
  49. self.assertFalse(name != name)
  50. def test_nonequality(self):
  51. """
  52. Two different L{NamedConstant} instances do not compare equal to each
  53. other.
  54. """
  55. first = NamedConstant()
  56. first._realize(self.container, "bar", None)
  57. second = NamedConstant()
  58. second._realize(self.container, "bar", None)
  59. self.assertFalse(first == second)
  60. self.assertTrue(first != second)
  61. def test_hash(self):
  62. """
  63. Because two different L{NamedConstant} instances do not compare as
  64. equal to each other, they also have different hashes to avoid
  65. collisions when added to a C{dict} or C{set}.
  66. """
  67. first = NamedConstant()
  68. first._realize(self.container, "bar", None)
  69. second = NamedConstant()
  70. second._realize(self.container, "bar", None)
  71. self.assertNotEqual(hash(first), hash(second))
  72. class _ConstantsTestsMixin(object):
  73. """
  74. Mixin defining test helpers common to multiple types of constants
  75. collections.
  76. """
  77. def _notInstantiableTest(self, name, cls):
  78. """
  79. Assert that an attempt to instantiate the constants class raises
  80. C{TypeError}.
  81. @param name: A C{str} giving the name of the constants collection.
  82. @param cls: The constants class to test.
  83. """
  84. exc = self.assertRaises(TypeError, cls)
  85. self.assertEqual(name + " may not be instantiated.", str(exc))
  86. def _initializedOnceTest(self, container, constantName):
  87. """
  88. Assert that C{container._enumerants} does not change as a side-effect
  89. of one of its attributes being accessed.
  90. @param container: A L{_ConstantsContainer} subclass which will be
  91. tested.
  92. @param constantName: The name of one of the constants which is an
  93. attribute of C{container}.
  94. """
  95. first = container._enumerants
  96. # Accessing an attribute of the container should not have any
  97. # observable side-effect on the _enumerants attribute.
  98. getattr(container, constantName)
  99. second = container._enumerants
  100. self.assertIs(first, second)
  101. class NamesTests(TestCase, _ConstantsTestsMixin):
  102. """
  103. Tests for L{twisted.python.constants.Names}, a base class for containers of
  104. related constraints.
  105. """
  106. def setUp(self):
  107. """
  108. Create a fresh new L{Names} subclass for each unit test to use. Since
  109. L{Names} is stateful, re-using the same subclass across test methods
  110. makes exercising all of the implementation code paths difficult.
  111. """
  112. class METHOD(Names):
  113. """
  114. A container for some named constants to use in unit tests for
  115. L{Names}.
  116. """
  117. GET = NamedConstant()
  118. PUT = NamedConstant()
  119. POST = NamedConstant()
  120. DELETE = NamedConstant()
  121. extra = object()
  122. self.METHOD = METHOD
  123. def test_notInstantiable(self):
  124. """
  125. A subclass of L{Names} raises C{TypeError} if an attempt is made to
  126. instantiate it.
  127. """
  128. self._notInstantiableTest("METHOD", self.METHOD)
  129. def test_symbolicAttributes(self):
  130. """
  131. Each name associated with a L{NamedConstant} instance in the definition
  132. of a L{Names} subclass is available as an attribute on the resulting
  133. class.
  134. """
  135. self.assertTrue(hasattr(self.METHOD, "GET"))
  136. self.assertTrue(hasattr(self.METHOD, "PUT"))
  137. self.assertTrue(hasattr(self.METHOD, "POST"))
  138. self.assertTrue(hasattr(self.METHOD, "DELETE"))
  139. def test_withoutOtherAttributes(self):
  140. """
  141. As usual, names not defined in the class scope of a L{Names}
  142. subclass are not available as attributes on the resulting class.
  143. """
  144. self.assertFalse(hasattr(self.METHOD, "foo"))
  145. def test_representation(self):
  146. """
  147. The string representation of a constant on a L{Names} subclass includes
  148. the name of the L{Names} subclass and the name of the constant itself.
  149. """
  150. self.assertEqual("<METHOD=GET>", repr(self.METHOD.GET))
  151. def test_lookupByName(self):
  152. """
  153. Constants can be looked up by name using L{Names.lookupByName}.
  154. """
  155. method = self.METHOD.lookupByName("GET")
  156. self.assertIs(self.METHOD.GET, method)
  157. def test_notLookupMissingByName(self):
  158. """
  159. Names not defined with a L{NamedConstant} instance cannot be looked up
  160. using L{Names.lookupByName}.
  161. """
  162. self.assertRaises(ValueError, self.METHOD.lookupByName, "lookupByName")
  163. self.assertRaises(ValueError, self.METHOD.lookupByName, "__init__")
  164. self.assertRaises(ValueError, self.METHOD.lookupByName, "foo")
  165. self.assertRaises(ValueError, self.METHOD.lookupByName, "extra")
  166. def test_name(self):
  167. """
  168. The C{name} attribute of one of the named constants gives that
  169. constant's name.
  170. """
  171. self.assertEqual("GET", self.METHOD.GET.name)
  172. def test_attributeIdentity(self):
  173. """
  174. Repeated access of an attribute associated with a L{NamedConstant}
  175. value in a L{Names} subclass results in the same object.
  176. """
  177. self.assertIs(self.METHOD.GET, self.METHOD.GET)
  178. def test_iterconstants(self):
  179. """
  180. L{Names.iterconstants} returns an iterator over all of the constants
  181. defined in the class, in the order they were defined.
  182. """
  183. constants = list(self.METHOD.iterconstants())
  184. self.assertEqual(
  185. [self.METHOD.GET, self.METHOD.PUT,
  186. self.METHOD.POST, self.METHOD.DELETE],
  187. constants)
  188. def test_attributeIterconstantsIdentity(self):
  189. """
  190. The constants returned from L{Names.iterconstants} are identical to the
  191. constants accessible using attributes.
  192. """
  193. constants = list(self.METHOD.iterconstants())
  194. self.assertIs(self.METHOD.GET, constants[0])
  195. self.assertIs(self.METHOD.PUT, constants[1])
  196. self.assertIs(self.METHOD.POST, constants[2])
  197. self.assertIs(self.METHOD.DELETE, constants[3])
  198. def test_iterconstantsIdentity(self):
  199. """
  200. The constants returned from L{Names.iterconstants} are identical on
  201. each call to that method.
  202. """
  203. constants = list(self.METHOD.iterconstants())
  204. again = list(self.METHOD.iterconstants())
  205. self.assertIs(again[0], constants[0])
  206. self.assertIs(again[1], constants[1])
  207. self.assertIs(again[2], constants[2])
  208. self.assertIs(again[3], constants[3])
  209. def test_initializedOnce(self):
  210. """
  211. L{Names._enumerants} is initialized once and its value re-used on
  212. subsequent access.
  213. """
  214. self._initializedOnceTest(self.METHOD, "GET")
  215. def test_asForeignClassAttribute(self):
  216. """
  217. A constant defined on a L{Names} subclass may be set as an attribute of
  218. another class and then retrieved using that attribute.
  219. """
  220. class Another(object):
  221. something = self.METHOD.GET
  222. self.assertIs(self.METHOD.GET, Another.something)
  223. def test_asForeignClassAttributeViaInstance(self):
  224. """
  225. A constant defined on a L{Names} subclass may be set as an attribute of
  226. another class and then retrieved from an instance of that class using
  227. that attribute.
  228. """
  229. class Another(object):
  230. something = self.METHOD.GET
  231. self.assertIs(self.METHOD.GET, Another().something)
  232. def test_notAsAlternateContainerAttribute(self):
  233. """
  234. It is explicitly disallowed (via a L{ValueError}) to use a constant
  235. defined on a L{Names} subclass as the value of an attribute of another
  236. L{Names} subclass.
  237. """
  238. def defineIt():
  239. class AnotherNames(Names):
  240. something = self.METHOD.GET
  241. exc = self.assertRaises(ValueError, defineIt)
  242. self.assertEqual(
  243. "Cannot use <METHOD=GET> as the value of an attribute on "
  244. "AnotherNames",
  245. str(exc))
  246. class ValuesTests(TestCase, _ConstantsTestsMixin):
  247. """
  248. Tests for L{twisted.python.constants.Names}, a base class for containers of
  249. related constraints with arbitrary values.
  250. """
  251. def setUp(self):
  252. """
  253. Create a fresh new L{Values} subclass for each unit test to use. Since
  254. L{Values} is stateful, re-using the same subclass across test methods
  255. makes exercising all of the implementation code paths difficult.
  256. """
  257. class STATUS(Values):
  258. OK = ValueConstant("200")
  259. NOT_FOUND = ValueConstant("404")
  260. self.STATUS = STATUS
  261. def test_notInstantiable(self):
  262. """
  263. A subclass of L{Values} raises C{TypeError} if an attempt is made to
  264. instantiate it.
  265. """
  266. self._notInstantiableTest("STATUS", self.STATUS)
  267. def test_symbolicAttributes(self):
  268. """
  269. Each name associated with a L{ValueConstant} instance in the definition
  270. of a L{Values} subclass is available as an attribute on the resulting
  271. class.
  272. """
  273. self.assertTrue(hasattr(self.STATUS, "OK"))
  274. self.assertTrue(hasattr(self.STATUS, "NOT_FOUND"))
  275. def test_withoutOtherAttributes(self):
  276. """
  277. As usual, names not defined in the class scope of a L{Values}
  278. subclass are not available as attributes on the resulting class.
  279. """
  280. self.assertFalse(hasattr(self.STATUS, "foo"))
  281. def test_representation(self):
  282. """
  283. The string representation of a constant on a L{Values} subclass
  284. includes the name of the L{Values} subclass and the name of the
  285. constant itself.
  286. """
  287. self.assertEqual("<STATUS=OK>", repr(self.STATUS.OK))
  288. def test_lookupByName(self):
  289. """
  290. Constants can be looked up by name using L{Values.lookupByName}.
  291. """
  292. method = self.STATUS.lookupByName("OK")
  293. self.assertIs(self.STATUS.OK, method)
  294. def test_notLookupMissingByName(self):
  295. """
  296. Names not defined with a L{ValueConstant} instance cannot be looked up
  297. using L{Values.lookupByName}.
  298. """
  299. self.assertRaises(ValueError, self.STATUS.lookupByName, "lookupByName")
  300. self.assertRaises(ValueError, self.STATUS.lookupByName, "__init__")
  301. self.assertRaises(ValueError, self.STATUS.lookupByName, "foo")
  302. def test_lookupByValue(self):
  303. """
  304. Constants can be looked up by their associated value, defined by the
  305. argument passed to L{ValueConstant}, using L{Values.lookupByValue}.
  306. """
  307. status = self.STATUS.lookupByValue("200")
  308. self.assertIs(self.STATUS.OK, status)
  309. def test_lookupDuplicateByValue(self):
  310. """
  311. If more than one constant is associated with a particular value,
  312. L{Values.lookupByValue} returns whichever of them is defined first.
  313. """
  314. class TRANSPORT_MESSAGE(Values):
  315. """
  316. Message types supported by an SSH transport.
  317. """
  318. KEX_DH_GEX_REQUEST_OLD = ValueConstant(30)
  319. KEXDH_INIT = ValueConstant(30)
  320. self.assertIs(
  321. TRANSPORT_MESSAGE.lookupByValue(30),
  322. TRANSPORT_MESSAGE.KEX_DH_GEX_REQUEST_OLD)
  323. def test_notLookupMissingByValue(self):
  324. """
  325. L{Values.lookupByValue} raises L{ValueError} when called with a value
  326. with which no constant is associated.
  327. """
  328. self.assertRaises(ValueError, self.STATUS.lookupByValue, "OK")
  329. self.assertRaises(ValueError, self.STATUS.lookupByValue, 200)
  330. self.assertRaises(ValueError, self.STATUS.lookupByValue, "200.1")
  331. def test_name(self):
  332. """
  333. The C{name} attribute of one of the constants gives that constant's
  334. name.
  335. """
  336. self.assertEqual("OK", self.STATUS.OK.name)
  337. def test_attributeIdentity(self):
  338. """
  339. Repeated access of an attribute associated with a L{ValueConstant}
  340. value in a L{Values} subclass results in the same object.
  341. """
  342. self.assertIs(self.STATUS.OK, self.STATUS.OK)
  343. def test_iterconstants(self):
  344. """
  345. L{Values.iterconstants} returns an iterator over all of the constants
  346. defined in the class, in the order they were defined.
  347. """
  348. constants = list(self.STATUS.iterconstants())
  349. self.assertEqual(
  350. [self.STATUS.OK, self.STATUS.NOT_FOUND],
  351. constants)
  352. def test_attributeIterconstantsIdentity(self):
  353. """
  354. The constants returned from L{Values.iterconstants} are identical to
  355. the constants accessible using attributes.
  356. """
  357. constants = list(self.STATUS.iterconstants())
  358. self.assertIs(self.STATUS.OK, constants[0])
  359. self.assertIs(self.STATUS.NOT_FOUND, constants[1])
  360. def test_iterconstantsIdentity(self):
  361. """
  362. The constants returned from L{Values.iterconstants} are identical on
  363. each call to that method.
  364. """
  365. constants = list(self.STATUS.iterconstants())
  366. again = list(self.STATUS.iterconstants())
  367. self.assertIs(again[0], constants[0])
  368. self.assertIs(again[1], constants[1])
  369. def test_initializedOnce(self):
  370. """
  371. L{Values._enumerants} is initialized once and its value re-used on
  372. subsequent access.
  373. """
  374. self._initializedOnceTest(self.STATUS, "OK")
  375. class _FlagsTestsMixin(object):
  376. """
  377. Mixin defining setup code for any tests for L{Flags} subclasses.
  378. @ivar FXF: A L{Flags} subclass created for each test method.
  379. """
  380. def setUp(self):
  381. """
  382. Create a fresh new L{Flags} subclass for each unit test to use. Since
  383. L{Flags} is stateful, re-using the same subclass across test methods
  384. makes exercising all of the implementation code paths difficult.
  385. """
  386. class FXF(Flags):
  387. # Implicitly assign three flag values based on definition order
  388. READ = FlagConstant()
  389. WRITE = FlagConstant()
  390. APPEND = FlagConstant()
  391. # Explicitly assign one flag value by passing it in
  392. EXCLUSIVE = FlagConstant(0x20)
  393. # Implicitly assign another flag value, following the previously
  394. # specified explicit value.
  395. TEXT = FlagConstant()
  396. self.FXF = FXF
  397. class FlagsTests(_FlagsTestsMixin, TestCase, _ConstantsTestsMixin):
  398. """
  399. Tests for L{twisted.python.constants.Flags}, a base class for containers of
  400. related, combinable flag or bitvector-like constants.
  401. """
  402. def test_notInstantiable(self):
  403. """
  404. A subclass of L{Flags} raises L{TypeError} if an attempt is made to
  405. instantiate it.
  406. """
  407. self._notInstantiableTest("FXF", self.FXF)
  408. def test_symbolicAttributes(self):
  409. """
  410. Each name associated with a L{FlagConstant} instance in the definition
  411. of a L{Flags} subclass is available as an attribute on the resulting
  412. class.
  413. """
  414. self.assertTrue(hasattr(self.FXF, "READ"))
  415. self.assertTrue(hasattr(self.FXF, "WRITE"))
  416. self.assertTrue(hasattr(self.FXF, "APPEND"))
  417. self.assertTrue(hasattr(self.FXF, "EXCLUSIVE"))
  418. self.assertTrue(hasattr(self.FXF, "TEXT"))
  419. def test_withoutOtherAttributes(self):
  420. """
  421. As usual, names not defined in the class scope of a L{Flags} subclass
  422. are not available as attributes on the resulting class.
  423. """
  424. self.assertFalse(hasattr(self.FXF, "foo"))
  425. def test_representation(self):
  426. """
  427. The string representation of a constant on a L{Flags} subclass includes
  428. the name of the L{Flags} subclass and the name of the constant itself.
  429. """
  430. self.assertEqual("<FXF=READ>", repr(self.FXF.READ))
  431. def test_lookupByName(self):
  432. """
  433. Constants can be looked up by name using L{Flags.lookupByName}.
  434. """
  435. flag = self.FXF.lookupByName("READ")
  436. self.assertIs(self.FXF.READ, flag)
  437. def test_notLookupMissingByName(self):
  438. """
  439. Names not defined with a L{FlagConstant} instance cannot be looked up
  440. using L{Flags.lookupByName}.
  441. """
  442. self.assertRaises(ValueError, self.FXF.lookupByName, "lookupByName")
  443. self.assertRaises(ValueError, self.FXF.lookupByName, "__init__")
  444. self.assertRaises(ValueError, self.FXF.lookupByName, "foo")
  445. def test_lookupByValue(self):
  446. """
  447. Constants can be looked up by their associated value, defined
  448. implicitly by the position in which the constant appears in the class
  449. definition or explicitly by the argument passed to L{FlagConstant}.
  450. """
  451. flag = self.FXF.lookupByValue(0x01)
  452. self.assertIs(flag, self.FXF.READ)
  453. flag = self.FXF.lookupByValue(0x02)
  454. self.assertIs(flag, self.FXF.WRITE)
  455. flag = self.FXF.lookupByValue(0x04)
  456. self.assertIs(flag, self.FXF.APPEND)
  457. flag = self.FXF.lookupByValue(0x20)
  458. self.assertIs(flag, self.FXF.EXCLUSIVE)
  459. flag = self.FXF.lookupByValue(0x40)
  460. self.assertIs(flag, self.FXF.TEXT)
  461. def test_lookupDuplicateByValue(self):
  462. """
  463. If more than one constant is associated with a particular value,
  464. L{Flags.lookupByValue} returns whichever of them is defined first.
  465. """
  466. class TIMEX(Flags):
  467. # (timex.mode)
  468. ADJ_OFFSET = FlagConstant(0x0001) # time offset
  469. # xntp 3.4 compatibility names
  470. MOD_OFFSET = FlagConstant(0x0001)
  471. self.assertIs(TIMEX.lookupByValue(0x0001), TIMEX.ADJ_OFFSET)
  472. def test_notLookupMissingByValue(self):
  473. """
  474. L{Flags.lookupByValue} raises L{ValueError} when called with a value
  475. with which no constant is associated.
  476. """
  477. self.assertRaises(ValueError, self.FXF.lookupByValue, 0x10)
  478. def test_name(self):
  479. """
  480. The C{name} attribute of one of the constants gives that constant's
  481. name.
  482. """
  483. self.assertEqual("READ", self.FXF.READ.name)
  484. def test_attributeIdentity(self):
  485. """
  486. Repeated access of an attribute associated with a L{FlagConstant} value
  487. in a L{Flags} subclass results in the same object.
  488. """
  489. self.assertIs(self.FXF.READ, self.FXF.READ)
  490. def test_iterconstants(self):
  491. """
  492. L{Flags.iterconstants} returns an iterator over all of the constants
  493. defined in the class, in the order they were defined.
  494. """
  495. constants = list(self.FXF.iterconstants())
  496. self.assertEqual(
  497. [self.FXF.READ, self.FXF.WRITE, self.FXF.APPEND,
  498. self.FXF.EXCLUSIVE, self.FXF.TEXT],
  499. constants)
  500. def test_attributeIterconstantsIdentity(self):
  501. """
  502. The constants returned from L{Flags.iterconstants} are identical to the
  503. constants accessible using attributes.
  504. """
  505. constants = list(self.FXF.iterconstants())
  506. self.assertIs(self.FXF.READ, constants[0])
  507. self.assertIs(self.FXF.WRITE, constants[1])
  508. self.assertIs(self.FXF.APPEND, constants[2])
  509. self.assertIs(self.FXF.EXCLUSIVE, constants[3])
  510. self.assertIs(self.FXF.TEXT, constants[4])
  511. def test_iterconstantsIdentity(self):
  512. """
  513. The constants returned from L{Flags.iterconstants} are identical on
  514. each call to that method.
  515. """
  516. constants = list(self.FXF.iterconstants())
  517. again = list(self.FXF.iterconstants())
  518. self.assertIs(again[0], constants[0])
  519. self.assertIs(again[1], constants[1])
  520. self.assertIs(again[2], constants[2])
  521. self.assertIs(again[3], constants[3])
  522. self.assertIs(again[4], constants[4])
  523. def test_initializedOnce(self):
  524. """
  525. L{Flags._enumerants} is initialized once and its value re-used on
  526. subsequent access.
  527. """
  528. self._initializedOnceTest(self.FXF, "READ")
  529. class FlagConstantSimpleOrTests(_FlagsTestsMixin, TestCase):
  530. """
  531. Tests for the C{|} operator as defined for L{FlagConstant} instances, used
  532. to create new L{FlagConstant} instances representing both of two existing
  533. L{FlagConstant} instances from the same L{Flags} class.
  534. """
  535. def test_value(self):
  536. """
  537. The value of the L{FlagConstant} which results from C{|} has all of the
  538. bits set which were set in either of the values of the two original
  539. constants.
  540. """
  541. flag = self.FXF.READ | self.FXF.WRITE
  542. self.assertEqual(
  543. self.FXF.READ.value | self.FXF.WRITE.value, flag.value
  544. )
  545. def test_name(self):
  546. """
  547. The name of the L{FlagConstant} instance which results from C{|}
  548. includes the names of both of the two original constants.
  549. """
  550. flag = self.FXF.READ | self.FXF.WRITE
  551. self.assertEqual("{READ,WRITE}", flag.name)
  552. def test_representation(self):
  553. """
  554. The string representation of a L{FlagConstant} instance which results
  555. from C{|} includes the names of both of the two original constants.
  556. """
  557. flag = self.FXF.READ | self.FXF.WRITE
  558. self.assertEqual("<FXF={READ,WRITE}>", repr(flag))
  559. def test_iterate(self):
  560. """
  561. A L{FlagConstant} instance which results from C{|} can be
  562. iterated upon to yield the original constants.
  563. """
  564. self.assertEqual(
  565. set(self.FXF.WRITE & self.FXF.READ), # No flags
  566. set(()))
  567. self.assertEqual(
  568. set(self.FXF.WRITE),
  569. set((self.FXF.WRITE,)))
  570. self.assertEqual(
  571. set(self.FXF.WRITE | self.FXF.EXCLUSIVE),
  572. set((self.FXF.WRITE, self.FXF.EXCLUSIVE)))
  573. def test_membership(self):
  574. """
  575. A L{FlagConstant} instance which results from C{|} can be
  576. tested for membership.
  577. """
  578. flags = self.FXF.WRITE | self.FXF.EXCLUSIVE
  579. self.assertIn(self.FXF.WRITE, flags)
  580. self.assertNotIn(self.FXF.READ, flags)
  581. def test_truthiness(self):
  582. """
  583. Empty flags is false, non-empty flags is true.
  584. """
  585. self.assertTrue(self.FXF.WRITE)
  586. self.assertTrue(self.FXF.WRITE | self.FXF.EXCLUSIVE)
  587. self.assertFalse(self.FXF.WRITE & self.FXF.EXCLUSIVE)
  588. class FlagConstantSimpleAndTests(_FlagsTestsMixin, TestCase):
  589. """
  590. Tests for the C{&} operator as defined for L{FlagConstant} instances, used
  591. to create new L{FlagConstant} instances representing the common parts of
  592. two existing L{FlagConstant} instances from the same L{Flags} class.
  593. """
  594. def test_value(self):
  595. """
  596. The value of the L{FlagConstant} which results from C{&} has all of the
  597. bits set which were set in both of the values of the two original
  598. constants.
  599. """
  600. readWrite = (self.FXF.READ | self.FXF.WRITE)
  601. writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
  602. flag = readWrite & writeAppend
  603. self.assertEqual(self.FXF.WRITE.value, flag.value)
  604. def test_name(self):
  605. """
  606. The name of the L{FlagConstant} instance which results from C{&}
  607. includes the names of only the flags which were set in both of the two
  608. original constants.
  609. """
  610. readWrite = (self.FXF.READ | self.FXF.WRITE)
  611. writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
  612. flag = readWrite & writeAppend
  613. self.assertEqual("WRITE", flag.name)
  614. def test_representation(self):
  615. """
  616. The string representation of a L{FlagConstant} instance which results
  617. from C{&} includes the names of only the flags which were set in both
  618. both of the two original constants.
  619. """
  620. readWrite = (self.FXF.READ | self.FXF.WRITE)
  621. writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
  622. flag = readWrite & writeAppend
  623. self.assertEqual("<FXF=WRITE>", repr(flag))
  624. class FlagConstantSimpleExclusiveOrTests(_FlagsTestsMixin, TestCase):
  625. """
  626. Tests for the C{^} operator as defined for L{FlagConstant} instances, used
  627. to create new L{FlagConstant} instances representing the uncommon parts of
  628. two existing L{FlagConstant} instances from the same L{Flags} class.
  629. """
  630. def test_value(self):
  631. """
  632. The value of the L{FlagConstant} which results from C{^} has all of the
  633. bits set which were set in exactly one of the values of the two
  634. original constants.
  635. """
  636. readWrite = (self.FXF.READ | self.FXF.WRITE)
  637. writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
  638. flag = readWrite ^ writeAppend
  639. self.assertEqual(
  640. self.FXF.READ.value | self.FXF.APPEND.value, flag.value
  641. )
  642. def test_name(self):
  643. """
  644. The name of the L{FlagConstant} instance which results from C{^}
  645. includes the names of only the flags which were set in exactly one of
  646. the two original constants.
  647. """
  648. readWrite = (self.FXF.READ | self.FXF.WRITE)
  649. writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
  650. flag = readWrite ^ writeAppend
  651. self.assertEqual("{APPEND,READ}", flag.name)
  652. def test_representation(self):
  653. """
  654. The string representation of a L{FlagConstant} instance which results
  655. from C{^} includes the names of only the flags which were set in
  656. exactly one of the two original constants.
  657. """
  658. readWrite = (self.FXF.READ | self.FXF.WRITE)
  659. writeAppend = (self.FXF.WRITE | self.FXF.APPEND)
  660. flag = readWrite ^ writeAppend
  661. self.assertEqual("<FXF={APPEND,READ}>", repr(flag))
  662. class FlagConstantNegationTests(_FlagsTestsMixin, TestCase):
  663. """
  664. Tests for the C{~} operator as defined for L{FlagConstant} instances, used
  665. to create new L{FlagConstant} instances representing all the flags from a
  666. L{Flags} class not set in a particular L{FlagConstant} instance.
  667. """
  668. def test_value(self):
  669. """
  670. The value of the L{FlagConstant} which results from C{~} has all of the
  671. bits set which were not set in the original constant.
  672. """
  673. flag = ~self.FXF.READ
  674. self.assertEqual(
  675. self.FXF.WRITE.value |
  676. self.FXF.APPEND.value |
  677. self.FXF.EXCLUSIVE.value |
  678. self.FXF.TEXT.value,
  679. flag.value)
  680. flag = ~self.FXF.WRITE
  681. self.assertEqual(
  682. self.FXF.READ.value |
  683. self.FXF.APPEND.value |
  684. self.FXF.EXCLUSIVE.value |
  685. self.FXF.TEXT.value,
  686. flag.value)
  687. def test_name(self):
  688. """
  689. The name of the L{FlagConstant} instance which results from C{~}
  690. includes the names of all the flags which were not set in the original
  691. constant.
  692. """
  693. flag = ~self.FXF.WRITE
  694. self.assertEqual("{APPEND,EXCLUSIVE,READ,TEXT}", flag.name)
  695. def test_representation(self):
  696. """
  697. The string representation of a L{FlagConstant} instance which results
  698. from C{~} includes the names of all the flags which were not set in the
  699. original constant.
  700. """
  701. flag = ~self.FXF.WRITE
  702. self.assertEqual("<FXF={APPEND,EXCLUSIVE,READ,TEXT}>", repr(flag))
  703. class OrderedConstantsTests(TestCase):
  704. """
  705. Tests for the ordering of constants. All constants are ordered by
  706. the order in which they are defined in their container class.
  707. The ordering of constants that are not in the same container is not
  708. defined.
  709. """
  710. def test_orderedNameConstants_lt(self):
  711. """
  712. L{twisted.python.constants.NamedConstant} preserves definition
  713. order in C{<} comparisons.
  714. """
  715. self.assertTrue(NamedLetters.alpha < NamedLetters.beta)
  716. def test_orderedNameConstants_le(self):
  717. """
  718. L{twisted.python.constants.NamedConstant} preserves definition
  719. order in C{<=} comparisons.
  720. """
  721. self.assertTrue(NamedLetters.alpha <= NamedLetters.alpha)
  722. self.assertTrue(NamedLetters.alpha <= NamedLetters.beta)
  723. def test_orderedNameConstants_gt(self):
  724. """
  725. L{twisted.python.constants.NamedConstant} preserves definition
  726. order in C{>} comparisons.
  727. """
  728. self.assertTrue(NamedLetters.beta > NamedLetters.alpha)
  729. def test_orderedNameConstants_ge(self):
  730. """
  731. L{twisted.python.constants.NamedConstant} preserves definition
  732. order in C{>=} comparisons.
  733. """
  734. self.assertTrue(NamedLetters.alpha >= NamedLetters.alpha)
  735. self.assertTrue(NamedLetters.beta >= NamedLetters.alpha)
  736. def test_orderedValueConstants_lt(self):
  737. """
  738. L{twisted.python.constants.ValueConstant} preserves definition
  739. order in C{<} comparisons.
  740. """
  741. self.assertTrue(ValuedLetters.alpha < ValuedLetters.digamma)
  742. self.assertTrue(ValuedLetters.digamma < ValuedLetters.zeta)
  743. def test_orderedValueConstants_le(self):
  744. """
  745. L{twisted.python.constants.ValueConstant} preserves definition
  746. order in C{<=} comparisons.
  747. """
  748. self.assertTrue(ValuedLetters.alpha <= ValuedLetters.alpha)
  749. self.assertTrue(ValuedLetters.alpha <= ValuedLetters.digamma)
  750. self.assertTrue(ValuedLetters.digamma <= ValuedLetters.zeta)
  751. def test_orderedValueConstants_gt(self):
  752. """
  753. L{twisted.python.constants.ValueConstant} preserves definition
  754. order in C{>} comparisons.
  755. """
  756. self.assertTrue(ValuedLetters.digamma > ValuedLetters.alpha)
  757. self.assertTrue(ValuedLetters.zeta > ValuedLetters.digamma)
  758. def test_orderedValueConstants_ge(self):
  759. """
  760. L{twisted.python.constants.ValueConstant} preserves definition
  761. order in C{>=} comparisons.
  762. """
  763. self.assertTrue(ValuedLetters.alpha >= ValuedLetters.alpha)
  764. self.assertTrue(ValuedLetters.digamma >= ValuedLetters.alpha)
  765. self.assertTrue(ValuedLetters.zeta >= ValuedLetters.digamma)
  766. def test_orderedFlagConstants_lt(self):
  767. """
  768. L{twisted.python.constants.FlagConstant} preserves definition
  769. order in C{<} comparisons.
  770. """
  771. self.assertTrue(PizzaToppings.mozzarella < PizzaToppings.pesto)
  772. self.assertTrue(PizzaToppings.pesto < PizzaToppings.pepperoni)
  773. def test_orderedFlagConstants_le(self):
  774. """
  775. L{twisted.python.constants.FlagConstant} preserves definition
  776. order in C{<=} comparisons.
  777. """
  778. self.assertTrue(PizzaToppings.mozzarella <= PizzaToppings.mozzarella)
  779. self.assertTrue(PizzaToppings.mozzarella <= PizzaToppings.pesto)
  780. self.assertTrue(PizzaToppings.pesto <= PizzaToppings.pepperoni)
  781. def test_orderedFlagConstants_gt(self):
  782. """
  783. L{twisted.python.constants.FlagConstant} preserves definition
  784. order in C{>} comparisons.
  785. """
  786. self.assertTrue(PizzaToppings.pesto > PizzaToppings.mozzarella)
  787. self.assertTrue(PizzaToppings.pepperoni > PizzaToppings.pesto)
  788. def test_orderedFlagConstants_ge(self):
  789. """
  790. L{twisted.python.constants.FlagConstant} preserves definition
  791. order in C{>=} comparisons.
  792. """
  793. self.assertTrue(PizzaToppings.mozzarella >= PizzaToppings.mozzarella)
  794. self.assertTrue(PizzaToppings.pesto >= PizzaToppings.mozzarella)
  795. self.assertTrue(PizzaToppings.pepperoni >= PizzaToppings.pesto)
  796. def test_orderedDifferentConstants_lt(self):
  797. """
  798. L{twisted.python.constants._Constant.__lt__} returns C{NotImplemented}
  799. when comparing constants of different types.
  800. """
  801. self.assertEqual(
  802. NotImplemented,
  803. NamedLetters.alpha.__lt__(ValuedLetters.alpha)
  804. )
  805. def test_orderedDifferentConstants_le(self):
  806. """
  807. L{twisted.python.constants._Constant.__le__} returns C{NotImplemented}
  808. when comparing constants of different types.
  809. """
  810. self.assertEqual(
  811. NotImplemented,
  812. NamedLetters.alpha.__le__(ValuedLetters.alpha)
  813. )
  814. def test_orderedDifferentConstants_gt(self):
  815. """
  816. L{twisted.python.constants._Constant.__gt__} returns C{NotImplemented}
  817. when comparing constants of different types.
  818. """
  819. self.assertEqual(
  820. NotImplemented,
  821. NamedLetters.alpha.__gt__(ValuedLetters.alpha)
  822. )
  823. def test_orderedDifferentConstants_ge(self):
  824. """
  825. L{twisted.python.constants._Constant.__ge__} returns C{NotImplemented}
  826. when comparing constants of different types.
  827. """
  828. self.assertEqual(
  829. NotImplemented,
  830. NamedLetters.alpha.__ge__(ValuedLetters.alpha)
  831. )
  832. def test_orderedDifferentContainers_lt(self):
  833. """
  834. L{twisted.python.constants._Constant.__lt__} returns C{NotImplemented}
  835. when comparing constants belonging to different containers.
  836. """
  837. self.assertEqual(
  838. NotImplemented,
  839. NamedLetters.alpha.__lt__(MoreNamedLetters.digamma)
  840. )
  841. def test_orderedDifferentContainers_le(self):
  842. """
  843. L{twisted.python.constants._Constant.__le__} returns C{NotImplemented}
  844. when comparing constants belonging to different containers.
  845. """
  846. self.assertEqual(
  847. NotImplemented,
  848. NamedLetters.alpha.__le__(MoreNamedLetters.digamma)
  849. )
  850. def test_orderedDifferentContainers_gt(self):
  851. """
  852. L{twisted.python.constants._Constant.__gt__} returns C{NotImplemented}
  853. when comparing constants belonging to different containers.
  854. """
  855. self.assertEqual(
  856. NotImplemented,
  857. NamedLetters.alpha.__gt__(MoreNamedLetters.digamma)
  858. )
  859. def test_orderedDifferentContainers_ge(self):
  860. """
  861. L{twisted.python.constants._Constant.__ge__} returns C{NotImplemented}
  862. when comparing constants belonging to different containers.
  863. """
  864. self.assertEqual(
  865. NotImplemented,
  866. NamedLetters.alpha.__ge__(MoreNamedLetters.digamma)
  867. )
  868. class NamedLetters(Names):
  869. """
  870. Some letters, named.
  871. """
  872. alpha = NamedConstant()
  873. beta = NamedConstant()
  874. class MoreNamedLetters(Names):
  875. """
  876. Some more letters, named.
  877. """
  878. digamma = NamedConstant()
  879. zeta = NamedConstant()
  880. class ValuedLetters(Values):
  881. """
  882. Some more letters, with corresponding unicode values.
  883. """
  884. # Note u'\u0391' < u'\u03dc' > u'\u0396'. We are ensuring here that the
  885. # definition is order different from the order of the values, which lets us
  886. # test that we're not somehow ordering by value and happen the get the same
  887. # results.
  888. alpha = ValueConstant(u'\u0391')
  889. digamma = ValueConstant(u'\u03dc')
  890. zeta = ValueConstant(u'\u0396')
  891. class PizzaToppings(Flags):
  892. """
  893. Some pizza toppings, with obviously meaningful bitwise values.
  894. """
  895. # Note 1<<1 < 1<<4 > 1<<2, so we are ensuring here that the definition
  896. # order is different from the order of the values, which lets us test that
  897. # we're not somehow ordering by value and happen the get the same results.
  898. mozzarella = FlagConstant(1 << 1)
  899. pesto = FlagConstant(1 << 4)
  900. pepperoni = FlagConstant(1 << 2)
  901. class ConstantsDeprecationTests(TestCase):
  902. """
  903. L{twisted.python.constants} is deprecated.
  904. """
  905. def test_constantsDeprecation(self):
  906. """
  907. L{twisted.python.constants} is deprecated since Twisted 16.5.
  908. """
  909. from twisted.python import constants
  910. constants
  911. warningsShown = self.flushWarnings([self.test_constantsDeprecation])
  912. self.assertEqual(1, len(warningsShown))
  913. self.assertEqual(
  914. ("twisted.python.constants was deprecated in Twisted 16.5.0: "
  915. "Please use constantly from PyPI instead."),
  916. warningsShown[0]['message'])