test_xmlstream.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for L{twisted.words.xish.xmlstream}.
  5. """
  6. from __future__ import absolute_import, division
  7. from twisted.internet import protocol
  8. from twisted.python import failure
  9. from twisted.trial import unittest
  10. from twisted.words.xish import domish, utility, xmlstream
  11. class XmlStreamTests(unittest.TestCase):
  12. def setUp(self):
  13. self.connectionLostMsg = "no reason"
  14. self.outlist = []
  15. self.xmlstream = xmlstream.XmlStream()
  16. self.xmlstream.transport = self
  17. self.xmlstream.transport.write = self.outlist.append
  18. def loseConnection(self):
  19. """
  20. Stub loseConnection because we are a transport.
  21. """
  22. self.xmlstream.connectionLost(failure.Failure(
  23. Exception(self.connectionLostMsg)))
  24. def test_send(self):
  25. """
  26. Calling L{xmlstream.XmlStream.send} results in the data being written
  27. to the transport.
  28. """
  29. self.xmlstream.connectionMade()
  30. self.xmlstream.send(b"<root>")
  31. self.assertEqual(self.outlist[0], b"<root>")
  32. def test_receiveRoot(self):
  33. """
  34. Receiving the starttag of the root element results in stream start.
  35. """
  36. streamStarted = []
  37. def streamStartEvent(rootelem):
  38. streamStarted.append(None)
  39. self.xmlstream.addObserver(xmlstream.STREAM_START_EVENT,
  40. streamStartEvent)
  41. self.xmlstream.connectionMade()
  42. self.xmlstream.dataReceived("<root>")
  43. self.assertEqual(1, len(streamStarted))
  44. def test_receiveBadXML(self):
  45. """
  46. Receiving malformed XML results in an L{STREAM_ERROR_EVENT}.
  47. """
  48. streamError = []
  49. streamEnd = []
  50. def streamErrorEvent(reason):
  51. streamError.append(reason)
  52. def streamEndEvent(_):
  53. streamEnd.append(None)
  54. self.xmlstream.addObserver(xmlstream.STREAM_ERROR_EVENT,
  55. streamErrorEvent)
  56. self.xmlstream.addObserver(xmlstream.STREAM_END_EVENT,
  57. streamEndEvent)
  58. self.xmlstream.connectionMade()
  59. self.xmlstream.dataReceived("<root>")
  60. self.assertEqual(0, len(streamError))
  61. self.assertEqual(0, len(streamEnd))
  62. self.xmlstream.dataReceived("<child><unclosed></child>")
  63. self.assertEqual(1, len(streamError))
  64. self.assertTrue(streamError[0].check(domish.ParserError))
  65. self.assertEqual(1, len(streamEnd))
  66. def test_streamEnd(self):
  67. """
  68. Ending the stream fires a L{STREAM_END_EVENT}.
  69. """
  70. streamEnd = []
  71. def streamEndEvent(reason):
  72. streamEnd.append(reason)
  73. self.xmlstream.addObserver(xmlstream.STREAM_END_EVENT,
  74. streamEndEvent)
  75. self.xmlstream.connectionMade()
  76. self.loseConnection()
  77. self.assertEqual(1, len(streamEnd))
  78. self.assertIsInstance(streamEnd[0], failure.Failure)
  79. self.assertEqual(streamEnd[0].getErrorMessage(),
  80. self.connectionLostMsg)
  81. class DummyProtocol(protocol.Protocol, utility.EventDispatcher):
  82. """
  83. I am a protocol with an event dispatcher without further processing.
  84. This protocol is only used for testing XmlStreamFactoryMixin to make
  85. sure the bootstrap observers are added to the protocol instance.
  86. """
  87. def __init__(self, *args, **kwargs):
  88. self.args = args
  89. self.kwargs = kwargs
  90. self.observers = []
  91. utility.EventDispatcher.__init__(self)
  92. class BootstrapMixinTests(unittest.TestCase):
  93. """
  94. Tests for L{xmlstream.BootstrapMixin}.
  95. @ivar factory: Instance of the factory or mixin under test.
  96. """
  97. def setUp(self):
  98. self.factory = xmlstream.BootstrapMixin()
  99. def test_installBootstraps(self):
  100. """
  101. Dispatching an event fires registered bootstrap observers.
  102. """
  103. called = []
  104. def cb(data):
  105. called.append(data)
  106. dispatcher = DummyProtocol()
  107. self.factory.addBootstrap('//event/myevent', cb)
  108. self.factory.installBootstraps(dispatcher)
  109. dispatcher.dispatch(None, '//event/myevent')
  110. self.assertEqual(1, len(called))
  111. def test_addAndRemoveBootstrap(self):
  112. """
  113. Test addition and removal of a bootstrap event handler.
  114. """
  115. called = []
  116. def cb(data):
  117. called.append(data)
  118. self.factory.addBootstrap('//event/myevent', cb)
  119. self.factory.removeBootstrap('//event/myevent', cb)
  120. dispatcher = DummyProtocol()
  121. self.factory.installBootstraps(dispatcher)
  122. dispatcher.dispatch(None, '//event/myevent')
  123. self.assertFalse(called)
  124. class GenericXmlStreamFactoryTestsMixin(BootstrapMixinTests):
  125. """
  126. Generic tests for L{XmlStream} factories.
  127. """
  128. def setUp(self):
  129. self.factory = xmlstream.XmlStreamFactory()
  130. def test_buildProtocolInstallsBootstraps(self):
  131. """
  132. The protocol factory installs bootstrap event handlers on the protocol.
  133. """
  134. called = []
  135. def cb(data):
  136. called.append(data)
  137. self.factory.addBootstrap('//event/myevent', cb)
  138. xs = self.factory.buildProtocol(None)
  139. xs.dispatch(None, '//event/myevent')
  140. self.assertEqual(1, len(called))
  141. def test_buildProtocolStoresFactory(self):
  142. """
  143. The protocol factory is saved in the protocol.
  144. """
  145. xs = self.factory.buildProtocol(None)
  146. self.assertIdentical(self.factory, xs.factory)
  147. class XmlStreamFactoryMixinTests(GenericXmlStreamFactoryTestsMixin):
  148. """
  149. Tests for L{xmlstream.XmlStreamFactoryMixin}.
  150. """
  151. def setUp(self):
  152. self.factory = xmlstream.XmlStreamFactoryMixin(None, test=None)
  153. self.factory.protocol = DummyProtocol
  154. def test_buildProtocolFactoryArguments(self):
  155. """
  156. Arguments passed to the factory are passed to protocol on
  157. instantiation.
  158. """
  159. xs = self.factory.buildProtocol(None)
  160. self.assertEqual((None,), xs.args)
  161. self.assertEqual({'test': None}, xs.kwargs)