comparison test/org/tmatesoft/hg/test/TestCommit.java @ 559:6ca3d0c5b4bc

Commit: tests and fixes for defects discovered
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Mon, 25 Feb 2013 19:48:20 +0100
parents 9edfd5a223b8
children 78a9e26e670d
comparison
equal deleted inserted replaced
558:154718ae23ed 559:6ca3d0c5b4bc
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.test; 17 package org.tmatesoft.hg.test;
18 18
19 import static org.junit.Assert.*;
20 import static org.tmatesoft.hg.repo.HgRepository.*;
21 import static org.tmatesoft.hg.repo.HgRepository.DEFAULT_BRANCH_NAME;
19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; 22 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION;
20 23
21 import java.io.File; 24 import java.io.File;
25 import java.io.FileInputStream;
22 import java.io.FileWriter; 26 import java.io.FileWriter;
27 import java.io.IOException;
23 import java.nio.ByteBuffer; 28 import java.nio.ByteBuffer;
24 29 import java.nio.channels.FileChannel;
30 import java.util.List;
31
32 import org.hamcrest.CoreMatchers;
25 import org.junit.Test; 33 import org.junit.Test;
34 import org.tmatesoft.hg.core.HgAddRemoveCommand;
35 import org.tmatesoft.hg.core.HgCatCommand;
36 import org.tmatesoft.hg.core.HgChangeset;
37 import org.tmatesoft.hg.core.HgLogCommand;
38 import org.tmatesoft.hg.core.Nodeid;
39 import org.tmatesoft.hg.internal.ByteArrayChannel;
26 import org.tmatesoft.hg.repo.CommitFacility; 40 import org.tmatesoft.hg.repo.CommitFacility;
41 import org.tmatesoft.hg.repo.HgDataFile;
27 import org.tmatesoft.hg.repo.HgLookup; 42 import org.tmatesoft.hg.repo.HgLookup;
28 import org.tmatesoft.hg.repo.HgRepository; 43 import org.tmatesoft.hg.repo.HgRepository;
44 import org.tmatesoft.hg.util.Path;
29 45
30 /** 46 /**
47 * Handy for debug to see patch content:
48 * ...RevlogDump /tmp/test-commit2non-empty/.hg/ store/data/file1.i dumpData
31 * 49 *
32 * @author Artem Tikhomirov 50 * @author Artem Tikhomirov
33 * @author TMate Software Ltd. 51 * @author TMate Software Ltd.
34 */ 52 */
35 public class TestCommit { 53 public class TestCommit {
36 54
37 @Test 55 @Test
38 public void testCommitToNonEmpty() throws Exception { 56 public void testCommitToNonEmpty() throws Exception {
39 File repoLoc = RepoUtils.initEmptyTempRepo("test-commit2non-empty"); 57 File repoLoc = RepoUtils.initEmptyTempRepo("test-commit2non-empty");
40 FileWriter fw = new FileWriter(new File(repoLoc, "file1")); 58 RepoUtils.createFile(new File(repoLoc, "file1"), "hello\n");
41 fw.write("hello"); 59 new ExecHelper(new OutputParser.Stub(), repoLoc).run("hg", "commit", "--addremove", "-m", "FIRST");
42 fw.close();
43 new ExecHelper(new OutputParser.Stub(true), repoLoc).run("hg", "commit", "--addremove", "-m", "FIRST");
44 // 60 //
45 HgRepository hgRepo = new HgLookup().detect(repoLoc); 61 HgRepository hgRepo = new HgLookup().detect(repoLoc);
46 CommitFacility cf = new CommitFacility(hgRepo, 0); 62 CommitFacility cf = new CommitFacility(hgRepo, 0);
47 // FIXME test diff for processing changed newlines - if a whole line or just changed endings are in the patch! 63 // FIXME test diff for processing changed newlines (ie \r\n -> \n or vice verse) - if a whole line or
48 cf.add(hgRepo.getFileNode("file1"), new ByteArraySupplier("hello\nworld".getBytes())); 64 // just changed endings are in the patch!
49 cf.commit("SECOND"); 65 HgDataFile df = hgRepo.getFileNode("file1");
50 // /tmp/test-commit2non-empty/.hg/ store/data/file1.i dumpData 66 cf.add(df, new ByteArraySupplier("hello\nworld".getBytes()));
67 Nodeid secondRev = cf.commit("SECOND");
68 //
69 List<HgChangeset> commits = new HgLogCommand(hgRepo).execute();
70 assertEquals(2, commits.size());
71 HgChangeset c1 = commits.get(0);
72 HgChangeset c2 = commits.get(1);
73 assertEquals("FIRST", c1.getComment());
74 assertEquals("SECOND", c2.getComment());
75 assertEquals(df.getPath(), c2.getAffectedFiles().get(0));
76 assertEquals(c1.getNodeid(), c2.getFirstParentRevision());
77 assertEquals(Nodeid.NULL, c2.getSecondParentRevision());
78 assertEquals(secondRev, c2.getNodeid());
51 } 79 }
52 80
53 @Test 81 @Test
54 public void testCommitToEmpty() throws Exception { 82 public void testCommitToEmpty() throws Exception {
55 File repoLoc = RepoUtils.initEmptyTempRepo("test-commit2empty"); 83 File repoLoc = RepoUtils.initEmptyTempRepo("test-commit2empty");
56 FileWriter fw = new FileWriter(new File(repoLoc, "file1")); 84 String fname = "file1";
57 fw.write("hello"); 85 RepoUtils.createFile(new File(repoLoc, fname), null);
58 fw.close(); 86 new ExecHelper(new OutputParser.Stub(), repoLoc).run("hg", "add", fname);
59 // 87 //
60 HgRepository hgRepo = new HgLookup().detect(repoLoc); 88 HgRepository hgRepo = new HgLookup().detect(repoLoc);
89 assertEquals("[sanity]", 0, new HgLogCommand(hgRepo).execute().size());
61 CommitFacility cf = new CommitFacility(hgRepo, NO_REVISION); 90 CommitFacility cf = new CommitFacility(hgRepo, NO_REVISION);
62 // FIXME test diff for processing changed newlines - if a whole line or just changed endings are in the patch! 91 HgDataFile df = hgRepo.getFileNode(fname);
63 cf.add(hgRepo.getFileNode("file1"), new ByteArraySupplier("hello\nworld".getBytes())); 92 final byte[] initialContent = "hello\nworld".getBytes();
64 cf.commit("commit 1"); 93 cf.add(df, new ByteArraySupplier(initialContent));
94 String comment = "commit 1";
95 Nodeid c1Rev = cf.commit(comment);
96 List<HgChangeset> commits = new HgLogCommand(hgRepo).execute();
97 assertEquals(1, commits.size());
98 HgChangeset c1 = commits.get(0);
99 assertEquals(1, c1.getAffectedFiles().size());
100 assertEquals(df.getPath(), c1.getAffectedFiles().get(0));
101 assertEquals(0, c1.getRevisionIndex());
102 assertEquals(Nodeid.NULL, c1.getFirstParentRevision());
103 assertEquals(Nodeid.NULL, c1.getSecondParentRevision());
104 assertEquals(HgRepository.DEFAULT_BRANCH_NAME, c1.getBranch());
105 assertEquals(comment, c1.getComment());
106 assertEquals(c1Rev, c1.getNodeid());
107 ByteArrayChannel bac = new ByteArrayChannel();
108 new HgCatCommand(hgRepo).file(df.getPath()).execute(bac);
109 assertArrayEquals(initialContent, bac.toArray());
110 }
111
112 @Test
113 public void testCommitIntoBranch() throws Exception {
114 File repoLoc = RepoUtils.cloneRepoToTempLocation("log-1", "test-add-remove-commit", false);
115 HgRepository hgRepo = new HgLookup().detect(repoLoc);
116 HgDataFile dfD = hgRepo.getFileNode("d");
117 assertTrue("[sanity]", dfD.exists());
118 File fileD = new File(repoLoc, "d");
119 assertTrue("[sanity]", fileD.canRead());
120 final int parentCsetRevIndex = hgRepo.getChangelog().getLastRevision();
121 HgChangeset parentCset = new HgLogCommand(hgRepo).range(parentCsetRevIndex, parentCsetRevIndex).execute().get(0);
122 assertEquals("[sanity]", DEFAULT_BRANCH_NAME, parentCset.getBranch());
123 //
124 RepoUtils.modifyFileAppend(fileD, "A CHANGE\n");
125 CommitFacility cf = new CommitFacility(hgRepo, parentCsetRevIndex);
126 FileContentSupplier contentProvider = new FileContentSupplier(fileD);
127 cf.add(dfD, contentProvider);
128 cf.branch("branch1");
129 Nodeid commitRev1 = cf.commit("FIRST");
130 contentProvider.done();
131 //
132 // FIXME requirement to reload repository is disgusting
133 hgRepo = new HgLookup().detect(repoLoc);
134 List<HgChangeset> commits = new HgLogCommand(hgRepo).range(parentCsetRevIndex+1, TIP).execute();
135 assertEquals(1, commits.size());
136 HgChangeset c1 = commits.get(0);
137 assertEquals(c1.getNodeid(), commitRev1);
138 assertEquals("branch1", c1.getBranch());
139 assertEquals("FIRST", c1.getComment());
140 //
141 assertHgVerifyOk(repoLoc);
142 }
143
144 /**
145 * use own add and remove commands and then commit
146 */
147 @Test
148 public void testCommitWithAddRemove() throws Exception {
149 File repoLoc = RepoUtils.cloneRepoToTempLocation("log-1", "test-add-remove-commit", false);
150 HgRepository hgRepo = new HgLookup().detect(repoLoc);
151 assertTrue("[sanity]", hgRepo.getFileNode("d").exists());
152 assertTrue("[sanity]", new File(repoLoc, "d").canRead());
153 RepoUtils.createFile(new File(repoLoc, "xx"), "xyz");
154 new HgAddRemoveCommand(hgRepo).add(Path.create("xx")).remove(Path.create("d")).execute();
155 CommitFacility cf = new CommitFacility(hgRepo, hgRepo.getChangelog().getLastRevision());
156 FileContentSupplier contentProvider = new FileContentSupplier(new File(repoLoc, "xx"));
157 cf.add(hgRepo.getFileNode("xx"), contentProvider);
158 cf.forget(hgRepo.getFileNode("d"));
159 Nodeid commitRev = cf.commit("Commit with add/remove cmd");
160 contentProvider.done();
161 // Note, working directory still points to original revision, CommitFacility doesn't update dirstate
162 //
163 // FIXME requirement to reload repository is disgusting
164 hgRepo = new HgLookup().detect(repoLoc);
165 List<HgChangeset> commits = new HgLogCommand(hgRepo).changeset(commitRev).execute();
166 HgChangeset cmt = commits.get(0);
167 assertEquals(1, cmt.getAddedFiles().size());
168 assertEquals("xx", cmt.getAddedFiles().get(0).getPath().toString());
169 assertEquals(1, cmt.getRemovedFiles().size());
170 assertEquals("d", cmt.getRemovedFiles().get(0).toString());
171 ByteArrayChannel sink = new ByteArrayChannel();
172 new HgCatCommand(hgRepo).file(Path.create("xx")).changeset(commitRev).execute(sink);
173 assertArrayEquals("xyz".getBytes(), sink.toArray());
174 //
175 assertHgVerifyOk(repoLoc);
176 }
177 /**
178 * perform few commits one by one, into different branches
179 */
180 @Test
181 public void testSequentialCommits() throws Exception {
182 File repoLoc = RepoUtils.cloneRepoToTempLocation("log-1", "test-add-remove-commit", false);
183 HgRepository hgRepo = new HgLookup().detect(repoLoc);
184 HgDataFile dfD = hgRepo.getFileNode("d");
185 assertTrue("[sanity]", dfD.exists());
186 File fileD = new File(repoLoc, "d");
187 assertTrue("[sanity]", fileD.canRead());
188 //
189 RepoUtils.modifyFileAppend(fileD, " 1 \n");
190 final int parentCsetRevIndex = hgRepo.getChangelog().getLastRevision();
191 CommitFacility cf = new CommitFacility(hgRepo, parentCsetRevIndex);
192 FileContentSupplier contentProvider = new FileContentSupplier(fileD);
193 cf.add(dfD, contentProvider);
194 cf.branch("branch1");
195 Nodeid commitRev1 = cf.commit("FIRST");
196 contentProvider.done();
197 //
198 RepoUtils.modifyFileAppend(fileD, " 2 \n");
199 cf.add(dfD, contentProvider = new FileContentSupplier(fileD));
200 cf.branch("branch2");
201 Nodeid commitRev2 = cf.commit("SECOND");
202 contentProvider.done();
203 //
204 RepoUtils.modifyFileAppend(fileD, " 2 \n");
205 cf.add(dfD, contentProvider = new FileContentSupplier(fileD));
206 cf.branch(DEFAULT_BRANCH_NAME);
207 Nodeid commitRev3 = cf.commit("THIRD");
208 contentProvider.done();
209 //
210 // FIXME requirement to reload repository is disgusting
211 hgRepo = new HgLookup().detect(repoLoc);
212 List<HgChangeset> commits = new HgLogCommand(hgRepo).range(parentCsetRevIndex+1, TIP).execute();
213 assertEquals(3, commits.size());
214 HgChangeset c1 = commits.get(0);
215 HgChangeset c2 = commits.get(1);
216 HgChangeset c3 = commits.get(2);
217 assertEquals(c1.getNodeid(), commitRev1);
218 assertEquals(c2.getNodeid(), commitRev2);
219 assertEquals(c3.getNodeid(), commitRev3);
220 assertEquals("branch1", c1.getBranch());
221 assertEquals("branch2", c2.getBranch());
222 assertEquals(DEFAULT_BRANCH_NAME, c3.getBranch());
223 assertEquals("FIRST", c1.getComment());
224 assertEquals("SECOND", c2.getComment());
225 assertEquals("THIRD", c3.getComment());
226 assertHgVerifyOk(repoLoc);
227 }
228
229 private void assertHgVerifyOk(File repoLoc) throws InterruptedException, IOException {
230 ExecHelper verifyRun = new ExecHelper(new OutputParser.Stub(), repoLoc);
231 verifyRun.run("hg", "verify");
232 assertEquals("hg verify", 0, verifyRun.getExitValue());
65 } 233 }
66 234
67 public static void main(String[] args) throws Exception { 235 public static void main(String[] args) throws Exception {
68 new TestCommit().testCommitToEmpty(); 236 new TestCommit().testCommitToEmpty();
69 if (Boolean.TRUE.booleanValue()) { 237 if (Boolean.TRUE.booleanValue()) {
107 buf.put(data, pos, count); 275 buf.put(data, pos, count);
108 pos += count; 276 pos += count;
109 return count; 277 return count;
110 } 278 }
111 } 279 }
280
281 static class FileContentSupplier implements CommitFacility.ByteDataSupplier {
282 private final FileChannel channel;
283 private IOException error;
284
285 public FileContentSupplier(File f) throws IOException {
286 if (!f.canRead()) {
287 throw new IOException(String.format("Can't read file %s", f));
288 }
289 channel = new FileInputStream(f).getChannel();
290 }
291
292 public int read(ByteBuffer buf) {
293 if (error != null) {
294 return -1;
295 }
296 try {
297 return channel.read(buf);
298 } catch (IOException ex) {
299 error = ex;
300 }
301 return -1;
302 }
303
304 public void done() throws IOException {
305 channel.close();
306 if (error != null) {
307 throw error;
308 }
309 }
310 }
112 } 311 }