View Javadoc
1   /*
2    * Copyright (C) 2008, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.patch;
12  
13  import static org.junit.Assert.assertEquals;
14  import static org.junit.Assert.assertFalse;
15  import static org.junit.Assert.assertNotNull;
16  import static org.junit.Assert.assertNull;
17  import static org.junit.Assert.assertSame;
18  import static org.junit.Assert.assertTrue;
19  
20  import org.eclipse.jgit.diff.DiffEntry;
21  import org.eclipse.jgit.lib.Constants;
22  import org.eclipse.jgit.lib.FileMode;
23  import org.eclipse.jgit.lib.ObjectId;
24  import org.junit.Test;
25  
26  public class FileHeaderTest {
27  	@Test
28  	public void testParseGitFileName_Empty() {
29  		final FileHeader fh = data("");
30  		assertEquals(-1, fh.parseGitFileName(0, fh.buf.length));
31  		assertNotNull(fh.getHunks());
32  		assertTrue(fh.getHunks().isEmpty());
33  		assertFalse(fh.hasMetaDataChanges());
34  	}
35  
36  	@Test
37  	public void testParseGitFileName_NoLF() {
38  		final FileHeader fh = data("a/ b/");
39  		assertEquals(-1, fh.parseGitFileName(0, fh.buf.length));
40  	}
41  
42  	@Test
43  	public void testParseGitFileName_NoSecondLine() {
44  		final FileHeader fh = data("\n");
45  		assertEquals(-1, fh.parseGitFileName(0, fh.buf.length));
46  	}
47  
48  	@Test
49  	public void testParseGitFileName_EmptyHeader() {
50  		final FileHeader fh = data("\n\n");
51  		assertEquals(1, fh.parseGitFileName(0, fh.buf.length));
52  	}
53  
54  	@Test
55  	public void testParseGitFileName_Foo() {
56  		final String name = "foo";
57  		final FileHeader fh = header(name);
58  		assertEquals(gitLine(name).length(), fh.parseGitFileName(0,
59  				fh.buf.length));
60  		assertEquals(name, fh.getOldPath());
61  		assertSame(fh.getOldPath(), fh.getNewPath());
62  		assertFalse(fh.hasMetaDataChanges());
63  	}
64  
65  	@Test
66  	public void testParseGitFileName_FailFooBar() {
67  		final FileHeader fh = data("a/foo b/bar\n-");
68  		assertTrue(fh.parseGitFileName(0, fh.buf.length) > 0);
69  		assertNull(fh.getOldPath());
70  		assertNull(fh.getNewPath());
71  		assertFalse(fh.hasMetaDataChanges());
72  	}
73  
74  	@Test
75  	public void testParseGitFileName_FooSpBar() {
76  		final String name = "foo bar";
77  		final FileHeader fh = header(name);
78  		assertEquals(gitLine(name).length(), fh.parseGitFileName(0,
79  				fh.buf.length));
80  		assertEquals(name, fh.getOldPath());
81  		assertSame(fh.getOldPath(), fh.getNewPath());
82  		assertFalse(fh.hasMetaDataChanges());
83  	}
84  
85  	@Test
86  	public void testParseGitFileName_DqFooTabBar() {
87  		final String name = "foo\tbar";
88  		final String dqName = "foo\\tbar";
89  		final FileHeader fh = dqHeader(dqName);
90  		assertEquals(dqGitLine(dqName).length(), fh.parseGitFileName(0,
91  				fh.buf.length));
92  		assertEquals(name, fh.getOldPath());
93  		assertSame(fh.getOldPath(), fh.getNewPath());
94  		assertFalse(fh.hasMetaDataChanges());
95  	}
96  
97  	@Test
98  	public void testParseGitFileName_DqFooSpLfNulBar() {
99  		final String name = "foo \n\0bar";
100 		final String dqName = "foo \\n\\0bar";
101 		final FileHeader fh = dqHeader(dqName);
102 		assertEquals(dqGitLine(dqName).length(), fh.parseGitFileName(0,
103 				fh.buf.length));
104 		assertEquals(name, fh.getOldPath());
105 		assertSame(fh.getOldPath(), fh.getNewPath());
106 		assertFalse(fh.hasMetaDataChanges());
107 	}
108 
109 	@Test
110 	public void testParseGitFileName_SrcFooC() {
111 		final String name = "src/foo/bar/argh/code.c";
112 		final FileHeader fh = header(name);
113 		assertEquals(gitLine(name).length(), fh.parseGitFileName(0,
114 				fh.buf.length));
115 		assertEquals(name, fh.getOldPath());
116 		assertSame(fh.getOldPath(), fh.getNewPath());
117 		assertFalse(fh.hasMetaDataChanges());
118 	}
119 
120 	@Test
121 	public void testParseGitFileName_SrcFooCNonStandardPrefix() {
122 		final String name = "src/foo/bar/argh/code.c";
123 		final String header = "project-v-1.0/" + name + " mydev/" + name + "\n";
124 		final FileHeader fh = data(header + "-");
125 		assertEquals(header.length(), fh.parseGitFileName(0, fh.buf.length));
126 		assertEquals(name, fh.getOldPath());
127 		assertSame(fh.getOldPath(), fh.getNewPath());
128 		assertFalse(fh.hasMetaDataChanges());
129 	}
130 
131 	@Test
132 	public void testParseUnicodeName_NewFile() {
133 		final FileHeader fh = data("diff --git \"a/\\303\\205ngstr\\303\\266m\" \"b/\\303\\205ngstr\\303\\266m\"\n"
134 				+ "new file mode 100644\n"
135 				+ "index 0000000..7898192\n"
136 				+ "--- /dev/null\n"
137 				+ "+++ \"b/\\303\\205ngstr\\303\\266m\"\n"
138 				+ "@@ -0,0 +1 @@\n" + "+a\n");
139 		assertParse(fh);
140 
141 		assertEquals("/dev/null", fh.getOldPath());
142 		assertSame(DiffEntry.DEV_NULL, fh.getOldPath());
143 		assertEquals("\u00c5ngstr\u00f6m", fh.getNewPath());
144 
145 		assertSame(FileHeader.ChangeType.ADD, fh.getChangeType());
146 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
147 		assertTrue(fh.hasMetaDataChanges());
148 
149 		assertSame(FileMode.MISSING, fh.getOldMode());
150 		assertSame(FileMode.REGULAR_FILE, fh.getNewMode());
151 
152 		assertEquals("0000000", fh.getOldId().name());
153 		assertEquals("7898192", fh.getNewId().name());
154 		assertEquals(0, fh.getScore());
155 	}
156 
157 	@Test
158 	public void testParseUnicodeName_DeleteFile() {
159 		final FileHeader fh = data("diff --git \"a/\\303\\205ngstr\\303\\266m\" \"b/\\303\\205ngstr\\303\\266m\"\n"
160 				+ "deleted file mode 100644\n"
161 				+ "index 7898192..0000000\n"
162 				+ "--- \"a/\\303\\205ngstr\\303\\266m\"\n"
163 				+ "+++ /dev/null\n"
164 				+ "@@ -1 +0,0 @@\n" + "-a\n");
165 		assertParse(fh);
166 
167 		assertEquals("\u00c5ngstr\u00f6m", fh.getOldPath());
168 		assertEquals("/dev/null", fh.getNewPath());
169 		assertSame(DiffEntry.DEV_NULL, fh.getNewPath());
170 
171 		assertSame(FileHeader.ChangeType.DELETE, fh.getChangeType());
172 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
173 		assertTrue(fh.hasMetaDataChanges());
174 
175 		assertSame(FileMode.REGULAR_FILE, fh.getOldMode());
176 		assertSame(FileMode.MISSING, fh.getNewMode());
177 
178 		assertEquals("7898192", fh.getOldId().name());
179 		assertEquals("0000000", fh.getNewId().name());
180 		assertEquals(0, fh.getScore());
181 	}
182 
183 	@Test
184 	public void testParseModeChange() {
185 		final FileHeader fh = data("diff --git a/a b b/a b\n"
186 				+ "old mode 100644\n" + "new mode 100755\n");
187 		assertParse(fh);
188 		assertEquals("a b", fh.getOldPath());
189 		assertEquals("a b", fh.getNewPath());
190 
191 		assertSame(FileHeader.ChangeType.MODIFY, fh.getChangeType());
192 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
193 		assertTrue(fh.hasMetaDataChanges());
194 
195 		assertNull(fh.getOldId());
196 		assertNull(fh.getNewId());
197 
198 		assertSame(FileMode.REGULAR_FILE, fh.getOldMode());
199 		assertSame(FileMode.EXECUTABLE_FILE, fh.getNewMode());
200 		assertEquals(0, fh.getScore());
201 	}
202 
203 	@Test
204 	public void testParseRename100_NewStyle() {
205 		final FileHeader fh = data("diff --git a/a b/ c/\\303\\205ngstr\\303\\266m\n"
206 				+ "similarity index 100%\n"
207 				+ "rename from a\n"
208 				+ "rename to \" c/\\303\\205ngstr\\303\\266m\"\n");
209 		int ptr = fh.parseGitFileName(0, fh.buf.length);
210 		assertTrue(ptr > 0);
211 		assertNull(fh.getOldPath()); // can't parse names on a rename
212 		assertNull(fh.getNewPath());
213 
214 		ptr = fh.parseGitHeaders(ptr, fh.buf.length);
215 		assertTrue(ptr > 0);
216 
217 		assertEquals("a", fh.getOldPath());
218 		assertEquals(" c/\u00c5ngstr\u00f6m", fh.getNewPath());
219 
220 		assertSame(FileHeader.ChangeType.RENAME, fh.getChangeType());
221 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
222 		assertTrue(fh.hasMetaDataChanges());
223 
224 		assertNull(fh.getOldId());
225 		assertNull(fh.getNewId());
226 
227 		assertNull(fh.getOldMode());
228 		assertNull(fh.getNewMode());
229 
230 		assertEquals(100, fh.getScore());
231 	}
232 
233 	@Test
234 	public void testParseRename100_OldStyle() {
235 		final FileHeader fh = data("diff --git a/a b/ c/\\303\\205ngstr\\303\\266m\n"
236 				+ "similarity index 100%\n"
237 				+ "rename old a\n"
238 				+ "rename new \" c/\\303\\205ngstr\\303\\266m\"\n");
239 		int ptr = fh.parseGitFileName(0, fh.buf.length);
240 		assertTrue(ptr > 0);
241 		assertNull(fh.getOldPath()); // can't parse names on a rename
242 		assertNull(fh.getNewPath());
243 
244 		ptr = fh.parseGitHeaders(ptr, fh.buf.length);
245 		assertTrue(ptr > 0);
246 
247 		assertEquals("a", fh.getOldPath());
248 		assertEquals(" c/\u00c5ngstr\u00f6m", fh.getNewPath());
249 
250 		assertSame(FileHeader.ChangeType.RENAME, fh.getChangeType());
251 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
252 		assertTrue(fh.hasMetaDataChanges());
253 
254 		assertNull(fh.getOldId());
255 		assertNull(fh.getNewId());
256 
257 		assertNull(fh.getOldMode());
258 		assertNull(fh.getNewMode());
259 
260 		assertEquals(100, fh.getScore());
261 	}
262 
263 	@Test
264 	public void testParseCopy100() {
265 		final FileHeader fh = data("diff --git a/a b/ c/\\303\\205ngstr\\303\\266m\n"
266 				+ "similarity index 100%\n"
267 				+ "copy from a\n"
268 				+ "copy to \" c/\\303\\205ngstr\\303\\266m\"\n");
269 		int ptr = fh.parseGitFileName(0, fh.buf.length);
270 		assertTrue(ptr > 0);
271 		assertNull(fh.getOldPath()); // can't parse names on a copy
272 		assertNull(fh.getNewPath());
273 
274 		ptr = fh.parseGitHeaders(ptr, fh.buf.length);
275 		assertTrue(ptr > 0);
276 
277 		assertEquals("a", fh.getOldPath());
278 		assertEquals(" c/\u00c5ngstr\u00f6m", fh.getNewPath());
279 
280 		assertSame(FileHeader.ChangeType.COPY, fh.getChangeType());
281 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
282 		assertTrue(fh.hasMetaDataChanges());
283 
284 		assertNull(fh.getOldId());
285 		assertNull(fh.getNewId());
286 
287 		assertNull(fh.getOldMode());
288 		assertNull(fh.getNewMode());
289 
290 		assertEquals(100, fh.getScore());
291 	}
292 
293 	@Test
294 	public void testParseFullIndexLine_WithMode() {
295 		final String oid = "78981922613b2afb6025042ff6bd878ac1994e85";
296 		final String nid = "61780798228d17af2d34fce4cfbdf35556832472";
297 		final FileHeader fh = data("diff --git a/a b/a\n" + "index " + oid
298 				+ ".." + nid + " 100644\n" + "--- a/a\n" + "+++ b/a\n");
299 		assertParse(fh);
300 
301 		assertEquals("a", fh.getOldPath());
302 		assertEquals("a", fh.getNewPath());
303 
304 		assertSame(FileMode.REGULAR_FILE, fh.getOldMode());
305 		assertSame(FileMode.REGULAR_FILE, fh.getNewMode());
306 		assertFalse(fh.hasMetaDataChanges());
307 
308 		assertNotNull(fh.getOldId());
309 		assertNotNull(fh.getNewId());
310 
311 		assertTrue(fh.getOldId().isComplete());
312 		assertTrue(fh.getNewId().isComplete());
313 
314 		assertEquals(ObjectId.fromString(oid), fh.getOldId().toObjectId());
315 		assertEquals(ObjectId.fromString(nid), fh.getNewId().toObjectId());
316 	}
317 
318 	@Test
319 	public void testParseFullIndexLine_NoMode() {
320 		final String oid = "78981922613b2afb6025042ff6bd878ac1994e85";
321 		final String nid = "61780798228d17af2d34fce4cfbdf35556832472";
322 		final FileHeader fh = data("diff --git a/a b/a\n" + "index " + oid
323 				+ ".." + nid + "\n" + "--- a/a\n" + "+++ b/a\n");
324 		assertParse(fh);
325 
326 		assertEquals("a", fh.getOldPath());
327 		assertEquals("a", fh.getNewPath());
328 		assertFalse(fh.hasMetaDataChanges());
329 
330 		assertNull(fh.getOldMode());
331 		assertNull(fh.getNewMode());
332 
333 		assertNotNull(fh.getOldId());
334 		assertNotNull(fh.getNewId());
335 
336 		assertTrue(fh.getOldId().isComplete());
337 		assertTrue(fh.getNewId().isComplete());
338 
339 		assertEquals(ObjectId.fromString(oid), fh.getOldId().toObjectId());
340 		assertEquals(ObjectId.fromString(nid), fh.getNewId().toObjectId());
341 	}
342 
343 	@Test
344 	public void testParseAbbrIndexLine_WithMode() {
345 		final int a = 7;
346 		final String oid = "78981922613b2afb6025042ff6bd878ac1994e85";
347 		final String nid = "61780798228d17af2d34fce4cfbdf35556832472";
348 		final FileHeader fh = data("diff --git a/a b/a\n" + "index "
349 				+ oid.substring(0, a - 1) + ".." + nid.substring(0, a - 1)
350 				+ " 100644\n" + "--- a/a\n" + "+++ b/a\n");
351 		assertParse(fh);
352 
353 		assertEquals("a", fh.getOldPath());
354 		assertEquals("a", fh.getNewPath());
355 
356 		assertSame(FileMode.REGULAR_FILE, fh.getOldMode());
357 		assertSame(FileMode.REGULAR_FILE, fh.getNewMode());
358 		assertFalse(fh.hasMetaDataChanges());
359 
360 		assertNotNull(fh.getOldId());
361 		assertNotNull(fh.getNewId());
362 
363 		assertFalse(fh.getOldId().isComplete());
364 		assertFalse(fh.getNewId().isComplete());
365 
366 		assertEquals(oid.substring(0, a - 1), fh.getOldId().name());
367 		assertEquals(nid.substring(0, a - 1), fh.getNewId().name());
368 
369 		assertTrue(ObjectId.fromString(oid).startsWith(fh.getOldId()));
370 		assertTrue(ObjectId.fromString(nid).startsWith(fh.getNewId()));
371 	}
372 
373 	@Test
374 	public void testParseAbbrIndexLine_NoMode() {
375 		final int a = 7;
376 		final String oid = "78981922613b2afb6025042ff6bd878ac1994e85";
377 		final String nid = "61780798228d17af2d34fce4cfbdf35556832472";
378 		final FileHeader fh = data("diff --git a/a b/a\n" + "index "
379 				+ oid.substring(0, a - 1) + ".." + nid.substring(0, a - 1)
380 				+ "\n" + "--- a/a\n" + "+++ b/a\n");
381 		assertParse(fh);
382 
383 		assertEquals("a", fh.getOldPath());
384 		assertEquals("a", fh.getNewPath());
385 
386 		assertNull(fh.getOldMode());
387 		assertNull(fh.getNewMode());
388 		assertFalse(fh.hasMetaDataChanges());
389 
390 		assertNotNull(fh.getOldId());
391 		assertNotNull(fh.getNewId());
392 
393 		assertFalse(fh.getOldId().isComplete());
394 		assertFalse(fh.getNewId().isComplete());
395 
396 		assertEquals(oid.substring(0, a - 1), fh.getOldId().name());
397 		assertEquals(nid.substring(0, a - 1), fh.getNewId().name());
398 
399 		assertTrue(ObjectId.fromString(oid).startsWith(fh.getOldId()));
400 		assertTrue(ObjectId.fromString(nid).startsWith(fh.getNewId()));
401 	}
402 
403 	private static void assertParse(FileHeader fh) {
404 		int ptr = fh.parseGitFileName(0, fh.buf.length);
405 		assertTrue(ptr > 0);
406 		ptr = fh.parseGitHeaders(ptr, fh.buf.length);
407 		assertTrue(ptr > 0);
408 	}
409 
410 	private static FileHeader data(String in) {
411 		return new FileHeader(Constants.encodeASCII(in), 0);
412 	}
413 
414 	private static FileHeader header(String path) {
415 		return data(gitLine(path) + "--- " + path + "\n");
416 	}
417 
418 	private static String gitLine(String path) {
419 		return "a/" + path + " b/" + path + "\n";
420 	}
421 
422 	private static FileHeader dqHeader(String path) {
423 		return data(dqGitLine(path) + "--- " + path + "\n");
424 	}
425 
426 	private static String dqGitLine(String path) {
427 		return "\"a/" + path + "\" \"b/" + path + "\"\n";
428 	}
429 }