vcs: EA-88856 - assert: Block.createPreviousBlock

* reuse existing logic, that allows to update line range on document modification
* changed ranges do not intersect, so we can just "apply" changes one-by-one
This commit is contained in:
Aleksey Pivovarov
2016-11-22 15:54:59 +03:00
parent dbcb067e01
commit 99511e32c5
2 changed files with 173 additions and 18 deletions
@@ -182,7 +182,17 @@ public class SelectedBlockHistoryTest extends TestCase {
);
}
public void test15() throws FilesTooBigForDiffException {
public void testGreediness() throws FilesTooBigForDiffException {
doTest(
new String[]{},
new String[]{"x", "y", "z"},
new String[]{},
new String[]{"1"},
new String[]{"2", "3"},
new String[]{"4"}
);
doTest(
new String[]{"1"},
new String[]{"0"},
@@ -192,6 +202,150 @@ public class SelectedBlockHistoryTest extends TestCase {
new String[]{"5", "0"},
new String[]{"3"}
);
doTest(
new String[]{"1", "2"},
new String[]{"3", "5", "X", "Z", "7"},
new String[]{"8", "9"},
new String[]{"1", "2"},
new String[]{"3", "4", "5", "6", "7"},
new String[]{"8", "9"}
);
doTest(
new String[]{"1"},
new String[]{"5", "X", "Z"},
new String[]{"9"},
new String[]{"1", "2"},
new String[]{"3", "4", "5", "6", "7"},
new String[]{"8", "9"}
);
doTest(
new String[]{"1"},
new String[]{"5", "X", "7"},
new String[]{"Z", "9"},
new String[]{"1", "2"},
new String[]{"3", "4", "5", "6", "7"},
new String[]{"8", "9"}
);
}
public void testEmptyPreviousText() throws FilesTooBigForDiffException {
doTest(
new String[]{},
new String[]{},
new String[]{},
new String[]{},
new String[]{},
new String[]{}
);
doTest(
new String[]{},
new String[]{},
new String[]{},
new String[]{},
new String[]{},
new String[]{"x"}
);
doTest(
new String[]{},
new String[]{},
new String[]{},
new String[]{"x"},
new String[]{},
new String[]{}
);
doTest(
new String[]{},
new String[]{},
new String[]{},
new String[]{},
new String[]{"x"},
new String[]{}
);
doTest(
new String[]{},
new String[]{},
new String[]{},
new String[]{"z"},
new String[]{"x"},
new String[]{"y"}
);
}
public void testEmptyCurrentRange() throws FilesTooBigForDiffException {
doTest(
new String[]{},
new String[]{},
new String[]{"x"},
new String[]{},
new String[]{},
new String[]{}
);
doTest(
new String[]{},
new String[]{},
new String[]{"x", "y", "z"},
new String[]{},
new String[]{},
new String[]{}
);
doTest(
new String[]{},
new String[]{},
new String[]{"x"},
new String[]{},
new String[]{},
new String[]{"z"}
);
doTest(
new String[]{},
new String[]{},
new String[]{"x"},
new String[]{},
new String[]{},
new String[]{"y", "z"}
);
doTest(
new String[]{"x"},
new String[]{},
new String[]{},
new String[]{"y"},
new String[]{},
new String[]{"z"}
);
doTest(
new String[]{"y"},
new String[]{},
new String[]{"w", "z"},
new String[]{"y"},
new String[]{},
new String[]{"z"}
);
}
public void testContent(){
@@ -19,6 +19,7 @@ import com.intellij.diff.comparison.ByLine;
import com.intellij.diff.comparison.ComparisonPolicy;
import com.intellij.diff.comparison.DiffTooBigException;
import com.intellij.diff.comparison.iterables.FairDiffIterable;
import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.Range;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.DumbProgressIndicator;
@@ -61,29 +62,29 @@ public class Block {
@NotNull
public Block createPreviousBlock(@NotNull String[] prevContent) {
int start = -1;
int end = -1;
int shift = 0;
try {
FairDiffIterable iterable = ByLine.compare(Arrays.asList(prevContent), Arrays.asList(mySource),
ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE);
for (Range range : iterable.iterateChanges()) {
if (Math.max(myStart, range.start2) < Math.min(myEnd, range.end2)) {
// ranges intersect
if (range.start2 <= myStart) start = range.start1;
if (range.end2 > myEnd) end = range.end1;
}
if (range.start2 > myStart) {
if (start == -1) start = myStart - shift;
if (end == -1 && range.start2 >= myEnd) end = myEnd - shift;
}
// empty range should not be transferred to the non-empty range
boolean greedy = myStart != myEnd;
shift += (range.end2 - range.start2) - (range.end1 - range.start1);
int start = myStart;
int end = myEnd;
int shift = 0;
for (Range range : iterable.iterateChanges()) {
int changeStart = range.start2 + shift;
int changeEnd = range.end2 + shift;
int changeShift = (range.end1 - range.start1) - (range.end2 - range.start2);
DiffUtil.UpdatedLineRange updatedRange =
DiffUtil.updateRangeOnModification(start, end, changeStart, changeEnd, changeShift, greedy);
start = updatedRange.startLine;
end = updatedRange.endLine;
shift += changeShift;
}
if (start == -1) start = myStart - shift;
if (end == -1) end = myEnd - shift;
if (start < 0 || end > prevContent.length || end < start) {
LOG.error("Invalid block range: [" + start + ", " + end + "); length - " + prevContent.length);