tikhomirov@67: /* tikhomirov@457: * Copyright (c) 2011-2012 TMate Software Ltd tikhomirov@67: * tikhomirov@67: * This program is free software; you can redistribute it and/or modify tikhomirov@67: * it under the terms of the GNU General Public License as published by tikhomirov@67: * the Free Software Foundation; version 2 of the License. tikhomirov@67: * tikhomirov@67: * This program is distributed in the hope that it will be useful, tikhomirov@67: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@67: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@67: * GNU General Public License for more details. tikhomirov@67: * tikhomirov@67: * For information on how to redistribute this software under tikhomirov@67: * the terms of a license other than GNU General Public License tikhomirov@102: * contact TMate Software at support@hg4j.com tikhomirov@67: */ tikhomirov@67: package org.tmatesoft.hg.test; tikhomirov@67: tikhomirov@103: import static org.hamcrest.CoreMatchers.equalTo; tikhomirov@103: import static org.hamcrest.CoreMatchers.notNullValue; tikhomirov@479: import static org.junit.Assert.*; tikhomirov@74: import static org.tmatesoft.hg.repo.HgRepository.TIP; tikhomirov@67: tikhomirov@103: import java.util.Collections; tikhomirov@67: import java.util.LinkedHashMap; tikhomirov@67: import java.util.LinkedList; tikhomirov@67: import java.util.Map; tikhomirov@479: import java.util.regex.Pattern; tikhomirov@67: tikhomirov@103: import org.junit.Rule; tikhomirov@101: import org.junit.Test; tikhomirov@427: import org.tmatesoft.hg.core.HgManifestHandler; tikhomirov@249: import org.tmatesoft.hg.core.HgFileRevision; tikhomirov@143: import org.tmatesoft.hg.core.HgManifestCommand; tikhomirov@74: import org.tmatesoft.hg.core.Nodeid; tikhomirov@479: import org.tmatesoft.hg.internal.IntMap; tikhomirov@103: import org.tmatesoft.hg.repo.HgLookup; tikhomirov@479: import org.tmatesoft.hg.repo.HgManifest; tikhomirov@74: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@479: import org.tmatesoft.hg.repo.HgManifest.Flags; tikhomirov@133: import org.tmatesoft.hg.util.Path; tikhomirov@67: tikhomirov@67: tikhomirov@67: /** tikhomirov@67: * tikhomirov@67: * @author Artem Tikhomirov tikhomirov@67: * @author TMate Software Ltd. tikhomirov@67: */ tikhomirov@67: public class TestManifest { tikhomirov@67: tikhomirov@103: @Rule tikhomirov@103: public ErrorCollectorExt errorCollector = new ErrorCollectorExt(); tikhomirov@103: tikhomirov@67: private final HgRepository repo; tikhomirov@67: private ManifestOutputParser manifestParser; tikhomirov@67: private ExecHelper eh; tikhomirov@249: final LinkedList revisions = new LinkedList(); tikhomirov@427: private HgManifestHandler handler = new HgManifestHandler() { tikhomirov@67: tikhomirov@249: public void file(HgFileRevision fileRevision) { tikhomirov@67: revisions.add(fileRevision); tikhomirov@67: } tikhomirov@67: tikhomirov@67: public void end(Nodeid manifestRevision) {} tikhomirov@67: public void dir(Path p) {} tikhomirov@67: public void begin(Nodeid manifestRevision) {} tikhomirov@67: }; tikhomirov@67: tikhomirov@103: public static void main(String[] args) throws Throwable { tikhomirov@101: TestManifest tm = new TestManifest(); tikhomirov@67: tm.testTip(); tikhomirov@67: tm.testFirstRevision(); tikhomirov@67: tm.testRevisionInTheMiddle(); tikhomirov@479: tm.testWalkFileRevisions(); tikhomirov@103: tm.errorCollector.verify(); tikhomirov@67: } tikhomirov@101: tikhomirov@101: public TestManifest() throws Exception { tikhomirov@101: this(new HgLookup().detectFromWorkingDir()); tikhomirov@101: } tikhomirov@67: tikhomirov@101: private TestManifest(HgRepository hgRepo) { tikhomirov@67: repo = hgRepo; tikhomirov@106: assertTrue(!repo.isInvalid()); tikhomirov@282: eh = new ExecHelper(manifestParser = new ManifestOutputParser(), repo.getWorkingDir()); tikhomirov@67: } tikhomirov@101: tikhomirov@101: @Test tikhomirov@67: public void testTip() throws Exception { tikhomirov@67: testRevision(TIP); tikhomirov@67: } tikhomirov@67: tikhomirov@101: @Test tikhomirov@67: public void testFirstRevision() throws Exception { tikhomirov@67: testRevision(0); tikhomirov@67: } tikhomirov@67: tikhomirov@101: @Test tikhomirov@67: public void testRevisionInTheMiddle() throws Exception { tikhomirov@67: int rev = repo.getManifest().getRevisionCount() / 2; tikhomirov@67: if (rev == 0) { tikhomirov@67: throw new IllegalStateException("Need manifest with few revisions"); tikhomirov@67: } tikhomirov@67: testRevision(rev); tikhomirov@67: } tikhomirov@479: tikhomirov@479: @Test tikhomirov@479: public void testWalkFileRevisions() throws Exception { tikhomirov@479: // hg --debug manifest --rev 150 | grep cmdline/org/tmatesoft/hg/console/Main.java tikhomirov@479: String fname = "cmdline/org/tmatesoft/hg/console/Main.java"; tikhomirov@479: Pattern ptrn = Pattern.compile("(\\w+)\\s+\\d{3}\\s+\\Q" + fname + "\\E$", Pattern.MULTILINE); tikhomirov@479: OutputParser.Stub output = new OutputParser.Stub(); tikhomirov@479: ExecHelper eh = new ExecHelper(output, repo.getWorkingDir()); tikhomirov@479: int[] revisions = new int[] { 100, 150, 200, 210, 300 }; tikhomirov@479: final IntMap expected = new IntMap(10); tikhomirov@479: for (int r : revisions) { tikhomirov@479: eh.run("hg", "--debug", "manifest", "--rev", Integer.toString(r)); tikhomirov@479: for (String l : output.lines(ptrn, 1)) { tikhomirov@479: assertFalse(expected.containsKey(r)); tikhomirov@479: expected.put(r, Nodeid.fromAscii(l)); tikhomirov@479: } tikhomirov@479: if (!expected.containsKey(r)) { tikhomirov@479: expected.put(r, Nodeid.NULL); tikhomirov@479: } tikhomirov@479: } tikhomirov@479: assertEquals(revisions.length, expected.size()); tikhomirov@479: final Path path = Path.create(fname); tikhomirov@479: repo.getManifest().walkFileRevisions(path, new HgManifest.Inspector() { tikhomirov@479: tikhomirov@479: private Nodeid expectedNodeid; tikhomirov@479: private int clogRev; tikhomirov@479: tikhomirov@479: public boolean begin(int mainfestRevision, Nodeid nid, int changelogRevision) { tikhomirov@479: clogRev = changelogRevision; tikhomirov@479: assertTrue(expected.containsKey(changelogRevision)); tikhomirov@479: expectedNodeid = expected.get(changelogRevision); tikhomirov@479: // we walk revisions of specific file, hence can't get into manifest without tikhomirov@479: // that file, expectedNodeid should have been reported by `hg manifest`: tikhomirov@479: assertTrue(!expectedNodeid.isNull()); tikhomirov@479: return true; tikhomirov@479: } tikhomirov@479: tikhomirov@479: public boolean next(Nodeid nid, Path fname, Flags flags) { tikhomirov@479: assertEquals(path, fname); // only selected path shall pass tikhomirov@479: assertEquals(expectedNodeid, nid); tikhomirov@479: expected.remove(clogRev); tikhomirov@479: return true; tikhomirov@479: } tikhomirov@479: tikhomirov@479: public boolean end(int manifestRevision) { tikhomirov@479: return true; tikhomirov@479: } tikhomirov@479: tikhomirov@479: }, revisions); tikhomirov@479: for (int r : revisions) { tikhomirov@479: if (expected.containsKey(r)) { tikhomirov@479: // Each manifest entry reported by `hg manifest` shall be tikhomirov@479: // reported (and removed) by walkFileRevisions(), too. Only null nodeids tikhomirov@479: // (revisions where the file was missing) are left tikhomirov@479: assertTrue(expected.get(r).isNull()); tikhomirov@479: } tikhomirov@479: } tikhomirov@479: } tikhomirov@479: tikhomirov@67: tikhomirov@67: private void testRevision(int rev) throws Exception { tikhomirov@67: manifestParser.reset(); tikhomirov@199: eh.run("hg", "manifest", "--debug", "--rev", String.valueOf(rev == TIP ? -1 : rev)); tikhomirov@67: revisions.clear(); tikhomirov@457: new HgManifestCommand(repo).changeset(rev).execute(handler); tikhomirov@67: report("manifest " + (rev == TIP ? "TIP:" : "--rev " + rev)); tikhomirov@67: } tikhomirov@67: tikhomirov@67: private void report(String what) throws Exception { tikhomirov@67: final Map cmdLineResult = new LinkedHashMap(manifestParser.getResult()); tikhomirov@249: for (HgFileRevision fr : revisions) { tikhomirov@67: Nodeid nid = cmdLineResult.remove(fr.getPath()); tikhomirov@103: errorCollector.checkThat("Extra " + fr.getPath() + " in Java result", nid, notNullValue()); tikhomirov@103: if (nid != null) { tikhomirov@103: errorCollector.checkThat("Non-matching nodeid:" + nid, nid, equalTo(fr.getRevision())); tikhomirov@67: } tikhomirov@67: } tikhomirov@103: errorCollector.checkThat("Non-matched entries from command line:", cmdLineResult, equalTo(Collections.emptyMap())); tikhomirov@67: } tikhomirov@67: }