View Javadoc
1   /*
2    * Copyright (C) 2008-2009, Google Inc.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.patch;
45  
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertFalse;
48  import static org.junit.Assert.assertNotNull;
49  import static org.junit.Assert.assertNull;
50  import static org.junit.Assert.assertSame;
51  import static org.junit.Assert.assertTrue;
52  import static org.junit.Assert.fail;
53  
54  import java.io.IOException;
55  import java.io.InputStream;
56  
57  import org.eclipse.jgit.junit.JGitTestUtil;
58  import org.eclipse.jgit.lib.FileMode;
59  import org.eclipse.jgit.lib.ObjectId;
60  import org.junit.Test;
61  
62  public class PatchTest {
63  	@Test
64  	public void testEmpty() {
65  		final Patch p = new Patch();
66  		assertTrue(p.getFiles().isEmpty());
67  		assertTrue(p.getErrors().isEmpty());
68  	}
69  
70  	@Test
71  	public void testParse_ConfigCaseInsensitive() throws IOException {
72  		final Patch p = parseTestPatchFile();
73  		assertEquals(2, p.getFiles().size());
74  		assertTrue(p.getErrors().isEmpty());
75  
76  		final FileHeader fRepositoryConfigTest = p.getFiles().get(0);
77  		final FileHeader fRepositoryConfig = p.getFiles().get(1);
78  
79  		assertEquals(
80  				"org.eclipse.jgit.test/tst/org/spearce/jgit/lib/RepositoryConfigTest.java",
81  				fRepositoryConfigTest.getNewPath());
82  
83  		assertEquals(
84  				"org.eclipse.jgit/src/org/spearce/jgit/lib/RepositoryConfig.java",
85  				fRepositoryConfig.getNewPath());
86  
87  		assertEquals(572, fRepositoryConfigTest.startOffset);
88  		assertEquals(1490, fRepositoryConfig.startOffset);
89  
90  		assertEquals("da7e704", fRepositoryConfigTest.getOldId().name());
91  		assertEquals("34ce04a", fRepositoryConfigTest.getNewId().name());
92  		assertSame(FileHeader.PatchType.UNIFIED, fRepositoryConfigTest
93  				.getPatchType());
94  		assertSame(FileMode.REGULAR_FILE, fRepositoryConfigTest.getOldMode());
95  		assertSame(FileMode.REGULAR_FILE, fRepositoryConfigTest.getNewMode());
96  		assertEquals(1, fRepositoryConfigTest.getHunks().size());
97  		{
98  			final HunkHeader h = fRepositoryConfigTest.getHunks().get(0);
99  			assertSame(fRepositoryConfigTest, h.getFileHeader());
100 			assertEquals(921, h.startOffset);
101 			assertEquals(109, h.getOldImage().getStartLine());
102 			assertEquals(4, h.getOldImage().getLineCount());
103 			assertEquals(109, h.getNewStartLine());
104 			assertEquals(11, h.getNewLineCount());
105 
106 			assertEquals(4, h.getLinesContext());
107 			assertEquals(7, h.getOldImage().getLinesAdded());
108 			assertEquals(0, h.getOldImage().getLinesDeleted());
109 			assertSame(fRepositoryConfigTest.getOldId(), h.getOldImage()
110 					.getId());
111 
112 			assertEquals(1490, h.endOffset);
113 		}
114 
115 		assertEquals("45c2f8a", fRepositoryConfig.getOldId().name());
116 		assertEquals("3291bba", fRepositoryConfig.getNewId().name());
117 		assertSame(FileHeader.PatchType.UNIFIED, fRepositoryConfig
118 				.getPatchType());
119 		assertSame(FileMode.REGULAR_FILE, fRepositoryConfig.getOldMode());
120 		assertSame(FileMode.REGULAR_FILE, fRepositoryConfig.getNewMode());
121 		assertEquals(3, fRepositoryConfig.getHunks().size());
122 		{
123 			final HunkHeader h = fRepositoryConfig.getHunks().get(0);
124 			assertSame(fRepositoryConfig, h.getFileHeader());
125 			assertEquals(1803, h.startOffset);
126 			assertEquals(236, h.getOldImage().getStartLine());
127 			assertEquals(9, h.getOldImage().getLineCount());
128 			assertEquals(236, h.getNewStartLine());
129 			assertEquals(9, h.getNewLineCount());
130 
131 			assertEquals(7, h.getLinesContext());
132 			assertEquals(2, h.getOldImage().getLinesAdded());
133 			assertEquals(2, h.getOldImage().getLinesDeleted());
134 			assertSame(fRepositoryConfig.getOldId(), h.getOldImage().getId());
135 
136 			assertEquals(2434, h.endOffset);
137 		}
138 		{
139 			final HunkHeader h = fRepositoryConfig.getHunks().get(1);
140 			assertEquals(2434, h.startOffset);
141 			assertEquals(300, h.getOldImage().getStartLine());
142 			assertEquals(7, h.getOldImage().getLineCount());
143 			assertEquals(300, h.getNewStartLine());
144 			assertEquals(7, h.getNewLineCount());
145 
146 			assertEquals(6, h.getLinesContext());
147 			assertEquals(1, h.getOldImage().getLinesAdded());
148 			assertEquals(1, h.getOldImage().getLinesDeleted());
149 
150 			assertEquals(2816, h.endOffset);
151 		}
152 		{
153 			final HunkHeader h = fRepositoryConfig.getHunks().get(2);
154 			assertEquals(2816, h.startOffset);
155 			assertEquals(954, h.getOldImage().getStartLine());
156 			assertEquals(7, h.getOldImage().getLineCount());
157 			assertEquals(954, h.getNewStartLine());
158 			assertEquals(7, h.getNewLineCount());
159 
160 			assertEquals(6, h.getLinesContext());
161 			assertEquals(1, h.getOldImage().getLinesAdded());
162 			assertEquals(1, h.getOldImage().getLinesDeleted());
163 
164 			assertEquals(3035, h.endOffset);
165 		}
166 	}
167 
168 	@Test
169 	public void testParse_NoBinary() throws IOException {
170 		final Patch p = parseTestPatchFile();
171 		assertEquals(5, p.getFiles().size());
172 		assertTrue(p.getErrors().isEmpty());
173 
174 		for (int i = 0; i < 4; i++) {
175 			final FileHeader fh = p.getFiles().get(i);
176 			assertSame(FileHeader.ChangeType.ADD, fh.getChangeType());
177 			assertNotNull(fh.getOldId());
178 			assertNotNull(fh.getNewId());
179 			assertEquals("0000000", fh.getOldId().name());
180 			assertSame(FileMode.MISSING, fh.getOldMode());
181 			assertSame(FileMode.REGULAR_FILE, fh.getNewMode());
182 			assertTrue(fh.getNewPath().startsWith(
183 					"org.spearce.egit.ui/icons/toolbar/"));
184 			assertSame(FileHeader.PatchType.BINARY, fh.getPatchType());
185 			assertTrue(fh.getHunks().isEmpty());
186 			assertTrue(fh.hasMetaDataChanges());
187 
188 			assertNull(fh.getForwardBinaryHunk());
189 			assertNull(fh.getReverseBinaryHunk());
190 		}
191 
192 		final FileHeader fh = p.getFiles().get(4);
193 		assertEquals("org.spearce.egit.ui/plugin.xml", fh.getNewPath());
194 		assertSame(FileHeader.ChangeType.MODIFY, fh.getChangeType());
195 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
196 		assertFalse(fh.hasMetaDataChanges());
197 		assertEquals("ee8a5a0", fh.getNewId().name());
198 		assertNull(fh.getForwardBinaryHunk());
199 		assertNull(fh.getReverseBinaryHunk());
200 		assertEquals(1, fh.getHunks().size());
201 		assertEquals(272, fh.getHunks().get(0).getOldImage().getStartLine());
202 	}
203 
204 	@Test
205 	public void testParse_GitBinaryLiteral() throws IOException {
206 		final Patch p = parseTestPatchFile();
207 		final int[] binsizes = { 359, 393, 372, 404 };
208 		assertEquals(5, p.getFiles().size());
209 		assertTrue(p.getErrors().isEmpty());
210 
211 		for (int i = 0; i < 4; i++) {
212 			final FileHeader fh = p.getFiles().get(i);
213 			assertSame(FileHeader.ChangeType.ADD, fh.getChangeType());
214 			assertNotNull(fh.getOldId());
215 			assertNotNull(fh.getNewId());
216 			assertEquals(ObjectId.zeroId().name(), fh.getOldId().name());
217 			assertSame(FileMode.REGULAR_FILE, fh.getNewMode());
218 			assertTrue(fh.getNewPath().startsWith(
219 					"org.spearce.egit.ui/icons/toolbar/"));
220 			assertSame(FileHeader.PatchType.GIT_BINARY, fh.getPatchType());
221 			assertTrue(fh.getHunks().isEmpty());
222 			assertTrue(fh.hasMetaDataChanges());
223 
224 			final BinaryHunk fwd = fh.getForwardBinaryHunk();
225 			final BinaryHunk rev = fh.getReverseBinaryHunk();
226 			assertNotNull(fwd);
227 			assertNotNull(rev);
228 			assertEquals(binsizes[i], fwd.getSize());
229 			assertEquals(0, rev.getSize());
230 
231 			assertSame(fh, fwd.getFileHeader());
232 			assertSame(fh, rev.getFileHeader());
233 
234 			assertSame(BinaryHunk.Type.LITERAL_DEFLATED, fwd.getType());
235 			assertSame(BinaryHunk.Type.LITERAL_DEFLATED, rev.getType());
236 		}
237 
238 		final FileHeader fh = p.getFiles().get(4);
239 		assertEquals("org.spearce.egit.ui/plugin.xml", fh.getNewPath());
240 		assertSame(FileHeader.ChangeType.MODIFY, fh.getChangeType());
241 		assertSame(FileHeader.PatchType.UNIFIED, fh.getPatchType());
242 		assertFalse(fh.hasMetaDataChanges());
243 		assertEquals("ee8a5a0", fh.getNewId().name());
244 		assertNull(fh.getForwardBinaryHunk());
245 		assertNull(fh.getReverseBinaryHunk());
246 		assertEquals(1, fh.getHunks().size());
247 		assertEquals(272, fh.getHunks().get(0).getOldImage().getStartLine());
248 	}
249 
250 	@Test
251 	public void testParse_GitBinaryDelta() throws IOException {
252 		final Patch p = parseTestPatchFile();
253 		assertEquals(1, p.getFiles().size());
254 		assertTrue(p.getErrors().isEmpty());
255 
256 		final FileHeader fh = p.getFiles().get(0);
257 		assertTrue(fh.getNewPath().startsWith("zero.bin"));
258 		assertSame(FileHeader.ChangeType.MODIFY, fh.getChangeType());
259 		assertSame(FileHeader.PatchType.GIT_BINARY, fh.getPatchType());
260 		assertSame(FileMode.REGULAR_FILE, fh.getNewMode());
261 
262 		assertNotNull(fh.getOldId());
263 		assertNotNull(fh.getNewId());
264 		assertEquals("08e7df176454f3ee5eeda13efa0adaa54828dfd8", fh.getOldId()
265 				.name());
266 		assertEquals("d70d8710b6d32ff844af0ee7c247e4b4b051867f", fh.getNewId()
267 				.name());
268 
269 		assertTrue(fh.getHunks().isEmpty());
270 		assertFalse(fh.hasMetaDataChanges());
271 
272 		final BinaryHunk fwd = fh.getForwardBinaryHunk();
273 		final BinaryHunk rev = fh.getReverseBinaryHunk();
274 		assertNotNull(fwd);
275 		assertNotNull(rev);
276 		assertEquals(12, fwd.getSize());
277 		assertEquals(11, rev.getSize());
278 
279 		assertSame(fh, fwd.getFileHeader());
280 		assertSame(fh, rev.getFileHeader());
281 
282 		assertSame(BinaryHunk.Type.DELTA_DEFLATED, fwd.getType());
283 		assertSame(BinaryHunk.Type.DELTA_DEFLATED, rev.getType());
284 
285 		assertEquals(496, fh.endOffset);
286 	}
287 
288 	@Test
289 	public void testParse_FixNoNewline() throws IOException {
290 		final Patch p = parseTestPatchFile();
291 		assertEquals(1, p.getFiles().size());
292 		assertTrue(p.getErrors().isEmpty());
293 
294 		final FileHeader f = p.getFiles().get(0);
295 
296 		assertEquals("a", f.getNewPath());
297 		assertEquals(252, f.startOffset);
298 
299 		assertEquals("2e65efe", f.getOldId().name());
300 		assertEquals("f2ad6c7", f.getNewId().name());
301 		assertSame(FileHeader.PatchType.UNIFIED, f.getPatchType());
302 		assertSame(FileMode.REGULAR_FILE, f.getOldMode());
303 		assertSame(FileMode.REGULAR_FILE, f.getNewMode());
304 		assertEquals(1, f.getHunks().size());
305 		{
306 			final HunkHeader h = f.getHunks().get(0);
307 			assertSame(f, h.getFileHeader());
308 			assertEquals(317, h.startOffset);
309 			assertEquals(1, h.getOldImage().getStartLine());
310 			assertEquals(1, h.getOldImage().getLineCount());
311 			assertEquals(1, h.getNewStartLine());
312 			assertEquals(1, h.getNewLineCount());
313 
314 			assertEquals(0, h.getLinesContext());
315 			assertEquals(1, h.getOldImage().getLinesAdded());
316 			assertEquals(1, h.getOldImage().getLinesDeleted());
317 			assertSame(f.getOldId(), h.getOldImage().getId());
318 
319 			assertEquals(363, h.endOffset);
320 		}
321 	}
322 
323 	@Test
324 	public void testParse_AddNoNewline() throws IOException {
325 		final Patch p = parseTestPatchFile();
326 		assertEquals(1, p.getFiles().size());
327 		assertTrue(p.getErrors().isEmpty());
328 
329 		final FileHeader f = p.getFiles().get(0);
330 
331 		assertEquals("a", f.getNewPath());
332 		assertEquals(256, f.startOffset);
333 
334 		assertEquals("f2ad6c7", f.getOldId().name());
335 		assertEquals("c59d9b6", f.getNewId().name());
336 		assertSame(FileHeader.PatchType.UNIFIED, f.getPatchType());
337 		assertSame(FileMode.REGULAR_FILE, f.getOldMode());
338 		assertSame(FileMode.REGULAR_FILE, f.getNewMode());
339 		assertEquals(1, f.getHunks().size());
340 		{
341 			final HunkHeader h = f.getHunks().get(0);
342 			assertSame(f, h.getFileHeader());
343 			assertEquals(321, h.startOffset);
344 			assertEquals(1, h.getOldImage().getStartLine());
345 			assertEquals(1, h.getOldImage().getLineCount());
346 			assertEquals(1, h.getNewStartLine());
347 			assertEquals(1, h.getNewLineCount());
348 
349 			assertEquals(0, h.getLinesContext());
350 			assertEquals(1, h.getOldImage().getLinesAdded());
351 			assertEquals(1, h.getOldImage().getLinesDeleted());
352 			assertSame(f.getOldId(), h.getOldImage().getId());
353 
354 			assertEquals(367, h.endOffset);
355 		}
356 	}
357 
358 	private Patch parseTestPatchFile() throws IOException {
359 		final String patchFile = JGitTestUtil.getName() + ".patch";
360 		try (InputStream in = getClass().getResourceAsStream(patchFile)) {
361 			if (in == null) {
362 				fail("No " + patchFile + " test vector");
363 				return null; // Never happens
364 			}
365 			final Patch p = new Patch();
366 			p.parse(in);
367 			return p;
368 		}
369 	}
370 }