comparison test/org/tmatesoft/hg/test/TestBlame.java @ 543:1e95f48d9886

Report line index for insertion and deletion, test against 'hg diff' output
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 15 Feb 2013 15:52:03 +0100
parents a71a05ec11bc
children 7f5998a9619d
comparison
equal deleted inserted replaced
542:a71a05ec11bc 543:1e95f48d9886
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.test; 17 package org.tmatesoft.hg.test;
18 18
19 import java.io.ByteArrayOutputStream;
20 import java.io.PrintStream;
21 import java.util.Arrays;
22 import java.util.regex.Pattern;
23
24 import org.junit.Assert;
19 import org.junit.Test; 25 import org.junit.Test;
20 import org.tmatesoft.hg.internal.AnnotateFacility; 26 import org.tmatesoft.hg.internal.AnnotateFacility;
21 import org.tmatesoft.hg.internal.AnnotateFacility.AddBlock; 27 import org.tmatesoft.hg.internal.AnnotateFacility.AddBlock;
28 import org.tmatesoft.hg.internal.AnnotateFacility.Block;
22 import org.tmatesoft.hg.internal.AnnotateFacility.ChangeBlock; 29 import org.tmatesoft.hg.internal.AnnotateFacility.ChangeBlock;
23 import org.tmatesoft.hg.internal.AnnotateFacility.DeleteBlock; 30 import org.tmatesoft.hg.internal.AnnotateFacility.DeleteBlock;
24 import org.tmatesoft.hg.internal.IntMap; 31 import org.tmatesoft.hg.internal.IntMap;
25 import org.tmatesoft.hg.internal.AnnotateFacility.Block;
26 import org.tmatesoft.hg.repo.HgDataFile; 32 import org.tmatesoft.hg.repo.HgDataFile;
27 import org.tmatesoft.hg.repo.HgLookup; 33 import org.tmatesoft.hg.repo.HgLookup;
28 import org.tmatesoft.hg.repo.HgRepository; 34 import org.tmatesoft.hg.repo.HgRepository;
29 35
30 /** 36 /**
36 42
37 43
38 @Test 44 @Test
39 public void testSingleParentBlame() throws Exception { 45 public void testSingleParentBlame() throws Exception {
40 HgRepository repo = new HgLookup().detectFromWorkingDir(); 46 HgRepository repo = new HgLookup().detectFromWorkingDir();
41 HgDataFile df = repo.getFileNode("src/org/tmatesoft/hg/internal/PatchGenerator.java"); 47 final String fname = "src/org/tmatesoft/hg/internal/PatchGenerator.java";
42 final IntMap<String> linesOld= new IntMap<String>(100); 48 final int checkChangeset = 539;
43 final IntMap<String> linesNew = new IntMap<String>(100); 49 HgDataFile df = repo.getFileNode(fname);
44 new AnnotateFacility().annotate(df, 539, new AnnotateFacility.Inspector() { 50 ByteArrayOutputStream bos = new ByteArrayOutputStream();
45 51 new AnnotateFacility().annotate(df, checkChangeset, new DiffOutInspector(new PrintStream(bos)));
46 public void same(Block block) { 52 LineGrepOutputParser gp = new LineGrepOutputParser("^@@.+");
47 // TODO Auto-generated method stub 53 ExecHelper eh = new ExecHelper(gp, null);
48 54 eh.run("hg", "diff", "-c", String.valueOf(checkChangeset), "-U", "0", fname);
55 //
56 String[] apiResult = splitLines(bos.toString());
57 String[] expected = splitLines(gp.result());
58 Assert.assertArrayEquals(expected, apiResult);
59 }
60
61 private static String[] splitLines(CharSequence seq) {
62 int lineCount = 0;
63 for (int i = 0, x = seq.length(); i < x; i++) {
64 if (seq.charAt(i) == '\n') {
65 lineCount++;
49 } 66 }
50 67 }
51 public void deleted(DeleteBlock block) { 68 if (seq.length() > 0 && seq.charAt(seq.length()-1) != '\n') {
52 String[] lines = block.removedLines(); 69 lineCount++;
53 assert lines.length == block.totalRemovedLines(); 70 }
54 for (int i = 0, ln = block.firstRemovedLine(); i < lines.length; i++, ln++) { 71 String[] rv = new String[lineCount];
55 linesOld.put(ln, String.format("%3d:---:%s", ln, lines[i])); 72 int lineStart = 0, lineEnd = 0, ix = 0;
56 } 73 do {
74 while (lineEnd < seq.length() && seq.charAt(lineEnd) != '\n') lineEnd++;
75 if (lineEnd == lineStart) {
76 continue;
57 } 77 }
58 78 CharSequence line = seq.subSequence(lineStart, lineEnd);
59 public void changed(ChangeBlock block) { 79 rv[ix++] = line.toString();
60 deleted(block); 80 lineStart = ++lineEnd;
61 added(block); 81 } while (lineStart < seq.length());
62 } 82 assert ix == lineCount;
63 83 return rv;
64 public void added(AddBlock block) { 84 }
65 String[] addedLines = block.addedLines(); 85
66 assert addedLines.length == block.totalAddedLines(); 86 private void leftovers() {
67 for (int i = 0, ln = block.firstAddedLine(), x = addedLines.length; i < x; i++, ln++) { 87 IntMap<String> linesOld = new IntMap<String>(100), linesNew = new IntMap<String>(100);
68 linesNew.put(ln, String.format("%3d:+++:%s", ln, addedLines[i]));
69 }
70 }
71 });
72
73 System.out.println("Changes to old revision:"); 88 System.out.println("Changes to old revision:");
74 for (int i = linesOld.firstKey(), x = linesOld.lastKey(); i < x; i++) { 89 for (int i = linesOld.firstKey(), x = linesOld.lastKey(); i < x; i++) {
75 if (linesOld.containsKey(i)) { 90 if (linesOld.containsKey(i)) {
76 System.out.println(linesOld.get(i)); 91 System.out.println(linesOld.get(i));
77 } 92 }
84 } 99 }
85 } 100 }
86 } 101 }
87 102
88 public static void main(String[] args) throws Exception { 103 public static void main(String[] args) throws Exception {
104 System.out.println(Arrays.equals(new String[0], splitLines("")));
105 System.out.println(Arrays.equals(new String[] { "abc" }, splitLines("abc")));
89 new TestBlame().testSingleParentBlame(); 106 new TestBlame().testSingleParentBlame();
90 } 107 }
108
109 static class DiffOutInspector implements AnnotateFacility.Inspector {
110 private final PrintStream out;
111
112 DiffOutInspector(PrintStream ps) {
113 out = ps;
114 }
115
116 public void same(Block block) {
117 // nothing
118 }
119
120 public void deleted(DeleteBlock block) {
121 out.printf("@@ -%d,%d +%d,0 @@\n", block.firstRemovedLine() + 1, block.totalRemovedLines(), block.removedAt());
122 // String[] lines = block.removedLines();
123 // assert lines.length == block.totalRemovedLines();
124 // for (int i = 0, ln = block.firstRemovedLine(); i < lines.length; i++, ln++) {
125 // linesOld.put(ln, String.format("%3d:---:%s", ln, lines[i]));
126 // }
127 }
128
129 public void changed(ChangeBlock block) {
130 // deleted(block);
131 // added(block);
132 out.printf("@@ -%d,%d +%d,%d @@\n", block.firstRemovedLine() + 1, block.totalRemovedLines(), block.firstAddedLine() + 1, block.totalAddedLines());
133 }
134
135 public void added(AddBlock block) {
136 out.printf("@@ -%d,0 +%d,%d @@\n", block.insertedAt(), block.firstAddedLine() + 1, block.totalAddedLines());
137 // String[] addedLines = block.addedLines();
138 // assert addedLines.length == block.totalAddedLines();
139 // for (int i = 0, ln = block.firstAddedLine(), x = addedLines.length; i < x; i++, ln++) {
140 // linesNew.put(ln, String.format("%3d:+++:%s", ln, addedLines[i]));
141 // }
142 }
143 }
144
145 public static class LineGrepOutputParser implements OutputParser {
146
147 private final Pattern pattern;
148 private final StringBuilder result = new StringBuilder();
149
150 public LineGrepOutputParser(String regexp) {
151 pattern = Pattern.compile(regexp);
152 }
153
154 public CharSequence result() {
155 return result;
156 }
157
158 public void parse(CharSequence seq) {
159 int lineStart = 0, lineEnd = 0;
160 do {
161 while (lineEnd < seq.length() && seq.charAt(lineEnd) != '\n') lineEnd++;
162 if (lineEnd == lineStart) {
163 continue;
164 }
165 CharSequence line = seq.subSequence(lineStart, lineEnd);
166 if (pattern.matcher(line).matches()) {
167 result.append(line);
168 result.append('\n');
169 }
170 lineStart = ++lineEnd;
171 } while (lineStart < seq.length());
172 }
173 }
91 } 174 }