tikhomirov@286: /* tikhomirov@609: * Copyright (c) 2011-2013 TMate Software Ltd tikhomirov@286: * tikhomirov@286: * This program is free software; you can redistribute it and/or modify tikhomirov@286: * it under the terms of the GNU General Public License as published by tikhomirov@286: * the Free Software Foundation; version 2 of the License. tikhomirov@286: * tikhomirov@286: * This program is distributed in the hope that it will be useful, tikhomirov@286: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@286: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@286: * GNU General Public License for more details. tikhomirov@286: * tikhomirov@286: * For information on how to redistribute this software under tikhomirov@286: * the terms of a license other than GNU General Public License tikhomirov@286: * contact TMate Software at support@hg4j.com tikhomirov@286: */ tikhomirov@286: package org.tmatesoft.hg.test; tikhomirov@286: tikhomirov@296: import static java.lang.Character.*; tikhomirov@609: import static org.junit.Assert.*; tikhomirov@296: tikhomirov@296: import java.util.TreeSet; tikhomirov@296: tikhomirov@286: import org.junit.Assert; tikhomirov@286: import org.junit.Test; tikhomirov@286: import org.tmatesoft.hg.core.Nodeid; tikhomirov@296: import org.tmatesoft.hg.repo.HgDirstate; tikhomirov@296: import org.tmatesoft.hg.repo.HgDirstate.EntryKind; tikhomirov@296: import org.tmatesoft.hg.repo.HgDirstate.Record; tikhomirov@296: import org.tmatesoft.hg.repo.HgInternals; tikhomirov@286: import org.tmatesoft.hg.repo.HgLookup; tikhomirov@286: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@286: import org.tmatesoft.hg.util.Pair; tikhomirov@296: import org.tmatesoft.hg.util.Path; tikhomirov@286: tikhomirov@286: /** tikhomirov@286: * tikhomirov@286: * @author Artem Tikhomirov tikhomirov@286: * @author TMate Software Ltd. tikhomirov@286: */ tikhomirov@286: public class TestDirstate { tikhomirov@286: private HgRepository repo; tikhomirov@286: tikhomirov@286: @Test tikhomirov@286: public void testParents() throws Exception { tikhomirov@286: repo = Configuration.get().find("log-branches"); tikhomirov@286: final Pair wcParents = repo.getWorkingCopyParents(); tikhomirov@609: assertEquals("5f24ef64e9dfb1540db524f88cb5c3d265e1a3b5", wcParents.first().toString()); tikhomirov@609: assertTrue(wcParents.second().isNull()); tikhomirov@286: // tikhomirov@609: HgDirstate ds = new HgInternals(repo).getDirstate(); tikhomirov@609: final Pair wcParents2 = ds.parents(); tikhomirov@609: assertEquals(wcParents.first(), wcParents2.first()); tikhomirov@609: assertEquals(wcParents.second(), wcParents2.second()); tikhomirov@286: } tikhomirov@286: tikhomirov@286: @Test tikhomirov@286: public void testParentsEmptyRepo() throws Exception { tikhomirov@286: // check contract return values for empty/nonexistent dirstate tikhomirov@536: repo = new HgLookup().detect(RepoUtils.initEmptyTempRepo("testParentsEmptyRepo")); tikhomirov@286: final Pair wcParents = repo.getWorkingCopyParents(); tikhomirov@286: Assert.assertTrue(wcParents.first().isNull()); tikhomirov@286: Assert.assertTrue(wcParents.second().isNull()); tikhomirov@286: } tikhomirov@286: tikhomirov@286: @Test tikhomirov@286: public void testBranchName() throws Exception { tikhomirov@286: repo = Configuration.get().find("log-branches"); tikhomirov@286: Assert.assertEquals("test", repo.getWorkingCopyBranchName()); tikhomirov@286: repo = Configuration.get().own(); tikhomirov@410: OutputParser.Stub output = new OutputParser.Stub(); tikhomirov@410: ExecHelper eh = new ExecHelper(output, repo.getWorkingDir()); tikhomirov@410: eh.run("hg", "branch"); tikhomirov@410: String branchName = output.result().toString().trim(); tikhomirov@410: Assert.assertEquals(branchName, repo.getWorkingCopyBranchName()); tikhomirov@286: } tikhomirov@293: tikhomirov@296: @Test tikhomirov@296: public void testMixedNameCaseHandling() throws Exception { tikhomirov@296: // General idea: to check cases like tikhomirov@293: // 1. dirstate: /a/b/c, FileIterator: /a/B/C tikhomirov@293: // 2. dirstate: /a/B/C, FileIterator: /a/b/c tikhomirov@293: // 2. dirstate: /a/B/C, FileIterator: /A/b/C tikhomirov@296: repo = Configuration.get().find("mixed-case"); tikhomirov@296: // Windows, case-insensitive file system tikhomirov@296: final HgInternals testAccess = new HgInternals(repo); tikhomirov@296: HgDirstate dirstate = testAccess.createDirstate(false); tikhomirov@296: final TreeSet entries = new TreeSet(); tikhomirov@296: dirstate.walk(new HgDirstate.Inspector() { tikhomirov@296: tikhomirov@296: public boolean next(EntryKind kind, Record entry) { tikhomirov@296: entries.add(entry.name()); tikhomirov@296: return true; tikhomirov@296: } tikhomirov@296: }); tikhomirov@296: Path[] expected = new Path[] { tikhomirov@296: Path.create("a/low/low"), tikhomirov@296: Path.create("a/low/UP"), tikhomirov@296: Path.create("a/UP/low"), tikhomirov@296: Path.create("a/UP/UP"), tikhomirov@296: }; tikhomirov@296: Path[] allLower = new Path[expected.length]; tikhomirov@296: Path[] allUpper = new Path[expected.length]; tikhomirov@296: Path[] mixedNonMatching = new Path[expected.length]; tikhomirov@296: for (int i = 0; i < expected.length; i++) { tikhomirov@296: assertTrue("prereq", entries.contains(expected[i])); tikhomirov@296: final String s = expected[i].toString(); tikhomirov@296: allLower[i] = Path.create(s.toLowerCase()); tikhomirov@296: allUpper[i] = Path.create(s.toUpperCase()); tikhomirov@296: char[] ss = s.toCharArray(); tikhomirov@296: for (int j = 0; j < ss.length; j++) { tikhomirov@296: if (isLetter(ss[j])) { tikhomirov@296: ss[j] = isLowerCase(ss[j]) ? toUpperCase(ss[j]) : toLowerCase(ss[j]); tikhomirov@296: } tikhomirov@296: } tikhomirov@296: Path mixed = Path.create(new String(ss)); tikhomirov@296: mixedNonMatching[i] = mixed; tikhomirov@296: } tikhomirov@296: // prereq tikhomirov@296: checkKnownInDirstate(testAccess, dirstate, expected, expected); tikhomirov@296: // all upper tikhomirov@296: checkKnownInDirstate(testAccess, dirstate, allUpper, expected); tikhomirov@296: // all lower tikhomirov@296: checkKnownInDirstate(testAccess, dirstate, allLower, expected); tikhomirov@296: // mixed tikhomirov@296: checkKnownInDirstate(testAccess, dirstate, mixedNonMatching, expected); tikhomirov@296: // tikhomirov@296: // check that in case-sensitive file system mangled names do not match tikhomirov@296: dirstate = testAccess.createDirstate(true); tikhomirov@296: // ensure read tikhomirov@296: dirstate.walk(new HgDirstate.Inspector() { tikhomirov@296: public boolean next(EntryKind kind, Record entry) { tikhomirov@296: return false; tikhomirov@296: } tikhomirov@296: }); tikhomirov@296: Path[] known = testAccess.checkKnown(dirstate, mixedNonMatching); tikhomirov@296: for (int i = 0; i < known.length; i++) { tikhomirov@296: if (known[i] != null) { tikhomirov@296: fail(expected[i] + " in case-sensitive dirstate matched " + known[i]); tikhomirov@296: } tikhomirov@296: } tikhomirov@296: tikhomirov@296: } tikhomirov@296: tikhomirov@296: private static void checkKnownInDirstate(HgInternals testAccess, HgDirstate dirstate, Path[] toCheck, Path[] expected) { tikhomirov@296: Path[] known = testAccess.checkKnown(dirstate, toCheck); tikhomirov@296: for (int i = 0; i < expected.length; i++) { tikhomirov@296: assertTrue(expected[i].equals(known[i])); tikhomirov@296: } tikhomirov@293: } tikhomirov@286: }