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