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

DiffTest.test_double_changes_with_same_diff()   A

Complexity

Conditions 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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