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.
 
 
 
 

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