From 35e10411797f0c029a273bca5fc9f8ff1a5ffe7b Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Tue, 25 Apr 2023 08:29:10 -0500 Subject: [PATCH 1/3] fix(formatter): fixed extra indent on endblocktrans tags closes #611 --- src/djlint/formatter/condense.py | 9 ++++++--- tests/test_django/test_blocktrans.py | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/djlint/formatter/condense.py b/src/djlint/formatter/condense.py index 2714f6a87..c5d8eda4e 100644 --- a/src/djlint/formatter/condense.py +++ b/src/djlint/formatter/condense.py @@ -8,7 +8,7 @@ import regex as re -from ..helpers import inside_ignored_block +from ..helpers import inside_ignored_block, is_safe_closing_tag from ..settings import Config @@ -18,7 +18,11 @@ def clean_whitespace(html: str, config: Config) -> str: def strip_space(config: Config, html: str, match: re.Match) -> str: """Trim leading whitespace.""" - if inside_ignored_block(config, html, match): + # either inside a block, or this is a newline + closing block tag. + # if it is a newline + closing block we can format it. + if inside_ignored_block(config, html, match) and not is_safe_closing_tag( + config, match.group() + ): return match.group() return match.group(1) @@ -34,7 +38,6 @@ def strip_space(config: Config, html: str, match: re.Match) -> str: if not config.preserve_leading_space: # remove any leading/trailing space - html = re.sub( re.compile(rf"^[ \t]*{line_contents}[{trailing_contents}]*$", re.M), func, diff --git a/tests/test_django/test_blocktrans.py b/tests/test_django/test_blocktrans.py index e18425e5b..c8deabaf2 100644 --- a/tests/test_django/test_blocktrans.py +++ b/tests/test_django/test_blocktrans.py @@ -164,6 +164,33 @@ ("

\n" " {% trans 'Please do Blah.' %}\n" "

