View Javadoc
1   /*
2    * Copyright (C) 2011, Robin Rosenberg 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  package org.eclipse.jgit.dircache;
11  
12  import static org.junit.Assert.assertEquals;
13  import static org.junit.Assert.fail;
14  
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
19  import org.eclipse.jgit.errors.DirCacheNameConflictException;
20  import org.eclipse.jgit.lib.FileMode;
21  import org.eclipse.jgit.lib.ObjectId;
22  import org.junit.Test;
23  
24  public class DirCachePathEditTest {
25  
26  	static final class AddEdit extends PathEdit {
27  
28  		public AddEdit(String entryPath) {
29  			super(entryPath);
30  		}
31  
32  		@Override
33  		public void apply(DirCacheEntry ent) {
34  			ent.setFileMode(FileMode.REGULAR_FILE);
35  			ent.setLength(1);
36  			ent.setObjectId(ObjectId.zeroId());
37  		}
38  
39  	}
40  
41  	private static final class RecordingEdit extends PathEdit {
42  		final List<DirCacheEntry> entries = new ArrayList<>();
43  
44  		public RecordingEdit(String entryPath) {
45  			super(entryPath);
46  		}
47  
48  		@Override
49  		public void apply(DirCacheEntry ent) {
50  			entries.add(ent);
51  		}
52  	}
53  
54  	@Test
55  	public void testAddDeletePathAndTreeNormalNames() {
56  		DirCache dc = DirCache.newInCore();
57  		DirCacheEditor editor = dc.editor();
58  		editor.add(new AddEdit("a"));
59  		editor.add(new AddEdit("b/c"));
60  		editor.add(new AddEdit("c/d"));
61  		editor.finish();
62  		assertEquals(3, dc.getEntryCount());
63  		assertEquals("a", dc.getEntry(0).getPathString());
64  		assertEquals("b/c", dc.getEntry(1).getPathString());
65  		assertEquals("c/d", dc.getEntry(2).getPathString());
66  
67  		editor = dc.editor();
68  		editor.add(new DirCacheEditor.DeletePath("b/c"));
69  		editor.finish();
70  		assertEquals(2, dc.getEntryCount());
71  		assertEquals("a", dc.getEntry(0).getPathString());
72  		assertEquals("c/d", dc.getEntry(1).getPathString());
73  
74  		editor = dc.editor();
75  		editor.add(new DirCacheEditor.DeleteTree(""));
76  		editor.finish();
77  		assertEquals(0, dc.getEntryCount());
78  	}
79  
80  	@Test
81  	public void testAddDeleteTrickyNames() {
82  		DirCache dc = DirCache.newInCore();
83  		DirCacheEditor editor = dc.editor();
84  		editor.add(new AddEdit("a/b"));
85  		editor.add(new AddEdit("a-"));
86  		editor.add(new AddEdit("ab"));
87  		editor.finish();
88  		assertEquals(3, dc.getEntryCount());
89  
90  		// Validate sort order
91  		assertEquals("a-", dc.getEntry(0).getPathString());
92  		assertEquals("a/b", dc.getEntry(1).getPathString());
93  		assertEquals("ab", dc.getEntry(2).getPathString());
94  
95  		editor = dc.editor();
96  
97  		// Sort order should not confuse DeleteTree
98  		editor.add(new DirCacheEditor.DeleteTree("a"));
99  		editor.finish();
100 		assertEquals(2, dc.getEntryCount());
101 		assertEquals("a-", dc.getEntry(0).getPathString());
102 		assertEquals("ab", dc.getEntry(1).getPathString());
103 	}
104 
105 	@Test
106 	public void testPathEditShouldBeCalledForEachStage() throws Exception {
107 		DirCache dc = DirCache.newInCore();
108 		DirCacheBuilder builder = new DirCacheBuilder(dc, 3);
109 		builder.add(createEntry("a", DirCacheEntry.STAGE_1));
110 		builder.add(createEntry("a", DirCacheEntry.STAGE_2));
111 		builder.add(createEntry("a", DirCacheEntry.STAGE_3));
112 		builder.finish();
113 
114 		DirCacheEditor editor = dc.editor();
115 		RecordingEdit recorder = new RecordingEdit("a");
116 		editor.add(recorder);
117 		editor.finish();
118 
119 		List<DirCacheEntry> entries = recorder.entries;
120 		assertEquals(3, entries.size());
121 		assertEquals(DirCacheEntry.STAGE_1, entries.get(0).getStage());
122 		assertEquals(DirCacheEntry.STAGE_2, entries.get(1).getStage());
123 		assertEquals(DirCacheEntry.STAGE_3, entries.get(2).getStage());
124 	}
125 
126 	@Test
127 	public void testFileReplacesTree() throws Exception {
128 		DirCache dc = DirCache.newInCore();
129 		DirCacheEditor editor = dc.editor();
130 		editor.add(new AddEdit("a"));
131 		editor.add(new AddEdit("b/c"));
132 		editor.add(new AddEdit("b/d"));
133 		editor.add(new AddEdit("e"));
134 		editor.finish();
135 
136 		editor = dc.editor();
137 		editor.add(new AddEdit("b"));
138 		editor.finish();
139 
140 		assertEquals(3, dc.getEntryCount());
141 		assertEquals("a", dc.getEntry(0).getPathString());
142 		assertEquals("b", dc.getEntry(1).getPathString());
143 		assertEquals("e", dc.getEntry(2).getPathString());
144 
145 		dc.clear();
146 		editor = dc.editor();
147 		editor.add(new AddEdit("A.c"));
148 		editor.add(new AddEdit("A/c"));
149 		editor.add(new AddEdit("A0c"));
150 		editor.finish();
151 
152 		editor = dc.editor();
153 		editor.add(new AddEdit("A"));
154 		editor.finish();
155 		assertEquals(3, dc.getEntryCount());
156 		assertEquals("A", dc.getEntry(0).getPathString());
157 		assertEquals("A.c", dc.getEntry(1).getPathString());
158 		assertEquals("A0c", dc.getEntry(2).getPathString());
159 	}
160 
161 	@Test
162 	public void testTreeReplacesFile() throws Exception {
163 		DirCache dc = DirCache.newInCore();
164 		DirCacheEditor editor = dc.editor();
165 		editor.add(new AddEdit("a"));
166 		editor.add(new AddEdit("ab"));
167 		editor.add(new AddEdit("b"));
168 		editor.add(new AddEdit("e"));
169 		editor.finish();
170 
171 		editor = dc.editor();
172 		editor.add(new AddEdit("b/c/d/f"));
173 		editor.add(new AddEdit("b/g/h/i"));
174 		editor.finish();
175 
176 		assertEquals(5, dc.getEntryCount());
177 		assertEquals("a", dc.getEntry(0).getPathString());
178 		assertEquals("ab", dc.getEntry(1).getPathString());
179 		assertEquals("b/c/d/f", dc.getEntry(2).getPathString());
180 		assertEquals("b/g/h/i", dc.getEntry(3).getPathString());
181 		assertEquals("e", dc.getEntry(4).getPathString());
182 	}
183 
184 	@Test
185 	public void testDuplicateFiles() throws Exception {
186 		DirCache dc = DirCache.newInCore();
187 		DirCacheEditor editor = dc.editor();
188 		editor.add(new AddEdit("a"));
189 		editor.add(new AddEdit("a"));
190 
191 		try {
192 			editor.finish();
193 			fail("Expected DirCacheNameConflictException to be thrown");
194 		} catch (DirCacheNameConflictException e) {
195 			assertEquals("a a", e.getMessage());
196 			assertEquals("a", e.getPath1());
197 			assertEquals("a", e.getPath2());
198 		}
199 	}
200 
201 	@Test
202 	public void testFileOverlapsTree() throws Exception {
203 		DirCache dc = DirCache.newInCore();
204 		DirCacheEditor editor = dc.editor();
205 		editor.add(new AddEdit("a"));
206 		editor.add(new AddEdit("a/b").setReplace(false));
207 		try {
208 			editor.finish();
209 			fail("Expected DirCacheNameConflictException to be thrown");
210 		} catch (DirCacheNameConflictException e) {
211 			assertEquals("a a/b", e.getMessage());
212 			assertEquals("a", e.getPath1());
213 			assertEquals("a/b", e.getPath2());
214 		}
215 
216 		editor = dc.editor();
217 		editor.add(new AddEdit("A.c"));
218 		editor.add(new AddEdit("A/c").setReplace(false));
219 		editor.add(new AddEdit("A0c"));
220 		editor.add(new AddEdit("A"));
221 		try {
222 			editor.finish();
223 			fail("Expected DirCacheNameConflictException to be thrown");
224 		} catch (DirCacheNameConflictException e) {
225 			assertEquals("A A/c", e.getMessage());
226 			assertEquals("A", e.getPath1());
227 			assertEquals("A/c", e.getPath2());
228 		}
229 
230 		editor = dc.editor();
231 		editor.add(new AddEdit("A.c"));
232 		editor.add(new AddEdit("A/b/c/d").setReplace(false));
233 		editor.add(new AddEdit("A/b/c"));
234 		editor.add(new AddEdit("A0c"));
235 		try {
236 			editor.finish();
237 			fail("Expected DirCacheNameConflictException to be thrown");
238 		} catch (DirCacheNameConflictException e) {
239 			assertEquals("A/b/c A/b/c/d", e.getMessage());
240 			assertEquals("A/b/c", e.getPath1());
241 			assertEquals("A/b/c/d", e.getPath2());
242 		}
243 	}
244 
245 	private static DirCacheEntry createEntry(String path, int stage) {
246 		DirCacheEntry entry = new DirCacheEntry(path, stage);
247 		entry.setFileMode(FileMode.REGULAR_FILE);
248 		return entry;
249 	}
250 }