Merge branch 'master' of git.labs.intellij.net:idea/community
authorDmitry Jemerov <yole@jetbrains.com>
Fri, 12 Nov 2010 09:22:57 +0000 (12:22 +0300)
committerDmitry Jemerov <yole@jetbrains.com>
Fri, 12 Nov 2010 09:22:57 +0000 (12:22 +0300)
29 files changed:
platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java
platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffStatusBar.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/ByWord.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DiffDividerPaint.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java [moved from platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java with 81% similarity]
platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/LineBlocks.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/util/LabeledEditor.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/util/TextDiffType.java
platform/platform-impl/testSrc/com/intellij/openapi/diff/LineTokenizerTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/MultiCheck.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/external/DiffManagerTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/FragmentEquality.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/FragmentStringConvertion.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/LineBlockDividesTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilderTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/ByWordTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/CorrectionTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/NormalizationTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/PreferWholeLinesTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/UniteSameTypeTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/splitter/LineBlocksTest.java [new file with mode: 0644]
platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/splitter/TransformationTest.java [new file with mode: 0644]
platform/platform-resources-en/src/messages/DiffBundle.properties

index 9356e5eb3d48dfffeb4b60238157056b98f3574d..cc6be708344bb011d80c4fa114eb51483c09be67 100644 (file)
@@ -49,7 +49,9 @@ public class IgnoreWhiteSpacesAction extends ComboBoxAction implements DumbAware
   @Override
   public JComponent createCustomComponent(final Presentation presentation) {
     JPanel panel = new JPanel(new BorderLayout());
-    panel.add(new JLabel(DiffBundle.message("comparison.ignore.whitespace.acton.name")), BorderLayout.WEST);
+    final JLabel label = new JLabel(DiffBundle.message("comparison.ignore.whitespace.acton.name"));
+    label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
+    panel.add(label, BorderLayout.WEST);
     panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER);
     return panel;
   }
@@ -67,8 +69,8 @@ public class IgnoreWhiteSpacesAction extends ComboBoxAction implements DumbAware
     Presentation presentation = e.getPresentation();
     DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
     if (diffPanel != null && diffPanel.getComponent().isDisplayable()) {
-      AnAction actoin = myActions.get(diffPanel.getComparisonPolicy());
-      Presentation templatePresentation = actoin.getTemplatePresentation();
+      AnAction action = myActions.get(diffPanel.getComparisonPolicy());
+      Presentation templatePresentation = action.getTemplatePresentation();
       presentation.setIcon(templatePresentation.getIcon());
       presentation.setText(templatePresentation.getText());
       presentation.setEnabled(true);
index 6ad8c09a138dae2fde4ceb779526b0691ac1d4ad..a7379192358e3359b3bbc676680cdda6d40e4a4c 100644 (file)
@@ -17,15 +17,13 @@ package com.intellij.openapi.diff.ex;
 
 import com.intellij.openapi.editor.colors.EditorColorsManager;
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
-import com.intellij.openapi.vcs.FileStatus;
-import com.intellij.openapi.vcs.VcsBundle;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
@@ -33,12 +31,6 @@ import java.util.List;
  * @author Yura Cangea
  */
 public class DiffStatusBar extends JPanel {
-  public static final List<? extends LegendTypeDescriptor> DEFAULT_TYPES =
-    Arrays.asList(
-      new LegendTypeDescriptorImpl(VcsBundle.message("diff.type.name.modified"), FileStatus.COLOR_MODIFIED),
-      new LegendTypeDescriptorImpl(VcsBundle.message("diff.type.name.added"), FileStatus.COLOR_ADDED),
-      new LegendTypeDescriptorImpl(VcsBundle.message("diff.type.name.deleted"), FileStatus.COLOR_MISSING));
-
   private final Collection<JComponent> myLabels = new ArrayList<JComponent>();
 
   private final JLabel myTextLabel = new JLabel("");
@@ -143,24 +135,7 @@ public class DiffStatusBar extends JPanel {
 
   public interface LegendTypeDescriptor {
     String getDisplayName();
+    @Nullable
     Color getLegendColor(EditorColorsScheme colorScheme);
   }
-
-  static class LegendTypeDescriptorImpl implements LegendTypeDescriptor {
-    private final String myDisplayName;
-    private final Color myColor;
-
-    LegendTypeDescriptorImpl(final String displayName, final Color color) {
-      myDisplayName = displayName;
-      myColor = color;
-    }
-
-    public String getDisplayName() {
-      return myDisplayName;
-    }
-
-    public Color getLegendColor(final EditorColorsScheme colorScheme) {
-      return myColor;
-    }
-  }
 }
index e9f13b7c2a8850f289a282423125d49c07c0dd22..fe4b23b930bb0e37ff77d7a450a2d7e35691c442 100644 (file)
@@ -77,7 +77,10 @@ public abstract class DiffMarkup implements EditorSource {
                                                          attributes, HighlighterTargetArea.EXACT_RANGE);
     }
     Color stripeBarColor = attributes.getErrorStripeColor();
-    if (stripeBarColor != null) rangeMarker.setErrorStripeMarkColor(stripeBarColor);
+    if (stripeBarColor != null) {
+      rangeMarker.setErrorStripeMarkColor(stripeBarColor);
+      rangeMarker.setThinErrorStripeMark(true);
+    }
     saveHighlighter(rangeMarker);
   }
 
index 23a153b3e2088a0f199e794a487d7db6e273ab30..214a942565859f329cf55b6030fdabaec41f5afd 100644 (file)
@@ -221,8 +221,9 @@ class ByWord implements DiffPolicy{
     }
 
     private DiffFragment[] fragmentsByChar(String text1, String text2) {
-      DiffFragment[] fragments = BY_CHAR.buildFragments(myVersion1.getPrevChar() + text1,
-                                                        myVersion2.getPrevChar() + text2);
+      final String side1 = myVersion1.getPrevChar() + text1;
+      final String side2 = myVersion2.getPrevChar() + text2;
+      DiffFragment[] fragments = BY_CHAR.buildFragments(side1, side2);
       return Util.cutFirst(fragments);
     }
 
