Settings: disable automatic yaml line breaks (#3096)
* Settings: disable automatic yaml line breaks * Tests: add settings formatting checks * Tests: fix typing in test_host_yaml
This commit is contained in:
parent
f89cee4b15
commit
6087ec539b
|
@ -200,7 +200,7 @@ class Group:
|
|||
def _dump_value(cls, value: Any, f: TextIO, indent: str) -> None:
|
||||
"""Write a single yaml line to f"""
|
||||
from Utils import dump, Dumper as BaseDumper
|
||||
yaml_line: str = dump(value, Dumper=cast(BaseDumper, cls._dumper))
|
||||
yaml_line: str = dump(value, Dumper=cast(BaseDumper, cls._dumper), width=2**31-1)
|
||||
assert yaml_line.count("\n") == 1, f"Unexpected input for yaml dumper: {value}"
|
||||
f.write(f"{indent}{yaml_line}")
|
||||
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
import os
|
||||
import unittest
|
||||
from io import StringIO
|
||||
from tempfile import TemporaryFile
|
||||
from typing import Any, Dict, List, cast
|
||||
|
||||
from settings import Settings
|
||||
import Utils
|
||||
from settings import Settings, Group
|
||||
|
||||
|
||||
class TestIDs(unittest.TestCase):
|
||||
yaml_options: Dict[Any, Any]
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
with TemporaryFile("w+", encoding="utf-8") as f:
|
||||
Settings(None).dump(f)
|
||||
f.seek(0, os.SEEK_SET)
|
||||
cls.yaml_options = Utils.parse_yaml(f.read())
|
||||
yaml_options = Utils.parse_yaml(f.read())
|
||||
assert isinstance(yaml_options, dict)
|
||||
cls.yaml_options = yaml_options
|
||||
|
||||
def test_utils_in_yaml(self) -> None:
|
||||
"""Tests that the auto generated host.yaml has default settings in it"""
|
||||
|
@ -30,3 +36,47 @@ class TestIDs(unittest.TestCase):
|
|||
self.assertIn(option_key, utils_options)
|
||||
for sub_option_key in option_set:
|
||||
self.assertIn(sub_option_key, utils_options[option_key])
|
||||
|
||||
|
||||
class TestSettingsDumper(unittest.TestCase):
|
||||
def test_string_format(self) -> None:
|
||||
"""Test that dumping a string will yield the expected output"""
|
||||
# By default, pyyaml has automatic line breaks in strings and quoting is optional.
|
||||
# What we want for consistency instead is single-line strings and always quote them.
|
||||
# Line breaks have to become \n in that quoting style.
|
||||
class AGroup(Group):
|
||||
key: str = " ".join(["x"] * 60) + "\n" # more than 120 chars, contains spaces and a line break
|
||||
|
||||
with StringIO() as writer:
|
||||
AGroup().dump(writer, 0)
|
||||
expected_value = AGroup.key.replace("\n", "\\n")
|
||||
self.assertEqual(writer.getvalue(), f"key: \"{expected_value}\"\n",
|
||||
"dumped string has unexpected formatting")
|
||||
|
||||
def test_indentation(self) -> None:
|
||||
"""Test that dumping items will add indentation"""
|
||||
# NOTE: we don't care how many spaces there are, but it has to be a multiple of level
|
||||
class AList(List[Any]):
|
||||
__doc__ = None # make sure we get no doc string
|
||||
|
||||
class AGroup(Group):
|
||||
key: AList = cast(AList, ["a", "b", [1]])
|
||||
|
||||
for level in range(3):
|
||||
with StringIO() as writer:
|
||||
AGroup().dump(writer, level)
|
||||
lines = writer.getvalue().split("\n", 5)
|
||||
key_line = lines[0]
|
||||
key_spaces = len(key_line) - len(key_line.lstrip(" "))
|
||||
value_lines = lines[1:-1]
|
||||
value_spaces = [len(value_line) - len(value_line.lstrip(" ")) for value_line in value_lines]
|
||||
if level == 0:
|
||||
self.assertEqual(key_spaces, 0)
|
||||
else:
|
||||
self.assertGreaterEqual(key_spaces, level)
|
||||
self.assertEqual(key_spaces % level, 0)
|
||||
self.assertGreaterEqual(value_spaces[0], key_spaces) # a
|
||||
self.assertEqual(value_spaces[1], value_spaces[0]) # b
|
||||
self.assertEqual(value_spaces[2], value_spaces[0]) # start of sub-list
|
||||
self.assertGreater(value_spaces[3], value_spaces[0],
|
||||
f"{value_lines[3]} should have more indentation than {value_lines[0]} in {lines}")
|
||||
|
|
Loading…
Reference in New Issue