A Python parser for MediaWiki wikicode https://mwparserfromhell.readthedocs.io/
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.

преди 5 години
преди 10 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 8 години
преди 11 години
преди 8 години
преди 8 години
преди 6 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2012-2017 Ben Kurtovic <ben.kurtovic@gmail.com>
  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. from difflib import unified_diff
  24. import unittest
  25. from mwparserfromhell.compat import str
  26. from mwparserfromhell.nodes import HTMLEntity, Template, Text
  27. from mwparserfromhell.nodes.extras import Parameter
  28. from mwparserfromhell import parse
  29. from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext
  30. pgens = lambda k, v: Parameter(wraptext(k), wraptext(v), showkey=True)
  31. pgenh = lambda k, v: Parameter(wraptext(k), wraptext(v), showkey=False)
  32. class TestTemplate(TreeEqualityTestCase):
  33. """Test cases for the Template node."""
  34. def test_unicode(self):
  35. """test Template.__unicode__()"""
  36. node = Template(wraptext("foobar"))
  37. self.assertEqual("{{foobar}}", str(node))
  38. node2 = Template(wraptext("foo"),
  39. [pgenh("1", "bar"), pgens("abc", "def")])
  40. self.assertEqual("{{foo|bar|abc=def}}", str(node2))
  41. def test_children(self):
  42. """test Template.__children__()"""
  43. node2p1 = Parameter(wraptext("1"), wraptext("bar"), showkey=False)
  44. node2p2 = Parameter(wraptext("abc"), wrap([Text("def"), Text("ghi")]),
  45. showkey=True)
  46. node1 = Template(wraptext("foobar"))
  47. node2 = Template(wraptext("foo"), [node2p1, node2p2])
  48. gen1 = node1.__children__()
  49. gen2 = node2.__children__()
  50. self.assertEqual(node1.name, next(gen1))
  51. self.assertEqual(node2.name, next(gen2))
  52. self.assertEqual(node2.params[0].value, next(gen2))
  53. self.assertEqual(node2.params[1].name, next(gen2))
  54. self.assertEqual(node2.params[1].value, next(gen2))
  55. self.assertRaises(StopIteration, next, gen1)
  56. self.assertRaises(StopIteration, next, gen2)
  57. def test_strip(self):
  58. """test Template.__strip__()"""
  59. node1 = Template(wraptext("foobar"))
  60. node2 = Template(wraptext("foo"), [
  61. pgenh("1", "bar"), pgens("foo", ""), pgens("abc", "def")])
  62. node3 = Template(wraptext("foo"), [
  63. pgenh("1", "foo"),
  64. Parameter(wraptext("2"), wrap([Template(wraptext("hello"))]),
  65. showkey=False),
  66. pgenh("3", "bar")])
  67. self.assertEqual(None, node1.__strip__(keep_template_params=False))
  68. self.assertEqual(None, node2.__strip__(keep_template_params=False))
  69. self.assertEqual("", node1.__strip__(keep_template_params=True))
  70. self.assertEqual("bar def", node2.__strip__(keep_template_params=True))
  71. self.assertEqual("foo bar", node3.__strip__(keep_template_params=True))
  72. def test_showtree(self):
  73. """test Template.__showtree__()"""
  74. output = []
  75. getter, marker = object(), object()
  76. get = lambda code: output.append((getter, code))
  77. mark = lambda: output.append(marker)
  78. node1 = Template(wraptext("foobar"))
  79. node2 = Template(wraptext("foo"),
  80. [pgenh("1", "bar"), pgens("abc", "def")])
  81. node1.__showtree__(output.append, get, mark)
  82. node2.__showtree__(output.append, get, mark)
  83. valid = [
  84. "{{", (getter, node1.name), "}}", "{{", (getter, node2.name),
  85. " | ", marker, (getter, node2.params[0].name), " = ", marker,
  86. (getter, node2.params[0].value), " | ", marker,
  87. (getter, node2.params[1].name), " = ", marker,
  88. (getter, node2.params[1].value), "}}"]
  89. self.assertEqual(valid, output)
  90. def test_name(self):
  91. """test getter/setter for the name attribute"""
  92. name = wraptext("foobar")
  93. node1 = Template(name)
  94. node2 = Template(name, [pgenh("1", "bar")])
  95. self.assertIs(name, node1.name)
  96. self.assertIs(name, node2.name)
  97. node1.name = "asdf"
  98. node2.name = "téstïng"
  99. self.assertWikicodeEqual(wraptext("asdf"), node1.name)
  100. self.assertWikicodeEqual(wraptext("téstïng"), node2.name)
  101. def test_params(self):
  102. """test getter for the params attribute"""
  103. node1 = Template(wraptext("foobar"))
  104. plist = [pgenh("1", "bar"), pgens("abc", "def")]
  105. node2 = Template(wraptext("foo"), plist)
  106. self.assertEqual([], node1.params)
  107. self.assertIs(plist, node2.params)
  108. def test_has(self):
  109. """test Template.has()"""
  110. node1 = Template(wraptext("foobar"))
  111. node2 = Template(wraptext("foo"),
  112. [pgenh("1", "bar"), pgens("\nabc ", "def")])
  113. node3 = Template(wraptext("foo"),
  114. [pgenh("1", "a"), pgens("b", "c"), pgens("1", "d")])
  115. node4 = Template(wraptext("foo"), [pgenh("1", "a"), pgens("b", " ")])
  116. self.assertFalse(node1.has("foobar", False))
  117. self.assertTrue(node2.has(1, False))
  118. self.assertTrue(node2.has("abc", False))
  119. self.assertFalse(node2.has("def", False))
  120. self.assertTrue(node3.has("1", False))
  121. self.assertTrue(node3.has(" b ", False))
  122. self.assertTrue(node4.has("b", False))
  123. self.assertTrue(node3.has("b", True))
  124. self.assertFalse(node4.has("b", True))
  125. self.assertFalse(node1.has_param("foobar", False))
  126. self.assertTrue(node2.has_param(1, False))
  127. def test_get(self):
  128. """test Template.get()"""
  129. node1 = Template(wraptext("foobar"))
  130. node2p1 = pgenh("1", "bar")
  131. node2p2 = pgens("abc", "def")
  132. node2 = Template(wraptext("foo"), [node2p1, node2p2])
  133. node3p1 = pgens("b", "c")
  134. node3p2 = pgens("1", "d")
  135. node3 = Template(wraptext("foo"), [pgenh("1", "a"), node3p1, node3p2])
  136. node4p1 = pgens(" b", " ")
  137. node4 = Template(wraptext("foo"), [pgenh("1", "a"), node4p1])
  138. self.assertRaises(ValueError, node1.get, "foobar")
  139. self.assertIs(node2p1, node2.get(1))
  140. self.assertIs(node2p2, node2.get("abc"))
  141. self.assertRaises(ValueError, node2.get, "def")
  142. self.assertIs(node3p1, node3.get("b"))
  143. self.assertIs(node3p2, node3.get("1"))
  144. self.assertIs(node4p1, node4.get("b "))
  145. def test_add(self):
  146. """test Template.add()"""
  147. node1 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  148. node2 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  149. node3 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  150. node4 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  151. node5 = Template(wraptext("a"), [pgens("b", "c"),
  152. pgens(" d ", "e")])
  153. node6 = Template(wraptext("a"), [pgens("b", "c"), pgens("b", "d"),
  154. pgens("b", "e")])
  155. node7 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  156. node8p = pgenh("1", "d")
  157. node8 = Template(wraptext("a"), [pgens("b", "c"), node8p])
  158. node9 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  159. node10 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "e")])
  160. node11 = Template(wraptext("a"), [pgens("b", "c")])
  161. node12 = Template(wraptext("a"), [pgens("b", "c")])
  162. node13 = Template(wraptext("a"), [
  163. pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
  164. node14 = Template(wraptext("a\n"), [
  165. pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
  166. pgens("h ", " i\n")])
  167. node15 = Template(wraptext("a"), [
  168. pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
  169. node16 = Template(wraptext("a"), [
  170. pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
  171. node17 = Template(wraptext("a"), [pgenh("1", "b")])
  172. node18 = Template(wraptext("a"), [pgenh("1", "b")])
  173. node19 = Template(wraptext("a"), [pgenh("1", "b")])
  174. node20 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
  175. pgenh("3", "d"), pgenh("4", "e")])
  176. node21 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
  177. pgens("4", "d"), pgens("5", "e")])
  178. node22 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
  179. pgens("4", "d"), pgens("5", "e")])
  180. node23 = Template(wraptext("a"), [pgenh("1", "b")])
  181. node24 = Template(wraptext("a"), [pgenh("1", "b")])
  182. node25 = Template(wraptext("a"), [pgens("b", "c")])
  183. node26 = Template(wraptext("a"), [pgenh("1", "b")])
  184. node27 = Template(wraptext("a"), [pgenh("1", "b")])
  185. node28 = Template(wraptext("a"), [pgens("1", "b")])
  186. node29 = Template(wraptext("a"), [
  187. pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
  188. node30 = Template(wraptext("a\n"), [
  189. pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
  190. pgens("h ", " i\n")])
  191. node31 = Template(wraptext("a"), [
  192. pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
  193. node32 = Template(wraptext("a"), [
  194. pgens("\nb ", " c "), pgens("\nd ", " e "), pgens("\nf ", " g ")])
  195. node33 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
  196. pgens("b", "f"), pgens("b", "h"),
  197. pgens("i", "j")])
  198. node34 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
  199. pgens("1", "c"), pgens("2", "d")])
  200. node35 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
  201. pgenh("1", "c"), pgenh("2", "d")])
  202. node36 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
  203. pgens("f", "g")])
  204. node37 = Template(wraptext("a"), [pgenh("1", "")])
  205. node38 = Template(wraptext("abc"))
  206. node39 = Template(wraptext("a"), [pgenh("1", " b ")])
  207. node40 = Template(wraptext("a"), [pgenh("1", " b"), pgenh("2", " c")])
  208. node41 = Template(wraptext("a"), [pgens("1", " b"), pgens("2", " c")])
  209. node42 = Template(wraptext("a"), [pgens("b", " \n")])
  210. node1.add("e", "f", showkey=True)
  211. node2.add(2, "g", showkey=False)
  212. node3.add("e", "foo|bar", showkey=True)
  213. node4.add("e", "f", showkey=True, before="b")
  214. node5.add("f", "g", showkey=True, before=" d ")
  215. node6.add("f", "g", showkey=True, before="b")
  216. self.assertRaises(ValueError, node7.add, "e", "f", showkey=True,
  217. before="q")
  218. node8.add("e", "f", showkey=True, before=node8p)
  219. node9.add("e", "f", showkey=True, before=pgenh("1", "d"))
  220. self.assertRaises(ValueError, node10.add, "e", "f", showkey=True,
  221. before=pgenh("1", "d"))
  222. node11.add("d", "foo=bar", showkey=True)
  223. node12.add("1", "foo=bar", showkey=False)
  224. node13.add("h", "i", showkey=True)
  225. node14.add("j", "k", showkey=True)
  226. node15.add("h", "i", showkey=True)
  227. node16.add("h", "i", showkey=True, preserve_spacing=False)
  228. node17.add("2", "c")
  229. node18.add("3", "c")
  230. node19.add("c", "d")
  231. node20.add("5", "f")
  232. node21.add("3", "f")
  233. node22.add("6", "f")
  234. node23.add("c", "foo=bar")
  235. node24.add("2", "foo=bar")
  236. node25.add("b", "d")
  237. node26.add("1", "foo=bar")
  238. node27.add("1", "foo=bar", showkey=True)
  239. node28.add("1", "foo=bar", showkey=False)
  240. node29.add("d", "foo")
  241. node30.add("f", "foo")
  242. node31.add("f", "foo")
  243. node32.add("d", "foo", preserve_spacing=False)
  244. node33.add("b", "k")
  245. node34.add("1", "e")
  246. node35.add("1", "e")
  247. node36.add("d", "h", before="b")
  248. node37.add(1, "b")
  249. node38.add("1", "foo")
  250. self.assertRaises(ValueError, node38.add, "z", "bar", showkey=False)
  251. node39.add("1", "c")
  252. node40.add("3", "d")
  253. node41.add("3", "d")
  254. node42.add("b", "hello")
  255. self.assertEqual("{{a|b=c|d|e=f}}", node1)
  256. self.assertEqual("{{a|b=c|d|g}}", node2)
  257. self.assertEqual("{{a|b=c|d|e=foo&#124;bar}}", node3)
  258. self.assertIsInstance(node3.params[2].value.get(1), HTMLEntity)
  259. self.assertEqual("{{a|e=f|b=c|d}}", node4)
  260. self.assertEqual("{{a|b=c|f=g| d =e}}", node5)
  261. self.assertEqual("{{a|b=c|b=d|f=g|b=e}}", node6)
  262. self.assertEqual("{{a|b=c|d}}", node7)
  263. self.assertEqual("{{a|b=c|e=f|d}}", node8)
  264. self.assertEqual("{{a|b=c|e=f|d}}", node9)
  265. self.assertEqual("{{a|b=c|e}}", node10)
  266. self.assertEqual("{{a|b=c|d=foo=bar}}", node11)
  267. self.assertEqual("{{a|b=c|foo&#61;bar}}", node12)
  268. self.assertIsInstance(node12.params[1].value.get(1), HTMLEntity)
  269. self.assertEqual("{{a|\nb = c|\nd = e|\nf = g|\nh = i}}", node13)
  270. self.assertEqual("{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}", node14)
  271. self.assertEqual("{{a|b = c\n|\nd = e|\nf =g |\nh = i}}", node15)
  272. self.assertEqual("{{a|\nb = c|\nd = e|\nf = g|h=i}}", node16)
  273. self.assertEqual("{{a|b|c}}", node17)
  274. self.assertEqual("{{a|b|3=c}}", node18)
  275. self.assertEqual("{{a|b|c=d}}", node19)
  276. self.assertEqual("{{a|b|c|d|e|f}}", node20)
  277. self.assertEqual("{{a|b|c|4=d|5=e|f}}", node21)
  278. self.assertEqual("{{a|b|c|4=d|5=e|6=f}}", node22)
  279. self.assertEqual("{{a|b|c=foo=bar}}", node23)
  280. self.assertEqual("{{a|b|foo&#61;bar}}", node24)
  281. self.assertIsInstance(node24.params[1].value.get(1), HTMLEntity)
  282. self.assertEqual("{{a|b=d}}", node25)
  283. self.assertEqual("{{a|foo&#61;bar}}", node26)
  284. self.assertIsInstance(node26.params[0].value.get(1), HTMLEntity)
  285. self.assertEqual("{{a|1=foo=bar}}", node27)
  286. self.assertEqual("{{a|foo&#61;bar}}", node28)
  287. self.assertIsInstance(node28.params[0].value.get(1), HTMLEntity)
  288. self.assertEqual("{{a|\nb = c|\nd = foo|\nf = g}}", node29)
  289. self.assertEqual("{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}", node30)
  290. self.assertEqual("{{a|b = c\n|\nd = e|\nf =foo }}", node31)
  291. self.assertEqual("{{a|\nb = c |\nd =foo|\nf = g }}", node32)
  292. self.assertEqual("{{a|b=k|d=e|i=j}}", node33)
  293. self.assertEqual("{{a|1=e|x=y|2=d}}", node34)
  294. self.assertEqual("{{a|x=y|e|d}}", node35)
  295. self.assertEqual("{{a|b=c|d=h|f=g}}", node36)
  296. self.assertEqual("{{a|b}}", node37)
  297. self.assertEqual("{{abc|foo}}", node38)
  298. self.assertEqual("{{a|c}}", node39)
  299. self.assertEqual("{{a| b| c|d}}", node40)
  300. self.assertEqual("{{a|1= b|2= c|3= d}}", node41)
  301. self.assertEqual("{{a|b=hello \n}}", node42)
  302. def test_remove(self):
  303. """test Template.remove()"""
  304. node1 = Template(wraptext("foobar"))
  305. node2 = Template(wraptext("foo"),
  306. [pgenh("1", "bar"), pgens("abc", "def")])
  307. node3 = Template(wraptext("foo"),
  308. [pgenh("1", "bar"), pgens("abc", "def")])
  309. node4 = Template(wraptext("foo"),
  310. [pgenh("1", "bar"), pgenh("2", "baz")])
  311. node5 = Template(wraptext("foo"), [
  312. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  313. node6 = Template(wraptext("foo"), [
  314. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  315. node7 = Template(wraptext("foo"), [
  316. pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")])
  317. node8 = Template(wraptext("foo"), [
  318. pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")])
  319. node9 = Template(wraptext("foo"), [
  320. pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
  321. node10 = Template(wraptext("foo"), [
  322. pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
  323. node11 = Template(wraptext("foo"), [
  324. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  325. node12 = Template(wraptext("foo"), [
  326. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  327. node13 = Template(wraptext("foo"), [
  328. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  329. node14 = Template(wraptext("foo"), [
  330. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  331. node15 = Template(wraptext("foo"), [
  332. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  333. node16 = Template(wraptext("foo"), [
  334. pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
  335. node17 = Template(wraptext("foo"), [
  336. pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
  337. node18 = Template(wraptext("foo"), [
  338. pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
  339. node19 = Template(wraptext("foo"), [
  340. pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
  341. node20 = Template(wraptext("foo"), [
  342. pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
  343. node21 = Template(wraptext("foo"), [
  344. pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
  345. pgens("a", "b")])
  346. node22 = Template(wraptext("foo"), [
  347. pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
  348. pgens("a", "b")])
  349. node23 = Template(wraptext("foo"), [
  350. pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
  351. pgens("a", "b")])
  352. node24 = Template(wraptext("foo"), [
  353. pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
  354. pgens("a", "b")])
  355. node25 = Template(wraptext("foo"), [
  356. pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
  357. pgens("a", "b")])
  358. node26 = Template(wraptext("foo"), [
  359. pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
  360. pgens("a", "b")])
  361. node27 = Template(wraptext("foo"), [pgenh("1", "bar")])
  362. node28 = Template(wraptext("foo"), [pgenh("1", "bar")])
  363. node2.remove("1")
  364. node2.remove("abc")
  365. node3.remove(1, keep_field=True)
  366. node3.remove("abc", keep_field=True)
  367. node4.remove("1", keep_field=False)
  368. node5.remove("a", keep_field=False)
  369. node6.remove("a", keep_field=True)
  370. node7.remove(1, keep_field=True)
  371. node8.remove(1, keep_field=False)
  372. node9.remove(1, keep_field=True)
  373. node10.remove(1, keep_field=False)
  374. node11.remove(node11.params[0], keep_field=False)
  375. node12.remove(node12.params[0], keep_field=True)
  376. node13.remove(node13.params[1], keep_field=False)
  377. node14.remove(node14.params[1], keep_field=True)
  378. node15.remove(node15.params[2], keep_field=False)
  379. node16.remove(node16.params[2], keep_field=True)
  380. node17.remove(node17.params[0], keep_field=False)
  381. node18.remove(node18.params[0], keep_field=True)
  382. node19.remove(node19.params[1], keep_field=False)
  383. node20.remove(node20.params[1], keep_field=True)
  384. node21.remove("a", keep_field=False)
  385. node22.remove("a", keep_field=True)
  386. node23.remove(node23.params[0], keep_field=False)
  387. node24.remove(node24.params[0], keep_field=True)
  388. node25.remove(node25.params[3], keep_field=False)
  389. node26.remove(node26.params[3], keep_field=True)
  390. self.assertRaises(ValueError, node1.remove, 1)
  391. self.assertRaises(ValueError, node1.remove, "a")
  392. self.assertRaises(ValueError, node2.remove, "1")
  393. self.assertEqual("{{foo}}", node2)
  394. self.assertEqual("{{foo||abc=}}", node3)
  395. self.assertEqual("{{foo|2=baz}}", node4)
  396. self.assertEqual("{{foo|b=c}}", node5)
  397. self.assertEqual("{{foo| a=|b=c}}", node6)
  398. self.assertEqual("{{foo|1 =|2=c}}", node7)
  399. self.assertEqual("{{foo|2=c}}", node8)
  400. self.assertEqual("{{foo||c}}", node9)
  401. self.assertEqual("{{foo|2=c}}", node10)
  402. self.assertEqual("{{foo|b=c|a =d}}", node11)
  403. self.assertEqual("{{foo| a=|b=c|a =d}}", node12)
  404. self.assertEqual("{{foo| a=b|a =d}}", node13)
  405. self.assertEqual("{{foo| a=b|b=|a =d}}", node14)
  406. self.assertEqual("{{foo| a=b|b=c}}", node15)
  407. self.assertEqual("{{foo| a=b|b=c|a =}}", node16)
  408. self.assertEqual("{{foo|b|c}}", node17)
  409. self.assertEqual("{{foo|1 =|b|c}}", node18)
  410. self.assertEqual("{{foo|1 =a|2=c}}", node19)
  411. self.assertEqual("{{foo|1 =a||c}}", node20)
  412. self.assertEqual("{{foo|c=d|e=f}}", node21)
  413. self.assertEqual("{{foo|a=|c=d|e=f}}", node22)
  414. self.assertEqual("{{foo|c=d|e=f|a=b|a=b}}", node23)
  415. self.assertEqual("{{foo|a=|c=d|e=f|a=b|a=b}}", node24)
  416. self.assertEqual("{{foo|a=b|c=d|e=f|a=b}}", node25)
  417. self.assertEqual("{{foo|a=b|c=d|e=f|a=|a=b}}", node26)
  418. self.assertRaises(ValueError, node27.remove, node28.get(1))
  419. def test_formatting(self):
  420. """test realistic param manipulation with complex whitespace formatting
  421. (assumes that parsing works correctly)"""
  422. tests = [
  423. # https://en.wikipedia.org/w/index.php?title=Lamar_County,_Georgia&oldid=792356004
  424. ("""{{Infobox U.S. county
  425. | county = Lamar County
  426. | state = Georgia
  427. | seal =
  428. | founded = 1920
  429. | seat wl = Barnesville
  430. | largest city wl = Barnesville
  431. | area_total_sq_mi = 186
  432. | area_land_sq_mi = 184
  433. | area_water_sq_mi = 2.3
  434. | area percentage = 1.3%
  435. | census yr = 2010
  436. | pop = 18317
  437. | density_sq_mi = 100
  438. | time zone = Eastern
  439. | footnotes =
  440. | web = www.lamarcountyga.com
  441. | ex image = Lamar County Georgia Courthouse.jpg
  442. | ex image cap = Lamar County courthouse in Barnesville
  443. | district = 3rd
  444. | named for = [[Lucius Quintus Cincinnatus Lamar II]]
  445. }}""",
  446. """@@ -11,4 +11,4 @@
  447. | area percentage = 1.3%
  448. -| census yr = 2010
  449. -| pop = 18317
  450. +| census estimate yr = 2016
  451. +| pop = 12345<ref>example ref</ref>
  452. | density_sq_mi = 100"""),
  453. # https://en.wikipedia.org/w/index.php?title=Rockdale_County,_Georgia&oldid=792359760
  454. ("""{{Infobox U.S. County|
  455. county = Rockdale County |
  456. state = Georgia |
  457. seal = |
  458. founded = October 18, 1870 |
  459. seat wl = Conyers |
  460. largest city wl = Conyers |
  461. area_total_sq_mi = 132 |
  462. area_land_sq_mi = 130 |
  463. area_water_sq_mi = 2.3 |
  464. area percentage = 1.7% |
  465. census yr = 2010|
  466. pop = 85215 |
  467. density_sq_mi = 657 |
  468. web = www.rockdalecounty.org
  469. | ex image = Rockdale-county-courthouse.jpg
  470. | ex image cap = Rockdale County Courthouse in Conyers
  471. | district = 4th
  472. | time zone= Eastern
  473. }}""",
  474. """@@ -11,4 +11,4 @@
  475. area percentage = 1.7% |
  476. - census yr = 2010|
  477. - pop = 85215 |
  478. + census estimate yr = 2016 |
  479. + pop = 12345<ref>example ref</ref> |
  480. density_sq_mi = 657 |"""),
  481. # https://en.wikipedia.org/w/index.php?title=Spalding_County,_Georgia&oldid=792360413
  482. ("""{{Infobox U.S. County|
  483. | county = Spalding County |
  484. | state = Georgia |
  485. | seal = |
  486. | founded = 1851 |
  487. | seat wl = Griffin |
  488. | largest city wl = Griffin |
  489. | area_total_sq_mi = 200 |
  490. | area_land_sq_mi = 196 |
  491. | area_water_sq_mi = 3.1 |
  492. | area percentage = 1.6% |
  493. | census yr = 2010|
  494. | pop = 64073 |
  495. | density_sq_mi = 326 |
  496. | web = www.spaldingcounty.com |
  497. | named for = [[Thomas Spalding]]
  498. | ex image = Spalding County Courthouse (NE corner).JPG
  499. | ex image cap = Spalding County Courthouse in Griffin
  500. | district = 3rd
  501. | time zone = Eastern
  502. }}""",
  503. """@@ -11,4 +11,4 @@
  504. | area percentage = 1.6% |
  505. -| census yr = 2010|
  506. -| pop = 64073 |
  507. +|
  508. +| census estimate yr = 2016 | pop = 12345<ref>example ref</ref> |
  509. | density_sq_mi = 326 |"""),
  510. # https://en.wikipedia.org/w/index.php?title=Clinton_County,_Illinois&oldid=794694648
  511. ("""{{Infobox U.S. county
  512. |county = Clinton County
  513. |state = Illinois
  514. | ex image = File:Clinton County Courthouse, Carlyle.jpg
  515. | ex image cap = [[Clinton County Courthouse (Illinois)|Clinton County Courthouse]]
  516. |seal =
  517. |founded = 1824
  518. |named for = [[DeWitt Clinton]]
  519. |seat wl= Carlyle
  520. | largest city wl = Breese
  521. |time zone=Central
  522. |area_total_sq_mi = 503
  523. |area_land_sq_mi = 474
  524. |area_water_sq_mi = 29
  525. |area percentage = 5.8%
  526. |census yr = 2010
  527. |pop = 37762
  528. |density_sq_mi = 80
  529. |web = www.clintonco.illinois.gov
  530. | district = 15th
  531. }}""",
  532. """@@ -15,4 +15,4 @@
  533. |area percentage = 5.8%
  534. - |census yr = 2010
  535. - |pop = 37762
  536. + |census estimate yr = 2016
  537. + |pop = 12345<ref>example ref</ref>
  538. |density_sq_mi = 80"""),
  539. # https://en.wikipedia.org/w/index.php?title=Winnebago_County,_Illinois&oldid=789193800
  540. ("""{{Infobox U.S. county |
  541. county = Winnebago County |
  542. state = Illinois |
  543. seal = Winnebago County il seal.png |
  544. named for = [[Winnebago (tribe)|Winnebago Tribe]] |
  545. seat wl= Rockford |
  546. largest city wl = Rockford|
  547. area_total_sq_mi = 519 |
  548. area_land_sq_mi = 513|
  549. area_water_sq_mi = 5.9 |
  550. area percentage = 1.1% |
  551. census yr = 2010|
  552. pop = 295266 |
  553. density_sq_mi = 575
  554. | web = www.wincoil.us
  555. | founded year = 1836
  556. | founded date = January 16
  557. | time zone = Central
  558. | district = 16th
  559. | district2 = 17th
  560. }}""",
  561. """@@ -11,4 +11,4 @@
  562. area percentage = 1.1% |
  563. - census yr = 2010|
  564. - pop = 295266 |
  565. + census estimate yr = 2016|
  566. + pop = 12345<ref>example ref</ref> |
  567. density_sq_mi = 575""")]
  568. for (original, expected) in tests:
  569. code = parse(original)
  570. template = code.filter_templates()[0]
  571. template.add("pop", "12345<ref>example ref</ref>")
  572. template.add('census estimate yr', "2016", before="pop")
  573. template.remove("census yr")
  574. oldlines = original.splitlines(True)
  575. newlines = str(code).splitlines(True)
  576. difflines = unified_diff(oldlines, newlines, n=1)
  577. diff = "".join(list(difflines)[2:]).strip()
  578. self.assertEqual(expected, diff)
  579. if __name__ == "__main__":
  580. unittest.main(verbosity=2)