changeset 527:47b7bedf0569

Tests for present HgCheckoutCommand functionality. Update branch information on checkout. Use UTF8 encoding for the branch file
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 15 Jan 2013 19:46:19 +0100
parents 2f9ed6bcefa2
children f7fbf48b9383
files src/org/tmatesoft/hg/core/HgCheckoutCommand.java src/org/tmatesoft/hg/internal/DirstateReader.java src/org/tmatesoft/hg/internal/EncodingHelper.java src/org/tmatesoft/hg/repo/HgRepositoryFiles.java test/org/tmatesoft/hg/test/TestCheckout.java test/org/tmatesoft/hg/test/TestRevert.java
diffstat 6 files changed, 122 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCheckoutCommand.java	Tue Jan 15 17:07:19 2013 +0100
+++ b/src/org/tmatesoft/hg/core/HgCheckoutCommand.java	Tue Jan 15 19:46:19 2013 +0100
@@ -16,14 +16,17 @@
  */
 package org.tmatesoft.hg.core;
 
+import static org.tmatesoft.hg.repo.HgRepositoryFiles.Branch;
 import static org.tmatesoft.hg.repo.HgRepositoryFiles.Dirstate;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.nio.channels.FileChannel;
 
 import org.tmatesoft.hg.internal.DirstateBuilder;
+import org.tmatesoft.hg.internal.EncodingHelper;
 import org.tmatesoft.hg.internal.Experimental;
 import org.tmatesoft.hg.internal.Internals;
 import org.tmatesoft.hg.internal.WorkingDirFileWriter;
@@ -130,7 +133,19 @@
 			} catch (IOException ex) {
 				throw new HgIOException("Can't write down new directory state", ex, dirstateFile);
 			}
-			// FIXME write down branch file
+			String branchName = repo.getChangelog().range(revisionToCheckout, revisionToCheckout).get(0).branch();
+			assert branchName != null;
+			if (!HgRepository.DEFAULT_BRANCH_NAME.equals(branchName)) {
+				File branchFile = internalRepo.getRepositoryFile(Branch);
+				try {
+					// branch file is UTF-8, see http://mercurial.selenic.com/wiki/EncodingStrategy#UTF-8_strings
+					OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(branchFile), EncodingHelper.getUTF8());
+					ow.write(branchName);
+					ow.close();
+				} catch (IOException ex) {
+					throw new HgIOException("Can't write down branch information", ex, branchFile);
+				}
+			}
 		} catch (HgRuntimeException ex) {
 			throw new HgLibraryFailureException(ex);
 		}
--- a/src/org/tmatesoft/hg/internal/DirstateReader.java	Tue Jan 15 17:07:19 2013 +0100
+++ b/src/org/tmatesoft/hg/internal/DirstateReader.java	Tue Jan 15 19:46:19 2013 +0100
@@ -17,14 +17,16 @@
 package org.tmatesoft.hg.internal;
 
 import static org.tmatesoft.hg.core.Nodeid.NULL;
+import static org.tmatesoft.hg.repo.HgRepositoryFiles.Branch;
 import static org.tmatesoft.hg.repo.HgRepositoryFiles.Dirstate;
 import static org.tmatesoft.hg.util.LogFacility.Severity.Debug;
 
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgDirstate;
@@ -158,11 +160,17 @@
 	 * @return branch associated with the working directory
 	 */
 	public static String readBranch(Internals internalRepo) throws HgInvalidControlFileException {
-		File branchFile = internalRepo.getFileFromRepoDir("branch"); // FIXME constant in the HgRepositoryFiles
+		File branchFile = internalRepo.getRepositoryFile(Branch);
 		String branch = HgRepository.DEFAULT_BRANCH_NAME;
 		if (branchFile.exists()) {
 			try {
-				BufferedReader r = new BufferedReader(new FileReader(branchFile));
+				// branch file is UTF-8 encoded, see http://mercurial.selenic.com/wiki/EncodingStrategy#UTF-8_strings
+				// shall not use system-default encoding (FileReader) when reading it!
+				// Perhaps, shall use EncodingHelper.fromBranch and InputStream instead, for uniformity?
+				// Since whole file is in UTF8, InputStreamReader is a convenience over InputStream,
+				// which we use elsewhere (together with EncodingHelper) - other files are usually a mix of binary data 
+				// and encoded text (hence, InputStreamReader with charset is not an option there)
+				BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(branchFile), EncodingHelper.getUTF8()));
 				String b = r.readLine();
 				if (b != null) {
 					b = b.trim().intern();
--- a/src/org/tmatesoft/hg/internal/EncodingHelper.java	Tue Jan 15 17:07:19 2013 +0100
+++ b/src/org/tmatesoft/hg/internal/EncodingHelper.java	Tue Jan 15 19:46:19 2013 +0100
@@ -111,4 +111,7 @@
 		return encoder.charset();
 	}
 
+	public static Charset getUTF8() {
+		return Charset.forName("UTF-8");
+	}
 }
