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.

testutils.py 5.1KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. I{Private} test utilities for use throughout Twisted's test suite. Unlike
  5. C{proto_helpers}, this is no exception to the
  6. don't-use-it-outside-Twisted-we-won't-maintain-compatibility rule!
  7. @note: Maintainers be aware: things in this module should be gradually promoted
  8. to more full-featured test helpers and exposed as public API as your
  9. maintenance time permits. In order to be public API though, they need
  10. their own test cases.
  11. """
  12. from io import BytesIO
  13. from xml.dom import minidom as dom
  14. from twisted.internet.protocol import FileWrapper
  15. class IOPump:
  16. """Utility to pump data between clients and servers for protocol testing.
  17. Perhaps this is a utility worthy of being in protocol.py?
  18. """
  19. def __init__(self, client, server, clientIO, serverIO):
  20. self.client = client
  21. self.server = server
  22. self.clientIO = clientIO
  23. self.serverIO = serverIO
  24. def flush(self):
  25. "Pump until there is no more input or output."
  26. while self.pump():
  27. pass
  28. def pump(self):
  29. """Move data back and forth.
  30. Returns whether any data was moved.
  31. """
  32. self.clientIO.seek(0)
  33. self.serverIO.seek(0)
  34. cData = self.clientIO.read()
  35. sData = self.serverIO.read()
  36. self.clientIO.seek(0)
  37. self.serverIO.seek(0)
  38. self.clientIO.truncate()
  39. self.serverIO.truncate()
  40. for byte in cData:
  41. self.server.dataReceived(byte)
  42. for byte in sData:
  43. self.client.dataReceived(byte)
  44. if cData or sData:
  45. return 1
  46. else:
  47. return 0
  48. def returnConnected(server, client):
  49. """Take two Protocol instances and connect them."""
  50. cio = BytesIO()
  51. sio = BytesIO()
  52. client.makeConnection(FileWrapper(cio))
  53. server.makeConnection(FileWrapper(sio))
  54. pump = IOPump(client, server, cio, sio)
  55. # Challenge-response authentication:
  56. pump.flush()
  57. # Uh...
  58. pump.flush()
  59. return pump
  60. class XMLAssertionMixin:
  61. """
  62. Test mixin defining a method for comparing serialized XML documents.
  63. Must be mixed in to a L{test case<unittest.TestCase>}.
  64. """
  65. def assertXMLEqual(self, first, second):
  66. """
  67. Verify that two strings represent the same XML document.
  68. @param first: An XML string.
  69. @type first: L{bytes}
  70. @param second: An XML string that should match C{first}.
  71. @type second: L{bytes}
  72. """
  73. self.assertEqual(
  74. dom.parseString(first).toxml(), dom.parseString(second).toxml()
  75. )
  76. class _Equal:
  77. """
  78. A class the instances of which are equal to anything and everything.
  79. """
  80. def __eq__(self, other: object) -> bool:
  81. return True
  82. class _NotEqual:
  83. """
  84. A class the instances of which are equal to nothing.
  85. """
  86. def __eq__(self, other: object) -> bool:
  87. return False
  88. class ComparisonTestsMixin:
  89. """
  90. A mixin which defines a method for making assertions about the correctness
  91. of an implementation of C{==} and C{!=}.
  92. Use this to unit test objects which follow the common convention for C{==}
  93. and C{!=}:
  94. - The object compares equal to itself
  95. - The object cooperates with unrecognized types to allow them to
  96. implement the comparison
  97. - The object implements not-equal as the opposite of equal
  98. """
  99. def assertNormalEqualityImplementation(
  100. self, firstValueOne, secondValueOne, valueTwo
  101. ):
  102. """
  103. Assert that C{firstValueOne} is equal to C{secondValueOne} but not
  104. equal to C{valueOne} and that it defines equality cooperatively with
  105. other types it doesn't know about.
  106. @param firstValueOne: An object which is expected to compare as equal
  107. to C{secondValueOne} and not equal to C{valueTwo}.
  108. @param secondValueOne: A different object than C{firstValueOne} but
  109. which is expected to compare equal to that object.
  110. @param valueTwo: An object which is expected to compare as not equal to
  111. C{firstValueOne}.
  112. """
  113. # This doesn't use assertEqual and assertNotEqual because the exact
  114. # operator those functions use is not very well defined. The point
  115. # of these assertions is to check the results of the use of specific
  116. # operators (precisely to ensure that using different permutations
  117. # (eg "x == y" or "not (x != y)") which should yield the same results
  118. # actually does yield the same result). -exarkun
  119. self.assertTrue(firstValueOne == firstValueOne)
  120. self.assertTrue(firstValueOne == secondValueOne)
  121. self.assertFalse(firstValueOne == valueTwo)
  122. self.assertFalse(firstValueOne != firstValueOne)
  123. self.assertFalse(firstValueOne != secondValueOne)
  124. self.assertTrue(firstValueOne != valueTwo)
  125. self.assertTrue(firstValueOne == _Equal())
  126. self.assertFalse(firstValueOne != _Equal())
  127. self.assertFalse(firstValueOne == _NotEqual())
  128. self.assertTrue(firstValueOne != _NotEqual())