changeset 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
files src/org/tmatesoft/hg/internal/AnnotateFacility.java src/org/tmatesoft/hg/internal/PatchGenerator.java test/org/tmatesoft/hg/test/TestBlame.java
diffstat 3 files changed, 138 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/AnnotateFacility.java	Thu Feb 14 16:36:13 2013 +0100
+++ b/src/org/tmatesoft/hg/internal/AnnotateFacility.java	Fri Feb 15 15:52:03 2013 +0100
@@ -83,11 +83,13 @@
 	}
 	
 	public interface AddBlock extends Block {
+		int insertedAt(); // line index in the old file 
 		int firstAddedLine();
 		int totalAddedLines();
 		String[] addedLines();
 	}
 	public interface DeleteBlock extends Block {
+		int removedAt(); // line index in the new file
 		int firstRemovedLine();
 		int totalRemovedLines();
 		String[] removedLines();
@@ -105,17 +107,17 @@
 
 		@Override
 		protected void changed(int s1From, int s1To, int s2From, int s2To) {
-			insp.changed(new BlockImpl2(seq1, seq2, s1From, s1To-s1From, s2From, s2To - s2From));
+			insp.changed(new BlockImpl2(seq1, seq2, s1From, s1To-s1From, s2From, s2To - s2From, s1From, s2From));
 		}
 		
 		@Override
 		protected void added(int s1InsertPoint, int s2From, int s2To) {
-			insp.added(new BlockImpl2(null, seq2, -1, -1, s2From, s2To - s2From));
+			insp.added(new BlockImpl2(null, seq2, -1, -1, s2From, s2To - s2From, s1InsertPoint, -1));
 		}
 		
 		@Override
-		protected void deleted(int s1From, int s1To) {
-			insp.deleted(new BlockImpl2(seq1, null, s1From, s1To - s1From, -1, -1));
+		protected void deleted(int s2DeletePoint, int s1From, int s1To) {
+			insp.deleted(new BlockImpl2(seq1, null, s1From, s1To - s1From, -1, -1, -1, s2DeletePoint));
 		}
 
 		@Override
@@ -151,14 +153,22 @@
 		private final int s1Len;
 		private final int s2Start;
 		private final int s2Len;
+		private final int s1InsertPoint;
+		private final int s2DeletePoint;
 
-		public BlockImpl2(ChunkSequence s1, ChunkSequence s2, int s1Start, int s1Len, int s2Start, int s2Len) {
+		public BlockImpl2(ChunkSequence s1, ChunkSequence s2, int s1Start, int s1Len, int s2Start, int s2Len, int s1InsertPoint, int s2DeletePoint) {
 			oldSeq = s1;
 			newSeq = s2;
 			this.s1Start = s1Start;
 			this.s1Len = s1Len;
 			this.s2Start = s2Start;
 			this.s2Len = s2Len;
+			this.s1InsertPoint = s1InsertPoint;
+			this.s2DeletePoint = s2DeletePoint;
+		}
+		
+		public int insertedAt() {
+			return s1InsertPoint;
 		}
 
 		public int firstAddedLine() {
@@ -172,6 +182,10 @@
 		public String[] addedLines() {
 			return generateLines(totalAddedLines(), firstAddedLine());
 		}
+		
+		public int removedAt() {
+			return s2DeletePoint;
+		}
 
 		public int firstRemovedLine() {
 			return s1Start;
@@ -188,7 +202,7 @@
 		private String[] generateLines(int count, int startFrom) {
 			String[] rv = new String[count];
 			for (int i = 0; i < count; i++) {
-				rv[i] = String.format("LINE %d", startFrom + i);
+				rv[i] = String.format("LINE %d", startFrom + i+1);
 			}
 			return rv;
 		}
--- a/src/org/tmatesoft/hg/internal/PatchGenerator.java	Thu Feb 14 16:36:13 2013 +0100
+++ b/src/org/tmatesoft/hg/internal/PatchGenerator.java	Fri Feb 15 15:52:03 2013 +0100
@@ -187,7 +187,7 @@
 					changed(changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2);
 				} else {
 					assert changeStartS2 == matchStartSeq2;
-					deleted(changeStartS1, matchStartSeq1);
+					deleted(matchStartSeq2, changeStartS1, matchStartSeq1);
 				}
 			} else {
 				assert changeStartS1 == matchStartSeq1;
@@ -210,7 +210,7 @@
 			// NO-OP
 		}
 
-		protected void deleted(int s1From, int s1To) {
+		protected void deleted(int s2DeletePoint, int s1From, int s1To) {
 			// NO-OP
 		}
 
@@ -231,7 +231,7 @@
 		}
 		
 		@Override
-		protected void deleted(int s1From, int s1To) {
+		protected void deleted(int s2DeletionPoint, int s1From, int s1To) {
 			System.out.printf("deleted [%d..%d)\n", s1From, s1To);
 		}
 		
@@ -259,7 +259,7 @@
 		}
 		
 		@Override
-		protected void deleted(int s1From, int s1To) {
+		protected void deleted(int s2DeletionPoint, int s1From, int s1To) {
 			int from = seq1.chunk(s1From).getOffset();
 			int to = seq1.chunk(s1To).getOffset();
 			deltaCollector.add(from, to, new byte[0]);
--- a/test/org/tmatesoft/hg/test/TestBlame.java	Thu Feb 14 16:36:13 2013 +0100
+++ b/test/org/tmatesoft/hg/test/TestBlame.java	Fri Feb 15 15:52:03 2013 +0100
@@ -16,13 +16,19 @@
  */
 package org.tmatesoft.hg.test;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import org.junit.Assert;
 import org.junit.Test;
 import org.tmatesoft.hg.internal.AnnotateFacility;
 import org.tmatesoft.hg.internal.AnnotateFacility.AddBlock;
+import org.tmatesoft.hg.internal.AnnotateFacility.Block;
 import org.tmatesoft.hg.internal.AnnotateFacility.ChangeBlock;
 import org.tmatesoft.hg.internal.AnnotateFacility.DeleteBlock;
 import org.tmatesoft.hg.internal.IntMap;
-import org.tmatesoft.hg.internal.AnnotateFacility.Block;
 import org.tmatesoft.hg.repo.HgDataFile;
 import org.tmatesoft.hg.repo.HgLookup;
 import org.tmatesoft.hg.repo.HgRepository;
@@ -38,38 +44,47 @@
 	@Test
 	public void testSingleParentBlame() throws Exception {
 		HgRepository repo = new HgLookup().detectFromWorkingDir();
-		HgDataFile df = repo.getFileNode("src/org/tmatesoft/hg/internal/PatchGenerator.java");
-		final IntMap<String> linesOld= new IntMap<String>(100);
-		final IntMap<String> linesNew = new IntMap<String>(100);
-		new AnnotateFacility().annotate(df, 539, new AnnotateFacility.Inspector() {
-			
-			public void same(Block block) {
-				// TODO Auto-generated method stub
-				
+		final String fname = "src/org/tmatesoft/hg/internal/PatchGenerator.java";
+		final int checkChangeset = 539;
+		HgDataFile df = repo.getFileNode(fname);
+		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		new AnnotateFacility().annotate(df, checkChangeset, new DiffOutInspector(new PrintStream(bos)));
+		LineGrepOutputParser gp = new LineGrepOutputParser("^@@.+");
+		ExecHelper eh = new ExecHelper(gp, null);
+		eh.run("hg", "diff", "-c", String.valueOf(checkChangeset), "-U", "0", fname);
+		//
+		String[] apiResult = splitLines(bos.toString());
+		String[] expected = splitLines(gp.result());
+		Assert.assertArrayEquals(expected, apiResult);
+	}
+	
+	private static String[] splitLines(CharSequence seq) {
+		int lineCount = 0;
+		for (int i = 0, x = seq.length(); i < x; i++) {
+			if (seq.charAt(i) == '\n') {
+				lineCount++;
 			}
-			
-			public void deleted(DeleteBlock block) {
-				String[] lines = block.removedLines();
-				assert lines.length == block.totalRemovedLines();
-				for (int i = 0, ln = block.firstRemovedLine(); i < lines.length; i++, ln++) {
-					linesOld.put(ln, String.format("%3d:---:%s", ln, lines[i]));
-				}
+		}
+		if (seq.length() > 0 && seq.charAt(seq.length()-1) != '\n') {
+			lineCount++;
+		}
+		String[] rv = new String[lineCount];
+		int lineStart = 0, lineEnd = 0, ix = 0;
+		do {
+			while (lineEnd < seq.length() && seq.charAt(lineEnd) != '\n') lineEnd++;
+			if (lineEnd == lineStart) {
+				continue;
 			}
-			
-			public void changed(ChangeBlock block) {
-				deleted(block);
-				added(block);
-			}
-			
-			public void added(AddBlock block) {
-				String[] addedLines = block.addedLines();
-				assert addedLines.length == block.totalAddedLines();
-				for (int i = 0, ln = block.firstAddedLine(), x = addedLines.length; i < x; i++, ln++) {
-					linesNew.put(ln, String.format("%3d:+++:%s", ln, addedLines[i]));
-				}
-			}
-		});
-		
+			CharSequence line = seq.subSequence(lineStart, lineEnd);
+			rv[ix++] = line.toString();
+			lineStart = ++lineEnd;
+		} while (lineStart < seq.length());
+		assert ix == lineCount;
+		return rv;
+	}
+	
+	private void leftovers() {
+		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++) {
 			if (linesOld.containsKey(i)) {
@@ -86,6 +101,74 @@
 	}
 	
 	public static void main(String[] args) throws Exception {
+		System.out.println(Arrays.equals(new String[0], splitLines("")));
+		System.out.println(Arrays.equals(new String[] { "abc" }, splitLines("abc")));
 		new TestBlame().testSingleParentBlame();
 	}
+
+	static class DiffOutInspector implements AnnotateFacility.Inspector {
+		private final PrintStream out;
+		
+		DiffOutInspector(PrintStream ps) {
+			out = ps;
+		}
+		
+		public void same(Block block) {
+			// nothing 
+		}
+		
+		public void deleted(DeleteBlock block) {
+			out.printf("@@ -%d,%d +%d,0 @@\n", block.firstRemovedLine() + 1, block.totalRemovedLines(), block.removedAt());
+//			String[] lines = block.removedLines();
+//			assert lines.length == block.totalRemovedLines();
+//			for (int i = 0, ln = block.firstRemovedLine(); i < lines.length; i++, ln++) {
+//				linesOld.put(ln, String.format("%3d:---:%s", ln, lines[i]));
+//			}
+		}
+		
+		public void changed(ChangeBlock block) {
+//			deleted(block);
+//			added(block);
+			out.printf("@@ -%d,%d +%d,%d @@\n", block.firstRemovedLine() + 1, block.totalRemovedLines(), block.firstAddedLine() + 1, block.totalAddedLines());
+		}
+		
+		public void added(AddBlock block) {
+			out.printf("@@ -%d,0 +%d,%d @@\n", block.insertedAt(), block.firstAddedLine() + 1, block.totalAddedLines());
+//			String[] addedLines = block.addedLines();
+//			assert addedLines.length == block.totalAddedLines();
+//			for (int i = 0, ln = block.firstAddedLine(), x = addedLines.length; i < x; i++, ln++) {
+//				linesNew.put(ln, String.format("%3d:+++:%s", ln, addedLines[i]));
+//			}
+		}
+	}
+	
+	public static class LineGrepOutputParser implements OutputParser {
+		
+		private final Pattern pattern;
+		private final StringBuilder result = new StringBuilder();
+
+		public LineGrepOutputParser(String regexp) {
+			pattern = Pattern.compile(regexp);
+		}
+		
+		public CharSequence result() {
+			return result;
+		}
+
+		public void parse(CharSequence seq) {
+			int lineStart = 0, lineEnd = 0;
+			do {
+				while (lineEnd < seq.length() && seq.charAt(lineEnd) != '\n') lineEnd++;
+				if (lineEnd == lineStart) {
+					continue;
+				}
+				CharSequence line = seq.subSequence(lineStart, lineEnd);
+				if (pattern.matcher(line).matches()) {
+					result.append(line);
+					result.append('\n');
+				}
+				lineStart = ++lineEnd;
+			} while (lineStart < seq.length());
+		}
+	}
 }