blob: 6fdb8a512ab91909d45a9db530535f6d5fe12126 [file] [log] [blame]
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.formatting;
import com.intellij.openapi.editor.impl.BulkChangesMerger;
import com.intellij.openapi.editor.impl.TextChangeImpl;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
/**
* @author Denis Zhdanov
* @since 12/22/2010
*/
public class BulkChangesMergerTest {
@Rule
public TestWatcher configReader = new TestWatcher() {
@Override
protected void starting(Description description) {
Config config = description.getAnnotation(Config.class);
if (config != null) {
myConfig = config;
}
else {
try {
myConfig = BulkChangesMergerTest.class.getMethod("dummy").getAnnotation(Config.class);
}
catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
};
@Config
public static void dummy() {
}
private Config myConfig;
private BulkChangesMerger myMerger;
@Before
public void setUp() {
myMerger = new BulkChangesMerger();
}
@Test
public void simpleReplaceInTheMiddle() {
doTest("abcd", "a123d", c("123", 1, 3));
}
@Test
public void disjointInserts() {
doTest("abcd", "a1b2c3d45", c("1", 1), c("2", 2), c("3", 3), c("45", 4));
}
@Config(initialTextLength = 4)
@Test
public void interestedSymbolsNumberLessThanAvailable() {
doTest("abcdefg", "a12bc3d", c("12", 1), c("3", 3));
}
@Config(inplace = true)
@Test
public void inplaceZeroGroups() {
doTest("0123456789", "a2bc4defg8", c("a", 0, 2), c("bc", 3, 4), c("defg", 5, 8), c("", 9, 10));
}
@Config(inplace = true)
@Test
public void inplaceGrowingGroupsWithLastPositive() {
doTest("abcdefghijklmnopqrst", "acABdCjkDEFGHIJKLMpqrst", c("", 1, 2), c("AB", 3), c("C", 4, 9), c("DEFGHIJKLM", 11, 15));
}
@Config(inplace = true)
@Test
public void inplaceGrowingGroupsWithLastNegative() {
doTest("abcdefghijk", "acABdCjk", c("", 1, 2), c("AB", 3), c("C", 4, 9));
}
@Config(inplace = true)
@Test
public void onlyGrowing() {
doTest("0123456789", "0ab2c3defg67hijk9", c("ab", 1, 2), c("c", 3), c("defg", 4, 6), c("hijk", 8, 9));
}
@Config(inplace = true)
@Test
public void onlyShrinking() {
doTest("0123456789", "0a35b9", c("a", 1, 3), c("", 4, 5), c("b", 6, 9));
}
@Config(inplace = true, dataArrayLength = 4)
@Test(expected = IllegalArgumentException.class)
public void insufficientLengthForInplaceMerge() {
doTest("0123", "", c("", 1, 3), c("abc", 4));
}
@Config(inplace = true)
@Test
public void overlapWithPositiveGroupOnStart() {
doTest("0123456789ABC", "0abc1358d9eBC", c("abc", 1), c("", 2, 3), c("", 4, 5), c("", 6, 8), c("d", 9), c("e", 10, 11));
}
//@Config(inplace = true)
//@Test
//public void client() {
// int arrayLength = 31486;
// int dataLength = 9552;
// char[] initial = new char[arrayLength];
// List<int[]> rawChanges = new ArrayList<int[]>();
// rawChanges.add(new int[] {6609, 8209, 14634});
//
// List<TextChangeImpl> changes = new ArrayList<TextChangeImpl>();
// for (int[] rawChange : rawChanges) {
// changes.add(new TextChangeImpl(StringUtil.repeatSymbol('a', rawChange[0]), rawChange[1], rawChange[2]));
// }
// myMerger.mergeInPlace(initial, dataLength, changes);
//}
private static TextChangeImpl c(String text, int offset) {
return c(text, offset, offset);
}
private static TextChangeImpl c(String text, int start, int end) {
return new TextChangeImpl(text, start, end);
}
private void doTest(String initial, String expected, TextChangeImpl ... changes) {
if (myConfig.inplace()) {
int diff = 0;
for (TextChangeImpl change : changes) {
diff += change.getDiff();
}
int outputUsefulLength = initial.length() + diff;
int dataLength = myConfig.dataArrayLength();
if (dataLength < 0) {
dataLength = Math.max(outputUsefulLength, initial.length());
}
char[] data = new char[dataLength];
System.arraycopy(initial.toCharArray(), 0, data, 0, initial.length());
myMerger.mergeInPlace(data, initial.length(), Arrays.asList(changes));
assertEquals(expected, new String(data, 0, outputUsefulLength));
}
else {
int interestedSymbolsNumber = myConfig.initialTextLength();
if (interestedSymbolsNumber < 0) {
interestedSymbolsNumber = initial.length();
}
CharSequence actual = myMerger.mergeToCharSequence(initial.toCharArray(), interestedSymbolsNumber, Arrays.asList(changes));
assertEquals(expected, actual.toString());
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
private @interface Config {
boolean inplace() default false;
int dataArrayLength() default -1;
int initialTextLength() default -1;
}
}