123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- # Copyright (c) Twisted Matrix Laboratories.
- # See LICENSE for details.
-
- """
- I{Private} test utilities for use throughout Twisted's test suite. Unlike
- C{proto_helpers}, this is no exception to the
- don't-use-it-outside-Twisted-we-won't-maintain-compatibility rule!
-
- @note: Maintainers be aware: things in this module should be gradually promoted
- to more full-featured test helpers and exposed as public API as your
- maintenance time permits. In order to be public API though, they need
- their own test cases.
- """
-
- from io import BytesIO
- from xml.dom import minidom as dom
-
- from twisted.internet.protocol import FileWrapper
-
-
- class IOPump:
- """Utility to pump data between clients and servers for protocol testing.
-
- Perhaps this is a utility worthy of being in protocol.py?
- """
-
- def __init__(self, client, server, clientIO, serverIO):
- self.client = client
- self.server = server
- self.clientIO = clientIO
- self.serverIO = serverIO
-
- def flush(self):
- "Pump until there is no more input or output."
- while self.pump():
- pass
-
- def pump(self):
- """Move data back and forth.
-
- Returns whether any data was moved.
- """
- self.clientIO.seek(0)
- self.serverIO.seek(0)
- cData = self.clientIO.read()
- sData = self.serverIO.read()
- self.clientIO.seek(0)
- self.serverIO.seek(0)
- self.clientIO.truncate()
- self.serverIO.truncate()
- for byte in cData:
- self.server.dataReceived(byte)
- for byte in sData:
- self.client.dataReceived(byte)
- if cData or sData:
- return 1
- else:
- return 0
-
-
- def returnConnected(server, client):
- """Take two Protocol instances and connect them."""
- cio = BytesIO()
- sio = BytesIO()
- client.makeConnection(FileWrapper(cio))
- server.makeConnection(FileWrapper(sio))
- pump = IOPump(client, server, cio, sio)
- # Challenge-response authentication:
- pump.flush()
- # Uh...
- pump.flush()
- return pump
-
-
- class XMLAssertionMixin:
- """
- Test mixin defining a method for comparing serialized XML documents.
-
- Must be mixed in to a L{test case<unittest.TestCase>}.
- """
-
- def assertXMLEqual(self, first, second):
- """
- Verify that two strings represent the same XML document.
-
- @param first: An XML string.
- @type first: L{bytes}
-
- @param second: An XML string that should match C{first}.
- @type second: L{bytes}
- """
- self.assertEqual(
- dom.parseString(first).toxml(), dom.parseString(second).toxml()
- )
-
-
- class _Equal:
- """
- A class the instances of which are equal to anything and everything.
- """
-
- def __eq__(self, other: object) -> bool:
- return True
-
-
- class _NotEqual:
- """
- A class the instances of which are equal to nothing.
- """
-
- def __eq__(self, other: object) -> bool:
- return False
-
-
- class ComparisonTestsMixin:
- """
- A mixin which defines a method for making assertions about the correctness
- of an implementation of C{==} and C{!=}.
-
- Use this to unit test objects which follow the common convention for C{==}
- and C{!=}:
-
- - The object compares equal to itself
- - The object cooperates with unrecognized types to allow them to
- implement the comparison
- - The object implements not-equal as the opposite of equal
- """
-
- def assertNormalEqualityImplementation(
- self, firstValueOne, secondValueOne, valueTwo
- ):
- """
- Assert that C{firstValueOne} is equal to C{secondValueOne} but not
- equal to C{valueOne} and that it defines equality cooperatively with
- other types it doesn't know about.
-
- @param firstValueOne: An object which is expected to compare as equal
- to C{secondValueOne} and not equal to C{valueTwo}.
-
- @param secondValueOne: A different object than C{firstValueOne} but
- which is expected to compare equal to that object.
-
- @param valueTwo: An object which is expected to compare as not equal to
- C{firstValueOne}.
- """
- # This doesn't use assertEqual and assertNotEqual because the exact
- # operator those functions use is not very well defined. The point
- # of these assertions is to check the results of the use of specific
- # operators (precisely to ensure that using different permutations
- # (eg "x == y" or "not (x != y)") which should yield the same results
- # actually does yield the same result). -exarkun
- self.assertTrue(firstValueOne == firstValueOne)
- self.assertTrue(firstValueOne == secondValueOne)
- self.assertFalse(firstValueOne == valueTwo)
- self.assertFalse(firstValueOne != firstValueOne)
- self.assertFalse(firstValueOne != secondValueOne)
- self.assertTrue(firstValueOne != valueTwo)
- self.assertTrue(firstValueOne == _Equal())
- self.assertFalse(firstValueOne != _Equal())
- self.assertFalse(firstValueOne == _NotEqual())
- self.assertTrue(firstValueOne != _NotEqual())
|