djlint 1.28.0 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/.coveragerc +9 -0
  2. package/.editorconfig +21 -0
  3. package/.flake8 +0 -0
  4. package/.github/FUNDING.yml +2 -0
  5. package/.github/ISSUE_TEMPLATE/config.yml +6 -0
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  7. package/.github/ISSUE_TEMPLATE/formatter_but_report.md +30 -0
  8. package/.github/ISSUE_TEMPLATE/linter_bug_report.md +34 -0
  9. package/.github/ISSUE_TEMPLATE/translation.md +14 -0
  10. package/.github/config.yml +4 -0
  11. package/.github/pull_request_template.md +10 -0
  12. package/.github/workflows/cancel.yml +17 -0
  13. package/.github/workflows/demo.yml +98 -0
  14. package/.github/workflows/issues.yml +23 -0
  15. package/.github/workflows/linkcheck.yaml +21 -0
  16. package/.github/workflows/lint.yml +25 -0
  17. package/.github/workflows/release.yml +57 -0
  18. package/.github/workflows/test.yml +85 -0
  19. package/.pre-commit-config.yaml +45 -0
  20. package/.pre-commit-hooks.yaml +71 -0
  21. package/.prettierignore +7 -0
  22. package/.prettierrc +11 -0
  23. package/.releaserc +16 -0
  24. package/CHANGELOG.md +13 -0
  25. package/MANIFEST.in +2 -0
  26. package/build_demo.sh +17 -0
  27. package/docs/.eleventy.js +425 -0
  28. package/docs/.eleventyignore +2 -0
  29. package/docs/.prettierignore +3 -0
  30. package/docs/.prettierrc +11 -0
  31. package/docs/package.json +73 -0
  32. package/docs/readme.md +17 -0
  33. package/docs/src/_data/configuration.json +646 -0
  34. package/docs/src/_data/eleventyComputed.js +22 -0
  35. package/docs/src/_data/i18n/index.js +159 -0
  36. package/docs/src/_data/js.js +7 -0
  37. package/docs/src/_data/locales.js +17 -0
  38. package/docs/src/_data/site.json +8 -0
  39. package/docs/src/_includes/demo.njk +157 -0
  40. package/docs/src/_includes/docs_layout.njk +34 -0
  41. package/docs/src/_includes/foot.njk +26 -0
  42. package/docs/src/_includes/index.njk +187 -0
  43. package/docs/src/_includes/languages_layout.njk +11 -0
  44. package/docs/src/_includes/layout.njk +111 -0
  45. package/docs/src/_includes/nav.njk +85 -0
  46. package/docs/src/_utils/minify-html.js +14 -0
  47. package/docs/src/_utils/rollupper.js +91 -0
  48. package/docs/src/_utils/scripts.11ty.js +27 -0
  49. package/docs/src/demo.njk +4 -0
  50. package/docs/src/docs/best-practices.md +78 -0
  51. package/docs/src/docs/changelog.md +452 -0
  52. package/docs/src/docs/configuration.md +145 -0
  53. package/docs/src/docs/docs.json +4 -0
  54. package/docs/src/docs/formatter.md +82 -0
  55. package/docs/src/docs/getting-started.md +126 -0
  56. package/docs/src/docs/ignoring-code.md +75 -0
  57. package/docs/src/docs/integrations.md +120 -0
  58. package/docs/src/docs/languages/angular.md +31 -0
  59. package/docs/src/docs/languages/django.md +40 -0
  60. package/docs/src/docs/languages/golang.md +31 -0
  61. package/docs/src/docs/languages/handlebars.md +31 -0
  62. package/docs/src/docs/languages/jinja.md +39 -0
  63. package/docs/src/docs/languages/languages.json +3 -0
  64. package/docs/src/docs/languages/mustache.md +31 -0
  65. package/docs/src/docs/languages/nunjucks.md +39 -0
  66. package/docs/src/docs/languages/twig.md +41 -0
  67. package/docs/src/docs/linter.md +199 -0
  68. package/docs/src/fr/demo.njk +4 -0
  69. package/docs/src/fr/docs/best-practices.md +78 -0
  70. package/docs/src/fr/docs/changelog.md +452 -0
  71. package/docs/src/fr/docs/configuration.md +144 -0
  72. package/docs/src/fr/docs/docs.json +3 -0
  73. package/docs/src/fr/docs/formatter.md +83 -0
  74. package/docs/src/fr/docs/getting-started.md +127 -0
  75. package/docs/src/fr/docs/ignoring-code.md +75 -0
  76. package/docs/src/fr/docs/integrations.md +100 -0
  77. package/docs/src/fr/docs/languages/angular.md +31 -0
  78. package/docs/src/fr/docs/languages/django.md +31 -0
  79. package/docs/src/fr/docs/languages/golang.md +31 -0
  80. package/docs/src/fr/docs/languages/handlebars.md +31 -0
  81. package/docs/src/fr/docs/languages/jinja.md +31 -0
  82. package/docs/src/fr/docs/languages/languages.json +3 -0
  83. package/docs/src/fr/docs/languages/mustache.md +31 -0
  84. package/docs/src/fr/docs/languages/nunjucks.md +31 -0
  85. package/docs/src/fr/docs/languages/twig.md +31 -0
  86. package/docs/src/fr/docs/linter.md +207 -0
  87. package/docs/src/fr/fr.json +4 -0
  88. package/docs/src/fr/index.njk +4 -0
  89. package/docs/src/index.njk +4 -0
  90. package/docs/src/lib/generate-content-hash.js +13 -0
  91. package/docs/src/robots.txt +4 -0
  92. package/docs/src/ru/demo.njk +4 -0
  93. package/docs/src/ru/docs/best-practices.md +78 -0
  94. package/docs/src/ru/docs/changelog.md +453 -0
  95. package/docs/src/ru/docs/configuration.md +142 -0
  96. package/docs/src/ru/docs/docs.json +3 -0
  97. package/docs/src/ru/docs/formatter.md +82 -0
  98. package/docs/src/ru/docs/getting-started.md +127 -0
  99. package/docs/src/ru/docs/ignoring-code.md +75 -0
  100. package/docs/src/ru/docs/integrations.md +100 -0
  101. package/docs/src/ru/docs/languages/angular.md +31 -0
  102. package/docs/src/ru/docs/languages/django.md +31 -0
  103. package/docs/src/ru/docs/languages/golang.md +31 -0
  104. package/docs/src/ru/docs/languages/handlebars.md +31 -0
  105. package/docs/src/ru/docs/languages/jinja.md +31 -0
  106. package/docs/src/ru/docs/languages/languages.json +3 -0
  107. package/docs/src/ru/docs/languages/mustache.md +31 -0
  108. package/docs/src/ru/docs/languages/nunjucks.md +31 -0
  109. package/docs/src/ru/docs/languages/twig.md +31 -0
  110. package/docs/src/ru/docs/linter.md +126 -0
  111. package/docs/src/ru/index.njk +4 -0
  112. package/docs/src/ru/ru.json +4 -0
  113. package/docs/src/sitemap.njk +16 -0
  114. package/docs/src/static/css/site.scss +467 -0
  115. package/docs/src/static/font/fontawesome/stylesheet.scss +78 -0
  116. package/docs/src/static/img/apple-touch-icon.png +0 -0
  117. package/docs/src/static/img/demo-min.gif +0 -0
  118. package/docs/src/static/img/demo.gif +0 -0
  119. package/docs/src/static/img/demo.webm +0 -0
  120. package/docs/src/static/img/favicon-16x16.png +0 -0
  121. package/docs/src/static/img/favicon-32x32.png +0 -0
  122. package/docs/src/static/img/favicon.ico +0 -0
  123. package/docs/src/static/img/icon-square.indd +0 -0
  124. package/docs/src/static/img/icon-square.png +0 -0
  125. package/docs/src/static/img/icon.png +0 -0
  126. package/docs/src/static/img/logo-192x192.png +0 -0
  127. package/docs/src/static/img/logo-512x512.png +0 -0
  128. package/docs/src/static/img/logos/angular.png +0 -0
  129. package/docs/src/static/img/logos/django.png +0 -0
  130. package/docs/src/static/img/logos/golang.png +0 -0
  131. package/docs/src/static/img/logos/handlebars.png +0 -0
  132. package/docs/src/static/img/logos/jinja.png +0 -0
  133. package/docs/src/static/img/logos/mustache.png +0 -0
  134. package/docs/src/static/img/logos/nunjucks.png +0 -0
  135. package/docs/src/static/img/logos/twig.png +0 -0
  136. package/docs/src/static/img/old_demo.gif +0 -0
  137. package/docs/src/static/img/style.css +122 -0
  138. package/docs/src/static/js/animate.js +69 -0
  139. package/docs/src/static/js/editor.js +171 -0
  140. package/docs/src/static/js/hamburger.js +19 -0
  141. package/docs/src/static/js/modal.js +47 -0
  142. package/docs/src/static/js/worker.js +142 -0
  143. package/docs/src/static/py/EditorConfig-99-py3-none-any.whl +0 -0
  144. package/docs/src/static/py/PyYAML-99-py3-none-any.whl +0 -0
  145. package/docs/src/static/py/click-99-py3-none-any.whl +0 -0
  146. package/docs/src/static/py/colorama-99-py3-none-any.whl +0 -0
  147. package/docs/src/static/py/cssbeautifier-99-py3-none-any.whl +0 -0
  148. package/docs/src/static/py/djlint-99-py3-none-any.whl +0 -0
  149. package/docs/src/static/py/html_tag_names-99-py3-none-any.whl +0 -0
  150. package/docs/src/static/py/html_void_elements-99-py3-none-any.whl +0 -0
  151. package/docs/src/static/py/jsbeautifier-99-py3-none-any.whl +0 -0
  152. package/docs/src/static/py/json5-99-py3-none-any.whl +0 -0
  153. package/docs/src/static/py/pathspec-99-py3-none-any.whl +0 -0
  154. package/docs/src/static/py/regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
  155. package/docs/src/static/py/six-1.16.0-py2.py3-none-any.whl +0 -0
  156. package/docs/src/static/py/tomli-2.0.1-py3-none-any.whl +0 -0
  157. package/docs/src/static/py/tqdm-4.65.0-py3-none-any.whl +0 -0
  158. package/icon.xcf +0 -0
  159. package/package.json +4 -33
  160. package/poetry.lock +835 -0
  161. package/pyproject.toml +100 -0
  162. package/renovate.json +44 -0
  163. package/scripts/updateVersion.js +16 -0
  164. package/src/djlint/__init__.py +451 -0
  165. package/src/djlint/__main__.py +4 -0
  166. package/src/djlint/formatter/__init__.py +1 -0
  167. package/src/djlint/formatter/attributes.py +212 -0
  168. package/src/djlint/formatter/compress.py +64 -0
  169. package/src/djlint/formatter/condense.py +221 -0
  170. package/src/djlint/formatter/css.py +60 -0
  171. package/src/djlint/formatter/expand.py +111 -0
  172. package/src/djlint/formatter/indent.py +418 -0
  173. package/src/djlint/formatter/js.py +58 -0
  174. package/src/djlint/helpers.py +321 -0
  175. package/src/djlint/lint.py +128 -0
  176. package/src/djlint/output.py +220 -0
  177. package/src/djlint/reformat.py +63 -0
  178. package/src/djlint/rules/H025.py +65 -0
  179. package/src/djlint/rules.yaml +279 -0
  180. package/src/djlint/settings.py +969 -0
  181. package/src/djlint/src.py +91 -0
  182. package/tests/__init__.py +0 -0
  183. package/tests/conftest.py +239 -0
  184. package/tests/test_cli.py +71 -0
  185. package/tests/test_config/__init__.py +0 -0
  186. package/tests/test_config/test_blank_line_after_tag.py +135 -0
  187. package/tests/test_config/test_blank_line_before_tag.py +141 -0
  188. package/tests/test_config/test_close_void_tags.py +31 -0
  189. package/tests/test_config/test_custom_blocks.py +56 -0
  190. package/tests/test_config/test_custom_html.py +45 -0
  191. package/tests/test_config/test_djlintrc/.djlintrc +38 -0
  192. package/tests/test_config/test_djlintrc/__init__.py +0 -0
  193. package/tests/test_config/test_djlintrc/test_config.py +44 -0
  194. package/tests/test_config/test_djlintrc_custom/.djlint-cust +38 -0
  195. package/tests/test_config/test_djlintrc_custom/.djlintrc +2 -0
  196. package/tests/test_config/test_djlintrc_custom/__init__.py +0 -0
  197. package/tests/test_config/test_djlintrc_custom/test_config.py +48 -0
  198. package/tests/test_config/test_excludes/__init__.py +0 -0
  199. package/tests/test_config/test_excludes/excluded.html +1 -0
  200. package/tests/test_config/test_excludes/foo/excluded.html +1 -0
  201. package/tests/test_config/test_excludes/html.html +1 -0
  202. package/tests/test_config/test_excludes/pyproject.toml +3 -0
  203. package/tests/test_config/test_excludes/test_config.py +30 -0
  204. package/tests/test_config/test_extension/__init__.py +0 -0
  205. package/tests/test_config/test_extension/html.test +1 -0
  206. package/tests/test_config/test_extension/pyproject.toml +3 -0
  207. package/tests/test_config/test_extension/test_config.py +27 -0
  208. package/tests/test_config/test_files/.djlintrc_global +9 -0
  209. package/tests/test_config/test_files/test.html +3 -0
  210. package/tests/test_config/test_files/test_config.py +123 -0
  211. package/tests/test_config/test_files/test_two.html +1 -0
  212. package/tests/test_config/test_format_attribute_template_tags.py +280 -0
  213. package/tests/test_config/test_format_css.py +197 -0
  214. package/tests/test_config/test_format_js.py +220 -0
  215. package/tests/test_config/test_gitignore/__init__.py +0 -0
  216. package/tests/test_config/test_gitignore/html_one.html +1 -0
  217. package/tests/test_config/test_gitignore/html_two.html +1 -0
  218. package/tests/test_config/test_gitignore/test_config.py +142 -0
  219. package/tests/test_config/test_ignore/__init__.py +0 -0
  220. package/tests/test_config/test_ignore/html.html +1 -0
  221. package/tests/test_config/test_ignore/html_two.html +12 -0
  222. package/tests/test_config/test_ignore/pyproject.toml +3 -0
  223. package/tests/test_config/test_ignore/test_config.py +32 -0
  224. package/tests/test_config/test_ignore_blocks.py +45 -0
  225. package/tests/test_config/test_ignore_case.py +39 -0
  226. package/tests/test_config/test_indent.py +63 -0
  227. package/tests/test_config/test_linter_output_format/__init__.py +0 -0
  228. package/tests/test_config/test_linter_output_format/html-one.html +1 -0
  229. package/tests/test_config/test_linter_output_format/html-two.html +1 -0
  230. package/tests/test_config/test_linter_output_format/pyproject.toml +3 -0
  231. package/tests/test_config/test_linter_output_format/test_config.py +34 -0
  232. package/tests/test_config/test_max_attribute_length.py +100 -0
  233. package/tests/test_config/test_max_line_length.py +94 -0
  234. package/tests/test_config/test_per_file_ignores/__init__.py +0 -0
  235. package/tests/test_config/test_per_file_ignores/html.html +2 -0
  236. package/tests/test_config/test_per_file_ignores/pyproject.toml +2 -0
  237. package/tests/test_config/test_per_file_ignores/test_config.py +25 -0
  238. package/tests/test_config/test_pragmas/__init__.py +0 -0
  239. package/tests/test_config/test_pragmas/html_five.html +2 -0
  240. package/tests/test_config/test_pragmas/html_four.html +5 -0
  241. package/tests/test_config/test_pragmas/html_one.html +1 -0
  242. package/tests/test_config/test_pragmas/html_six.html +2 -0
  243. package/tests/test_config/test_pragmas/html_three.html +4 -0
  244. package/tests/test_config/test_pragmas/html_two.html +2 -0
  245. package/tests/test_config/test_pragmas/pyproject.toml +3 -0
  246. package/tests/test_config/test_pragmas/test_config.py +142 -0
  247. package/tests/test_config/test_preserve_blank_lines.py +109 -0
  248. package/tests/test_config/test_preserve_leading_space.py +159 -0
  249. package/tests/test_config/test_profile/__init__.py +0 -0
  250. package/tests/test_config/test_profile/html.html +2 -0
  251. package/tests/test_config/test_profile/pyproject.toml +3 -0
  252. package/tests/test_config/test_profile/test_config.py +64 -0
  253. package/tests/test_config/test_pyproject/__init__.py +0 -0
  254. package/tests/test_config/test_pyproject/blank.html +0 -0
  255. package/tests/test_config/test_pyproject/pyproject.toml +36 -0
  256. package/tests/test_config/test_pyproject/test_config.py +44 -0
  257. package/tests/test_django/__init__.py +0 -0
  258. package/tests/test_django/test_asset.py +32 -0
  259. package/tests/test_django/test_autoescape.py +25 -0
  260. package/tests/test_django/test_block.py +29 -0
  261. package/tests/test_django/test_blocktrans.py +236 -0
  262. package/tests/test_django/test_blocktrans_trimmed.py +283 -0
  263. package/tests/test_django/test_comments.py +164 -0
  264. package/tests/test_django/test_filter.py +30 -0
  265. package/tests/test_django/test_for.py +34 -0
  266. package/tests/test_django/test_if.py +34 -0
  267. package/tests/test_django/test_ifchanged.py +37 -0
  268. package/tests/test_django/test_include.py +24 -0
  269. package/tests/test_django/test_load.py +24 -0
  270. package/tests/test_django/test_quoted.py +34 -0
  271. package/tests/test_django/test_spaceless.py +30 -0
  272. package/tests/test_django/test_tag_spaces.py +35 -0
  273. package/tests/test_django/test_templatetag.py +40 -0
  274. package/tests/test_django/test_verbatim.py +24 -0
  275. package/tests/test_django/test_with.py +32 -0
  276. package/tests/test_djlint/-.html +1 -0
  277. package/tests/test_djlint/__init__.py +0 -0
  278. package/tests/test_djlint/bad.html +6 -0
  279. package/tests/test_djlint/bad.html.dj +23 -0
  280. package/tests/test_djlint/bad.html.dj2 +2 -0
  281. package/tests/test_djlint/multiple_files/a/a.html +1 -0
  282. package/tests/test_djlint/multiple_files/b/b1.html +1 -0
  283. package/tests/test_djlint/multiple_files/b/b2.html +1 -0
  284. package/tests/test_djlint/test_djlint.py +242 -0
  285. package/tests/test_golang/__init__.py +0 -0
  286. package/tests/test_golang/test_if.py +24 -0
  287. package/tests/test_golang/test_range.py +24 -0
  288. package/tests/test_handlebars/__init__.py +0 -0
  289. package/tests/test_handlebars/test_each.py +34 -0
  290. package/tests/test_handlebars/test_else.py +24 -0
  291. package/tests/test_handlebars/test_with.py +24 -0
  292. package/tests/test_html/__init__.py +0 -0
  293. package/tests/test_html/test_alpinejs.py +65 -0
  294. package/tests/test_html/test_attributes.py +935 -0
  295. package/tests/test_html/test_aurelia.py +24 -0
  296. package/tests/test_html/test_basics.py +905 -0
  297. package/tests/test_html/test_bracket_same_line.py +177 -0
  298. package/tests/test_html/test_case.py +81 -0
  299. package/tests/test_html/test_cdata.py +34 -0
  300. package/tests/test_html/test_comments.py +333 -0
  301. package/tests/test_html/test_css.py +193 -0
  302. package/tests/test_html/test_doctype_declarations.py +202 -0
  303. package/tests/test_html/test_ignored.py +193 -0
  304. package/tests/test_html/test_interpolation.py +56 -0
  305. package/tests/test_html/test_line_break_after_multiline_tag.py +95 -0
  306. package/tests/test_html/test_next_line_empty.py +53 -0
  307. package/tests/test_html/test_selfclosing.py +55 -0
  308. package/tests/test_html/test_single_attribute_per_line.py +87 -0
  309. package/tests/test_html/test_srcset.py +43 -0
  310. package/tests/test_html/test_svg.py +104 -0
  311. package/tests/test_html/test_symbol_entities.py +34 -0
  312. package/tests/test_html/test_tag_code.py +24 -0
  313. package/tests/test_html/test_tag_dd.py +24 -0
  314. package/tests/test_html/test_tag_details_summary.py +24 -0
  315. package/tests/test_html/test_tag_dt.py +24 -0
  316. package/tests/test_html/test_tag_fig_caption.py +29 -0
  317. package/tests/test_html/test_tag_hr.py +29 -0
  318. package/tests/test_html/test_tag_picture.py +32 -0
  319. package/tests/test_html/test_tag_pre.py +45 -0
  320. package/tests/test_html/test_tag_script.py +516 -0
  321. package/tests/test_html/test_tag_small.py +24 -0
  322. package/tests/test_html/test_tag_span.py +119 -0
  323. package/tests/test_html/test_tag_textarea.py +82 -0
  324. package/tests/test_html/test_tags.py +842 -0
  325. package/tests/test_html/test_text.py +34 -0
  326. package/tests/test_html/test_whitespace.py +477 -0
  327. package/tests/test_html/test_yaml.py +156 -0
  328. package/tests/test_jinja/__init__.py +0 -0
  329. package/tests/test_jinja/test_call.py +34 -0
  330. package/tests/test_jinja/test_parenthesis.py +24 -0
  331. package/tests/test_linter/__init__.py +0 -0
  332. package/tests/test_linter/test_custom_rules/.djlint_rules.yaml +6 -0
  333. package/tests/test_linter/test_custom_rules/__init__.py +0 -0
  334. package/tests/test_linter/test_custom_rules/html.html +1 -0
  335. package/tests/test_linter/test_custom_rules/pyproject.toml +1 -0
  336. package/tests/test_linter/test_custom_rules/test_linter.py +29 -0
  337. package/tests/test_linter/test_custom_rules_bad/.djlint_rules.yaml +24 -0
  338. package/tests/test_linter/test_custom_rules_bad/__init__.py +0 -0
  339. package/tests/test_linter/test_custom_rules_bad/html.html +1 -0
  340. package/tests/test_linter/test_custom_rules_bad/pyproject.toml +1 -0
  341. package/tests/test_linter/test_custom_rules_bad/test_linter.py +29 -0
  342. package/tests/test_linter/test_django_linter.py +476 -0
  343. package/tests/test_linter/test_h005.py +45 -0
  344. package/tests/test_linter/test_h006.py +81 -0
  345. package/tests/test_linter/test_h007.py +45 -0
  346. package/tests/test_linter/test_h008.py +60 -0
  347. package/tests/test_linter/test_h009.py +45 -0
  348. package/tests/test_linter/test_h010.py +44 -0
  349. package/tests/test_linter/test_h037.py +150 -0
  350. package/tests/test_linter/test_ignore_rules.py +45 -0
  351. package/tests/test_linter/test_jinja_linter.py +227 -0
  352. package/tests/test_linter/test_linter.py +691 -0
  353. package/tests/test_linter/test_nunjucks_linter.py +59 -0
  354. package/tests/test_linter/test_python_module_rules/.djlint_rules.yaml +4 -0
  355. package/tests/test_linter/test_python_module_rules/__init__.py +0 -0
  356. package/tests/test_linter/test_python_module_rules/html_bad.html +3 -0
  357. package/tests/test_linter/test_python_module_rules/html_ok.html +3 -0
  358. package/tests/test_linter/test_python_module_rules/my_module.py +32 -0
  359. package/tests/test_linter/test_python_module_rules/pyproject.toml +1 -0
  360. package/tests/test_linter/test_python_module_rules/test_linter.py +26 -0
  361. package/tests/test_nunjucks/__init__.py +0 -0
  362. package/tests/test_nunjucks/test_functions.py +94 -0
  363. package/tests/test_nunjucks/test_macros.py +41 -0
  364. package/tests/test_nunjucks/test_set.py +206 -0
  365. package/tests/test_nunjucks/test_spaceless.py +24 -0
  366. package/tests/test_twig/__init__.py +0 -0
  367. package/tests/test_twig/test_comments.py +51 -0
  368. package/tox.ini +48 -0
