File: test_diff.py

package info (click to toggle)
dulwich 0.24.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,392 kB
  • sloc: python: 87,517; makefile: 162; sh: 11
file content (184 lines) | stat: -rw-r--r-- 6,088 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# test_diff.py -- Tests for diff functionality.
# Copyright (C) 2025 Dulwich contributors
#
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
# Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
# General Public License as published by the Free Software Foundation; version 2.0
# or (at your option) any later version. You can redistribute it and/or
# modify it under the terms of either of these two licenses.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# You should have received a copy of the licenses; if not, see
# <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
# and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
# License, Version 2.0.
#

"""Tests for diff functionality."""

import io
import unittest

from dulwich.diff import ColorizedDiffStream

from . import TestCase


class ColorizedDiffStreamTests(TestCase):
    """Tests for ColorizedDiffStream."""

    def setUp(self):
        super().setUp()
        self.output = io.BytesIO()

    @unittest.skipUnless(
        ColorizedDiffStream.is_available(), "Rich not available for colorization"
    )
    def test_write_simple_diff(self):
        """Test writing a simple diff with colorization."""
        stream = ColorizedDiffStream(self.output)

        diff_content = b"""--- a/file.txt
+++ b/file.txt
@@ -1,3 +1,3 @@
 unchanged line
-removed line
+added line
 another unchanged line
"""

        stream.write(diff_content)
        stream.flush()

        # We can't easily test the exact colored output without mocking Rich,
        # but we can test that the stream writes something and doesn't crash
        result = self.output.getvalue()
        self.assertGreater(len(result), 0)

    @unittest.skipUnless(
        ColorizedDiffStream.is_available(), "Rich not available for colorization"
    )
    def test_write_line_by_line(self):
        """Test writing diff content line by line."""
        stream = ColorizedDiffStream(self.output)

        lines = [
            b"--- a/file.txt\n",
            b"+++ b/file.txt\n",
            b"@@ -1,2 +1,2 @@\n",
            b"-old line\n",
            b"+new line\n",
        ]

        for line in lines:
            stream.write(line)

        stream.flush()

        result = self.output.getvalue()
        self.assertGreater(len(result), 0)

    @unittest.skipUnless(
        ColorizedDiffStream.is_available(), "Rich not available for colorization"
    )
    def test_writelines(self):
        """Test writelines method."""
        stream = ColorizedDiffStream(self.output)

        lines = [
            b"--- a/file.txt\n",
            b"+++ b/file.txt\n",
            b"@@ -1,1 +1,1 @@\n",
            b"-old\n",
            b"+new\n",
        ]

        stream.writelines(lines)
        stream.flush()

        result = self.output.getvalue()
        self.assertGreater(len(result), 0)

    @unittest.skipUnless(
        ColorizedDiffStream.is_available(), "Rich not available for colorization"
    )
    def test_partial_line_buffering(self):
        """Test that partial lines are buffered correctly."""
        stream = ColorizedDiffStream(self.output)

        # Write partial line
        stream.write(b"+partial")
        # Output should be empty as line is not complete
        result = self.output.getvalue()
        self.assertEqual(len(result), 0)

        # Complete the line
        stream.write(b" line\n")
        result = self.output.getvalue()
        self.assertGreater(len(result), 0)

    @unittest.skipUnless(
        ColorizedDiffStream.is_available(), "Rich not available for colorization"
    )
    def test_unicode_handling(self):
        """Test handling of unicode content in diffs."""
        stream = ColorizedDiffStream(self.output)

        # UTF-8 encoded content
        unicode_diff = "--- a/ünïcödë.txt\n+++ b/ünïcödë.txt\n@@ -1,1 +1,1 @@\n-ōld\n+nëw\n".encode()

        stream.write(unicode_diff)
        stream.flush()

        result = self.output.getvalue()
        self.assertGreater(len(result), 0)

    def test_is_available_static_method(self):
        """Test is_available static method."""
        # This should not raise an error regardless of Rich availability
        result = ColorizedDiffStream.is_available()
        self.assertIsInstance(result, bool)

    @unittest.skipIf(
        ColorizedDiffStream.is_available(), "Rich is available, skipping fallback test"
    )
    def test_rich_not_available(self):
        """Test behavior when Rich is not available."""
        # When Rich is not available, we can't instantiate ColorizedDiffStream
        # This test only runs when Rich is not available
        with self.assertRaises(ImportError):
            ColorizedDiffStream(self.output)


class MockColorizedDiffStreamTests(TestCase):
    """Tests for ColorizedDiffStream using a mock when Rich is not available."""

    def setUp(self):
        super().setUp()
        self.output = io.BytesIO()

    def test_fallback_behavior_with_mock(self):
        """Test that we can handle cases where Rich is not available."""
        # This test demonstrates how the CLI handles the case where Rich is unavailable
        if not ColorizedDiffStream.is_available():
            # When Rich is not available, we should use the raw stream
            stream = self.output
        else:
            # When Rich is available, we can use ColorizedDiffStream
            stream = ColorizedDiffStream(self.output)

        diff_content = b"+added line\n-removed line\n"

        if hasattr(stream, "write"):
            stream.write(diff_content)
            if hasattr(stream, "flush"):
                stream.flush()

        # Test that some output was produced
        result = self.output.getvalue()
        self.assertGreaterEqual(len(result), 0)