1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.attributes;
11
12 import static java.util.Arrays.asList;
13 import static org.hamcrest.CoreMatchers.hasItem;
14 import static org.hamcrest.MatcherAssert.assertThat;
15 import static org.junit.Assert.assertEquals;
16 import static org.junit.Assert.assertFalse;
17 import static org.junit.Assert.assertNotNull;
18 import static org.junit.Assert.assertTrue;
19
20 import java.io.IOException;
21 import java.util.Collections;
22 import java.util.List;
23
24 import org.eclipse.jgit.api.Git;
25 import org.eclipse.jgit.attributes.Attribute.State;
26 import org.eclipse.jgit.dircache.DirCacheIterator;
27 import org.eclipse.jgit.junit.RepositoryTestCase;
28 import org.eclipse.jgit.lib.FileMode;
29 import org.eclipse.jgit.treewalk.TreeWalk;
30 import org.junit.Before;
31 import org.junit.Test;
32
33
34
35
36 public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase {
37
38 private static final FileMode D = FileMode.TREE;
39
40 private static final FileMode F = FileMode.REGULAR_FILE;
41
42 private static Attribute EOL_LF = new Attribute("eol", "lf");
43
44 private static Attribute DELTA_UNSET = new Attribute("delta", State.UNSET);
45
46 private Git git;
47
48 @Override
49 @Before
50 public void setUp() throws Exception {
51 super.setUp();
52 git = new Git(db);
53
54 }
55
56 @Test
57 public void testRules() throws Exception {
58 writeAttributesFile(".git/info/attributes", "windows* eol=crlf");
59
60 writeAttributesFile(".gitattributes", "*.txt eol=lf");
61 writeTrashFile("windows.file", "");
62 writeTrashFile("windows.txt", "");
63 writeTrashFile("readme.txt", "");
64
65 writeAttributesFile("src/config/.gitattributes", "*.txt -delta");
66 writeTrashFile("src/config/readme.txt", "");
67 writeTrashFile("src/config/windows.file", "");
68 writeTrashFile("src/config/windows.txt", "");
69
70
71 git.add().addFilepattern(".").call();
72
73 try (TreeWalk walk = beginWalk()) {
74 assertIteration(walk, F, ".gitattributes");
75 assertIteration(walk, F, "readme.txt", asList(EOL_LF));
76
77 assertIteration(walk, D, "src");
78
79 assertIteration(walk, D, "src/config");
80 assertIteration(walk, F, "src/config/.gitattributes");
81 assertIteration(walk, F, "src/config/readme.txt",
82 asList(DELTA_UNSET));
83 assertIteration(walk, F, "src/config/windows.file", null);
84 assertIteration(walk, F, "src/config/windows.txt",
85 asList(DELTA_UNSET));
86
87 assertIteration(walk, F, "windows.file", null);
88 assertIteration(walk, F, "windows.txt", asList(EOL_LF));
89
90 assertFalse("Not all files tested", walk.next());
91 }
92 }
93
94
95
96
97
98
99
100 @Test
101 public void testNoAttributes() throws Exception {
102 writeTrashFile("l0.txt", "");
103 writeTrashFile("level1/l1.txt", "");
104 writeTrashFile("level1/level2/l2.txt", "");
105
106
107 git.add().addFilepattern(".").call();
108
109 try (TreeWalk walk = beginWalk()) {
110 assertIteration(walk, F, "l0.txt");
111
112 assertIteration(walk, D, "level1");
113 assertIteration(walk, F, "level1/l1.txt");
114
115 assertIteration(walk, D, "level1/level2");
116 assertIteration(walk, F, "level1/level2/l2.txt");
117
118 assertFalse("Not all files tested", walk.next());
119 }
120 }
121
122
123
124
125
126
127 @Test
128 public void testEmptyGitAttributeFile() throws Exception {
129 writeAttributesFile(".git/info/attributes", "");
130 writeTrashFile("l0.txt", "");
131 writeAttributesFile(".gitattributes", "");
132 writeTrashFile("level1/l1.txt", "");
133 writeTrashFile("level1/level2/l2.txt", "");
134
135
136 git.add().addFilepattern(".").call();
137
138 try (TreeWalk walk = beginWalk()) {
139 assertIteration(walk, F, ".gitattributes");
140 assertIteration(walk, F, "l0.txt");
141
142 assertIteration(walk, D, "level1");
143 assertIteration(walk, F, "level1/l1.txt");
144
145 assertIteration(walk, D, "level1/level2");
146 assertIteration(walk, F, "level1/level2/l2.txt");
147
148 assertFalse("Not all files tested", walk.next());
149 }
150 }
151
152 @Test
153 public void testNoMatchingAttributes() throws Exception {
154 writeAttributesFile(".git/info/attributes", "*.java delta");
155 writeAttributesFile(".gitattributes", "*.java -delta");
156 writeAttributesFile("levelA/.gitattributes", "*.java eol=lf");
157 writeAttributesFile("levelB/.gitattributes", "*.txt eol=lf");
158
159 writeTrashFile("levelA/lA.txt", "");
160
161
162 git.add().addFilepattern(".").call();
163
164 try (TreeWalk walk = beginWalk()) {
165 assertIteration(walk, F, ".gitattributes");
166
167 assertIteration(walk, D, "levelA");
168 assertIteration(walk, F, "levelA/.gitattributes");
169 assertIteration(walk, F, "levelA/lA.txt");
170
171 assertIteration(walk, D, "levelB");
172 assertIteration(walk, F, "levelB/.gitattributes");
173
174 assertFalse("Not all files tested", walk.next());
175 }
176 }
177
178 @Test
179 public void testIncorrectAttributeFileName() throws Exception {
180 writeAttributesFile("levelA/file.gitattributes", "*.txt -delta");
181 writeAttributesFile("gitattributes", "*.txt eol=lf");
182
183 writeTrashFile("l0.txt", "");
184 writeTrashFile("levelA/lA.txt", "");
185
186
187 git.add().addFilepattern(".").call();
188
189 try (TreeWalk walk = beginWalk()) {
190 assertIteration(walk, F, "gitattributes");
191
192 assertIteration(walk, F, "l0.txt");
193
194 assertIteration(walk, D, "levelA");
195 assertIteration(walk, F, "levelA/file.gitattributes");
196 assertIteration(walk, F, "levelA/lA.txt");
197
198 assertFalse("Not all files tested", walk.next());
199 }
200 }
201
202 private void assertIteration(TreeWalk walk, FileMode type, String pathName)
203 throws IOException {
204 assertIteration(walk, type, pathName,
205 Collections.<Attribute> emptyList());
206 }
207
208 private void assertIteration(TreeWalk walk, FileMode type, String pathName,
209 List<Attribute> nodeAttrs) throws IOException {
210 assertTrue("walk has entry", walk.next());
211 assertEquals(pathName, walk.getPathString());
212 assertEquals(type, walk.getFileMode(0));
213 DirCacheIterator itr = walk.getTree(0, DirCacheIterator.class);
214 assertNotNull("has tree", itr);
215
216 AttributesNode attributesNode = itr.getEntryAttributesNode(db
217 .newObjectReader());
218 assertAttributesNode(walk, pathName, attributesNode, nodeAttrs);
219
220 if (D.equals(type))
221 walk.enterSubtree();
222
223 }
224
225 private void assertAttributesNode(TreeWalk walk, String pathName,
226 AttributesNode attributesNode, List<Attribute> nodeAttrs)
227 throws IOException {
228 if (attributesNode == null)
229 assertTrue(nodeAttrs == null || nodeAttrs.isEmpty());
230 else {
231
232 Attributes entryAttributes = new Attributes();
233 new AttributesHandler(walk).mergeAttributes(attributesNode,
234 pathName,
235 false,
236 entryAttributes);
237
238 if (nodeAttrs != null && !nodeAttrs.isEmpty()) {
239 for (Attribute attribute : nodeAttrs) {
240 assertThat(entryAttributes.getAll(),
241 hasItem(attribute));
242 }
243 } else {
244 assertTrue(
245 "The entry "
246 + pathName
247 + " should not have any attributes. Instead, the following attributes are applied to this file "
248 + entryAttributes.toString(),
249 entryAttributes.isEmpty());
250 }
251 }
252 }
253
254 private void writeAttributesFile(String name, String... rules)
255 throws IOException {
256 StringBuilder data = new StringBuilder();
257 for (String line : rules)
258 data.append(line + "\n");
259 writeTrashFile(name, data.toString());
260 }
261
262 private TreeWalk beginWalk() throws Exception {
263 TreeWalk newWalk = new TreeWalk(db);
264 newWalk.addTree(new DirCacheIterator(db.readDirCache()));
265 return newWalk;
266 }
267 }