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.

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