import io
import os
import tempfile
import unittest
from contextlib import redirect_stdout
from common import find_target_items, reverse_items, sort_items
class CommonScriptTest(unittest.TestCase):
def run_file_op(self, func, input_text, *, input_bytes=None):
with tempfile.TemporaryDirectory() as tmpdir:
src = os.path.join(tmpdir, "in.txt")
dst = os.path.join(tmpdir, "out.txt")
if input_bytes is not None:
with open(src, "wb") as f:
f.write(input_bytes)
else:
with open(src, "w", encoding="utf-8") as f:
f.write(input_text)
func(src, dst)
with open(dst, "rb") as f:
return f.read()
def test_sort_entries(self):
out = self.run_file_op(sort_items, "b\tB\na\tA\n")
self.assertEqual(out.decode("utf-8"), "a\tA\nb\tB\n")
def test_sort_moves_comment_with_following_entry(self):
out = self.run_file_op(sort_items, "b\tB\n# comment for a\na\tA\n")
self.assertEqual(
out.decode("utf-8"),
"# comment for a\na\tA\nb\tB\n",
)
def test_sort_preserves_blank_lines_in_anchored_block(self):
out = self.run_file_op(sort_items, "b\tB\n\n# comment for a\na\tA\n")
self.assertEqual(
out.decode("utf-8"),
"\n# comment for a\na\tA\nb\tB\n",
)
def test_sort_splits_header_from_first_entry_comment(self):
out = self.run_file_op(
sort_items,
"# Header\n\n# comment for b\nb\tB\na\tA\n",
)
self.assertEqual(
out.decode("utf-8"),
"# Header\n\na\tA\n# comment for b\nb\tB\n",
)
def test_sort_keeps_footer_at_end(self):
out = self.run_file_op(sort_items, "b\tB\na\tA\n\n# footer\n")
self.assertEqual(
out.decode("utf-8"),
"a\tA\nb\tB\n\n# footer\n",
)
def test_sort_preserves_missing_final_newline(self):
out = self.run_file_op(
sort_items,
"",
input_bytes=b"b\tB\na\tA",
)
self.assertEqual(out, b"a\tA\nb\tB")
def test_sort_normalizes_crlf_input(self):
out = self.run_file_op(
sort_items,
"",
input_bytes=b"b\tB\r\na\tA\r\n",
)
self.assertEqual(out, b"a\tA\nb\tB\n")
def test_reverse_items(self):
out = self.run_file_op(reverse_items, "A\tx y\nB\tx\n")
self.assertEqual(
out.decode("utf-8"),
"x\tA B\ny\tA\n",
)
def test_reverse_items_applies_reverse_preference(self):
out = self.run_file_op(
reverse_items,
"# @reverse-prefer: x B\nA\tx\nB\tx\n",
)
self.assertEqual(out.decode("utf-8"), "x\tB A\n")
def test_reverse_items_uses_key_as_default_reverse_preference(self):
out = self.run_file_op(
reverse_items,
"# @reverse-prefer: x\nx\tx\nA\tx\n",
)
self.assertEqual(out.decode("utf-8"), "x\tx A\n")
def test_reverse_items_rejects_unmatched_reverse_preference(self):
with self.assertRaises(ValueError):
self.run_file_op(
reverse_items,
"# @reverse-prefer: x C\nA\tx\nB\tx\n",
)
def test_find_target_items_matches_values_only(self):
with tempfile.TemporaryDirectory() as tmpdir:
src = os.path.join(tmpdir, "in.txt")
with open(src, "w", encoding="utf-8") as f:
f.write("foo\tbar baz\n")
f.write("target\txxx\n")
f.write("abc\ttarget-value\n")
buf = io.StringIO()
with redirect_stdout(buf):
find_target_items(src, "target")
self.assertEqual(buf.getvalue(), "abc\ttarget-value\n")
if __name__ == "__main__":
unittest.main()