Mercurial > hg4j
comparison test/org/tmatesoft/hg/test/TestBlame.java @ 676:3219cfadda49
Switch to alternative annotate producer (walks from parents to children). Refactor FileAnnotation to match updated annotate approach
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 18 Jul 2013 18:03:51 +0200 |
parents | 54e16ab771ec |
children | 1c49c0cee540 |
comparison
equal
deleted
inserted
replaced
675:a20121a2bba6 | 676:3219cfadda49 |
---|---|
18 | 18 |
19 import static org.junit.Assert.assertEquals; | 19 import static org.junit.Assert.assertEquals; |
20 import static org.junit.Assert.assertTrue; | 20 import static org.junit.Assert.assertTrue; |
21 import static org.tmatesoft.hg.core.HgIterateDirection.NewToOld; | 21 import static org.tmatesoft.hg.core.HgIterateDirection.NewToOld; |
22 import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew; | 22 import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew; |
23 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; | |
24 import static org.tmatesoft.hg.repo.HgRepository.TIP; | 23 import static org.tmatesoft.hg.repo.HgRepository.TIP; |
25 | 24 |
26 import java.io.ByteArrayOutputStream; | 25 import java.io.ByteArrayOutputStream; |
27 import java.io.File; | 26 import java.io.File; |
28 import java.io.IOException; | 27 import java.io.IOException; |
45 import org.tmatesoft.hg.core.HgBlameInspector; | 44 import org.tmatesoft.hg.core.HgBlameInspector; |
46 import org.tmatesoft.hg.core.HgCallbackTargetException; | 45 import org.tmatesoft.hg.core.HgCallbackTargetException; |
47 import org.tmatesoft.hg.core.HgDiffCommand; | 46 import org.tmatesoft.hg.core.HgDiffCommand; |
48 import org.tmatesoft.hg.core.HgRepoFacade; | 47 import org.tmatesoft.hg.core.HgRepoFacade; |
49 import org.tmatesoft.hg.core.Nodeid; | 48 import org.tmatesoft.hg.core.Nodeid; |
50 import org.tmatesoft.hg.internal.FileAnnotation; | 49 import org.tmatesoft.hg.internal.ForwardAnnotateInspector; |
51 import org.tmatesoft.hg.internal.FileAnnotation.LineDescriptor; | |
52 import org.tmatesoft.hg.internal.FileAnnotation.LineInspector; | |
53 import org.tmatesoft.hg.internal.IntVector; | 50 import org.tmatesoft.hg.internal.IntVector; |
51 import org.tmatesoft.hg.internal.ReverseAnnotateInspector; | |
54 import org.tmatesoft.hg.repo.HgChangelog; | 52 import org.tmatesoft.hg.repo.HgChangelog; |
55 import org.tmatesoft.hg.repo.HgDataFile; | 53 import org.tmatesoft.hg.repo.HgDataFile; |
56 import org.tmatesoft.hg.repo.HgLookup; | 54 import org.tmatesoft.hg.repo.HgLookup; |
57 import org.tmatesoft.hg.repo.HgRepository; | 55 import org.tmatesoft.hg.repo.HgRepository; |
56 import org.tmatesoft.hg.util.CancelSupport; | |
57 import org.tmatesoft.hg.util.CancelledException; | |
58 import org.tmatesoft.hg.util.Path; | 58 import org.tmatesoft.hg.util.Path; |
59 import org.tmatesoft.hg.util.ProgressSupport; | |
59 | 60 |
60 /** | 61 /** |
61 * | 62 * |
62 * @author Artem Tikhomirov | 63 * @author Artem Tikhomirov |
63 * @author TMate Software Ltd. | 64 * @author TMate Software Ltd. |
101 clog.getRevisionIndex(Nodeid.fromAscii("946b131962521f9199e1fedbdc2487d3aaef5e46")), // 539 | 102 clog.getRevisionIndex(Nodeid.fromAscii("946b131962521f9199e1fedbdc2487d3aaef5e46")), // 539 |
102 clog.getRevisionIndex(Nodeid.fromAscii("1e95f48d9886abe79b9711ab371bc877ca5e773e")), // 541 | 103 clog.getRevisionIndex(Nodeid.fromAscii("1e95f48d9886abe79b9711ab371bc877ca5e773e")), // 541 |
103 /*, TIP */}; | 104 /*, TIP */}; |
104 for (int cs : toTest) { | 105 for (int cs : toTest) { |
105 ar.run(cs, false); | 106 ar.run(cs, false); |
106 FileAnnotateInspector fa = new FileAnnotateInspector(); | |
107 diffCmd.range(0, cs); | 107 diffCmd.range(0, cs); |
108 diffCmd.executeAnnotate(new FileAnnotation(fa)); | 108 final ReverseAnnotateInspector insp = new ReverseAnnotateInspector(); |
109 doAnnotateLineCheck(cs, ar.getLines(), Arrays.asList(fa.lineRevisions), Arrays.asList(fa.lines)); | 109 diffCmd.executeAnnotate(insp); |
110 AnnotateInspector fa = new AnnotateInspector().fill(cs, insp); | |
111 doAnnotateLineCheck(cs, ar.getLines(), fa.changesets, fa.lines); | |
110 } | 112 } |
111 } | 113 } |
112 | 114 |
113 @Test | 115 @Test |
114 public void testFileLineAnnotate2() throws Exception { | 116 public void testFileLineAnnotate2() throws Exception { |
117 AnnotateRunner ar = new AnnotateRunner(df.getPath(), repo.getWorkingDir()); | 119 AnnotateRunner ar = new AnnotateRunner(df.getPath(), repo.getWorkingDir()); |
118 | 120 |
119 final HgDiffCommand diffCmd = new HgDiffCommand(repo).file(df).order(NewToOld); | 121 final HgDiffCommand diffCmd = new HgDiffCommand(repo).file(df).order(NewToOld); |
120 for (int cs : new int[] { 4, 6 /*, 8 see below*/, TIP}) { | 122 for (int cs : new int[] { 4, 6 /*, 8 see below*/, TIP}) { |
121 ar.run(cs, false); | 123 ar.run(cs, false); |
122 FileAnnotateInspector fa = new FileAnnotateInspector(); | |
123 diffCmd.range(0, cs); | 124 diffCmd.range(0, cs); |
124 diffCmd.executeAnnotate(new FileAnnotation(fa)); | 125 final ReverseAnnotateInspector insp = new ReverseAnnotateInspector(); |
125 doAnnotateLineCheck(cs, ar.getLines(), Arrays.asList(fa.lineRevisions), Arrays.asList(fa.lines)); | 126 diffCmd.executeAnnotate(insp); |
127 AnnotateInspector fa = new AnnotateInspector().fill(cs, insp); | |
128 doAnnotateLineCheck(cs, ar.getLines(), fa.changesets, fa.lines); | |
126 } | 129 } |
127 /*`hg annotate -r 8` and HgBlameFacility give different result | 130 /*`hg annotate -r 8` and HgBlameFacility give different result |
128 * for "r0, line 5" line, which was deleted in rev2 and restored back in | 131 * for "r0, line 5" line, which was deleted in rev2 and restored back in |
129 * rev4 (both in default branch), while branch with r3 and r6 kept the line intact. | 132 * rev4 (both in default branch), while branch with r3 and r6 kept the line intact. |
130 * HgBlame reports rev4 for the line, `hg annotate` gives original, rev0. | 133 * HgBlame reports rev4 for the line, `hg annotate` gives original, rev0. |
131 * However `hg annotate -r 4` shows rev4 for the line, too. The aforementioned rev0 for | 134 * However `hg annotate -r 4` shows rev4 for the line, too. The aforementioned rev0 for |
132 * the merge rev8 results from the iteration order and is implementation specific | 135 * the merge rev8 results from the iteration order and is implementation specific |
133 * (i.e. one can't tell which one is right). Mercurial walks from parents to children, | 136 * (i.e. one can't tell which one is right). Mercurial walks from parents to children, |
134 * and traces equal lines, wile HgBlameFacility walks from child to parents and records | 137 * and traces equal lines, while HgBlameFacility walks from child to parents and records |
135 * changes (additions). Seems it processes branch with rev3 and rev6 first | 138 * changes (additions). Seems it processes branch with rev3 and rev6 first |
136 * (printout in context.py, annotate and annotate.pair reveals that), and the line 0_5 | 139 * (printout in context.py, annotate and annotate.pair reveals that), and the line 0_5 |
137 * comes as unchanged through this branch, and later processing rev2 and rev4 doesn't | 140 * comes as unchanged through this branch, and later processing rev2 and rev4 doesn't |
138 * change that. | 141 * change that. |
139 */ | 142 */ |
257 ai = new AnnotateInspector(); | 260 ai = new AnnotateInspector(); |
258 cmd.execute(ai); | 261 cmd.execute(ai); |
259 ar.run(changeset, false); | 262 ar.run(changeset, false); |
260 doAnnotateLineCheck(changeset, ar.getLines(), ai.changesets, ai.lines); | 263 doAnnotateLineCheck(changeset, ar.getLines(), ai.changesets, ai.lines); |
261 } | 264 } |
265 | |
266 // FIXME add originLineNumber to HgAnnotateCommand#LineInfo, pass it from FileAnnotate, test | |
262 | 267 |
263 private void doAnnotateLineCheck(int cs, String[] hgAnnotateLines, List<Integer> cmdChangesets, List<String> cmdLines) { | 268 private void doAnnotateLineCheck(int cs, String[] hgAnnotateLines, List<Integer> cmdChangesets, List<String> cmdLines) { |
264 assertTrue("[sanity]", hgAnnotateLines.length > 0); | 269 assertTrue("[sanity]", hgAnnotateLines.length > 0); |
265 assertEquals("Number of lines reported by native annotate and our impl", hgAnnotateLines.length, cmdLines.size()); | 270 assertEquals("Number of lines reported by native annotate and our impl", hgAnnotateLines.length, cmdLines.size()); |
266 | 271 |
365 for (int cs : new int[] { 24, 46, 49, 52, 59, 62, 64, TIP}) { | 370 for (int cs : new int[] { 24, 46, 49, 52, 59, 62, 64, TIP}) { |
366 doLineAnnotateTest(df, cs, op); | 371 doLineAnnotateTest(df, cs, op); |
367 } | 372 } |
368 errorCollector.verify(); | 373 errorCollector.verify(); |
369 */ | 374 */ |
370 FileAnnotateInspector fa = new FileAnnotateInspector(); | 375 ForwardAnnotateInspector insp = new ForwardAnnotateInspector(); |
371 diffCmd.range(0, 8).order(NewToOld); | 376 diffCmd.range(0, 8).order(insp.iterateDirection()); |
372 diffCmd.executeAnnotate(new FileAnnotation(fa)); | 377 diffCmd.executeAnnotate(insp); |
373 for (int i = 0; i < fa.lineRevisions.length; i++) { | 378 AnnotateInspector fa = new AnnotateInspector().fill(8, insp); |
374 System.out.printf("%d: %s", fa.lineRevisions[i], fa.line(i) == null ? "null\n" : fa.line(i)); | 379 for (int i = 0; i < fa.changesets.size(); i++) { |
380 final String line = fa.lines.get(i); | |
381 System.out.printf("%d: %s", fa.changesets.get(i), line == null ? "null\n" : line); | |
375 } | 382 } |
376 } | 383 } |
377 | 384 |
378 public static void main(String[] args) throws Throwable { | 385 public static void main(String[] args) throws Throwable { |
379 TestBlame tt = new TestBlame(); | 386 TestBlame tt = new TestBlame(); |
474 lineStart = ++lineEnd; | 481 lineStart = ++lineEnd; |
475 } while (lineStart < seq.length()); | 482 } while (lineStart < seq.length()); |
476 } | 483 } |
477 } | 484 } |
478 | 485 |
479 private static class FileAnnotateInspector implements LineInspector { | |
480 private Integer[] lineRevisions; | |
481 private String[] lines; | |
482 | |
483 FileAnnotateInspector() { | |
484 } | |
485 | |
486 public void line(int lineNumber, int changesetRevIndex, HgBlameInspector.BlockData lineContent, LineDescriptor ld) { | |
487 if (lineRevisions == null) { | |
488 lineRevisions = new Integer[ld.totalLines()]; | |
489 Arrays.fill(lineRevisions, NO_REVISION); | |
490 lines = new String[ld.totalLines()]; | |
491 } | |
492 lineRevisions[lineNumber] = changesetRevIndex; | |
493 lines[lineNumber] = new String(lineContent.asArray()); | |
494 } | |
495 | |
496 public String line(int i) { | |
497 return lines[i]; | |
498 } | |
499 } | |
500 | |
501 @SuppressWarnings("unused") | 486 @SuppressWarnings("unused") |
502 private static class LineDumpInspector implements HgBlameInspector { | 487 private static class LineDumpInspector implements HgBlameInspector { |
503 | 488 |
504 private final boolean lineByLine; | 489 private final boolean lineByLine; |
505 | 490 |
542 | 527 |
543 static class AnnotateInspector implements HgAnnotateCommand.Inspector { | 528 static class AnnotateInspector implements HgAnnotateCommand.Inspector { |
544 private int lineNumber = 1; | 529 private int lineNumber = 1; |
545 public final ArrayList<String> lines = new ArrayList<String>(); | 530 public final ArrayList<String> lines = new ArrayList<String>(); |
546 public final ArrayList<Integer> changesets = new ArrayList<Integer>(); | 531 public final ArrayList<Integer> changesets = new ArrayList<Integer>(); |
547 | 532 |
533 AnnotateInspector fill(int rev, ReverseAnnotateInspector ai) throws HgCallbackTargetException, CancelledException { | |
534 ai.report(rev, this, ProgressSupport.Factory.get(null), CancelSupport.Factory.get(null)); | |
535 return this; | |
536 } | |
537 AnnotateInspector fill(int rev, ForwardAnnotateInspector ai) throws HgCallbackTargetException, CancelledException { | |
538 ai.report(rev, this, ProgressSupport.Factory.get(null), CancelSupport.Factory.get(null)); | |
539 return this; | |
540 } | |
541 | |
548 public void next(LineInfo lineInfo) throws HgCallbackTargetException { | 542 public void next(LineInfo lineInfo) throws HgCallbackTargetException { |
549 Assert.assertEquals(lineInfo.getLineNumber(), lineNumber); | 543 Assert.assertEquals(lineInfo.getLineNumber(), lineNumber); |
550 lineNumber++; | 544 lineNumber++; |
551 lines.add(new String(lineInfo.getContent())); | 545 lines.add(new String(lineInfo.getContent())); |
552 changesets.add(lineInfo.getChangesetIndex()); | 546 changesets.add(lineInfo.getChangesetIndex()); |