Completed
Pull Request — master (#2655)
by
unknown
01:49
created

DiffTest   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 267
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 26
c 4
b 0
f 0
dl 0
loc 267
rs 10

20 Methods

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