Mercurial > hg4j
comparison test/org/tmatesoft/hg/test/TestBlame.java @ 677:1c49c0cee540
Report line number at the first appearance, like 'hg annotate -l' does
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 18 Jul 2013 18:47:45 +0200 |
parents | 3219cfadda49 |
children | 58a6900f845d |
comparison
equal
deleted
inserted
replaced
676:3219cfadda49 | 677:1c49c0cee540 |
---|---|
29 import java.io.PrintStream; | 29 import java.io.PrintStream; |
30 import java.util.ArrayList; | 30 import java.util.ArrayList; |
31 import java.util.Arrays; | 31 import java.util.Arrays; |
32 import java.util.LinkedHashSet; | 32 import java.util.LinkedHashSet; |
33 import java.util.LinkedList; | 33 import java.util.LinkedList; |
34 import java.util.List; | |
35 import java.util.ListIterator; | 34 import java.util.ListIterator; |
36 import java.util.regex.Matcher; | 35 import java.util.regex.Matcher; |
37 import java.util.regex.Pattern; | 36 import java.util.regex.Pattern; |
38 | 37 |
39 import org.junit.Assert; | 38 import org.junit.Assert; |
106 ar.run(cs, false); | 105 ar.run(cs, false); |
107 diffCmd.range(0, cs); | 106 diffCmd.range(0, cs); |
108 final ReverseAnnotateInspector insp = new ReverseAnnotateInspector(); | 107 final ReverseAnnotateInspector insp = new ReverseAnnotateInspector(); |
109 diffCmd.executeAnnotate(insp); | 108 diffCmd.executeAnnotate(insp); |
110 AnnotateInspector fa = new AnnotateInspector().fill(cs, insp); | 109 AnnotateInspector fa = new AnnotateInspector().fill(cs, insp); |
111 doAnnotateLineCheck(cs, ar.getLines(), fa.changesets, fa.lines); | 110 doAnnotateLineCheck(cs, ar, fa); |
112 } | 111 } |
113 } | 112 } |
114 | 113 |
115 @Test | 114 @Test |
116 public void testFileLineAnnotate2() throws Exception { | 115 public void testFileLineAnnotate2() throws Exception { |
123 ar.run(cs, false); | 122 ar.run(cs, false); |
124 diffCmd.range(0, cs); | 123 diffCmd.range(0, cs); |
125 final ReverseAnnotateInspector insp = new ReverseAnnotateInspector(); | 124 final ReverseAnnotateInspector insp = new ReverseAnnotateInspector(); |
126 diffCmd.executeAnnotate(insp); | 125 diffCmd.executeAnnotate(insp); |
127 AnnotateInspector fa = new AnnotateInspector().fill(cs, insp); | 126 AnnotateInspector fa = new AnnotateInspector().fill(cs, insp); |
128 doAnnotateLineCheck(cs, ar.getLines(), fa.changesets, fa.lines); | 127 doAnnotateLineCheck(cs, ar, fa); |
129 } | 128 } |
130 /*`hg annotate -r 8` and HgBlameFacility give different result | 129 /*`hg annotate -r 8` and HgBlameFacility give different result |
131 * for "r0, line 5" line, which was deleted in rev2 and restored back in | 130 * for "r0, line 5" line, which was deleted in rev2 and restored back in |
132 * rev4 (both in default branch), while branch with r3 and r6 kept the line intact. | 131 * rev4 (both in default branch), while branch with r3 and r6 kept the line intact. |
133 * HgBlame reports rev4 for the line, `hg annotate` gives original, rev0. | 132 * HgBlame reports rev4 for the line, `hg annotate` gives original, rev0. |
251 // follow | 250 // follow |
252 cmd.file(fname); | 251 cmd.file(fname); |
253 cmd.execute(ai); | 252 cmd.execute(ai); |
254 AnnotateRunner ar = new AnnotateRunner(fname, repo.getWorkingDir()); | 253 AnnotateRunner ar = new AnnotateRunner(fname, repo.getWorkingDir()); |
255 ar.run(changeset, true); | 254 ar.run(changeset, true); |
256 doAnnotateLineCheck(changeset, ar.getLines(), ai.changesets, ai.lines); | 255 doAnnotateLineCheck(changeset, ar, ai); |
257 | 256 |
258 // no follow | 257 // no follow |
259 cmd.file(fname, false); | 258 cmd.file(fname, false); |
260 ai = new AnnotateInspector(); | 259 ai = new AnnotateInspector(); |
261 cmd.execute(ai); | 260 cmd.execute(ai); |
262 ar.run(changeset, false); | 261 ar.run(changeset, false); |
263 doAnnotateLineCheck(changeset, ar.getLines(), ai.changesets, ai.lines); | 262 doAnnotateLineCheck(changeset, ar, ai); |
264 } | 263 } |
265 | 264 |
266 // FIXME add originLineNumber to HgAnnotateCommand#LineInfo, pass it from FileAnnotate, test | 265 private void doAnnotateLineCheck(int cs, AnnotateRunner ar, AnnotateInspector hg4jResult) { |
267 | 266 String[] hgAnnotateLines = ar.getLines(); |
268 private void doAnnotateLineCheck(int cs, String[] hgAnnotateLines, List<Integer> cmdChangesets, List<String> cmdLines) { | |
269 assertTrue("[sanity]", hgAnnotateLines.length > 0); | 267 assertTrue("[sanity]", hgAnnotateLines.length > 0); |
270 assertEquals("Number of lines reported by native annotate and our impl", hgAnnotateLines.length, cmdLines.size()); | 268 assertEquals("Number of lines reported by native annotate and our impl", hgAnnotateLines.length, hg4jResult.getLineCount()); |
271 | 269 |
272 for (int i = 0; i < cmdChangesets.size(); i++) { | 270 for (int i = 0; i < hgAnnotateLines.length; i++) { |
273 int hgAnnotateRevIndex = Integer.parseInt(hgAnnotateLines[i].substring(0, hgAnnotateLines[i].indexOf(':')).trim()); | 271 String[] hgLine = hgAnnotateLines[i].split(":"); |
274 errorCollector.assertEquals(String.format("Revision mismatch for line %d (annotating rev: %d)", i+1, cs), hgAnnotateRevIndex, cmdChangesets.get(i)); | 272 assertTrue(hgAnnotateLines[i], hgLine.length >= 3); |
275 String hgAnnotateLine = hgAnnotateLines[i].substring(hgAnnotateLines[i].indexOf(':') + 1); | 273 int hgAnnotateRevIndex = Integer.parseInt(hgLine[0].trim()); |
276 String apiLine = cmdLines.get(i).trim(); | 274 int hgFirstAppLine = Integer.parseInt(hgLine[1].trim()); |
277 errorCollector.assertEquals(hgAnnotateLine.trim(), apiLine); | 275 String hgLineText = hgAnnotateLines[i].substring(hgLine[0].length() + hgLine[1].length() + 2).trim(); |
276 errorCollector.assertEquals(String.format("Revision mismatch for line %d (annotating rev: %d)", i+1, cs), hgAnnotateRevIndex, hg4jResult.getChangeset(i)); | |
277 errorCollector.assertEquals(hgLineText, hg4jResult.getLine(i).trim()); | |
278 errorCollector.assertEquals(hgFirstAppLine, hg4jResult.getOriginLine(i)); | |
278 } | 279 } |
279 } | 280 } |
280 | 281 |
281 | 282 |
282 @Test | 283 @Test |
523 System.out.printf("%3d:%s:[%d..%d):\n%s", cset, marker, first, first+length, content); | 524 System.out.printf("%3d:%s:[%d..%d):\n%s", cset, marker, first, first+length, content); |
524 } | 525 } |
525 } | 526 } |
526 } | 527 } |
527 | 528 |
529 /** | |
530 * Note, this class expects lines coming in natural sequence (not the order they are detected - possible with {@link ReverseAnnotateInspector}) | |
531 * Once async lines are done, shall change implementation here | |
532 */ | |
528 static class AnnotateInspector implements HgAnnotateCommand.Inspector { | 533 static class AnnotateInspector implements HgAnnotateCommand.Inspector { |
529 private int lineNumber = 1; | 534 private int lineNumber = 1; |
530 public final ArrayList<String> lines = new ArrayList<String>(); | 535 private final ArrayList<String> lines = new ArrayList<String>(); |
531 public final ArrayList<Integer> changesets = new ArrayList<Integer>(); | 536 private final IntVector changesets = new IntVector(); |
537 private final IntVector firstAppLines = new IntVector(); | |
532 | 538 |
533 AnnotateInspector fill(int rev, ReverseAnnotateInspector ai) throws HgCallbackTargetException, CancelledException { | 539 AnnotateInspector fill(int rev, ReverseAnnotateInspector ai) throws HgCallbackTargetException, CancelledException { |
534 ai.report(rev, this, ProgressSupport.Factory.get(null), CancelSupport.Factory.get(null)); | 540 ai.report(rev, this, ProgressSupport.Factory.get(null), CancelSupport.Factory.get(null)); |
535 return this; | 541 return this; |
536 } | 542 } |
542 public void next(LineInfo lineInfo) throws HgCallbackTargetException { | 548 public void next(LineInfo lineInfo) throws HgCallbackTargetException { |
543 Assert.assertEquals(lineInfo.getLineNumber(), lineNumber); | 549 Assert.assertEquals(lineInfo.getLineNumber(), lineNumber); |
544 lineNumber++; | 550 lineNumber++; |
545 lines.add(new String(lineInfo.getContent())); | 551 lines.add(new String(lineInfo.getContent())); |
546 changesets.add(lineInfo.getChangesetIndex()); | 552 changesets.add(lineInfo.getChangesetIndex()); |
553 firstAppLines.add(lineInfo.getOriginLineNumber()); | |
554 } | |
555 | |
556 int getLineCount() { | |
557 return changesets.size(); | |
558 } | |
559 int getChangeset(int line) { | |
560 return changesets.get(line); | |
561 } | |
562 String getLine(int line) { | |
563 return lines.get(line); | |
564 } | |
565 int getOriginLine(int line) { | |
566 return firstAppLines.get(line); | |
547 } | 567 } |
548 } | 568 } |
549 | 569 |
550 private static class AnnotateRunner { | 570 private static class AnnotateRunner { |
551 private final ExecHelper eh; | 571 private final ExecHelper eh; |
561 public void run(int cset, boolean follow) throws Exception { | 581 public void run(int cset, boolean follow) throws Exception { |
562 op.reset(); | 582 op.reset(); |
563 ArrayList<String> args = new ArrayList<String>(); | 583 ArrayList<String> args = new ArrayList<String>(); |
564 args.add("hg"); | 584 args.add("hg"); |
565 args.add("annotate"); | 585 args.add("annotate"); |
586 args.add("--line-number"); | |
566 args.add("-r"); | 587 args.add("-r"); |
567 args.add(cset == TIP ? "tip" : String.valueOf(cset)); | 588 args.add(cset == TIP ? "tip" : String.valueOf(cset)); |
568 if (!follow) { | 589 if (!follow) { |
569 args.add("--no-follow"); | 590 args.add("--no-follow"); |
570 } | 591 } |