# HG changeset patch # User Artem Tikhomirov # Date 1342035988 -7200 # Node ID 2a0b09eec376207411e74285c28cfff402577521 # Parent 7bcfbc255f48e19b4a3de98682e2f5f0ca961628 Tests for issue 31 diff -r 7bcfbc255f48 -r 2a0b09eec376 cmdline/org/tmatesoft/hg/console/Main.java --- a/cmdline/org/tmatesoft/hg/console/Main.java Wed Jul 11 20:40:47 2012 +0200 +++ b/cmdline/org/tmatesoft/hg/console/Main.java Wed Jul 11 21:46:28 2012 +0200 @@ -108,14 +108,13 @@ // m.checkWalkFileRevisions(); // m.checkSubProgress(); // m.checkFileFlags(); - m.testMqManager(); -// m.testRevisionDescendants(); +// m.testMqManager(); // m.dumpPhases(); // m.buildFileLog(); // m.testConsoleLog(); // m.testTreeTraversal(); // m.testRevisionMap(); - m.testSubrepos(); +// m.testSubrepos(); // m.testReadWorkingCopy(); // m.testParents(); // m.testEffectiveFileLog(); @@ -159,25 +158,6 @@ } - // -R {junit-test-repos}/branches-1 - private void testRevisionDescendants() throws Exception { - int[] roots = new int[] {0, 1, 2, 3, 4, 5}; - RevisionDescendants[] result = new RevisionDescendants[roots.length]; - for (int i = 0; i < roots.length; i++) { - result[i] = new RevisionDescendants(hgRepo, roots[i]); - result[i].build(); - } - for (int i = 0; i < roots.length; i++) { - System.out.printf("For root %d descendats are:", roots[i]); - for (int j = roots[i], x = hgRepo.getChangelog().getLastRevision(); j <= x; j++) { - if (result[i].isDescendant(j)) { - System.out.printf("%3d ", j); - } - } - System.out.printf(", isEmpty:%b\n", !result[i].hasDescendants()); - } - } - // -R ${system_property:user.home}/hg/test-phases/ // TODO as junit test private void dumpPhases() throws Exception { diff -r 7bcfbc255f48 -r 2a0b09eec376 src/org/tmatesoft/hg/internal/RevisionDescendants.java --- a/src/org/tmatesoft/hg/internal/RevisionDescendants.java Wed Jul 11 20:40:47 2012 +0200 +++ b/src/org/tmatesoft/hg/internal/RevisionDescendants.java Wed Jul 11 21:46:28 2012 +0200 @@ -95,6 +95,13 @@ return descendants.nextSetBit(rootRevIndex+1) != -1; } + /** + * Tells whether specified revision is on a descent line from the root revision. + *

NOTE, root revision itself is considered to be its own descendant. + * + * @param revisionIndex revision index to check, shall pass {@link #isCandidate(int)} + * @return true if revision is descendant of or is the same as root revision + */ public boolean isDescendant(int revisionIndex) { assert isCandidate(revisionIndex); int ix = revisionIndex - rootRevIndex; diff -r 7bcfbc255f48 -r 2a0b09eec376 test/org/tmatesoft/hg/test/TestAuxUtilities.java --- a/test/org/tmatesoft/hg/test/TestAuxUtilities.java Wed Jul 11 20:40:47 2012 +0200 +++ b/test/org/tmatesoft/hg/test/TestAuxUtilities.java Wed Jul 11 21:46:28 2012 +0200 @@ -16,6 +16,8 @@ */ package org.tmatesoft.hg.test; +import static java.lang.Integer.toBinaryString; +import static org.junit.Assert.*; import static org.tmatesoft.hg.repo.HgRepository.TIP; import static org.tmatesoft.hg.util.Path.CompareResult.*; @@ -30,6 +32,7 @@ import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.internal.ArrayHelper; import org.tmatesoft.hg.internal.PathScope; +import org.tmatesoft.hg.internal.RevisionDescendants; import org.tmatesoft.hg.repo.HgChangelog; import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; import org.tmatesoft.hg.repo.HgDataFile; @@ -63,14 +66,14 @@ String[] result = initial.clone(); ah.sort(result); String[] restored = restore(result, ah.getReverse()); - Assert.assertArrayEquals(initial, restored); + assertArrayEquals(initial, restored); // // few elements are on the right place from the very start and do not shift during sort. // make sure for them we've got correct reversed indexes as well initial = new String[] {"d", "h", "c", "b", "k", "i", "a", "r", "e", "w" }; ah.sort(result = initial.clone()); restored = restore(result, ah.getReverse()); - Assert.assertArrayEquals(initial, restored); + assertArrayEquals(initial, restored); } private static String[] restore(String[] sorted, int[] sortReverse) { @@ -236,9 +239,9 @@ int i = 0; public void next(int localRevision, Nodeid revision, int linkedRevision) { - Assert.assertEquals(i++, localRevision); - Assert.assertEquals(fileNode.getChangesetRevisionIndex(localRevision), linkedRevision); - Assert.assertEquals(fileNode.getRevision(localRevision), revision); + assertEquals(i++, localRevision); + assertEquals(fileNode.getChangesetRevisionIndex(localRevision), linkedRevision); + assertEquals(fileNode.getRevision(localRevision), revision); } }); class ParentInspectorCheck implements HgDataFile.ParentInspector { @@ -254,11 +257,11 @@ } public void next(int localRevision, Nodeid revision, int parent1, int parent2, Nodeid nidParent1, Nodeid nidParent2) { - Assert.assertEquals(i++, localRevision); + assertEquals(i++, localRevision); all[c++] = revision; - Assert.assertNotNull(revision); - Assert.assertFalse(localRevision == 0 && (parent1 != -1 || parent2 != -1)); - Assert.assertFalse(localRevision > 0 && parent1 == -1 && parent2 == -1); + assertNotNull(revision); + assertFalse(localRevision == 0 && (parent1 != -1 || parent2 != -1)); + assertFalse(localRevision > 0 && parent1 == -1 && parent2 == -1); if (parent1 != -1) { Assert.assertNotNull(nidParent1); if (parent1 >= start) { @@ -280,6 +283,61 @@ fileNode.indexWalk(1, 3, new ParentInspectorCheck(1, 3)); } + /* + * This test checks not only RevisionDescendants class, but also + * Revlog.indexWalk implementation defect, aka: + * Issue 31: Revlog#walk doesn't handle ParentInspector correctly with start revision other than 0, fails with AIOOBE + */ + @Test + public void testRevisionDescendants() throws Exception { + HgRepository hgRepo = Configuration.get().find("branches-1"); + int[] roots = new int[] {0, 1, 2, 3, 4, 5}; + // 0: all revisions are descendants, 17 total. + // 1: 2, 4, 7, 8, 9 + // 2: 7, 8, 9 + // 3: 5,6, 10-16 + // 4: no children + // 5: 6, 10-16 + // array values represent bit mask, '1' for revision that shall re reported as descendant + // least significant bit is revision 0, and so on, so that 1<