mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+3
-3
@@ -88,7 +88,8 @@ class InlayAssert(private val file: PsiFile, val inlays: List<Inlay>) {
|
||||
val hintOffsets = hints.map { it.first }
|
||||
val hintNames = hints.map { it.second }
|
||||
|
||||
assertThat(hints.size).isEqualTo(expectedInlays.size)
|
||||
val elements = hintOffsets.mapNotNull { file.findElementAt(it) }
|
||||
assertThat(hints.size).isEqualTo(expectedInlays.size).withFailMessage("Element at offsets: ${elements.joinToString(", ")}")
|
||||
|
||||
val expect = expectedInlays.map { it.substringBefore("->") to it.substringAfter("->") }
|
||||
val expectedHintNames = expect.map { it.first }
|
||||
@@ -96,8 +97,7 @@ class InlayAssert(private val file: PsiFile, val inlays: List<Inlay>) {
|
||||
|
||||
assertThat(hintNames).isEqualTo(expectedHintNames)
|
||||
|
||||
val wordsAfter = hintOffsets.mapNotNull { file.findElementAt(it) }.map { it.text }
|
||||
|
||||
val wordsAfter = elements.map { it.text }
|
||||
assertThat(wordsAfter).isEqualTo(expectedWordsAfter)
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -708,13 +708,16 @@ class Key {
|
||||
setup("""
|
||||
class Test {
|
||||
void test() {
|
||||
xxx(100);
|
||||
check(1 + 1);
|
||||
int i=1; check(1 + 1 + 1);
|
||||
}
|
||||
void check(int isShow) {}
|
||||
void xxx(int followTheSum) {}
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
onLineStartingWith("xxx").assertInlays("followTheSum->100")
|
||||
onLineStartingWith("check").assertInlays("isShow->1")
|
||||
onLineStartingWith("int").assertInlays("isShow->1")
|
||||
}
|
||||
|
||||
@@ -600,7 +600,8 @@ public class ByWord {
|
||||
Range expanded = expandW(myText1, myText2, range);
|
||||
Range trimmed = trim(myText1, myText2, expanded);
|
||||
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (!trimmed.isEmpty() &&
|
||||
!isEqualsIW(myText1, myText2, trimmed)) {
|
||||
myChanges.add(trimmed);
|
||||
}
|
||||
}
|
||||
@@ -638,7 +639,8 @@ public class ByWord {
|
||||
MergeRange expanded = expandW(myText1, myText2, myText3, range);
|
||||
MergeRange trimmed = trim(myText1, myText2, myText3, expanded);
|
||||
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (!trimmed.isEmpty() &&
|
||||
!isEqualsIW(myText1, myText2, myText3, trimmed)) {
|
||||
myChanges.add(trimmed);
|
||||
}
|
||||
}
|
||||
@@ -690,7 +692,8 @@ public class ByWord {
|
||||
|
||||
Range trimmed = new Range(start1, end1, start2, end2);
|
||||
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (!trimmed.isEmpty() &&
|
||||
!isEquals(myText1, myText2, trimmed)) {
|
||||
myChanges.add(trimmed);
|
||||
}
|
||||
}
|
||||
@@ -753,7 +756,8 @@ public class ByWord {
|
||||
|
||||
MergeRange trimmed = new MergeRange(start1, end1, start2, end2, start3, end3);
|
||||
|
||||
if (!trimmed.isEmpty()) {
|
||||
if (!trimmed.isEmpty() &&
|
||||
!isEquals(myText1, myText2, myText3, trimmed)) {
|
||||
myChanges.add(trimmed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,4 +384,40 @@ public class TrimUtil {
|
||||
public static Range expandIW(@NotNull CharSequence text1, @NotNull CharSequence text2) {
|
||||
return expandIW(text1, text2, 0, 0, text1.length(), text2.length());
|
||||
}
|
||||
|
||||
//
|
||||
// Equality
|
||||
//
|
||||
|
||||
public static boolean isEquals(@NotNull CharSequence text1, @NotNull CharSequence text2,
|
||||
@NotNull Range range) {
|
||||
CharSequence sequence1 = text1.subSequence(range.start1, range.end1);
|
||||
CharSequence sequence2 = text2.subSequence(range.start2, range.end2);
|
||||
return ComparisonUtil.isEquals(sequence1, sequence2, ComparisonPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
public static boolean isEqualsIW(@NotNull CharSequence text1, @NotNull CharSequence text2,
|
||||
@NotNull Range range) {
|
||||
CharSequence sequence1 = text1.subSequence(range.start1, range.end1);
|
||||
CharSequence sequence2 = text2.subSequence(range.start2, range.end2);
|
||||
return ComparisonUtil.isEquals(sequence1, sequence2, ComparisonPolicy.IGNORE_WHITESPACES);
|
||||
}
|
||||
|
||||
public static boolean isEquals(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3,
|
||||
@NotNull MergeRange range) {
|
||||
CharSequence sequence1 = text1.subSequence(range.start1, range.end1);
|
||||
CharSequence sequence2 = text2.subSequence(range.start2, range.end2);
|
||||
CharSequence sequence3 = text3.subSequence(range.start3, range.end3);
|
||||
return ComparisonUtil.isEquals(sequence2, sequence1, ComparisonPolicy.DEFAULT) &&
|
||||
ComparisonUtil.isEquals(sequence2, sequence3, ComparisonPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
public static boolean isEqualsIW(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3,
|
||||
@NotNull MergeRange range) {
|
||||
CharSequence sequence1 = text1.subSequence(range.start1, range.end1);
|
||||
CharSequence sequence2 = text2.subSequence(range.start2, range.end2);
|
||||
CharSequence sequence3 = text3.subSequence(range.start3, range.end3);
|
||||
return ComparisonUtil.isEquals(sequence2, sequence1, ComparisonPolicy.IGNORE_WHITESPACES) &&
|
||||
ComparisonUtil.isEquals(sequence2, sequence3, ComparisonPolicy.IGNORE_WHITESPACES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.diff.util.ThreeSide
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.util.Couple
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
@@ -66,6 +65,10 @@ abstract class DiffTestCase : UsefulTestCase() {
|
||||
assertTrue(message, actual)
|
||||
}
|
||||
|
||||
fun assertFalse(actual: Boolean, message: String = "") {
|
||||
assertFalse(message, actual)
|
||||
}
|
||||
|
||||
fun assertEquals(expected: Any?, actual: Any?, message: String = "") {
|
||||
assertEquals(message, expected, actual)
|
||||
}
|
||||
@@ -75,17 +78,33 @@ abstract class DiffTestCase : UsefulTestCase() {
|
||||
}
|
||||
|
||||
fun assertEqualsCharSequences(chunk1: CharSequence, chunk2: CharSequence, ignoreSpaces: Boolean, skipLastNewline: Boolean) {
|
||||
if (skipLastNewline && !ignoreSpaces) {
|
||||
assertTrue(StringUtil.equals(chunk1, chunk2) ||
|
||||
StringUtil.equals(stripNewline(chunk1), chunk2) ||
|
||||
StringUtil.equals(chunk1, stripNewline(chunk2)))
|
||||
}
|
||||
else {
|
||||
assertTrue(isEqualsCharSequences(chunk1, chunk2, ignoreSpaces))
|
||||
}
|
||||
}
|
||||
|
||||
fun assertNotEqualsCharSequences(chunk1: CharSequence, chunk2: CharSequence, ignoreSpaces: Boolean, skipLastNewline: Boolean) {
|
||||
if (skipLastNewline && !ignoreSpaces) {
|
||||
assertTrue(!StringUtil.equals(chunk1, chunk2) ||
|
||||
!StringUtil.equals(stripNewline(chunk1), chunk2) ||
|
||||
!StringUtil.equals(chunk1, stripNewline(chunk2)))
|
||||
}
|
||||
else {
|
||||
assertFalse(isEqualsCharSequences(chunk1, chunk2, ignoreSpaces))
|
||||
}
|
||||
}
|
||||
|
||||
fun isEqualsCharSequences(chunk1: CharSequence, chunk2: CharSequence, ignoreSpaces: Boolean): Boolean {
|
||||
if (ignoreSpaces) {
|
||||
assertTrue(StringUtil.equalsIgnoreWhitespaces(chunk1, chunk2))
|
||||
} else {
|
||||
if (skipLastNewline) {
|
||||
if (StringUtil.equals(chunk1, chunk2)) return
|
||||
if (StringUtil.equals(stripNewline(chunk1), chunk2)) return
|
||||
if (StringUtil.equals(chunk1, stripNewline(chunk2))) return
|
||||
assertTrue(false)
|
||||
} else {
|
||||
assertTrue(StringUtil.equals(chunk1, chunk2))
|
||||
}
|
||||
return StringUtil.equalsIgnoreWhitespaces(chunk1, chunk2)
|
||||
}
|
||||
else {
|
||||
return StringUtil.equals(chunk1, chunk2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,14 +221,14 @@ abstract class DiffTestCase : UsefulTestCase() {
|
||||
// Helpers
|
||||
//
|
||||
|
||||
open class Trio<T : Any>(val data1: T, val data2: T, val data3: T) {
|
||||
open class Trio<out T>(val data1: T, val data2: T, val data3: T) {
|
||||
companion object {
|
||||
fun <V : Any> from(f: (ThreeSide) -> V): Trio<V> = Trio(f(ThreeSide.LEFT), f(ThreeSide.BASE), f(ThreeSide.RIGHT))
|
||||
fun <V> from(f: (ThreeSide) -> V): Trio<V> = Trio(f(ThreeSide.LEFT), f(ThreeSide.BASE), f(ThreeSide.RIGHT))
|
||||
}
|
||||
|
||||
fun <V : Any> map(f: (T) -> V): Trio<V> = Trio(f(data1), f(data2), f(data3))
|
||||
fun <V> map(f: (T) -> V): Trio<V> = Trio(f(data1), f(data2), f(data3))
|
||||
|
||||
fun <V : Any> map(f: (T, ThreeSide) -> V): Trio<V> = Trio(f(data1, ThreeSide.LEFT), f(data2, ThreeSide.BASE), f(data3, ThreeSide.RIGHT))
|
||||
fun <V> map(f: (T, ThreeSide) -> V): Trio<V> = Trio(f(data1, ThreeSide.LEFT), f(data2, ThreeSide.BASE), f(data3, ThreeSide.RIGHT))
|
||||
|
||||
fun forEach(f: (T, ThreeSide) -> Unit): Unit {
|
||||
f(data1, ThreeSide.LEFT)
|
||||
@@ -228,7 +247,11 @@ abstract class DiffTestCase : UsefulTestCase() {
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return data1.hashCode() * 37 * 37 + data2.hashCode() * 37 + data3.hashCode()
|
||||
var h = 0
|
||||
if (data1 != null) h = h * 31 + data1.hashCode()
|
||||
if (data2 != null) h = h * 31 + data2.hashCode()
|
||||
if (data3 != null) h = h * 31 + data3.hashCode()
|
||||
return h
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,28 +26,31 @@ import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
|
||||
class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
val RUNS = 30
|
||||
val MAX_LENGTH = 300
|
||||
|
||||
fun testChar() {
|
||||
doTestChar(System.currentTimeMillis(), 30, 30)
|
||||
doTestChar(System.currentTimeMillis(), RUNS, MAX_LENGTH)
|
||||
}
|
||||
|
||||
fun testWord() {
|
||||
doTestWord(System.currentTimeMillis(), 30, 300)
|
||||
doTestWord(System.currentTimeMillis(), RUNS, MAX_LENGTH)
|
||||
}
|
||||
|
||||
fun testLine() {
|
||||
doTestLine(System.currentTimeMillis(), 30, 300)
|
||||
doTestLine(System.currentTimeMillis(), RUNS, MAX_LENGTH)
|
||||
}
|
||||
|
||||
fun testLineSquashed() {
|
||||
doTestLineSquashed(System.currentTimeMillis(), 30, 300)
|
||||
doTestLineSquashed(System.currentTimeMillis(), RUNS, MAX_LENGTH)
|
||||
}
|
||||
|
||||
fun testLineTrimSquashed() {
|
||||
doTestLineTrimSquashed(System.currentTimeMillis(), 30, 300)
|
||||
doTestLineTrimSquashed(System.currentTimeMillis(), RUNS, MAX_LENGTH)
|
||||
}
|
||||
|
||||
fun testMerge() {
|
||||
doTestMerge(System.currentTimeMillis(), 30, 300)
|
||||
doTestMerge(System.currentTimeMillis(), RUNS, MAX_LENGTH)
|
||||
}
|
||||
|
||||
private fun doTestLine(seed: Long, runs: Int, maxLength: Int) {
|
||||
@@ -141,8 +144,8 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
val chunk2 = DiffUtil.getLinesContent(text2, f.startLine2, f.endLine2)
|
||||
val chunk3 = DiffUtil.getLinesContent(text3, f.startLine3, f.endLine3)
|
||||
|
||||
val wordFragments = ByWord.compare(chunk1, chunk2, chunk3, policy, INDICATOR);
|
||||
MergeLineFragmentImpl(f, wordFragments);
|
||||
val wordFragments = ByWord.compare(chunk1, chunk2, chunk3, policy, INDICATOR)
|
||||
MergeLineFragmentImpl(f, wordFragments)
|
||||
}
|
||||
debugData.put("Fragments", fineFragments)
|
||||
|
||||
@@ -200,18 +203,18 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
checkUnchanged(text1.charsSequence, text2.charsSequence, fragments, policy, true)
|
||||
checkValidRanges(text1.charsSequence, text2.charsSequence, fragments, policy, true)
|
||||
checkCantTrimLines(text1, text2, fragments, policy, allowNonSquashed)
|
||||
}
|
||||
|
||||
private fun checkResultWord(text1: CharSequence, text2: CharSequence, fragments: List<DiffFragment>, policy: ComparisonPolicy) {
|
||||
checkDiffConsistency(fragments)
|
||||
checkUnchanged(text1, text2, fragments, policy, false)
|
||||
checkValidRanges(text1, text2, fragments, policy, false)
|
||||
}
|
||||
|
||||
private fun checkResultChar(text1: CharSequence, text2: CharSequence, fragments: List<DiffFragment>, policy: ComparisonPolicy) {
|
||||
checkDiffConsistency(fragments)
|
||||
checkUnchanged(text1, text2, fragments, policy, false)
|
||||
checkValidRanges(text1, text2, fragments, policy, false)
|
||||
}
|
||||
|
||||
private fun checkResultMerge(text1: Document, text2: Document, text3: Document, fragments: List<MergeLineFragment>, policy: ComparisonPolicy) {
|
||||
@@ -223,10 +226,10 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
val chunk3 = DiffUtil.getLinesContent(text3, f.startLine3, f.endLine3)
|
||||
|
||||
checkDiffConsistency3(f.innerFragments!!)
|
||||
checkUnchanged3(chunk1, chunk2, chunk3, f.innerFragments!!, policy)
|
||||
checkValidRanges3(chunk1, chunk2, chunk3, f.innerFragments!!, policy)
|
||||
}
|
||||
|
||||
checkUnchanged3(text1, text2, text3, fragments, policy)
|
||||
checkValidRanges3(text1, text2, text3, fragments, policy)
|
||||
checkCantTrimLines3(text1, text2, text3, fragments, policy)
|
||||
}
|
||||
|
||||
@@ -374,28 +377,39 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkUnchanged(text1: CharSequence, text2: CharSequence, fragments: List<DiffFragment>, policy: ComparisonPolicy, skipNewline: Boolean) {
|
||||
private fun checkValidRanges(text1: CharSequence, text2: CharSequence, fragments: List<DiffFragment>, policy: ComparisonPolicy, skipNewline: Boolean) {
|
||||
// TODO: better check for Trim spaces case ?
|
||||
val ignoreSpaces = policy !== ComparisonPolicy.DEFAULT
|
||||
val ignoreSpacesUnchanged = policy != ComparisonPolicy.DEFAULT
|
||||
val ignoreSpacesChanged = policy == ComparisonPolicy.IGNORE_WHITESPACES
|
||||
|
||||
var last1 = 0
|
||||
var last2 = 0
|
||||
for (fragment in fragments) {
|
||||
val chunk1 = text1.subSequence(last1, fragment.startOffset1)
|
||||
val chunk2 = text2.subSequence(last2, fragment.startOffset2)
|
||||
val start1 = fragment.startOffset1
|
||||
val start2 = fragment.startOffset2
|
||||
val end1 = fragment.endOffset1
|
||||
val end2 = fragment.endOffset2
|
||||
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpaces, skipNewline)
|
||||
val chunk1 = text1.subSequence(last1, start1)
|
||||
val chunk2 = text2.subSequence(last2, start2)
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpacesUnchanged, skipNewline)
|
||||
|
||||
val chunkContent1 = text1.subSequence(start1, end1)
|
||||
val chunkContent2 = text2.subSequence(start2, end2)
|
||||
if (!skipNewline) {
|
||||
assertNotEqualsCharSequences(chunkContent1, chunkContent2, ignoreSpacesChanged, skipNewline)
|
||||
}
|
||||
|
||||
last1 = fragment.endOffset1
|
||||
last2 = fragment.endOffset2
|
||||
}
|
||||
val chunk1 = text1.subSequence(last1, text1.length)
|
||||
val chunk2 = text2.subSequence(last2, text2.length)
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpaces, skipNewline)
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpacesUnchanged, skipNewline)
|
||||
}
|
||||
|
||||
private fun checkUnchanged3(text1: Document, text2: Document, text3: Document, fragments: List<MergeLineFragment>, policy: ComparisonPolicy) {
|
||||
val ignoreSpaces = policy !== ComparisonPolicy.DEFAULT
|
||||
private fun checkValidRanges3(text1: Document, text2: Document, text3: Document, fragments: List<MergeLineFragment>, policy: ComparisonPolicy) {
|
||||
val ignoreSpaces = policy != ComparisonPolicy.DEFAULT
|
||||
|
||||
var last1 = 0
|
||||
var last2 = 0
|
||||
@@ -425,8 +439,9 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
assertEqualsCharSequences(content2, content3, ignoreSpaces, false)
|
||||
}
|
||||
|
||||
private fun checkUnchanged3(text1: CharSequence, text2: CharSequence, text3: CharSequence, fragments: List<MergeWordFragment>, policy: ComparisonPolicy) {
|
||||
val ignoreSpaces = policy !== ComparisonPolicy.DEFAULT
|
||||
private fun checkValidRanges3(text1: CharSequence, text2: CharSequence, text3: CharSequence, fragments: List<MergeWordFragment>, policy: ComparisonPolicy) {
|
||||
val ignoreSpacesUnchanged = policy != ComparisonPolicy.DEFAULT
|
||||
val ignoreSpacesChanged = policy == ComparisonPolicy.IGNORE_WHITESPACES
|
||||
|
||||
var last1 = 0
|
||||
var last2 = 0
|
||||
@@ -435,13 +450,21 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
val start1 = fragment.startOffset1
|
||||
val start2 = fragment.startOffset2
|
||||
val start3 = fragment.startOffset3
|
||||
val end1 = fragment.endOffset1
|
||||
val end2 = fragment.endOffset2
|
||||
val end3 = fragment.endOffset3
|
||||
|
||||
val content1 = text1.subSequence(last1, start1)
|
||||
val content2 = text2.subSequence(last2, start2)
|
||||
val content3 = text3.subSequence(last3, start3)
|
||||
assertEqualsCharSequences(content2, content1, ignoreSpacesUnchanged, false)
|
||||
assertEqualsCharSequences(content2, content3, ignoreSpacesUnchanged, false)
|
||||
|
||||
assertEqualsCharSequences(content2, content1, ignoreSpaces, false)
|
||||
assertEqualsCharSequences(content2, content3, ignoreSpaces, false)
|
||||
val chunkContent1 = text1.subSequence(start1, end1)
|
||||
val chunkContent2 = text2.subSequence(start2, end2)
|
||||
val chunkContent3 = text3.subSequence(start3, end3)
|
||||
assertFalse(isEqualsCharSequences(chunkContent2, chunkContent1, ignoreSpacesChanged) &&
|
||||
isEqualsCharSequences(chunkContent2, chunkContent3, ignoreSpacesChanged))
|
||||
|
||||
last1 = fragment.endOffset1
|
||||
last2 = fragment.endOffset2
|
||||
@@ -452,8 +475,8 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
val content2 = text2.subSequence(last2, text2.length)
|
||||
val content3 = text3.subSequence(last3, text3.length)
|
||||
|
||||
assertEqualsCharSequences(content2, content1, ignoreSpaces, false)
|
||||
assertEqualsCharSequences(content2, content3, ignoreSpaces, false)
|
||||
assertEqualsCharSequences(content2, content1, ignoreSpacesUnchanged, false)
|
||||
assertEqualsCharSequences(content2, content3, ignoreSpacesUnchanged, false)
|
||||
}
|
||||
|
||||
private fun checkCantTrimLines(text1: Document, text2: Document, fragments: List<LineFragment>, policy: ComparisonPolicy, allowNonSquashed: Boolean) {
|
||||
@@ -491,11 +514,7 @@ class ComparisonUtilAutoTest : DiffTestCase() {
|
||||
}
|
||||
|
||||
private fun countNonWhitespaceCharacters(line: CharSequence): Int {
|
||||
var count = 0
|
||||
for (i in 0 until line.length) {
|
||||
if (!StringUtil.isWhiteSpace(line[i])) count++
|
||||
}
|
||||
return count
|
||||
return (0 until line.length).count { !StringUtil.isWhiteSpace(line[it]) }
|
||||
}
|
||||
|
||||
private fun getFirstLastLines(text: Document, start: Int, end: Int): Couple<CharSequence>? {
|
||||
|
||||
@@ -18,6 +18,9 @@ package com.intellij.diff.comparison
|
||||
import com.intellij.diff.DiffTestCase
|
||||
import com.intellij.diff.fragments.DiffFragment
|
||||
import com.intellij.diff.fragments.LineFragment
|
||||
import com.intellij.diff.fragments.MergeWordFragment
|
||||
import com.intellij.diff.util.IntPair
|
||||
import com.intellij.diff.util.ThreeSide
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl
|
||||
import com.intellij.openapi.util.Couple
|
||||
@@ -25,31 +28,64 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import java.util.*
|
||||
|
||||
abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
private fun doLineTest(before: Document, after: Document, matchings: Couple<BitSet>?, expected: List<Change>?, policy: ComparisonPolicy) {
|
||||
private fun doLineTest(text: Couple<Document>, matchings: Couple<BitSet>?, expected: List<Couple<IntPair>>?, policy: ComparisonPolicy) {
|
||||
val before = text.first
|
||||
val after = text.second
|
||||
val fragments = MANAGER.compareLines(before.charsSequence, after.charsSequence, policy, INDICATOR)
|
||||
checkConsistency(fragments, before, after)
|
||||
if (matchings != null) checkLineMatching(fragments, matchings)
|
||||
if (expected != null) checkLineChanges(fragments, expected)
|
||||
}
|
||||
|
||||
private fun doWordTest(before: Document, after: Document, matchings: Couple<BitSet>?, expected: List<Change>?, policy: ComparisonPolicy) {
|
||||
private fun doLineInnerTest(text: Couple<Document>, matchings: Couple<BitSet>?, expected: List<Couple<IntPair>>?, policy: ComparisonPolicy) {
|
||||
val before = text.first
|
||||
val after = text.second
|
||||
val rawFragments = MANAGER.compareLinesInner(before.charsSequence, after.charsSequence, policy, INDICATOR)
|
||||
val fragments = MANAGER.squash(rawFragments)
|
||||
checkConsistencyWord(fragments, before, after)
|
||||
checkConsistencyLineInner(fragments, before, after)
|
||||
|
||||
val diffFragments = fragments[0].innerFragments!!
|
||||
if (matchings != null) checkDiffMatching(diffFragments, matchings)
|
||||
if (expected != null) checkDiffChanges(diffFragments, expected)
|
||||
}
|
||||
|
||||
private fun doCharTest(before: Document, after: Document, matchings: Couple<BitSet>?, expected: List<Change>?, policy: ComparisonPolicy) {
|
||||
private fun doWordTest(text: Couple<Document>, matchings: Couple<BitSet>?, expected: List<Couple<IntPair>>?, policy: ComparisonPolicy) {
|
||||
val before = text.first
|
||||
val after = text.second
|
||||
val fragments = MANAGER.compareWords(before.charsSequence, after.charsSequence, policy, INDICATOR)
|
||||
checkConsistency(fragments, before, after)
|
||||
|
||||
if (matchings != null) checkDiffMatching(fragments, matchings)
|
||||
if (expected != null) checkDiffChanges(fragments, expected)
|
||||
}
|
||||
|
||||
private fun doWordTest(text: Trio<Document>, matchings: Trio<BitSet>?, expected: List<Trio<IntPair>>?, policy: ComparisonPolicy) {
|
||||
val before = text.data1
|
||||
val base = text.data2
|
||||
val after = text.data3
|
||||
val fragments = ByWord.compare(before.charsSequence, base.charsSequence, after.charsSequence, policy, INDICATOR)
|
||||
checkConsistency(fragments)
|
||||
|
||||
if (matchings != null) checkMergeMatching(fragments, matchings)
|
||||
if (expected != null) checkMergeChanges(fragments, expected)
|
||||
}
|
||||
|
||||
private fun doCharTest(text: Couple<Document>, matchings: Couple<BitSet>?, expected: List<Couple<IntPair>>?, policy: ComparisonPolicy) {
|
||||
val before = text.first
|
||||
val after = text.second
|
||||
val fragments = MANAGER.compareChars(before.charsSequence, after.charsSequence, policy, INDICATOR)
|
||||
checkConsistency(fragments, before, after)
|
||||
if (matchings != null) checkDiffMatching(fragments, matchings)
|
||||
if (expected != null) checkDiffChanges(fragments, expected)
|
||||
}
|
||||
|
||||
private fun doSplitterTest(before: Document, after: Document, squash: Boolean, trim: Boolean, expected: List<Change>?, policy: ComparisonPolicy) {
|
||||
private fun doSplitterTest(text: Couple<Document>,
|
||||
squash: Boolean,
|
||||
trim: Boolean,
|
||||
expected: List<Couple<IntPair>>?,
|
||||
policy: ComparisonPolicy) {
|
||||
val before = text.first
|
||||
val after = text.second
|
||||
val text1 = before.charsSequence
|
||||
val text2 = after.charsSequence
|
||||
|
||||
@@ -62,7 +98,7 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
if (expected != null) checkLineChanges(fragments, expected)
|
||||
}
|
||||
|
||||
private fun checkConsistencyWord(fragments: List<LineFragment>, before: Document, after: Document) {
|
||||
private fun checkConsistencyLineInner(fragments: List<LineFragment>, before: Document, after: Document) {
|
||||
assertTrue(fragments.size == 1)
|
||||
val fragment = fragments[0]
|
||||
|
||||
@@ -102,16 +138,33 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLineChanges(fragments: List<LineFragment>, expected: List<Change>) {
|
||||
private fun checkConsistency(fragments: List<MergeWordFragment>) {
|
||||
for (fragment in fragments) {
|
||||
assertTrue(fragment.getStartOffset(ThreeSide.LEFT) <= fragment.getEndOffset(ThreeSide.LEFT))
|
||||
assertTrue(fragment.getStartOffset(ThreeSide.BASE) <= fragment.getEndOffset(ThreeSide.BASE))
|
||||
assertTrue(fragment.getStartOffset(ThreeSide.RIGHT) <= fragment.getEndOffset(ThreeSide.RIGHT))
|
||||
|
||||
assertTrue(fragment.getStartOffset(ThreeSide.LEFT) != fragment.getEndOffset(ThreeSide.LEFT) ||
|
||||
fragment.getStartOffset(ThreeSide.BASE) != fragment.getEndOffset(ThreeSide.BASE) ||
|
||||
fragment.getStartOffset(ThreeSide.RIGHT) != fragment.getEndOffset(ThreeSide.RIGHT))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLineChanges(fragments: List<LineFragment>, expected: List<Couple<IntPair>>) {
|
||||
val changes = convertLineFragments(fragments)
|
||||
assertOrderedEquals(changes, expected)
|
||||
}
|
||||
|
||||
private fun checkDiffChanges(fragments: List<DiffFragment>, expected: List<Change>) {
|
||||
private fun checkDiffChanges(fragments: List<DiffFragment>, expected: List<Couple<IntPair>>) {
|
||||
val changes = convertDiffFragments(fragments)
|
||||
assertOrderedEquals(changes, expected)
|
||||
}
|
||||
|
||||
private fun checkMergeChanges(fragments: List<MergeWordFragment>, expected: List<Trio<IntPair>>) {
|
||||
val changes = convertMergeFragments(fragments)
|
||||
assertOrderedEquals(changes, expected)
|
||||
}
|
||||
|
||||
private fun checkLineMatching(fragments: List<LineFragment>, matchings: Couple<BitSet>) {
|
||||
val set1 = BitSet()
|
||||
val set2 = BitSet()
|
||||
@@ -120,8 +173,8 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
set2.set(fragment.startLine2, fragment.endLine2)
|
||||
}
|
||||
|
||||
assertEquals(matchings.first, set1)
|
||||
assertEquals(matchings.second, set2)
|
||||
assertEquals(matchings.first, set1, "Before")
|
||||
assertEquals(matchings.second, set2, "After")
|
||||
}
|
||||
|
||||
private fun checkDiffMatching(fragments: List<DiffFragment>, matchings: Couple<BitSet>) {
|
||||
@@ -132,16 +185,39 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
set2.set(fragment.startOffset2, fragment.endOffset2)
|
||||
}
|
||||
|
||||
assertEquals(matchings.first, set1)
|
||||
assertEquals(matchings.second, set2)
|
||||
assertEquals(matchings.first, set1, "Before")
|
||||
assertEquals(matchings.second, set2, "After")
|
||||
}
|
||||
|
||||
private fun convertDiffFragments(fragments: List<DiffFragment>): List<Change> {
|
||||
return fragments.map { Change(it.startOffset1, it.endOffset1, it.startOffset2, it.endOffset2) }
|
||||
private fun checkMergeMatching(fragments: List<MergeWordFragment>, matchings: Trio<BitSet>) {
|
||||
val set1 = BitSet()
|
||||
val set2 = BitSet()
|
||||
val set3 = BitSet()
|
||||
for (fragment in fragments) {
|
||||
set1.set(fragment.getStartOffset(ThreeSide.LEFT), fragment.getEndOffset(ThreeSide.LEFT))
|
||||
set2.set(fragment.getStartOffset(ThreeSide.BASE), fragment.getEndOffset(ThreeSide.BASE))
|
||||
set3.set(fragment.getStartOffset(ThreeSide.RIGHT), fragment.getEndOffset(ThreeSide.RIGHT))
|
||||
}
|
||||
|
||||
assertEquals(matchings.data1, set1, "Before")
|
||||
assertEquals(matchings.data2, set2, "Base")
|
||||
assertEquals(matchings.data3, set3, "After")
|
||||
}
|
||||
|
||||
private fun convertLineFragments(fragments: List<LineFragment>): List<Change> {
|
||||
return fragments.map { Change(it.startLine1, it.endLine1, it.startLine2, it.endLine2) }
|
||||
private fun convertDiffFragments(fragments: List<DiffFragment>): List<Couple<IntPair>> {
|
||||
return fragments.map { Couple(IntPair(it.startOffset1, it.endOffset1), IntPair(it.startOffset2, it.endOffset2)) }
|
||||
}
|
||||
|
||||
private fun convertLineFragments(fragments: List<LineFragment>): List<Couple<IntPair>> {
|
||||
return fragments.map { Couple(IntPair(it.startLine1, it.endLine1), IntPair(it.startLine2, it.endLine2)) }
|
||||
}
|
||||
|
||||
private fun convertMergeFragments(fragments: List<MergeWordFragment>): List<Trio<IntPair>> {
|
||||
return fragments.map {
|
||||
Trio(IntPair(it.getStartOffset(ThreeSide.LEFT), it.getEndOffset(ThreeSide.LEFT)),
|
||||
IntPair(it.getStartOffset(ThreeSide.BASE), it.getEndOffset(ThreeSide.BASE)),
|
||||
IntPair(it.getStartOffset(ThreeSide.RIGHT), it.getEndOffset(ThreeSide.RIGHT)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkLineOffsets(fragment: LineFragment, before: Document, after: Document) {
|
||||
@@ -168,39 +244,51 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
// Test Builder
|
||||
//
|
||||
|
||||
private fun parseLineMatching(matching: String, document: Document): BitSet {
|
||||
assertEquals(matching.length, document.textLength)
|
||||
|
||||
val lines1 = matching.split('_', '*')
|
||||
val lines2 = document.charsSequence.split('\n')
|
||||
assertEquals(lines1.size, lines2.size)
|
||||
for (i in 0..lines1.size - 1) {
|
||||
assertEquals(lines1[i].length, lines2[i].length, "line $i")
|
||||
}
|
||||
|
||||
|
||||
val set = BitSet()
|
||||
|
||||
var index = 0
|
||||
var lineNumber = 0
|
||||
while (index < matching.length) {
|
||||
var end = matching.indexOfAny(listOf("_", "*"), index) + 1
|
||||
if (end == 0) end = matching.length
|
||||
|
||||
val line = matching.subSequence(index, end)
|
||||
if (line.find { it != ' ' && it != '_' } != null) {
|
||||
assert(!line.contains(' '))
|
||||
set.set(lineNumber)
|
||||
}
|
||||
lineNumber++
|
||||
index = end
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
internal enum class TestType {
|
||||
LINE, WORD, CHAR, SPLITTER
|
||||
LINE, LINE_INNER, WORD, CHAR, SPLITTER
|
||||
}
|
||||
|
||||
internal inner class TestBuilder(private val type: TestType) {
|
||||
private var isExecuted: Boolean = false
|
||||
|
||||
private var before: Document? = null
|
||||
private var after: Document? = null
|
||||
|
||||
private var defaultChanges: List<Change>? = null
|
||||
private var trimChanges: List<Change>? = null
|
||||
private var ignoreChanges: List<Change>? = null
|
||||
|
||||
private var defaultMatching: Couple<BitSet>? = null
|
||||
private var trimMatching: Couple<BitSet>? = null
|
||||
private var ignoreMatching: Couple<BitSet>? = null
|
||||
private var text: Data<Document> = Data()
|
||||
private var changes: PolicyData<List<Data<IntPair>>> = PolicyData()
|
||||
private var matchings: PolicyData<Data<BitSet>> = PolicyData()
|
||||
|
||||
private var shouldSquash: Boolean = false
|
||||
private var shouldTrim: Boolean = false
|
||||
|
||||
private fun changes(policy: ComparisonPolicy): List<Change>? = when (policy) {
|
||||
ComparisonPolicy.IGNORE_WHITESPACES -> ignoreChanges ?: trimChanges ?: defaultChanges
|
||||
ComparisonPolicy.TRIM_WHITESPACES -> trimChanges ?: defaultChanges
|
||||
ComparisonPolicy.DEFAULT -> defaultChanges
|
||||
}
|
||||
|
||||
private fun matchings(policy: ComparisonPolicy): Couple<BitSet>? = when (policy) {
|
||||
ComparisonPolicy.IGNORE_WHITESPACES -> ignoreMatching ?: trimMatching ?: defaultMatching
|
||||
ComparisonPolicy.TRIM_WHITESPACES -> trimMatching ?: defaultMatching
|
||||
ComparisonPolicy.DEFAULT -> defaultMatching
|
||||
}
|
||||
|
||||
fun assertExecuted() {
|
||||
assertTrue(isExecuted)
|
||||
}
|
||||
@@ -209,17 +297,36 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
try {
|
||||
isExecuted = true
|
||||
|
||||
val change = changes(policy)
|
||||
val matchings = matchings(policy)
|
||||
assertTrue(change != null || matchings != null)
|
||||
if (text.isTwoSide()) {
|
||||
val text = text.asCouple()
|
||||
val changes = changes.get(policy)?.map { it.asCouple() }
|
||||
val matchings = matchings.get(policy)?.asCouple()
|
||||
assertTrue(changes != null || matchings != null)
|
||||
|
||||
when (type) {
|
||||
TestType.LINE -> doLineTest(before!!, after!!, matchings, change, policy)
|
||||
TestType.WORD -> doWordTest(before!!, after!!, matchings, change, policy)
|
||||
TestType.CHAR -> doCharTest(before!!, after!!, matchings, change, policy)
|
||||
TestType.SPLITTER -> {
|
||||
assertNull(matchings)
|
||||
doSplitterTest(before!!, after!!, shouldSquash, shouldTrim, change, policy)
|
||||
when (type) {
|
||||
TestType.LINE -> doLineTest(text, matchings, changes, policy)
|
||||
TestType.LINE_INNER -> {
|
||||
doLineInnerTest(text, matchings, changes, policy)
|
||||
doWordTest(text, matchings, changes, policy)
|
||||
}
|
||||
TestType.WORD -> doWordTest(text, matchings, changes, policy)
|
||||
TestType.CHAR -> doCharTest(text, matchings, changes, policy)
|
||||
TestType.SPLITTER -> {
|
||||
assertNull(matchings)
|
||||
doSplitterTest(text, shouldSquash, shouldTrim, changes, policy)
|
||||
}
|
||||
else -> assert(false)
|
||||
}
|
||||
}
|
||||
else {
|
||||
val text = text.asTrio()
|
||||
val changes = changes.get(policy)?.map { it.asTrio() }
|
||||
val matchings = matchings.get(policy)?.asTrio()
|
||||
assertTrue(changes != null || matchings != null)
|
||||
|
||||
when (type) {
|
||||
TestType.WORD -> doWordTest(text, matchings, changes, policy)
|
||||
else -> assert(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,102 +361,84 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
return Helper(this, v)
|
||||
}
|
||||
|
||||
inner class Helper(val before: String, val after: String) {
|
||||
operator fun Helper.minus(v: String): Helper {
|
||||
return Helper(before, v, after)
|
||||
}
|
||||
|
||||
inner class Helper(val before: String, val after: String, val base: String? = null) {
|
||||
init {
|
||||
val builder = this@TestBuilder
|
||||
if (builder.before == null && builder.after == null) {
|
||||
builder.before = DocumentImpl(parseSource(before))
|
||||
builder.after = DocumentImpl(parseSource(after))
|
||||
if (builder.text.before == null && builder.text.after == null ||
|
||||
base != null && builder.text.base == null) {
|
||||
builder.text.before = DocumentImpl(parseSource(before))
|
||||
builder.text.after = DocumentImpl(parseSource(after))
|
||||
if (base != null) builder.text.base = DocumentImpl(parseSource(base))
|
||||
}
|
||||
}
|
||||
|
||||
fun plainSource() {
|
||||
val builder = this@TestBuilder
|
||||
builder.before = DocumentImpl(before)
|
||||
builder.after = DocumentImpl(after)
|
||||
builder.text.before = DocumentImpl(before)
|
||||
builder.text.after = DocumentImpl(after)
|
||||
if (base != null) {
|
||||
builder.text.base = DocumentImpl(base)
|
||||
}
|
||||
}
|
||||
|
||||
fun default() {
|
||||
defaultMatching = parseMatching(before, after)
|
||||
matchings.default = parseMatching(before, after, base)
|
||||
}
|
||||
|
||||
fun trim() {
|
||||
trimMatching = parseMatching(before, after)
|
||||
matchings.trim = parseMatching(before, after, base)
|
||||
}
|
||||
|
||||
fun ignore() {
|
||||
ignoreMatching = parseMatching(before, after)
|
||||
matchings.ignore = parseMatching(before, after, base)
|
||||
}
|
||||
|
||||
private fun parseMatching(before: String, after: String): Couple<BitSet> {
|
||||
private fun parseMatching(before: String, after: String, base: String?): Data<BitSet> {
|
||||
if (type == TestType.LINE) {
|
||||
val builder = this@TestBuilder
|
||||
return Couple.of(parseLineMatching(before, builder.before!!), parseLineMatching(after, builder.after!!))
|
||||
return Data(parseLineMatching(before, builder.text.before!!),
|
||||
if (base != null) parseLineMatching(base, builder.text.base!!) else null,
|
||||
parseLineMatching(after, builder.text.after!!))
|
||||
}
|
||||
else {
|
||||
return Couple.of(parseMatching(before), parseMatching(after))
|
||||
return Data(parseMatching(before),
|
||||
if (base != null) parseMatching(base) else null,
|
||||
parseMatching(after))
|
||||
}
|
||||
}
|
||||
|
||||
fun parseLineMatching(matching: String, document: Document): BitSet {
|
||||
assertEquals(matching.length, document.textLength)
|
||||
|
||||
val lines1 = matching.split('_', '*')
|
||||
val lines2 = document.charsSequence.split('\n')
|
||||
assertEquals(lines1.size, lines2.size)
|
||||
for (i in 0..lines1.size - 1) {
|
||||
assertEquals(lines1[i].length, lines2[i].length, "line $i")
|
||||
}
|
||||
|
||||
|
||||
val set = BitSet()
|
||||
|
||||
var index = 0
|
||||
var lineNumber = 0
|
||||
while (index < matching.length) {
|
||||
var end = matching.indexOfAny(listOf("_", "*"), index) + 1
|
||||
if (end == 0) end = matching.length
|
||||
|
||||
val line = matching.subSequence(index, end)
|
||||
if (line.find { it != ' ' && it != '_' } != null) {
|
||||
assert(!line.contains(' '))
|
||||
set.set(lineNumber)
|
||||
}
|
||||
lineNumber++
|
||||
index = end
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun default(vararg expected: Change): Unit {
|
||||
defaultChanges = ContainerUtil.list(*expected)
|
||||
fun default(vararg expected: Couple<IntPair>): Unit {
|
||||
changes.default = ContainerUtil.list(*expected).map { Data(it.first, it.second) }
|
||||
}
|
||||
|
||||
fun trim(vararg expected: Change): Unit {
|
||||
trimChanges = ContainerUtil.list(*expected)
|
||||
fun trim(vararg expected: Couple<IntPair>): Unit {
|
||||
changes.trim = ContainerUtil.list(*expected).map { Data(it.first, it.second) }
|
||||
}
|
||||
|
||||
fun ignore(vararg expected: Change): Unit {
|
||||
ignoreChanges = ContainerUtil.list(*expected)
|
||||
fun ignore(vararg expected: Couple<IntPair>): Unit {
|
||||
changes.ignore = ContainerUtil.list(*expected).map { Data(it.first, it.second) }
|
||||
}
|
||||
|
||||
fun mod(line1: Int, line2: Int, count1: Int, count2: Int): Change {
|
||||
fun mod(line1: Int, line2: Int, count1: Int, count2: Int): Couple<IntPair> {
|
||||
assert(count1 != 0)
|
||||
assert(count2 != 0)
|
||||
return Change(line1, line1 + count1, line2, line2 + count2)
|
||||
return Couple(IntPair(line1, line1 + count1), IntPair(line2, line2 + count2))
|
||||
}
|
||||
|
||||
fun del(line1: Int, line2: Int, count1: Int): Change {
|
||||
fun del(line1: Int, line2: Int, count1: Int): Couple<IntPair> {
|
||||
assert(count1 != 0)
|
||||
return Change(line1, line1 + count1, line2, line2)
|
||||
return Couple(IntPair(line1, line1 + count1), IntPair(line2, line2))
|
||||
}
|
||||
|
||||
fun ins(line1: Int, line2: Int, count2: Int): Change {
|
||||
fun ins(line1: Int, line2: Int, count2: Int): Couple<IntPair> {
|
||||
assert(count2 != 0)
|
||||
return Change(line1, line1, line2, line2 + count2)
|
||||
return Couple(IntPair(line1, line1), IntPair(line2, line2 + count2))
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +450,8 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
|
||||
internal fun lines(f: TestBuilder.() -> Unit): Unit = doTest(TestType.LINE, f)
|
||||
|
||||
internal fun lines_inner(f: TestBuilder.() -> Unit): Unit = doTest(TestType.LINE_INNER, f)
|
||||
|
||||
internal fun words(f: TestBuilder.() -> Unit): Unit = doTest(TestType.WORD, f)
|
||||
|
||||
internal fun chars(f: TestBuilder.() -> Unit): Unit = doTest(TestType.CHAR, f)
|
||||
@@ -382,9 +473,28 @@ abstract class ComparisonUtilTestBase : DiffTestCase() {
|
||||
// Helpers
|
||||
//
|
||||
|
||||
data class Change(val start1: Int, val end1: Int, val start2: Int, val end2: Int) {
|
||||
override fun toString(): String {
|
||||
return "($start1, $end1) - ($start2, $end2)"
|
||||
private data class Data<T>(var before: T?, var base: T?, var after: T?) {
|
||||
constructor() : this(null, null, null)
|
||||
constructor(before: T?, after : T?) : this(before, null, after)
|
||||
fun isTwoSide(): Boolean = before != null && after != null && base == null
|
||||
fun isThreeSide(): Boolean = before != null && after != null && base != null
|
||||
fun asCouple(): Couple<T> {
|
||||
assert(isTwoSide())
|
||||
return Couple(before!!, after!!)
|
||||
}
|
||||
|
||||
fun asTrio(): Trio<T> {
|
||||
assert(isThreeSide())
|
||||
return Trio(before!!, base!!, after!!)
|
||||
}
|
||||
}
|
||||
|
||||
private data class PolicyData<T>(var default: T? = null, var trim: T? = null, var ignore: T? = null) {
|
||||
fun get(policy: ComparisonPolicy): T? =
|
||||
when (policy) {
|
||||
ComparisonPolicy.IGNORE_WHITESPACES -> ignore ?: trim ?: default
|
||||
ComparisonPolicy.TRIM_WHITESPACES -> trim ?: default
|
||||
ComparisonPolicy.DEFAULT -> default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,25 +187,31 @@ class MergeResolveUtilTest : DiffTestCase() {
|
||||
)
|
||||
}
|
||||
|
||||
fun testRegressions() {
|
||||
test(
|
||||
"i\n",
|
||||
"i",
|
||||
"\ni",
|
||||
"i\n",
|
||||
"i"
|
||||
)
|
||||
}
|
||||
|
||||
private fun testGreedy(base: String, left: String, right: String, expected: String?) {
|
||||
test(base, left, right, expected, true);
|
||||
test(base, left, right, expected, true)
|
||||
}
|
||||
|
||||
private fun test(base: String, left: String, right: String, expected: String?, isGreedy: Boolean = false) {
|
||||
val simpleResult = MergeResolveUtil.tryResolve(left, base, right)
|
||||
val magicResult = MergeResolveUtil.tryGreedyResolve(left, base, right);
|
||||
val expectedSimple = if (isGreedy) null else expected
|
||||
val expectedGreedy = expected
|
||||
test(base, left, right, expectedSimple, expectedGreedy)
|
||||
}
|
||||
|
||||
if (expected == null) {
|
||||
assertNull(simpleResult)
|
||||
assertNull(magicResult)
|
||||
}
|
||||
else if (isGreedy) {
|
||||
assertNull(simpleResult)
|
||||
assertEquals(expected, magicResult)
|
||||
}
|
||||
else {
|
||||
assertEquals(expected, simpleResult)
|
||||
assertEquals(expected, magicResult)
|
||||
}
|
||||
private fun test(base: String, left: String, right: String, expectedSimple: String?, expectedGreedy: String?) {
|
||||
val simpleResult = MergeResolveUtil.tryResolve(left, base, right)
|
||||
val greedyResult = MergeResolveUtil.tryGreedyResolve(left, base, right)
|
||||
|
||||
assertEquals(expectedSimple, simpleResult, "Simple")
|
||||
assertEquals(expectedGreedy, greedyResult, "Greedy")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,72 +17,72 @@ package com.intellij.diff.comparison
|
||||
|
||||
class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
fun testSimpleCases() {
|
||||
words {
|
||||
lines_inner {
|
||||
("x z" - "y z")
|
||||
("- " - "- ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x z" - "y z")
|
||||
("- " - "- ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" x z" - "y z")
|
||||
("-- " - "- ").default()
|
||||
(" - " - "- ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x z " - "y z")
|
||||
("- -" - "- ").default()
|
||||
("- " - "- ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x z " - "y z")
|
||||
("- -" - "- ").default()
|
||||
("- " - "- ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x z" - " y z ")
|
||||
("- " - "-- -").default()
|
||||
("- " - " - ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x y" - "x z ")
|
||||
(" -" - " --").default()
|
||||
(" -" - " - ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x,y" - "x")
|
||||
(" --" - " ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x,y" - "y")
|
||||
("-- " - " ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(".x=" - ".!=")
|
||||
(" - " - " - ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("X xyz1 Z" - "X xyz2 Z")
|
||||
(" ---- " - " ---- ").default()
|
||||
testAll()
|
||||
@@ -90,52 +90,52 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun testPunctuation() {
|
||||
words {
|
||||
lines_inner {
|
||||
(" x.z.x " - "x..x")
|
||||
("- - -" - " ").default()
|
||||
(" - " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x..x" - " x.z.x ")
|
||||
(" " - "- - -").default()
|
||||
(" " - " - ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x ... z" - "y ... z")
|
||||
("- " - "- ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x ... z" - "x ... y")
|
||||
(" -" - " -").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x ,... z" - "x ... y")
|
||||
(" - -" - " -").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x . , .. z" - "x ... y")
|
||||
(" --- -" - " -").default()
|
||||
(" - -" - " -").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x==y==z" - "x====z")
|
||||
(" - " - " ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x====z" - "x==t==z")
|
||||
(" " - " - ").default()
|
||||
testAll()
|
||||
@@ -143,13 +143,13 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun testOldDiffBug() {
|
||||
words {
|
||||
lines_inner {
|
||||
("x'y'>" - "x'>")
|
||||
(" -- " - " ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x'>" - "x'y'>")
|
||||
(" " - " -- ").default()
|
||||
testAll()
|
||||
@@ -157,14 +157,14 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun testWhitespaceOnlyChanges() {
|
||||
words {
|
||||
lines_inner {
|
||||
("x =z" - "x= z")
|
||||
(" -- " - " -- ").default()
|
||||
testDefault()
|
||||
testTrim()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x =" - "x= z")
|
||||
(" -- " - " ---").default()
|
||||
(" " - " -").ignore()
|
||||
@@ -173,7 +173,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun testNewlines() {
|
||||
words {
|
||||
lines_inner {
|
||||
(" x _ y _ z " - "x z")
|
||||
("- ------ -" - " ").default()
|
||||
(" - " - " ").trim()
|
||||
@@ -181,17 +181,48 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x z" - " x _ y _ z ")
|
||||
(" " - "- ------ -").default()
|
||||
(" " - " - ").trim()
|
||||
(" " - " - ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("_i" - "i_")
|
||||
("- " - " -").default()
|
||||
(" " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("i_" - "_i")
|
||||
("- " - " -").default() // TODO
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("x_y" - "xy")
|
||||
(" " - " ").ignore()
|
||||
testIgnore()
|
||||
}
|
||||
|
||||
words {
|
||||
("A x_y B" - "a xy b")
|
||||
("-------" - "------").ignore()
|
||||
testIgnore()
|
||||
}
|
||||
|
||||
words {
|
||||
("A xy B" - "a xy b")
|
||||
("- -" - "- -").ignore()
|
||||
testIgnore()
|
||||
}
|
||||
}
|
||||
|
||||
fun testFixedBugs() {
|
||||
words {
|
||||
lines_inner {
|
||||
(".! " - ". y!")
|
||||
(" -" - " --- ").default()
|
||||
(" " - " --- ").trim()
|
||||
@@ -199,7 +230,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" x n" - " y_ x m")
|
||||
(" -" - "---- -").default()
|
||||
(" -" - " - -").trim()
|
||||
@@ -207,7 +238,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x_" - "x! ")
|
||||
(" -" - " ---").default()
|
||||
(" " - " - ").trim()
|
||||
@@ -217,35 +248,35 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun testInnerWhitespaces() {
|
||||
words {
|
||||
lines_inner {
|
||||
("<< x >>" - "<.<>.>")
|
||||
(" --- " - " - - ").default()
|
||||
(" - " - " - - ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("<< x >>" - "y<<x>>y")
|
||||
(" - - " - "- -").default()
|
||||
(" " - "- -").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x .. z" - "x y .. z")
|
||||
(" " - " -- ").default() // TODO: looks wrong
|
||||
(" " - " -- ").default()
|
||||
(" " - " - ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" x..z" - "x..y ")
|
||||
("-- -" - " ---").default()
|
||||
(" -" - " - ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" x y x _ x z x " - "x x_x x")
|
||||
("- -- - - -- -" - " ").default()
|
||||
(" -- -- " - " ").trim()
|
||||
@@ -256,28 +287,28 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
|
||||
fun testAlgorithmSpecific() {
|
||||
// prefer words over punctuation
|
||||
words {
|
||||
lines_inner {
|
||||
("...x" - "x...")
|
||||
("--- " - " ---").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
// prefer longer words sequences
|
||||
words {
|
||||
lines_inner {
|
||||
("x x y" - "x y")
|
||||
("-- " - " ").default()
|
||||
("- " - " ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("y x x" - "y x")
|
||||
(" --" - " ").default()
|
||||
(" -" - " ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("A X A B" - "A B")
|
||||
("---- " - " ").default()
|
||||
("--- " - " ").ignore()
|
||||
@@ -285,14 +316,14 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
// prefer less modified 'sentences'
|
||||
words {
|
||||
lines_inner {
|
||||
("A.X A.Z" - "A.X A.Y A.Z")
|
||||
(" " - " ---- ").default()
|
||||
(" " - " --- ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("X.A Z.A" - "X.A Y.A Z.A")
|
||||
(" " - " ---- ").default()
|
||||
(" " - " --- ").ignore()
|
||||
@@ -300,7 +331,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
// prefer punctuation over whitespaces
|
||||
words {
|
||||
lines_inner {
|
||||
(". " - " .")
|
||||
(" ---" - "--- ").default()
|
||||
testDefault()
|
||||
@@ -308,26 +339,26 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun `test legacy cases from ByWordTest`() {
|
||||
words {
|
||||
lines_inner {
|
||||
("abc def, 123" - "ab def, 12")
|
||||
("--- ---" - "-- --").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" a[xy]+1" - ",a[]+1")
|
||||
("- -- " - "- ").default()
|
||||
(" -- " - "- ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("0987_ a.g();_" - "yyyy_")
|
||||
("------------- " - "---- ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" abc_2222_" - " x = abc_zzzz_")
|
||||
//(" ---- " - "-- ---- ---- ").legacy()
|
||||
(" ---- " - " ------ ---- ").default()
|
||||
@@ -335,7 +366,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words { // Idea58505
|
||||
lines_inner { // Idea58505
|
||||
(" if (eventMerger!=null && !dataSelection.getValueIsAdjusting()) {" -
|
||||
" if (eventMerger!=null && (dataSelection==null || !dataSelection.getValueIsAdjusting())) {")
|
||||
//(" - " -
|
||||
@@ -347,7 +378,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words { // Idea56428
|
||||
lines_inner { // Idea56428
|
||||
("messageInsertStatement = connection.prepareStatement(\"INSERT INTO AUDIT (AUDIT_TYPE_ID, STATUS, SERVER_ID, INSTANCE_ID, REQUEST_ID) VALUES (?, ?, ?, ?, ?)\");" -
|
||||
"messageInsertStatement = connection.prepareStatement(\"INSERT INTO AUDIT (AUDIT_TYPE_ID, CREATION_TIMESTAMP, STATUS, SERVER_ID, INSTANCE_ID, REQUEST_ID) VALUES (?, ?, ?, ?, ?, ?)\");").plainSource()
|
||||
//(" . . " -
|
||||
@@ -359,14 +390,14 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("f(a, b);" - "f(a,_ b);")
|
||||
(" " - " -- ").default()
|
||||
(" " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" o.f(a)" - "o. f( b)")
|
||||
("- - " - " - -- ").default()
|
||||
(" - " - " - -- ").trim()
|
||||
@@ -374,7 +405,7 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
(" 123 " - "xyz")
|
||||
(" --- " - "---").trim()
|
||||
testTrim()
|
||||
@@ -382,14 +413,14 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
}
|
||||
|
||||
fun testEmptyRangePositions() {
|
||||
words {
|
||||
lines_inner {
|
||||
("x? y" - "x y")
|
||||
(" - " - " ").default()
|
||||
default(del(1, 1, 1))
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
lines_inner {
|
||||
("x ?y" - "x y")
|
||||
(" - " - " ").default()
|
||||
default(del(2, 2, 1))
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.diff.comparison
|
||||
|
||||
class WordMergeComparisonUtilTest : ComparisonUtilTestBase() {
|
||||
fun testSimple() {
|
||||
words {
|
||||
("" - "" - "")
|
||||
("" - "" - "").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("" - "X" - "")
|
||||
("" - "-" - "").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("X" - "" - "")
|
||||
("-" - "" - "").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("a b" - "a b" - "a b")
|
||||
(" " - " " - " ").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("A b c" - "a b c" - "a b C")
|
||||
("- -" - "- -" - "- -").default()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("a c" - "a c" - "a X c")
|
||||
(" " - " " - " -- ").default()
|
||||
(" " - " " - " - ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("a X c" - "a X c" - "a c")
|
||||
(" -- " - " -- " - " ").default()
|
||||
(" - " - " - " - " ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("a X c" - "a c" - "a Y c")
|
||||
(" -- " - " " - " -- ").default()
|
||||
(" - " - " " - " - ").ignore()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("a c" - "a X c" - "a Y c")
|
||||
(" " - " -- " - " -- ").default()
|
||||
(" " - " - " - " - ").ignore()
|
||||
testAll()
|
||||
}
|
||||
}
|
||||
|
||||
fun testNewlines() {
|
||||
words {
|
||||
("i" - "i_" - "_i")
|
||||
("-" - "--" - "--").default() // TODO
|
||||
(" " - " " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("_i" - "i_" - "i")
|
||||
("--" - "--" - "-").default()
|
||||
(" " - " " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("i" - "_i" - "i_")
|
||||
(" " - "- " - " -").default()
|
||||
(" " - " " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
|
||||
words {
|
||||
("_i" - "i" - "i_")
|
||||
("- " - " " - " -").default()
|
||||
(" " - " " - " ").trim()
|
||||
testAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ class MergeAutoTest : MergeTestBase() {
|
||||
private fun doUndoTest(seed: Long, runs: Int, maxLength: Int) {
|
||||
doTest(seed, runs, maxLength) { text1, text2, text3, debugData ->
|
||||
testN(text1, text2, text3) {
|
||||
if (changes.size == 0) {
|
||||
if (changes.isEmpty()) {
|
||||
assertEquals(text1, text2)
|
||||
assertEquals(text1, text3)
|
||||
assertEquals(text2, text3)
|
||||
|
||||
@@ -99,7 +99,7 @@ abstract class MergeTestBase : DiffTestCase() {
|
||||
val editor: EditorEx = viewer.editor
|
||||
val document: Document = editor.document
|
||||
|
||||
private val textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
|
||||
private val textEditor = TextEditorProvider.getInstance().getTextEditor(editor)
|
||||
private val undoManager = UndoManager.getInstance(project!!)
|
||||
|
||||
fun change(num: Int): TextMergeChange {
|
||||
@@ -114,7 +114,7 @@ abstract class MergeTestBase : DiffTestCase() {
|
||||
//
|
||||
|
||||
fun runActionByTitle(name: String): Boolean {
|
||||
val action = actions.filter { name.equals(it.templatePresentation.text) }
|
||||
val action = actions.filter { name == it.templatePresentation.text }
|
||||
assertTrue(action.size == 1, action.toString())
|
||||
return runAction(action[0])
|
||||
}
|
||||
@@ -396,7 +396,7 @@ abstract class MergeTestBase : DiffTestCase() {
|
||||
if (other !is ViewerState) return false
|
||||
|
||||
if (!StringUtil.equals(content, other.content)) return false
|
||||
if (!changes.equals(other.changes)) return false
|
||||
if (changes != other.changes) return false
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -411,9 +411,9 @@ abstract class MergeTestBase : DiffTestCase() {
|
||||
if (other !is ChangeState) return false
|
||||
|
||||
if (!StringUtil.equals(content, other.content)) return false
|
||||
if (!starts.equals(other.starts)) return false
|
||||
if (!ends.equals(other.ends)) return false
|
||||
if (!resolved.equals(other.resolved)) return false
|
||||
if (starts != other.starts) return false
|
||||
if (ends != other.ends) return false
|
||||
if (resolved != other.resolved) return false
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -175,6 +175,7 @@ class LineNumberConvertorCorrectorTest : UsefulTestCase() {
|
||||
assertEquals(minimumMatched2, counter2)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun printMatchings() {
|
||||
for (i in 0..length * 2 - 1) {
|
||||
val value = convertor.convert1(i)
|
||||
|
||||
+2
-2
@@ -34,8 +34,8 @@ class UnifiedFragmentBuilderAutoTest : DiffTestCase() {
|
||||
doAutoTest(seed, runs) { debugData ->
|
||||
debugData.put("MaxLength", maxLength)
|
||||
|
||||
var text1 = DocumentImpl(generateText(maxLength))
|
||||
var text2 = DocumentImpl(generateText(maxLength))
|
||||
val text1 = DocumentImpl(generateText(maxLength))
|
||||
val text2 = DocumentImpl(generateText(maxLength))
|
||||
|
||||
debugData.put("Text1", textToReadableFormat(text1.charsSequence))
|
||||
debugData.put("Text2", textToReadableFormat(text2.charsSequence))
|
||||
|
||||
@@ -38,9 +38,7 @@ public class VfsEventsMerger {
|
||||
while (true) {
|
||||
ChangeInfo existingChangeInfo = myChangeInfos.get(fileId);
|
||||
ChangeInfo newChangeInfo = new ChangeInfo(file, mask, existingChangeInfo);
|
||||
boolean replaced = existingChangeInfo == null ? myChangeInfos.putIfAbsent(fileId, newChangeInfo) == null
|
||||
: myChangeInfos.replace(fileId, existingChangeInfo, newChangeInfo);
|
||||
if (replaced) break;
|
||||
if(myChangeInfos.put(fileId, newChangeInfo) == existingChangeInfo) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -2,7 +2,7 @@
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog.PluginUpdateInfoPanel">
|
||||
<grid id="18751" binding="myPanel" layout-manager="GridBagLayout">
|
||||
<constraints>
|
||||
<xy x="63" y="44" width="604" height="510"/>
|
||||
<xy x="63" y="44" width="604" height="522"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -13,7 +13,6 @@
|
||||
<gridbag weightx="1.0" weighty="0.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<preferredSize width="268" height="30"/>
|
||||
<text resource-bundle="messages/IdeBundle" key="updates.plugins.ready.header"/>
|
||||
</properties>
|
||||
</component>
|
||||
|
||||
@@ -21,4 +21,5 @@ public class SSHUtil {
|
||||
public static final Pattern PASSPHRASE_PROMPT = Pattern.compile("Enter passphrase for key \\'(.*)\\':\\s?");
|
||||
public static final Pattern PASSWORD_PROMPT = Pattern.compile("(.*)\\'s password:\\s?");
|
||||
public static final String PASSWORD_PROMPT_SUFFIX = "password:";
|
||||
public static final String CONFIRM_CONNECTION_PROMPT = "Are you sure you want to continue connecting";
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
// unless stated otherwise, the behavior described in cases is true for 162+
|
||||
class UpdateStrategyTest {
|
||||
@Test fun `channel contains no builds`() {
|
||||
val result = check("IU-145.258", ChannelStatus.RELEASE, """<channel id="IDEA_Release" status="release" licensing="release"/>""")
|
||||
@@ -150,6 +151,7 @@ class UpdateStrategyTest {
|
||||
assertBuild("143.2332", result.newBuild)
|
||||
}
|
||||
|
||||
// since 163
|
||||
@Test fun `updates from the same baseline are preferred (per-release channels)`() {
|
||||
val result = check("IU-143.2287", ChannelStatus.EAP, """
|
||||
<channel id="IDEA_143_EAP" status="eap" licensing="eap">
|
||||
|
||||
Reference in New Issue
Block a user