\n"), id="blocktrans_indent_3", ), + pytest.param( + ("{% autoescape off %}\n" + "\n" + " {% blocktrans %}\n" + " You're receiving this email because you requested a password reset for your user account at {{ site_name }}.\n" + " {% endblocktrans %}\n" + ), + ("{% autoescape off %}\n" + " {% blocktrans %}\n" + " You're receiving this email because you requested a password reset for your user account at {{ site_name }}.\n" + " {% endblocktrans %}\n" + ), + id="blocktrans_autoescape", + ), + pytest.param( + ("{% autoescape off %}\n" + " {% blocktrans %}\n" + " You're receiving this email because you requested a password reset for your user account at {{ site_name }}.\n" + " {% endblocktrans %}\n" + ), + ("{% autoescape off %}\n" + " {% blocktrans %}\n" + " You're receiving this email because you requested a password reset for your user account at {{ site_name }}.\n" + " {% endblocktrans %}\n" + ), + id="blocktrans_autoescape_two", + ), ] From 16bd8fd001b39ac610217b834a91625f7db4eb9e Mon Sep 17 00:00:00 2001 From: Christopher Pickering Date: Tue, 25 Apr 2023 14:02:12 -0500 Subject: [PATCH 2/3] feat(cli): added all args to cli closes #595 --- docs/src/_data/configuration.json | 114 ++++++- docs/src/_utils/scripts.11ty.js | 6 +- docs/src/docs/configuration.md | 34 ++- docs/src/fr/docs/configuration.md | 34 ++- docs/src/ru/docs/configuration.md | 34 ++- docs/src/static/js/tabs.js | 34 --- src/djlint/__init__.py | 105 ++++++- src/djlint/settings.py | 64 ++-- tests/test_cli.py | 71 +++++ .../test_config/test_blank_line_after_tag.py | 135 +++++++++ .../test_config/test_blank_line_before_tag.py | 141 +++++++++ .../test_blank_lines_after_tag/html.html | 1 - .../html_eight.html | 3 - .../test_blank_lines_after_tag/html_five.html | 6 - .../test_blank_lines_after_tag/html_four.html | 3 - .../test_blank_lines_after_tag/html_nine.html | 3 - .../html_seven.html | 6 - .../test_blank_lines_after_tag/html_six.html | 3 - .../test_blank_lines_after_tag/html_ten.html | 4 - .../html_three.html | 8 - .../test_blank_lines_after_tag/html_two.html | 2 - .../test_blank_lines_after_tag/pyproject.toml | 3 - .../test_blank_lines_after_tag/test_config.py | 144 --------- .../test_blank_lines_before_tag/html.html | 1 - .../html_eight.html | 3 - .../html_five.html | 6 - .../html_four.html | 3 - .../html_seven.html | 6 - .../test_blank_lines_before_tag/html_six.html | 4 - .../html_three.html | 8 - .../test_blank_lines_before_tag/html_two.html | 2 - .../pyproject.toml | 3 - .../test_config.py | 116 -------- tests/test_config/test_custom_blocks.py | 40 +++ tests/test_config/test_custom_html.py | 45 +++ tests/test_config/test_custom_html/html.html | 1 - .../test_custom_html/pyproject.toml | 3 - .../test_custom_html/test_config.py | 45 --- tests/test_config/test_custom_tags/html.html | 3 - .../test_custom_tags/pyproject.toml | 3 - .../test_custom_tags/test_config.py | 41 --- tests/test_config/test_djlintrc/.djlintrc | 38 +++ .../__init__.py | 0 .../test_config/test_djlintrc/test_config.py | 44 +++ .../test_djlintrc_custom/.djlint-cust | 38 +++ .../test_djlintrc_custom/.djlintrc | 2 + .../__init__.py | 0 .../test_djlintrc_custom/test_config.py | 48 +++ .../test_format_attribute_template_tags.py | 280 ++++++++++++++++++ .../html-one.html | 61 ---- .../pyproject.toml | 3 - .../test_config.py | 173 ----------- tests/test_config/test_format_css.py | 183 ++++++++++++ tests/test_config/test_format_js.py | 177 +++++++++++ .../__init__.py | 0 .../{test_ignores => test_ignore}/html.html | 0 .../html_two.html | 0 .../pyproject.toml | 0 .../test_config.py | 17 +- tests/test_config/test_ignore_blocks.py | 2 +- tests/test_config/test_ignore_case.py | 39 +++ tests/test_config/test_ignores/__init__.py | 0 tests/test_config/test_indent.py | 63 ++++ tests/test_config/test_indent/__init__.py | 0 tests/test_config/test_indent/html.html | 1 - tests/test_config/test_indent/pyproject.toml | 3 - tests/test_config/test_indent/test_config.py | 53 ---- tests/test_config/test_json/.djlint-cust | 5 - tests/test_config/test_json/.djlintrc | 4 - tests/test_config/test_json/__init__.py | 0 tests/test_config/test_json/html.html | 1 - tests/test_config/test_json/test_config.py | 51 ---- .../test_config/test_max_attribute_length.py | 100 +++++++ tests/test_config/test_max_line_length.py | 94 ++++++ .../test_config/test_preserve_blank_lines.py | 109 +++++++ .../test_preserve_blank_lines/__init__.py | 0 .../test_preserve_blank_lines/html.html | 34 --- .../test_preserve_blank_lines/html_one.html | 3 - .../test_preserve_blank_lines/html_two.html | 1 - .../test_preserve_blank_lines/test_config.py | 54 ---- .../test_preserve_leading_space.py | 159 ++++++++++ .../test_preserve_leading_space/__init__.py | 0 .../test_preserve_leading_space/html.html | 27 -- .../test_config.py | 64 ---- .../__init__.py | 0 .../__init__.py => test_pyproject/blank.html} | 0 .../test_config/test_pyproject/pyproject.toml | 36 +++ .../test_config/test_pyproject/test_config.py | 44 +++ .../test_scripts_styles/__init__.py | 0 .../test_scripts_styles/blank_lines.html | 14 - .../test_config/test_scripts_styles/html.html | 21 -- .../test_scripts_styles/ignore.html | 21 -- .../test_scripts_styles/pyproject.toml | 9 - .../test_scripts_styles/test_config.py | 48 --- tests/test_django/test_blocktrans.py | 40 +-- 95 files changed, 2261 insertions(+), 1194 deletions(-) delete mode 100644 docs/src/static/js/tabs.js create mode 100644 tests/test_cli.py create mode 100644 tests/test_config/test_blank_line_after_tag.py create mode 100644 tests/test_config/test_blank_line_before_tag.py delete mode 100644 tests/test_config/test_blank_lines_after_tag/html.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_eight.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_five.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_four.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_nine.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_seven.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_six.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_ten.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_three.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/html_two.html delete mode 100644 tests/test_config/test_blank_lines_after_tag/pyproject.toml delete mode 100644 tests/test_config/test_blank_lines_after_tag/test_config.py delete mode 100644 tests/test_config/test_blank_lines_before_tag/html.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_eight.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_five.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_four.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_seven.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_six.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_three.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/html_two.html delete mode 100644 tests/test_config/test_blank_lines_before_tag/pyproject.toml delete mode 100644 tests/test_config/test_blank_lines_before_tag/test_config.py create mode 100644 tests/test_config/test_custom_blocks.py create mode 100644 tests/test_config/test_custom_html.py delete mode 100644 tests/test_config/test_custom_html/html.html delete mode 100644 tests/test_config/test_custom_html/pyproject.toml delete mode 100644 tests/test_config/test_custom_html/test_config.py delete mode 100644 tests/test_config/test_custom_tags/html.html delete mode 100644 tests/test_config/test_custom_tags/pyproject.toml delete mode 100644 tests/test_config/test_custom_tags/test_config.py create mode 100644 tests/test_config/test_djlintrc/.djlintrc rename tests/test_config/{test_blank_lines_after_tag => test_djlintrc}/__init__.py (100%) create mode 100644 tests/test_config/test_djlintrc/test_config.py create mode 100644 tests/test_config/test_djlintrc_custom/.djlint-cust create mode 100644 tests/test_config/test_djlintrc_custom/.djlintrc rename tests/test_config/{test_blank_lines_before_tag => test_djlintrc_custom}/__init__.py (100%) create mode 100644 tests/test_config/test_djlintrc_custom/test_config.py create mode 100644 tests/test_config/test_format_attribute_template_tags.py delete mode 100644 tests/test_config/test_format_attribute_template_tags/html-one.html delete mode 100644 tests/test_config/test_format_attribute_template_tags/pyproject.toml delete mode 100644 tests/test_config/test_format_attribute_template_tags/test_config.py create mode 100644 tests/test_config/test_format_css.py create mode 100644 tests/test_config/test_format_js.py rename tests/test_config/{test_custom_html => test_ignore}/__init__.py (100%) rename tests/test_config/{test_ignores => test_ignore}/html.html (100%) rename tests/test_config/{test_ignores => test_ignore}/html_two.html (100%) rename tests/test_config/{test_ignores => test_ignore}/pyproject.toml (100%) rename tests/test_config/{test_ignores => test_ignore}/test_config.py (57%) create mode 100644 tests/test_config/test_ignore_case.py delete mode 100644 tests/test_config/test_ignores/__init__.py create mode 100644 tests/test_config/test_indent.py delete mode 100644 tests/test_config/test_indent/__init__.py delete mode 100644 tests/test_config/test_indent/html.html delete mode 100644 tests/test_config/test_indent/pyproject.toml delete mode 100644 tests/test_config/test_indent/test_config.py delete mode 100644 tests/test_config/test_json/.djlint-cust delete mode 100644 tests/test_config/test_json/.djlintrc delete mode 100644 tests/test_config/test_json/__init__.py delete mode 100644 tests/test_config/test_json/html.html delete mode 100644 tests/test_config/test_json/test_config.py create mode 100644 tests/test_config/test_max_attribute_length.py create mode 100644 tests/test_config/test_max_line_length.py create mode 100644 tests/test_config/test_preserve_blank_lines.py delete mode 100644 tests/test_config/test_preserve_blank_lines/__init__.py delete mode 100644 tests/test_config/test_preserve_blank_lines/html.html delete mode 100644 tests/test_config/test_preserve_blank_lines/html_one.html delete mode 100644 tests/test_config/test_preserve_blank_lines/html_two.html delete mode 100644 tests/test_config/test_preserve_blank_lines/test_config.py create mode 100644 tests/test_config/test_preserve_leading_space.py delete mode 100644 tests/test_config/test_preserve_leading_space/__init__.py delete mode 100644 tests/test_config/test_preserve_leading_space/html.html delete mode 100644 tests/test_config/test_preserve_leading_space/test_config.py rename tests/test_config/{test_custom_tags => test_pyproject}/__init__.py (100%) rename tests/test_config/{test_format_attribute_template_tags/__init__.py => test_pyproject/blank.html} (100%) create mode 100644 tests/test_config/test_pyproject/pyproject.toml create mode 100644 tests/test_config/test_pyproject/test_config.py delete mode 100644 tests/test_config/test_scripts_styles/__init__.py delete mode 100644 tests/test_config/test_scripts_styles/blank_lines.html delete mode 100644 tests/test_config/test_scripts_styles/html.html delete mode 100644 tests/test_config/test_scripts_styles/ignore.html delete mode 100644 tests/test_config/test_scripts_styles/pyproject.toml delete mode 100644 tests/test_config/test_scripts_styles/test_config.py diff --git a/docs/src/_data/configuration.json b/docs/src/_data/configuration.json index ca2b68823..28e5f55b2 100644 --- a/docs/src/_data/configuration.json +++ b/docs/src/_data/configuration.json @@ -14,6 +14,10 @@ { "name": ".djlintrc", "value": "\"ignore\": \"H014,H015\"" + }, + { + "name": "cli", + "value": "--ignore \"H014,H015\"" } ], "tags": ["linter"] @@ -34,6 +38,10 @@ { "name": ".djlintrc", "value": "\"include\": \"H014,H015\"" + }, + { + "name": "cli", + "value": "--include \"H014,H015\"" } ] }, @@ -53,6 +61,10 @@ { "name": ".djlintrc", "value": "\"extension\": \"html.dj\"" + }, + { + "name": "cli", + "value": "--extension \"html.dj\"\n# or\n-e \"html.dj\"" } ] }, @@ -72,6 +84,10 @@ { "name": ".djlintrc", "value": "\"custom_blocks\": \"toc,example\"" + }, + { + "name": "cli", + "value": "--custom-blocks \"toc,example\"" } ] }, @@ -101,9 +117,9 @@ { "name": "custom_html", "description": { - "en": "Use to indent custom HTML tags. For example `` or `` or ``", - "ru": "Используется для отступа пользовательских HTML-тегов. Например, `` или `` или ``.", - "fr": "Permet d'indenter les balises HTML personnalisées. Par exemple, `` ou `` ou ``." + "en": "Use to indent custom HTML tags. For example `` or `` or ``", + "ru": "Используется для отступа пользовательских HTML-тегов. Например, `` или `` или ``.", + "fr": "Permet d'indenter les balises HTML personnalisées. Par exemple, `` ou `` ou ``." }, "tags": ["formatter"], "usage": [ @@ -114,6 +130,10 @@ { "name": ".djlintrc", "value": "\"custom_html\": \"mjml,simple-greeting,mj-\\w+\"" + }, + { + "name": "cli", + "value": "--custom_html \"mjml,simple-greeting,mj-\\\\w+\"" } ] }, @@ -133,6 +153,10 @@ { "name": ".djlintrc", "value": "\"indent\": \"3\"" + }, + { + "name": "cli", + "value": "--indent 3" } ] }, @@ -152,6 +176,10 @@ { "name": ".djlintrc", "value": "\"exclude\": \".venv,venv,.tox,.eggs,...\"" + }, + { + "name": "cli", + "value": "--exclude \".venv,venv,.tox,.eggs,...\"" } ] }, @@ -171,6 +199,10 @@ { "name": ".djlintrc", "value": "\"extend_exclude\": \".custom\"" + }, + { + "name": "cli", + "value": "--extend-exclude \".custom\"" } ] }, @@ -190,6 +222,10 @@ { "name": ".djlintrc", "value": "\"blank_line_after_tag\": \"load,extends,include\"" + }, + { + "name": "cli", + "value": "--blank-line-after-tag \"load,extends,include\"" } ] }, @@ -209,6 +245,10 @@ { "name": ".djlintrc", "value": "\"blank_line_before_tag\": \"load,extends,include\"" + }, + { + "name": "cli", + "value": "--blank-line-before-tag \"load,extends,include\"" } ] }, @@ -228,6 +268,10 @@ { "name": ".djlintrc", "value": "\"profile\": \"django\"" + }, + { + "name": "cli", + "value": "--profile \"django\"" } ] }, @@ -246,7 +290,11 @@ }, { "name": ".djlintrc", - "value": "\"require_pragma\": \"true\"" + "value": "\"require_pragma\": true" + }, + { + "name": "cli", + "value": "--require_pragma" } ] }, @@ -266,6 +314,10 @@ { "name": ".djlintrc", "value": "\"max_line_length\": \"120\"" + }, + { + "name": "cli", + "value": "--max_line_length 120" } ] }, @@ -285,6 +337,10 @@ { "name": ".djlintrc", "value": "\"max_attribute_length\": \"10\"" + }, + { + "name": "cli", + "value": "--max-attribute-length 10" } ] }, @@ -299,11 +355,15 @@ "usage": [ { "name": "pyproject.toml", - "value": "use_gitignore=True" + "value": "use_gitignore=true" }, { "name": ".djlintrc", - "value": "\"use_gitignore\": \"True\"" + "value": "\"use_gitignore\": true" + }, + { + "name": "cli", + "value": "--use_gitignore" } ] }, @@ -322,7 +382,11 @@ }, { "name": ".djlintrc", - "value": "\"format_attribute_template_tags\": \"true\"" + "value": "\"format_attribute_template_tags\": true" + }, + { + "name": "cli", + "value": "--format-attribute-template-tags" } ] }, @@ -342,6 +406,10 @@ { "name": ".djlintrc", "value": "\"linter_output_format\": \"{filename}:{line}: {code} {message} {match}\"" + }, + { + "name": "cli", + "value": "--linter_output_format \"{filename}:{line}: {code} {message} {match}\"" } ] }, @@ -361,6 +429,10 @@ { "name": ".djlintrc", "value": "\"preserve_leading_space\": true" + }, + { + "name": "cli", + "value": "--preserve_leading_space" } ] }, @@ -380,6 +452,10 @@ { "name": ".djlintrc", "value": "\"preserve_blank_lines\": true" + }, + { + "name": "cli", + "value": "--preserve_blank_lines" } ] }, @@ -399,6 +475,10 @@ { "name": ".djlintrc", "value": "\"per-file-ignores\": {\n \"file.html\": \"H026,H025\",\n \"file_two.html\":\"H001\"\n }" + }, + { + "name": "cli", + "value": "--per-file-ignores \"file.html\" \"H026,H025\" --per-file-ignores \"file_two.html\" \"H001\"" } ] }, @@ -418,6 +498,10 @@ { "name": ".djlintrc", "value": "\"format_js\": true\n\"js\": {\n \"indent_size\": 5\n }" + }, + { + "name": "cli", + "value": "--format-js --indent-js 5" } ] }, @@ -437,6 +521,10 @@ { "name": ".djlintrc", "value": "\"format_css\": true\n\"css\": {\n \"indent_size\": 5\n }" + }, + { + "name": "cli", + "value": "--format-css --indent-css 5" } ] }, @@ -455,7 +543,11 @@ }, { "name": ".djlintrc", - "value": "\"files\": [\n \"index.html\"\n }" + "value": "\"files\": [\n \"index.html\"\n]" + }, + { + "name": "cli", + "value": "index.html" } ] }, @@ -470,11 +562,15 @@ "usage": [ { "name": "pyproject.toml", - "value": "[tool.djlint]\nignore-case=true\n" + "value": "[tool.djlint]\nignore_case=true\n" }, { "name": ".djlintrc", "value": "\"ignore_case\": true" + }, + { + "name": "cli", + "value": "--ignore_case" } ] } diff --git a/docs/src/_utils/scripts.11ty.js b/docs/src/_utils/scripts.11ty.js index 77b626f8b..907289ca0 100644 --- a/docs/src/_utils/scripts.11ty.js +++ b/docs/src/_utils/scripts.11ty.js @@ -14,11 +14,7 @@ module.exports = class { async render() { await esbuild.build({ entryPoints: ['src/static/js/hamburger.js'], - inject: [ - './src/static/js/animate.js', - './src/static/js/modal.js', - './src/static/js/tabs.js', - ], + inject: ['./src/static/js/animate.js', './src/static/js/modal.js'], bundle: true, minify: true, outfile: `_site/static/js/${generateContentHash( diff --git a/docs/src/docs/configuration.md b/docs/src/docs/configuration.md index e837a14b3..9e44c3d2c 100644 --- a/docs/src/docs/configuration.md +++ b/docs/src/docs/configuration.md @@ -90,7 +90,7 @@ document.querySelector('#filter').addEventListener('input', (event) => { {% for flag in option.usage %} -
  • {{ flag.name }}
  • +
  • {{ flag.name }}
  • {% endfor %} @@ -99,7 +99,7 @@ document.querySelector('#filter').addEventListener('input', (event) => {
    {% for flag in option.usage %} -
    +
    ```{% if flag.name == "pyproject.toml" %}toml{% else %}json{% endif %} {{ flag.value | safe }} @@ -113,3 +113,33 @@ document.querySelector('#filter').addEventListener('input', (event) => { {% endfor %} + + diff --git a/docs/src/fr/docs/configuration.md b/docs/src/fr/docs/configuration.md index e45dceef5..6f070487c 100644 --- a/docs/src/fr/docs/configuration.md +++ b/docs/src/fr/docs/configuration.md @@ -89,7 +89,7 @@ document.querySelector('#filter').addEventListener('input', (event) => { {% for flag in option.usage %} -
  • {{ flag.name }}
  • +
  • {{ flag.name }}
  • {% endfor %} @@ -98,7 +98,7 @@ document.querySelector('#filter').addEventListener('input', (event) => {
    {% for flag in option.usage %} -
    +
    ```{% if flag.name == "pyproject.toml" %}toml{% else %}json{% endif %} {{ flag.value | safe }} @@ -112,3 +112,33 @@ document.querySelector('#filter').addEventListener('input', (event) => { {% endfor %} + + diff --git a/docs/src/ru/docs/configuration.md b/docs/src/ru/docs/configuration.md index b46668c0a..2877fb784 100644 --- a/docs/src/ru/docs/configuration.md +++ b/docs/src/ru/docs/configuration.md @@ -87,7 +87,7 @@ document.querySelector('#filter').addEventListener('input', (event) => { {% for flag in option.usage %} -
  • {{ flag.name }}
  • +
  • {{ flag.name }}
  • {% endfor %} @@ -96,7 +96,7 @@ document.querySelector('#filter').addEventListener('input', (event) => {
    {% for flag in option.usage %} -
    +
    ```{% if flag.name == "pyproject.toml" %}toml{% else %}json{% endif %} {{ flag.value | safe }} @@ -110,3 +110,33 @@ document.querySelector('#filter').addEventListener('input', (event) => { {% endfor %} + + diff --git a/docs/src/static/js/tabs.js b/docs/src/static/js/tabs.js deleted file mode 100644 index 128f1a998..000000000 --- a/docs/src/static/js/tabs.js +++ /dev/null @@ -1,34 +0,0 @@ -document.addEventListener('click', function (e) { - if ( - e.target.closest('.tabs li a') && - e.target.closest('.tabs li a').hasAttribute('tab') - ) { - console.log('tab click'); - - // change active tab button - var tabLinks = e.target.closest('.tabs').querySelectorAll('li.is-active'); - - for (var i = 0; i < tabLinks.length; i++) { - tabLinks[i].classList.remove('is-active'); - } - - e.target.closest('li').classList.add('is-active'); - - // change active tab - - // find container with tab - var tabContainer = document - .querySelector('.tab-container .tab#' + e.target.getAttribute('tab')) - .closest('.tab-container'); - - var tabs = tabContainer.querySelectorAll('.tab.is-active'); - - for (var i = 0; i < tabs.length; i++) { - tabs[i].classList.remove('is-active'); - } - - tabContainer - .querySelector('.tab#' + e.target.getAttribute('tab')) - .classList.add('is-active'); - } -}); diff --git a/src/djlint/__init__.py b/src/djlint/__init__.py index 690705e12..e25c946c9 100644 --- a/src/djlint/__init__.py +++ b/src/djlint/__init__.py @@ -7,7 +7,7 @@ from concurrent.futures import ProcessPoolExecutor, as_completed from functools import partial from pathlib import Path -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Tuple import click from click import echo @@ -145,6 +145,83 @@ default="", help="Comma list of template blocks to not indent.", ) +@click.option( + "--blank-line-after-tag", + type=str, + default="", + help="Add an additional blank line after {% ... %} tag groups.", +) +@click.option( + "--blank-line-before-tag", + type=str, + default="", + help="Add an additional blank line before {% ... %} tag groups.", +) +@click.option( + "--custom-blocks", + type=str, + default="", + help="Indent custom template blocks. For example {% toc %}...{% endtoc %}", +) +@click.option( + "--custom-html", + type=str, + default="", + help="Indent custom HTML tags. For example ", +) +@click.option( + "--exclude", + type=str, + default="", + help="Override the default exclude paths.", +) +@click.option( + "--extend-exclude", + type=str, + default="", + help="Add additional paths to the default exclude.", +) +@click.option( + "--linter-output-format", + type=str, + default="", + help="Customize order of linter output message.", +) +@click.option( + "--max-line-length", + type=int, + help="Max line length. [default: 120]", + show_default=False, +) +@click.option( + "--max-attribute-length", + type=int, + help="Max attribute length. [default: 70]", + show_default=False, +) +@click.option( + "--format-attribute-template-tags", + is_flag=True, + help="Attempt to format template syntax inside of tag attributes.", +) +@click.option( + "--per-file-ignores", + type=(str, str), + multiple=True, + help="Ignore linter rules on a per-file basis.", +) +@click.option( + "--indent-css", + type=int, + help="Set CSS indent level.", + show_default=False, +) +@click.option( + "--indent-js", + type=int, + help="Set JS indent level.", + show_default=False, +) @colorama_text(autoreset=True) def main( src: List[str], @@ -168,6 +245,19 @@ def main( include: str, ignore_case: bool, ignore_blocks: str, + blank_line_after_tag: str, + blank_line_before_tag: str, + custom_blocks: str, + custom_html: str, + exclude: str, + extend_exclude: str, + linter_output_format: str, + max_line_length: Optional[int], + max_attribute_length: Optional[int], + format_attribute_template_tags: bool, + per_file_ignores: Optional[List[Tuple[str, str]]], + indent_css: Optional[int], + indent_js: Optional[int], ) -> None: """djLint · HTML template linter and formatter.""" config = Config( @@ -192,6 +282,19 @@ def main( include=include, ignore_case=ignore_case, ignore_blocks=ignore_blocks, + blank_line_after_tag=blank_line_after_tag, + blank_line_before_tag=blank_line_before_tag, + custom_blocks=custom_blocks, + custom_html=custom_html, + exclude=exclude, + extend_exclude=extend_exclude, + linter_output_format=linter_output_format, + max_line_length=max_line_length, + max_attribute_length=max_attribute_length, + format_attribute_template_tags=format_attribute_template_tags, + per_file_ignores=per_file_ignores, + indent_css=indent_css, + indent_js=indent_js, ) temp_file = None diff --git a/src/djlint/settings.py b/src/djlint/settings.py index 91c3d449c..4a3c1a09c 100644 --- a/src/djlint/settings.py +++ b/src/djlint/settings.py @@ -8,7 +8,7 @@ ## get pyproject.toml settings from pathlib import Path -from typing import Dict, List, Optional, Union +from typing import Dict, List, Optional, Tuple, Union import yaml from click import echo @@ -184,7 +184,7 @@ def build_custom_blocks(custom_blocks: Union[str, None]) -> Optional[str]: # need to also do "end" open_tags = [x.strip() for x in custom_blocks.split(",")] close_tags = ["end" + x.strip() for x in custom_blocks.split(",")] - return "|" + "|".join(list(set(open_tags + close_tags))) + return "|" + "|".join(sorted(set(open_tags + close_tags))) return None @@ -194,7 +194,7 @@ def build_ignore_blocks(ignore_blocks: Union[str, None]) -> Optional[str]: # need to also do "end" open_tags = [x.strip() + r"\b" for x in ignore_blocks.split(",")] close_tags = ["end" + x.strip() + r"\b" for x in ignore_blocks.split(",")] - return "|".join(list(set(open_tags + close_tags))) + return "|".join(sorted(set(open_tags + close_tags))) return None @@ -232,6 +232,18 @@ def __init__( ignore_case: bool = False, ignore_blocks: str = "", custom_blocks: str = "", + blank_line_after_tag: str = "", + blank_line_before_tag: str = "", + custom_html: str = "", + exclude: str = "", + extend_exclude: str = "", + linter_output_format: str = "", + max_line_length: Optional[int] = None, + max_attribute_length: Optional[int] = None, + format_attribute_template_tags: bool = False, + per_file_ignores: Optional[List[Tuple[str, str]]] = None, + indent_css: Optional[int] = None, + indent_js: Optional[int] = None, ): self.reformat = reformat self.check = check @@ -264,11 +276,12 @@ def __init__( ) self.custom_html: str = str( - build_custom_html(djlint_settings.get("custom_html")) or "" + build_custom_html(custom_html or djlint_settings.get("custom_html")) or "" ) - self.format_attribute_template_tags: bool = djlint_settings.get( - "format_attribute_template_tags", False + self.format_attribute_template_tags: bool = ( + format_attribute_template_tags + or djlint_settings.get("format_attribute_template_tags", False) ) self.preserve_leading_space: bool = ( @@ -285,8 +298,13 @@ def __init__( self.format_js: bool = format_js or djlint_settings.get("format_js", False) - self.js_config = djlint_settings.get("js") - self.css_config = djlint_settings.get("css") + self.js_config = ( + {"indent_size": indent_js} if indent_js else djlint_settings.get("js") + ) + + self.css_config = ( + {"indent_size": indent_css} if indent_css else djlint_settings.get("css") + ) self.format_css: bool = format_css or djlint_settings.get("format_css", False) @@ -319,7 +337,7 @@ def __init__( profile or djlint_settings.get("profile", "all") ).lower() - self.linter_output_format: str = djlint_settings.get( + self.linter_output_format: str = linter_output_format or djlint_settings.get( "linter_output_format", "{code} {line} {message} {match}" ) @@ -360,7 +378,7 @@ def __init__( + f"Error: Invalid pyproject.toml indent value {djlint_settings['indent']}" ) indent = default_indent - self.indent: str = indent * " " + self.indent: str = int(indent) * " " default_exclude: str = r""" \.venv @@ -383,26 +401,30 @@ def __init__( | __pypackages__ """ - self.exclude: str = djlint_settings.get("exclude", default_exclude) + self.exclude: str = exclude or djlint_settings.get("exclude", default_exclude) - extend_exclude: str = djlint_settings.get("extend_exclude", "") + extend_exclude = extend_exclude or djlint_settings.get("extend_exclude", "") if extend_exclude: self.exclude += r" | " + r" | ".join( x.strip() for x in extend_exclude.split(",") ) - self.per_file_ignores = djlint_settings.get("per-file-ignores", {}) + self.per_file_ignores = ( + (dict((x, y) for x, y in per_file_ignores)) + if per_file_ignores + else djlint_settings.get("per-file-ignores", {}) + ) # add blank line after load tags - self.blank_line_after_tag: Optional[str] = djlint_settings.get( - "blank_line_after_tag", None - ) + self.blank_line_after_tag: Optional[ + str + ] = blank_line_after_tag or djlint_settings.get("blank_line_after_tag", None) # add blank line before load tags - self.blank_line_before_tag: Optional[str] = djlint_settings.get( - "blank_line_before_tag", None - ) + self.blank_line_before_tag: Optional[ + str + ] = blank_line_before_tag or djlint_settings.get("blank_line_before_tag", None) # contents of tags will not be formatted self.ignored_block_opening: str = r""" @@ -511,7 +533,7 @@ def __init__( self.max_line_length = 120 try: - self.max_line_length = int( + self.max_line_length = max_line_length or int( djlint_settings.get("max_line_length", self.max_line_length) ) except ValueError: @@ -523,7 +545,7 @@ def __init__( self.max_attribute_length = 70 try: - self.max_attribute_length = int( + self.max_attribute_length = max_attribute_length or int( djlint_settings.get("max_attribute_length", self.max_attribute_length) ) except ValueError: diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 000000000..2f40b6b5b --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,71 @@ +"""Test for cli inputs. + +poetry run pytest tests/test_cli.py +""" +from click.testing import CliRunner + +from src.djlint import main as djlint + + +def test_cli(runner: CliRunner) -> None: + # missing options: + result = runner.invoke( + djlint, + [ + "-", + "--check", + "--blank-line-after-tag", + "p", + "--blank-line-before-tag", + "p", + "--custom-blocks", + "toc", + "--custom-html", + "asdf", + "--exclude", + ".asdf", + "--extend-exclude", + ".asdf", + "--extension", + "html.dj", + "--format-attribute-template-tags", + "--format-css", + "--format-js", + "--ignore", + "H014,H015", + "--ignore-blocks", + "raw", + "--ignore-case", + "--include", + "H014", + "--indent", + "4", + "--linter-output-format", + "{code}", + "--max-attribute-length", + "9", + "--max-line-length", + "100", + "--preserve-blank-lines", + "--preserve-leading-space", + "--profile", + "django", + "--require-pragma", + "--use-gitignore", + "--per-file-ignores", + "test.html", + "H014", + "--per-file-ignores", + "test2.html", + "H015", + "--indent-css", + "4", + "--indent-js", + "4", + ], + input="
    \n", + ) + + print(result.output) + + assert result.exit_code == 0 diff --git a/tests/test_config/test_blank_line_after_tag.py b/tests/test_config/test_blank_line_after_tag.py new file mode 100644 index 000000000..368cfa715 --- /dev/null +++ b/tests/test_config/test_blank_line_after_tag.py @@ -0,0 +1,135 @@ +"""Test for blank line after tag. + +--blank-line-after-tag 'include,load' + +poetry run pytest tests/test_config/test_blank_line_after_tag.py +""" +import pytest + +from src.djlint.reformat import formatter +from tests.conftest import config_builder, printer + +test_data = [ + pytest.param( + ( + '{% extends "nothing.html" %}{% load stuff %}{% load stuff 2 %}{% include "html_two.html" %}
    ' + ), + ( + '{% extends "nothing.html" %}\n' + "\n" + "{% load stuff %}\n" + "{% load stuff 2 %}\n" + "\n" + '{% include "html_two.html" %}\n' + "\n" + "
    \n" + ), + ({"blank_line_after_tag": "include,load, extends"}), + id="one", + ), + pytest.param( + ( + '
    \n' + '
    \n' + '
    \n' + ' {% include "pages/task/details_source.html.j2" %}\n' + "\n" + "
    \n" + "
    \n" + "
    " + ), + ( + '
    \n' + '
    \n' + '
    \n' + ' {% include "pages/task/details_source.html.j2" %}\n' + "\n" + "
    \n" + "
    \n" + "
    \n" + ), + ({"blank_line_after_tag": "include"}), + id="blank_nested", + ), + pytest.param( + ("{% block this %}\n" "{% load i18n %}\n" "{% endblock this %}"), + ("{% block this %}\n" " {% load i18n %}\n" "\n" "{% endblock this %}\n"), + ({"blank_line_after_tag": "endblock , junk,load "}), + id="nested_indent", + ), + pytest.param( + ( + "{% block include %}\n" + " {# {% include 'common/sticky-topbar-hidden-nav.html' %}#}\n" + "{% endblock %}\n" + ), + ( + "{% block include %}\n" + " {# {% include 'common/sticky-topbar-hidden-nav.html' %}#}\n" + "{% endblock %}\n" + ), + ({"blank_line_after_tag": "load, extends,endblock"}), + id="test inside comment", + ), + pytest.param( + ( + "{% blocktrans %}my words{% endblocktrans %}\n" + "{% block body %}\n" + "
    \n" + "{% endblock body %}\n" + "\n" + "{% block js %}{% endblock %}" + ), + ( + "{% blocktrans %}my words{% endblocktrans %}\n" + "{% block body %}\n" + "
    \n" + "{% endblock body %}\n" + "\n" + "{% block js %}{% endblock %}\n" + ), + ({"blank_line_after_tag": "endblock"}), + id="endblock is not endblocktrans", + ), + pytest.param( + ("{% extends nothing %}\n" "\n" "
    \n"), + ("{% extends nothing %}\n" "\n" "
    \n"), + ({"blank_line_after_tag": "load, extends", "preserve_blank_lines": True}), + id="option should work with preserve blank lines", + ), + pytest.param( + ( + "{% block %}stuff{% endblock %}\n" + "\n" + "{% block %}stuff{% endblock %}\n" + "\n" + ), + ("{% block %}stuff{% endblock %}\n" "\n" "{% block %}stuff{% endblock %}\n"), + ({"blank_line_after_tag": "load, extends, include ,endblock "}), + id="double block", + ), + pytest.param( + ( + '{% include "pages/task/details/data_source.html.j2" %}\n' + '{% include "pages/task/details/query_location.html.j2" %}\n' + '{% include "pages/task/details/processing.html.j2" %}\n' + '{% include "pages/task/details/destination.html.j2" %}\n' + ), + ( + '{% include "pages/task/details/data_source.html.j2" %}\n' + '{% include "pages/task/details/query_location.html.j2" %}\n' + '{% include "pages/task/details/processing.html.j2" %}\n' + '{% include "pages/task/details/destination.html.j2" %}\n' + ), + ({"blank_line_after_tag": " include ,endblock "}), + id="test multiple", + ), +] + + +@pytest.mark.parametrize(("source", "expected", "args"), test_data) +def test_base(source, expected, args): + output = formatter(config_builder(args), source) + + printer(expected, source, output) + assert expected == output diff --git a/tests/test_config/test_blank_line_before_tag.py b/tests/test_config/test_blank_line_before_tag.py new file mode 100644 index 000000000..97c7a412b --- /dev/null +++ b/tests/test_config/test_blank_line_before_tag.py @@ -0,0 +1,141 @@ +"""Test for blank line before tag. + +--blank-line-before-tag 'include,load' + +poetry run pytest tests/test_config/test_blank_line_before_tag.py +""" +import pytest + +from src.djlint.reformat import formatter +from tests.conftest import config_builder, printer + +test_data = [ + pytest.param( + ( + '{% extends "nothing.html" %}{% load stuff %}{% load stuff 2 %}{% include "html_two.html" %}
    ' + ), + ( + '{% extends "nothing.html" %}\n' + "\n" + "{% load stuff %}\n" + "{% load stuff 2 %}\n" + "\n" + '{% include "html_two.html" %}\n' + "
    \n" + ), + ({"blank_line_before_tag": "include,load, extends"}), + id="one", + ), + pytest.param( + ( + '
    \n' + '
    \n' + '
    \n' + ' {% include "pages/task/details_source.html.j2" %}\n' + "\n" + "
    \n" + "
    \n" + "
    " + ), + ( + '
    \n' + '
    \n' + '
    \n' + "\n" + ' {% include "pages/task/details_source.html.j2" %}\n' + "
    \n" + "
    \n" + "
    \n" + ), + ({"blank_line_before_tag": "include"}), + id="blank_nested", + ), + pytest.param( + ("{% block this %}\n" "{% load i18n %}\n" "{% endblock this %}"), + ( + "{% block this %}\n" + "\n" + " {% load i18n %}\n" + "\n" + "{% endblock this %}\n" + ), + ({"blank_line_before_tag": "endblock , junk,load "}), + id="nested_indent", + ), + pytest.param( + ( + "{% block include %}\n" + " {# {% include 'common/sticky-topbar-hidden-nav.html' %}#}\n" + "{% endblock %}\n" + ), + ( + "{% block include %}\n" + " {# {% include 'common/sticky-topbar-hidden-nav.html' %}#}\n" + "\n" + "{% endblock %}\n" + ), + ({"blank_line_before_tag": "load, extends,endblock"}), + id="test inside comment", + ), + pytest.param( + ( + "{% blocktrans %}my words{% endblocktrans %}\n" + "{% block body %}\n" + "
    \n" + "{% endblock body %}\n" + "\n" + "{% block js %}{% endblock %}" + ), + ( + "{% blocktrans %}my words{% endblocktrans %}\n" + "{% block body %}\n" + "
    \n" + "\n" + "{% endblock body %}\n" + "{% block js %}{% endblock %}\n" + ), + ({"blank_line_before_tag": "endblock"}), + id="endblock is not endblocktrans", + ), + pytest.param( + ("{% extends nothing %}\n" "\n" "
    \n"), + ("{% extends nothing %}\n" "\n" "
    \n"), + ({"blank_line_before_tag": "load, extends", "preserve_blank_lines": True}), + id="option should work with preserve blank lines", + ), + pytest.param( + ( + "{% block %}stuff{% endblock %}\n" + "\n" + "{% block %}stuff{% endblock %}\n" + "\n" + ), + ("{% block %}stuff{% endblock %}\n" "{% block %}stuff{% endblock %}\n"), + ({"blank_line_before_tag": "load, extends, include ,endblock "}), + id="double block", + ), + pytest.param( + ( + '{% include "pages/task/details/data_source.html.j2" %}\n' + '{% include "pages/task/details/query_location.html.j2" %}\n' + '{% include "pages/task/details/processing.html.j2" %}\n' + '{% include "pages/task/details/destination.html.j2" %}\n' + ), + ( + '{% include "pages/task/details/data_source.html.j2" %}\n' + '{% include "pages/task/details/query_location.html.j2" %}\n' + '{% include "pages/task/details/processing.html.j2" %}\n' + '{% include "pages/task/details/destination.html.j2" %}\n' + ), + ({"blank_line_before_tag": " include ,endblock "}), + id="test multiple", + ), +] + + +@pytest.mark.parametrize(("source", "expected", "args"), test_data) +def test_base(source, expected, args): + output = formatter(config_builder(args), source) + + printer(expected, source, output) + assert expected == output diff --git a/tests/test_config/test_blank_lines_after_tag/html.html b/tests/test_config/test_blank_lines_after_tag/html.html deleted file mode 100644 index 0cf231edb..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "nothing.html" %}{% load stuff %}{% load stuff 2 %}{% include "html_two.html" %}
    diff --git a/tests/test_config/test_blank_lines_after_tag/html_eight.html b/tests/test_config/test_blank_lines_after_tag/html_eight.html deleted file mode 100644 index fe01ca0ad..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_eight.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends nothing %} - -
    diff --git a/tests/test_config/test_blank_lines_after_tag/html_five.html b/tests/test_config/test_blank_lines_after_tag/html_five.html deleted file mode 100644 index 0bf4a4bc9..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_five.html +++ /dev/null @@ -1,6 +0,0 @@ - - - {% include "common/pdfs/partials/display_quality_improvements.html" %} - - - diff --git a/tests/test_config/test_blank_lines_after_tag/html_four.html b/tests/test_config/test_blank_lines_after_tag/html_four.html deleted file mode 100644 index f115c2f0f..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_four.html +++ /dev/null @@ -1,3 +0,0 @@ -{% block this %} -{% load i18n %} -{% endblock this %} diff --git a/tests/test_config/test_blank_lines_after_tag/html_nine.html b/tests/test_config/test_blank_lines_after_tag/html_nine.html deleted file mode 100644 index 0d75ed62f..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_nine.html +++ /dev/null @@ -1,3 +0,0 @@ -{% block %}stuff{% endblock %} - -{% block %}stuff{% endblock %} diff --git a/tests/test_config/test_blank_lines_after_tag/html_seven.html b/tests/test_config/test_blank_lines_after_tag/html_seven.html deleted file mode 100644 index 685d0ae01..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_seven.html +++ /dev/null @@ -1,6 +0,0 @@ -{% blocktrans %}my words{% endblocktrans %} -{% block body %} -
    -{% endblock body %} - -{% block js %}{% endblock %} diff --git a/tests/test_config/test_blank_lines_after_tag/html_six.html b/tests/test_config/test_blank_lines_after_tag/html_six.html deleted file mode 100644 index 2b446442f..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_six.html +++ /dev/null @@ -1,3 +0,0 @@ -{% block include %} - {# {% include 'common/sticky-topbar-hidden-nav.html' %}#} -{% endblock %} diff --git a/tests/test_config/test_blank_lines_after_tag/html_ten.html b/tests/test_config/test_blank_lines_after_tag/html_ten.html deleted file mode 100644 index 408e91595..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_ten.html +++ /dev/null @@ -1,4 +0,0 @@ -{% include "pages/task/details/data_source.html.j2" %} -{% include "pages/task/details/query_location.html.j2" %} -{% include "pages/task/details/processing.html.j2" %} -{% include "pages/task/details/destination.html.j2" %} diff --git a/tests/test_config/test_blank_lines_after_tag/html_three.html b/tests/test_config/test_blank_lines_after_tag/html_three.html deleted file mode 100644 index 2448f44e9..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_three.html +++ /dev/null @@ -1,8 +0,0 @@ -
    -
    -
    - {% include "pages/task/details_source.html.j2" %} - -
    -
    -
    diff --git a/tests/test_config/test_blank_lines_after_tag/html_two.html b/tests/test_config/test_blank_lines_after_tag/html_two.html deleted file mode 100644 index f887fcbed..000000000 --- a/tests/test_config/test_blank_lines_after_tag/html_two.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load stuff %} -
    diff --git a/tests/test_config/test_blank_lines_after_tag/pyproject.toml b/tests/test_config/test_blank_lines_after_tag/pyproject.toml deleted file mode 100644 index 0796ce12b..000000000 --- a/tests/test_config/test_blank_lines_after_tag/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[tool] -[tool.djlint] -blank_line_after_tag = "load, extends, include ,endblock " diff --git a/tests/test_config/test_blank_lines_after_tag/test_config.py b/tests/test_config/test_blank_lines_after_tag/test_config.py deleted file mode 100644 index e7bd911b1..000000000 --- a/tests/test_config/test_blank_lines_after_tag/test_config.py +++ /dev/null @@ -1,144 +0,0 @@ -"""Djlint tests specific to pyproject.toml configuration. - -run:: - - pytest tests/test_config/test_blank_lines_after_tag/test_config.py --cov=src/djlint --cov-branch \ - --cov-report xml:coverage.xml --cov-report term-missing - -for a single test, run:: - - pytest tests/test_config/test_blank_lines_after_tag/test_config.py::test_blank_lines_after_tag_eight --cov=src/djlint \ - --cov-branch --cov-report xml:coverage.xml --cov-report term-missing - -""" -# pylint: disable=C0116 - -from click.testing import CliRunner - -from src.djlint import main as djlint - - -def test_blank_lines_after_tag(runner: CliRunner) -> None: - result = runner.invoke( - djlint, ["tests/test_config/test_blank_lines_after_tag/html.html", "--check"] - ) - assert ( - """+{% extends "nothing.html" %} -+ -+{% load stuff %} -+{% load stuff 2 %} -+ -+{% include "html_two.html" %} -+ -+
    """ - in result.output - ) - assert """1 file would be updated.""" in result.output - assert result.exit_code == 1 - - -def test_blank_lines_after_tag_two(runner: CliRunner) -> None: - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_after_tag/html_two.html", "--check"], - ) - assert ( - """ {% load stuff %} -+ -
    """ - in result.output - ) - assert """1 file would be updated.""" in result.output - assert result.exit_code == 1 - - -def test_blank_lines_after_tag_three(runner: CliRunner) -> None: - # check blocks that do not start on a newline - they should be left as is. - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_after_tag/html_three.html", "--check"], - ) - - assert """0 files would be updated.""" in result.output - assert result.exit_code == 0 - - -def test_blank_lines_after_tag_four(runner: CliRunner) -> None: - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_after_tag/html_four.html", "--check"], - ) - - assert result.exit_code == 1 - assert ( - """ {% block this %} --{% load i18n %} -+ {% load i18n %} -+ - {% endblock this %} -""" - in result.output - ) - - -def test_blank_lines_after_tag_five(runner: CliRunner) -> None: - # something perfect should stay perfect :) - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_after_tag/html_five.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_after_tag_six(runner: CliRunner) -> None: - # something perfect should stay perfect :) - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_after_tag/html_six.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_after_tag_seven(runner: CliRunner) -> None: - # make sure endblock doesn't pick up endblocktrans :) - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_after_tag/html_seven.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_after_tag_eight(runner: CliRunner) -> None: - # check that multiple blank lines are not added - result = runner.invoke( - djlint, - [ - "tests/test_config/test_blank_lines_after_tag/html_eight.html", - "--preserve-blank-lines", - "--check", - ], - ) - print(result.output) - assert result.exit_code == 0 - - -def test_blank_lines_after_tag_nine(runner: CliRunner) -> None: - result = runner.invoke( - djlint, - [ - "tests/test_config/test_blank_lines_after_tag/html_nine.html", - "--check", - ], - ) - assert result.exit_code == 0 - - -def test_blank_lines_after_tag_ten(runner: CliRunner) -> None: - result = runner.invoke( - djlint, - [ - "tests/test_config/test_blank_lines_after_tag/html_ten.html", - "--check", - ], - ) - assert result.exit_code == 0 diff --git a/tests/test_config/test_blank_lines_before_tag/html.html b/tests/test_config/test_blank_lines_before_tag/html.html deleted file mode 100644 index 0cf231edb..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "nothing.html" %}{% load stuff %}{% load stuff 2 %}{% include "html_two.html" %}
    diff --git a/tests/test_config/test_blank_lines_before_tag/html_eight.html b/tests/test_config/test_blank_lines_before_tag/html_eight.html deleted file mode 100644 index fe01ca0ad..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_eight.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends nothing %} - -
    diff --git a/tests/test_config/test_blank_lines_before_tag/html_five.html b/tests/test_config/test_blank_lines_before_tag/html_five.html deleted file mode 100644 index ae38524b3..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_five.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - {% include "common/pdfs/partials/display_quality_improvements.html" %} - - diff --git a/tests/test_config/test_blank_lines_before_tag/html_four.html b/tests/test_config/test_blank_lines_before_tag/html_four.html deleted file mode 100644 index f115c2f0f..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_four.html +++ /dev/null @@ -1,3 +0,0 @@ -{% block this %} -{% load i18n %} -{% endblock this %} diff --git a/tests/test_config/test_blank_lines_before_tag/html_seven.html b/tests/test_config/test_blank_lines_before_tag/html_seven.html deleted file mode 100644 index 41352a25c..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_seven.html +++ /dev/null @@ -1,6 +0,0 @@ -{% blocktrans %}my words{% endblocktrans %} -{% block body %} -
    - -{% endblock body %} -{% block js %}{% endblock %} diff --git a/tests/test_config/test_blank_lines_before_tag/html_six.html b/tests/test_config/test_blank_lines_before_tag/html_six.html deleted file mode 100644 index ede15b2bf..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_six.html +++ /dev/null @@ -1,4 +0,0 @@ -{% block include %} - {# {% include 'common/sticky-topbar-hidden-nav.html' %}#} - -{% endblock %} diff --git a/tests/test_config/test_blank_lines_before_tag/html_three.html b/tests/test_config/test_blank_lines_before_tag/html_three.html deleted file mode 100644 index fac20772d..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_three.html +++ /dev/null @@ -1,8 +0,0 @@ -
    -
    -
    - - {% include "pages/task/details_source.html.j2" %} -
    -
    -
    diff --git a/tests/test_config/test_blank_lines_before_tag/html_two.html b/tests/test_config/test_blank_lines_before_tag/html_two.html deleted file mode 100644 index f887fcbed..000000000 --- a/tests/test_config/test_blank_lines_before_tag/html_two.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load stuff %} -
    diff --git a/tests/test_config/test_blank_lines_before_tag/pyproject.toml b/tests/test_config/test_blank_lines_before_tag/pyproject.toml deleted file mode 100644 index fec3ea892..000000000 --- a/tests/test_config/test_blank_lines_before_tag/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[tool] -[tool.djlint] -blank_line_before_tag = "load, extends, include ,endblock " diff --git a/tests/test_config/test_blank_lines_before_tag/test_config.py b/tests/test_config/test_blank_lines_before_tag/test_config.py deleted file mode 100644 index 7ac1758b8..000000000 --- a/tests/test_config/test_blank_lines_before_tag/test_config.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Djlint tests specific to pyproject.toml configuration. - -run:: - - pytest tests/test_config/test_blank_lines_before_tag/test_config.py --cov=src/djlint --cov-branch \ - --cov-report xml:coverage.xml --cov-report term-missing - -for a single test, run:: - - pytest tests/test_config/test_blank_lines_before_tag/test_config.py::test_blank_lines_before_tag_four --cov=src/djlint \ - --cov-branch --cov-report xml:coverage.xml --cov-report term-missing - -""" -# pylint: disable=C0116 - -from click.testing import CliRunner - -from src.djlint import main as djlint - - -def test_blank_lines_before_tag(runner: CliRunner) -> None: - result = runner.invoke( - djlint, ["tests/test_config/test_blank_lines_before_tag/html.html", "--check"] - ) - - assert ( - """+{% extends "nothing.html" %} -+ -+{% load stuff %} -+{% load stuff 2 %} -+ -+{% include "html_two.html" %} -+
    """ - in result.output - ) - assert """1 file would be updated.""" in result.output - assert result.exit_code == 1 - - -def test_blank_lines_before_tag_two(runner: CliRunner) -> None: - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_before_tag/html_two.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_before_tag_three(runner: CliRunner) -> None: - # check blocks that do not start on a newline - they should be left as is. - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_before_tag/html_three.html", "--check"], - ) - - assert """0 files would be updated.""" in result.output - assert result.exit_code == 0 - - -def test_blank_lines_before_tag_four(runner: CliRunner) -> None: - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_before_tag/html_four.html", "--check"], - ) - - assert result.exit_code == 1 - print(result.output) - assert ( - """ {% block this %} --{% load i18n %} -+ -+ {% load i18n %} -+ - {% endblock this %} -""" - in result.output - ) - - -def test_blank_lines_before_tag_five(runner: CliRunner) -> None: - # something perfect should stay perfect :) - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_before_tag/html_five.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_before_tag_six(runner: CliRunner) -> None: - # something perfect should stay perfect :) - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_before_tag/html_six.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_before_tag_seven(runner: CliRunner) -> None: - # make sure endblock doesn't pick up endblocktrans :) - result = runner.invoke( - djlint, - ["tests/test_config/test_blank_lines_before_tag/html_seven.html", "--check"], - ) - assert result.exit_code == 0 - - -def test_blank_lines_before_tag_eight(runner: CliRunner) -> None: - # check that multiple blank lines are not added - result = runner.invoke( - djlint, - [ - "tests/test_config/test_blank_lines_before_tag/html_eight.html", - "--preserve-blank-lines", - "--check", - ], - ) - assert result.exit_code == 0 diff --git a/tests/test_config/test_custom_blocks.py b/tests/test_config/test_custom_blocks.py new file mode 100644 index 000000000..0c06633f1 --- /dev/null +++ b/tests/test_config/test_custom_blocks.py @@ -0,0 +1,40 @@ +"""Test for custom blocks. + +--custom-blocks 'toc' + +poetry run pytest tests/test_config/test_custom_blocks.py +""" +import pytest + +from src.djlint.reformat import formatter +from tests.conftest import config_builder, printer + +test_data = [ + pytest.param( + ( + "{% example stuff %}

    this is a very very long paragraph that does nothing except be a long paragraph asdfasdfasdfasdfasdf fasdf asdfasdfasdf

    {% endexample %}\n" + "\n" + "{% verylongexampletagthatiskindaneattolookat stuff%}{{ tag }}{% endverylongexampletagthatiskindaneattolookat %}" + ), + ( + "{% example stuff %}\n" + "

    \n" + " this is a very very long paragraph that does nothing except be a long paragraph asdfasdfasdfasdfasdf fasdf asdfasdfasdf\n" + "

    \n" + "{% endexample %}\n" + "{% verylongexampletagthatiskindaneattolookat stuff %}\n" + " {{ tag }}\n" + "{% endverylongexampletagthatiskindaneattolookat %}\n" + ), + ({"custom_blocks": "toc,example,verylongexampletagthatiskindaneattolookat"}), + id="one", + ), +] + + +@pytest.mark.parametrize(("source", "expected", "args"), test_data) +def test_base(source, expected, args): + output = formatter(config_builder(args), source) + + printer(expected, source, output) + assert expected == output diff --git a/tests/test_config/test_custom_html.py b/tests/test_config/test_custom_html.py new file mode 100644 index 000000000..6bed476cb --- /dev/null +++ b/tests/test_config/test_custom_html.py @@ -0,0 +1,45 @@ +"""Test for custom html. + +--custom-html 'dov' + +poetry run pytest tests/test_config/test_custom_html.py +""" +import pytest + +from src.djlint.reformat import formatter +from tests.conftest import config_builder, printer + +test_data = [ + pytest.param( + ("this is a email text"), + ( + "\n" + " \n" + " this is a email text\n" + " \n" + "\n" + ), + ({"custom_html": "mjml,mj-body"}), + id="with_flag", + ), + pytest.param( + ("this is a email text"), + ("this is a email text\n"), + (), + id="without_flag", + ), + pytest.param( + (""), + ("\n"), + ({"custom_html": "mjml,mj-body"}), + id="other tag", + ), +] + + +@pytest.mark.parametrize(("source", "expected", "args"), test_data) +def test_base(source, expected, args): + output = formatter(config_builder(args), source) + + printer(expected, source, output) + assert expected == output diff --git a/tests/test_config/test_custom_html/html.html b/tests/test_config/test_custom_html/html.html deleted file mode 100644 index a5a1acc7c..000000000 --- a/tests/test_config/test_custom_html/html.html +++ /dev/null @@ -1 +0,0 @@ -this is a email text diff --git a/tests/test_config/test_custom_html/pyproject.toml b/tests/test_config/test_custom_html/pyproject.toml deleted file mode 100644 index 8a60a8735..000000000 --- a/tests/test_config/test_custom_html/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[tool] -[tool.djlint] -custom_html = "mjml,mj-body" diff --git a/tests/test_config/test_custom_html/test_config.py b/tests/test_config/test_custom_html/test_config.py deleted file mode 100644 index 5047b28ec..000000000 --- a/tests/test_config/test_custom_html/test_config.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Djlint tests specific to pyproject.toml configuration. - -run:: - - pytest tests/test_config/test_custom_html/test_config.py --cov=src/djlint --cov-branch \ - --cov-report xml:coverage.xml --cov-report term-missing - -for a single test, run:: - - pytest tests/test_config.py::test_custom_html --cov=src/djlint \ - --cov-branch --cov-report xml:coverage.xml --cov-report term-missing - -""" -# pylint: disable=C0116 - -from typing import TextIO - -from click.testing import CliRunner - -from src.djlint import main as djlint -from tests.conftest import reformat - - -def test_custom_html(runner: CliRunner, tmp_file: TextIO) -> None: - result = runner.invoke( - djlint, ["tests/test_config/test_custom_html/html.html", "--check"] - ) - print(result.output) - assert ( - """-this is a email text -+ -+ -+ this is a email text -+ -+ -""" - in result.output - ) - assert result.exit_code == 1 - - # https://github.com/Riverside-Healthcare/djLint/issues/236 - output = reformat( - tmp_file, runner, b"\n" - ) - assert output.exit_code == 0 diff --git a/tests/test_config/test_custom_tags/html.html b/tests/test_config/test_custom_tags/html.html deleted file mode 100644 index 1ff4bd994..000000000 --- a/tests/test_config/test_custom_tags/html.html +++ /dev/null @@ -1,3 +0,0 @@ -{% example stuff %}

    this is a very very long paragraph that does nothing except be a long paragraph asdfasdfasdfasdfasdf fasdf asdfasdfasdf

    {% endexample %} - -{% verylongexampletagthatiskindaneattolookat stuff%}{{ tag }}{% endverylongexampletagthatiskindaneattolookat %} diff --git a/tests/test_config/test_custom_tags/pyproject.toml b/tests/test_config/test_custom_tags/pyproject.toml deleted file mode 100644 index 24e2e2664..000000000 --- a/tests/test_config/test_custom_tags/pyproject.toml +++ /dev/null @@ -1,3 +0,0 @@ -[tool] -[tool.djlint] -custom_blocks = "toc,example,verylongexampletagthatiskindaneattolookat" diff --git a/tests/test_config/test_custom_tags/test_config.py b/tests/test_config/test_custom_tags/test_config.py deleted file mode 100644 index 733026956..000000000 --- a/tests/test_config/test_custom_tags/test_config.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Djlint tests specific to pyproject.toml configuration. - -run:: - - pytest tests/test_config/test_custom_tags/test_config.py --cov=src/djlint --cov-branch \ - --cov-report xml:coverage.xml --cov-report term-missing - -for a single test, run:: - - pytest tests/test_config/test_custom_tags/test_config.py::test_custom_tags - -""" -# pylint: disable=C0116 - - -from click.testing import CliRunner - -from src.djlint import main as djlint - - -def test_custom_tags(runner: CliRunner) -> None: - result = runner.invoke( - djlint, ["tests/test_config/test_custom_tags/html.html", "--check"] - ) - - assert ( - """-{% example stuff %}

    this is a very very long paragraph that does nothing except be a long paragraph asdfasdfasdfasdfasdf fasdf asdfasdfasdf

    {% endexample %} -- --{% verylongexampletagthatiskindaneattolookat stuff%}{{ tag }}{% endverylongexampletagthatiskindaneattolookat %} -+{% example stuff %} -+

    -+ this is a very very long paragraph that does nothing except be a long paragraph asdfasdfasdfasdfasdf fasdf asdfasdfasdf -+

    -+{% endexample %} -+{% verylongexampletagthatiskindaneattolookat stuff %} -+ {{ tag }} -+{% endverylongexampletagthatiskindaneattolookat %} -""" - in result.output - ) - assert result.exit_code == 1 diff --git a/tests/test_config/test_djlintrc/.djlintrc b/tests/test_config/test_djlintrc/.djlintrc new file mode 100644 index 000000000..0edee3a2f --- /dev/null +++ b/tests/test_config/test_djlintrc/.djlintrc @@ -0,0 +1,38 @@ +{ + "blank_line_after_tag": "load,extends,include", + "blank_line_before_tag": "load,extends,include", + "custom_blocks": "toc,example", + "files": [ + "index.html" + ], + "custom_html": "mjml,simple-greeting,mj-\\w+", + "exclude": ".venv,venv,.tox,.eggs,...", + "extend_exclude": ".custom", + "extension": "html.dj", + "format_attribute_template_tags": true, + "format_css": true, + "css": { + "indent_size": 5 + }, + "format_js": true, + "js": { + "indent_size": 5 + }, + "ignore": "H014,H015", + "ignore_blocks": "raw,example", + "ignore_case": true, + "include": "H014,H015", + "indent": "3", + "linter_output_format": "{filename}:{line}: {code} {message} {match}", + "max_attribute_length": "10", + "max_line_length": "120", + "per-file-ignores": { + "file.html": "H026,H025", + "file_two.html":"H001" + }, + "preserve_blank_lines": true, + "preserve_leading_space": true, + "profile": "django", + "require_pragma": true, + "use_gitignore": true +} diff --git a/tests/test_config/test_blank_lines_after_tag/__init__.py b/tests/test_config/test_djlintrc/__init__.py similarity index 100% rename from tests/test_config/test_blank_lines_after_tag/__init__.py rename to tests/test_config/test_djlintrc/__init__.py diff --git a/tests/test_config/test_djlintrc/test_config.py b/tests/test_config/test_djlintrc/test_config.py new file mode 100644 index 000000000..772c7cad3 --- /dev/null +++ b/tests/test_config/test_djlintrc/test_config.py @@ -0,0 +1,44 @@ +"""Test djlintrc config. + +poetry run pytest tests/test_config/test_djlintrc + +""" +from pathlib import Path + +from src.djlint.settings import Config + + +def test_default() -> None: + config = Config(Path(__file__).parent / "blank.html") + + assert config.exclude == ".venv,venv,.tox,.eggs,... | .custom" + assert config.blank_line_after_tag == "load,extends,include" + assert config.blank_line_before_tag == "load,extends,include" + assert config.custom_blocks == "|endexample|endtoc|example|toc" + assert config.custom_html == r"|mjml|simple-greeting|mj-\w+" + assert config.extension == "html.dj" + assert config.files == ["index.html"] + assert config.format_attribute_template_tags is True + assert config.format_css is True + assert config.format_js is True + assert config.ignore == "H014,H015" + assert config.ignore_blocks == r"endexample\b|endraw\b|example\b|raw\b" + assert config.ignore_case is True + assert config.include == "H014,H015" + assert config.indent == 3 * " " + assert config.linter_output_format == "{filename}:{line}: {code} {message} {match}" + assert config.max_attribute_length == 10 + assert config.max_line_length == 120 + assert config.preserve_blank_lines is True + assert config.preserve_leading_space is True + assert config.profile == "django" + assert config.require_pragma is True + assert config.use_gitignore is True + + assert config.js_config == {"indent_size": 5} + assert config.css_config == {"indent_size": 5} + + assert config.per_file_ignores == { + "file.html": "H026,H025", + "file_two.html": "H001", + } diff --git a/tests/test_config/test_djlintrc_custom/.djlint-cust b/tests/test_config/test_djlintrc_custom/.djlint-cust new file mode 100644 index 000000000..d70f02d81 --- /dev/null +++ b/tests/test_config/test_djlintrc_custom/.djlint-cust @@ -0,0 +1,38 @@ +{ + "blank_line_after_tag": "load,extends,include", + "blank_line_before_tag": "load,extends,include", + "custom_blocks": "toc,example", + "files": [ + "index.html" + ], + "custom_html": "mjml,simple-greeting,mj-\\w+", + "exclude": ".venv,venv,.tox,.egg,...", + "extend_exclude": ".customs", + "extension": "html.dj", + "format_attribute_template_tags": true, + "format_css": true, + "css": { + "indent_size": 4 + }, + "format_js": true, + "js": { + "indent_size": 4 + }, + "ignore": "H014,H015", + "ignore_blocks": "raw,example", + "ignore_case": true, + "include": "H014,H015", + "indent": "4", + "linter_output_format": "{filename}:{line}: {code} {message} {match}", + "max_attribute_length": "10", + "max_line_length": "120", + "per-file-ignores": { + "file.html": "H026,H025", + "file_two.html":"H001" + }, + "preserve_blank_lines": true, + "preserve_leading_space": true, + "profile": "django", + "require_pragma": true, + "use_gitignore": true +} diff --git a/tests/test_config/test_djlintrc_custom/.djlintrc b/tests/test_config/test_djlintrc_custom/.djlintrc new file mode 100644 index 000000000..2c63c0851 --- /dev/null +++ b/tests/test_config/test_djlintrc_custom/.djlintrc @@ -0,0 +1,2 @@ +{ +} diff --git a/tests/test_config/test_blank_lines_before_tag/__init__.py b/tests/test_config/test_djlintrc_custom/__init__.py similarity index 100% rename from tests/test_config/test_blank_lines_before_tag/__init__.py rename to tests/test_config/test_djlintrc_custom/__init__.py diff --git a/tests/test_config/test_djlintrc_custom/test_config.py b/tests/test_config/test_djlintrc_custom/test_config.py new file mode 100644 index 000000000..8e065157b --- /dev/null +++ b/tests/test_config/test_djlintrc_custom/test_config.py @@ -0,0 +1,48 @@ +"""Test djlintrc custom config. + +poetry run pytest tests/test_config/test_djlintrc_custom + +""" +from pathlib import Path + +from src.djlint.settings import Config + + +def test_custom() -> None: + config = Config( + Path(__file__).parent / "blank.html", + configuration=Path(__file__).parent / ".djlint-cust", + ) + + print(config.exclude) + assert config.exclude == ".venv,venv,.tox,.egg,... | .customs" + assert config.blank_line_after_tag == "load,extends,include" + assert config.blank_line_before_tag == "load,extends,include" + assert config.custom_blocks == "|endexample|endtoc|example|toc" + assert config.custom_html == r"|mjml|simple-greeting|mj-\w+" + assert config.extension == "html.dj" + assert config.files == ["index.html"] + assert config.format_attribute_template_tags is True + assert config.format_css is True + assert config.format_js is True + assert config.ignore == "H014,H015" + assert config.ignore_blocks == r"endexample\b|endraw\b|example\b|raw\b" + assert config.ignore_case is True + assert config.include == "H014,H015" + assert config.indent == 4 * " " + assert config.linter_output_format == "{filename}:{line}: {code} {message} {match}" + assert config.max_attribute_length == 10 + assert config.max_line_length == 120 + assert config.preserve_blank_lines is True + assert config.preserve_leading_space is True + assert config.profile == "django" + assert config.require_pragma is True + assert config.use_gitignore is True + + assert config.js_config == {"indent_size": 4} + assert config.css_config == {"indent_size": 4} + + assert config.per_file_ignores == { + "file.html": "H026,H025", + "file_two.html": "H001", + } diff --git a/tests/test_config/test_format_attribute_template_tags.py b/tests/test_config/test_format_attribute_template_tags.py new file mode 100644 index 000000000..da33502ac --- /dev/null +++ b/tests/test_config/test_format_attribute_template_tags.py @@ -0,0 +1,280 @@ +"""Test for format attribute template tags. + +--format-attribute-template-tags + +poetry run pytest tests/test_config/test_format_attribute_template_tags.py +""" +import pytest + +from src.djlint.reformat import formatter +from tests.conftest import config_builder, printer + +test_data = [ + pytest.param( + ( + "\n" + '\n' + 'report image\n' + '\n' + ' \n' + ' \n' + " \n" + "\n" + '
    \n" + '\n' + "\n" + "{% block body %}\n" + '
    \n' + "
    \n" + "{% endblock body %}\n" + '\n" + '
    \n' + ), + ( + "\n" + '\n' + 'report image\n' + '\n' + ' \n' + ' \n' + " \n" + "\n" + '
    \n" + '\n' + "\n" + "{% block body %}\n" + '
    \n' + "
    \n" + "{% endblock body %}\n" + '\n" + '
    \n' + ), + ({"format_attribute_template_tags": True}), + id="one", + ), + pytest.param( + ( + '\n' + ), + ( + '\n' + ), + (), + id="no option", + ), + pytest.param( + ( + 'foo\n' + ), + ( + 'foo\n' + ), + (), + id="no option two", + ), + pytest.param( + ( + 'report image' + ), + ( + 'report image\n' + ), + (), + id="no option three", + ), + pytest.param( + ( + '' + ), + ( + '\n' + ), + (), + id="no option four", + ), + pytest.param( + ( + '
    \n' + ), + ( + '
    \n" + ), + (), + id="no option five", + ), + pytest.param( + ( + '' + ), + ( + '\n' + ), + (), + id="no option six", + ), + pytest.param( + ( + "\n" + ), + ( + "\n" + ), + (), + id="no option seven", + ), + pytest.param( + ( + '
    = 70 %}1{% elif value >= 60 %}2{% elif value >= 50 %}3{% else %}4{% endif %}>\n
    \n' + ), + (), + id="no option eight", + ), + pytest.param( + ( + "{% block body %}\n" + '
    \n' + "
    \n" + "{% endblock body %}\n" + ), + ( + "{% block body %}\n" + '
    \n' + "
    \n" + "{% endblock body %}\n" + ), + (), + id="no option nine", + ), + pytest.param( + ( + '