diff --git a/src/yamlfix/adapters.py b/src/yamlfix/adapters.py index dbb845b..95b2789 100644 --- a/src/yamlfix/adapters.py +++ b/src/yamlfix/adapters.py @@ -374,13 +374,23 @@ def _ruamel_yaml_fixer(self, source_code: str) -> str: Corrected source code. """ log.debug("Running ruamel yaml fixer...") - source_dicts = self.yaml.load_all(source_code) + + # Detect if the original source starts with an explicit document marker + source_dicts = list(self.yaml.load_all(source_code)) + + # Determine if ruyaml will emit --- for each document + yaml_emits_start = bool(self.yaml.explicit_start) # Return the output to a string string_stream = StringIO() - for source_dict in source_dicts: + for i, source_dict in enumerate(source_dicts): + if i > 0 and not yaml_emits_start: + # Inter-document separators are structurally required for + # multi-document YAML; always preserve them even when + # explicit_start is False (which only controls the leading ---) + string_stream.write("---\n") self.yaml.dump(source_dict, string_stream) - source_code = string_stream.getvalue() + source_code = string_stream.getvalue() string_stream.close() return source_code.strip() diff --git a/tests/unit/test_explicit_start.py b/tests/unit/test_explicit_start.py new file mode 100644 index 0000000..9c14f98 --- /dev/null +++ b/tests/unit/test_explicit_start.py @@ -0,0 +1,110 @@ +"""Test explicit_start configuration behavior.""" + +from textwrap import dedent + +from yamlfix.model import YamlfixConfig +from yamlfix.services import fix_code + + +class TestExplicitStartFalse: + """Tests for explicit_start = False.""" + + def test_removes_leading_start_marker(self) -> None: + """When explicit_start is False, leading --- is removed.""" + source = dedent( + """\ + --- + project_name: yamlfix + """ + ) + fixed_source = dedent( + """\ + project_name: yamlfix + """ + ) + config = YamlfixConfig() + config.explicit_start = False + + result = fix_code(source, config) + + assert result == fixed_source + + def test_preserves_inter_document_separators(self) -> None: + """When explicit_start is False, inter-document --- separators are preserved.""" + source = dedent( + """\ + --- + name: doc1 + --- + name: doc2 + """ + ) + config = YamlfixConfig() + config.explicit_start = False + + result = fix_code(source, config) + + # The inter-document separator must remain (structurally required) + assert "---\nname: doc2" in result + + def test_multi_document_three_docs(self) -> None: + """When explicit_start is False, all inter-document separators are preserved.""" + source = dedent( + """\ + --- + name: doc1 + --- + name: doc2 + --- + name: doc3 + """ + ) + config = YamlfixConfig() + config.explicit_start = False + + result = fix_code(source, config) + + # Inter-document separators must remain (at least 2 for 3 docs) + assert result.count("---") >= 2 + + +class TestExplicitStartTrue: + """Tests for explicit_start = True.""" + + def test_adds_start_marker(self) -> None: + """When explicit_start is True, --- is added.""" + source = dedent( + """\ + project_name: yamlfix + """ + ) + fixed_source = dedent( + """\ + --- + project_name: yamlfix + """ + ) + config = YamlfixConfig() + config.explicit_start = True + + result = fix_code(source, config) + + assert result == fixed_source + + def test_multi_document_preserves_separators(self) -> None: + """Multi-document files keep --- dividers with explicit_start=True.""" + source = dedent( + """\ + --- + name: doc1 + --- + name: doc2 + """ + ) + config = YamlfixConfig() + config.explicit_start = True + + result = fix_code(source, config) + + # Both documents should have separators + assert result.count("---") >= 2