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
41
42
43 package org.eclipse.jgit.api;
44
45 import static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertNull;
47
48 import java.beans.Statement;
49 import java.io.IOException;
50 import java.io.OutputStream;
51 import java.util.Arrays;
52 import java.util.Collections;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56
57 import org.eclipse.jgit.api.errors.GitAPIException;
58 import org.eclipse.jgit.junit.RepositoryTestCase;
59 import org.eclipse.jgit.lib.FileMode;
60 import org.eclipse.jgit.lib.ObjectLoader;
61 import org.eclipse.jgit.revwalk.RevCommit;
62 import org.eclipse.jgit.util.StringUtils;
63 import org.junit.After;
64 import org.junit.Before;
65 import org.junit.Test;
66
67 public class ArchiveCommandTest extends RepositoryTestCase {
68
69 private static final String UNEXPECTED_ARCHIVE_SIZE = "Unexpected archive size";
70 private static final String UNEXPECTED_FILE_CONTENTS = "Unexpected file contents";
71 private static final String UNEXPECTED_TREE_CONTENTS = "Unexpected tree contents";
72
73 private MockFormat format = null;
74
75 @Before
76 public void setup() {
77 format = new MockFormat();
78 ArchiveCommand.registerFormat(format.SUFFIXES.get(0), format);
79 }
80
81 @After
82 public void tearDown() {
83 ArchiveCommand.unregisterFormat(format.SUFFIXES.get(0));
84 }
85
86 @Test
87 public void archiveHeadAllFiles() throws IOException, GitAPIException {
88 Git git = new Git(db);
89 writeTrashFile("file_1.txt", "content_1_1");
90 git.add().addFilepattern("file_1.txt").call();
91 git.commit().setMessage("create file").call();
92
93 writeTrashFile("file_1.txt", "content_1_2");
94 writeTrashFile("file_2.txt", "content_2_2");
95 git.add().addFilepattern(".").call();
96 git.commit().setMessage("updated file").call();
97
98 git.archive().setOutputStream(new MockOutputStream())
99 .setFormat(format.SUFFIXES.get(0))
100 .setTree(git.getRepository().resolve("HEAD")).call();
101
102 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 2, format.size());
103 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_2", format.getByPath("file_1.txt"));
104 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath("file_2.txt"));
105 }
106
107 @Test
108 public void archiveHeadSpecificPath() throws IOException, GitAPIException {
109 Git git = new Git(db);
110 writeTrashFile("file_1.txt", "content_1_1");
111 git.add().addFilepattern("file_1.txt").call();
112 git.commit().setMessage("create file").call();
113
114 writeTrashFile("file_1.txt", "content_1_2");
115 String expectedFilePath = "some_directory/file_2.txt";
116 writeTrashFile(expectedFilePath, "content_2_2");
117 git.add().addFilepattern(".").call();
118 git.commit().setMessage("updated file").call();
119
120 git.archive().setOutputStream(new MockOutputStream())
121 .setFormat(format.SUFFIXES.get(0))
122 .setTree(git.getRepository().resolve("HEAD"))
123 .setPaths(expectedFilePath).call();
124
125 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 2, format.size());
126 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath(expectedFilePath));
127 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory"));
128 }
129
130 @Test
131 public void archiveByIdSpecificFile() throws IOException, GitAPIException {
132 Git git = new Git(db);
133 writeTrashFile("file_1.txt", "content_1_1");
134 git.add().addFilepattern("file_1.txt").call();
135 RevCommit first = git.commit().setMessage("create file").call();
136
137 writeTrashFile("file_1.txt", "content_1_2");
138 String expectedFilePath = "some_directory/file_2.txt";
139 writeTrashFile(expectedFilePath, "content_2_2");
140 git.add().addFilepattern(".").call();
141 git.commit().setMessage("updated file").call();
142
143 Map<String, Object> options = new HashMap<>();
144 Integer opt = Integer.valueOf(42);
145 options.put("foo", opt);
146 MockOutputStream out = new MockOutputStream();
147 git.archive().setOutputStream(out)
148 .setFormat(format.SUFFIXES.get(0))
149 .setFormatOptions(options)
150 .setTree(first)
151 .setPaths("file_1.txt").call();
152
153 assertEquals(opt.intValue(), out.getFoo());
154 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 1, format.size());
155 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_1", format.getByPath("file_1.txt"));
156 }
157
158 @Test
159 public void archiveByDirectoryPath() throws GitAPIException, IOException {
160 Git git = new Git(db);
161 writeTrashFile("file_0.txt", "content_0_1");
162 git.add().addFilepattern("file_0.txt").call();
163 git.commit().setMessage("commit_1").call();
164
165 writeTrashFile("file_0.txt", "content_0_2");
166 String expectedFilePath1 = "some_directory/file_1.txt";
167 writeTrashFile(expectedFilePath1, "content_1_2");
168 String expectedFilePath2 = "some_directory/file_2.txt";
169 writeTrashFile(expectedFilePath2, "content_2_2");
170 String expectedFilePath3 = "some_directory/nested_directory/file_3.txt";
171 writeTrashFile(expectedFilePath3, "content_3_2");
172 git.add().addFilepattern(".").call();
173 git.commit().setMessage("commit_2").call();
174 git.archive().setOutputStream(new MockOutputStream())
175 .setFormat(format.SUFFIXES.get(0))
176 .setTree(git.getRepository().resolve("HEAD"))
177 .setPaths("some_directory/").call();
178
179 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 5, format.size());
180 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_2", format.getByPath(expectedFilePath1));
181 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath(expectedFilePath2));
182 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_3_2", format.getByPath(expectedFilePath3));
183 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory"));
184 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory/nested_directory"));
185 }
186
187 private class MockFormat implements ArchiveCommand.Format<MockOutputStream> {
188
189 private Map<String, String> entries = new HashMap<String, String>();
190
191 private int size() {
192 return entries.size();
193 }
194
195 private String getByPath(String path) {
196 return entries.get(path);
197 }
198
199 private final List<String> SUFFIXES = Collections
200 .unmodifiableList(Arrays.asList(".mck"));
201
202 public MockOutputStream createArchiveOutputStream(OutputStream s)
203 throws IOException {
204 return createArchiveOutputStream(s,
205 Collections.<String, Object> emptyMap());
206 }
207
208 public MockOutputStream createArchiveOutputStream(OutputStream s,
209 Map<String, Object> o) throws IOException {
210 for (Map.Entry<String, Object> p : o.entrySet()) {
211 try {
212 String methodName = "set"
213 + StringUtils.capitalize(p.getKey());
214 new Statement(s, methodName, new Object[] { p.getValue() })
215 .execute();
216 } catch (Exception e) {
217 throw new IOException("cannot set option: " + p.getKey(), e);
218 }
219 }
220 return new MockOutputStream();
221 }
222
223 public void putEntry(MockOutputStream out, String path, FileMode mode, ObjectLoader loader) {
224 String content = mode != FileMode.TREE ? new String(loader.getBytes()) : null;
225 entries.put(path, content);
226 }
227
228 public Iterable<String> suffixes() {
229 return SUFFIXES;
230 }
231 }
232
233 public class MockOutputStream extends OutputStream {
234
235 private int foo;
236
237 public void setFoo(int foo) {
238 this.foo = foo;
239 }
240
241 public int getFoo() {
242 return foo;
243 }
244
245 @Override
246 public void write(int b) throws IOException {
247
248 }
249 }
250 }