PageRenderTime 48ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/yarss2/include/html5lib/html5lib/tests/support.py

https://gitlab.com/lepaperwan/Deluge-YaRSS2
Python | 198 lines | 146 code | 40 blank | 12 comment | 26 complexity | aa87f2afda43800a72b3e811f36d055e MD5 | raw file
  1. from __future__ import absolute_import, division, unicode_literals
  2. # pylint:disable=wrong-import-position
  3. import os
  4. import sys
  5. import codecs
  6. import glob
  7. import xml.sax.handler
  8. base_path = os.path.split(__file__)[0]
  9. test_dir = os.path.join(base_path, 'testdata')
  10. sys.path.insert(0, os.path.abspath(os.path.join(base_path,
  11. os.path.pardir,
  12. os.path.pardir)))
  13. from html5lib import treebuilders, treewalkers, treeadapters # noqa
  14. del base_path
  15. # Build a dict of available trees
  16. treeTypes = {}
  17. # DOM impls
  18. treeTypes["DOM"] = {
  19. "builder": treebuilders.getTreeBuilder("dom"),
  20. "walker": treewalkers.getTreeWalker("dom")
  21. }
  22. # ElementTree impls
  23. import xml.etree.ElementTree as ElementTree # noqa
  24. treeTypes['ElementTree'] = {
  25. "builder": treebuilders.getTreeBuilder("etree", ElementTree, fullTree=True),
  26. "walker": treewalkers.getTreeWalker("etree", ElementTree)
  27. }
  28. try:
  29. import xml.etree.cElementTree as cElementTree # noqa
  30. except ImportError:
  31. treeTypes['cElementTree'] = None
  32. else:
  33. # On Python 3.3 and above cElementTree is an alias, don't run them twice.
  34. if cElementTree.Element is ElementTree.Element:
  35. treeTypes['cElementTree'] = None
  36. else:
  37. treeTypes['cElementTree'] = {
  38. "builder": treebuilders.getTreeBuilder("etree", cElementTree, fullTree=True),
  39. "walker": treewalkers.getTreeWalker("etree", cElementTree)
  40. }
  41. try:
  42. import lxml.etree as lxml # noqa
  43. except ImportError:
  44. treeTypes['lxml'] = None
  45. else:
  46. treeTypes['lxml'] = {
  47. "builder": treebuilders.getTreeBuilder("lxml"),
  48. "walker": treewalkers.getTreeWalker("lxml")
  49. }
  50. # Genshi impls
  51. try:
  52. import genshi # noqa
  53. except ImportError:
  54. treeTypes["genshi"] = None
  55. else:
  56. treeTypes["genshi"] = {
  57. "builder": treebuilders.getTreeBuilder("dom"),
  58. "adapter": lambda tree: treeadapters.genshi.to_genshi(treewalkers.getTreeWalker("dom")(tree)),
  59. "walker": treewalkers.getTreeWalker("genshi")
  60. }
  61. # pylint:enable=wrong-import-position
  62. def get_data_files(subdirectory, files='*.dat', search_dir=test_dir):
  63. return sorted(glob.glob(os.path.join(search_dir, subdirectory, files)))
  64. class DefaultDict(dict):
  65. def __init__(self, default, *args, **kwargs):
  66. self.default = default
  67. dict.__init__(self, *args, **kwargs)
  68. def __getitem__(self, key):
  69. return dict.get(self, key, self.default)
  70. class TestData(object):
  71. def __init__(self, filename, newTestHeading="data", encoding="utf8"):
  72. if encoding is None:
  73. self.f = open(filename, mode="rb")
  74. else:
  75. self.f = codecs.open(filename, encoding=encoding)
  76. self.encoding = encoding
  77. self.newTestHeading = newTestHeading
  78. def __iter__(self):
  79. data = DefaultDict(None)
  80. key = None
  81. for line in self.f:
  82. heading = self.isSectionHeading(line)
  83. if heading:
  84. if data and heading == self.newTestHeading:
  85. # Remove trailing newline
  86. data[key] = data[key][:-1]
  87. yield self.normaliseOutput(data)
  88. data = DefaultDict(None)
  89. key = heading
  90. data[key] = "" if self.encoding else b""
  91. elif key is not None:
  92. data[key] += line
  93. if data:
  94. yield self.normaliseOutput(data)
  95. def isSectionHeading(self, line):
  96. """If the current heading is a test section heading return the heading,
  97. otherwise return False"""
  98. # print(line)
  99. if line.startswith("#" if self.encoding else b"#"):
  100. return line[1:].strip()
  101. else:
  102. return False
  103. def normaliseOutput(self, data):
  104. # Remove trailing newlines
  105. for key, value in data.items():
  106. if value.endswith("\n" if self.encoding else b"\n"):
  107. data[key] = value[:-1]
  108. return data
  109. def convert(stripChars):
  110. def convertData(data):
  111. """convert the output of str(document) to the format used in the testcases"""
  112. data = data.split("\n")
  113. rv = []
  114. for line in data:
  115. if line.startswith("|"):
  116. rv.append(line[stripChars:])
  117. else:
  118. rv.append(line)
  119. return "\n".join(rv)
  120. return convertData
  121. convertExpected = convert(2)
  122. def errorMessage(input, expected, actual):
  123. msg = ("Input:\n%s\nExpected:\n%s\nRecieved\n%s\n" %
  124. (repr(input), repr(expected), repr(actual)))
  125. if sys.version_info[0] == 2:
  126. msg = msg.encode("ascii", "backslashreplace")
  127. return msg
  128. class TracingSaxHandler(xml.sax.handler.ContentHandler):
  129. def __init__(self):
  130. xml.sax.handler.ContentHandler.__init__(self)
  131. self.visited = []
  132. def startDocument(self):
  133. self.visited.append('startDocument')
  134. def endDocument(self):
  135. self.visited.append('endDocument')
  136. def startPrefixMapping(self, prefix, uri):
  137. # These are ignored as their order is not guaranteed
  138. pass
  139. def endPrefixMapping(self, prefix):
  140. # These are ignored as their order is not guaranteed
  141. pass
  142. def startElement(self, name, attrs):
  143. self.visited.append(('startElement', name, attrs))
  144. def endElement(self, name):
  145. self.visited.append(('endElement', name))
  146. def startElementNS(self, name, qname, attrs):
  147. self.visited.append(('startElementNS', name, qname, dict(attrs)))
  148. def endElementNS(self, name, qname):
  149. self.visited.append(('endElementNS', name, qname))
  150. def characters(self, content):
  151. self.visited.append(('characters', content))
  152. def ignorableWhitespace(self, whitespace):
  153. self.visited.append(('ignorableWhitespace', whitespace))
  154. def processingInstruction(self, target, data):
  155. self.visited.append(('processingInstruction', target, data))
  156. def skippedEntity(self, name):
  157. self.visited.append(('skippedEntity', name))