Просмотр исходного кода

test: add tests for write_columns function

xifOO 4 месяцев назад
Родитель
Сommit
a964d8c440
1 измененных файлов с 164 добавлено и 1 удалено
  1. 164 1
      tests/test_cli.py

+ 164 - 1
tests/test_cli.py

@@ -33,7 +33,7 @@ from unittest import skipIf
 from unittest.mock import MagicMock, patch
 
 from dulwich import cli
-from dulwich.cli import format_bytes, launch_editor, parse_relative_time
+from dulwich.cli import format_bytes, launch_editor, parse_relative_time, write_columns
 from dulwich.repo import Repo
 from dulwich.tests.utils import (
     build_commit_graph,
@@ -658,6 +658,169 @@ class BranchCommandTest(DulwichCliTestCase):
         self.assertTrue(multiple_columns)
 
 
+class TestWriteColumns(TestCase):
+    """Tests for write_columns function"""
+
+    def setUp(self) -> None:
+        super().setUp()
+        self.original_stdout = sys.stdout
+        self.original_get_terminal_size = os.get_terminal_size
+
+    def tearDown(self):
+        super().tearDown()
+        sys.stdout = self.original_stdout
+        os.get_terminal_size = self.original_get_terminal_size
+
+    @patch("os.get_terminal_size")
+    def test_basic_functionality(self, mock_terminal_size):
+        """Test basic functionality with default terminal width."""
+        mock_terminal_size.return_value.columns = 80
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [b"main", b"dev", b"feature/branch-1"]
+            write_columns(items)
+
+            self.assertGreater(mock_write.call_count, 0)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            self.assertIn("main", output_text)
+            self.assertIn("dev", output_text)
+            self.assertIn("feature/branch-1", output_text)
+
+    @patch("os.get_terminal_size")
+    def test_narrow_terminal_single_column(self, mock_terminal_size):
+        """Test with narrow terminal forcing single column."""
+        mock_terminal_size.return_value.columns = 20
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [b"main", b"dev", b"feature/branch-1"]
+            write_columns(items)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            for item in items:
+                self.assertIn(item.decode(), output_text)
+
+    @patch("os.get_terminal_size")
+    def test_wide_terminal_multiple_columns(self, mock_terminal_size):
+        """Test with wide terminal allowing multiple columns."""
+        mock_terminal_size.return_value.columns = 120
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [
+                b"main",
+                b"dev",
+                b"feature/branch-1",
+                b"feature/branch-2",
+                b"feature/branch-3",
+            ]
+            write_columns(items)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            for item in items:
+                self.assertIn(item.decode(), output_text)
+
+    @patch("os.get_terminal_size")
+    def test_single_item(self, mock_terminal_size):
+        """Test with single item."""
+        mock_terminal_size.return_value.columns = 80
+
+        with patch("sys.stdout.write") as mock_write:
+            write_columns([b"single"])
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            self.assertIn("single", output_text)
+            self.assertTrue(output_text.endswith("\n"))
+
+    def test_os_error_fallback(self):
+        """Test fallback behavior when os.get_terminal_size raises OSError."""
+        with patch("os.get_terminal_size", side_effect=OSError("No terminal")):
+            with patch("sys.stdout.write") as mock_write:
+                items = [b"main", b"dev"]
+                write_columns(items)
+
+                output_text = "".join(
+                    call.args[0] for call in mock_write.call_args_list
+                )
+                self.assertIn("main", output_text)
+                self.assertIn("dev", output_text)
+
+    @patch("os.get_terminal_size")
+    def test_iterator_input(self, mock_terminal_size):
+        """Test with iterator input instead of list."""
+        mock_terminal_size.return_value.columns = 80
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [b"main", b"dev", b"feature/branch-1"]
+            items_iterator = iter(items)
+            write_columns(items_iterator)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            for item in items:
+                self.assertIn(item.decode(), output_text)
+
+    @patch("os.get_terminal_size")
+    def test_column_alignment(self, mock_terminal_size):
+        """Test that columns are properly aligned."""
+        mock_terminal_size.return_value.columns = 50
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [b"short", b"medium_length", b"very_long______name"]
+            write_columns(items)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            for item in items:
+                self.assertIn(item.decode(), output_text)
+
+    @patch("os.get_terminal_size")
+    def test_columns_formatting(self, mock_terminal_size):
+        """Test that items are formatted in columns within single line."""
+        mock_terminal_size.return_value.columns = 80
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [b"branch-1", b"branch-2", b"branch-3", b"branch-4", b"branch-5"]
+            write_columns(items)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+
+            self.assertEqual(output_text.count("\n"), 1)
+            self.assertTrue(output_text.endswith("\n"))
+
+            line = output_text.strip()
+            for item in items:
+                self.assertIn(item.decode(), line)
+
+    @patch("os.get_terminal_size")
+    def test_column_alignment_multiple_lines(self, mock_terminal_size):
+        """Test that columns are properly aligned across multiple lines."""
+        mock_terminal_size.return_value.columns = 60
+
+        with patch("sys.stdout.write") as mock_write:
+            items = [
+                b"short",
+                b"medium_length",
+                b"very_long_branch_name",
+                b"another",
+                b"more",
+                b"even_longer_branch_name_here",
+            ]
+
+            write_columns(items)
+
+            output_text = "".join(call.args[0] for call in mock_write.call_args_list)
+            lines = output_text.strip().split("\n")
+
+            self.assertGreater(len(lines), 1)
+
+            line_lengths = [len(line) for line in lines if line.strip()]
+
+            for length in line_lengths:
+                self.assertLessEqual(length, mock_terminal_size.return_value.columns)
+
+            all_output = " ".join(lines)
+            for item in items:
+                self.assertIn(item.decode(), all_output)
+
+
 class CheckoutCommandTest(DulwichCliTestCase):
     """Tests for checkout command."""