Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
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_twisted.py 6.1KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for miscellaneous behaviors of the top-level L{twisted} package (ie, for
  5. the code in C{twisted/__init__.py}.
  6. """
  7. import sys
  8. from types import ModuleType
  9. from twisted.trial.unittest import TestCase
  10. # This is somewhat generally useful and should probably be part of a public API
  11. # somewhere. See #5977.
  12. class SetAsideModule:
  13. """
  14. L{SetAsideModule} is a context manager for temporarily removing a module
  15. from C{sys.modules}.
  16. @ivar name: The name of the module to remove.
  17. """
  18. def __init__(self, name):
  19. self.name = name
  20. def _unimport(self, name):
  21. """
  22. Find the given module and all of its hierarchically inferior modules in
  23. C{sys.modules}, remove them from it, and return whatever was found.
  24. """
  25. modules = {
  26. moduleName: module
  27. for (moduleName, module) in list(sys.modules.items())
  28. if (moduleName == self.name or moduleName.startswith(self.name + "."))
  29. }
  30. for name in modules:
  31. del sys.modules[name]
  32. return modules
  33. def __enter__(self):
  34. self.modules = self._unimport(self.name)
  35. def __exit__(self, excType, excValue, traceback):
  36. self._unimport(self.name)
  37. sys.modules.update(self.modules)
  38. def _install(modules):
  39. """
  40. Take a mapping defining a package and turn it into real C{ModuleType}
  41. instances in C{sys.modules}.
  42. Consider these example::
  43. a = {"foo": "bar"}
  44. b = {"twisted": {"__version__": "42.6"}}
  45. c = {"twisted": {"plugin": {"getPlugins": stub}}}
  46. C{_install(a)} will place an item into C{sys.modules} with C{"foo"} as the
  47. key and C{"bar" as the value.
  48. C{_install(b)} will place an item into C{sys.modules} with C{"twisted"} as
  49. the key. The value will be a new module object. The module will have a
  50. C{"__version__"} attribute with C{"42.6"} as the value.
  51. C{_install(c)} will place an item into C{sys.modules} with C{"twisted"} as
  52. the key. The value will be a new module object with a C{"plugin"}
  53. attribute. An item will also be placed into C{sys.modules} with the key
  54. C{"twisted.plugin"} which refers to that module object. That module will
  55. have an attribute C{"getPlugins"} with a value of C{stub}.
  56. @param modules: A mapping from names to definitions of modules. The names
  57. are native strings like C{"twisted"} or C{"unittest"}. Values may be
  58. arbitrary objects. Any value which is not a dictionary will be added to
  59. C{sys.modules} unmodified. Any dictionary value indicates the value is
  60. a new module and its items define the attributes of that module. The
  61. definition of this structure is recursive, so a value in the dictionary
  62. may be a dictionary to trigger another level of processing.
  63. @return: L{None}
  64. """
  65. result = {}
  66. _makePackages(None, modules, result)
  67. sys.modules.update(result)
  68. def _makePackages(parent, attributes, result):
  69. """
  70. Construct module objects (for either modules or packages).
  71. @param parent: L{None} or a module object which is the Python package
  72. containing all of the modules being created by this function call. Its
  73. name will be prepended to the name of all created modules.
  74. @param attributes: A mapping giving the attributes of the particular module
  75. object this call is creating.
  76. @param result: A mapping which is populated with all created module names.
  77. This is suitable for use in updating C{sys.modules}.
  78. @return: A mapping of all of the attributes created by this call. This is
  79. suitable for populating the dictionary of C{parent}.
  80. @see: L{_install}.
  81. """
  82. attrs = {}
  83. for (name, value) in list(attributes.items()):
  84. if parent is None:
  85. if isinstance(value, dict):
  86. module = ModuleType(name)
  87. module.__dict__.update(_makePackages(module, value, result))
  88. result[name] = module
  89. else:
  90. result[name] = value
  91. else:
  92. if isinstance(value, dict):
  93. module = ModuleType(parent.__name__ + "." + name)
  94. module.__dict__.update(_makePackages(module, value, result))
  95. result[parent.__name__ + "." + name] = module
  96. attrs[name] = module
  97. else:
  98. attrs[name] = value
  99. return attrs
  100. class MakePackagesTests(TestCase):
  101. """
  102. Tests for L{_makePackages}, a helper for populating C{sys.modules} with
  103. fictional modules.
  104. """
  105. def test_nonModule(self):
  106. """
  107. A non-C{dict} value in the attributes dictionary passed to L{_makePackages}
  108. is preserved unchanged in the return value.
  109. """
  110. modules = {}
  111. _makePackages(None, dict(reactor="reactor"), modules)
  112. self.assertEqual(modules, dict(reactor="reactor"))
  113. def test_moduleWithAttribute(self):
  114. """
  115. A C{dict} value in the attributes dictionary passed to L{_makePackages}
  116. is turned into a L{ModuleType} instance with attributes populated from
  117. the items of that C{dict} value.
  118. """
  119. modules = {}
  120. _makePackages(None, dict(twisted=dict(version="123")), modules)
  121. self.assertIsInstance(modules, dict)
  122. self.assertIsInstance(modules["twisted"], ModuleType)
  123. self.assertEqual("twisted", modules["twisted"].__name__)
  124. self.assertEqual("123", modules["twisted"].version)
  125. def test_packageWithModule(self):
  126. """
  127. Processing of the attributes dictionary is recursive, so a C{dict} value
  128. it contains may itself contain a C{dict} value to the same effect.
  129. """
  130. modules = {}
  131. _makePackages(None, dict(twisted=dict(web=dict(version="321"))), modules)
  132. self.assertIsInstance(modules, dict)
  133. self.assertIsInstance(modules["twisted"], ModuleType)
  134. self.assertEqual("twisted", modules["twisted"].__name__)
  135. self.assertIsInstance(modules["twisted"].web, ModuleType)
  136. self.assertEqual("twisted.web", modules["twisted"].web.__name__)
  137. self.assertEqual("321", modules["twisted"].web.version)