--- a/src/org/tmatesoft/hg/repo/HgRepositoryFiles.java	Tue Jan 15 17:07:19 2013 +0100
+++ b/src/org/tmatesoft/hg/repo/HgRepositoryFiles.java	Tue Jan 15 19:46:19 2013 +0100
@@ -29,7 +29,8 @@
 	Dirstate(false, "dirstate"), HgLocalTags(false, "localtags"),
 	HgSub(".hgsub"), HgSubstate(".hgsubstate"),
 	LastMessage(false, "last-message.txt"),
-	Bookmarks(false, "bookmarks"), BookmarksCurrent(false, "bookmarks.current");
+	Bookmarks(false, "bookmarks"), BookmarksCurrent(false, "bookmarks.current"),
+	Branch(false, "branch");
 
 	private final String fname;
 	private final boolean livesInWC; 
--- a/test/org/tmatesoft/hg/test/TestCheckout.java	Tue Jan 15 17:07:19 2013 +0100
+++ b/test/org/tmatesoft/hg/test/TestCheckout.java	Tue Jan 15 19:46:19 2013 +0100
@@ -16,8 +16,20 @@
  */
 package org.tmatesoft.hg.test;
 
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileFilter;
+
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;
+import org.tmatesoft.hg.core.HgCheckoutCommand;
+import org.tmatesoft.hg.core.Nodeid;
+import org.tmatesoft.hg.repo.HgLookup;
+import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.util.Pair;
+import org.tmatesoft.hg.util.Path;
 
 /**
  * 
@@ -26,10 +38,42 @@
  */
 public class TestCheckout {
 
+	@Rule
+	public ErrorCollectorExt errorCollector = new ErrorCollectorExt();
+
+	private HgRepository repo;
+	private ExecHelper eh;
+
 
 	@Test
-	public void testCleanCheckoutInEmptyDir() {
-		Assert.fail("clone without update, checkout, status");
+	public void testCleanCheckoutInEmptyDir() throws Exception {
+		File testRepoLoc = TestRevert.cloneRepoToTempLocation(Configuration.get().find("log-1"), "test-checkoutClean", true);
+		repo = new HgLookup().detect(testRepoLoc);
+		// nothing but .hg dir
+		assertEquals("[sanity]", 0, testRepoLoc.listFiles(new FilesOnlyFilter()).length);
+		
+		new HgCheckoutCommand(repo).changeset(1).execute();
+		errorCollector.assertEquals(2, testRepoLoc.listFiles(new FilesOnlyFilter()).length);
+
+		Pair<Nodeid, Nodeid> workingCopyParents = repo.getWorkingCopyParents();
+		errorCollector.assertEquals("da3461cd828dae8eb5fd11189d40e9df1961f191", workingCopyParents.first().toString());
+		errorCollector.assertEquals(Nodeid.NULL, workingCopyParents.second());
+		errorCollector.assertEquals(HgRepository.DEFAULT_BRANCH_NAME, repo.getWorkingCopyBranchName());
+
+		StatusOutputParser statusOutputParser = new StatusOutputParser();
+		eh = new ExecHelper(statusOutputParser, testRepoLoc);
+		eh.run("hg", "status", "-A");
+		errorCollector.assertEquals(2, statusOutputParser.getClean().size());
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("a")));
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b")));
+		
+		new HgCheckoutCommand(repo).changeset(3).execute();
+		statusOutputParser.reset();
+		eh.run("hg", "status", "-A");
+		errorCollector.assertEquals(3, statusOutputParser.getClean().size());
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b")));
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("d")));
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("dir/b")));
 	}
 
 	@Test
