A Python parser for MediaWiki wikicode https://mwparserfromhell.readthedocs.io/
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

230 řádky
9.9 KiB

  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2012-2013 Ben Kurtovic <ben.kurtovic@verizon.net>
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a copy
  6. # of this software and associated documentation files (the "Software"), to deal
  7. # in the Software without restriction, including without limitation the rights
  8. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the Software is
  10. # furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. # SOFTWARE.
  22. from __future__ import unicode_literals
  23. import unittest
  24. from mwparserfromhell.nodes import (Argument, Comment, Heading, HTMLEntity,
  25. Tag, Template, Text, Wikilink)
  26. from mwparserfromhell.smart_list import SmartList
  27. from mwparserfromhell.wikicode import Wikicode
  28. from mwparserfromhell import parse
  29. from mwparserfromhell.compat import str
  30. from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext
  31. class TestWikicode(TreeEqualityTestCase):
  32. """Tests for the Wikicode class, which manages a list of nodes."""
  33. def test_unicode(self):
  34. """test Wikicode.__unicode__()"""
  35. code1 = parse("foobar")
  36. code2 = parse("Have a {{template}} and a [[page|link]]")
  37. self.assertEqual("foobar", str(code1))
  38. self.assertEqual("Have a {{template}} and a [[page|link]]", str(code2))
  39. def test_nodes(self):
  40. """test getter/setter for the nodes attribute"""
  41. code = parse("Have a {{template}}")
  42. self.assertEqual(["Have a ", "{{template}}"], code.nodes)
  43. L1 = SmartList([Text("foobar"), Template(wraptext("abc"))])
  44. L2 = [Text("barfoo"), Template(wraptext("cba"))]
  45. L3 = "abc{{def}}"
  46. code.nodes = L1
  47. self.assertIs(L1, code.nodes)
  48. code.nodes = L2
  49. self.assertIs(L2, code.nodes)
  50. code.nodes = L3
  51. self.assertEqual(["abc", "{{def}}"], code.nodes)
  52. self.assertRaises(ValueError, setattr, code, "nodes", object)
  53. def test_get(self):
  54. """test Wikicode.get()"""
  55. code = parse("Have a {{template}} and a [[page|link]]")
  56. self.assertIs(code.nodes[0], code.get(0))
  57. self.assertIs(code.nodes[2], code.get(2))
  58. self.assertRaises(IndexError, code.get, 4)
  59. def test_set(self):
  60. """test Wikicode.set()"""
  61. code = parse("Have a {{template}} and a [[page|link]]")
  62. code.set(1, "{{{argument}}}")
  63. self.assertEqual("Have a {{{argument}}} and a [[page|link]]", code)
  64. self.assertIsInstance(code.get(1), Argument)
  65. code.set(2, None)
  66. self.assertEqual("Have a {{{argument}}}[[page|link]]", code)
  67. code.set(-3, "This is an ")
  68. self.assertEqual("This is an {{{argument}}}[[page|link]]", code)
  69. self.assertRaises(ValueError, code.set, 1, "foo {{bar}}")
  70. self.assertRaises(IndexError, code.set, 3, "{{baz}}")
  71. self.assertRaises(IndexError, code.set, -4, "{{baz}}")
  72. def test_index(self):
  73. """test Wikicode.index()"""
  74. code = parse("Have a {{template}} and a [[page|link]]")
  75. self.assertEqual(0, code.index("Have a "))
  76. self.assertEqual(3, code.index("[[page|link]]"))
  77. self.assertEqual(1, code.index(code.get(1)))
  78. self.assertRaises(ValueError, code.index, "foo")
  79. code = parse("{{foo}}{{bar|{{baz}}}}")
  80. self.assertEqual(1, code.index("{{bar|{{baz}}}}"))
  81. self.assertEqual(1, code.index("{{baz}}", recursive=True))
  82. self.assertEqual(1, code.index(code.get(1).get(1).value,
  83. recursive=True))
  84. self.assertRaises(ValueError, code.index, "{{baz}}", recursive=False)
  85. self.assertRaises(ValueError, code.index,
  86. code.get(1).get(1).value, recursive=False)
  87. def test_insert(self):
  88. """test Wikicode.insert()"""
  89. code = parse("Have a {{template}} and a [[page|link]]")
  90. code.insert(1, "{{{argument}}}")
  91. self.assertEqual(
  92. "Have a {{{argument}}}{{template}} and a [[page|link]]", code)
  93. self.assertIsInstance(code.get(1), Argument)
  94. code.insert(2, None)
  95. self.assertEqual(
  96. "Have a {{{argument}}}{{template}} and a [[page|link]]", code)
  97. code.insert(-3, Text("foo"))
  98. self.assertEqual(
  99. "Have a {{{argument}}}foo{{template}} and a [[page|link]]", code)
  100. code2 = parse("{{foo}}{{bar}}{{baz}}")
  101. code2.insert(1, "abc{{def}}ghi[[jk]]")
  102. self.assertEqual("{{foo}}abc{{def}}ghi[[jk]]{{bar}}{{baz}}", code2)
  103. self.assertEqual(["{{foo}}", "abc", "{{def}}", "ghi", "[[jk]]",
  104. "{{bar}}", "{{baz}}"], code2.nodes)
  105. code3 = parse("{{foo}}bar")
  106. code3.insert(1000, "[[baz]]")
  107. code3.insert(-1000, "derp")
  108. self.assertEqual("derp{{foo}}bar[[baz]]", code3)
  109. def test_insert_before(self):
  110. """test Wikicode.insert_before()"""
  111. code = parse("{{a}}{{b}}{{c}}{{d}}")
  112. code.insert_before("{{b}}", "x", recursive=True)
  113. code.insert_before("{{d}}", "[[y]]", recursive=False)
  114. self.assertEqual("{{a}}x{{b}}{{c}}[[y]]{{d}}", code)
  115. code.insert_before(code.get(2), "z")
  116. self.assertEqual("{{a}}xz{{b}}{{c}}[[y]]{{d}}", code)
  117. self.assertRaises(ValueError, code.insert_before, "{{r}}", "n",
  118. recursive=True)
  119. self.assertRaises(ValueError, code.insert_before, "{{r}}", "n",
  120. recursive=False)
  121. code2 = parse("{{a|{{b}}|{{c|d={{f}}}}}}")
  122. code2.insert_before(code2.get(0).params[0].value.get(0), "x",
  123. recursive=True)
  124. code2.insert_before("{{f}}", "y", recursive=True)
  125. self.assertEqual("{{a|x{{b}}|{{c|d=y{{f}}}}}}", code2)
  126. self.assertRaises(ValueError, code2.insert_before, "{{f}}", "y",
  127. recursive=False)
  128. def test_insert_after(self):
  129. """test Wikicode.insert_after()"""
  130. code = parse("{{a}}{{b}}{{c}}{{d}}")
  131. code.insert_after("{{b}}", "x", recursive=True)
  132. code.insert_after("{{d}}", "[[y]]", recursive=False)
  133. self.assertEqual("{{a}}{{b}}x{{c}}{{d}}[[y]]", code)
  134. code.insert_after(code.get(2), "z")
  135. self.assertEqual("{{a}}{{b}}xz{{c}}{{d}}[[y]]", code)
  136. self.assertRaises(ValueError, code.insert_after, "{{r}}", "n",
  137. recursive=True)
  138. self.assertRaises(ValueError, code.insert_after, "{{r}}", "n",
  139. recursive=False)
  140. code2 = parse("{{a|{{b}}|{{c|d={{f}}}}}}")
  141. code2.insert_after(code2.get(0).params[0].value.get(0), "x",
  142. recursive=True)
  143. code2.insert_after("{{f}}", "y", recursive=True)
  144. self.assertEqual("{{a|{{b}}x|{{c|d={{f}}y}}}}", code2)
  145. self.assertRaises(ValueError, code2.insert_after, "{{f}}", "y",
  146. recursive=False)
  147. def test_replace(self):
  148. """test Wikicode.replace()"""
  149. code = parse("{{a}}{{b}}{{c}}{{d}}")
  150. code.replace("{{b}}", "x", recursive=True)
  151. code.replace("{{d}}", "[[y]]", recursive=False)
  152. self.assertEqual("{{a}}x{{c}}[[y]]", code)
  153. code.replace(code.get(1), "z")
  154. self.assertEqual("{{a}}z{{c}}[[y]]", code)
  155. self.assertRaises(ValueError, code.replace, "{{r}}", "n",
  156. recursive=True)
  157. self.assertRaises(ValueError, code.replace, "{{r}}", "n",
  158. recursive=False)
  159. code2 = parse("{{a|{{b}}|{{c|d={{f}}}}}}")
  160. code2.replace(code2.get(0).params[0].value.get(0), "x", recursive=True)
  161. code2.replace("{{f}}", "y", recursive=True)
  162. self.assertEqual("{{a|x|{{c|d=y}}}}", code2)
  163. self.assertRaises(ValueError, code2.replace, "y", "z", recursive=False)
  164. def test_append(self):
  165. """test Wikicode.append()"""
  166. code = parse("Have a {{template}}")
  167. code.append("{{{argument}}}")
  168. self.assertEqual("Have a {{template}}{{{argument}}}", code)
  169. self.assertIsInstance(code.get(2), Argument)
  170. code.append(None)
  171. self.assertEqual("Have a {{template}}{{{argument}}}", code)
  172. code.append(Text(" foo"))
  173. self.assertEqual("Have a {{template}}{{{argument}}} foo", code)
  174. self.assertRaises(ValueError, code.append, slice(0, 1))
  175. def test_remove(self):
  176. """test Wikicode.remove()"""
  177. code = parse("{{a}}{{b}}{{c}}{{d}}")
  178. code.remove("{{b}}", recursive=True)
  179. code.remove(code.get(1), recursive=True)
  180. self.assertEqual("{{a}}{{d}}", code)
  181. self.assertRaises(ValueError, code.remove, "{{r}}", recursive=True)
  182. self.assertRaises(ValueError, code.remove, "{{r}}", recursive=False)
  183. code2 = parse("{{a|{{b}}|{{c|d={{f}}{{h}}}}}}")
  184. code2.remove(code2.get(0).params[0].value.get(0), recursive=True)
  185. code2.remove("{{f}}", recursive=True)
  186. self.assertEqual("{{a||{{c|d={{h}}}}}}", code2)
  187. self.assertRaises(ValueError, code2.remove, "{{h}}", recursive=False)
  188. def test_filter_family(self):
  189. """test the Wikicode.i?filter() family of functions"""
  190. pass
  191. def test_get_sections(self):
  192. """test Wikicode.get_sections()"""
  193. pass
  194. def test_strip_code(self):
  195. """test Wikicode.strip_code()"""
  196. pass
  197. def test_get_tree(self):
  198. """test Wikicode.get_tree()"""
  199. pass
  200. if __name__ == "__main__":
  201. unittest.main(verbosity=2)