/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.text.tests; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.eclipse.text.edits.CopySourceEdit; import org.eclipse.text.edits.CopyTargetEdit; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.ISourceModifier; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.MoveSourceEdit; import org.eclipse.text.edits.MoveTargetEdit; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.RangeMarker; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; import org.eclipse.text.edits.TextEditCopier; import org.eclipse.text.edits.UndoEdit; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; public class TextEditTests { private IDocument fDocument; private MultiTextEdit fRoot; @Before public void setUp() { fDocument= new Document("0123456789"); fRoot= new MultiTextEdit(); } @After public void tearDown() { fRoot= null; fRoot= null; } @Test public void testCovers1() throws Exception { InsertEdit insert= new InsertEdit(1, ""); DeleteEdit delete= new DeleteEdit(2, 2); Assert.assertEquals(false, insert.covers(delete)); } @Test public void testCovers2() throws Exception { MultiTextEdit multi= new MultiTextEdit(0,0); MultiTextEdit child= new MultiTextEdit(0,0); Assert.assertEquals(true, multi.covers(child)); } @Test public void testOverlap1() throws Exception { // [ [ ] ] fRoot.addChild(new ReplaceEdit(0, 2, "01")); boolean exception= false; try { fRoot.addChild(new ReplaceEdit(1, 2, "12")); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap2() throws Exception { // [[ ] ] fRoot.addChild(new ReplaceEdit(0, 2, "01")); boolean exception= false; try { fRoot.addChild(new ReplaceEdit(0, 1, "0")); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap3() throws Exception { // [ [ ]] fRoot.addChild(new ReplaceEdit(0, 2, "01")); boolean exception= false; try { fRoot.addChild(new ReplaceEdit(1, 1, "1")); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap4() throws Exception { // [ [ ] ] fRoot.addChild(new ReplaceEdit(0, 3, "012")); boolean exception= false; try { fRoot.addChild(new ReplaceEdit(1, 1, "1")); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap5() throws Exception { // [ [] ] fRoot.addChild(new ReplaceEdit(0, 3, "012")); boolean exception= false; try { fRoot.addChild(new InsertEdit(1, "xx")); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap6() throws Exception { // [ [] ] fRoot.addChild(new ReplaceEdit(0, 3, "012")); boolean exception= false; try { fRoot.addChild(new InsertEdit(2, "xx")); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap7() throws Exception { MoveSourceEdit source= new MoveSourceEdit(2, 5); MoveTargetEdit target= new MoveTargetEdit(3, source); fRoot.addChild(source); boolean exception= false; try { fRoot.addChild(target); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap8() throws Exception { MoveSourceEdit source= new MoveSourceEdit(2, 5); MoveTargetEdit target= new MoveTargetEdit(6, source); fRoot.addChild(source); boolean exception= false; try { fRoot.addChild(target); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testOverlap9() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(3, 1); MoveTargetEdit t1= new MoveTargetEdit(7, s1); MoveSourceEdit s2= new MoveSourceEdit(2, 3); MoveTargetEdit t2= new MoveTargetEdit(8, s2); fRoot.addChild(s1); fRoot.addChild(t1); boolean exception= false; try { fRoot.addChild(s2); fRoot.addChild(t2); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testUndefinedMultiEdit1() throws Exception { MultiTextEdit m1= new MultiTextEdit(); m1.addChild(new InsertEdit(0,"")); fRoot.addChild(m1); MultiTextEdit m2= new MultiTextEdit(); m2.addChild(new InsertEdit(2, "")); fRoot.addChild(m2); } @Test public void testUndefinedMultiEdit2() throws Exception { MultiTextEdit m1= new MultiTextEdit(); MultiTextEdit m2= new MultiTextEdit(); assertTrue(m1.covers(m2)); assertTrue(m2.covers(m1)); } @Test public void testUndefinedMultiEdit3() throws Exception { MultiTextEdit m2= new MultiTextEdit(); Assert.assertEquals(0, m2.getOffset()); Assert.assertEquals(0, m2.getLength()); m2.addChild(new DeleteEdit(1,3)); Assert.assertEquals(1, m2.getOffset()); Assert.assertEquals(3, m2.getLength()); } @Test public void testUndefinedMultiEdit4() throws Exception { MultiTextEdit m2= new MultiTextEdit(); m2.addChild(new DeleteEdit(1,3)); m2.addChild(new DeleteEdit(4, 2)); Assert.assertEquals(1, m2.getOffset()); Assert.assertEquals(5, m2.getLength()); } @Test public void testUndefinedMultiEdit5() throws Exception { MultiTextEdit m2= new MultiTextEdit(); m2.addChild(new DeleteEdit(4, 2)); m2.addChild(new DeleteEdit(1,3)); Assert.assertEquals(1, m2.getOffset()); Assert.assertEquals(5, m2.getLength()); } @Test public void testUndefinedMultiEdit6() throws Exception { DeleteEdit d1= new DeleteEdit(1,3); MultiTextEdit m2= new MultiTextEdit(); assertTrue(d1.covers(m2)); } @Test public void testUnconnected1() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(3, 1); boolean exception= false; try { fRoot.addChild(s1); fRoot.apply(fDocument); } catch (MalformedTreeException e) { exception= true; } assertTrue(exception); } @Test public void testBufferLength() throws Exception { MultiTextEdit edit= new MultiTextEdit(0, fDocument.getLength() + 1); boolean exception= false; try { fRoot.addChild(edit); fRoot.apply(fDocument); } catch (MalformedTreeException e) { exception= true; assertTrue(exception); } } @Test public void testCopy1() throws Exception { MultiTextEdit root= new MultiTextEdit(); TextEdit e1= new InsertEdit(2, "yy"); TextEdit e2= new ReplaceEdit(2, 3, "3456"); root.addChild(e1); root.addChild(e2); List<TextEdit> org= flatten(root); TextEditCopier copier= new TextEditCopier(root); List<TextEdit> copy= flatten(copier.perform()); compare(org, copy); } @Test public void testCopy2() throws Exception { MultiTextEdit root= new MultiTextEdit(); CopySourceEdit s1= new CopySourceEdit(5, 2); CopyTargetEdit t1= new CopyTargetEdit(8, s1); CopySourceEdit s2= new CopySourceEdit(5, 2); CopyTargetEdit t2= new CopyTargetEdit(2, s2); s1.addChild(s2); root.addChild(s1); root.addChild(t1); root.addChild(t2); List<TextEdit> org= flatten(root); TextEditCopier copier= new TextEditCopier(root); List<TextEdit> copy= flatten(copier.perform()); compare(org, copy); } private List<TextEdit> flatten(TextEdit edit) { List<TextEdit> result= new ArrayList<>(); flatten(result, edit); return result; } private static void flatten(List<TextEdit> result, TextEdit edit) { result.add(edit); TextEdit[] children= edit.getChildren(); for (int i= 0; i < children.length; i++) { flatten(result, children[i]); } } private static void compare(List<TextEdit> org, List<TextEdit> copy) { assertTrue("Same length", org.size() == copy.size()); for (Iterator<TextEdit> iter= copy.iterator(); iter.hasNext();) { TextEdit edit= iter.next(); assertTrue("Original is part of copy list", !org.contains(edit)); if (edit instanceof MoveSourceEdit) { MoveSourceEdit source= (MoveSourceEdit)edit; assertTrue("Target edit isn't a copy", copy.contains(source.getTargetEdit())); assertTrue("Traget edit is a original", !org.contains(source.getTargetEdit())); } else if (edit instanceof MoveTargetEdit) { MoveTargetEdit target= (MoveTargetEdit)edit; assertTrue("Source edit isn't a copy", copy.contains(target.getSourceEdit())); assertTrue("Source edit is a original", !org.contains(target.getSourceEdit())); } else if (edit instanceof CopySourceEdit) { CopySourceEdit source= (CopySourceEdit)edit; assertTrue("Target edit isn't a copy", copy.contains(source.getTargetEdit())); assertTrue("Traget edit is a original", !org.contains(source.getTargetEdit())); } else if (edit instanceof CopyTargetEdit) { CopyTargetEdit target= (CopyTargetEdit)edit; assertTrue("Source edit isn't a copy", copy.contains(target.getSourceEdit())); assertTrue("Source edit is a original", !org.contains(target.getSourceEdit())); } } } @Test public void testInsert1() throws Exception { // [][ ] TextEdit e1= new InsertEdit(2, "yy"); TextEdit e2= new ReplaceEdit(2, 3, "3456"); fRoot.addChild(e1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 2, 6); assertEquals(e1, 2, 2); assertEquals(e2, 4, 4); Assert.assertEquals("Buffer content", "01yy345656789", fDocument.get()); doUndoRedo(undo, "01yy345656789"); } @Test public void testInsert2() throws Exception { // [][] TextEdit e1= new InsertEdit(2, "yy"); TextEdit e2= new InsertEdit(2, "xx"); fRoot.addChild(e1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 2, 4); assertEquals(e1, 2, 2); assertEquals(e2, 4, 2); Assert.assertEquals("Buffer content", "01yyxx23456789", fDocument.get()); doUndoRedo(undo, "01yyxx23456789"); } @Test public void testInsert3() throws Exception { // [ ][][ ] TextEdit e1= new ReplaceEdit(0, 2, "011"); TextEdit e2= new InsertEdit(2, "xx"); TextEdit e3= new ReplaceEdit(2, 2, "2"); fRoot.addChild(e1); fRoot.addChild(e2); fRoot.addChild(e3); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 0, 6); assertEquals(e1, 0, 3); assertEquals(e2, 3, 2); assertEquals(e3, 5, 1); Assert.assertEquals("Buffer content", "011xx2456789", fDocument.get()); doUndoRedo(undo, "011xx2456789"); } @Test public void testInsert4() throws Exception { TextEdit e1= new InsertEdit(0, "xx"); fRoot.addChild(e1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer length", 12, fDocument.getLength()); assertEquals(fRoot, 0, 2); assertEquals(e1, 0, 2); Assert.assertEquals("Buffer content", "xx0123456789", fDocument.get()); doUndoRedo(undo, "xx0123456789"); } @Test public void testInsert5() throws Exception { TextEdit e1= new InsertEdit(10, "xx"); fRoot.addChild(e1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer length", 12, fDocument.getLength()); assertEquals(fRoot, 10, 2); assertEquals(e1, 10, 2); Assert.assertEquals("Buffer content", "0123456789xx", fDocument.get()); doUndoRedo(undo, "0123456789xx"); } @Test public void testInsertReplace1() throws Exception { TextEdit e1= new ReplaceEdit(2, 1, "y"); TextEdit e2= new InsertEdit(2, "xx"); fRoot.addChild(e1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 2, 3); assertEquals(e1, 4, 1); assertEquals(e2, 2, 2); Assert.assertEquals("Buffer content", "01xxy3456789", fDocument.get()); doUndoRedo(undo, "01xxy3456789"); } @Test public void testDelete1() throws Exception { TextEdit e1= new DeleteEdit(3, 1); fRoot.addChild(e1); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 3, 0); assertEquals(e1, 3, 0); Assert.assertEquals("Buffer content", "012456789", fDocument.get()); doUndoRedo(undo, "012456789"); } @Test public void testDelete2() throws Exception { TextEdit e1= new DeleteEdit(4, 1); TextEdit e2= new DeleteEdit(3, 1); TextEdit e3= new DeleteEdit(5, 1); fRoot.addChild(e1); fRoot.addChild(e2); fRoot.addChild(e3); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 3, 0); assertEquals(e1, 3, 0); assertEquals(e2, 3, 0); assertEquals(e3, 3, 0); Assert.assertEquals("Buffer content", "0126789", fDocument.get()); doUndoRedo(undo, "0126789"); } @Test public void testDelete3() throws Exception { TextEdit e1= new InsertEdit(3, "x"); TextEdit e2= new DeleteEdit(3, 1); fRoot.addChild(e1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(fRoot, 3, 1); assertEquals(e1, 3, 1); assertEquals(e2, 4, 0); Assert.assertEquals("Buffer content", "012x456789", fDocument.get()); doUndoRedo(undo, "012x456789"); } @Test public void testDeleteWithChildren() throws Exception { TextEdit e1= new DeleteEdit(2, 6); MultiTextEdit e2= new MultiTextEdit(3, 3); e1.addChild(e2); TextEdit e3= new ReplaceEdit(3, 1, "xx"); TextEdit e4= new ReplaceEdit(5, 1, "yy"); e2.addChild(e3); e2.addChild(e4); fRoot.addChild(e1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0189", fDocument.get()); assertEquals(fRoot, 2, 0); assertEquals(e1, 2, 0); assertTrue(e2.isDeleted()); assertTrue(e3.isDeleted()); assertTrue(e4.isDeleted()); doUndoRedo(undo, "0189"); } @Test public void testTreeUpdate1() throws Exception { MultiTextEdit m1= new MultiTextEdit(); TextEdit e1= new InsertEdit(2, "aa"); TextEdit e2= new InsertEdit(4, "bb"); m1.addChild(e1); m1.addChild(e2); MultiTextEdit m2= new MultiTextEdit(); TextEdit e3= new InsertEdit(6, "cc"); TextEdit e4= new InsertEdit(8, "dd"); m2.addChild(e3); m2.addChild(e4); fRoot.addChild(m1); fRoot.addChild(m2); assertEquals(m1, 2, 2); assertEquals(m2, 6, 2); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "01aa23bb45cc67dd89", fDocument.get()); assertEquals(e1, 2, 2); assertEquals(e2, 6, 2); assertEquals(e3, 10, 2); assertEquals(e4, 14, 2); assertEquals(m1, 2, 6); assertEquals(m2, 10, 6); assertEquals(fRoot, 2, 14); doUndoRedo(undo, "01aa23bb45cc67dd89"); } @Test public void testMove1() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(5, s1); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0142356789", fDocument.get()); assertEquals(s1, 2, 0); assertEquals(t1, 3, 2); doUndoRedo(undo, "0142356789"); } @Test public void testMove2() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(5, 2); MoveTargetEdit t1= new MoveTargetEdit(2, s1); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0156234789", fDocument.get()); assertEquals(s1, 7, 0); assertEquals(t1, 2, 2); doUndoRedo(undo, "0156234789"); } @Test public void testMove3() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(7, s1); TextEdit e2= new ReplaceEdit(4, 1, "x"); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "01x5623789", fDocument.get()); assertEquals(s1, 2, 0); assertEquals(t1, 5, 2); assertEquals(e2, 2, 1); doUndoRedo(undo, "01x5623789"); } @Test public void testMove4() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(7, 2); MoveTargetEdit t1= new MoveTargetEdit(2, s1); TextEdit e2= new ReplaceEdit(5, 1, "x"); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0178234x69", fDocument.get()); assertEquals(s1, 9, 0); assertEquals(t1, 2, 2); assertEquals(e2, 7, 1); doUndoRedo(undo, "0178234x69"); } @Test public void testMove5() throws Exception { // Move onto itself MoveSourceEdit s1= new MoveSourceEdit(2, 1); MoveTargetEdit t1= new MoveTargetEdit(3, s1); TextEdit e2= new ReplaceEdit(2, 1, "x"); s1.addChild(e2); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 2, 0); assertEquals(t1, 2, 1); assertEquals(e2, 2, 1); Assert.assertEquals("Buffer content", "01x3456789", fDocument.get()); doUndoRedo(undo, "01x3456789"); } @Test public void testMove6() throws Exception { // Move onto itself MoveSourceEdit s1= new MoveSourceEdit(2, 1); MoveTargetEdit t1= new MoveTargetEdit(2, s1); TextEdit e2= new ReplaceEdit(2, 1, "x"); s1.addChild(e2); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 3, 0); assertEquals(t1, 2, 1); assertEquals(e2, 2, 1); Assert.assertEquals("Buffer content", "01x3456789", fDocument.get()); doUndoRedo(undo,"01x3456789"); } @Test public void testMove7() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 3); MoveTargetEdit t1= new MoveTargetEdit(7, s1); TextEdit e2= new ReplaceEdit(3, 1, "x"); s1.addChild(e2); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "01562x4789", fDocument.get()); assertEquals(s1, 2, 0); assertEquals(t1, 4, 3); assertEquals(e2, 5, 1); doUndoRedo(undo, "01562x4789"); } @Test public void testMove8() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(5, 3); MoveTargetEdit t1= new MoveTargetEdit(1, s1); TextEdit e2= new ReplaceEdit(6, 1, "x"); s1.addChild(e2); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "05x7123489", fDocument.get()); assertEquals(s1, 8, 0); assertEquals(t1, 1, 3); assertEquals(e2, 2, 1); doUndoRedo(undo, "05x7123489"); } @Test public void testMove9() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(1, 3); MoveTargetEdit t1= new MoveTargetEdit(5, s1); MoveSourceEdit s2= new MoveSourceEdit(1, 1); MoveTargetEdit t2= new MoveTargetEdit(3, s2); s1.addChild(s2); s1.addChild(t2); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 0); assertEquals(t1, 2, 3); assertEquals(s2, 2, 0); assertEquals(t2, 3, 1); Assert.assertEquals("Buffer content", "0421356789", fDocument.get()); doUndoRedo(undo, "0421356789"); } @Test public void testMove10() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(8, s1); MoveSourceEdit s2= new MoveSourceEdit(5, 2); MoveTargetEdit t2= new MoveTargetEdit(1, s2); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(s2); fRoot.addChild(t2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 4, 0); assertEquals(t1, 6, 2); assertEquals(s2, 5, 0); assertEquals(t2, 1, 2); Assert.assertEquals("Buffer content", "0561472389", fDocument.get()); doUndoRedo(undo, "0561472389"); } @Test public void testMoveWithRangeMarker() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(5, s1); RangeMarker marker= new RangeMarker(2, 2); s1.addChild(marker); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0142356789", fDocument.get()); assertEquals(s1, 2, 0); assertEquals(t1, 3, 2); assertEquals(marker, 3, 2); doUndoRedo(undo, "0142356789"); } @Test public void testMoveWithTargetDelete() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 3); MoveTargetEdit t1= new MoveTargetEdit(7, s1); TextEdit e2= new DeleteEdit(6, 2); e2.addChild(t1); fRoot.addChild(s1); fRoot.addChild(e2); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "01589", fDocument.get()); assertEquals(s1, 2, 0); assertTrue(t1.isDeleted()); assertEquals(e2, 3, 0); doUndoRedo(undo, "01589"); } @Test public void testMoveUpWithSourceDelete() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(5, 2); MoveTargetEdit t1= new MoveTargetEdit(2, s1); TextEdit d1= new DeleteEdit(5, 2); d1.addChild(s1); RangeMarker marker= new RangeMarker(5, 2); s1.addChild(marker); fRoot.addChild(d1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0156234789", fDocument.get()); assertEquals(t1, 2, 2); assertEquals(marker, 2, 2); assertTrue(s1.isDeleted()); assertEquals(d1, 7, 0); doUndoRedo(undo, "0156234789"); } @Test public void testMoveDown() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); TextEdit i1= new InsertEdit(5, "x"); MoveTargetEdit t1= new MoveTargetEdit(7, s1); TextEdit d1= new DeleteEdit(9, 1); RangeMarker m1= new RangeMarker(2, 2); s1.addChild(m1); fRoot.addChild(s1); fRoot.addChild(i1); fRoot.addChild(t1); fRoot.addChild(d1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "014x562378", fDocument.get()); assertEquals(s1, 2, 0); assertEquals(i1, 3, 1); assertEquals(t1, 6, 2); assertEquals(m1, 6, 2); assertEquals(d1, 10, 0); doUndoRedo(undo, "014x562378"); } @Test public void testMoveUp() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(7, 2); MoveTargetEdit t1= new MoveTargetEdit(2, s1); TextEdit i1= new InsertEdit(5, "x"); TextEdit d1= new DeleteEdit(9, 1); RangeMarker m1= new RangeMarker(7, 2); s1.addChild(m1); fRoot.addChild(s1); fRoot.addChild(i1); fRoot.addChild(t1); fRoot.addChild(d1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0178234x56", fDocument.get()); assertEquals(s1, 10, 0); assertEquals(i1, 7, 1); assertEquals(t1, 2, 2); assertEquals(m1, 2, 2); assertEquals(d1, 10, 0); doUndoRedo(undo, "0178234x56"); } @Test public void testMoveDownWithSourceDelete() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(7, s1); TextEdit d1= new DeleteEdit(2, 2); d1.addChild(s1); RangeMarker m1= new RangeMarker(2, 2); s1.addChild(m1); fRoot.addChild(t1); fRoot.addChild(d1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0145623789", fDocument.get()); assertEquals(d1, 2, 0); assertTrue(s1.isDeleted()); assertEquals(t1, 5, 2); assertEquals(m1, 5, 2); doUndoRedo(undo, "0145623789"); } @Test public void testMoveUpWithInnerMark() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(7, 2); MoveTargetEdit t1= new MoveTargetEdit(2, s1); TextEdit m= new ReplaceEdit(4, 1, "yy"); fRoot.addChild(t1); fRoot.addChild(m); fRoot.addChild(s1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "017823yy569", fDocument.get()); assertEquals(s1, 10, 0); assertEquals(t1, 2, 2); assertEquals(m, 6, 2); doUndoRedo(undo, "017823yy569"); } @Test public void testMoveDownWithInnerMark() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(7, s1); TextEdit m= new ReplaceEdit(4, 1, "yy"); fRoot.addChild(t1); fRoot.addChild(m); fRoot.addChild(s1); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "01yy5623789", fDocument.get()); assertEquals(s1, 2, 0); assertEquals(t1, 6, 2); assertEquals(m, 2, 2); doUndoRedo(undo, "01yy5623789"); } @Test public void testMoveUpWithParentMark() throws Exception { RangeMarker m= new RangeMarker(2, 6); MoveSourceEdit s1= new MoveSourceEdit(4, 2); MoveTargetEdit t1= new MoveTargetEdit(3, s1); m.addChild(s1); m.addChild(t1); fRoot.addChild(m); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0124536789", fDocument.get()); assertEquals(m, 2, 6); assertEquals(t1, 3, 2); assertEquals(s1, 6, 0); doUndoRedo(undo, "0124536789"); } @Test public void testMoveDownWithParentMark() throws Exception { RangeMarker m= new RangeMarker(2, 6); MoveSourceEdit s1= new MoveSourceEdit(2, 2); MoveTargetEdit t1= new MoveTargetEdit(5, s1); m.addChild(s1); m.addChild(t1); fRoot.addChild(m); UndoEdit undo= fRoot.apply(fDocument); Assert.assertEquals("Buffer content", "0142356789", fDocument.get()); assertEquals(m, 2, 6); assertEquals(t1, 3, 2); assertEquals(s1, 2, 0); doUndoRedo(undo, "0142356789"); } @Test public void testNestedMoveSource() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(1, 5); MoveSourceEdit s2= new MoveSourceEdit(2, 3); MoveSourceEdit s3= new MoveSourceEdit(3, 1); s1.addChild(s2); s2.addChild(s3); MoveTargetEdit t1= new MoveTargetEdit(9, s1); MoveTargetEdit t2= new MoveTargetEdit(8, s2); MoveTargetEdit t3= new MoveTargetEdit(7, s3); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(t2); fRoot.addChild(t3); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 0); assertEquals(s2, 8, 0); assertEquals(s3, 5, 0); assertEquals(t1, 7, 2); assertEquals(t2, 4, 2); assertEquals(t3, 2, 1); String result= "0637248159"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testNestedMoveSourceWithInsert() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(1, 5); MoveSourceEdit s2= new MoveSourceEdit(2, 3); MoveSourceEdit s3= new MoveSourceEdit(3, 1); InsertEdit i1= new InsertEdit(4, "x"); s1.addChild(s2); s2.addChild(s3); s3.addChild(i1); MoveTargetEdit t1= new MoveTargetEdit(9, s1); MoveTargetEdit t2= new MoveTargetEdit(8, s2); MoveTargetEdit t3= new MoveTargetEdit(7, s3); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(t2); fRoot.addChild(t3); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 0); assertEquals(s2, 9, 0); assertEquals(s3, 6, 0); assertEquals(i1, 3, 1); assertEquals(t1, 8, 2); assertEquals(t2, 5, 2); assertEquals(t3, 2, 2); String result= "063x7248159"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testNestedMoveTarget() throws Exception { MoveSourceEdit s1= new MoveSourceEdit(1, 2); MoveSourceEdit s2= new MoveSourceEdit(5, 3); MoveTargetEdit t1= new MoveTargetEdit(6, s1); MoveTargetEdit t2= new MoveTargetEdit(9, s2); s2.addChild(t1); fRoot.addChild(s1); fRoot.addChild(s2); fRoot.addChild(t2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 0); assertEquals(s2, 3, 0); assertEquals(t1, 5, 2); assertEquals(t2, 4, 5); String result= "0348512679"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testCopyDown() throws Exception { CopySourceEdit s1= new CopySourceEdit(2, 3); CopyTargetEdit t1= new CopyTargetEdit(8, s1); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 2, 3); assertEquals(t1, 8, 3); String result= "0123456723489"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testCopyUp() throws Exception { CopySourceEdit s1= new CopySourceEdit(7, 2); CopyTargetEdit t1= new CopyTargetEdit(3, s1); fRoot.addChild(s1); fRoot.addChild(t1); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 9, 2); assertEquals(t1, 3, 2); String result= "012783456789"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testDoubleCopy() throws Exception { CopySourceEdit s1= new CopySourceEdit(5, 2); CopyTargetEdit t1= new CopyTargetEdit(8, s1); CopySourceEdit s2= new CopySourceEdit(5, 2); CopyTargetEdit t2= new CopyTargetEdit(2, s2); s1.addChild(s2); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(t2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 7, 2); assertEquals(t1, 10, 2); assertEquals(s2, 7, 2); assertEquals(t2, 2, 2); String result= "01562345675689"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testNestedCopySource() throws Exception { CopySourceEdit s1= new CopySourceEdit(1, 5); CopySourceEdit s2= new CopySourceEdit(2, 3); CopySourceEdit s3= new CopySourceEdit(3, 1); s1.addChild(s2); s2.addChild(s3); CopyTargetEdit t1= new CopyTargetEdit(9, s1); CopyTargetEdit t2= new CopyTargetEdit(8, s2); CopyTargetEdit t3= new CopyTargetEdit(7, s3); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(t2); fRoot.addChild(t3); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 5); assertEquals(s2, 2, 3); assertEquals(s3, 3, 1); assertEquals(t1, 13, 5); assertEquals(t2, 9, 3); assertEquals(t3, 7, 1); String result= "0123456372348123459"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testNestedCopySourceWithInsert() throws Exception { CopySourceEdit s1= new CopySourceEdit(1, 5); CopySourceEdit s2= new CopySourceEdit(2, 3); CopySourceEdit s3= new CopySourceEdit(3, 1); InsertEdit i1= new InsertEdit(4, "x"); s1.addChild(s2); s2.addChild(s3); s3.addChild(i1); CopyTargetEdit t1= new CopyTargetEdit(9, s1); CopyTargetEdit t2= new CopyTargetEdit(8, s2); CopyTargetEdit t3= new CopyTargetEdit(7, s3); fRoot.addChild(s1); fRoot.addChild(t1); fRoot.addChild(t2); fRoot.addChild(t3); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 6); assertEquals(s2, 2, 4); assertEquals(s3, 3, 2); assertEquals(i1, 4, 1); assertEquals(t1, 16, 6); assertEquals(t2, 11, 4); assertEquals(t3, 8, 2); String result= "0123x4563x723x48123x459"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testNestedCopyTarget() throws Exception { CopySourceEdit s1= new CopySourceEdit(1, 2); CopySourceEdit s2= new CopySourceEdit(5, 3); CopyTargetEdit t1= new CopyTargetEdit(6, s1); CopyTargetEdit t2= new CopyTargetEdit(9, s2); s2.addChild(t1); fRoot.addChild(s1); fRoot.addChild(s2); fRoot.addChild(t2); UndoEdit undo= fRoot.apply(fDocument); assertEquals(s1, 1, 2); assertEquals(s2, 5, 5); assertEquals(t1, 6, 2); assertEquals(t2, 11, 5); String result= "01234512678512679"; Assert.assertEquals("Buffer content", result, fDocument.get()); doUndoRedo(undo, result); } @Test public void testSwap1() throws Exception { IDocument document= new Document("foo(1, 2), 3"); MultiTextEdit root= new MultiTextEdit(); { CopySourceEdit innerRoot= new CopySourceEdit(0, 9); TextEdit e1= new ReplaceEdit(0, 9, ""); e1.addChild(innerRoot); CopyTargetEdit t1= new CopyTargetEdit(11, innerRoot); TextEdit e2= new ReplaceEdit(11, 1, ""); CopySourceEdit s2= new CopySourceEdit(11, 1); e2.addChild(s2); CopyTargetEdit t2= new CopyTargetEdit(0, s2); root.addChild(e1); root.addChild(t2); root.addChild(e2); root.addChild(t1); } root.apply(document); String result= "3, foo(1, 2)"; Assert.assertEquals("Buffer content", result, document.get()); } @Test public void testSwap2() throws Exception { IDocument document= new Document("foo(1, 2), 3"); MultiTextEdit root= new MultiTextEdit(); { TextEdit e1= new ReplaceEdit(4, 1, ""); CopySourceEdit s1= new CopySourceEdit(4, 1); e1.addChild(s1); CopyTargetEdit t1= new CopyTargetEdit(7, s1); TextEdit e2= new ReplaceEdit(7, 1, ""); CopySourceEdit s2= new CopySourceEdit(7, 1); e2.addChild(s2); CopyTargetEdit t2= new CopyTargetEdit(4, s2); root.addChild(e1); root.addChild(t2); root.addChild(e2); root.addChild(t1); } root.apply(document); String result= "foo(2, 1), 3"; Assert.assertEquals("Buffer content", result, document.get()); } @Test public void testSwap2InSwap1() throws Exception { IDocument document= new Document("foo(1, 2), 3"); CopySourceEdit innerRoot= new CopySourceEdit(0, 9); { TextEdit e1= new ReplaceEdit(4, 1, ""); CopySourceEdit s1= new CopySourceEdit(4, 1); e1.addChild(s1); CopyTargetEdit t1= new CopyTargetEdit(7, s1); TextEdit e2= new ReplaceEdit(7, 1, ""); CopySourceEdit s2= new CopySourceEdit(7, 1); e2.addChild(s2); CopyTargetEdit t2= new CopyTargetEdit(4, s2); innerRoot.addChild(e1); innerRoot.addChild(t2); innerRoot.addChild(e2); innerRoot.addChild(t1); } MultiTextEdit root= new MultiTextEdit(); { TextEdit e1= new ReplaceEdit(0, 9, ""); e1.addChild(innerRoot); CopyTargetEdit t1= new CopyTargetEdit(11, innerRoot); TextEdit e2= new ReplaceEdit(11, 1, ""); CopySourceEdit s2= new CopySourceEdit(11, 1); e2.addChild(s2); CopyTargetEdit t2= new CopyTargetEdit(0, s2); root.addChild(e1); root.addChild(t2); root.addChild(e2); root.addChild(t1); } root.apply(document); String result= "3, foo(2, 1)"; Assert.assertEquals("Buffer content", result, document.get()); } @Test public void testMoveTree1() { TextEdit root= new MultiTextEdit(); TextEdit e1= new ReplaceEdit(0, 1, ""); root.addChild(e1); TextEdit e2= new ReplaceEdit(2, 2, ""); root.addChild(e2); root.moveTree(3); Assert.assertEquals(3, root.getOffset()); Assert.assertEquals(4, root.getLength()); Assert.assertEquals(3, e1.getOffset()); Assert.assertEquals(1, e1.getLength()); Assert.assertEquals(5, e2.getOffset()); Assert.assertEquals(2, e2.getLength()); } @Test public void testMoveTree2() { TextEdit root= new MultiTextEdit(); TextEdit e1= new ReplaceEdit(3, 1, ""); root.addChild(e1); TextEdit e2= new ReplaceEdit(5, 2, ""); root.addChild(e2); root.moveTree(-3); Assert.assertEquals(0, root.getOffset()); Assert.assertEquals(4, root.getLength()); Assert.assertEquals(0, e1.getOffset()); Assert.assertEquals(1, e1.getLength()); Assert.assertEquals(2, e2.getOffset()); Assert.assertEquals(2, e2.getLength()); } @Test public void testMoveTree3() { boolean exception= false; try { TextEdit root= new ReplaceEdit(0, 1, ""); root.moveTree(-1); } catch (Exception e) { exception= true; } assertTrue(exception); } @Test public void testMoveTree4() { boolean exception= false; try { TextEdit root= new MultiTextEdit(); TextEdit e1= new ReplaceEdit(0, 1, ""); root.addChild(e1); e1.moveTree(1); } catch (Exception e) { exception= true; } assertTrue(exception); } @Test public void testComparator() throws Exception { DeleteEdit d1= new DeleteEdit(1,3); Accessor accessor= new Accessor(d1, TextEdit.class); @SuppressWarnings("unchecked") Comparator<TextEdit> comparator= (Comparator<TextEdit>)accessor.get("INSERTION_COMPARATOR"); TextEdit edit1= new InsertEdit(1, "test"); TextEdit edit2= new InsertEdit(1, "test"); TextEdit edit3= new InsertEdit(57, "test3"); assertTrue(edit1.equals(edit1)); Assert.assertEquals(0, comparator.compare(edit1, edit1)); Assert.assertEquals(0, comparator.compare(edit1, edit2)); Assert.assertEquals(0, comparator.compare(edit2, edit1)); assertTrue(comparator.compare(edit1, edit3) == -comparator.compare(edit3, edit1)); } @Test public void testSourceTransformationIncludes() throws Exception { MoveSourceEdit ms= new MoveSourceEdit(2, 4); MoveTargetEdit mt= new MoveTargetEdit(9, ms); fRoot.addChild(ms); fRoot.addChild(mt); RangeMarker r1= new RangeMarker(3,2); ms.addChild(r1); ms.setSourceModifier(new ISourceModifier() { @Override public ISourceModifier copy() { return this; } @Override public ReplaceEdit[] getModifications(String source) { return new ReplaceEdit[] { new ReplaceEdit(1,1,"aa") }; } }); fRoot.apply(fDocument); String result= "016782aa459"; Assert.assertEquals("Buffer content", result, fDocument.get()); assertEquals(r1, 6, 3); } // Regression test for 108672 [quick fix] Exception when applying Convert to enhanced for loop @Test public void testSourceTranformationMultipleCovers() throws Exception { MoveSourceEdit ms= new MoveSourceEdit(2, 4); MoveTargetEdit mt= new MoveTargetEdit(9, ms); fRoot.addChild(ms); fRoot.addChild(mt); RangeMarker r1= new RangeMarker(3,0); ms.addChild(r1); RangeMarker r2= new RangeMarker(3,0); ms.addChild(r2); RangeMarker r3= new RangeMarker(4,2); ms.addChild(r3); ms.setSourceModifier(new ISourceModifier() { @Override public ISourceModifier copy() { return this; } @Override public ReplaceEdit[] getModifications(String source) { return new ReplaceEdit[] { new ReplaceEdit(0,2,"aa") }; } }); fRoot.apply(fDocument); String result= "01678aa459"; Assert.assertEquals("Buffer content", result, fDocument.get()); assertTrue(r1.isDeleted()); assertTrue(r2.isDeleted()); assertEquals(r3, 7, 2); } @Test public void testSourceTranformationSplit1() throws Exception { MoveSourceEdit ms= new MoveSourceEdit(2, 4); MoveTargetEdit mt= new MoveTargetEdit(9, ms); fRoot.addChild(ms); fRoot.addChild(mt); RangeMarker r1= new RangeMarker(3,2); ms.addChild(r1); ms.setSourceModifier(new ISourceModifier() { @Override public ISourceModifier copy() { return this; } @Override public ReplaceEdit[] getModifications(String source) { return new ReplaceEdit[] { new ReplaceEdit(0,2,"aa") }; } }); fRoot.apply(fDocument); String result= "01678aa459"; Assert.assertEquals("Buffer content", result, fDocument.get()); assertEquals(r1, 7, 1); } @Test public void testSourceTranformationSplit2() throws Exception { MoveSourceEdit ms= new MoveSourceEdit(2, 4); MoveTargetEdit mt= new MoveTargetEdit(9, ms); fRoot.addChild(ms); fRoot.addChild(mt); RangeMarker r1= new RangeMarker(3,2); ms.addChild(r1); ms.setSourceModifier(new ISourceModifier() { @Override public ISourceModifier copy() { return this; } @Override public ReplaceEdit[] getModifications(String source) { return new ReplaceEdit[] { new ReplaceEdit(2,2,"aa") }; } }); fRoot.apply(fDocument); String result= "0167823aa9"; Assert.assertEquals("Buffer content", result, fDocument.get()); assertEquals(r1, 6, 3); } @Test public void testIntersect() throws Exception { IRegion result= MoveSourceEdit.intersect(new RangeMarker(0,1), new RangeMarker(2,1)); assertNull(result); result= MoveSourceEdit.intersect(new RangeMarker(2,1), new RangeMarker(0,1)); assertNull(result); result= MoveSourceEdit.intersect(new RangeMarker(0,1), new RangeMarker(1,1)); assertNull(result); result= MoveSourceEdit.intersect(new RangeMarker(1,1), new RangeMarker(0,1)); assertNull(result); result= MoveSourceEdit.intersect(new RangeMarker(0,2), new RangeMarker(1,2)); assertNotNull(result); assertEquals(result, 1, 1); result= MoveSourceEdit.intersect(new RangeMarker(1,2), new RangeMarker(0,2)); assertNotNull(result); assertEquals(result, 1, 1); result= MoveSourceEdit.intersect(new RangeMarker(1,2), new RangeMarker(2,2)); assertNotNull(result); assertEquals(result, 2, 1); result= MoveSourceEdit.intersect(new RangeMarker(2,2), new RangeMarker(1,2)); assertNotNull(result); assertEquals(result, 2, 1); } private void doUndoRedo(UndoEdit undo, String redoResult) throws Exception { UndoEdit redo= undo.apply(fDocument); assertBufferContent(); undo= redo.apply(fDocument); Assert.assertEquals("Buffer content redo", redoResult, fDocument.get()); undo.apply(fDocument); assertBufferContent(); } private void assertEquals(TextEdit edit, int offset, int length) { Assert.assertEquals("Offset", offset, edit.getOffset()); Assert.assertEquals("Length", length, edit.getLength()); } private void assertEquals(IRegion region, int offset, int length) { Assert.assertEquals("Offset", offset, region.getOffset()); Assert.assertEquals("Length", length, region.getLength()); } private void assertBufferContent() { Assert.assertEquals("Buffer content restored", "0123456789", fDocument.get()); } }