diff options
Diffstat (limited to 'test/test_yaml_utils.py')
-rw-r--r-- | test/test_yaml_utils.py | 130 |
1 files changed, 100 insertions, 30 deletions
diff --git a/test/test_yaml_utils.py b/test/test_yaml_utils.py index 5546e58..f4d9b46 100644 --- a/test/test_yaml_utils.py +++ b/test/test_yaml_utils.py @@ -1,16 +1,18 @@ """Tests for yaml-related utility functions.""" + +# pylint: disable=too-many-lines from __future__ import annotations from io import StringIO from pathlib import Path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, cast import pytest from ruamel.yaml.main import YAML from yamllint.linter import run as run_yamllint import ansiblelint.yaml_utils -from ansiblelint.file_utils import Lintable +from ansiblelint.file_utils import Lintable, cwd from ansiblelint.utils import task_in_list if TYPE_CHECKING: @@ -202,8 +204,7 @@ def test_custom_ruamel_yaml_emitter( assert output == expected_output -@pytest.fixture(name="yaml_formatting_fixtures") -def fixture_yaml_formatting_fixtures(fixture_filename: str) -> tuple[str, str, str]: +def load_yaml_formatting_fixtures(fixture_filename: str) -> tuple[str, str, str]: """Get the contents for the formatting fixture files. To regenerate these fixtures, please run ``pytest --regenerate-formatting-fixtures``. @@ -220,30 +221,67 @@ def fixture_yaml_formatting_fixtures(fixture_filename: str) -> tuple[str, str, s @pytest.mark.parametrize( - "fixture_filename", + ("before", "after", "version"), + ( + pytest.param("---\nfoo: bar\n", "---\nfoo: bar\n", None, id="1"), + # verify that 'on' is not translated to bool (1.2 behavior) + pytest.param("---\nfoo: on\n", "---\nfoo: on\n", None, id="2"), + # When version is manually mentioned by us, we expect to output without version directive + pytest.param("---\nfoo: on\n", "---\nfoo: on\n", (1, 2), id="3"), + pytest.param("---\nfoo: on\n", "---\nfoo: true\n", (1, 1), id="4"), + pytest.param("%YAML 1.1\n---\nfoo: on\n", "---\nfoo: true\n", (1, 1), id="5"), + # verify that in-line directive takes precedence but dumping strips if we mention a specific version + pytest.param("%YAML 1.1\n---\nfoo: on\n", "---\nfoo: true\n", (1, 2), id="6"), + # verify that version directive are kept if present + pytest.param("%YAML 1.1\n---\nfoo: on\n", "---\nfoo: true\n", None, id="7"), + pytest.param( + "%YAML 1.2\n---\nfoo: on\n", + "%YAML 1.2\n---\nfoo: on\n", + None, + id="8", + ), + pytest.param("---\nfoo: YES\n", "---\nfoo: true\n", (1, 1), id="9"), + pytest.param("---\nfoo: YES\n", "---\nfoo: YES\n", (1, 2), id="10"), + pytest.param("---\nfoo: YES\n", "---\nfoo: YES\n", None, id="11"), + ), +) +def test_fmt(before: str, after: str, version: tuple[int, int] | None) -> None: + """Tests behavior of formatter in regards to different YAML versions, specified or not.""" + yaml = ansiblelint.yaml_utils.FormattedYAML(version=version) + data = yaml.load(before) + result = yaml.dumps(data) + assert result == after + + +@pytest.mark.parametrize( + ("fixture_filename", "version"), ( - "fmt-1.yml", - "fmt-2.yml", - "fmt-3.yml", + pytest.param("fmt-1.yml", (1, 1), id="1"), + pytest.param("fmt-2.yml", (1, 1), id="2"), + pytest.param("fmt-3.yml", (1, 1), id="3"), + pytest.param("fmt-4.yml", (1, 1), id="4"), + pytest.param("fmt-5.yml", (1, 1), id="5"), + pytest.param("fmt-hex.yml", (1, 1), id="hex"), ), ) def test_formatted_yaml_loader_dumper( - yaml_formatting_fixtures: tuple[str, str, str], - fixture_filename: str, # noqa: ARG001 + fixture_filename: str, + version: tuple[int, int], ) -> None: """Ensure that FormattedYAML loads/dumps formatting fixtures consistently.""" - # pylint: disable=unused-argument - before_content, prettier_content, after_content = yaml_formatting_fixtures + before_content, prettier_content, after_content = load_yaml_formatting_fixtures( + fixture_filename, + ) assert before_content != prettier_content assert before_content != after_content - yaml = ansiblelint.yaml_utils.FormattedYAML() + yaml = ansiblelint.yaml_utils.FormattedYAML(version=version) - data_before = yaml.loads(before_content) + data_before = yaml.load(before_content) dump_from_before = yaml.dumps(data_before) - data_prettier = yaml.loads(prettier_content) + data_prettier = yaml.load(prettier_content) dump_from_prettier = yaml.dumps(data_prettier) - data_after = yaml.loads(after_content) + data_after = yaml.load(after_content) dump_from_after = yaml.dumps(data_after) # comparing data does not work because the Comment objects @@ -274,7 +312,7 @@ def fixture_lintable(file_path: str) -> Lintable: def fixture_ruamel_data(lintable: Lintable) -> CommentedMap | CommentedSeq: """Return the loaded YAML data for the Lintable.""" yaml = ansiblelint.yaml_utils.FormattedYAML() - data: CommentedMap | CommentedSeq = yaml.loads(lintable.content) + data: CommentedMap | CommentedSeq = yaml.load(lintable.content) return data @@ -384,7 +422,7 @@ def fixture_ruamel_data(lintable: Lintable) -> CommentedMap | CommentedSeq: ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 10, + 12, [1], id="4_play_playbook-first_line_in_play_2", ), @@ -402,7 +440,7 @@ def fixture_ruamel_data(lintable: Lintable) -> CommentedMap | CommentedSeq: ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 19, + 21, [2], id="4_play_playbook-first_line_in_play_3", ), @@ -420,7 +458,7 @@ def fixture_ruamel_data(lintable: Lintable) -> CommentedMap | CommentedSeq: ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 28, + 31, [3], id="4_play_playbook-first_line_in_play_4", ), @@ -601,7 +639,7 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 7, + 8, [0, "tasks", 0], id="4_play_playbook-play_1_first_line_task_1", ), @@ -613,7 +651,7 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 10, + 13, [], id="4_play_playbook-play_2_line_before_tasks", ), @@ -625,7 +663,7 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 13, + 15, [1, "tasks", 0], id="4_play_playbook-play_2_first_line_task_1", ), @@ -643,7 +681,7 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 19, + 23, [], id="4_play_playbook-play_3_line_before_tasks", ), @@ -655,7 +693,7 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 23, + 25, [2, "tasks", 0], id="4_play_playbook-play_3_first_line_task_1", ), @@ -673,7 +711,7 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 28, + 33, [], id="4_play_playbook-play_4_line_before_tasks", ), @@ -685,13 +723,13 @@ def test_get_path_to_play( ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 32, + 35, [3, "tasks", 0], id="4_play_playbook-play_4_first_line_task_1", ), pytest.param( "examples/playbooks/rule-partial-become-without-become-pass.yml", - 33, + 39, [3, "tasks", 0], id="4_play_playbook-play_4_middle_line_task_1", ), @@ -730,12 +768,12 @@ def test_get_path_to_play( pytest.param( "examples/playbooks/include.yml", 14, - [0, "tasks", 1], + [0, "tasks", 2], id="playbook-multi_tasks_blocks-tasks_last_task_before_handlers", ), pytest.param( "examples/playbooks/include.yml", - 16, + 17, [0, "handlers", 0], id="playbook-multi_tasks_blocks-handlers_task", ), @@ -953,3 +991,35 @@ def test_deannotate( ) -> None: """Ensure deannotate works as intended.""" assert ansiblelint.yaml_utils.deannotate(before) == after + + +def test_yamllint_incompatible_config() -> None: + """Ensure we can detect incompatible yamllint settings.""" + with (cwd(Path("examples/yamllint/incompatible-config")),): + config = ansiblelint.yaml_utils.load_yamllint_config() + assert config.incompatible + + +@pytest.mark.parametrize( + ("yaml_version", "explicit_start"), + ( + pytest.param((1, 1), True), + pytest.param((1, 1), False), + ), +) +def test_document_start( + yaml_version: tuple[int, int] | None, + explicit_start: bool, +) -> None: + """Ensure the explicit_start config option from .yamllint is applied correctly.""" + config = ansiblelint.yaml_utils.FormattedYAML.default_config + config["explicit_start"] = explicit_start + + yaml = ansiblelint.yaml_utils.FormattedYAML( + version=yaml_version, + config=cast(dict[str, bool | int | str], config), + ) + assert ( + yaml.dumps(yaml.load(_SINGLE_QUOTE_WITHOUT_INDENTS)).startswith("---") + == explicit_start + ) |