Completed
Pull Request — master (#2132)
by Udayan
01:48
created

DiffTest.test_affected_code()   B

Complexity

Conditions 1

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 26
rs 8.8571
1
import json
2
import unittest
3
from unittest.case import SkipTest
4
5
from coalib.output.JSONEncoder import create_json_encoder
6
from coalib.results.Diff import ConflictError, Diff, SourceRange
7
8
9
class DiffTest(unittest.TestCase):
10
11
    def setUp(self):
12
        self.file = ["1", "2", "3", "4"]
13
        self.uut = Diff(self.file)
14
15
    def test_add_lines(self):
16
        self.uut.add_lines(0, [])
17
        self.uut.add_lines(0, ["t"])
18
        self.uut.add_lines(0, [])
19
20
        # No double addition allowed
21
        self.assertRaises(ConflictError, self.uut.add_lines, 0, ["t"])
22
        self.assertRaises(ValueError, self.uut.add_lines, -1, ["t"])
23
        self.assertRaises(TypeError, self.uut.add_lines, "str", ["t"])
24
25
    def test_delete_line(self):
26
        self.uut.delete_line(1)
27
        self.uut.delete_line(1)  # Double deletion possible without conflict
28
        self.assertRaises(ValueError, self.uut.delete_line, 0)
29
30
    def test_change_line(self):
31
        self.assertEqual(len(self.uut), 0)
32
        self.uut.change_line(2, "1", "2")
33
        self.assertEqual(len(self.uut), 2)
34
        self.assertRaises(ConflictError, self.uut.change_line, 2, "1", "3")
35
        self.assertRaises(ValueError, self.uut.change_line, 0, "1", "2")
36
37
        self.uut.delete_line(1)
38
        # Line was deleted, unchangeable
39
        self.assertRaises(ConflictError, self.uut.change_line, 1, "1", "2")
40
41
    def test_affected_code(self):
42
        self.assertEqual(self.uut.affected_code("file"), [])
43
44
        self.uut.add_lines(0, ["test"])
45
        affected_code = [
46
            SourceRange.from_values("file", start_line=1)]
47
        self.assertEqual(self.uut.affected_code("file"), affected_code)
48
49
        self.uut.delete_line(2)
50
        affected_code = [
51
            SourceRange.from_values("file", start_line=1),
52
            SourceRange.from_values("file", start_line=2)]
53
        self.assertEqual(self.uut.affected_code("file"), affected_code)
54
55
        self.uut.delete_line(3)
56
        affected_code = [
57
            SourceRange.from_values("file", start_line=1),
58
            SourceRange.from_values("file", start_line=2, end_line=3)]
59
        self.assertEqual(self.uut.affected_code("file"), affected_code)
60
61
        self.uut.delete_line(6)
62
        affected_code = [
63
            SourceRange.from_values("file", start_line=1),
64
            SourceRange.from_values("file", start_line=2, end_line=3),
65
            SourceRange.from_values('file', start_line=6)]
66
        self.assertEqual(self.uut.affected_code("file"), affected_code)
67
68
    def test_len(self):
69
        self.uut.delete_line(2)
70
        self.assertEqual(len(self.uut), 1)
71
        self.uut.add_lines(2, ["2.3", "2.5", "2.6"])
72
        self.assertEqual(len(self.uut), 4)
73
        self.uut.change_line(1, "1", "1.1")
74
        self.assertEqual(len(self.uut), 6)
75
76
    def test_stats(self):
77
        self.uut.delete_line(2)
78
        self.assertEqual(self.uut.stats(), (0, 1))
79
        self.uut.add_lines(2, ["2.3", "2.5", "2.6"])
80
        self.assertEqual(self.uut.stats(), (3, 1))
81
        self.uut.change_line(1, "1", "1.1")
82
        self.assertEqual(self.uut.stats(), (4, 2))
83
84
    def test_modified(self):
85
        result_file = ["0.1",
86
                       "0.2",
87
                       "1",
88
                       "1.1",
89
                       "3.changed",
90
                       "4"]
91
92
        self.uut.delete_line(2)
93
        self.uut.add_lines(0, ["0.1", "0.2"])
94
        self.uut.add_lines(1, ["1.1"])
95
        self.uut.change_line(3, "3", "3.changed")
96
97
        # If delete is True then modified returns an empty list
98
        self.uut.delete = True
99
        self.assertEqual(self.uut.modified, [])
100
        self.uut.delete = False
101
102
        self.assertEqual(self.uut.modified, result_file)
103
        self.assertEqual(self.uut.original, self.file)
104
105
        self.uut.delete_line(len(self.file))
106
        del result_file[len(result_file) - 1]
107
        self.assertEqual(self.uut.modified, result_file)
108
109
        self.uut.delete_line(1)
110
        del result_file[2]
111
        self.assertEqual(self.uut.modified, result_file)
112
113
    def test_addition(self):
114
        self.assertRaises(TypeError, self.uut.__add__, 5)
115
116
        result_file = ["1",
117
                       "2",
118
                       "2"]
119
120
        other = Diff(self.file)
121
        other.delete_line(1)
122
        other.change_line(2, "1", "2")
123
        other.add_lines(0, ["1"])
124
125
        self.uut.delete_line(1)
126
        self.uut.delete_line(3)
127
        self.uut.change_line(4, "4", "2")
128
        result = self.uut + other
129
130
        self.assertEqual(result.modified, result_file)
131
        # Make sure it didn't happen in place!
132
        self.assertNotEqual(self.uut.modified, result_file)
133
134
    def test_addition_rename(self):
135
        uut = Diff(self.file, rename=False)
136
        other = Diff(self.file, rename=False)
137
        self.assertEqual((other + uut).rename, False)
138
139
        other.rename = "some.py"
140
        self.assertEqual((other + uut).rename, "some.py")
141
142
        uut.rename = "some.py"
143
        self.assertEqual((other + uut).rename, "some.py")
144
145
        uut.rename = "other.py"
146
        self.assertRaises(ConflictError, other.__add__, uut)
147
148
    def test_from_string_arrays(self):
149
        a = ["q", "a", "b", "x", "c", "d"]
150
        b = ["a", "b", "y", "c", "d", "f"]
151
        self.uut = Diff.from_string_arrays(a, b)
152
        self.assertEqual(self.uut.modified, b)
153
154
        a = ["first", "fourth"]
155
        b = ["first", "second", "third", "fourth"]
156
        self.uut = Diff.from_string_arrays(a, b)
157
        self.assertEqual(self.uut.modified, b)
158
159
        a = ["first", "fourth"]
160
        b = ["first_changed", "second", "third", "fourth"]
161
        self.uut = Diff.from_string_arrays(a, b)
162
        self.assertEqual(self.uut.modified, b)
163
164
        a = ["first", "second", "third", "fourth"]
165
        b = ["first", "fourth"]
166
        self.uut = Diff.from_string_arrays(a, b)
167
        self.assertEqual(self.uut.modified, b)
168
169
        a = ["first", "second", "third", "fourth"]
170
        b = ["first_changed", "second_changed", "fourth"]
171
        self.uut = Diff.from_string_arrays(a, b)
172
        self.assertEqual(self.uut.modified, b)
173
174
    def test_from_clang_fixit(self):
175
        try:
176
            from clang.cindex import Index, LibclangError
177
        except ImportError as err:
178
            raise SkipTest(str(err))
179
180
        joined_file = 'struct { int f0; }\nx = { f0 :1 };\n'
181
        file = joined_file.splitlines(True)
182
        fixed_file = ['struct { int f0; }\n', 'x = { .f0 = 1 };\n']
183
        try:
184
            tu = Index.create().parse('t.c', unsaved_files=[
185
                ('t.c', joined_file)])
186
        except LibclangError as err:
187
            raise SkipTest(str(err))
188
189
        fixit = tu.diagnostics[0].fixits[0]
190
        clang_fixed_file = Diff.from_clang_fixit(fixit, file).modified
191
        self.assertEqual(fixed_file, clang_fixed_file)
192
193
    def test_equality(self):
194
        a = ["first", "second", "third"]
195
        b = ["first", "third"]
196
        diff_1 = Diff.from_string_arrays(a, b)
197
198
        a[1] = "else"
199
        diff_2 = Diff.from_string_arrays(a, b)
200
        self.assertEqual(diff_1, diff_2)
201
202
        diff_1.rename = "abcd"
203
        self.assertNotEqual(diff_1, diff_2)
204
        diff_1.rename = False
205
206
        diff_1.delete = True
207
        self.assertNotEqual(diff_1, diff_2)
208
        diff_1.delete = False
209
210
        diff_1.add_lines(1, ["1"])
211
        self.assertNotEqual(diff_1, diff_2)
212
213
    def test_json_export(self):
214
        JSONEncoder = create_json_encoder()
215
        a = ["first\n", "second\n", "third\n"]
216
        b = ["first\n", "third\n"]
217
        diff = Diff.from_string_arrays(a, b)
218
        self.assertEqual(
219
            json.dumps(diff, cls=JSONEncoder, sort_keys=True),
220
            '"--- \\n'
221
            '+++ \\n'
222
            '@@ -1,3 +1,2 @@\\n'
223
            ' first\\n'
224
            '-second\\n'
225
            ' third\\n"')
226
227
    def test_rename(self):
228
        self.uut.rename = False
229
        self.uut.rename = "1234"
230
        with self.assertRaises(TypeError):
231
            self.uut.rename = True
232
        with self.assertRaises(TypeError):
233
            self.uut.rename = 1234
234
235
    def test_delete(self):
236
        self.uut.delete = True
237
        self.uut.delete = False
238
        # Double deletion is allowed
239
        self.uut.delete = False
240
        with self.assertRaises(TypeError):
241
            self.uut.delete = "abcd"
242