mirror of
https://github.com/Hopiu/djLint.git
synced 2026-05-11 23:23:10 +00:00
added rule H025, closes #58
This commit is contained in:
parent
569f9112ac
commit
b8562e463a
4 changed files with 71 additions and 17 deletions
|
|
@ -8,13 +8,14 @@ Next Release
|
|||
- Added rule H022 to find http links
|
||||
- Added rule H023 to find entity references
|
||||
- Added rule H024 to find type on scripts and styles
|
||||
- Added rule H025 to check for orphan tags. Thanks to https://stackoverflow.com/a/1736801/10265880
|
||||
- Improved attribute formatting
|
||||
- Updated ``blank_line_after_tag`` option to add newline regardless of location
|
||||
- Fixed django ``trans`` tag formatting
|
||||
- Added formatting for inline styles
|
||||
- Added formatting for template conditions inside attributes
|
||||
- Added srcset as possible url location in linter rules
|
||||
|
||||
- Special thanks to `jayvdb <https://github.com/jayvdb>`_
|
||||
0.5.3
|
||||
-----
|
||||
- Change stdout for ``--reformat/check`` options to only print new html when using stdin as the input
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""Djlint html linter."""
|
||||
import copy
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
|
|
@ -69,20 +70,59 @@ def lint_file(config: Config, this_file: Path) -> Dict:
|
|||
|
||||
for pattern in rule["patterns"]:
|
||||
|
||||
for match in re.finditer(
|
||||
re.compile(pattern, flags=build_flags(rule.get("flags", "re.DOTALL"))),
|
||||
html,
|
||||
):
|
||||
# rule H025 is a special case where the output must be an even num.
|
||||
if rule["name"] == "H025":
|
||||
open_tags = []
|
||||
|
||||
if _should_ignore(config, html, match) is False:
|
||||
errors[file_name].append(
|
||||
{
|
||||
"code": rule["name"],
|
||||
"line": get_line(match.start(), line_ends),
|
||||
"match": match.group().strip()[:20],
|
||||
"message": rule["message"],
|
||||
}
|
||||
)
|
||||
for match in re.finditer(
|
||||
re.compile(
|
||||
pattern, flags=build_flags(rule.get("flags", "re.DOTALL"))
|
||||
),
|
||||
html,
|
||||
):
|
||||
# close tags should equal open tags
|
||||
if match.group(1).split(" ")[0][0] != "/":
|
||||
open_tags.append(match)
|
||||
else:
|
||||
for i, tag in enumerate(copy.deepcopy(open_tags)):
|
||||
if (
|
||||
tag.group(1).split(" ")[0]
|
||||
== match.group(1).split(" ")[0][1:]
|
||||
):
|
||||
open_tags.pop(i)
|
||||
break
|
||||
else:
|
||||
# there was no open tag matching the close tag
|
||||
open_tags.append(match)
|
||||
|
||||
for match in open_tags:
|
||||
if _should_ignore(config, html, match) is False:
|
||||
errors[file_name].append(
|
||||
{
|
||||
"code": rule["name"],
|
||||
"line": get_line(match.start(), line_ends),
|
||||
"match": match.group().strip()[:20],
|
||||
"message": rule["message"],
|
||||
}
|
||||
)
|
||||
else:
|
||||
|
||||
for match in re.finditer(
|
||||
re.compile(
|
||||
pattern, flags=build_flags(rule.get("flags", "re.DOTALL"))
|
||||
),
|
||||
html,
|
||||
):
|
||||
|
||||
if _should_ignore(config, html, match) is False:
|
||||
errors[file_name].append(
|
||||
{
|
||||
"code": rule["name"],
|
||||
"line": get_line(match.start(), line_ends),
|
||||
"match": match.group().strip()[:20],
|
||||
"message": rule["message"],
|
||||
}
|
||||
)
|
||||
|
||||
# remove duplicate matches
|
||||
for file_name, error_dict in errors.items():
|
||||
|
|
|
|||
|
|
@ -299,3 +299,8 @@
|
|||
flags: re.I
|
||||
patterns:
|
||||
- <(?:script|style)[^>]*?type=["|'][^>]*?>
|
||||
- rule:
|
||||
name: H025
|
||||
message: Tag seems to be an orphan.
|
||||
patterns:
|
||||
- <((?:\"[^\"<>]*\"['\"]*|'[^'<>]*'['\"]*|[^'\"<>])+)(?<!/\s*)>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ run::
|
|||
|
||||
# for a single test
|
||||
|
||||
pytest tests/test_linter.py::test_H021 --cov=src/djlint --cov-branch \
|
||||
pytest tests/test_linter.py::test_H012 --cov=src/djlint --cov-branch \
|
||||
--cov-report xml:coverage.xml --cov-report term-missing
|
||||
|
||||
"""
|
||||
|
|
@ -152,6 +152,7 @@ def test_H012(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
b"<p>{% if activity.reporting_groups|length <= 0 %}<h3>{% trans 'General' %}</h3>{% endif %}</p>",
|
||||
)
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert "H012 1:" not in result.output
|
||||
|
||||
|
|
@ -203,7 +204,7 @@ def test_H017(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
assert "H017 1:" in result.output
|
||||
|
||||
# test colgroup tag
|
||||
write_to_file(tmp_file.name, b"<colgroup><colgroup asdf>")
|
||||
write_to_file(tmp_file.name, b"<colgroup><colgroup asdf></colgroup></colgroup>")
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
assert result.exit_code == 0
|
||||
assert "H017 1:" not in result.output
|
||||
|
|
@ -212,7 +213,7 @@ def test_H017(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
def test_DJ018(runner: CliRunner, tmp_file: TextIO) -> None:
|
||||
write_to_file(
|
||||
tmp_file.name,
|
||||
b'<a href="/Collections?handler=RemoveAgreement&id=@a.Id">\n<form action="/Collections">',
|
||||
b'<a href="/Collections?handler=RemoveAgreement&id=@a.Id">\n<form action="/Collections"></form></a>',
|
||||
)
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
assert result.exit_code == 1
|
||||
|
|
@ -306,6 +307,13 @@ def test_H024(runner: CliRunner, tmp_file: TextIO) -> None:
|
|||
assert "H024 1:" in result.output
|
||||
|
||||
|
||||
def test_H025(runner: CliRunner, tmp_file: TextIO) -> None:
|
||||
write_to_file(tmp_file.name, b"<div>")
|
||||
result = runner.invoke(djlint, [tmp_file.name])
|
||||
assert result.exit_code == 1
|
||||
assert "H025 1:" in result.output
|
||||
|
||||
|
||||
def test_rules_not_matched_in_ignored_block(
|
||||
runner: CliRunner, tmp_file: TextIO
|
||||
) -> None:
|
||||
|
|
|
|||
Loading…
Reference in a new issue