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.
 
 
 
 

750 lines
25 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. node43 = Template(
  312. wraptext("a"), [pgens("b", "c"), pgens("d", "e"), pgens("f", "g")]
  313. )
  314. node44 = Template(
  315. wraptext("a"), [pgens("b", "c"), pgens("d", "e"), pgens("f", "g")]
  316. )
  317. node43.add("new_param", "value", after="d")
  318. node44.add("new_param", "value", after="f")
  319. assert "{{a|b=c|d|e=f}}" == node1
  320. assert "{{a|b=c|d|g}}" == node2
  321. assert "{{a|b=c|d|e=foo&#124;bar}}" == node3
  322. assert isinstance(node3.params[2].value.get(1), HTMLEntity)
  323. assert "{{a|e=f|b=c|d}}" == node4
  324. assert "{{a|b=c|f=g| d =e}}" == node5
  325. assert "{{a|b=c|b=d|f=g|b=e}}" == node6
  326. assert "{{a|b=c|d}}" == node7
  327. assert "{{a|b=c|e=f|d}}" == node8
  328. assert "{{a|b=c|e=f|d}}" == node9
  329. assert "{{a|b=c|e}}" == node10
  330. assert "{{a|b=c|d=foo=bar}}" == node11
  331. assert "{{a|b=c|foo&#61;bar}}" == node12
  332. assert isinstance(node12.params[1].value.get(1), HTMLEntity)
  333. assert "{{a|\nb = c|\nd = e|\nf = g|\nh = i}}" == node13
  334. assert "{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}" == node14
  335. assert "{{a|b = c\n|\nd = e|\nf =g |\nh = i}}" == node15
  336. assert "{{a|\nb = c|\nd = e|\nf = g|h=i}}" == node16
  337. assert "{{a|b|c}}" == node17
  338. assert "{{a|b|3=c}}" == node18
  339. assert "{{a|b|c=d}}" == node19
  340. assert "{{a|b|c|d|e|f}}" == node20
  341. assert "{{a|b|c|4=d|5=e|f}}" == node21
  342. assert "{{a|b|c|4=d|5=e|6=f}}" == node22
  343. assert "{{a|b|c=foo=bar}}" == node23
  344. assert "{{a|b|foo&#61;bar}}" == node24
  345. assert isinstance(node24.params[1].value.get(1), HTMLEntity)
  346. assert "{{a|b=d}}" == node25
  347. assert "{{a|foo&#61;bar}}" == node26
  348. assert isinstance(node26.params[0].value.get(1), HTMLEntity)
  349. assert "{{a|1=foo=bar}}" == node27
  350. assert "{{a|foo&#61;bar}}" == node28
  351. assert isinstance(node28.params[0].value.get(1), HTMLEntity)
  352. assert "{{a|\nb = c|\nd = foo|\nf = g}}" == node29
  353. assert "{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}" == node30
  354. assert "{{a|b = c\n|\nd = e|\nf =foo }}" == node31
  355. assert "{{a|\nb = c |\nd =foo|\nf = g }}" == node32
  356. assert "{{a|b=k|d=e|i=j}}" == node33
  357. assert "{{a|1=e|x=y|2=d}}" == node34
  358. assert "{{a|x=y|e|d}}" == node35
  359. assert "{{a|b=c|d=h|f=g}}" == node36
  360. assert "{{a|b}}" == node37
  361. assert "{{abc|foo}}" == node38
  362. assert "{{a|c}}" == node39
  363. assert "{{a| b| c|d}}" == node40
  364. assert "{{a|1= b|2= c|3= d}}" == node41
  365. assert "{{a|b=hello \n}}" == node42
  366. assert "{{a|b=c|d=e|new_param=value|f=g}}" == node43
  367. assert "{{a|b=c|d=e|f=g|new_param=value}}" == node44
  368. def test_remove():
  369. """test Template.remove()"""
  370. node1 = Template(wraptext("foobar"))
  371. node2 = Template(wraptext("foo"), [pgenh("1", "bar"), pgens("abc", "def")])
  372. node3 = Template(wraptext("foo"), [pgenh("1", "bar"), pgens("abc", "def")])
  373. node4 = Template(wraptext("foo"), [pgenh("1", "bar"), pgenh("2", "baz")])
  374. node5 = Template(
  375. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  376. )
  377. node6 = Template(
  378. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  379. )
  380. node7 = Template(
  381. wraptext("foo"), [pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")]
  382. )
  383. node8 = Template(
  384. wraptext("foo"), [pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")]
  385. )
  386. node9 = Template(
  387. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  388. )
  389. node10 = Template(
  390. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  391. )
  392. node11 = Template(
  393. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  394. )
  395. node12 = Template(
  396. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  397. )
  398. node13 = Template(
  399. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  400. )
  401. node14 = Template(
  402. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  403. )
  404. node15 = Template(
  405. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  406. )
  407. node16 = Template(
  408. wraptext("foo"), [pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")]
  409. )
  410. node17 = Template(
  411. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  412. )
  413. node18 = Template(
  414. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  415. )
  416. node19 = Template(
  417. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  418. )
  419. node20 = Template(
  420. wraptext("foo"), [pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")]
  421. )
  422. node21 = 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. node22 = 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. node23 = 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. node24 = 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. node25 = 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. node26 = Template(
  473. wraptext("foo"),
  474. [
  475. pgens("a", "b"),
  476. pgens("c", "d"),
  477. pgens("e", "f"),
  478. pgens("a", "b"),
  479. pgens("a", "b"),
  480. ],
  481. )
  482. node27 = Template(wraptext("foo"), [pgenh("1", "bar")])
  483. node28 = Template(wraptext("foo"), [pgenh("1", "bar")])
  484. node2.remove("1")
  485. node2.remove("abc")
  486. node3.remove(1, keep_field=True)
  487. node3.remove("abc", keep_field=True)
  488. node4.remove("1", keep_field=False)
  489. node5.remove("a", keep_field=False)
  490. node6.remove("a", keep_field=True)
  491. node7.remove(1, keep_field=True)
  492. node8.remove(1, keep_field=False)
  493. node9.remove(1, keep_field=True)
  494. node10.remove(1, keep_field=False)
  495. node11.remove(node11.params[0], keep_field=False)
  496. node12.remove(node12.params[0], keep_field=True)
  497. node13.remove(node13.params[1], keep_field=False)
  498. node14.remove(node14.params[1], keep_field=True)
  499. node15.remove(node15.params[2], keep_field=False)
  500. node16.remove(node16.params[2], keep_field=True)
  501. node17.remove(node17.params[0], keep_field=False)
  502. node18.remove(node18.params[0], keep_field=True)
  503. node19.remove(node19.params[1], keep_field=False)
  504. node20.remove(node20.params[1], keep_field=True)
  505. node21.remove("a", keep_field=False)
  506. node22.remove("a", keep_field=True)
  507. node23.remove(node23.params[0], keep_field=False)
  508. node24.remove(node24.params[0], keep_field=True)
  509. node25.remove(node25.params[3], keep_field=False)
  510. node26.remove(node26.params[3], keep_field=True)
  511. with pytest.raises(ValueError):
  512. node1.remove(1)
  513. with pytest.raises(ValueError):
  514. node1.remove("a")
  515. with pytest.raises(ValueError):
  516. node2.remove("1")
  517. assert "{{foo}}" == node2
  518. assert "{{foo||abc=}}" == node3
  519. assert "{{foo|2=baz}}" == node4
  520. assert "{{foo|b=c}}" == node5
  521. assert "{{foo| a=|b=c}}" == node6
  522. assert "{{foo|1 =|2=c}}" == node7
  523. assert "{{foo|2=c}}" == node8
  524. assert "{{foo||c}}" == node9
  525. assert "{{foo|2=c}}" == node10
  526. assert "{{foo|b=c|a =d}}" == node11
  527. assert "{{foo| a=|b=c|a =d}}" == node12
  528. assert "{{foo| a=b|a =d}}" == node13
  529. assert "{{foo| a=b|b=|a =d}}" == node14
  530. assert "{{foo| a=b|b=c}}" == node15
  531. assert "{{foo| a=b|b=c|a =}}" == node16
  532. assert "{{foo|b|c}}" == node17
  533. assert "{{foo|1 =|b|c}}" == node18
  534. assert "{{foo|1 =a|2=c}}" == node19
  535. assert "{{foo|1 =a||c}}" == node20
  536. assert "{{foo|c=d|e=f}}" == node21
  537. assert "{{foo|a=|c=d|e=f}}" == node22
  538. assert "{{foo|c=d|e=f|a=b|a=b}}" == node23
  539. assert "{{foo|a=|c=d|e=f|a=b|a=b}}" == node24
  540. assert "{{foo|a=b|c=d|e=f|a=b}}" == node25
  541. assert "{{foo|a=b|c=d|e=f|a=|a=b}}" == node26
  542. with pytest.raises(ValueError):
  543. node27.remove(node28.get(1))
  544. def test_formatting():
  545. """test realistic param manipulation with complex whitespace formatting
  546. (assumes that parsing works correctly)"""
  547. tests = [
  548. # https://en.wikipedia.org/w/index.php?title=Lamar_County,_Georgia&oldid=792356004
  549. (
  550. """{{Infobox U.S. county
  551. | county = Lamar County
  552. | state = Georgia
  553. | seal =
  554. | founded = 1920
  555. | seat wl = Barnesville
  556. | largest city wl = Barnesville
  557. | area_total_sq_mi = 186
  558. | area_land_sq_mi = 184
  559. | area_water_sq_mi = 2.3
  560. | area percentage = 1.3%
  561. | census yr = 2010
  562. | pop = 18317
  563. | density_sq_mi = 100
  564. | time zone = Eastern
  565. | footnotes =
  566. | web = www.lamarcountyga.com
  567. | ex image = Lamar County Georgia Courthouse.jpg
  568. | ex image cap = Lamar County courthouse in Barnesville
  569. | district = 3rd
  570. | named for = [[Lucius Quintus Cincinnatus Lamar II]]
  571. }}""",
  572. """@@ -11,4 +11,4 @@
  573. | area percentage = 1.3%
  574. -| census yr = 2010
  575. -| pop = 18317
  576. +| census estimate yr = 2016
  577. +| pop = 12345<ref>example ref</ref>
  578. | density_sq_mi = 100""",
  579. ),
  580. # https://en.wikipedia.org/w/index.php?title=Rockdale_County,_Georgia&oldid=792359760
  581. (
  582. """{{Infobox U.S. County|
  583. county = Rockdale County |
  584. state = Georgia |
  585. seal = |
  586. founded = October 18, 1870 |
  587. seat wl = Conyers |
  588. largest city wl = Conyers |
  589. area_total_sq_mi = 132 |
  590. area_land_sq_mi = 130 |
  591. area_water_sq_mi = 2.3 |
  592. area percentage = 1.7% |
  593. census yr = 2010|
  594. pop = 85215 |
  595. density_sq_mi = 657 |
  596. web = www.rockdalecounty.org
  597. | ex image = Rockdale-county-courthouse.jpg
  598. | ex image cap = Rockdale County Courthouse in Conyers
  599. | district = 4th
  600. | time zone= Eastern
  601. }}""",
  602. """@@ -11,4 +11,4 @@
  603. area percentage = 1.7% |
  604. - census yr = 2010|
  605. - pop = 85215 |
  606. + census estimate yr = 2016 |
  607. + pop = 12345<ref>example ref</ref> |
  608. density_sq_mi = 657 |""",
  609. ),
  610. # https://en.wikipedia.org/w/index.php?title=Spalding_County,_Georgia&oldid=792360413
  611. (
  612. """{{Infobox U.S. County|
  613. | county = Spalding County |
  614. | state = Georgia |
  615. | seal = |
  616. | founded = 1851 |
  617. | seat wl = Griffin |
  618. | largest city wl = Griffin |
  619. | area_total_sq_mi = 200 |
  620. | area_land_sq_mi = 196 |
  621. | area_water_sq_mi = 3.1 |
  622. | area percentage = 1.6% |
  623. | census yr = 2010|
  624. | pop = 64073 |
  625. | density_sq_mi = 326 |
  626. | web = www.spaldingcounty.com |
  627. | named for = [[Thomas Spalding]]
  628. | ex image = Spalding County Courthouse (NE corner).JPG
  629. | ex image cap = Spalding County Courthouse in Griffin
  630. | district = 3rd
  631. | time zone = Eastern
  632. }}""",
  633. """@@ -11,4 +11,4 @@
  634. | area percentage = 1.6% |
  635. -| census yr = 2010|
  636. -| pop = 64073 |
  637. +|
  638. +| census estimate yr = 2016 | pop = 12345<ref>example ref</ref> |
  639. | density_sq_mi = 326 |""",
  640. ),
  641. # https://en.wikipedia.org/w/index.php?title=Clinton_County,_Illinois&oldid=794694648
  642. (
  643. """{{Infobox U.S. county
  644. |county = Clinton County
  645. |state = Illinois
  646. | ex image = File:Clinton County Courthouse, Carlyle.jpg
  647. | ex image cap = [[Clinton County Courthouse (Illinois)|Clinton County Courthouse]]
  648. |seal =
  649. |founded = 1824
  650. |named for = [[DeWitt Clinton]]
  651. |seat wl= Carlyle
  652. | largest city wl = Breese
  653. |time zone=Central
  654. |area_total_sq_mi = 503
  655. |area_land_sq_mi = 474
  656. |area_water_sq_mi = 29
  657. |area percentage = 5.8%
  658. |census yr = 2010
  659. |pop = 37762
  660. |density_sq_mi = 80
  661. |web = www.clintonco.illinois.gov
  662. | district = 15th
  663. }}""",
  664. """@@ -15,4 +15,4 @@
  665. |area percentage = 5.8%
  666. - |census yr = 2010
  667. - |pop = 37762
  668. + |census estimate yr = 2016
  669. + |pop = 12345<ref>example ref</ref>
  670. |density_sq_mi = 80""",
  671. ),
  672. # https://en.wikipedia.org/w/index.php?title=Winnebago_County,_Illinois&oldid=789193800
  673. (
  674. """{{Infobox U.S. county |
  675. county = Winnebago County |
  676. state = Illinois |
  677. seal = Winnebago County il seal.png |
  678. named for = [[Winnebago (tribe)|Winnebago Tribe]] |
  679. seat wl= Rockford |
  680. largest city wl = Rockford|
  681. area_total_sq_mi = 519 |
  682. area_land_sq_mi = 513|
  683. area_water_sq_mi = 5.9 |
  684. area percentage = 1.1% |
  685. census yr = 2010|
  686. pop = 295266 |
  687. density_sq_mi = 575
  688. | web = www.wincoil.us
  689. | founded year = 1836
  690. | founded date = January 16
  691. | time zone = Central
  692. | district = 16th
  693. | district2 = 17th
  694. }}""",
  695. """@@ -11,4 +11,4 @@
  696. area percentage = 1.1% |
  697. - census yr = 2010|
  698. - pop = 295266 |
  699. + census estimate yr = 2016|
  700. + pop = 12345<ref>example ref</ref> |
  701. density_sq_mi = 575""",
  702. ),
  703. ]
  704. for original, expected in tests:
  705. code = parse(original)
  706. template = code.filter_templates()[0]
  707. template.add("pop", "12345<ref>example ref</ref>")
  708. template.add("census estimate yr", "2016", before="pop")
  709. template.remove("census yr")
  710. oldlines = original.splitlines(True)
  711. newlines = str(code).splitlines(True)
  712. difflines = unified_diff(oldlines, newlines, n=1)
  713. diff = "".join(list(difflines)[2:]).strip()
  714. assert expected == diff