blob: a0d9e426be100e4953695520bd641f6a426d9a2f [file]
# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
# SPDX-License-Identifier: Apache-2.0
"""
Unit tests for kconfig_style.py.
"""
import kconfig_style
def _rules(text):
"""The set of rule ids reported for 'text' (line-based rules)."""
lines = text[:-1].split("\n") if text.endswith("\n") else text.split("\n")
return {issue.rule for issue in kconfig_style.lint(lines)}
def _file_rules(tmp_path, text):
"""The set of rule ids reported for 'text' written to a real file."""
path = tmp_path / "Kconfig"
path.write_text(text)
return {issue.rule for issue in kconfig_style.check_file(path)}
# Rule 1: line length, with the $(...) macro exemption.
def test_line_too_long_flagged():
assert _rules("config " + "A" * 110 + "\n") == {"line-too-long"}
def test_line_too_long_macro_exempt():
assert not _rules('config X\n\tdefault "$(' + "y" * 110 + ')"\n')
# Rule 2: indentation (tabs, flat layout, help body, continuations).
def test_space_indentation_flagged():
assert _rules("""\
config X
default y
""") == {"tab-indent"}
def test_property_single_tab_clean():
assert not _rules("""\
config X
\tdefault y
""")
def test_property_over_indent_flagged():
assert _rules("""\
config X
\t\tdefault y
""") == {"over-indent"}
def test_help_body_indent_clean():
assert not _rules("""\
config X
\thelp
\t Help text.
""")
def test_help_body_indent_flagged():
# Help body must be one tab plus two spaces; two tabs is wrong.
assert _rules("""\
config X
\thelp
\t\tHelp text.
""") == {"help-indent"}
def test_continuation_tabs_clean():
assert not _rules("""\
config X
\tdepends on A \\
\t\t|| B
""")
def test_continuation_spaces_flagged():
assert _rules("""\
config X
\tdepends on A \\
\t || B
""") == {"cont-indent"}
# Rule 3: single blank line between declarations, no consecutive blanks.
def test_consecutive_blank_lines_flagged():
assert _rules("""\
config A
\tbool
config B
\tbool
""") == {"blank-lines"}
def test_decl_blank_missing_flagged():
assert _rules("""\
config A
\tbool
config B
\tbool
""") == {"decl-blank"}
def test_decl_blank_present_clean():
assert not _rules("""\
config A
\tbool
config B
\tbool
""")
def test_decl_after_multiline_opener_no_decl_blank():
# A declaration right after a backslash-continued opener needs no decl-blank;
# the 'if' still legitimately needs a blank line after it (if-blank).
assert _rules("""\
if B \\
\t|| C
config D
\tbool
endif
""") == {"if-blank"}
# Rule 4: comment spacing.
def test_comment_space_flagged():
assert _rules("#comment\n") == {"comment-space"}
def test_comment_space_clean():
assert not _rules("# comment\n")
# Rule 5: blank lines around top-level if/endif, incl. multi-line conditions.
def test_if_blank_missing_flagged():
assert _rules("""\
config A
\tbool
if B
config C
\tbool
endif
""") == {"if-blank"}
def test_if_blank_multiline_condition_clean():
assert not _rules("""\
config A
\tbool
if B \\
\t|| C
config D
\tbool
endif
""")
# Rule 6: exactly one trailing newline (whole-file rule).
def test_final_newline_missing_flagged(tmp_path):
assert _file_rules(tmp_path, "config A\n\tbool") == {"final-newline"}
def test_final_newline_extra_flagged(tmp_path):
assert _file_rules(tmp_path, "config A\n\tbool\n\n") == {"final-newline"}
def test_final_newline_single_clean(tmp_path):
assert not _file_rules(tmp_path, "config A\n\tbool\n")