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 try (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
108 @Test
109 public void archiveHeadSpecificPath() throws IOException, GitAPIException {
110 try (Git git = new Git(db)) {
111 writeTrashFile("file_1.txt", "content_1_1");
112 git.add().addFilepattern("file_1.txt").call();
113 git.commit().setMessage("create file").call();
114
115 writeTrashFile("file_1.txt", "content_1_2");
116 String expectedFilePath = "some_directory/file_2.txt";
117 writeTrashFile(expectedFilePath, "content_2_2");
118 git.add().addFilepattern(".").call();
119 git.commit().setMessage("updated file").call();
120
121 git.archive().setOutputStream(new MockOutputStream())
122 .setFormat(format.SUFFIXES.get(0))
123 .setTree(git.getRepository().resolve("HEAD"))
124 .setPaths(expectedFilePath).call();
125
126 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 2, format.size());
127 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath(expectedFilePath));
128 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory"));
129 }
130 }
131
132 @Test
133 public void archiveByIdSpecificFile() throws IOException, GitAPIException {
134 try (Git git = new Git(db)) {
135 writeTrashFile("file_1.txt", "content_1_1");
136 git.add().addFilepattern("file_1.txt").call();
137 RevCommit first = git.commit().setMessage("create file").call();
138
139 writeTrashFile("file_1.txt", "content_1_2");
140 String expectedFilePath = "some_directory/file_2.txt";
141 writeTrashFile(expectedFilePath, "content_2_2");
142 git.add().addFilepattern(".").call();
143 git.commit().setMessage("updated file").call();
144
145 Map<String, Object> options = new HashMap<>();
146 Integer opt = Integer.valueOf(42);
147 options.put("foo", opt);
148 MockOutputStream out = new MockOutputStream();
149 git.archive().setOutputStream(out)
150 .setFormat(format.SUFFIXES.get(0))
151 .setFormatOptions(options)
152 .setTree(first)
153 .setPaths("file_1.txt").call();
154
155 assertEquals(opt.intValue(), out.getFoo());
156 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 1, format.size());
157 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_1", format.getByPath("file_1.txt"));
158 }
159 }
160
161 @Test
162 public void archiveByDirectoryPath() throws GitAPIException, IOException {
163 try (Git git = new Git(db)) {
164 writeTrashFile("file_0.txt", "content_0_1");
165 git.add().addFilepattern("file_0.txt").call();
166 git.commit().setMessage("commit_1").call();
167
168 writeTrashFile("file_0.txt", "content_0_2");
169 String expectedFilePath1 = "some_directory/file_1.txt";
170 writeTrashFile(expectedFilePath1, "content_1_2");
171 String expectedFilePath2 = "some_directory/file_2.txt";
172 writeTrashFile(expectedFilePath2, "content_2_2");
173 String expectedFilePath3 = "some_directory/nested_directory/file_3.txt";
174 writeTrashFile(expectedFilePath3, "content_3_2");
175 git.add().addFilepattern(".").call();
176 git.commit().setMessage("commit_2").call();
177 git.archive().setOutputStream(new MockOutputStream())
178 .setFormat(format.SUFFIXES.get(0))
179 .setTree(git.getRepository().resolve("HEAD"))
180 .setPaths("some_directory/").call();
181
182 assertEquals(UNEXPECTED_ARCHIVE_SIZE, 5, format.size());
183 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_1_2", format.getByPath(expectedFilePath1));
184 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_2_2", format.getByPath(expectedFilePath2));
185 assertEquals(UNEXPECTED_FILE_CONTENTS, "content_3_2", format.getByPath(expectedFilePath3));
186 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory"));
187 assertNull(UNEXPECTED_TREE_CONTENTS, format.getByPath("some_directory/nested_directory"));
188 }
189 }
190
191 private class MockFormat implements ArchiveCommand.Format<MockOutputStream> {
192
193 private Map<String, String> entries = new HashMap<String, String>();
194
195 private int size() {
196 return entries.size();
197 }
198
199 private String getByPath(String path) {
200 return entries.get(path);
201 }
202
203 private final List<String> SUFFIXES = Collections
204 .unmodifiableList(Arrays.asList(".mck"));
205
206 public MockOutputStream createArchiveOutputStream(OutputStream s)
207 throws IOException {
208 return createArchiveOutputStream(s,
209 Collections.<String, Object> emptyMap());
210 }
211
212 public MockOutputStream createArchiveOutputStream(OutputStream s,
213 Map<String, Object> o) throws IOException {
214 for (Map.Entry<String, Object> p : o.entrySet()) {
215 try {
216 String methodName = "set"
217 + StringUtils.capitalize(p.getKey());
218 new Statement(s, methodName, new Object[] { p.getValue() })
219 .execute();
220 } catch (Exception e) {
221 throw new IOException("cannot set option: " + p.getKey(), e);
222 }
223 }
224 return new MockOutputStream();
225 }
226
227 public void putEntry(MockOutputStream out, String path, FileMode mode, ObjectLoader loader) {
228 String content = mode != FileMode.TREE ? new String(loader.getBytes()) : null;
229 entries.put(path, content);
230 }
231
232 public Iterable<String> suffixes() {
233 return SUFFIXES;
234 }
235 }
236
237 public class MockOutputStream extends OutputStream {
238
239 private int foo;
240
241 public void setFoo(int foo) {
242 this.foo = foo;
243 }
244
245 public int getFoo() {
246 return foo;
247 }
248
249 @Override
250 public void write(int b) throws IOException {
251
252 }
253 }
254 }