6.1 KB287 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {CommitRev} from '../common';
9
10import {ABSENT_FLAG} from '../common';
11import {applyDiffSplit, diffCommit, displayDiff} from '../diffSplit';
12import {linearStackWithFiles} from './commitStackState.test';
13
14describe('diffCommit', () => {
15 const stack = linearStackWithFiles([
16 {'x.txt': {dataBase85: 'HHa&FWG5;0PL2'}, 'z.txt': {data: ''}},
17 {'x.txt': {data: '1\n2\n3\n4\n'}},
18 {'x.txt': null, 'y.txt': {copyFrom: 'x.txt', data: '3\n4\n5\n6', flags: 'x'}},
19 {'z.txt': null},
20 ]);
21
22 it('exports commit diff as json', () => {
23 // Commit 2 includes deletion of "x.txt", and rename from "x.txt" to "y.txt".
24 // Right now we don't "optimize" the diff to exclude the deletion.
25 const diff = diffCommit(stack, 2 as CommitRev);
26 expect(diff).toMatchInlineSnapshot(`
27 {
28 "files": [
29 {
30 "aFlag": "",
31 "aPath": "x.txt",
32 "bFlag": "a",
33 "bPath": "x.txt",
34 "lines": [
35 {
36 "a": 0,
37 "b": null,
38 "content": "1
39 ",
40 },
41 {
42 "a": 1,
43 "b": null,
44 "content": "2
45 ",
46 },
47 {
48 "a": 2,
49 "b": null,
50 "content": "3
51 ",
52 },
53 {
54 "a": 3,
55 "b": null,
56 "content": "4
57 ",
58 },
59 ],
60 },
61 {
62 "aFlag": "",
63 "aPath": "x.txt",
64 "bFlag": "x",
65 "bPath": "y.txt",
66 "lines": [
67 {
68 "a": 0,
69 "b": null,
70 "content": "1
71 ",
72 },
73 {
74 "a": 1,
75 "b": null,
76 "content": "2
77 ",
78 },
79 {
80 "a": 2,
81 "b": 0,
82 "content": "3
83 ",
84 },
85 {
86 "a": 3,
87 "b": 1,
88 "content": "4
89 ",
90 },
91 {
92 "a": null,
93 "b": 2,
94 "content": "5
95 ",
96 },
97 {
98 "a": null,
99 "b": 3,
100 "content": "6",
101 },
102 ],
103 },
104 ],
105 "message": "Commit 2",
106 }
107 `);
108 expect(displayDiff(diff)).toMatchInlineSnapshot(`
109 "Commit 2
110 diff a/x.txt b/x.txt
111 deleted file mode 100644
112 -1
113 -2
114 -3
115 -4
116 diff a/x.txt b/y.txt
117 old mode 100644
118 new mode 100755
119 copy from x.txt
120 copy to y.txt
121 -1
122 -2
123 3
124 4
125 +5
126 +6
127 \\ No newline at end of file"
128 `);
129 });
130
131 it('skips binary changes', () => {
132 // Commit 1 modifies "x.txt" from binary to text. It is skipped because the binary data.
133 const diff = diffCommit(stack, 1 as CommitRev);
134 expect(diff).toMatchInlineSnapshot(`
135 {
136 "files": [],
137 "message": "Commit 1",
138 }
139 `);
140 expect(displayDiff(diff)).toMatchInlineSnapshot(`
141 "Commit 1
142 "
143 `);
144 });
145
146 it('reports deletion of an empty file', () => {
147 // Commit 3 deletes "z.txt". It should be reported despite the content diff is empty.
148 const diff = diffCommit(stack, 3 as CommitRev);
149 expect(diff).toMatchInlineSnapshot(`
150 {
151 "files": [
152 {
153 "aFlag": "",
154 "aPath": "z.txt",
155 "bFlag": "a",
156 "bPath": "z.txt",
157 "lines": [],
158 },
159 ],
160 "message": "Commit 3",
161 }
162 `);
163 expect(displayDiff(diff)).toMatchInlineSnapshot(`
164 "Commit 3
165 diff a/z.txt b/z.txt
166 deleted file mode 100644
167 "
168 `);
169 });
170});
171
172describe('applyDiffSplit', () => {
173 it('works in a basic case', () => {
174 const stack = linearStackWithFiles([
175 {'x.txt': {data: '', flags: ABSENT_FLAG}},
176 {'x.txt': {data: '1\n2\n3\n4\n'}},
177 {'x.txt': {data: '3\n4\n5\n6\n'}},
178 {'x.txt': {data: '3\n4\n5\n6\n7\n'}},
179 ]);
180 const diff = diffCommit(stack, 2 as CommitRev);
181 expect(diff.files[0].lines).toMatchInlineSnapshot(`
182 [
183 {
184 "a": 0,
185 "b": null,
186 "content": "1
187 ",
188 },
189 {
190 "a": 1,
191 "b": null,
192 "content": "2
193 ",
194 },
195 {
196 "a": 2,
197 "b": 0,
198 "content": "3
199 ",
200 },
201 {
202 "a": 3,
203 "b": 1,
204 "content": "4
205 ",
206 },
207 {
208 "a": null,
209 "b": 2,
210 "content": "5
211 ",
212 },
213 {
214 "a": null,
215 "b": 3,
216 "content": "6
217 ",
218 },
219 ]
220 `);
221 expect(displayDiff(diff)).toMatchInlineSnapshot(`
222 "Commit 2
223 diff a/x.txt b/x.txt
224 -1
225 -2
226 3
227 4
228 +5
229 +6
230 "
231 `);
232
233 // Pick "-2" and "+5" in the first commit, "+6" in the 2nd, and does not specify the 3rd.
234 const newStack = applyDiffSplit(stack, 2 as CommitRev, [
235 {message: 'Commit 2a', files: [{bPath: 'x.txt', aLines: [1], bLines: [2]}]},
236 {message: 'Commit 2b', files: [{bPath: 'x.txt', aLines: [], bLines: [3]}]},
237 {message: 'Commit 2c', files: []},
238 ]);
239 expect(
240 [0, 1, 2, 3, 4, 5].map(i => displayDiff(diffCommit(newStack, i as CommitRev))).join('\n'),
241 ).toMatchInlineSnapshot(`
242 "Commit 0
243
244 Commit 1
245 diff a/x.txt b/x.txt
246 new file mode 100644
247 +1
248 +2
249 +3
250 +4
251
252 Commit 2a
253 diff a/x.txt b/x.txt
254 1
255 -2
256 3
257 4
258 +5
259
260 Commit 2b
261 diff a/x.txt b/x.txt
262 1
263 3
264 4
265 5
266 +6
267
268 Commit 2c
269 diff a/x.txt b/x.txt
270 -1
271 3
272 4
273 5
274 6
275
276 Commit 3
277 diff a/x.txt b/x.txt
278 3
279 4
280 5
281 6
282 +7
283 "
284 `);
285 });
286});
287