@@ -267,7 +268,7 @@ class ByWord implements DiffPolicy{
       String tail1 = myVersion1.getNotProcessedTail();
       String tail2 = myVersion2.getNotProcessedTail();
       if (tail1.length() == 0 && tail2.length() == 0) return;
-      DiffFragment[] fragments = fragmentsByChar(tail1, tail2);
+      DiffFragment[] fragments = BY_CHAR.buildFragments(tail1, tail2);
       if (myFragments.size() > 0) {
         DiffFragment lastFragment = myFragments.get(myFragments.size() - 1);
         if (lastFragment.isChange()) {
index 5278ff3c40eff836fdc3dc87fdc57e6bdc2f6ecb..b59f188b3ed6184ee962fc5c0d8aadc203b09019 100644 (file)
@@ -25,7 +25,6 @@ import com.intellij.openapi.diff.impl.highlighting.LineBlockDivider;
 import com.intellij.openapi.diff.impl.highlighting.Util;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 
 public class TextCompareProcessor {
   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Processor");
@@ -40,8 +39,7 @@ public class TextCompareProcessor {
     DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).
         correctAndNormalize(woFormattingBlocks);
     ArrayList<LineFragment> lineBlocks = new DiffFragmentsProcessor().process(step1lineFragments);
-    for (Iterator<LineFragment> iterator = lineBlocks.iterator(); iterator.hasNext();) {
-      LineFragment lineBlock = iterator.next();
+    for (LineFragment lineBlock : lineBlocks) {
       if (lineBlock.isOneSide() || lineBlock.isEqual()) continue;
       String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1);
       String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2);
@@ -61,12 +59,10 @@ public class TextCompareProcessor {
     lines = Util.uniteFormattingOnly(lines);
 
     LineFragmentsCollector collector = new LineFragmentsCollector();
-    for (int i = 0; i < lines.length; i++) {
-      DiffFragment[] line = lines[i];
+    for (DiffFragment[] line : lines) {
       DiffFragment[][] subLines = LineBlockDivider.SINGLE_SIDE.divide(line);
       subLines = Util.uniteFormattingOnly(subLines);
-      for (int j = 0; j < subLines.length; j++) {
-        DiffFragment[] subLineFragments = subLines[j];
+      for (DiffFragment[] subLineFragments : subLines) {
         LineFragment subLine = collector.addDiffFragment(Util.concatenate(subLineFragments));
         if (!subLine.isOneSide()) {
           subLine.setChildren(processInlineFragments(subLineFragments));
@@ -76,11 +72,10 @@ public class TextCompareProcessor {
     return collector.getFragments();
   }
 
-  private ArrayList<Fragment> processInlineFragments(DiffFragment[] subLineFragments) {
+  private static ArrayList<Fragment> processInlineFragments(DiffFragment[] subLineFragments) {
     LOG.assertTrue(subLineFragments.length > 0);
     FragmentsCollector result = new FragmentsCollector();
-    for (int i = 0; i < subLineFragments.length; i++) {
-      DiffFragment fragment = subLineFragments[i];
+    for (DiffFragment fragment : subLineFragments) {
       result.addDiffFragment(fragment);
     }
     return result.getFragments();
index 7506265525dc9333605a698e145fe97c492d90ae..bf1e435f7b93132eeea1324cac526511a9c226bc 100644 (file)
@@ -36,7 +36,7 @@ public class DiffDividerPaint {
     int height = component.getHeight();
     int editorHeight = mySides.getEditor(myLeftSide).getComponent().getHeight();
     Graphics2D gg = (Graphics2D)g.create(0, height - editorHeight, width, editorHeight);
-    DividerPoligon.paintPoligons(DividerPoligon.createVisiblePoligons(mySides, myLeftSide), gg, width);
+    DividerPolygon.paintPolygons(DividerPolygon.createVisiblePolygons(mySides, myLeftSide), gg, width);
     gg.dispose();
   }
 
similarity index 81%
rename from platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPoligon.java
rename to platform/platform-impl/src/com/intellij/openapi/diff/impl/splitter/DividerPolygon.java
index a9ea482155a59de32594765a7d9f53a6954e423d..5b2b15bf1878bc6f9b274fc0bd21ba1d31b6c409 100644 (file)
@@ -26,16 +26,15 @@ import com.intellij.util.ui.UIUtil;
 
 import java.awt.*;
 import java.util.ArrayList;
-import java.util.Iterator;
 
-class DividerPoligon {
+class DividerPolygon {
   private final Color myColor;
   private final int myStart1;
   private final int myStart2;
   private final int myEnd1;
   private final int myEnd2;
 
-  public DividerPoligon(int start1, int start2, int end1, int end2, Color color) {
+  public DividerPolygon(int start1, int start2, int end1, int end2, Color color) {
     myStart1 = advance(start1);
     myStart2 = advance(start2);
     myEnd1 = advance(end1);
@@ -60,8 +59,8 @@ class DividerPoligon {
   }
 
   public boolean equals(Object obj) {
-    if (!(obj instanceof DividerPoligon)) return false;
-    DividerPoligon other = (DividerPoligon)obj;
+    if (!(obj instanceof DividerPolygon)) return false;
+    DividerPolygon other = (DividerPolygon)obj;
     return myStart1 == other.myStart1 &&
            myStart2 == other.myStart2 &&
            myEnd1 == other.myEnd1 &&
@@ -76,38 +75,37 @@ class DividerPoligon {
     return myColor;
   }
 
-  public static void paintPoligons(ArrayList<DividerPoligon> poligons, Graphics2D g, int width) {
+  public static void paintPolygons(ArrayList<DividerPolygon> polygons, Graphics2D g, int width) {
     g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
     //Composite composite = g.getComposite();
     //g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4f));
-    for (Iterator<DividerPoligon> iterator = poligons.iterator(); iterator.hasNext();) {
-      DividerPoligon poligon = iterator.next();
-      poligon.paint(g, width);
+    for (DividerPolygon polygon : polygons) {
+      polygon.paint(g, width);
     }
     //g.setComposite(composite);
   }
 
-  public static ArrayList<DividerPoligon> createVisiblePoligons(EditingSides sides, FragmentSide left) {
+  public static ArrayList<DividerPolygon> createVisiblePolygons(EditingSides sides, FragmentSide left) {
     Editor editor1 = sides.getEditor(left);
     Editor editor2 = sides.getEditor(left.otherSide());
     LineBlocks lineBlocks = sides.getLineBlocks();
     Trapezium visibleArea = new Trapezium(getVisibleInterval(editor1),
                                           getVisibleInterval(editor2));
-    Interval indecies = lineBlocks.getVisibleIndecies(visibleArea);
+    Interval indices = lineBlocks.getVisibleIndices(visibleArea);
     Transformation[] transformations = new Transformation[]{getTransformation(editor1),
       getTransformation(editor2)};
-    ArrayList<DividerPoligon> poligons = new ArrayList<DividerPoligon>();
-    for (int i = indecies.getStart(); i < indecies.getEnd(); i++) {
+    ArrayList<DividerPolygon> polygons = new ArrayList<DividerPolygon>();
+    for (int i = indices.getStart(); i < indices.getEnd(); i++) {
       Trapezium trapezium = lineBlocks.getTrapezium(i);
       final TextDiffTypeEnum diffTypeEnum = lineBlocks.getType(i);
       if (diffTypeEnum == null) continue;
       TextDiffType type = TextDiffType.create(diffTypeEnum);
       if (type == null) continue;
-      Color color = type.getPoligonColor(editor1);
-      poligons.add(createPoligon(transformations, trapezium, color, left));
+      Color color = type.getPolygonColor(editor1);
+      polygons.add(createPolygon(transformations, trapezium, color, left));
     }
-    return poligons;
+    return polygons;
   }
 
   private static Transformation getTransformation(Editor editor) {
@@ -115,7 +113,7 @@ class DividerPoligon {
     return new FoldingTransformation(editor);
   }
 
-  private static DividerPoligon createPoligon(Transformation[] transformations, Trapezium trapezium, Color color, FragmentSide left) {
+  private static DividerPolygon createPolygon(Transformation[] transformations, Trapezium trapezium, Color color, FragmentSide left) {
     Interval base1 = trapezium.getBase(left);
     Interval base2 = trapezium.getBase(left.otherSide());
     Transformation leftTransform = transformations[left.getIndex()];
@@ -124,7 +122,7 @@ class DividerPoligon {
     int end1 = leftTransform.transform(base1.getEnd());
     int start2 = rightTransform.transform(base2.getStart());
     int end2 = rightTransform.transform(base2.getEnd());
-    return new DividerPoligon(start1, start2, end1, end2, color);
+    return new DividerPolygon(start1, start2, end1, end2, color);
   }
 
   static Interval getVisibleInterval(Editor editor) {
index be99deef041d6d32e0f048f910b23b38a7efcfb2..728bd8c55c2f318b6d72598d7734102dcf87d32a 100644 (file)
@@ -39,7 +39,7 @@ public class LineBlocks {
     myTypes = types;
   }
 
-  public Interval getVisibleIndecies(Trapezium visibleArea) {
+  public Interval getVisibleIndices(Trapezium visibleArea) {
     Interval visible1 = visibleArea.getBase1();
     Interval visible2 = visibleArea.getBase2();
     Interval[] intervals1 = getIntervals(FragmentSide.SIDE1);
index fc0c5714e0e1c5e67e17628929216c618a93f0d5..258a43504b99dffc41f77ad6a48b1ea0bca29c86 100644 (file)
@@ -27,8 +27,8 @@ public class LabeledEditor extends JPanel {
     super(new BorderLayout());
   }
 
-  private String addReadOnly(String title, boolean readonly) {
-    if (readonly) title += DiffBundle.message("diff.content.read.only.content.title.suffix");
+  private static String addReadOnly(String title, boolean readonly) {
+    if (readonly) title += " " + DiffBundle.message("diff.content.read.only.content.title.suffix");
     return title;
   }
 
index a5337169e95194f67b45cda9533a76fe97fe6d79..f713c7e5153d9277e10bd3e9566fde029c9ebacc 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
 import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.util.containers.Convertor;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.awt.*;
 import java.util.Arrays;
@@ -38,8 +39,8 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
   public static final TextDiffType NONE = new TextDiffType(TextDiffTypeEnum.NONE, DiffBundle.message("diff.type.none.name"), null);
 
   private final TextDiffTypeEnum myType;
-  public static final List<TextDiffType> DIFF_TYPES = Arrays.asList(new TextDiffType[]{DELETED, CHANGED, INSERT});
-  public static final List<TextDiffType> MERGE_TYPES = Arrays.asList(new TextDiffType[]{DELETED, CHANGED, INSERT, CONFLICT});
+  public static final List<TextDiffType> DIFF_TYPES = Arrays.asList(DELETED, CHANGED, INSERT);
+  public static final List<TextDiffType> MERGE_TYPES = Arrays.asList(DELETED, CHANGED, INSERT, CONFLICT);
   private final TextAttributesKey myAttributesKey;
   private final String myDisplayName;
   public static final Convertor<TextDiffType, TextAttributesKey> ATTRIBUTES_KEY = new Convertor<TextDiffType, TextAttributesKey>() {
@@ -73,6 +74,7 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
     return myDisplayName;
   }
 
+  @Nullable
   public Color getLegendColor(EditorColorsScheme colorScheme) {
     TextAttributes attributes = getTextAttributes(colorScheme);
     return attributes != null ? attributes.getBackgroundColor() : null;
@@ -86,14 +88,16 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
     return scheme.getAttributes(myAttributesKey);
   }
 
-  public Color getPoligonColor(Editor editor1) {
-    return getLegendColor(editor1.getColorsScheme());
+  @Nullable
+  public Color getPolygonColor(Editor editor) {
+    return getLegendColor(editor.getColorsScheme());
   }
 
   public TextAttributes getTextAttributes(Editor editor1) {
     return getTextAttributes(editor1.getColorsScheme());
   }
 
+  @Nullable
   public Color getTextBackground(Editor editor) {
     TextAttributes attributes = getTextAttributes(editor);
     return attributes != null ? attributes.getBackgroundColor() : null;
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/LineTokenizerTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/LineTokenizerTest.java
new file mode 100644 (file)
index 0000000..7cf0ce2
--- /dev/null
@@ -0,0 +1,16 @@
+package com.intellij.openapi.diff;
+
+import com.intellij.util.Assertion;
+import junit.framework.TestCase;
+
+public class LineTokenizerTest extends TestCase {
+  private final Assertion CHECK = new Assertion();
+
+  public void test() {
+    CHECK.compareAll(new String[]{"a\n", "b\n", "c\n", "d\n"}, new LineTokenizer("a\nb\n\rc\rd\r\n").execute());
+    CHECK.compareAll(new String[]{"a\n", "b"}, new LineTokenizer("a\nb").execute());
+    LineTokenizer lineTokenizer = new LineTokenizer("a\n\r\r\nb");
+    CHECK.compareAll(new String[]{"a\n", "\n", "b"}, lineTokenizer.execute());
+    assertEquals("\n\r", lineTokenizer.getLineSeparator());
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/IgnoreWhiteSpaceTest.java
new file mode 100644 (file)
index 0000000..7eb6c45
--- /dev/null
@@ -0,0 +1,34 @@
+package com.intellij.openapi.diff.impl;
+
+import junit.framework.TestCase;
+
+public class IgnoreWhiteSpaceTest extends TestCase {
+  private ComparisonPolicy myPolicy;
+
+  public void testTrim() {
+    myPolicy = ComparisonPolicy.TRIM_SPACE;
+    Object[] keys = myPolicy.getLineWrappers(new String[]{"a b", " a b ", "\ta b", "a  b"});
+    assertEquals(keys[0], keys[1]);
+    assertEquals(keys[1], keys[2]);
+    assertFalse(keys[2].equals(keys[3]));
+    keys = myPolicy.getWrappers(new String[]{" a b", " a b ", " a b \n", "\ta b", "\n", "   "});
+    assertEquals(keys[0], keys[3]);
+    assertFalse(keys[0].equals(keys[1]));
+    assertEquals(" a b", keys[2]);
+    assertEquals("", keys[4]);
+    assertEquals("", keys[5]);
+  }
+
+  public void testIgnore() {
+    myPolicy = ComparisonPolicy.IGNORE_SPACE;
+    Object[] keys = myPolicy.getLineWrappers(new String[]{"a b", " a b", " a  b ", "ab", " b a"});
+    assertEquals(keys[0], keys[1]);
+    assertEquals(keys[1], keys[2]);
+    assertEquals(keys[2], keys[3]);
+    assertFalse(keys[1].equals(keys[4]));
+    keys = myPolicy.getWrappers(new String[]{" ", "   ", "\t\n", "a"});
+    assertEquals(keys[0], keys[1]);
+    assertEquals(keys[1], keys[2]);
+    assertFalse(keys[2].equals(keys[3]));
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/MultiCheck.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/MultiCheck.java
new file mode 100644 (file)
index 0000000..e9ef622
--- /dev/null
@@ -0,0 +1,49 @@
+package com.intellij.openapi.diff.impl;
+
+import junit.framework.Assert;
+import junit.framework.AssertionFailedError;
+
+import java.util.ArrayList;
+
+public class MultiCheck {
+  private final ArrayList<FailedCondition> myFailedConditions = new ArrayList<FailedCondition> ();
+
+  public void assertEquals(int expected, int actual) {
+    if (expected != actual)
+      myFailedConditions.add(new BooleanCondition(expected + "==" + actual));
+  }
+
+  public void flush() {
+    if (myFailedConditions.size() == 0) return;
+    for (FailedCondition condition: myFailedConditions) {
+      try {
+        condition.fail();
+      }
+      catch (AssertionFailedError e) {
+        e.printStackTrace(System.err);
+      }
+    }
+    Assert.fail();
+  }
+
+  public void assertNull(Object object) {
+    if (object != null) myFailedConditions.add(new BooleanCondition("Expected null: " + object));
+  }
+
+  private static abstract class FailedCondition {
+    abstract void fail();
+  }
+
+  private static class BooleanCondition extends FailedCondition {
+    private final AssertionFailedError myFailure;
+
+    public BooleanCondition(String message) {
+      myFailure = new AssertionFailedError(message);
+    }
+
+    @Override
+    public void fail() {
+      throw myFailure;
+    }
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/external/DiffManagerTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/external/DiffManagerTest.java
new file mode 100644 (file)
index 0000000..e3d532d
--- /dev/null
@@ -0,0 +1,83 @@
+package com.intellij.openapi.diff.impl.external;
+
+import com.intellij.openapi.diff.BinaryContent;
+import com.intellij.openapi.diff.DiffContent;
+import com.intellij.openapi.diff.DiffRequest;
+import com.intellij.openapi.diff.DiffTool;
+import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.util.ArrayUtil;
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+
+public class DiffManagerTest extends TestCase {
+
+  public void testAdditionalTools() {
+    DiffManagerImpl diffManager = new DiffManagerImpl();
+    MyDiffTool tool = new MyDiffTool();
+    diffManager.registerDiffTool(tool);
+    MyDiffRequest request = new MyDiffRequest();
+    request.addContent();
+    request.addContent();
+    request.addContent();
+    request.addContent();
+    assertTrue(diffManager.getDiffTool().canShow(request));
+    assertEquals(1, tool.myCanShowCount);
+    diffManager.getDiffTool().show(request);
+    assertEquals(2, tool.myCanShowCount);
+    assertEquals(1, tool.myShowCount);
+  }
+
+  private static class MyDiffTool implements DiffTool {
+    public int myCanShowCount = 0;
+    public int myShowCount = 0;
+    @Override
+    public boolean canShow(DiffRequest request) {
+      myCanShowCount++;
+      return canShowImpl(request);
+    }
+
+    private boolean canShowImpl(DiffRequest request) {
+      return request.getContents().length == 4;
+    }
+
+    @Override
+    public void show(DiffRequest request) {
+      assertTrue(canShowImpl(request));
+      myShowCount++;
+    }
+  }
+
+  private static class MyDiffRequest extends DiffRequest {
+    private final ArrayList<String> myContentTitles = new ArrayList<String>();
+    private final ArrayList<DiffContent> myDiffContents = new ArrayList<DiffContent>();
+
+    public MyDiffRequest() {
+      super(null);
+    }
+
+    @Override
+    public String getWindowTitle() {
+      return "title";
+    }
+
+    @Override
+    public String[] getContentTitles() {
+      return ArrayUtil.toStringArray(myContentTitles);
+    }
+
+    @Override
+    public DiffContent[] getContents() {
+      return myDiffContents.toArray(new DiffContent[myDiffContents.size()]);
+    }
+
+    public void addContent(DiffContent content, String title) {
+      myDiffContents.add(content);
+      myContentTitles.add(title);
+    }
+
+    public void addContent() {
+      addContent(new BinaryContent(ArrayUtil.EMPTY_BYTE_ARRAY, null, FileTypes.UNKNOWN), "");
+    }
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/FragmentEquality.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/FragmentEquality.java
new file mode 100644 (file)
index 0000000..a01a1ca
--- /dev/null
@@ -0,0 +1,16 @@
+package com.intellij.openapi.diff.impl.highlighting;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.util.Comparing;
+import gnu.trove.Equality;
+
+public class FragmentEquality implements Equality {
+  @Override
+  public boolean equals(Object o1, Object o2) {
+    DiffFragment fragment1 = (DiffFragment) o1;
+    DiffFragment fragment2 = (DiffFragment) o2;
+    return Comparing.equal(fragment1.getText1(), fragment2.getText1()) &&
+           Comparing.equal(fragment1.getText2(), fragment2.getText2()) &&
+           fragment1.isModified() == fragment2.isModified();
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/FragmentStringConvertion.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/FragmentStringConvertion.java
new file mode 100644 (file)
index 0000000..ef36ddb
--- /dev/null
@@ -0,0 +1,14 @@
+package com.intellij.openapi.diff.impl.highlighting;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.util.StringConvertion;
+import junit.framework.Assert;
+
+public class FragmentStringConvertion extends StringConvertion {
+  @Override
+  public String convert(Object obj) {
+    Assert.assertNotNull(obj);
+    DiffFragment fragment = (DiffFragment)obj;
+    return String.valueOf(fragment.getText1()) + "->" + String.valueOf(fragment.getText2()) + "\n-----------";
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/LineBlockDividesTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/LineBlockDividesTest.java
new file mode 100644 (file)
index 0000000..1bf78de
--- /dev/null
@@ -0,0 +1,31 @@
+package com.intellij.openapi.diff.impl.highlighting;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.util.Assertion;
+import junit.framework.TestCase;
+
+public class LineBlockDividesTest extends TestCase {
+  private final Assertion CHECK = new Assertion(new FragmentStringConvertion());
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    CHECK.setEquality(new FragmentEquality());
+  }
+
+  public void testSingleSide() {
+    DiffFragment abc_ = new DiffFragment("abc", null);
+    DiffFragment xyzL_ = new DiffFragment("xyz\n", null);
+    DiffFragment x_y = new DiffFragment("x", "y");
+    DiffFragment a_b = new DiffFragment("a", "b");
+    DiffFragment xyzL_L = new DiffFragment("xyz\n", "\n");
+    DiffFragment abcL_ = new DiffFragment("abc\n", null);
+    DiffFragment[][] lineBlocks = LineBlockDivider.SINGLE_SIDE.divide(new DiffFragment[]{
+      abc_, xyzL_,
+      x_y, a_b, xyzL_L,
+      abcL_});
+    CHECK.compareAll(new DiffFragment[][]{
+      new DiffFragment[]{abc_, xyzL_}, new DiffFragment[]{x_y, a_b, xyzL_L}, new DiffFragment[]{abcL_}},
+                     lineBlocks);
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/highlighting/UtilTest.java
new file mode 100644 (file)
index 0000000..96fd1d9
--- /dev/null
@@ -0,0 +1,226 @@
+package com.intellij.openapi.diff.impl.highlighting;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.diff.impl.MultiCheck;
+import com.intellij.util.Assertion;
+import com.intellij.util.diff.Diff;
+import junit.framework.TestCase;
+
+public class UtilTest extends TestCase {
+  private final Assertion CHECK = new Assertion();
+
+  public void testSplitByWord() {
+    CHECK.singleElement(Util.splitByWord("abc"), "abc");
+    CHECK.compareAll(new String[]{"abc", " ", "123"}, Util.splitByWord("abc 123"));
+    CHECK.compareAll(new String[]{"abc", "  \n", "\t ", "123"}, Util.splitByWord("abc  \n\t 123"));
+    CHECK.compareAll(new String[]{"a_b", "(", "c"}, Util.splitByWord("a_b(c"));
+    CHECK.compareAll(new String[]{"ab", " ", "+","(", " ", "c"}, Util.splitByWord("ab +( c"));
+    CHECK.compareAll(new String[]{"a", " ", "b", "\n"}, Util.splitByWord("a b\n"));
+  }
+
+  public void testIsSpaceOnly() {
+    assertTrue(Util.isSpaceOnly(new DiffFragment(null, " ")));
+    assertTrue(Util.isSpaceOnly(new DiffFragment(" ", null)));
+  }
+
+  public void testUnit() {
+    DiffFragment fragment = Util.unite(new DiffFragment("1", "2"), new DiffFragment("a", "b"));
+    assertEquals("1a", fragment.getText1());
+    assertEquals("2b", fragment.getText2());
+    assertTrue(fragment.isModified());
+
+    fragment = Util.unite(new DiffFragment("1", "1"), DiffFragment.unchanged("  ", ""));
+    assertEquals("1  ", fragment.getText1());
+    assertEquals("1", fragment.getText2());
+    assertTrue(fragment.isEqual());
+
+    fragment = Util.unite(new DiffFragment("1", null), new DiffFragment("2", null));
+    assertEquals("12", fragment.getText1());
+    assertNull(fragment.getText2());
+  }
+
+  private void prepareForFragments() {
+    CHECK.setStringConvertion(new FragmentStringConvertion());
+    CHECK.setEquality(new FragmentEquality());
+  }
+
+  public void testSplitByUnchagedNewLine() {
+    prepareForFragments();
+    DiffFragment a_b = new DiffFragment("a", "b");
+    DiffFragment x_x = new DiffFragment("x", "x");
+    DiffFragment cl_dl = new DiffFragment("c\n", "d\n");
+    DiffFragment yl_yl = new DiffFragment("y\n", "y\n");
+    DiffFragment zl_z = new DiffFragment("z\n", "z");
+    DiffFragment z_zl = new DiffFragment("z", "z\n");
+    DiffFragment al_ = new DiffFragment("a\n", null);
+    DiffFragment _al = new DiffFragment(null, "a\n");
+    DiffFragment[] originalFragments = new DiffFragment[]{a_b, x_x, cl_dl, a_b, yl_yl,
+                                                         x_x, zl_z, z_zl, yl_yl,
+                                                         new DiffFragment("y\nx", "y\nx"),
+                                                         a_b, al_, _al};
+    CHECK.compareAll(new DiffFragment[][]{
+      new DiffFragment[]{a_b, x_x, cl_dl, a_b, yl_yl},
+      new DiffFragment[]{x_x, zl_z, z_zl, yl_yl},
+      new DiffFragment[]{yl_yl},
+      new DiffFragment[]{x_x, a_b, al_, _al}
+    }, Util.splitByUnchangedLines(originalFragments));
+
+    CHECK.compareAll(new DiffFragment[][]{new DiffFragment[]{new DiffFragment("abc\n", "abc\n")},
+                                          new DiffFragment[]{DiffFragment.unchanged("123\n", "123")}},
+                     Util.splitByUnchangedLines(new DiffFragment[]{DiffFragment.unchanged("abc\n123\n", "abc\n123")}));
+    CHECK.compareAll(new DiffFragment[][]{new DiffFragment[]{DiffFragment.unchanged("a\n ", "a")}},
+                     Util.splitByUnchangedLines(new DiffFragment[]{DiffFragment.unchanged("a\n ", "a")}));
+  }
+
+  public void testSplitByUnchangedLinesIgnoringSpaces() {
+    DiffFragment[][] diffFragments = Util.splitByUnchangedLines(new DiffFragment[]{DiffFragment.unchanged("f(a, b)\n", "f(a,\nb)\n")});
+    assertEquals(1, diffFragments.length);
+    DiffFragment[] line = diffFragments[0];
+    assertEquals(1, line.length);
+    assertTrue(line[0].isEqual());
+  }
+
+  public void testConcatEquals() {
+    Object[] left = new String[]{"a", "x", "a", "b"};
+    Object[] right = new String[]{"a", "b"};
+    Diff.Change change = Diff.buildChanges(left, right);
+    Diff.Change newChange = Util.concatEquals(change, left, right);
+    MultiCheck multiCheck = new MultiCheck();
+    multiCheck.assertEquals(0, newChange.line0);
+    multiCheck.assertEquals(0, newChange.line1);
+    multiCheck.assertEquals(2, newChange.deleted);
+    multiCheck.assertEquals(0, newChange.inserted);
+    multiCheck.assertNull(newChange.link);
+    multiCheck.flush();
+
+    change = Diff.buildChanges(right, left);
+    newChange = Util.concatEquals(change, right, left);
+    multiCheck = new MultiCheck();
+    multiCheck.assertEquals(0, newChange.line0);
+    multiCheck.assertEquals(0, newChange.line1);
+    multiCheck.assertEquals(0, newChange.deleted);
+    multiCheck.assertEquals(2, newChange.inserted);
+    multiCheck.assertNull(newChange.link);
+    multiCheck.flush();
+
+    left = new String[]{"a", "x", "a", "1", "b"};
+    right = new String[]{"a", "b"};
+    change = Diff.buildChanges(left, right);
+    newChange = Util.concatEquals(change, left, right);
+    multiCheck = new MultiCheck();
+    multiCheck.assertEquals(1, newChange.line0);
+    multiCheck.assertEquals(1, newChange.line1);
+    multiCheck.assertEquals(3, newChange.deleted);
+    multiCheck.assertEquals(0, newChange.inserted);
+    multiCheck.assertNull(newChange.link);
+    multiCheck.flush();
+
+    left = new String[]{"y", "y", "y", "a", "2", "a", "b"};
+    right = new String[]{"x", "a", "b"};
+    change = Diff.buildChanges(left, right);
+    newChange = Util.concatEquals(change, left, right);
+    multiCheck = new MultiCheck();
+    multiCheck.assertEquals(0, newChange.line0);
+    multiCheck.assertEquals(0, newChange.line1);
+    multiCheck.assertEquals(3, newChange.deleted);
+    multiCheck.assertEquals(1, newChange.inserted);
+    newChange = newChange.link;
+    multiCheck.assertEquals(3, newChange.line0);
+    multiCheck.assertEquals(1, newChange.line1);
+    multiCheck.assertEquals(2, newChange.deleted);
+    multiCheck.assertEquals(0, newChange.inserted);
+    multiCheck.assertNull(newChange.link);
+    multiCheck.flush();
+  }
+
+  public void testConcatEqualsConcatenatesChanged() {
+    String[] left = new String[]{"i1", "a", "i2", "a", "b"};
+    String[] right = new String[]{"a", "b"};
+    Diff.Change change = Diff.buildChanges(left, right);
+    assertNotNull(change.link);
+    assertEquals(2, change.link.deleted);
+    assertEquals(2, change.link.line0);
+    Diff.Change newChange = Util.concatEquals(change, left, right);
+    MultiCheck multiCheck = new MultiCheck();
+    multiCheck.assertEquals(0, newChange.line0);
+    multiCheck.assertEquals(0, newChange.line1);
+    multiCheck.assertEquals(3, newChange.deleted);
+    multiCheck.assertEquals(0, newChange.inserted);
+    multiCheck.assertNull(newChange.link);
+    multiCheck.flush();
+  }
+
+  public void testCalcShift() {
+    assertEquals(-1, Util.calcShift(new String[]{"1", "a", "x", "a"}, 1, 2, 2));
+    assertEquals(0, Util.calcShift(new String[]{"1", "a", "x", "b"}, 1, 2, 2));
+    assertEquals(0, Util.calcShift(new String[]{"1", "a", "x", "a"}, 0, 2, 2));
+    assertEquals(-2, Util.calcShift(new String[]{"1", "a", "b", "x", "a", "b"}, 1, 3, 3));
+  }
+
+  public void testSplitByLines() {
+    Util.splitByLines(new DiffFragment("false;", "false;"));
+  }
+
+  public void testUniteFormattingOnly() {
+    prepareForFragments();
+    DiffFragment[] first = new DiffFragment[]{DiffFragment.unchanged("123", "abc")};
+    DiffFragment[] last = new DiffFragment[]{new DiffFragment("qqq", "qqq")};
+    DiffFragment inline1 = new DiffFragment(" ", "  ");
+    DiffFragment inline2 = DiffFragment.unchanged("xyz", "cba");
+    DiffFragment inline3 = new DiffFragment("  ", " ");
+    DiffFragment inline4 = DiffFragment.unchanged("098", "890");
+    DiffFragment[][] lines = new DiffFragment[][]{
+      first,
+      new DiffFragment[]{inline1, inline2},
+      new DiffFragment[]{inline3, inline4},
+      last};
+    lines = Util.uniteFormattingOnly(lines);
+    CHECK.compareAll(new DiffFragment[][]{
+      first,
+      new DiffFragment[]{inline1, inline2, inline3, inline4},
+      last},
+                     lines);
+  }
+
+  public void testConcatenateEquals() {
+    prepareForFragments();
+    DiffFragment fragments = Util.concatenate(new DiffFragment[]{
+      new DiffFragment("a", "a"),
+      DiffFragment.unchanged("1", "XY"),
+      DiffFragment.unchanged("2\n3", "Q\nW\nE")});
+    assertTrue(fragments.isEqual());
+    assertFalse(fragments.isOneSide());
+    assertEquals("a12\n3", fragments.getText1());
+    assertEquals("aXYQ\nW\nE", fragments.getText2());
+  }
+
+  public void testConcatenateModified() {
+    DiffFragment fragment = Util.concatenate(new DiffFragment[]{new DiffFragment("a", "b"),
+                                                                DiffFragment.unchanged("1", "1")});
+    assertTrue(fragment.isModified());
+  }
+
+  public void testConcatenateWithOneSide() {
+    DiffFragment fragment = Util.concatenate(new DiffFragment[]{new DiffFragment("1", "1"),
+                                                                new DiffFragment("a", null)});
+    assertTrue(fragment.isModified());
+    assertFalse(fragment.isOneSide());
+  }
+
+  public void testCutFirst() {
+    prepareForFragments();
+
+    CHECK.singleElement(Util.cutFirst(new DiffFragment[]{DiffFragment.unchanged("ab", "ac")}),
+                        DiffFragment.unchanged("b", "c"));
+
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(null, "c")},
+                     Util.cutFirst(new DiffFragment[]{new DiffFragment(null, "b"),
+                                                      new DiffFragment(null, "c"),
+                                                      new DiffFragment("a", null)})
+                     );
+
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(null, "b"), new DiffFragment(null, "d")},
+                     Util.cutFirst(new DiffFragment[]{new DiffFragment(null, "ab"), new DiffFragment("c", "d")}));
+
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilderTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/incrementalMerge/MergeBuilderTest.java
new file mode 100644 (file)
index 0000000..b97fa99
--- /dev/null
@@ -0,0 +1,134 @@
+package com.intellij.openapi.diff.impl.incrementalMerge;
+
+import com.intellij.idea.IdeaLogger;
+import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
+import com.intellij.openapi.diff.impl.util.ContextLogger;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.util.Assertion;
+import junit.framework.TestCase;
+
+import java.util.List;
+
+public class MergeBuilderTest extends TestCase {
+  private final MergeBuilder myMergeBuilder = new MergeBuilder(new ContextLogger("TEST"));
+  private final Assertion CHECK = new Assertion();
+
+  public void testEqual() {
+    addLeft(new TextRange(0, 1), new TextRange(0, 1));
+    addRight(new TextRange(0, 1), new TextRange(0, 1));
+    CHECK.empty(finish(1, 1, 1));
+  }
+
+  public void testWholeConflict() {
+    CHECK.singleElement(finish(1, 2, 3),
+                        fragment(new TextRange(0, 1), new TextRange(0, 2), new TextRange(0, 3)));
+  }
+
+  public void testTailInsert() {
+    TextRange range = new TextRange(0, 1);
+    addLeft(range, range);
+    addRight(range, range);
+    CHECK.singleElement(finish(1, 1, 2),
+                        fragment(null, new TextRange(1, 1), new TextRange(1, 2)));
+  }
+
+  public void testSameInsertsConflicts1() {
+    TextRange base = new TextRange(0, 1);
+    TextRange version = new TextRange(1, 2);
+    addLeft(base, version);
+    addRight(base, version);
+    CHECK.singleElement(finish(2, 1, 2),
+                        fragment(new TextRange(0, 1), new TextRange(0, 0), new TextRange(0, 1)));
+  }
+
+  public void testSameInsertsConflicts2() {
+    TextRange base = new TextRange(1, 2);
+    TextRange version = new TextRange(0, 1);
+    addLeft(base, version);
+    addRight(base, version);
+    CHECK.compareAll(new MergeBuilder.MergeFragment[]{
+      fragment(new TextRange(0, 0), new TextRange(0, 1), new TextRange(0, 0)),
+      fragment(new TextRange(1, 2), new TextRange(2, 2), new TextRange(1, 2))
+    }, finish(2, 2, 2));
+  }
+
+  private MergeBuilder.MergeFragment fragment(TextRange left, TextRange base, TextRange right) {
+    return new MergeBuilder.MergeFragment(new TextRange[]{left, base, right});
+  }
+
+  public void testHeadInsert() {
+    TextRange range = new TextRange(0, 1);
+    addRight(range, new TextRange(1, 2));
+    addLeft(range, range);
+    CHECK.singleElement(finish(1, 1, 2),
+                        fragment(null, new TextRange(0, 0), new TextRange(0, 1)));
+  }
+
+  public void testOneSideChange() {
+    addLeft(new TextRange(1, 2), new TextRange(2, 3));
+    addRight(new TextRange(0, 2), new TextRange(0, 2));
+    CHECK.singleElement(finish(3, 2, 2), fragment(new TextRange(0, 2), new TextRange(0, 1), null));
+  }
+
+  public void testNotAllignedConflict() {
+    addLeft(new TextRange(1, 3), new TextRange(0, 2));
+    addRight(new TextRange(2, 4), new TextRange(1, 3));
+    CHECK.compareAll(new MergeBuilder.MergeFragment[]{
+      fragment(new TextRange(0, 1), new TextRange(0, 2), new TextRange(0, 1)),
+      fragment(new TextRange(2, 3), new TextRange(3, 4), null)
+    }, finish(3, 4, 3));
+  }
+
+  public void testMultiChanges() {
+    addLeft(new TextRange(1, 8), new TextRange(1, 8));
+    addRight(new TextRange(1, 2), new TextRange(0, 1));
+    addRight(new TextRange(3, 4), new TextRange(1, 2));
+    addRight(new TextRange(4, 5), new TextRange(3, 4));
+    addRight(new TextRange(6, 7), new TextRange(5, 6));
+    addLeft(new TextRange(9, 10), new TextRange(9, 10));
+    CHECK.compareAll(new MergeBuilder.MergeFragment[]{
+      fragment(new TextRange(0, 1), new TextRange(0, 1), new TextRange(0, 0)),
+      fragment(null, new TextRange(2, 3), new TextRange(1, 1)),
+      fragment(null, new TextRange(4, 4), new TextRange(2, 3)),
+      fragment(null, new TextRange(5, 6), new TextRange(4, 5)),
+      fragment(new TextRange(7, 10), new TextRange(7, 10), new TextRange(6, 7))
+    }, finish(10, 10, 7));
+  }
+
+  public void testNoIntersection() {
+    addLeft(new TextRange(0, 1), new TextRange(0, 1));
+    addRight(new TextRange(0, 2), new TextRange(0, 2));
+    addLeft(new TextRange(3, 5), new TextRange(1, 3));
+    addRight(new TextRange(4, 5), new TextRange(2, 3));
+    CHECK.compareAll(new MergeBuilder.MergeFragment[]{
+      fragment(new TextRange(1, 2), new TextRange(1, 4), new TextRange(1, 2))
+    }, finish(3, 5, 3));
+  }
+
+  private void addRight(TextRange base, TextRange right) {
+    myMergeBuilder.add(base, right, FragmentSide.SIDE2);
+  }
+
+  private void addLeft(TextRange base, TextRange left) {
+    myMergeBuilder.add(base, left, FragmentSide.SIDE1);
+  }
+
+  private List<MergeBuilder.MergeFragment> finish(int left, int base, int right) {
+    return myMergeBuilder.finish(left, base, right);
+  }
+
+  @Override
+  protected void runTest() throws Throwable {
+    try {
+      super.runTest();
+    } finally {
+      if (IdeaLogger.ourErrorsOccurred != null) throw IdeaLogger.ourErrorsOccurred;
+    }
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    IdeaLogger.ourErrorsOccurred = null;
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/ByWordTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/ByWordTest.java
new file mode 100644 (file)
index 0000000..9421b4a
--- /dev/null
@@ -0,0 +1,149 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.diff.impl.ComparisonPolicy;
+import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
+import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.util.Assertion;
+import com.intellij.util.StringConvertion;
+import gnu.trove.Equality;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+public class ByWordTest extends TestCase {
+  private final Assertion CHECK = new Assertion(new FragmentStringConvertion());
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    CHECK.setEquality(new FragmentEquality());
+  }
+
+  public void test1() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments("abc def, 123", "ab def, 12");
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("abc", "ab"),
+                                        new DiffFragment(" def, ", " def, "),
+                                        new DiffFragment("123", "12")}, fragments);
+  }
+
+  public void test2() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments(" a[xy]+1", ",a[]+1");
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(" ", null),
+                                        new DiffFragment(null, ","),
+                                        new DiffFragment("a[", "a["),
+                                        new DiffFragment("xy", null),
+                                        new DiffFragment("]+1", "]+1")}, fragments);
+  }
+
+  public void test3() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments("0987\n  a.g();\n", "yyyy\n");
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("0987\n  a.g();\n", "yyyy\n")}, fragments);
+  }
+
+  public void test4() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments("  abc\n2222\n", "    x = abc\nzzzz\n");
+    CHECK.compareAll(new DiffFragment[]{
+      new DiffFragment(null, "  "), new DiffFragment("  ", "  "), new DiffFragment(null, "x"), new DiffFragment(null, " ="),
+      new DiffFragment(null, " "),
+      new DiffFragment("abc\n", "abc\n"),
+      new DiffFragment("2222", "zzzz"),
+      new DiffFragment("\n", "\n")}, fragments);
+  }
+
+  public void testIdea58505() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments("   if (eventMerger!=null && !dataSelection.getValueIsAdjusting()) {",
+                                                     "   if (eventMerger!=null && (dataSelection==null || !dataSelection.getValueIsAdjusting())) {");
+    CHECK.compareAll(new DiffFragment[] {
+      new DiffFragment("   if (eventMerger!=null && ", "   if (eventMerger!=null && "),
+      new DiffFragment("!", "("),
+      new DiffFragment("dataSelection", "dataSelection"),
+      new DiffFragment(null, "=="),
+      new DiffFragment(null, "null || !dataSelection"),
+      new DiffFragment(".getValueIsAdjusting())", ".getValueIsAdjusting())"),
+      new DiffFragment(null, ")"),
+      new DiffFragment(" {", " {")
+    }, fragments);
+  }
+
+  public void testExtractWords() {
+    String text = "a b, c.d\n\n  x\n y";
+    Word[] words = ByWord.buildWords(text, ComparisonPolicy.DEFAULT);
+    CHECK.setEquality(new Equality() {
+      @Override
+      public boolean equals(Object o1, Object o2) {
+        Word word1 = (Word)o1;
+        Word word2 = (Word)o2;
+        return word1.getStart() == word2.getStart() && word1.getEnd() == word2.getEnd();
+      }
+    });
+    CHECK.setStringConvertion(StringConvertion.DEFAULT);
+    CHECK.compareAll(new Word[]{new Formatting(text, new TextRange(0, 0)),
+                                new Word(text, new TextRange(0, 1)),
+                                new Word(text, new TextRange(2, 3)),
+                                new Word(text, new TextRange(5, 6)),
+                                new Word(text, new TextRange(7, 8)),
+                                new Formatting(text, new TextRange(8, 12)),
+                                new Word(text, new TextRange(12, 13)),
+                                new Formatting(text, new TextRange(13, 15)),
+                                new Word(text, new TextRange(15, 16))}, words);
+    text = " b c";
+    words = ByWord.buildWords(text, ComparisonPolicy.DEFAULT);
+    CHECK.compareAll(new Word[]{new Formatting(text, new TextRange(0, 1)),
+                                new Word(text, new TextRange(1, 2)),
+                                new Word(text, new TextRange(3, 4))}, words);
+  }
+
+  public void testLeadingFormatting() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments(" abc\n 123", " 123");
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(" abc\n", null),
+                                        new DiffFragment(" 123", " 123")},
+                     UniteSameType.INSTANCE.correct(fragments));
+  }
+
+  public void testRestyleNewLines() {
+    DiffPolicy byWord = new ByWord(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = byWord.buildFragments("f(a, b);", "f(a,\n  b);");
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("f(a,", "f(a,"),
+                                        new DiffFragment(" ", "\n  "),
+                                        new DiffFragment("b);", "b);")},
+                     UniteSameType.INSTANCE.correct(fragments));
+  }
+
+  public void testIgnoreSpaces() {
+    ByWord byWord = new ByWord(ComparisonPolicy.IGNORE_SPACE);
+    DiffFragment[] fragments = byWord.buildFragments(" o.f(a)", "o. f( b)");
+    CHECK.compareAll(new DiffFragment[]{DiffFragment.unchanged(" o.f(", "o. f( "),
+                                        new DiffFragment("a", "b"),
+                                        DiffFragment.unchanged(")", ")")},
+                     UniteSameType.INSTANCE.correct(fragments));
+  }
+
+  public void testIgnoreLeadingAndTrailing() {
+    ByWord byWord = new ByWord(ComparisonPolicy.TRIM_SPACE);
+    checkEqual(byWord.buildFragments(" text", "text"));
+    checkEqual(byWord.buildFragments("text ", "text"));
+    checkEqual(byWord.buildFragments(" text \n", "text\n"));
+    //DiffFragment[] fragments = byWord.buildFragments(" 123 ", "xyz");
+    //CHECK.compareAll(new DiffFragment[]{DiffFragment.unchanged(" ", ""),
+    //                                    new DiffFragment("123", "xyz"),
+    //                                    DiffFragment.unchanged(" ", "")},
+    //                 fragments);
+  }
+
+  private void checkEqual(DiffFragment[] fragments) {
+    try {
+      assertEquals(1, fragments.length);
+      assertTrue(fragments[0].isEqual());
+    } catch(AssertionFailedError e) {
+      CHECK.enumerate(fragments);
+      throw e;
+    }
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/CorrectionTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/CorrectionTest.java
new file mode 100644 (file)
index 0000000..eeb9716
--- /dev/null
@@ -0,0 +1,102 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.diff.impl.ComparisonPolicy;
+import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
+import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
+import com.intellij.util.Assertion;
+import junit.framework.TestCase;
+
+public class CorrectionTest extends TestCase {
+  private final Assertion CHECK = new Assertion(new FragmentStringConvertion());
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    CHECK.setEquality(new FragmentEquality());
+  }
+
+  public void testTrueLineBlock() {
+    DiffCorrection.TrueLineBlocks correction = new DiffCorrection.TrueLineBlocks(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = correction.correctAndNormalize(new DiffFragment[]{
+      DiffFragment.unchanged(" 1\n  ab\n x\n", "  2\n ab\n x\n"),
+      new DiffFragment("XXX\n111\n", "YYY\n222\n"),
+      DiffFragment.unchanged(" a\n", "  a\n")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(" 1\n", "  2\n"),
+                                        new DiffFragment("  ab\n", " ab\n"),
+                                        new DiffFragment(" x\n", " x\n"),
+                                        new DiffFragment("XXX\n111\n", "YYY\n222\n"),
+                                        new DiffFragment(" a\n", "  a\n")},
+                     fragments);
+  }
+
+  public void testTrueLineBlocksWithSameLines() {
+    DiffCorrection.TrueLineBlocks correction = new DiffCorrection.TrueLineBlocks(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = correction.correctAndNormalize(new DiffFragment[]{
+      DiffFragment.unchanged(" X\n  X\n  X", "  X\n X\n  X")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(" X\n  X\n", "  X\n X\n"),
+                                        new DiffFragment("  X", "  X")},
+                     fragments);
+  }
+
+  public void testChangedSpaceCorrection() {
+    DiffCorrection correction = new DiffCorrection.ChangedSpace(ComparisonPolicy.DEFAULT);
+    DiffFragment[] fragments = correction.correct(new DiffFragment[]{
+        new DiffFragment("x", "y"),
+        new DiffFragment(" ", "   "),
+        new DiffFragment("ab", "ab"),
+        new DiffFragment(" ", " "),
+        new DiffFragment(" ", " w o r d"),
+        new DiffFragment("   ", " w o r d")});
+    CHECK.compareAll(new DiffFragment[]{
+      new DiffFragment("x", "y"),
+      new DiffFragment(null, "  "), new DiffFragment(" ", " "),
+      new DiffFragment("ab", "ab"),
+      new DiffFragment(" ", " "),
+      new DiffFragment(" ", " "), new DiffFragment(null, "w o r d"),
+      new DiffFragment("  ", null), new DiffFragment(" ", " "), new DiffFragment(null, "w o r d")}, fragments);
+
+    fragments = correction.correct(new DiffFragment[]{new DiffFragment("\n  ", "\n ")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("\n", "\n"),
+                                        new DiffFragment(" ", null), new DiffFragment(" ", " ")}, fragments);
+    fragments = correction.correct(new DiffFragment[]{new DiffFragment("\n", "\n\n")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("\n", "\n"), new DiffFragment(null, "\n")}, fragments);
+  }
+
+  public void testConcatinateSingleSide() {
+    DiffCorrection correction = new DiffCorrection.ConcatenateSingleSide();
+    DiffFragment[] corrected = correction.correct(
+        new DiffFragment[]{new DiffFragment(null, "a"),
+                           new DiffFragment("b", null),
+                           new DiffFragment("c", "d"),
+                           new DiffFragment(null, "a"),
+                           new DiffFragment("b", null),
+                           new DiffFragment("1", null),
+                           new DiffFragment("x", "x"),
+                           new DiffFragment(null, "a")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("b", "a"),
+                                        new DiffFragment("c", "d"),
+                                        new DiffFragment("b1", "a"),
+                                        new DiffFragment("x", "x"), new DiffFragment(null, "a")},
+                     corrected);
+  }
+
+  public void testConnectSingleSideToChange() {
+    DiffFragment first = DiffFragment.unchanged("a", "A");
+    DiffFragment oneSide = new DiffFragment(null, "b");
+    DiffFragment equal = new DiffFragment("c", "c");
+    DiffFragment last = DiffFragment.unchanged("g", "G");
+    DiffFragment[] fragments = DiffCorrection.ConnectSingleSideToChange.INSTANCE.correct(new DiffFragment[]{
+      first,
+      oneSide,
+      equal,
+      new DiffFragment(null, "d"), new DiffFragment("e", "E"), new DiffFragment("f", null),
+      last
+    });
+    CHECK.compareAll(new DiffFragment[]{
+      first, oneSide, equal,
+      new DiffFragment("ef", "dE"),
+      last
+    }, fragments);
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/LineBlocksDiffPolicyTest.java
new file mode 100644 (file)
index 0000000..ecf19a1
--- /dev/null
@@ -0,0 +1,23 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.diff.impl.ComparisonPolicy;
+import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
+import com.intellij.openapi.diff.impl.highlighting.Util;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class LineBlocksDiffPolicyTest extends TestCase{
+  public void test() {
+    DiffPolicy.LineBlocks diffPolicy = new DiffPolicy.LineBlocks(ComparisonPolicy.DEFAULT);
+    checkPolicy(diffPolicy, "abc\n123\n", "ABC\nXYZ\n");
+    checkPolicy(diffPolicy, "abc\n123", "ABC\nXYZ");
+    checkPolicy(diffPolicy, "abc\n123\n", "ABC\nXYZ");
+  }
+
+  private void checkPolicy(DiffPolicy.LineBlocks diffPolicy, String text1, String text2) {
+    DiffFragment[] fragments = diffPolicy.buildFragments(text1, text2);
+    Assert.assertEquals(text1, Util.getText(fragments, FragmentSide.SIDE1));
+    assertEquals(text2, Util.getText(fragments, FragmentSide.SIDE2));
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/NormalizationTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/NormalizationTest.java
new file mode 100644 (file)
index 0000000..9bc447c
--- /dev/null
@@ -0,0 +1,44 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
+import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
+import com.intellij.util.Assertion;
+import junit.framework.TestCase;
+
+public class NormalizationTest extends TestCase {
+  private final Assertion CHECK = new Assertion(new FragmentStringConvertion());
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    CHECK.setEquality(new FragmentEquality());
+  }
+
+  public void testSingleSide() {
+    DiffCorrection correction = DiffCorrection.Normalize.INSTANCE;
+    DiffFragment[] corrected = correction.correct(
+        new DiffFragment[]{new DiffFragment(null, "a"),
+                           new DiffFragment("b", null),
+                           new DiffFragment("c", "d"),
+                           new DiffFragment(null, "a"),
+                           new DiffFragment("b", null),
+                           new DiffFragment("1", null),
+                           new DiffFragment("x", "x"),
+                           new DiffFragment(null, "a")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("b", "a"),
+                                        new DiffFragment("c", "d"),
+                                        new DiffFragment("b1", "a"),
+                                        new DiffFragment("x", "x"), new DiffFragment(null, "a")},
+                     corrected);
+  }
+
+  public void testUnitesEquals() {
+    DiffCorrection correction = DiffCorrection.Normalize.INSTANCE;
+    DiffFragment[] fragments = correction.correct(new DiffFragment[]{new DiffFragment(null, "a"),
+                                            new DiffFragment("x", "x"),
+                                            new DiffFragment("y", "y"),
+                                            new DiffFragment("z", null), new DiffFragment(null, "z")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment(null, "a"), new DiffFragment("xyz", "xyz")}, fragments);
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/PreferWholeLinesTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/PreferWholeLinesTest.java
new file mode 100644 (file)
index 0000000..a798bd9
--- /dev/null
@@ -0,0 +1,12 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import junit.framework.TestCase;
+
+public class PreferWholeLinesTest extends TestCase {
+  public void test() {
+    DiffFragment[] fragments = new DiffFragment[]{new DiffFragment("1", "2"), new DiffFragment(null, "\nadded"), new DiffFragment("a", "\nb")};
+    fragments = new PreferWholeLines().correct(fragments);
+
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/TextCompareProcessorTest.java
new file mode 100644 (file)
index 0000000..2c74a0b
--- /dev/null
@@ -0,0 +1,16 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.impl.ComparisonPolicy;
+import com.intellij.openapi.diff.impl.fragments.LineFragment;
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+
+public class TextCompareProcessorTest extends TestCase {
+  public void testIgnoreWrappingEqualText() {
+    TextCompareProcessor processor = new TextCompareProcessor(ComparisonPolicy.IGNORE_SPACE);
+    ArrayList<LineFragment> lineFragments = processor.process("f(a, b)\n", "f(a,\nb)\n");
+    assertTrue(lineFragments.size() == 1);
+    assertNull(lineFragments.get(0).getType());
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/UniteSameTypeTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/processing/UniteSameTypeTest.java
new file mode 100644 (file)
index 0000000..787bc2a
--- /dev/null
@@ -0,0 +1,35 @@
+package com.intellij.openapi.diff.impl.processing;
+
+import com.intellij.openapi.diff.ex.DiffFragment;
+import com.intellij.openapi.diff.impl.highlighting.FragmentEquality;
+import com.intellij.openapi.diff.impl.highlighting.FragmentStringConvertion;
+import com.intellij.util.Assertion;
+import junit.framework.TestCase;
+
+public class UniteSameTypeTest extends TestCase {
+  private final Assertion CHECK = new Assertion(new FragmentStringConvertion());
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+    CHECK.setEquality(new FragmentEquality());
+  }
+
+  public void testUnitDifferentOnesides() {
+    DiffFragment[] fragments = UniteSameType.INSTANCE.correct(new DiffFragment[]{new DiffFragment("a", "b"),
+                                                        new DiffFragment(null, " "),
+                                                        new DiffFragment("\n ", null),
+                                                        new DiffFragment("x", "x")});
+    CHECK.compareAll(new DiffFragment[]{new DiffFragment("a\n ", "b "), new DiffFragment("x", "x")}, fragments);
+  }
+
+  public void testUniteEqualsUnitesFormattingOnly() {
+    DiffFragment changed = new DiffFragment("abc", "123");
+    DiffFragment equal = new DiffFragment("qqq", "qqq");
+    DiffFragment[] fragments = DiffCorrection.UnitEquals.INSTANCE.correct(new DiffFragment[]{
+      changed,
+      new DiffFragment(" xxx", "xxx"), new DiffFragment("yyy", "  yyy"),
+      equal});
+    CHECK.compareAll(new DiffFragment[]{changed, new DiffFragment(" xxxyyy", "xxx  yyy"), equal}, fragments);
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/splitter/LineBlocksTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/splitter/LineBlocksTest.java
new file mode 100644 (file)
index 0000000..b96b2e3
--- /dev/null
@@ -0,0 +1,60 @@
+package com.intellij.openapi.diff.impl.splitter;
+
+import com.intellij.openapi.diff.impl.fragments.LineBlock;
+import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
+import junit.framework.TestCase;
+
+public class LineBlocksTest extends TestCase {
+  public void testVisibles() {
+    LineBlocks lineBlocks = LineBlocks.createLineBlocks(new LineBlock[]{new LineBlock(0, 1, 2, 1, null), new LineBlock(2, 1, 4, 1, null)});
+    Interval indecies = lineBlocks.getVisibleIndices(new Trapezium(1, 1, 2, 1));
+    assertEquals(Interval.fromTo(0, 1), indecies);
+    assertEquals(new Trapezium(0, 1, 2, 1), lineBlocks.getTrapezium(indecies.getStart()));
+
+    indecies = lineBlocks.getVisibleIndices(new Trapezium(4, 2, 4, 3));
+    assertEquals(Interval.fromTo(1, 2), indecies);
+    assertEquals(new Trapezium(2, 1, 4, 1), lineBlocks.getTrapezium(indecies.getStart()));
+
+    indecies = lineBlocks.getVisibleIndices(new Trapezium(3, 1, 3, 1));
+    assertEquals(Interval.fromTo(1, 2), indecies);
+    assertEquals(new Trapezium(2, 1, 4, 1), lineBlocks.getTrapezium(indecies.getStart()));
+  }
+
+  public void testIndecies() {
+    Interval[] intervals = new Interval[]{new Interval(1, 2), new Interval(4, 2), new Interval(6, 2)};
+
+    assertEquals(0, LineBlocks.getMaxStartedIndex(intervals, 0));
+    assertEquals(0, LineBlocks.getMaxStartedIndex(intervals, 1));
+    assertEquals(0, LineBlocks.getMaxStartedIndex(intervals, 2));
+    assertEquals(1, LineBlocks.getMaxStartedIndex(intervals, 3));
+    assertEquals(1, LineBlocks.getMaxStartedIndex(intervals, 4));
+
+    assertEquals(1, LineBlocks.getMinNotStartedIndex(intervals, 2));
+    assertEquals(1, LineBlocks.getMinNotStartedIndex(intervals, 3));
+    assertEquals(2, LineBlocks.getMinNotStartedIndex(intervals, 6));
+    assertEquals(3, LineBlocks.getMinNotStartedIndex(intervals, 7));
+  }
+
+  public void testLineNumberTransformation() {
+    LineBlocks lineBlocks = LineBlocks.createLineBlocks(new LineBlock[]{
+        new LineBlock(2, 2, 2, 2, null),
+        new LineBlock(6, 1, 6, 2, null),
+        new LineBlock(8, 2, 9, 0, null)});
+
+    checkLeftRight(lineBlocks, 0, 0);
+    checkLeftRight(lineBlocks, 3, 3);
+    checkLeftRight(lineBlocks, 5, 5);
+    checkLeftRight(lineBlocks, 6, 6);
+    assertEquals(6, lineBlocks.transform(FragmentSide.SIDE2, 7));
+    checkLeftRight(lineBlocks, 7, 8);
+    checkLeftRight(lineBlocks, 8, 9);
+    assertEquals(9, lineBlocks.transform(FragmentSide.SIDE1, 9));
+    assertEquals(9, lineBlocks.transform(FragmentSide.SIDE1, 10));
+    checkLeftRight(lineBlocks, 11, 10);
+  }
+
+  private void checkLeftRight(LineBlocks lineBlocks, int left, int right) {
+    assertEquals(right, lineBlocks.transform(FragmentSide.SIDE1, left));
+    assertEquals(left, lineBlocks.transform(FragmentSide.SIDE2, right));
+  }
+}
diff --git a/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/splitter/TransformationTest.java b/platform/platform-impl/testSrc/com/intellij/openapi/diff/impl/splitter/TransformationTest.java
new file mode 100644 (file)
index 0000000..1f90233
--- /dev/null
@@ -0,0 +1,18 @@
+package com.intellij.openapi.diff.impl.splitter;
+
+import junit.framework.TestCase;
+
+public class TransformationTest extends TestCase {
+  public void testLinear() {
+    Transformation transformation = new LinearTransformation(8, 5);
+    assertEquals(-3, transformation.transform(1));
+    assertEquals(2, transformation.transform(2));
+  }
+
+  public void testOneToOne() {
+    Interval range = Interval.fromTo(10, 12);
+    assertEquals(10, LinearTransformation.oneToOne(1, 1, range));
+    assertEquals(11, LinearTransformation.oneToOne(2, 1, range));
+    assertEquals(11, LinearTransformation.oneToOne(3, 1, range));
+  }
+}
index 8fd86d758442dd2aecc6497146109f20b76cd772..5ba696d3db73d6a6d4924b49904b7f38022af824 100644 (file)
@@ -26,7 +26,7 @@ diff.element.qualified.name.vs.element.qualified.name.dialog.title={0} vs {1}
 diff.acton.ignore.qhitespace.policy.do.not.ignore=Do not ignore
 diff.acton.ignore.qhitespace.policy.leading.and.trailing=Leading and trailing
 diff.acton.ignore.qhitespace.policy.all=All
-ignore.whitespace.action.not.avaliable.action.name=<Not avaliable>
+ignore.whitespace.action.not.avaliable.action.name=<Not available>
 diff.dialog.select.change.action.name=Select Change
 diff.dialog.select.change.action.description=Select changed text in this version and corresponding in other
 merge.files.dialog.title=Merge
@@ -71,7 +71,7 @@ merge.init.merge.content.command.name=initMergeContent
 merge.color.options.stripe.mark.color.label=&Stripe mark color:
 merge.color.options.background.color.label=Background &color:
 merge.color.options.dialog.title=Merge Color Options
-diff.content.read.only.content.title.suffix= (Read-only)
+diff.content.read.only.content.title.suffix=(Read-only)
 diff.type.inserted.name=Inserted
 diff.type.changed.name=Changed
 diff.type.deleted.name=Deleted