1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.treewalk.filter;
12
13 import static org.junit.Assert.assertArrayEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertTrue;
16 import static org.junit.Assert.fail;
17
18 import java.io.IOException;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25
26 import org.eclipse.jgit.dircache.DirCache;
27 import org.eclipse.jgit.dircache.DirCacheEditor;
28 import org.eclipse.jgit.dircache.DirCacheEntry;
29 import org.eclipse.jgit.dircache.DirCacheIterator;
30 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
31 import org.eclipse.jgit.errors.MissingObjectException;
32 import org.eclipse.jgit.errors.StopWalkException;
33 import org.eclipse.jgit.lib.FileMode;
34 import org.eclipse.jgit.lib.ObjectReader;
35 import org.eclipse.jgit.lib.Sets;
36 import org.eclipse.jgit.treewalk.TreeWalk;
37 import org.junit.Before;
38 import org.junit.Test;
39
40 public class PathFilterGroupTest {
41
42 private TreeFilter filter;
43
44 private Map<String, TreeFilter> singles;
45
46 @Before
47 public void setup() {
48
49 String[] paths = new String[] {
50 "/a",
51 "/a/b",
52 "a",
53 "b/c",
54 "c/d/e",
55 "c/d/f",
56 "d/e/f/g",
57 "d/e/f/g.x"
58 };
59
60 filter = PathFilterGroup.createFromStrings(paths);
61 singles = new HashMap<>();
62 for (String path : paths) {
63 singles.put(path, PathFilterGroup.createFromStrings(path));
64 }
65 }
66
67 @Test
68 public void testExact() throws MissingObjectException,
69 IncorrectObjectTypeException, IOException {
70 assertMatches(Sets.of("a"), fakeWalk("a"));
71 assertMatches(Sets.of("b/c"), fakeWalk("b/c"));
72 assertMatches(Sets.of("c/d/e"), fakeWalk("c/d/e"));
73 assertMatches(Sets.of("c/d/f"), fakeWalk("c/d/f"));
74 assertMatches(Sets.of("d/e/f/g"), fakeWalk("d/e/f/g"));
75 assertMatches(Sets.of("d/e/f/g.x"), fakeWalk("d/e/f/g.x"));
76 }
77
78 @Test
79 public void testNoMatchButClose() throws MissingObjectException,
80 IncorrectObjectTypeException, IOException {
81 assertNoMatches(fakeWalk("a+"));
82 assertNoMatches(fakeWalk("b+/c"));
83 assertNoMatches(fakeWalk("c+/d/e"));
84 assertNoMatches(fakeWalk("c+/d/f"));
85 assertNoMatches(fakeWalk("c/d.a"));
86 assertNoMatches(fakeWalk("d+/e/f/g"));
87 }
88
89 @Test
90 public void testJustCommonPrefixIsNotMatch() throws MissingObjectException,
91 IncorrectObjectTypeException, IOException {
92 assertNoMatches(fakeWalk("b/a"));
93 assertNoMatches(fakeWalk("b/d"));
94 assertNoMatches(fakeWalk("c/d/a"));
95 assertNoMatches(fakeWalk("d/e/e"));
96 assertNoMatches(fakeWalk("d/e/f/g.y"));
97 }
98
99 @Test
100 public void testKeyIsPrefixOfFilter() throws MissingObjectException,
101 IncorrectObjectTypeException, IOException {
102 assertMatches(Sets.of("b/c"), fakeWalkAtSubtree("b"));
103 assertMatches(Sets.of("c/d/e", "c/d/f"), fakeWalkAtSubtree("c/d"));
104 assertMatches(Sets.of("c/d/e", "c/d/f"), fakeWalkAtSubtree("c"));
105 assertMatches(Sets.of("d/e/f/g", "d/e/f/g.x"),
106 fakeWalkAtSubtree("d/e/f"));
107 assertMatches(Sets.of("d/e/f/g", "d/e/f/g.x"),
108 fakeWalkAtSubtree("d/e"));
109 assertMatches(Sets.of("d/e/f/g", "d/e/f/g.x"), fakeWalkAtSubtree("d"));
110
111 assertNoMatches(fakeWalk("b"));
112 assertNoMatches(fakeWalk("c/d"));
113 assertNoMatches(fakeWalk("c"));
114 assertNoMatches(fakeWalk("d/e/f"));
115 assertNoMatches(fakeWalk("d/e"));
116 assertNoMatches(fakeWalk("d"));
117
118 }
119
120 @Test
121 public void testFilterIsPrefixOfKey() throws MissingObjectException,
122 IncorrectObjectTypeException, IOException {
123 assertMatches(Sets.of("a"), fakeWalk("a/b"));
124 assertMatches(Sets.of("b/c"), fakeWalk("b/c/d"));
125 assertMatches(Sets.of("c/d/e"), fakeWalk("c/d/e/f"));
126 assertMatches(Sets.of("c/d/f"), fakeWalk("c/d/f/g"));
127 assertMatches(Sets.of("d/e/f/g"), fakeWalk("d/e/f/g/h"));
128 assertMatches(Sets.of("d/e/f/g"), fakeWalk("d/e/f/g/y"));
129 assertMatches(Sets.of("d/e/f/g.x"), fakeWalk("d/e/f/g.x/h"));
130 }
131
132 @Test
133 public void testLongPaths() throws MissingObjectException,
134 IncorrectObjectTypeException, IOException {
135 TreeFilter longPathFilter = PathFilterGroup
136 .createFromStrings(
137 "tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java",
138 "tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest2.java");
139 assertFalse(longPathFilter
140 .include(fakeWalk("tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java")));
141 assertFalse(longPathFilter.include(fakeWalk("tst/a-other-in-same")));
142 assertFalse(longPathFilter.include(fakeWalk("a-nothing-in-common")));
143 }
144
145 @Test
146 public void testStopWalk() throws MissingObjectException,
147 IncorrectObjectTypeException, IOException {
148
149 filter.include(fakeWalk("d/e/f/f"));
150
151
152 try {
153 filter.include(fakeWalk("de"));
154 fail("StopWalkException expected");
155 } catch (StopWalkException e) {
156
157 }
158
159
160 filter.include(fakeWalk("d-"));
161
162
163 try {
164 filter.include(fakeWalk("d0"));
165 fail("StopWalkException expected");
166 } catch (StopWalkException e) {
167
168 }
169
170
171 filter.include(fakeWalk("d/e/f/g/h.txt"));
172
173
174 filter.include(fakeWalk("d/e/f/g.y"));
175 singles.get("d/e/f/g").include(fakeWalk("d/e/f/g.y"));
176
177
178 try {
179 filter.include(fakeWalk("\u00C0"));
180 fail("StopWalkException expected");
181 } catch (StopWalkException e) {
182
183 }
184 }
185
186 private void assertNoMatches(TreeWalk tw) throws MissingObjectException,
187 IncorrectObjectTypeException, IOException {
188 assertMatches(Sets.<String> of(), tw);
189 }
190
191 private void assertMatches(Set<String> expect, TreeWalk tw)
192 throws MissingObjectException, IncorrectObjectTypeException,
193 IOException {
194 List<String> actual = new ArrayList<>();
195 for (String path : singles.keySet()) {
196 if (includes(singles.get(path), tw)) {
197 actual.add(path);
198 }
199 }
200
201 String[] e = expect.toArray(new String[0]);
202 String[] a = actual.toArray(new String[0]);
203 Arrays.sort(e);
204 Arrays.sort(a);
205 assertArrayEquals(e, a);
206
207 if (expect.isEmpty()) {
208 assertFalse(includes(filter, tw));
209 } else {
210 assertTrue(includes(filter, tw));
211 }
212 }
213
214 private static boolean includes(TreeFilter f, TreeWalk tw)
215 throws MissingObjectException, IncorrectObjectTypeException,
216 IOException {
217 try {
218 return f.include(tw);
219 } catch (StopWalkException e) {
220 return false;
221 }
222 }
223
224 TreeWalk fakeWalk(String path) throws IOException {
225 DirCache dc = DirCache.newInCore();
226 DirCacheEditor dce = dc.editor();
227 dce.add(new DirCacheEditor.PathEdit(path) {
228
229 @Override
230 public void apply(DirCacheEntry ent) {
231 ent.setFileMode(FileMode.REGULAR_FILE);
232 }
233 });
234 dce.finish();
235
236 TreeWalk ret = new TreeWalk((ObjectReader) null);
237 ret.reset();
238 ret.setRecursive(true);
239 ret.addTree(new DirCacheIterator(dc));
240 ret.next();
241 return ret;
242 }
243
244 TreeWalk fakeWalkAtSubtree(String path) throws IOException {
245 DirCache dc = DirCache.newInCore();
246 DirCacheEditor dce = dc.editor();
247 dce.add(new DirCacheEditor.PathEdit(path + "/README") {
248 @Override
249 public void apply(DirCacheEntry ent) {
250 ent.setFileMode(FileMode.REGULAR_FILE);
251 }
252 });
253 dce.finish();
254
255 TreeWalk ret = new TreeWalk((ObjectReader) null);
256 ret.addTree(new DirCacheIterator(dc));
257 ret.next();
258 while (!path.equals(ret.getPathString())) {
259 if (ret.isSubtree()) {
260 ret.enterSubtree();
261 }
262 ret.next();
263 }
264 return ret;
265 }
266 }