1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.treewalk.filter;
44
45 import static org.junit.Assert.assertEquals;
46
47 import java.io.IOException;
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.Collections;
51 import java.util.List;
52
53 import org.eclipse.jgit.dircache.DirCache;
54 import org.eclipse.jgit.dircache.DirCacheBuilder;
55 import org.eclipse.jgit.dircache.DirCacheEntry;
56 import org.eclipse.jgit.junit.RepositoryTestCase;
57 import org.eclipse.jgit.lib.FileMode;
58 import org.eclipse.jgit.lib.ObjectId;
59 import org.eclipse.jgit.lib.ObjectInserter;
60 import org.eclipse.jgit.treewalk.TreeWalk;
61 import org.junit.Before;
62 import org.junit.Test;
63
64 public class PathFilterLogicTest extends RepositoryTestCase {
65
66 private ObjectId treeId;
67
68 @Before
69 public void setup() throws IOException {
70 String[] paths = new String[] {
71 "a.txt",
72 "sub1.txt",
73 "sub1/suba/a.txt",
74 "sub1/subb/b.txt",
75 "sub2/suba/a.txt"
76 };
77 treeId = createTree(paths);
78 }
79
80 @Test
81 public void testSinglePath() throws IOException {
82 List<String> expected = Arrays.asList("sub1/suba/a.txt",
83 "sub1/subb/b.txt");
84
85 TreeFilter tf = PathFilter.create("sub1");
86 List<String> paths = getMatchingPaths(treeId, tf);
87
88 assertEquals(expected, paths);
89 }
90
91 @Test
92 public void testSingleSubPath() throws IOException {
93 List<String> expected = Collections.singletonList("sub1/suba/a.txt");
94
95 TreeFilter tf = PathFilter.create("sub1/suba");
96 List<String> paths = getMatchingPaths(treeId, tf);
97
98 assertEquals(expected, paths);
99 }
100
101 @Test
102 public void testSinglePathNegate() throws IOException {
103 List<String> expected = Arrays.asList("a.txt", "sub1.txt",
104 "sub2/suba/a.txt");
105
106 TreeFilter tf = PathFilter.create("sub1").negate();
107 List<String> paths = getMatchingPaths(treeId, tf);
108
109 assertEquals(expected, paths);
110 }
111
112 @Test
113 public void testSingleSubPathNegate() throws IOException {
114 List<String> expected = Arrays.asList("a.txt", "sub1.txt",
115 "sub1/subb/b.txt", "sub2/suba/a.txt");
116
117 TreeFilter tf = PathFilter.create("sub1/suba").negate();
118 List<String> paths = getMatchingPaths(treeId, tf);
119
120 assertEquals(expected, paths);
121 }
122
123 @Test
124 public void testOrMultiTwoPath() throws IOException {
125 List<String> expected = Arrays.asList("sub1/suba/a.txt",
126 "sub1/subb/b.txt", "sub2/suba/a.txt");
127
128 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"),
129 PathFilter.create("sub2")};
130 List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf));
131
132 assertEquals(expected, paths);
133 }
134
135 @Test
136 public void testOrMultiThreePath() throws IOException {
137 List<String> expected = Arrays.asList("sub1.txt", "sub1/suba/a.txt",
138 "sub1/subb/b.txt", "sub2/suba/a.txt");
139
140 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"),
141 PathFilter.create("sub2"), PathFilter.create("sub1.txt")};
142 List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf));
143
144 assertEquals(expected, paths);
145 }
146
147 @Test
148 public void testOrMultiTwoSubPath() throws IOException {
149 List<String> expected = Arrays.asList("sub1/subb/b.txt",
150 "sub2/suba/a.txt");
151
152 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/subb"),
153 PathFilter.create("sub2/suba")};
154 List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf));
155
156 assertEquals(expected, paths);
157 }
158
159 @Test
160 public void testOrMultiTwoMixSubPath() throws IOException {
161 List<String> expected = Arrays.asList("sub1/subb/b.txt",
162 "sub2/suba/a.txt");
163
164 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/subb"),
165 PathFilter.create("sub2")};
166 List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf));
167
168 assertEquals(expected, paths);
169 }
170
171 @Test
172 public void testOrMultiTwoMixSubPathNegate() throws IOException {
173 List<String> expected = Arrays.asList("a.txt", "sub1.txt",
174 "sub1/suba/a.txt", "sub2/suba/a.txt");
175
176 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1").negate(),
177 PathFilter.create("sub1/suba")};
178 List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf));
179
180 assertEquals(expected, paths);
181 }
182
183 @Test
184 public void testOrMultiThreeMixSubPathNegate() throws IOException {
185 List<String> expected = Arrays.asList("a.txt", "sub1.txt",
186 "sub1/suba/a.txt", "sub2/suba/a.txt");
187
188 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1").negate(),
189 PathFilter.create("sub1/suba"), PathFilter.create("no/path")};
190 List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf));
191
192 assertEquals(expected, paths);
193 }
194
195 @Test
196 public void testPatternParentFileMatch() throws IOException {
197 List<String> expected = Collections.emptyList();
198
199 TreeFilter tf = PathFilter.create("a.txt/test/path");
200 List<String> paths = getMatchingPaths(treeId, tf);
201
202 assertEquals(expected, paths);
203 }
204
205 @Test
206 public void testAndMultiPath() throws IOException {
207 List<String> expected = Collections.emptyList();
208
209 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"),
210 PathFilter.create("sub2")};
211 List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf));
212
213 assertEquals(expected, paths);
214 }
215
216 @Test
217 public void testAndMultiPathNegate() throws IOException {
218 List<String> expected = Arrays.asList("sub1/suba/a.txt",
219 "sub1/subb/b.txt");
220
221 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"),
222 PathFilter.create("sub2").negate()};
223 List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf));
224
225 assertEquals(expected, paths);
226 }
227
228 @Test
229 public void testAndMultiSubPathDualNegate() throws IOException {
230 List<String> expected = Arrays.asList("a.txt", "sub1.txt",
231 "sub1/subb/b.txt");
232
233 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/suba").negate(),
234 PathFilter.create("sub2").negate()};
235 List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf));
236
237 assertEquals(expected, paths);
238 }
239
240 @Test
241 public void testAndMultiSubPath() throws IOException {
242 List<String> expected = Collections.emptyList();
243
244 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"),
245 PathFilter.create("sub2/suba")};
246 List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf));
247
248 assertEquals(expected, paths);
249 }
250
251 @Test
252 public void testAndMultiSubPathNegate() throws IOException {
253 List<String> expected = Collections.singletonList("sub1/subb/b.txt");
254
255 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"),
256 PathFilter.create("sub1/suba").negate()};
257 List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf));
258
259 assertEquals(expected, paths);
260 }
261
262 @Test
263 public void testAndMultiThreeSubPathNegate() throws IOException {
264 List<String> expected = Collections.singletonList("sub1/subb/b.txt");
265
266 TreeFilter[] tf = new TreeFilter[]{PathFilter.create("sub1"),
267 PathFilter.create("sub1/suba").negate(),
268 PathFilter.create("no/path").negate()};
269 List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf));
270
271 assertEquals(expected, paths);
272 }
273
274 @Test
275 public void testTopAndMultiPathDualNegate() throws IOException {
276 List<String> expected = Arrays.asList("a.txt", "sub1.txt");
277
278 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1").negate(),
279 PathFilter.create("sub2").negate()};
280 List<String> paths = getMatchingPathsFlat(treeId, AndTreeFilter.create(tf));
281
282 assertEquals(expected, paths);
283 }
284
285 @Test
286 public void testTopAndMultiSubPathDualNegate() throws IOException {
287 List<String> expected = Arrays.asList("a.txt", "sub1.txt", "sub1");
288
289
290
291
292
293 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/suba").negate(),
294 PathFilter.create("sub2").negate()};
295 List<String> paths = getMatchingPathsFlat(treeId, AndTreeFilter.create(tf));
296
297 assertEquals(expected, paths);
298 }
299
300 @Test
301 public void testTopOrMultiPathDual() throws IOException {
302 List<String> expected = Arrays.asList("sub1.txt", "sub2");
303
304 TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1.txt"),
305 PathFilter.create("sub2")};
306 List<String> paths = getMatchingPathsFlat(treeId, OrTreeFilter.create(tf));
307
308 assertEquals(expected, paths);
309 }
310
311 @Test
312 public void testTopNotPath() throws IOException {
313 List<String> expected = Arrays.asList("a.txt", "sub1.txt", "sub2");
314
315 TreeFilter tf = PathFilter.create("sub1");
316 List<String> paths = getMatchingPathsFlat(treeId, NotTreeFilter.create(tf));
317
318 assertEquals(expected, paths);
319 }
320
321 private List<String> getMatchingPaths(final ObjectId objId,
322 TreeFilter tf) throws IOException {
323 return getMatchingPaths(objId, tf, true);
324 }
325
326 private List<String> getMatchingPathsFlat(final ObjectId objId,
327 TreeFilter tf) throws IOException {
328 return getMatchingPaths(objId, tf, false);
329 }
330
331 private List<String> getMatchingPaths(final ObjectId objId,
332 TreeFilter tf, boolean recursive) throws IOException {
333 try (TreeWalk tw = new TreeWalk(db)) {
334 tw.setFilter(tf);
335 tw.setRecursive(recursive);
336 tw.addTree(objId);
337
338 List<String> paths = new ArrayList<>();
339 while (tw.next()) {
340 paths.add(tw.getPathString());
341 }
342 return paths;
343 }
344 }
345
346 private ObjectId createTree(String... paths) throws IOException {
347 final ObjectInserter odi = db.newObjectInserter();
348 final DirCache dc = db.readDirCache();
349 final DirCacheBuilder builder = dc.builder();
350 for (String path : paths) {
351 DirCacheEntry entry = createEntry(path, FileMode.REGULAR_FILE);
352 builder.add(entry);
353 }
354 builder.finish();
355 final ObjectId objId = dc.writeTree(odi);
356 odi.flush();
357 return objId;
358 }
359 }
360