View Javadoc
1   /*
2    * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3    * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org>
4    * and other copyright owners as documented in the project's IP log.
5    *
6    * This program and the accompanying materials are made available
7    * under the terms of the Eclipse Distribution License v1.0 which
8    * accompanies this distribution, is reproduced below, and is
9    * available at http://www.eclipse.org/org/documents/edl-v10.php
10   *
11   * All rights reserved.
12   *
13   * Redistribution and use in source and binary forms, with or
14   * without modification, are permitted provided that the following
15   * conditions are met:
16   *
17   * - Redistributions of source code must retain the above copyright
18   *   notice, this list of conditions and the following disclaimer.
19   *
20   * - Redistributions in binary form must reproduce the above
21   *   copyright notice, this list of conditions and the following
22   *   disclaimer in the documentation and/or other materials provided
23   *   with the distribution.
24   *
25   * - Neither the name of the Eclipse Foundation, Inc. nor the
26   *   names of its contributors may be used to endorse or promote
27   *   products derived from this software without specific prior
28   *   written permission.
29   *
30   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
31   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
32   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
39   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
42   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43   */
44  
45  package org.eclipse.jgit.lib;
46  
47  import static org.junit.Assert.assertEquals;
48  import static org.junit.Assert.assertFalse;
49  import static org.junit.Assert.assertNotNull;
50  import static org.junit.Assert.assertSame;
51  import static org.junit.Assert.assertTrue;
52  
53  import java.io.IOException;
54  import java.io.UnsupportedEncodingException;
55  import java.util.ArrayList;
56  import java.util.List;
57  
58  import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
59  import org.junit.Test;
60  
61  @SuppressWarnings("deprecation")
62  public class T0002_TreeTest extends SampleDataRepositoryTestCase {
63  	private static final ObjectId SOME_FAKE_ID = ObjectId.fromString(
64  			"0123456789abcdef0123456789abcdef01234567");
65  
66  	private static int compareNamesUsingSpecialCompare(String a, String b)
67  			throws UnsupportedEncodingException {
68  		char lasta = '\0';
69  		byte[] abytes;
70  		if (a.length() > 0 && a.charAt(a.length()-1) == '/') {
71  			lasta = '/';
72  			a = a.substring(0, a.length() - 1);
73  		}
74  		abytes = a.getBytes("ISO-8859-1");
75  		char lastb = '\0';
76  		byte[] bbytes;
77  		if (b.length() > 0 && b.charAt(b.length()-1) == '/') {
78  			lastb = '/';
79  			b = b.substring(0, b.length() - 1);
80  		}
81  		bbytes = b.getBytes("ISO-8859-1");
82  		return Tree.compareNames(abytes, bbytes, lasta, lastb);
83  	}
84  
85  	@Test
86  	public void test000_sort_01() throws UnsupportedEncodingException {
87  		assertEquals(0, compareNamesUsingSpecialCompare("a","a"));
88  	}
89  
90  	@Test
91  	public void test000_sort_02() throws UnsupportedEncodingException {
92  		assertEquals(-1, compareNamesUsingSpecialCompare("a","b"));
93  		assertEquals(1, compareNamesUsingSpecialCompare("b","a"));
94  	}
95  
96  	@Test
97  	public void test000_sort_03() throws UnsupportedEncodingException {
98  		assertEquals(1, compareNamesUsingSpecialCompare("a:","a"));
99  		assertEquals(1, compareNamesUsingSpecialCompare("a/","a"));
100 		assertEquals(-1, compareNamesUsingSpecialCompare("a","a/"));
101 		assertEquals(-1, compareNamesUsingSpecialCompare("a","a:"));
102 		assertEquals(1, compareNamesUsingSpecialCompare("a:","a/"));
103 		assertEquals(-1, compareNamesUsingSpecialCompare("a/","a:"));
104 	}
105 
106 	@Test
107 	public void test000_sort_04() throws UnsupportedEncodingException {
108 		assertEquals(-1, compareNamesUsingSpecialCompare("a.a","a/a"));
109 		assertEquals(1, compareNamesUsingSpecialCompare("a/a","a.a"));
110 	}
111 
112 	@Test
113 	public void test000_sort_05() throws UnsupportedEncodingException {
114 		assertEquals(-1, compareNamesUsingSpecialCompare("a.","a/"));
115 		assertEquals(1, compareNamesUsingSpecialCompare("a/","a."));
116 
117 	}
118 
119 	@Test
120 	public void test001_createEmpty() throws IOException {
121 		final Tree t = new Tree(db);
122 		assertTrue("isLoaded", t.isLoaded());
123 		assertTrue("isModified", t.isModified());
124 		assertTrue("no parent", t.getParent() == null);
125 		assertTrue("isRoot", t.isRoot());
126 		assertTrue("no name", t.getName() == null);
127 		assertTrue("no nameUTF8", t.getNameUTF8() == null);
128 		assertTrue("has entries array", t.members() != null);
129 		assertEquals("entries is empty", 0, t.members().length);
130 		assertEquals("full name is empty", "", t.getFullName());
131 		assertTrue("no id", t.getId() == null);
132 		assertTrue("database is r", t.getRepository() == db);
133 		assertTrue("no foo child", t.findTreeMember("foo") == null);
134 		assertTrue("no foo child", t.findBlobMember("foo") == null);
135 	}
136 
137 	@Test
138 	public void test002_addFile() throws IOException {
139 		final Tree t = new Tree(db);
140 		t.setId(SOME_FAKE_ID);
141 		assertTrue("has id", t.getId() != null);
142 		assertFalse("not modified", t.isModified());
143 
144 		final String n = "bob";
145 		final FileTreeEntry f = t.addFile(n);
146 		assertNotNull("have file", f);
147 		assertEquals("name matches", n, f.getName());
148 		assertEquals("name matches", f.getName(), new String(f.getNameUTF8(),
149 				"UTF-8"));
150 		assertEquals("full name matches", n, f.getFullName());
151 		assertTrue("no id", f.getId() == null);
152 		assertTrue("is modified", t.isModified());
153 		assertTrue("has no id", t.getId() == null);
154 		assertTrue("found bob", t.findBlobMember(f.getName()) == f);
155 
156 		final TreeEntry[] i = t.members();
157 		assertNotNull("members array not null", i);
158 		assertTrue("iterator is not empty", i != null && i.length > 0);
159 		assertTrue("iterator returns file", i != null && i[0] == f);
160 		assertTrue("iterator is empty", i != null && i.length == 1);
161 	}
162 
163 	@Test
164 	public void test004_addTree() throws IOException {
165 		final Tree t = new Tree(db);
166 		t.setId(SOME_FAKE_ID);
167 		assertTrue("has id", t.getId() != null);
168 		assertFalse("not modified", t.isModified());
169 
170 		final String n = "bob";
171 		final Tree f = t.addTree(n);
172 		assertNotNull("have tree", f);
173 		assertEquals("name matches", n, f.getName());
174 		assertEquals("name matches", f.getName(), new String(f.getNameUTF8(),
175 				"UTF-8"));
176 		assertEquals("full name matches", n, f.getFullName());
177 		assertTrue("no id", f.getId() == null);
178 		assertTrue("parent matches", f.getParent() == t);
179 		assertTrue("repository matches", f.getRepository() == db);
180 		assertTrue("isLoaded", f.isLoaded());
181 		assertFalse("has items", f.members().length > 0);
182 		assertFalse("is root", f.isRoot());
183 		assertTrue("parent is modified", t.isModified());
184 		assertTrue("parent has no id", t.getId() == null);
185 		assertTrue("found bob child", t.findTreeMember(f.getName()) == f);
186 
187 		final TreeEntry[] i = t.members();
188 		assertTrue("iterator is not empty", i.length > 0);
189 		assertTrue("iterator returns file", i[0] == f);
190 		assertEquals("iterator is empty", 1, i.length);
191 	}
192 
193 	@Test
194 	public void test005_addRecursiveFile() throws IOException {
195 		final Tree t = new Tree(db);
196 		final FileTreeEntry f = t.addFile("a/b/c");
197 		assertNotNull("created f", f);
198 		assertEquals("c", f.getName());
199 		assertEquals("b", f.getParent().getName());
200 		assertEquals("a", f.getParent().getParent().getName());
201 		assertTrue("t is great-grandparent", t == f.getParent().getParent()
202 				.getParent());
203 	}
204 
205 	@Test
206 	public void test005_addRecursiveTree() throws IOException {
207 		final Tree t = new Tree(db);
208 		final Tree f = t.addTree("a/b/c");
209 		assertNotNull("created f", f);
210 		assertEquals("c", f.getName());
211 		assertEquals("b", f.getParent().getName());
212 		assertEquals("a", f.getParent().getParent().getName());
213 		assertTrue("t is great-grandparent", t == f.getParent().getParent()
214 				.getParent());
215 	}
216 
217 	@Test
218 	public void test006_addDeepTree() throws IOException {
219 		final Tree t = new Tree(db);
220 
221 		final Tree e = t.addTree("e");
222 		assertNotNull("have e", e);
223 		assertTrue("e.parent == t", e.getParent() == t);
224 		final Tree f = t.addTree("f");
225 		assertNotNull("have f", f);
226 		assertTrue("f.parent == t", f.getParent() == t);
227 		final Tree g = f.addTree("g");
228 		assertNotNull("have g", g);
229 		assertTrue("g.parent == f", g.getParent() == f);
230 		final Tree h = g.addTree("h");
231 		assertNotNull("have h", h);
232 		assertTrue("h.parent = g", h.getParent() == g);
233 
234 		h.setId(SOME_FAKE_ID);
235 		assertTrue("h not modified", !h.isModified());
236 		g.setId(SOME_FAKE_ID);
237 		assertTrue("g not modified", !g.isModified());
238 		f.setId(SOME_FAKE_ID);
239 		assertTrue("f not modified", !f.isModified());
240 		e.setId(SOME_FAKE_ID);
241 		assertTrue("e not modified", !e.isModified());
242 		t.setId(SOME_FAKE_ID);
243 		assertTrue("t not modified.", !t.isModified());
244 
245 		assertEquals("full path of h ok", "f/g/h", h.getFullName());
246 		assertTrue("Can find h", t.findTreeMember(h.getFullName()) == h);
247 		assertTrue("Can't find f/z", t.findBlobMember("f/z") == null);
248 		assertTrue("Can't find y/z", t.findBlobMember("y/z") == null);
249 
250 		final FileTreeEntry i = h.addFile("i");
251 		assertNotNull(i);
252 		assertEquals("full path of i ok", "f/g/h/i", i.getFullName());
253 		assertTrue("Can find i", t.findBlobMember(i.getFullName()) == i);
254 		assertTrue("h modified", h.isModified());
255 		assertTrue("g modified", g.isModified());
256 		assertTrue("f modified", f.isModified());
257 		assertTrue("e not modified", !e.isModified());
258 		assertTrue("t modified", t.isModified());
259 
260 		assertTrue("h no id", h.getId() == null);
261 		assertTrue("g no id", g.getId() == null);
262 		assertTrue("f no id", f.getId() == null);
263 		assertTrue("e has id", e.getId() != null);
264 		assertTrue("t no id", t.getId() == null);
265 	}
266 
267 	@Test
268 	public void test007_manyFileLookup() throws IOException {
269 		final Tree t = new Tree(db);
270 		final List<FileTreeEntry> files = new ArrayList<FileTreeEntry>(26 * 26);
271 		for (char level1 = 'a'; level1 <= 'z'; level1++) {
272 			for (char level2 = 'a'; level2 <= 'z'; level2++) {
273 				final String n = "." + level1 + level2 + "9";
274 				final FileTreeEntry f = t.addFile(n);
275 				assertNotNull("File " + n + " added.", f);
276 				assertEquals(n, f.getName());
277 				files.add(f);
278 			}
279 		}
280 		assertEquals(files.size(), t.memberCount());
281 		final TreeEntry[] ents = t.members();
282 		assertNotNull(ents);
283 		assertEquals(files.size(), ents.length);
284 		for (int k = 0; k < ents.length; k++) {
285 			assertTrue("File " + files.get(k).getName()
286 					+ " is at " + k + ".", files.get(k) == ents[k]);
287 		}
288 	}
289 
290 	@Test
291 	public void test008_SubtreeInternalSorting() throws IOException {
292 		final Tree t = new Tree(db);
293 		final FileTreeEntry e0 = t.addFile("a-b");
294 		final FileTreeEntry e1 = t.addFile("a-");
295 		final FileTreeEntry e2 = t.addFile("a=b");
296 		final Tree e3 = t.addTree("a");
297 		final FileTreeEntry e4 = t.addFile("a=");
298 
299 		final TreeEntry[] ents = t.members();
300 		assertSame(e1, ents[0]);
301 		assertSame(e0, ents[1]);
302 		assertSame(e3, ents[2]);
303 		assertSame(e4, ents[3]);
304 		assertSame(e2, ents[4]);
305 	}
306 
307 	@Test
308 	public void test009_SymlinkAndGitlink() throws IOException {
309 		final Tree symlinkTree = mapTree("symlink");
310 		assertTrue("Symlink entry exists", symlinkTree.existsBlob("symlink.txt"));
311 		final Tree gitlinkTree = mapTree("gitlink");
312 		assertTrue("Gitlink entry exists", gitlinkTree.existsBlob("submodule"));
313 	}
314 
315 	private Tree mapTree(String name) throws IOException {
316 		ObjectId id = db.resolve(name + "^{tree}");
317 		return new Tree(db, id, db.open(id).getCachedBytes());
318 	}
319 }