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 package org.eclipse.jgit.attributes;
41
42 import static org.junit.Assert.assertEquals;
43 import static org.junit.Assert.assertFalse;
44 import static org.junit.Assert.assertTrue;
45
46 import java.io.File;
47 import java.io.IOException;
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.Collections;
51
52 import org.eclipse.jgit.junit.RepositoryTestCase;
53 import org.eclipse.jgit.lib.ConfigConstants;
54 import org.eclipse.jgit.lib.Constants;
55 import org.eclipse.jgit.lib.FileMode;
56 import org.eclipse.jgit.storage.file.FileBasedConfig;
57 import org.eclipse.jgit.treewalk.FileTreeIterator;
58 import org.eclipse.jgit.treewalk.TreeWalk;
59 import org.junit.Test;
60
61
62
63
64 public class AttributesHandlerTest extends RepositoryTestCase {
65 private static final FileMode D = FileMode.TREE;
66
67 private static final FileMode F = FileMode.REGULAR_FILE;
68
69 private TreeWalk walk;
70
71 @Test
72 public void testExpandNonMacro1() throws Exception {
73 setupRepo(null, null, null, "*.txt text");
74
75 walk = beginWalk();
76 assertIteration(D, "sub");
77 assertIteration(F, "sub/.gitattributes");
78 assertIteration(F, "sub/a.txt", attrs("text"));
79 endWalk();
80 }
81
82 @Test
83 public void testExpandNonMacro2() throws Exception {
84 setupRepo(null, null, null, "*.txt -text");
85
86 walk = beginWalk();
87 assertIteration(D, "sub");
88 assertIteration(F, "sub/.gitattributes");
89 assertIteration(F, "sub/a.txt", attrs("-text"));
90 endWalk();
91 }
92
93 @Test
94 public void testExpandNonMacro3() throws Exception {
95 setupRepo(null, null, null, "*.txt !text");
96
97 walk = beginWalk();
98 assertIteration(D, "sub");
99 assertIteration(F, "sub/.gitattributes");
100 assertIteration(F, "sub/a.txt", attrs(""));
101 endWalk();
102 }
103
104 @Test
105 public void testExpandNonMacro4() throws Exception {
106 setupRepo(null, null, null, "*.txt text=auto");
107
108 walk = beginWalk();
109 assertIteration(D, "sub");
110 assertIteration(F, "sub/.gitattributes");
111 assertIteration(F, "sub/a.txt", attrs("text=auto"));
112 endWalk();
113 }
114
115 @Test
116 public void testExpandBuiltInMacro1() throws Exception {
117 setupRepo(null, null, null, "*.txt binary");
118
119 walk = beginWalk();
120 assertIteration(D, "sub");
121 assertIteration(F, "sub/.gitattributes");
122 assertIteration(F, "sub/a.txt", attrs("binary -diff -merge -text"));
123 endWalk();
124 }
125
126 @Test
127 public void testExpandBuiltInMacro2() throws Exception {
128 setupRepo(null, null, null, "*.txt -binary");
129
130 walk = beginWalk();
131 assertIteration(D, "sub");
132 assertIteration(F, "sub/.gitattributes");
133 assertIteration(F, "sub/a.txt", attrs("-binary diff merge text"));
134 endWalk();
135 }
136
137 @Test
138 public void testExpandBuiltInMacro3() throws Exception {
139 setupRepo(null, null, null, "*.txt !binary");
140
141 walk = beginWalk();
142 assertIteration(D, "sub");
143 assertIteration(F, "sub/.gitattributes");
144 assertIteration(F, "sub/a.txt", attrs(""));
145 endWalk();
146 }
147
148 @Test
149 public void testCustomGlobalMacro1() throws Exception {
150 setupRepo(
151 "[attr]foo a -b !c d=e", null, null, "*.txt foo");
152
153 walk = beginWalk();
154 assertIteration(D, "sub");
155 assertIteration(F, "sub/.gitattributes");
156 assertIteration(F, "sub/a.txt", attrs("foo a -b d=e"));
157 endWalk();
158 }
159
160 @Test
161 public void testCustomGlobalMacro2() throws Exception {
162 setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt -foo");
163
164 walk = beginWalk();
165 assertIteration(D, "sub");
166 assertIteration(F, "sub/.gitattributes");
167 assertIteration(F, "sub/a.txt", attrs("-foo -a b d=e"));
168 endWalk();
169 }
170
171 @Test
172 public void testCustomGlobalMacro3() throws Exception {
173 setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt !foo");
174
175 walk = beginWalk();
176 assertIteration(D, "sub");
177 assertIteration(F, "sub/.gitattributes");
178 assertIteration(F, "sub/a.txt", attrs(""));
179 endWalk();
180 }
181
182 @Test
183 public void testCustomGlobalMacro4() throws Exception {
184 setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt foo=bar");
185
186 walk = beginWalk();
187 assertIteration(D, "sub");
188 assertIteration(F, "sub/.gitattributes");
189 assertIteration(F, "sub/a.txt", attrs("foo=bar a -b d=bar"));
190 endWalk();
191 }
192
193 @Test
194 public void testInfoOverridesGlobal() throws Exception {
195 setupRepo("[attr]foo bar1",
196 "[attr]foo bar2", null, "*.txt foo");
197
198 walk = beginWalk();
199 assertIteration(D, "sub");
200 assertIteration(F, "sub/.gitattributes");
201 assertIteration(F, "sub/a.txt", attrs("foo bar2"));
202 endWalk();
203 }
204
205 @Test
206 public void testWorkDirRootOverridesGlobal() throws Exception {
207 setupRepo("[attr]foo bar1",
208 null,
209 "[attr]foo bar3", "*.txt foo");
210
211 walk = beginWalk();
212 assertIteration(F, ".gitattributes");
213 assertIteration(D, "sub");
214 assertIteration(F, "sub/.gitattributes");
215 assertIteration(F, "sub/a.txt", attrs("foo bar3"));
216 endWalk();
217 }
218
219 @Test
220 public void testInfoOverridesWorkDirRoot() throws Exception {
221 setupRepo("[attr]foo bar1",
222 "[attr]foo bar2", "[attr]foo bar3", "*.txt foo");
223
224 walk = beginWalk();
225 assertIteration(F, ".gitattributes");
226 assertIteration(D, "sub");
227 assertIteration(F, "sub/.gitattributes");
228 assertIteration(F, "sub/a.txt", attrs("foo bar2"));
229 endWalk();
230 }
231
232 @Test
233 public void testRecursiveMacro() throws Exception {
234 setupRepo(
235 "[attr]foo x bar -foo",
236 null, null, "*.txt foo");
237
238 walk = beginWalk();
239 assertIteration(D, "sub");
240 assertIteration(F, "sub/.gitattributes");
241 assertIteration(F, "sub/a.txt", attrs("foo x bar"));
242 endWalk();
243 }
244
245 @Test
246 public void testCyclicMacros() throws Exception {
247 setupRepo(
248 "[attr]foo x -bar\n[attr]bar y -foo", null, null, "*.txt foo");
249
250 walk = beginWalk();
251 assertIteration(D, "sub");
252 assertIteration(F, "sub/.gitattributes");
253 assertIteration(F, "sub/a.txt", attrs("foo x -bar -y"));
254 endWalk();
255 }
256
257 private static Collection<Attribute> attrs(String s) {
258 return new AttributesRule("*", s).getAttributes();
259 }
260
261 private void assertIteration(FileMode type, String pathName)
262 throws IOException {
263 assertIteration(type, pathName, Collections.<Attribute> emptyList());
264 }
265
266 private void assertIteration(FileMode type, String pathName,
267 Collection<Attribute> expectedAttrs) throws IOException {
268 assertTrue("walk has entry", walk.next());
269 assertEquals(pathName, walk.getPathString());
270 assertEquals(type, walk.getFileMode(0));
271
272 if (expectedAttrs != null) {
273 assertEquals(new ArrayList<>(expectedAttrs),
274 new ArrayList<>(walk.getAttributes().getAll()));
275 }
276
277 if (D.equals(type))
278 walk.enterSubtree();
279 }
280
281
282
283
284
285
286
287
288
289
290 private void setupRepo(
291 String globalAttributesContent,
292 String infoAttributesContent, String rootAttributesContent, String subDirAttributesContent)
293 throws Exception {
294 FileBasedConfig config = db.getConfig();
295 if (globalAttributesContent != null) {
296 File f = new File(db.getDirectory(), "global/attributes");
297 write(f, globalAttributesContent);
298 config.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
299 ConfigConstants.CONFIG_KEY_ATTRIBUTESFILE,
300 f.getAbsolutePath());
301
302 }
303 if (infoAttributesContent != null) {
304 File f = new File(db.getDirectory(), Constants.INFO_ATTRIBUTES);
305 write(f, infoAttributesContent);
306 }
307 config.save();
308
309 if (rootAttributesContent != null) {
310 writeAttributesFile(Constants.DOT_GIT_ATTRIBUTES,
311 rootAttributesContent);
312 }
313
314 if (subDirAttributesContent != null) {
315 writeAttributesFile("sub/" + Constants.DOT_GIT_ATTRIBUTES,
316 subDirAttributesContent);
317 }
318
319 writeTrashFile("sub/a.txt", "a");
320 }
321
322 private void writeAttributesFile(String name, String... rules)
323 throws IOException {
324 StringBuilder data = new StringBuilder();
325 for (String line : rules)
326 data.append(line + "\n");
327 writeTrashFile(name, data.toString());
328 }
329
330 private TreeWalk beginWalk() {
331 TreeWalk newWalk = new TreeWalk(db);
332 newWalk.addTree(new FileTreeIterator(db));
333 return newWalk;
334 }
335
336 private void endWalk() throws IOException {
337 assertFalse("Not all files tested", walk.next());
338 }
339 }