@@ -38,7 +82,26 @@
 	}
 
 	@Test
-	public void testBranchCheckout() {
-		Assert.fail("Make sure branch file is written");
+	public void testBranchCheckout() throws Exception {
+		File testRepoLoc = TestRevert.cloneRepoToTempLocation(Configuration.get().find("log-branches"), "test-checkoutBranch", true);
+		repo = new HgLookup().detect(testRepoLoc);
+		
+		new HgCheckoutCommand(repo).changeset(3 /*branch test*/).execute();
+
+		StatusOutputParser statusOutputParser = new StatusOutputParser();
+		eh = new ExecHelper(statusOutputParser, testRepoLoc);
+		eh.run("hg", "status", "-A");
+		errorCollector.assertEquals(3, statusOutputParser.getClean().size());
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("a")));
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("b")));
+		errorCollector.assertTrue(statusOutputParser.getClean().contains(Path.create("c")));
+		
+		errorCollector.assertEquals("test", repo.getWorkingCopyBranchName());
+	}
+
+	private static final class FilesOnlyFilter implements FileFilter {
+		public boolean accept(File f) {
+			return f.isFile();
+		}
 	}
 }
--- a/test/org/tmatesoft/hg/test/TestRevert.java	Tue Jan 15 17:07:19 2013 +0100
+++ b/test/org/tmatesoft/hg/test/TestRevert.java	Tue Jan 15 19:46:19 2013 +0100
@@ -21,6 +21,8 @@
 
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -39,6 +41,7 @@
 
 	@Rule
 	public ErrorCollectorExt errorCollector = new ErrorCollectorExt();
+
 	private HgRepository repo;
 	private ExecHelper eh;
 
@@ -48,13 +51,8 @@
 	
 	@Test
 	public void testCommand() throws Exception {
-		File tmpDir = Configuration.get().getTempDir();
-		tmpDir.mkdirs();
-		eh = new ExecHelper(new OutputParser.Stub(), tmpDir);
-		File testRepoLoc = TestIncoming.createEmptyDir("test-revert");
 		// get a copy of a repository
-		eh.run("hg", "clone", Configuration.get().find("log-1").getWorkingDir().toString(), testRepoLoc.getName());
-		assertEquals("[sanity]", 0, eh.getExitValue());
+		File testRepoLoc = cloneRepoToTempLocation(Configuration.get().find("log-1"), "test-revert", false);
 		
 		repo = new HgLookup().detect(testRepoLoc);
 		Path targetFile = Path.create("b");
@@ -72,10 +70,10 @@
 		statusParser.reset();
 		eh.run("hg", "status", "-A");
 
-		assertEquals(3, statusParser.getClean().size());
-		assertTrue(statusParser.getClean().contains(targetFile));
-		assertEquals(1, statusParser.getUnknown().size());
-		assertEquals(targetFile.toString() + ".orig", statusParser.getUnknown().get(0).toString());
+		errorCollector.assertEquals(3, statusParser.getClean().size());
+		errorCollector.assertTrue(statusParser.getClean().contains(targetFile));
+		errorCollector.assertEquals(1, statusParser.getUnknown().size());
+		errorCollector.assertEquals(targetFile.toString() + ".orig", statusParser.getUnknown().get(0).toString());
 	}
 
 	private static void modifyFileAppend(File f) throws Exception {
@@ -84,4 +82,19 @@
 		fos.write("XXX".getBytes());
 		fos.close();
 	}
+
+	static File cloneRepoToTempLocation(HgRepository repo, String name, boolean noupdate) throws IOException, InterruptedException {
+		File testRepoLoc = TestIncoming.createEmptyDir(name);
+		ExecHelper eh = new ExecHelper(new OutputParser.Stub(), testRepoLoc.getParentFile());
+		ArrayList<String> cmd = new ArrayList<String>();
+		cmd.add("hg"); cmd.add("clone");
+		if (noupdate) {
+			cmd.add("--noupdate");
+		}
+		cmd.add(repo.getWorkingDir().toString());
+		cmd.add(testRepoLoc.getName());
+		eh.run(cmd.toArray(new String[cmd.size()]));
+		assertEquals("[sanity]", 0, eh.getExitValue());
+		return testRepoLoc;
+	}
 }