@@ -0,0 +1,177 @@
1
+ """Test bracket on same line flag.
2
+
3
+ poetry run pytest tests/test_html/test_bracket_same_line.py
4
+ """
5
+ import pytest
6
+
7
+ from src.djlint.reformat import formatter
8
+ from tests.conftest import printer
9
+
10
+ test_data = [
11
+ pytest.param(
12
+ (
13
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
14
+ "text\n"
15
+ "</div>\n"
16
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></div>\n'
17
+ '<div class="a">\n'
18
+ "text\n"
19
+ "</div>\n"
20
+ '<div class="a">text</div>\n'
21
+ ),
22
+ (
23
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</div>\n'
24
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></div>\n'
25
+ '<div class="a">text</div>\n'
26
+ '<div class="a">text</div>\n'
27
+ ),
28
+ id="block",
29
+ ),
30
+ pytest.param(
31
+ (
32
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
33
+ "text\n"
34
+ "</div>\n"
35
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></div>\n'
36
+ '<div class="a">\n'
37
+ "text\n"
38
+ "</div>\n"
39
+ '<div class="a">text</div>\n'
40
+ ),
41
+ (
42
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</div>\n'
43
+ '<div long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></div>\n'
44
+ '<div class="a">text</div>\n'
45
+ '<div class="a">text</div>\n'
46
+ ),
47
+ id="block_bracket_same_line",
48
+ ),
49
+ pytest.param(
50
+ (
51
+ '<script long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
52
+ "alert(1)</script>\n"
53
+ '<style long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
54
+ ".a{color: #f00}</style>\n"
55
+ "<script>\n"
56
+ "alert(1)</script>\n"
57
+ "<style>\n"
58
+ ".a{color: #f00}</style>\n"
59
+ ),
60
+ (
61
+ '<script long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">alert(1)</script>\n'
62
+ '<style long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">.a{color: #f00}</style>\n'
63
+ "<script>alert(1)</script>\n"
64
+ "<style>.a{color: #f00}</style>\n"
65
+ ),
66
+ id="embed",
67
+ ),
68
+ pytest.param(
69
+ (
70
+ '<script long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
71
+ "alert(1)</script>\n"
72
+ '<style long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
73
+ ".a{color: #f00}</style>\n"
74
+ "<script>\n"
75
+ "alert(1)</script>\n"
76
+ "<style>\n"
77
+ ".a{color: #f00}</style>\n"
78
+ ),
79
+ (
80
+ '<script long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">alert(1)</script>\n'
81
+ '<style long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">.a{color: #f00}</style>\n'
82
+ "<script>alert(1)</script>\n"
83
+ "<style>.a{color: #f00}</style>\n"
84
+ ),
85
+ id="embed_bracket_same_line",
86
+ ),
87
+ pytest.param(
88
+ (
89
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
90
+ "text\n"
91
+ "</span>\n"
92
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></span>\n'
93
+ '<span class="a">text</span>\n'
94
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
95
+ "text\n"
96
+ "</span>\n"
97
+ '<span class="a">text</span><span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
98
+ "text\n"
99
+ "</span>\n"
100
+ '<span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span>\n'
101
+ ),
102
+ (
103
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</span>\n'
104
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></span>\n'
105
+ '<span class="a">text</span>\n'
106
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</span>\n'
107
+ '<span class="a">text</span><span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</span>\n'
108
+ '<span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span>\n'
109
+ ),
110
+ id="inline",
111
+ ),
112
+ pytest.param(
113
+ (
114
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
115
+ "text\n"
116
+ "</span>\n"
117
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></span>\n'
118
+ '<span class="a">text</span>\n'
119
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
120
+ "text\n"
121
+ "</span>\n"
122
+ '<span class="a">text</span><span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">\n'
123
+ "text\n"
124
+ "</span>\n"
125
+ '<span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span>\n'
126
+ ),
127
+ (
128
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</span>\n'
129
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"></span>\n'
130
+ '<span class="a">text</span>\n'
131
+ '<span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</span>\n'
132
+ '<span class="a">text</span><span long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value">text</span>\n'
133
+ '<span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span><span class="a">text</span>\n'
134
+ ),
135
+ id="inline_bracket_same_line",
136
+ ),
137
+ pytest.param(
138
+ (
139
+ '<img long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value" src="./1.jpg"/>\n'
140
+ '<img src="./1.jpg"/><img src="./1.jpg"/><img src="./1.jpg"/><img src="./1.jpg"/><img src="./1.jpg"/>\n'
141
+ ),
142
+ (
143
+ '<img long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"\n'
144
+ ' src="./1.jpg" />\n'
145
+ '<img src="./1.jpg" />\n'
146
+ '<img src="./1.jpg" />\n'
147
+ '<img src="./1.jpg" />\n'
148
+ '<img src="./1.jpg" />\n'
149
+ '<img src="./1.jpg" />\n'
150
+ ),
151
+ id="void",
152
+ ),
153
+ pytest.param(
154
+ (
155
+ '<img long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value" src="./1.jpg"/>\n'
156
+ '<img src="./1.jpg"/><img src="./1.jpg"/><img src="./1.jpg"/><img src="./1.jpg"/><img src="./1.jpg"/>\n'
157
+ ),
158
+ (
159
+ '<img long_long_attribute="long_long_long_long_long_long_long_long_long_long_long_value"\n'
160
+ ' src="./1.jpg" />\n'
161
+ '<img src="./1.jpg" />\n'
162
+ '<img src="./1.jpg" />\n'
163
+ '<img src="./1.jpg" />\n'
164
+ '<img src="./1.jpg" />\n'
165
+ '<img src="./1.jpg" />\n'
166
+ ),
167
+ id="void_braket_same_line",
168
+ ),
169
+ ]
170
+
171
+
172
+ @pytest.mark.parametrize(("source", "expected"), test_data)
173
+ def test_base(source, expected, basic_config):
174
+ output = formatter(basic_config, source)
175
+
176
+ printer(expected, source, output)
177
+ assert expected == output
@@ -0,0 +1,81 @@
1
+ """Test case.
2
+
3
+ poetry run pytest tests/test_html/test_case.py
4
+ """
5
+ import pytest
6
+
7
+ from src.djlint.reformat import formatter
8
+ from src.djlint.settings import Config
9
+ from tests.conftest import printer
10
+
11
+ test_data = [
12
+ pytest.param(
13
+ (
14
+ "<!DOCTYPE html>\n"
15
+ '<HTML CLASS="no-js mY-ClAsS">\n'
16
+ " <HEAD>\n"
17
+ ' <META CHARSET="utf-8">\n'
18
+ " <TITLE>My tITlE</TITLE>\n"
19
+ ' <META NAME="description" content="My CoNtEnT">\n'
20
+ " </HEAD>\n"
21
+ " <body>\n"
22
+ " <P>Hello world!<BR> This is HTML5 Boilerplate.</P>\n"
23
+ " <SCRIPT>\n"
24
+ " window.ga = function () { ga.q.push(arguments) }; ga.q = []; ga.l = +new Date;\n"
25
+ " ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview')\n"
26
+ " </SCRIPT>\n"
27
+ ' <SCRIPT src="https://www.google-analytics.com/analytics.js" ASYNC DEFER> </SCRIPT>\n'
28
+ " </body>\n"
29
+ "</HTML>\n"
30
+ ),
31
+ (
32
+ "<!DOCTYPE html>\n"
33
+ '<html CLASS="no-js mY-ClAsS">\n'
34
+ " <head>\n"
35
+ ' <meta CHARSET="utf-8">\n'
36
+ " <title>My tITlE</title>\n"
37
+ ' <meta NAME="description" content="My CoNtEnT">\n'
38
+ " </head>\n"
39
+ " <body>\n"
40
+ " <p>\n"
41
+ " Hello world!\n"
42
+ " <br>\n"
43
+ " This is HTML5 Boilerplate.\n"
44
+ " </p>\n"
45
+ " <script>\n"
46
+ " window.ga = function () { ga.q.push(arguments) }; ga.q = []; ga.l = +new Date;\n"
47
+ " ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview')\n"
48
+ " </script>\n"
49
+ ' <script src="https://www.google-analytics.com/analytics.js" ASYNC DEFER> </script>\n'
50
+ " </body>\n"
51
+ "</html>\n"
52
+ ),
53
+ id="case",
54
+ )
55
+ ]
56
+
57
+
58
+ @pytest.mark.parametrize(("source", "expected"), test_data)
59
+ def test_base(source, expected, basic_config):
60
+ output = formatter(basic_config, source)
61
+
62
+ printer(expected, source, output)
63
+ assert expected == output
64
+
65
+
66
+ test_data_two = [
67
+ pytest.param(
68
+ ("<dIV></Div>\n" "<bR>\n" "<Br />\n" "<MeTa class='asdf' />\n"),
69
+ ("<dIV></Div>\n" "<bR>\n" "<Br />\n" "<MeTa class='asdf' />\n"),
70
+ id="preserve_case",
71
+ )
72
+ ]
73
+
74
+
75
+ @pytest.mark.parametrize(("source", "expected"), test_data_two)
76
+ def test_base_two(source, expected):
77
+ config = Config("dummy/source.html", ignore_case=True)
78
+ output = formatter(config, source)
79
+
80
+ printer(expected, source, output)
81
+ assert expected == output
@@ -0,0 +1,34 @@
1
+ """Test cdata.
2
+
3
+ poetry run pytest tests/test_html/test_cdata.py
4
+ """
5
+ import pytest
6
+
7
+ from src.djlint.reformat import formatter
8
+ from tests.conftest import printer
9
+
10
+ test_data = [
11
+ pytest.param(
12
+ (
13
+ "<span><![CDATA[<sender>John Smith</sender>]]></span>\n"
14
+ "<span><![CDATA[1]]> a <![CDATA[2]]></span>\n"
15
+ "<span><![CDATA[1]]> <br> <![CDATA[2]]></span>\n"
16
+ ),
17
+ (
18
+ "<span><![CDATA[<sender>John Smith</sender>]]></span>\n"
19
+ "<span><![CDATA[1]]> a <![CDATA[2]]></span>\n"
20
+ "<span><![CDATA[1]]>\n"
21
+ " <br>\n"
22
+ "<![CDATA[2]]></span>\n"
23
+ ),
24
+ id="cdata",
25
+ ),
26
+ ]
27
+
28
+
29
+ @pytest.mark.parametrize(("source", "expected"), test_data)
30
+ def test_base(source, expected, basic_config):
31
+ output = formatter(basic_config, source)
32
+
33
+ printer(expected, source, output)
34
+ assert expected == output
@@ -0,0 +1,333 @@
1
+ """Test for comments.
2
+
3
+ poetry run pytest tests/test_html/test_comments.py
4
+ """
5
+ import pytest
6
+
7
+ from src.djlint.reformat import formatter
8
+ from tests.conftest import printer
9
+
10
+ test_data = [
11
+ pytest.param(
12
+ ("<div>\n" " <!-- asdf--><!--\n" " multi\n" "line\n" "comment--></div>"),
13
+ (
14
+ "<div>\n"
15
+ " <!-- asdf--><!--\n"
16
+ " multi\n"
17
+ "line\n"
18
+ "comment-->\n"
19
+ "</div>\n"
20
+ ),
21
+ id="comments_tag",
22
+ ),
23
+ pytest.param(
24
+ ("<!-- hello -->\n" "123\n"),
25
+ ("<!-- hello -->\n" "123\n"),
26
+ id="before_text",
27
+ ),
28
+ pytest.param(
29
+ ("<? hello ?>\n" "<!- world ->\n"),
30
+ ("<? hello ?>\n" "<!- world ->\n"),
31
+ id="bogus",
32
+ ),
33
+ pytest.param(
34
+ (
35
+ "<!DOCTYPE html>\n"
36
+ "<html>\n"
37
+ " <body>\n"
38
+ " <!--[if IE 5]>This is IE 5<br><![endif]-->\n"
39
+ " <!--[if IE 6]>This is IE 6<br><![endif]-->\n"
40
+ " <!--[if IE 7]>This is IE 7<br><![endif]-->\n"
41
+ " <!--[if IE 8]>This is IE 8<br><![endif]-->\n"
42
+ " <!--[if IE 9]>This is IE 9<br><![endif]-->\n"
43
+ " </body>\n"
44
+ "</html>\n"
45
+ "<!DOCTYPE html>\n"
46
+ '<!--[if lt IE 9]><html lang="zh-CN"><![endif]-->\n'
47
+ '<html lang="zh-CN">\n'
48
+ " <head></head>\n"
49
+ " <body></body>\n"
50
+ "</html>\n"
51
+ "<!DOCTYPE html>\n"
52
+ '<!--[if lt IE 9]><html lang="zh-CN"><div><![endif]-->\n'
53
+ '<html lang="zh-CN">\n'
54
+ " <head></head>\n"
55
+ " <body></body>\n"
56
+ "</html>\n"
57
+ "<!DOCTYPE html>\n"
58
+ '<!--[if lt IE 9]><html lang="zh-CN"><div></div><![endif]-->\n'
59
+ '<html lang="zh-CN">\n'
60
+ " <head></head>\n"
61
+ " <body></body>\n"
62
+ "</html>\n"
63
+ '<body width="100%" align="center">\n'
64
+ " <center >\n"
65
+ ' <!--[if (gte mso 9)|(IE)]><table cellpadding="0" cellspacing="0" border="0" width="600" align="center"><tr><td><![endif]-->\n'
66
+ " <div> </div>\n"
67
+ " <!--[if (gte mso 9)|(IE)]></td></tr></table><![endif]-->\n"
68
+ " </center >\n"
69
+ "</body>\n"
70
+ "<!DOCTYPE html>\n"
71
+ '<!--[if lt IE 9]><html class="legacy-ie"><![endif]-->\n'
72
+ "<!--[if gte IE 9]><!--><html><!--<![endif]-->\n"
73
+ " <head></head>\n"
74
+ " <body></body>\n"
75
+ "</html>\n"
76
+ "<!DOCTYPE html>\n"
77
+ '<!--[if lt IE 9]><html class="legacy-ie"><![endif]-->\n'
78
+ "<!--[if gte IE 9]><!--><html hello><!--<![endif]-->\n"
79
+ " <head></head>\n"
80
+ " <body></body>\n"
81
+ "</html>\n"
82
+ "<!DOCTYPE html>\n"
83
+ '<!--[if lt IE 9]><html class="legacy-ie"><head><![endif]-->\n'
84
+ "<!--[if gte IE 9]><!--><html><head><!--<![endif]-->\n"
85
+ " </head>\n"
86
+ " <body></body>\n"
87
+ "</html>\n"
88
+ "<!DOCTYPE html>\n"
89
+ '<!--[if lt IE 9]><html class="legacy-ie"><![endif]-->\n'
90
+ "<!--[if gte IE 9\n"
91
+ "]><!--><html><!--<![endif]-->\n"
92
+ " <head></head>\n"
93
+ " <body></body>\n"
94
+ "</html>\n"
95
+ ),
96
+ (
97
+ "<!DOCTYPE html>\n"
98
+ "<html>\n"
99
+ " <body>\n"
100
+ " <!--[if IE 5]>This is IE 5<br><![endif]-->\n"
101
+ " <!--[if IE 6]>This is IE 6<br><![endif]-->\n"
102
+ " <!--[if IE 7]>This is IE 7<br><![endif]-->\n"
103
+ " <!--[if IE 8]>This is IE 8<br><![endif]-->\n"
104
+ " <!--[if IE 9]>This is IE 9<br><![endif]-->\n"
105
+ " </body>\n"
106
+ "</html>\n"
107
+ "<!DOCTYPE html>\n"
108
+ '<!--[if lt IE 9]><html lang="zh-CN"><![endif]-->\n'
109
+ '<html lang="zh-CN">\n'
110
+ " <head></head>\n"
111
+ " <body></body>\n"
112
+ "</html>\n"
113
+ "<!DOCTYPE html>\n"
114
+ '<!--[if lt IE 9]><html lang="zh-CN"><div><![endif]-->\n'
115
+ '<html lang="zh-CN">\n'
116
+ " <head></head>\n"
117
+ " <body></body>\n"
118
+ "</html>\n"
119
+ "<!DOCTYPE html>\n"
120
+ '<!--[if lt IE 9]><html lang="zh-CN"><div></div><![endif]-->\n'
121
+ '<html lang="zh-CN">\n'
122
+ " <head></head>\n"
123
+ " <body></body>\n"
124
+ "</html>\n"
125
+ '<body width="100%" align="center">\n'
126
+ " <center>\n"
127
+ ' <!--[if (gte mso 9)|(IE)]><table cellpadding="0" cellspacing="0" border="0" width="600" align="center"><tr><td><![endif]-->\n'
128
+ " <div></div>\n"
129
+ " <!--[if (gte mso 9)|(IE)]></td></tr></table><![endif]-->\n"
130
+ " </center>\n"
131
+ "</body>\n"
132
+ "<!DOCTYPE html>\n"
133
+ '<!--[if lt IE 9]><html class="legacy-ie"><![endif]-->\n'
134
+ "<!--[if gte IE 9]><!-->\n"
135
+ "<html>\n"
136
+ " <!--<![endif]-->\n"
137
+ " <head></head>\n"
138
+ " <body></body>\n"
139
+ "</html>\n"
140
+ "<!DOCTYPE html>\n"
141
+ '<!--[if lt IE 9]><html class="legacy-ie"><![endif]-->\n'
142
+ "<!--[if gte IE 9]><!-->\n"
143
+ "<html hello>\n"
144
+ " <!--<![endif]-->\n"
145
+ " <head></head>\n"
146
+ " <body></body>\n"
147
+ "</html>\n"
148
+ "<!DOCTYPE html>\n"
149
+ '<!--[if lt IE 9]><html class="legacy-ie"><head><![endif]-->\n'
150
+ "<!--[if gte IE 9]><!-->\n"
151
+ "<html>\n"
152
+ " <head>\n"
153
+ " <!--<![endif]-->\n"
154
+ " </head>\n"
155
+ " <body></body>\n"
156
+ "</html>\n"
157
+ "<!DOCTYPE html>\n"
158
+ '<!--[if lt IE 9]><html class="legacy-ie"><![endif]-->\n'
159
+ "<!--[if gte IE 9\n"
160
+ "]><!--><html><!--<![endif]-->\n"
161
+ "<head></head>\n"
162
+ "<body></body>\n"
163
+ "</html>\n"
164
+ ),
165
+ id="conditional",
166
+ ),
167
+ # opened https://github.com/Riverside-Healthcare/djLint/issues/247
168
+ pytest.param(
169
+ (
170
+ "<!DOCTYPE html>\n"
171
+ "<html>\n"
172
+ " <body>\n"
173
+ "<!-- Do not display this at the moment\n"
174
+ '<img border="0" src="pic_trulli.jpg" alt="Trulli">\n'
175
+ "-->\n"
176
+ " <!-- Do not display this at the moment\n"
177
+ ' <img border="0" src="pic_trulli.jpg" alt="Trulli">\n'
178
+ " -->\n"
179
+ " <!-- Do not display this at the moment\n"
180
+ ' <img border="0" src="pic_trulli.jpg" alt="Trulli">\n'
181
+ " -->\n"
182
+ " </body>\n"
183
+ "</html>\n"
184
+ ),
185
+ (
186
+ "<!DOCTYPE html>\n"
187
+ "<html>\n"
188
+ " <body>\n"
189
+ " <!-- Do not display this at the moment\n"
190
+ '<img border="0" src="pic_trulli.jpg" alt="Trulli">\n'
191
+ "-->\n"
192
+ " <!-- Do not display this at the moment\n"
193
+ ' <img border="0" src="pic_trulli.jpg" alt="Trulli">\n'
194
+ " -->\n"
195
+ " <!-- Do not display this at the moment\n"
196
+ ' <img border="0" src="pic_trulli.jpg" alt="Trulli">\n'
197
+ " -->\n"
198
+ " </body>\n"
199
+ "</html>\n"
200
+ ),
201
+ id="debugging",
202
+ ),
203
+ pytest.param(
204
+ (
205
+ "<!DOCTYPE html>\n"
206
+ "<html>\n"
207
+ " <body>\n"
208
+ " <!--This is a comment-->\n"
209
+ " <!-- This is a comment -->\n"
210
+ " <!-- This is a comment -->\n"
211
+ " <!-- This is a comment -->\n"
212
+ " <p>This is a paragraph.</p>\n"
213
+ " <!-- Comments are not displayed in the browser -->\n"
214
+ " </body>\n"
215
+ "</html>\n"
216
+ ),
217
+ (
218
+ "<!DOCTYPE html>\n"
219
+ "<html>\n"
220
+ " <body>\n"
221
+ " <!--This is a comment-->\n"
222
+ " <!-- This is a comment -->\n"
223
+ " <!-- This is a comment -->\n"
224
+ " <!-- This is a comment -->\n"
225
+ " <p>This is a paragraph.</p>\n"
226
+ " <!-- Comments are not displayed in the browser -->\n"
227
+ " </body>\n"
228
+ "</html>\n"
229
+ ),
230
+ id="hidden",
231
+ ),
232
+ pytest.param(
233
+ (
234
+ "<ul><!-- 123\n"
235
+ "--><li>First</li><!-- 123\n"
236
+ "456\n"
237
+ " 789\n"
238
+ "--><li>Second</li><!--\n"
239
+ " 123\n"
240
+ " 456\n"
241
+ " 789\n"
242
+ "--><li>Second</li><!--\n"
243
+ " 123\n"
244
+ " 456\n"
245
+ " 789\n"
246
+ "--></ul>\n"
247
+ "<span><!--\n"
248
+ "--><span>a</span><!--\n"
249
+ "--><span>b</span><!--\n"
250
+ "--></span>\n"
251
+ "<span><!-- 1\n"
252
+ "--><span>a</span><!-- 2\n"
253
+ "--><span>b</span><!-- 3\n"
254
+ "--></span>\n"
255
+ "<span><!--\n"
256
+ "1 --><span>a</span><!--\n"
257
+ "2 --><span>b</span><!--\n"
258
+ "3 --></span>\n"
259
+ "123<!---->456\n"
260
+ "123<!--x-->456\n"
261
+ "<!-- A\n"
262
+ " B -->\n"
263
+ "<!--\n"
264
+ "The null hero's name is {{nullHero.name}}\n"
265
+ "See console log:\n"
266
+ " TypeError: Cannot read property 'name' of null in [null]\n"
267
+ "-->\n"
268
+ "<!--\n"
269
+ " The null hero's name is {{nullHero.name}}\n"
270
+ " See console log:\n"
271
+ " TypeError: Cannot read property 'name' of null in [null]\n"
272
+ "-->\n"
273
+ ),
274
+ (
275
+ "<ul>\n"
276
+ " <!-- 123\n"
277
+ "-->\n"
278
+ " <li>First</li>\n"
279
+ " <!-- 123\n"
280
+ "456\n"
281
+ " 789\n"
282
+ "-->\n"
283
+ " <li>Second</li>\n"
284
+ " <!--\n"
285
+ " 123\n"
286
+ " 456\n"
287
+ " 789\n"
288
+ "-->\n"
289
+ " <li>Second</li>\n"
290
+ " <!--\n"
291
+ " 123\n"
292
+ " 456\n"
293
+ " 789\n"
294
+ "-->\n"
295
+ "</ul>\n"
296
+ "<span><!--\n"
297
+ "--><span>a</span><!--\n"
298
+ "--><span>b</span><!--\n"
299
+ "--></span>\n"
300
+ "<span><!-- 1\n"
301
+ "--><span>a</span><!-- 2\n"
302
+ "--><span>b</span><!-- 3\n"
303
+ "--></span>\n"
304
+ "<span><!--\n"
305
+ "1 --><span>a</span><!--\n"
306
+ "2 --><span>b</span><!--\n"
307
+ "3 --></span>\n"
308
+ "123<!---->456\n"
309
+ "123<!--x-->456\n"
310
+ "<!-- A\n"
311
+ " B -->\n"
312
+ "<!--\n"
313
+ "The null hero's name is {{nullHero.name}}\n"
314
+ "See console log:\n"
315
+ " TypeError: Cannot read property 'name' of null in [null]\n"
316
+ "-->\n"
317
+ "<!--\n"
318
+ " The null hero's name is {{nullHero.name}}\n"
319
+ " See console log:\n"
320
+ " TypeError: Cannot read property 'name' of null in [null]\n"
321
+ "-->\n"
322
+ ),
323
+ id="surrounding_empty_line",
324
+ ),
325
+ ]
326
+
327
+
328
+ @pytest.mark.parametrize(("source", "expected"), test_data)
329
+ def test_base(source, expected, basic_config):
330
+ output = formatter(basic_config, source)
331
+
332
+ printer(expected, source, output)
333
+ assert expected == output