# HG changeset patch # User Artem Tikhomirov # Date 1370536958 -7200 # Node ID 4ec2d44e2bf3f84a5b0efd65c3a0e1fd5336a445 # Parent 170b6ecc890e476f38108067daa3dfffe9758013 Compound test scenario for checkout, add, remove, revert and commit diff -r 170b6ecc890e -r 4ec2d44e2bf3 build.xml --- a/build.xml Thu Jun 06 14:21:11 2013 +0200 +++ b/build.xml Thu Jun 06 18:42:38 2013 +0200 @@ -84,6 +84,7 @@ + @@ -108,6 +109,8 @@ + + @@ -135,7 +138,7 @@ - + @@ -149,7 +152,7 @@ - + @@ -165,7 +168,7 @@ - + diff -r 170b6ecc890e -r 4ec2d44e2bf3 src/org/tmatesoft/hg/internal/COWTransaction.java --- a/src/org/tmatesoft/hg/internal/COWTransaction.java Thu Jun 06 14:21:11 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/COWTransaction.java Thu Jun 06 18:42:38 2013 +0200 @@ -46,19 +46,12 @@ @Override public File prepare(File f) throws HgIOException { - if (!f.exists()) { - record(f, null); - try { - f.getParentFile().mkdirs(); - f.createNewFile(); - return f; - } catch (IOException ex) { - throw new HgIOException("Failed to create new file", ex, f); - } - } if (known(f)) { return f; } + if (!f.exists()) { + return recordNonExistent(f); + } final File parentDir = f.getParentFile(); assert parentDir.canWrite(); File copy = new File(parentDir, f.getName() + ".hg4j.copy"); @@ -85,6 +78,9 @@ if (known(origin)) { return origin; } + if (!origin.exists()) { + return recordNonExistent(origin); + } fileHelper.copy(origin, backup); final RollbackEntry e = record(origin, backup); e.keepBackup = true; @@ -139,6 +135,17 @@ } } + private File recordNonExistent(File f) throws HgIOException { + record(f, null); + try { + f.getParentFile().mkdirs(); + f.createNewFile(); + return f; + } catch (IOException ex) { + throw new HgIOException("Failed to create new file", ex, f); + } + } + private RollbackEntry record(File origin, File backup) { final RollbackEntry e = new RollbackEntry(origin, backup); entries.add(e); @@ -146,23 +153,28 @@ } private boolean known(File f) { - for (RollbackEntry e : entries) { - if (e.origin.equals(f)) { - return true; - } + RollbackEntry e = lookup(f); + return e != null; + } + + private RollbackEntry find(File f) { + RollbackEntry e = lookup(f); + if (e != null) { + return e; } - return false; + assert false; + return new RollbackEntry(f,f); } - private RollbackEntry find(File f) { + + private RollbackEntry lookup(File f) { for (RollbackEntry e : entries) { if (e.origin.equals(f)) { return e; } } - assert false; - return new RollbackEntry(f,f); + return null; } - + private static class RollbackEntry { public final File origin; public final File backup; // may be null to indicate file didn't exist diff -r 170b6ecc890e -r 4ec2d44e2bf3 test/org/tmatesoft/hg/test/ComplexTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/org/tmatesoft/hg/test/ComplexTest.java Thu Jun 06 18:42:38 2013 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2013 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.test; + +import static org.junit.Assert.*; + +import java.io.File; + +import org.junit.Rule; +import org.junit.Test; +import org.tmatesoft.hg.core.HgAddRemoveCommand; +import org.tmatesoft.hg.core.HgCheckoutCommand; +import org.tmatesoft.hg.core.HgCommitCommand; +import org.tmatesoft.hg.core.HgRevertCommand; +import org.tmatesoft.hg.repo.HgLookup; +import org.tmatesoft.hg.repo.HgManifest; +import org.tmatesoft.hg.repo.HgRepository; +import org.tmatesoft.hg.util.Path; + +/** + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public class ComplexTest { + + @Rule + public ErrorCollectorExt errorCollector = new ErrorCollectorExt(); + + /** + * Regular work sequence with checkout, add, remove, and commit + */ + @Test + public void testLocalScenario1() throws Exception { + File repoLoc = RepoUtils.createEmptyDir("composite-scenario-1"); + // init empty + // TODO HgInitCommand + RepoUtils.exec(repoLoc, 0, "hg", "init"); + HgRepository hgRepo = new HgLookup().detect(repoLoc); + assertFalse("[sanity]", hgRepo.isInvalid()); + assertEquals("[sanity]", 0, hgRepo.getChangelog().getRevisionCount()); + // add 2 files + Path fa = Path.create("a"), fb = Path.create("b"); + final File fileA = new File(repoLoc, fa.toString()); + final File fileB = new File(repoLoc, fb.toString()); + RepoUtils.createFile(fileA, "first file"); + RepoUtils.createFile(fileB, "second file"); + new HgAddRemoveCommand(hgRepo).add(fa, fb).execute(); + new HgCommitCommand(hgRepo).message("FIRST").execute(); + // add one more file + // remove one initial file + Path fc = Path.create("c"); + final File fileC = new File(repoLoc, fc.toString()); + RepoUtils.createFile(fileC, "third file"); + fileB.delete(); + // TODO HgAddRemoveCommand needs #copy(from, to) method + new HgAddRemoveCommand(hgRepo).add(fc).remove(fb).execute(); + new HgCommitCommand(hgRepo).message("SECOND").execute(); + // + // TODO hgRepo.getCommitLastMessage() shall be updated from HgCommitCommand + assertEquals(2, hgRepo.getChangelog().getRevisionCount()); + // checkout previous version + new HgCheckoutCommand(hgRepo).changeset(0).clean(true).execute(); + assertTrue(fileA.isFile()); + assertTrue(fileB.isFile()); + assertFalse(fileC.isFile()); + // branch/two heads + RepoUtils.modifyFileAppend(fileA, "A1"); + RepoUtils.modifyFileAppend(fileB, "B1"); + new HgCommitCommand(hgRepo).message("THIRD").execute(); + // + new HgCheckoutCommand(hgRepo).changeset(1).clean(true).execute(); + assertTrue(fileA.isFile()); + assertFalse(fileB.isFile()); + assertTrue(fileC.isFile()); + RepoUtils.modifyFileAppend(fileA, "A2"); + RepoUtils.modifyFileAppend(fileC, "C1"); + new HgRevertCommand(hgRepo).changeset(1).file(fa).execute(); + errorCollector.assertTrue(new File(fileA.getParent(), fileA.getName() + ".orig").isFile()); + new HgCommitCommand(hgRepo).message("FOURTH").execute(); + // TODO merge and HgMergeCommand + + errorCollector.assertEquals(2, hgRepo.getFileNode(fa).getRevisionCount()); + errorCollector.assertEquals(2, hgRepo.getFileNode(fb).getRevisionCount()); + errorCollector.assertEquals(2, hgRepo.getFileNode(fc).getRevisionCount()); + final HgManifest mf = hgRepo.getManifest(); + errorCollector.assertEquals(mf.getFileRevision(0, fa), mf.getFileRevision(3, fa)); // "A2" was reverted + } +} diff -r 170b6ecc890e -r 4ec2d44e2bf3 test/org/tmatesoft/hg/test/RepoUtils.java --- a/test/org/tmatesoft/hg/test/RepoUtils.java Thu Jun 06 14:21:11 2013 +0200 +++ b/test/org/tmatesoft/hg/test/RepoUtils.java Thu Jun 06 18:42:38 2013 +0200 @@ -30,6 +30,8 @@ import java.util.Iterator; import java.util.LinkedList; +import junit.framework.Assert; + import org.tmatesoft.hg.core.HgException; import org.tmatesoft.hg.core.HgIOException; import org.tmatesoft.hg.internal.FileUtils; @@ -156,4 +158,16 @@ fw.close(); } } + + static void exec(File wd, int expectedRetVal, String... args) throws Exception { + OutputParser.Stub s = new OutputParser.Stub(); + try { + ExecHelper eh = new ExecHelper(s, wd); + eh.run(args); + Assert.assertEquals(expectedRetVal, eh.getExitValue()); + } catch (Exception ex) { + System.err.println(s.result()); + throw ex; + } + } }