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.
 
 
 
 

740 lines
24 KiB

  1. # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. #
  3. # Permission is hereby granted, free of charge, to any person obtaining a copy
  4. # of this software and associated documentation files (the "Software"), to deal
  5. # in the Software without restriction, including without limitation the rights
  6. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. # copies of the Software, and to permit persons to whom the Software is
  8. # furnished to do so, subject to the following conditions:
  9. #
  10. # The above copyright notice and this permission notice shall be included in
  11. # all copies or substantial portions of the Software.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. # SOFTWARE.
  20. """
  21. Test cases for the Template node.
  22. """
  23. from difflib import unified_diff
  24. import pytest
  25. from mwparserfromhell.nodes import HTMLEntity, Template, Text
  26. from mwparserfromhell.nodes.extras import Parameter
  27. from mwparserfromhell import parse
  28. from .conftest import assert_wikicode_equal, wrap, wraptext
  29. pgens = lambda k, v: Parameter(wraptext(k), wraptext(v), showkey=True)
  30. pgenh = lambda k, v: Parameter(wraptext(k), wraptext(v), showkey=False)
  31. def test_str():
  32. """test Template.__str__()"""
  33. node = Template(wraptext("foobar"))
  34. assert "{{foobar}}" == str(node)
  35. node2 = Template(wraptext("foo"), [pgenh("1", "bar"), pgens("abc", "def")])
  36. assert "{{foo|bar|abc=def}}" == str(node2)
  37. def test_children():
  38. """test Template.__children__()"""
  39. node2p1 = Parameter(wraptext("1"), wraptext("bar"), showkey=False)
  40. node2p2 = Parameter(wraptext("abc"), wrap([Text("def"), Text("ghi")]), showkey=True)
  41. node1 = Template(wraptext("foobar"))
  42. node2 = Template(wraptext("foo"), [node2p1, node2p2])
  43. gen1 = node1.__children__()
  44. gen2 = node2.__children__()
  45. assert node1.name == next(gen1)
  46. assert node2.name == next(gen2)
  47. assert node2.params[0].value == next(gen2)
  48. assert node2.params[1].name == next(gen2)
  49. assert node2.params[1].value == next(gen2)
  50. with pytest.raises(StopIteration):
  51. next(gen1)
  52. with pytest.raises(StopIteration):
  53. next(gen2)
  54. def test_strip():
  55. """test Template.__strip__()"""
  56. node1 = Template(wraptext("foobar"))
  57. node2 = Template(
  58. wraptext("foo"), [pgenh("1", "bar"), pgens("foo", ""), pgens("abc", "def")]
  59. )
  60. node3 = Template(
  61. wraptext("foo"),
  62. [
  63. pgenh("1", "foo"),
  64. Parameter(
  65. wraptext("2"), wrap([Template(wraptext("hello"))]), showkey=False
  66. ),
  67. pgenh("3", "bar"),
  68. ],
  69. )
  70. assert node1.__strip__(keep_template_params=False) is None
  71. assert node2.__strip__(keep_template_params=False) is None
  72. assert "" == node1.__strip__(keep_template_params=True)
  73. assert "bar def" == node2.__strip__(keep_template_params=True)
  74. assert "foo bar" == node3.__strip__(keep_template_params=True)
  75. def test_showtree():
  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"), [pgenh("1", "bar"), pgens("abc", "def")])
  83. node1.__showtree__(output.append, get, mark)
  84. node2.__showtree__(output.append, get, mark)
  85. valid = [
  86. "{{",
  87. (getter, node1.name),
  88. "}}",
  89. "{{",
  90. (getter, node2.name),
  91. " | ",
  92. marker,
  93. (getter, node2.params[0].name),
  94. " = ",
  95. marker,
  96. (getter, node2.params[0].value),
  97. " | ",
  98. marker,
  99. (getter, node2.params[1].name),
  100. " = ",
  101. marker,
  102. (getter, node2.params[1].value),
  103. "}}",
  104. ]
  105. assert valid == output
  106. def test_name():
  107. """test getter/setter for the name attribute"""
  108. name = wraptext("foobar")
  109. node1 = Template(name)
  110. node2 = Template(name, [pgenh("1", "bar")])
  111. assert name is node1.name
  112. assert name is node2.name
  113. node1.name = "asdf"
  114. node2.name = "téstïng"
  115. assert_wikicode_equal(wraptext("asdf"), node1.name)
  116. assert_wikicode_equal(wraptext("téstïng"), node2.name)
  117. def test_params():
  118. """test getter for the params attribute"""
  119. node1 = Template(wraptext("foobar"))
  120. plist = [pgenh("1", "bar"), pgens("abc", "def")]
  121. node2 = Template(wraptext("foo"), plist)
  122. assert [] == node1.params
  123. assert plist is node2.params
  124. def test_has():
  125. """test Template.has()"""
  126. node1 = Template(wraptext("foobar"))
  127. node2 = Template(wraptext("foo"), [pgenh("1", "bar"), pgens("\nabc ", "def")])
  128. node3 = Template(
  129. wraptext("foo"), [pgenh("1", "a"), pgens("b", "c"), pgens("1", "d")]
  130. )
  131. node4 = Template(wraptext("foo"), [pgenh("1", "a"), pgens("b", " ")])
  132. assert node1.has("foobar", False) is False
  133. assert node2.has(1, False) is True
  134. assert node2.has("abc", False) is True
  135. assert node2.has("def", False) is False
  136. assert node3.has("1", False) is True
  137. assert node3.has(" b ", False) is True
  138. assert node4.has("b", False) is True
  139. assert node3.has("b", True) is True
  140. assert node4.has("b", True) is False
  141. assert node1.has_param("foobar", False) is False
  142. assert node2.has_param(1, False) is True
  143. def test_get():
  144. """test Template.get()"""
  145. node1 = Template(wraptext("foobar"))
  146. node2p1 = pgenh("1", "bar")
  147. node2p2 = pgens("abc", "def")
  148. node2 = Template(wraptext("foo"), [node2p1, node2p2])
  149. node3p1 = pgens("b", "c")
  150. node3p2 = pgens("1", "d")
  151. node3 = Template(wraptext("foo"), [pgenh("1", "a"), node3p1, node3p2])
  152. node4p1 = pgens(" b", " ")
  153. node4 = Template(wraptext("foo"), [pgenh("1", "a"), node4p1])
  154. with pytest.raises(ValueError):
  155. node1.get("foobar")
  156. assert node2p1 is node2.get(1)
  157. assert node2p2 is node2.get("abc")
  158. with pytest.raises(ValueError):
  159. node2.get("def")
  160. assert node3p1 is node3.get("b")
  161. assert node3p2 is node3.get("1")
  162. assert node4p1 is node4.get("b ")
  163. def test_add():
  164. """test Template.add()"""
  165. node1 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  166. node2 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  167. node3 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  168. node4 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  169. node5 = Template(wraptext("a"), [pgens("b", "c"), pgens(" d ", "e")])
  170. node6 = Template(wraptext("a"), [pgens("b", "c"), pgens("b", "d"), pgens("b", "e")])
  171. node7 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  172. node8p = pgenh("1", "d")
  173. node8 = Template(wraptext("a"), [pgens("b", "c"), node8p])
  174. node9 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
  175. node10 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "e")])
  176. node11 = Template(wraptext("a"), [pgens("b", "c")])
  177. node12 = Template(wraptext("a"), [pgens("b", "c")])
  178. node13 = Template(
  179. wraptext("a"), [pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")]
  180. )
  181. node14 = Template(
  182. wraptext("a\n"),
  183. [
  184. pgens("b ", "c\n"),
  185. pgens("d ", " e"),
  186. pgens("f ", "g\n"),
  187. pgens("h ", " i\n"),
  188. ],
  189. )
  190. node15 = Template(
  191. wraptext("a"),
  192. [pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")],
  193. )
  194. node16 = Template(
  195. wraptext("a"), [pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")]
  196. )
  197. node17 = Template(wraptext("a"), [pgenh("1", "b")])
  198. node18 = Template(wraptext("a"), [pgenh("1", "b")])
  199. node19 = Template(wraptext("a"), [pgenh("1", "b")])
  200. node20 = Template(
  201. wraptext("a"),
  202. [pgenh("1", "b"), pgenh("2", "c"), pgenh("3", "d"), pgenh("4", "e")],
  203. )
  204. node21 = Template(
  205. wraptext("a"),
  206. [pgenh("1", "b"), pgenh("2", "c"), pgens("4", "d"), pgens("5", "e")],
  207. )
  208. node22 = Template(
  209. wraptext("a"),
  210. [pgenh("1", "b"), pgenh("2", "c"), pgens("4", "d"), pgens("5", "e")],
  211. )
  212. node23 = Template(wraptext("a"), [pgenh("1", "b")])
  213. node24 = Template(wraptext("a"), [pgenh("1", "b")])
  214. node25 = Template(wraptext("a"), [pgens("b", "c")])
  215. node26 = Template(wraptext("a"), [pgenh("1", "b")])
  216. node27 = Template(wraptext("a"), [pgenh("1", "b")])
  217. node28 = Template(wraptext("a"), [pgens("1", "b")])
  218. node29 = Template(
  219. wraptext("a"), [pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")]
  220. )
  221. node30 = Template(
  222. wraptext("a\n"),
  223. [
  224. pgens("b ", "c\n"),
  225. pgens("d ", " e"),
  226. pgens("f ", "g\n"),
  227. pgens("h ", " i\n"),
  228. ],
  229. )
  230. node31 = Template(
  231. wraptext("a"),
  232. [pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")],
  233. )
  234. node32 = Template(
  235. wraptext("a"),
  236. [pgens("\nb ", " c "), pgens("\nd ", " e "), pgens("\nf ", " g ")],
  237. )
  238. node33 = Template(
  239. wraptext("a"),
  240. [
  241. pgens("b", "c"),
  242. pgens("d", "e"),
  243. pgens("b", "f"),
  244. pgens("b", "h"),
  245. pgens("i", "j"),
  246. ],
  247. )
  248. node34 = Template(
  249. wraptext("a"),
  250. [pgens("1", "b"), pgens("x", "y"), pgens("1", "c"), pgens("2", "d")],
  251. )
  252. node35 = Template(
  253. wraptext("a"),
  254. [pgens("1", "b"), pgens("x", "y"), pgenh("1", "c"), pgenh("2", "d")],
  255. )
  256. node36 = Template(
  257. wraptext("a"), [pgens("b", "c"), pgens("d", "e"), pgens("f", "g")]
  258. )
  259. node37 = Template(wraptext("a"), [pgenh("1", "")])
  260. node38 = Template(wraptext("abc"))
  261. node39 = Template(wraptext("a"), [pgenh("1", " b ")])
  262. node40 = Template(wraptext("a"), [pgenh("1", " b"), pgenh("2", " c")])
  263. node41 = Template(wraptext("a"), [pgens("1", " b"), pgens("2", " c")])
  264. node42 = Template(wraptext("a"), [pgens("b", " \n")])
  265. node1.add("e", "f", showkey=True)
  266. node2.add(2, "g", showkey=False)
  267. node3.add("e", "foo|bar", showkey=True)
  268. node4.add("e", "f", showkey=True, before="b")
  269. node5.add("f", "g", showkey=True, before=" d ")
  270. node6.add("f", "g", showkey=True, before="b")
  271. with pytest.raises(ValueError):
  272. node7.add("e", "f", showkey=True, before="q")
  273. node8.add("e", "f", showkey=True, before=node8p)
  274. node9.add("e", "f", showkey=True, before=pgenh("1", "d"))
  275. with pytest.raises(ValueError):
  276. node10.add("e", "f", showkey=True, before=pgenh("1", "d"))
  277. node11.add("d", "foo=bar", showkey=True)
  278. node12.add("1", "foo=bar", showkey=False)
  279. node13.add("h", "i", showkey=True)
  280. node14.add("j", "k", showkey=True)
  281. node15.add("h", "i", showkey=True)
  282. node16.add("h", "i", showkey=True, preserve_spacing=False)
  283. node17.add("2", "c")
  284. node18.add("3", "c")
  285. node19.add("c", "d")
  286. node20.add("5", "f")
  287. node21.add("3", "f")
  288. node22.add("6", "f")
  289. node23.add("c", "foo=bar")
  290. node24.add("2", "foo=bar")
  291. node25.add("b", "d")
  292. node26.add("1", "foo=bar")
  293. node27.add("1", "foo=bar", showkey=True)
  294. node28.add("1", "foo=bar", showkey=False)
  295. node29.add("d", "foo")
  296. node30.add("f", "foo")
  297. node31.add("f", "foo")
  298. node32.add("d", "foo", preserve_spacing=False)
  299. node33.add("b", "k")
  300. node34.add("1", "e")
  301. node35.add("1", "e")
  302. node36.add("d", "h", before="b")
  303. node37.add(1, "b")
  304. node38.add("1", "foo")
  305. with pytest.raises(ValueError):
  306. node38.add("z", "bar", showkey=False)
  307. node39.add("1", "c")
  308. node40.add("3", "d")
  309. node41.add("3", "d")
  310. node42.add("b", "hello")
  311. assert "{{a|b=c|d|e=f}}" == node1
  312. assert "{{a|b=c|d|g}}" == node2
  313. assert "{{a|b=c|d|e=foo&#124;bar}}" == node3
  314. assert isinstance(node3.params[2].value.get(1), HTMLEntity)
  315. assert "{{a|e=f|b=c|d}}" == node4
  316. assert "{{a|b=c|f=g| d =e}}" == node5
  317. assert "{{a|b=c|b=d|f=g|b=e}}" == node6
  318. assert "{{a|b=c|d}}" == node7
  319. assert "{{a|b=c|e=f|d}}" == node8
  320. assert "{{a|b=c|e=f|d}}" == node9
  321. assert "{{a|b=c|e}}" == node10
  322. assert "{{a|b=c|d=foo=bar}}" == node11
  323. assert "{{a|b=c|foo&#61;bar}}" == node12
  324. assert isinstance(node12.params[1].value.get(1), HTMLEntity)
  325. assert "{{a|\nb = c|\nd = e|\nf = g|\nh = i}}" == node13
  326. assert "{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}" == node14
  327. assert "{{a|b = c\n|\nd = e|\nf =g |\nh = i}}" == node15
  328. assert "{{a|\nb = c|\nd = e|\nf = g|h=i}}" == node16
  329. assert "{{a|b|c}}" == node17
  330. assert "{{a|b|3=c}}" == node18
  331. assert "{{a|b|c=d}}" == node19
  332. assert "{{a|b|c|d|e|f}}" == node20
  333. assert "{{a|b|c|4=d|5=e|f}}" == node21
  334. assert "{{a|b|c|4=d|5=e|6=f}}" == node22
  335. assert "{{a|b|c=foo=bar}}" == node23
  336. assert "{{a|b|foo&#61;bar}}" == node24
  337. assert isinstance(node24.params[1].value.get(1), HTMLEntity)
  338. assert "{{a|b=d}}" == node25
  339. assert "{{a|foo&#61;bar}}" == node26
  340. assert isinstance(node26.params[0].value.get(1), HTMLEntity)
  341. assert "{{a|1=foo=bar}}" == node27
  342. assert "{{a|foo&#61;bar}}" == node28
  343. assert isinstance(node28.params[0].value.get(1), HTMLEntity)
  344. assert "{{a|\nb = c|\nd = foo|\nf = g}}" == node29
  345. assert "{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}" == node30
  346. assert "{{a|b = c\n|\nd = e|\nf =foo }}" == node31
  347. assert "{{a|\nb = c |\nd =foo|\nf = g }}" == node32
  348. assert "{{a|b=k|d=e|i=j}}" == node33
  349. assert "{{a|1=e|x=y|2=d}}" == node34
  350. assert "{{a|x=y|e|d}}" == node35
  351. assert "{{a|b=c|d=h|f=g}}" == node36
  352. assert "{{a|b}}" == node37
  353. assert "{{abc|foo}}" == node38
  354. assert "{{a|c}}" == node39
  355. assert "{{a| b| c|d}}" == node40
  356. assert "{{a|1= b|2= c|3= d}}" == node41
  357. assert "{{a|b=hello \n}}" == node42
  358. def test_remove():
  359. """test Template.remove()"""
  360. node1 = Template(wraptext("foobar"))
  361. node2 = Template(wraptext("foo"), [pgenh("1", "bar"), pgens("abc", "def")])
  362. node3 = Template(wraptext("foo"), [pgenh("1", "bar"), pgens("abc", "def")])
  363. node4 = Template(wraptext("foo"), [pgenh("1", "bar"), pgenh("2", "baz")])
  364. node5 = Template(
  365. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  366. )
  367. node6 = Template(
  368. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  369. )
  370. node7 = Template(
  371. wraptext("foo"), [pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")]
  372. )
  373. node8 = Template(
  374. wraptext("foo"), [pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")]
  375. )
  376. node9 = Template(
  377. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  378. )
  379. node10 = Template(
  380. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  381. )
  382. node11 = Template(
  383. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  384. )
  385. node12 = Template(
  386. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  387. )
  388. node13 = Template(
  389. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  390. )
  391. node14 = Template(
  392. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  393. )
  394. node15 = Template(
  395. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  396. )
  397. node16 = Template(
  398. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  399. )
  400. node17 = Template(
  401. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  402. )
  403. node18 = Template(
  404. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  405. )
  406. node19 = Template(
  407. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  408. )
  409. node20 = Template(
  410. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  411. )
  412. node21 = Template(
  413. wraptext("foo"),
  414. [
  415. pgens("a", "b"),
  416. pgens("c", "d"),
  417. pgens("e", "f"),
  418. pgens("a", "b"),
  419. pgens("a", "b"),
  420. ],
  421. )
  422. node22 = Template(
  423. wraptext("foo"),
  424. [
  425. pgens("a", "b"),
  426. pgens("c", "d"),
  427. pgens("e", "f"),
  428. pgens("a", "b"),
  429. pgens("a", "b"),
  430. ],
  431. )
  432. node23 = Template(
  433. wraptext("foo"),
  434. [
  435. pgens("a", "b"),
  436. pgens("c", "d"),
  437. pgens("e", "f"),
  438. pgens("a", "b"),
  439. pgens("a", "b"),
  440. ],
  441. )
  442. node24 = Template(
  443. wraptext("foo"),
  444. [
  445. pgens("a", "b"),
  446. pgens("c", "d"),
  447. pgens("e", "f"),
  448. pgens("a", "b"),
  449. pgens("a", "b"),
  450. ],
  451. )
  452. node25 = Template(
  453. wraptext("foo"),
  454. [
  455. pgens("a", "b"),
  456. pgens("c", "d"),
  457. pgens("e", "f"),
  458. pgens("a", "b"),
  459. pgens("a", "b"),
  460. ],
  461. )
  462. node26 = Template(
  463. wraptext("foo"),
  464. [
  465. pgens("a", "b"),
  466. pgens("c", "d"),
  467. pgens("e", "f"),
  468. pgens("a", "b"),
  469. pgens("a", "b"),
  470. ],
  471. )
  472. node27 = Template(wraptext("foo"), [pgenh("1", "bar")])
  473. node28 = Template(wraptext("foo"), [pgenh("1", "bar")])
  474. node2.remove("1")
  475. node2.remove("abc")
  476. node3.remove(1, keep_field=True)
  477. node3.remove("abc", keep_field=True)
  478. node4.remove("1", keep_field=False)
  479. node5.remove("a", keep_field=False)
  480. node6.remove("a", keep_field=True)
  481. node7.remove(1, keep_field=True)
  482. node8.remove(1, keep_field=False)
  483. node9.remove(1, keep_field=True)
  484. node10.remove(1, keep_field=False)
  485. node11.remove(node11.params[0], keep_field=False)
  486. node12.remove(node12.params[0], keep_field=True)
  487. node13.remove(node13.params[1], keep_field=False)
  488. node14.remove(node14.params[1], keep_field=True)
  489. node15.remove(node15.params[2], keep_field=False)
  490. node16.remove(node16.params[2], keep_field=True)
  491. node17.remove(node17.params[0], keep_field=False)
  492. node18.remove(node18.params[0], keep_field=True)
  493. node19.remove(node19.params[1], keep_field=False)
  494. node20.remove(node20.params[1], keep_field=True)
  495. node21.remove("a", keep_field=False)
  496. node22.remove("a", keep_field=True)
  497. node23.remove(node23.params[0], keep_field=False)
  498. node24.remove(node24.params[0], keep_field=True)
  499. node25.remove(node25.params[3], keep_field=False)
  500. node26.remove(node26.params[3], keep_field=True)
  501. with pytest.raises(ValueError):
  502. node1.remove(1)
  503. with pytest.raises(ValueError):
  504. node1.remove("a")
  505. with pytest.raises(ValueError):
  506. node2.remove("1")
  507. assert "{{foo}}" == node2
  508. assert "{{foo||abc=}}" == node3
  509. assert "{{foo|2=baz}}" == node4
  510. assert "{{foo|b=c}}" == node5
  511. assert "{{foo| a=|b=c}}" == node6
  512. assert "{{foo|1 =|2=c}}" == node7
  513. assert "{{foo|2=c}}" == node8
  514. assert "{{foo||c}}" == node9
  515. assert "{{foo|2=c}}" == node10
  516. assert "{{foo|b=c|a =d}}" == node11
  517. assert "{{foo| a=|b=c|a =d}}" == node12
  518. assert "{{foo| a=b|a =d}}" == node13
  519. assert "{{foo| a=b|b=|a =d}}" == node14
  520. assert "{{foo| a=b|b=c}}" == node15
  521. assert "{{foo| a=b|b=c|a =}}" == node16
  522. assert "{{foo|b|c}}" == node17
  523. assert "{{foo|1 =|b|c}}" == node18
  524. assert "{{foo|1 =a|2=c}}" == node19
  525. assert "{{foo|1 =a||c}}" == node20
  526. assert "{{foo|c=d|e=f}}" == node21
  527. assert "{{foo|a=|c=d|e=f}}" == node22
  528. assert "{{foo|c=d|e=f|a=b|a=b}}" == node23
  529. assert "{{foo|a=|c=d|e=f|a=b|a=b}}" == node24
  530. assert "{{foo|a=b|c=d|e=f|a=b}}" == node25
  531. assert "{{foo|a=b|c=d|e=f|a=|a=b}}" == node26
  532. with pytest.raises(ValueError):
  533. node27.remove(node28.get(1))
  534. def test_formatting():
  535. """test realistic param manipulation with complex whitespace formatting
  536. (assumes that parsing works correctly)"""
  537. tests = [
  538. # https://en.wikipedia.org/w/index.php?title=Lamar_County,_Georgia&oldid=792356004
  539. (
  540. """{{Infobox U.S. county
  541. | county = Lamar County
  542. | state = Georgia
  543. | seal =
  544. | founded = 1920
  545. | seat wl = Barnesville
  546. | largest city wl = Barnesville
  547. | area_total_sq_mi = 186
  548. | area_land_sq_mi = 184
  549. | area_water_sq_mi = 2.3
  550. | area percentage = 1.3%
  551. | census yr = 2010
  552. | pop = 18317
  553. | density_sq_mi = 100
  554. | time zone = Eastern
  555. | footnotes =
  556. | web = www.lamarcountyga.com
  557. | ex image = Lamar County Georgia Courthouse.jpg
  558. | ex image cap = Lamar County courthouse in Barnesville
  559. | district = 3rd
  560. | named for = [[Lucius Quintus Cincinnatus Lamar II]]
  561. }}""",
  562. """@@ -11,4 +11,4 @@
  563. | area percentage = 1.3%
  564. -| census yr = 2010
  565. -| pop = 18317
  566. +| census estimate yr = 2016
  567. +| pop = 12345<ref>example ref</ref>
  568. | density_sq_mi = 100""",
  569. ),
  570. # https://en.wikipedia.org/w/index.php?title=Rockdale_County,_Georgia&oldid=792359760
  571. (
  572. """{{Infobox U.S. County|
  573. county = Rockdale County |
  574. state = Georgia |
  575. seal = |
  576. founded = October 18, 1870 |
  577. seat wl = Conyers |
  578. largest city wl = Conyers |
  579. area_total_sq_mi = 132 |
  580. area_land_sq_mi = 130 |
  581. area_water_sq_mi = 2.3 |
  582. area percentage = 1.7% |
  583. census yr = 2010|
  584. pop = 85215 |
  585. density_sq_mi = 657 |
  586. web = www.rockdalecounty.org
  587. | ex image = Rockdale-county-courthouse.jpg
  588. | ex image cap = Rockdale County Courthouse in Conyers
  589. | district = 4th
  590. | time zone= Eastern
  591. }}""",
  592. """@@ -11,4 +11,4 @@
  593. area percentage = 1.7% |
  594. - census yr = 2010|
  595. - pop = 85215 |
  596. + census estimate yr = 2016 |
  597. + pop = 12345<ref>example ref</ref> |
  598. density_sq_mi = 657 |""",
  599. ),
  600. # https://en.wikipedia.org/w/index.php?title=Spalding_County,_Georgia&oldid=792360413
  601. (
  602. """{{Infobox U.S. County|
  603. | county = Spalding County |
  604. | state = Georgia |
  605. | seal = |
  606. | founded = 1851 |
  607. | seat wl = Griffin |
  608. | largest city wl = Griffin |
  609. | area_total_sq_mi = 200 |
  610. | area_land_sq_mi = 196 |
  611. | area_water_sq_mi = 3.1 |
  612. | area percentage = 1.6% |
  613. | census yr = 2010|
  614. | pop = 64073 |
  615. | density_sq_mi = 326 |
  616. | web = www.spaldingcounty.com |
  617. | named for = [[Thomas Spalding]]
  618. | ex image = Spalding County Courthouse (NE corner).JPG
  619. | ex image cap = Spalding County Courthouse in Griffin
  620. | district = 3rd
  621. | time zone = Eastern
  622. }}""",
  623. """@@ -11,4 +11,4 @@
  624. | area percentage = 1.6% |
  625. -| census yr = 2010|
  626. -| pop = 64073 |
  627. +|
  628. +| census estimate yr = 2016 | pop = 12345<ref>example ref</ref> |
  629. | density_sq_mi = 326 |""",
  630. ),
  631. # https://en.wikipedia.org/w/index.php?title=Clinton_County,_Illinois&oldid=794694648
  632. (
  633. """{{Infobox U.S. county
  634. |county = Clinton County
  635. |state = Illinois
  636. | ex image = File:Clinton County Courthouse, Carlyle.jpg
  637. | ex image cap = [[Clinton County Courthouse (Illinois)|Clinton County Courthouse]]
  638. |seal =
  639. |founded = 1824
  640. |named for = [[DeWitt Clinton]]
  641. |seat wl= Carlyle
  642. | largest city wl = Breese
  643. |time zone=Central
  644. |area_total_sq_mi = 503
  645. |area_land_sq_mi = 474
  646. |area_water_sq_mi = 29
  647. |area percentage = 5.8%
  648. |census yr = 2010
  649. |pop = 37762
  650. |density_sq_mi = 80
  651. |web = www.clintonco.illinois.gov
  652. | district = 15th
  653. }}""",
  654. """@@ -15,4 +15,4 @@
  655. |area percentage = 5.8%
  656. - |census yr = 2010
  657. - |pop = 37762
  658. + |census estimate yr = 2016
  659. + |pop = 12345<ref>example ref</ref>
  660. |density_sq_mi = 80""",
  661. ),
  662. # https://en.wikipedia.org/w/index.php?title=Winnebago_County,_Illinois&oldid=789193800
  663. (
  664. """{{Infobox U.S. county |
  665. county = Winnebago County |
  666. state = Illinois |
  667. seal = Winnebago County il seal.png |
  668. named for = [[Winnebago (tribe)|Winnebago Tribe]] |
  669. seat wl= Rockford |
  670. largest city wl = Rockford|
  671. area_total_sq_mi = 519 |
  672. area_land_sq_mi = 513|
  673. area_water_sq_mi = 5.9 |
  674. area percentage = 1.1% |
  675. census yr = 2010|
  676. pop = 295266 |
  677. density_sq_mi = 575
  678. | web = www.wincoil.us
  679. | founded year = 1836
  680. | founded date = January 16
  681. | time zone = Central
  682. | district = 16th
  683. | district2 = 17th
  684. }}""",
  685. """@@ -11,4 +11,4 @@
  686. area percentage = 1.1% |
  687. - census yr = 2010|
  688. - pop = 295266 |
  689. + census estimate yr = 2016|
  690. + pop = 12345<ref>example ref</ref> |
  691. density_sq_mi = 575""",
  692. ),
  693. ]
  694. for (original, expected) in tests:
  695. code = parse(original)
  696. template = code.filter_templates()[0]
  697. template.add("pop", "12345<ref>example ref</ref>")
  698. template.add("census estimate yr", "2016", before="pop")
  699. template.remove("census yr")
  700. oldlines = original.splitlines(True)
  701. newlines = str(code).splitlines(True)
  702. difflines = unified_diff(oldlines, newlines, n=1)
  703. diff = "".join(list(difflines)[2:]).strip()
  704. assert expected == diff