Mercurial > hg4j
diff test/org/tmatesoft/hg/test/TestBlame.java @ 546:cd78e8b9d7bc
File annotate test. Refactored FileAnnotation as standalone class, introduced LineInspector to make line offset calc code shared
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 18 Feb 2013 19:19:48 +0100 |
parents | 15b406c7cd9d |
children | ab21ac7dd833 |
line wrap: on
line diff
--- a/test/org/tmatesoft/hg/test/TestBlame.java Fri Feb 15 22:15:13 2013 +0100 +++ b/test/org/tmatesoft/hg/test/TestBlame.java Mon Feb 18 19:19:48 2013 +0100 @@ -16,12 +16,13 @@ */ package org.tmatesoft.hg.test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.Arrays; -import java.util.LinkedList; import java.util.regex.Pattern; import org.junit.Assert; @@ -31,8 +32,8 @@ import org.tmatesoft.hg.internal.AnnotateFacility.ChangeBlock; import org.tmatesoft.hg.internal.AnnotateFacility.DeleteBlock; import org.tmatesoft.hg.internal.AnnotateFacility.EqualBlock; +import org.tmatesoft.hg.internal.AnnotateFacility.LineDescriptor; import org.tmatesoft.hg.internal.IntMap; -import org.tmatesoft.hg.internal.IntVector; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgLookup; import org.tmatesoft.hg.repo.HgRepository; @@ -66,22 +67,25 @@ public void testFileAnnotate() throws Exception { HgRepository repo = new HgLookup().detectFromWorkingDir(); final String fname = "src/org/tmatesoft/hg/internal/PatchGenerator.java"; - final int checkChangeset = 539; + final int[] checkChangesets = new int[] { 539 , 536, 531 }; HgDataFile df = repo.getFileNode(fname); AnnotateFacility af = new AnnotateFacility(); - System.out.println("536 -> 539"); - af.annotateChange(df, checkChangeset, new DiffOutInspector(System.out)); - System.out.println("531 -> 536"); - af.annotateChange(df, 536, new DiffOutInspector(System.out)); - System.out.println(" -1 -> 531"); - af.annotateChange(df, 531, new DiffOutInspector(System.out)); + FileAnnotateInspector fa = new FileAnnotateInspector(); + for (int cs : checkChangesets) { + af.annotateChange(df, cs, new FileAnnotation(fa)); + } - FileAnnotation fa = new FileAnnotation(); - af.annotateChange(df, checkChangeset, fa); - af.annotateChange(df, 536, fa); - af.annotateChange(df, 531, fa); + OutputParser.Stub op = new OutputParser.Stub(); + ExecHelper eh = new ExecHelper(op, null); + eh.run("hg", "annotate", "-r", String.valueOf(checkChangesets[0]), fname); + + String[] hgAnnotateLines = splitLines(op.result()); + assertTrue("[sanity]", hgAnnotateLines.length > 0); + assertEquals("Number of lines reported by native annotate and our impl", hgAnnotateLines.length, fa.lineRevisions.length); + for (int i = 0; i < fa.lineRevisions.length; i++) { - System.out.printf("%3d: %d\n", fa.lineRevisions[i], i+1); + int hgAnnotateRevIndex = Integer.parseInt(hgAnnotateLines[i].substring(0, hgAnnotateLines[i].indexOf(':'))); + assertEquals(String.format("Revision mismatch for line %d", i+1), hgAnnotateRevIndex, fa.lineRevisions[i]); } } @@ -110,7 +114,19 @@ return rv; } - private void leftovers() { + private void leftovers() throws Exception { + HgRepository repo = new HgLookup().detectFromWorkingDir(); + final String fname = "src/org/tmatesoft/hg/internal/PatchGenerator.java"; + final int checkChangeset = 539; + HgDataFile df = repo.getFileNode(fname); + AnnotateFacility af = new AnnotateFacility(); + System.out.println("536 -> 539"); + af.annotateChange(df, checkChangeset, new DiffOutInspector(System.out)); + System.out.println("531 -> 536"); + af.annotateChange(df, 536, new DiffOutInspector(System.out)); + System.out.println(" -1 -> 531"); + af.annotateChange(df, 531, new DiffOutInspector(System.out)); + IntMap<String> linesOld = new IntMap<String>(100), linesNew = new IntMap<String>(100); System.out.println("Changes to old revision:"); for (int i = linesOld.firstKey(), x = linesOld.lastKey(); i < x; i++) { @@ -135,7 +151,7 @@ new TestBlame().testFileAnnotate(); } - static class DiffOutInspector implements AnnotateFacility.Inspector { + static class DiffOutInspector implements AnnotateFacility.BlockInspector { private final PrintStream out; DiffOutInspector(PrintStream ps) { @@ -201,154 +217,19 @@ } } - private static class FileAnnotation implements AnnotateFacility.InspectorEx { + private static class FileAnnotateInspector implements AnnotateFacility.LineInspector { private int[] lineRevisions; - private LinkedList<DeleteBlock> deleted = new LinkedList<DeleteBlock>(); - private LinkedList<DeleteBlock> newDeleted = new LinkedList<DeleteBlock>(); - // keeps <startSeq1, startSeq2, len> of equal blocks - // XXX smth like IntSliceVector to access triples (or slices of any size, in fact) - // with easy indexing, e.g. #get(sliceIndex, indexWithinSlice) - // and vect.get(7,2) instead of vect.get(7*SIZEOF_SLICE+2) - private IntVector identical = new IntVector(20*3, 2*3); - private IntVector newIdentical = new IntVector(20*3, 2*3); - public FileAnnotation() { + FileAnnotateInspector() { } - public void start(int originLineCount, int targetLineCount) { + public void line(int lineNumber, int changesetRevIndex, LineDescriptor ld) { if (lineRevisions == null) { - lineRevisions = new int [targetLineCount]; + lineRevisions = new int [ld.totalLines()]; Arrays.fill(lineRevisions, NO_REVISION); } - } - -// private static void ppp(IntVector v) { -// for (int i = 0; i < v.size(); i+= 3) { -// int len = v.get(i+2); -// System.out.printf("[%d..%d) == [%d..%d); ", v.get(i), v.get(i) + len, v.get(i+1), v.get(i+1) + len); -// } -// System.out.println(); -// } - - public void done() { - if (identical.size() > 0) { - // update line numbers of the intermediate target to point to ultimate target's line numbers - IntVector v = new IntVector(identical.size(), 2*3); - for (int i = 0; i < newIdentical.size(); i+= 3) { - int originLine = newIdentical.get(i); - int targetLine = newIdentical.get(i+1); - int length = newIdentical.get(i+2); - int startTargetLine = -1, startOriginLine = -1, c = 0; - for (int j = 0; j < length; j++) { - int lnInFinal = mapLineIndex(targetLine + j); - if (lnInFinal == -1 || (startTargetLine != -1 && lnInFinal != startTargetLine + c)) { - // the line is not among "same" in ultimate origin - // or belongs to another/next "same" chunk - if (startOriginLine == -1) { - continue; - } - v.add(startOriginLine); - v.add(startTargetLine); - v.add(c); - c = 0; - startOriginLine = startTargetLine = -1; - // fall-through to check if it's not complete miss but a next chunk - } - if (lnInFinal != -1) { - if (startOriginLine == -1) { - startOriginLine = originLine + j; - startTargetLine = lnInFinal; - c = 1; - } else { - assert lnInFinal == startTargetLine + c; - c++; - } - } - } - if (startOriginLine != -1) { - assert c > 0; - v.add(startOriginLine); - v.add(startTargetLine); - v.add(c); - } - } - newIdentical.clear(); - identical = v; - } else { - IntVector li = newIdentical; - newIdentical = identical; - identical = li; - } - LinkedList<DeleteBlock> ld = newDeleted; - deleted.clear(); - newDeleted = deleted; - deleted = ld; - } - - public void same(EqualBlock block) { - newIdentical.add(block.originStart()); - newIdentical.add(block.targetStart()); - newIdentical.add(block.length()); - } - - public void added(AddBlock block) { - for (int i = 0, ln = block.firstAddedLine(), x = block.totalAddedLines(); i < x; i++, ln++) { - int lnInFinal = mapLineIndex(ln); - if (lnInFinal != -1 && historyUnknown(lnInFinal)) { - lineRevisions[lnInFinal] = block.targetChangesetIndex(); - } - } - } - - public void changed(ChangeBlock block) { - deleted(block); - added(block); - } - - public void deleted(DeleteBlock block) { - newDeleted.add(block); - } - - private boolean historyUnknown(int lineNumber) { - return lineRevisions[lineNumber] == NO_REVISION; - } - - private boolean isDeleted(int line) { - for (DeleteBlock b : deleted) { - if (b.firstRemovedLine() > line) { - break; - } - // line >= b.firstRemovedLine - if (b.firstRemovedLine() + b.totalRemovedLines() > line) { - return true; - } - } - return false; - } - - // map target lines to the lines of the revision being annotated (the one that came first) - private int mapLineIndex(int ln) { - if (isDeleted(ln)) { - return -1; - } - if (identical.isEmpty()) { - return ln; - } - for (int i = 0; i < identical.size(); i += 3) { - final int originStart = identical.get(i); - if (originStart > ln) { - assert false; - return -1; - } - // ln >= b.originStart - final int length = identical.get(i+2); - if (originStart + length > ln) { - int targetStart = identical.get(i+1); - return targetStart + (ln - originStart); - } - } - assert false; - return -1; + lineRevisions[lineNumber] = changesetRevIndex; } } + }