get rid of duplicated code in editor fixtures (IDEA-80056)

This commit is contained in:
Dmitry Batrak
2014-02-25 11:53:27 +04:00
parent 70aaf37aea
commit ff01b5b40c
6 changed files with 202 additions and 480 deletions
@@ -39,7 +39,6 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
@@ -421,46 +420,10 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
}
protected void setupCursorAndSelection(@NotNull final Editor editor) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Document document = editor.getDocument();
EditorTestUtil.CaretsState caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
final String newText = document.getText();
if (editor.getCaretModel().supportsMultipleCarets()) {
List<LogicalPosition> caretPositions = new ArrayList<LogicalPosition>();
List<Segment> selections = new ArrayList<Segment>();
for (EditorTestUtil.Caret caret : caretState.carets) {
LogicalPosition pos = null;
if (caret.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(newText, caret.offset);
int caretCol = caret.offset - StringUtil.lineColToOffset(newText, caretLine, 0);
pos = new LogicalPosition(caretLine, caretCol);
}
caretPositions.add(pos);
selections.add(caret.selection == null ? null : caret.selection);
}
editor.getCaretModel().setCaretsAndSelections(caretPositions, selections);
}
else {
assert caretState.carets.size() == 1 : "Multiple carets are not supported by the model";
EditorTestUtil.Caret caret = caretState.carets.get(0);
if (caret.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(newText, caret.offset);
int caretCol = caret.offset - StringUtil.lineColToOffset(newText, caretLine, 0);
LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
editor.getCaretModel().moveToLogicalPosition(pos);
}
if (caret.selection != null) {
editor.getSelectionModel().setSelection(caret.selection.getStartOffset(), caret.selection.getEndOffset());
}
}
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
}
});
Document document = editor.getDocument();
EditorTestUtil.CaretAndSelectionState caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
EditorTestUtil.setCaretsAndSelection(editor, caretState);
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
}
@Override
@@ -516,7 +479,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
String fileText = StringUtil.convertLineSeparators(ft);
Document document = EditorFactory.getInstance().createDocument(fileText);
EditorTestUtil.CaretsState caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
EditorTestUtil.CaretAndSelectionState caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
String newFileText = document.getText();
String newFileText1 = newFileText;
@@ -536,47 +499,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
assertEquals("Text mismatch in file " + filePath, newFileText1, text);
CaretModel caretModel = myEditor.getCaretModel();
List<Caret> allCarets = new ArrayList<Caret>(caretModel.getAllCarets());
assertEquals("Unexpected number of carets", caretState.carets.size(), allCarets.size());
for (int i = 0; i < caretState.carets.size(); i++) {
String caretDescription = caretState.carets.size() == 1 ? "" : "caret " + (i + 1) + "/" + caretState.carets.size() + " ";
Caret currentCaret = allCarets.get(i);
LogicalPosition actualCaretPosition = currentCaret.getLogicalPosition();
EditorTestUtil.Caret expected = caretState.carets.get(i);
if (expected.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(newFileText, expected.offset);
int caretCol = expected.offset - StringUtil.lineColToOffset(newFileText, caretLine, 0);
assertEquals(caretDescription + "caretLine", caretLine + 1, actualCaretPosition.line + 1);
assertEquals(caretDescription + "caretColumn", caretCol + 1, actualCaretPosition.column + 1);
}
int actualSelectionStart = currentCaret.getSelectionStart();
int actualSelectionEnd = currentCaret.getSelectionEnd();
if (expected.selection != null) {
int selStartLine = StringUtil.offsetToLineNumber(newFileText, expected.selection.getStartOffset());
int selStartCol = expected.selection.getStartOffset() - StringUtil.lineColToOffset(newFileText, selStartLine, 0);
int selEndLine = StringUtil.offsetToLineNumber(newFileText, expected.selection.getEndOffset());
int selEndCol = expected.selection.getEndOffset() - StringUtil.lineColToOffset(newFileText, selEndLine, 0);
assertEquals(caretDescription + "selectionStartLine", selStartLine + 1,
StringUtil.offsetToLineNumber(newFileText, actualSelectionStart) + 1);
assertEquals(caretDescription + "selectionStartCol", selStartCol + 1,
actualSelectionStart - StringUtil.lineColToOffset(newFileText, selStartLine, 0) + 1);
assertEquals(caretDescription + "selectionEndLine", selEndLine + 1,
StringUtil.offsetToLineNumber(newFileText, actualSelectionEnd) + 1);
assertEquals(caretDescription + "selectionEndCol", selEndCol + 1,
actualSelectionEnd - StringUtil.lineColToOffset(newFileText, selEndLine, 0) + 1);
}
else {
assertFalse(caretDescription + "should has no selection, but was: (" + actualSelectionStart + ", " + actualSelectionEnd + ")",
currentCaret.hasSelection());
}
}
EditorTestUtil.verifyCaretAndSelectionState(myEditor, caretState);
}
}.execute();
}
@@ -15,34 +15,20 @@
*/
package com.intellij.codeInsight;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.testFramework.EditorTestUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author cdr
*/
public class EditorInfo {
String newFileText = null;
public EditorTestUtil.CaretsState caretState;
public EditorTestUtil.CaretAndSelectionState caretState;
public EditorInfo(final String fileText) {
new WriteCommandAction(null){
@Override
protected void run(@NotNull Result result) throws Throwable {
updateCaretAndSelection(EditorFactory.getInstance().createDocument(fileText));
}
}.execute();
}
private void updateCaretAndSelection(final Document document) {
Document document = EditorFactory.getInstance().createDocument(fileText);
caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document, false);
newFileText = document.getText();
}
@@ -52,33 +38,6 @@ public class EditorInfo {
}
public void applyToEditor(Editor editor) {
if (editor.getCaretModel().supportsMultipleCarets()) {
List<LogicalPosition> caretPositions = new ArrayList<LogicalPosition>();
List<Segment> selections = new ArrayList<Segment>();
for (EditorTestUtil.Caret caret : caretState.carets) {
LogicalPosition pos = null;
if (caret.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(newFileText, caret.offset);
int caretCol = caret.offset - StringUtil.lineColToOffset(newFileText, caretLine, 0);
pos = new LogicalPosition(caretLine, caretCol);
}
caretPositions.add(pos);
selections.add(caret.selection == null ? null : caret.selection);
}
editor.getCaretModel().setCaretsAndSelections(caretPositions, selections);
}
else {
assert caretState.carets.size() == 1 : "Multiple carets are not supported by the model";
EditorTestUtil.Caret caret = caretState.carets.get(0);
if (caret.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(newFileText, caret.offset);
int caretCol = caret.offset - StringUtil.lineColToOffset(newFileText, caretLine, 0);
LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
editor.getCaretModel().moveToLogicalPosition(pos);
}
if (caret.selection != null) {
editor.getSelectionModel().setSelection(caret.selection.getStartOffset(), caret.selection.getEndOffset());
}
}
EditorTestUtil.setCaretsAndSelection(editor, caretState);
}
}
@@ -15,9 +15,6 @@
*/
package com.intellij.openapi.editor;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.HeavyFileEditorManagerTestCase;
@@ -26,7 +23,6 @@ import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.EditorTestUtil;
import org.jetbrains.annotations.NotNull;
public class EditorMultiCaretStateRestoreTest extends HeavyFileEditorManagerTestCase {
public void testRestoreState() throws Exception {
@@ -54,12 +50,7 @@ public class EditorMultiCaretStateRestoreTest extends HeavyFileEditorManagerTest
private static void verifyEditorState(Editor editor, String textWithMarkup) {
final Document document = new DocumentImpl(textWithMarkup);
EditorTestUtil.CaretsState caretAndSelectionState = new WriteCommandAction<EditorTestUtil.CaretsState>(null) {
@Override
protected void run(@NotNull Result<EditorTestUtil.CaretsState> result) throws Throwable {
result.setResult(EditorTestUtil.extractCaretAndSelectionMarkers(document));
}
}.execute().getResultObject();
EditorTestUtil.CaretAndSelectionState caretAndSelectionState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
assertEquals(document.getCharsSequence().toString(), editor.getDocument().getText());
EditorTestUtil.verifyCaretAndSelectionState(editor, caretAndSelectionState);
}
@@ -17,6 +17,8 @@ package com.intellij.testFramework;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
@@ -26,6 +28,7 @@ import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.impl.DefaultEditorTextRepresentationHelper;
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
import com.intellij.openapi.editor.impl.softwrap.mapping.SoftWrapApplianceManager;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -188,7 +191,7 @@ public class EditorTestUtil {
*
* @see #extractCaretAndSelectionMarkers(com.intellij.openapi.editor.Document, boolean)
*/
public static CaretsState extractCaretAndSelectionMarkers(Document document) {
public static CaretAndSelectionState extractCaretAndSelectionMarkers(Document document) {
return extractCaretAndSelectionMarkers(document, true);
}
@@ -196,119 +199,177 @@ public class EditorTestUtil {
* Removes &lt;caret&gt;, &lt;selection&gt; and &lt;/selection&gt; tags from document and returns a list of caret positions and selection
* ranges for each caret. Both caret positions and selection ranges can be null in the returned data.
*
* Should be invoked in write action, as it modifies the document!
*
* @param processBlockSelection if <code>true</code>, &lt;block&gt; and &lt;/block&gt; tags describing a block selection state will also be extracted.
*/
public static CaretsState extractCaretAndSelectionMarkers(Document document, boolean processBlockSelection) {
CaretsState result = new CaretsState();
public static CaretAndSelectionState extractCaretAndSelectionMarkers(final Document document, final boolean processBlockSelection) {
return new WriteCommandAction<CaretAndSelectionState>(null) {
@Override
public void run(@NotNull Result<CaretAndSelectionState> actionResult) {
final CaretAndSelectionState result = new CaretAndSelectionState();
String fileText = document.getText();
String fileText = document.getText();
RangeMarker blockSelectionStartMarker = null;
RangeMarker blockSelectionEndMarker = null;
if (processBlockSelection) {
int blockSelectionStart = fileText.indexOf(BLOCK_SELECTION_START_TAG);
int blockSelectionEnd = fileText.indexOf(BLOCK_SELECTION_END_TAG);
if ((blockSelectionStart ^ blockSelectionEnd) < 0) {
throw new IllegalArgumentException("Both block selection opening and closing tag must be present");
}
if (blockSelectionStart >= 0) {
blockSelectionStartMarker = document.createRangeMarker(blockSelectionStart, blockSelectionStart);
blockSelectionEndMarker = document.createRangeMarker(blockSelectionEnd, blockSelectionEnd);
document.deleteString(blockSelectionStartMarker.getStartOffset(), blockSelectionStartMarker.getStartOffset() + BLOCK_SELECTION_START_TAG.length());
document.deleteString(blockSelectionEndMarker.getStartOffset(), blockSelectionEndMarker.getStartOffset() + BLOCK_SELECTION_END_TAG.length());
}
}
RangeMarker blockSelectionStartMarker = null;
RangeMarker blockSelectionEndMarker = null;
if (processBlockSelection) {
int blockSelectionStart = fileText.indexOf(BLOCK_SELECTION_START_TAG);
int blockSelectionEnd = fileText.indexOf(BLOCK_SELECTION_END_TAG);
if ((blockSelectionStart ^ blockSelectionEnd) < 0) {
throw new IllegalArgumentException("Both block selection opening and closing tag must be present");
}
if (blockSelectionStart >= 0) {
blockSelectionStartMarker = document.createRangeMarker(blockSelectionStart, blockSelectionStart);
blockSelectionEndMarker = document.createRangeMarker(blockSelectionEnd, blockSelectionEnd);
document.deleteString(blockSelectionStartMarker.getStartOffset(), blockSelectionStartMarker.getStartOffset() + BLOCK_SELECTION_START_TAG.length());
document.deleteString(blockSelectionEndMarker.getStartOffset(), blockSelectionEndMarker.getStartOffset() + BLOCK_SELECTION_END_TAG.length());
}
}
boolean multiCaret = StringUtil.getOccurrenceCount(document.getText(), CARET_TAG) > 1
|| StringUtil.getOccurrenceCount(document.getText(), SELECTION_START_TAG) > 1;
int pos = 0;
while (pos < document.getTextLength()) {
fileText = document.getText();
int caretIndex = fileText.indexOf(CARET_TAG, pos);
int selStartIndex = fileText.indexOf(SELECTION_START_TAG, pos);
int selEndIndex = fileText.indexOf(SELECTION_END_TAG, pos);
boolean multiCaret = StringUtil.getOccurrenceCount(document.getText(), CARET_TAG) > 1
|| StringUtil.getOccurrenceCount(document.getText(), SELECTION_START_TAG) > 1;
int pos = 0;
while (pos < document.getTextLength()) {
fileText = document.getText();
int caretIndex = fileText.indexOf(CARET_TAG, pos);
int selStartIndex = fileText.indexOf(SELECTION_START_TAG, pos);
int selEndIndex = fileText.indexOf(SELECTION_END_TAG, pos);
if ((selStartIndex ^ selEndIndex) < 0) {
selStartIndex = -1;
selEndIndex = -1;
}
if (0 <= selEndIndex && selEndIndex < selStartIndex) {
throw new IllegalArgumentException("Wrong order of selection opening and closing tags");
}
if (caretIndex < 0 && selStartIndex < 0 && selEndIndex < 0) {
break;
}
if (multiCaret && 0 <= caretIndex && caretIndex < selStartIndex) {
selStartIndex = -1;
selEndIndex = -1;
}
if (multiCaret && caretIndex > selEndIndex && selEndIndex >= 0) {
caretIndex = -1;
}
if ((selStartIndex ^ selEndIndex) < 0) {
selStartIndex = -1;
selEndIndex = -1;
}
if (0 <= selEndIndex && selEndIndex < selStartIndex) {
throw new IllegalArgumentException("Wrong order of selection opening and closing tags");
}
if (caretIndex < 0 && selStartIndex < 0 && selEndIndex < 0) {
break;
}
if (multiCaret && 0 <= caretIndex && caretIndex < selStartIndex) {
selStartIndex = -1;
selEndIndex = -1;
}
if (multiCaret && caretIndex > selEndIndex && selEndIndex >= 0) {
caretIndex = -1;
}
final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
final RangeMarker selStartMarker = selStartIndex >= 0
? document.createRangeMarker(selStartIndex, selStartIndex)
: null;
final RangeMarker selEndMarker = selEndIndex >= 0
? document.createRangeMarker(selEndIndex, selEndIndex)
: null;
final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
final RangeMarker selStartMarker = selStartIndex >= 0
? document.createRangeMarker(selStartIndex, selStartIndex)
: null;
final RangeMarker selEndMarker = selEndIndex >= 0
? document.createRangeMarker(selEndIndex, selEndIndex)
: null;
if (caretMarker != null) {
document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_TAG.length());
}
if (selStartMarker != null) {
document.deleteString(selStartMarker.getStartOffset(),
selStartMarker.getStartOffset() + SELECTION_START_TAG.length());
}
if (selEndMarker != null) {
document.deleteString(selEndMarker.getStartOffset(),
selEndMarker.getStartOffset() + SELECTION_END_TAG.length());
}
if (caretMarker != null) {
document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_TAG.length());
LogicalPosition caretPosition = null;
if (caretMarker != null) {
int line = document.getLineNumber(caretMarker.getStartOffset());
int column = caretMarker.getStartOffset() - document.getLineStartOffset(line);
caretPosition = new LogicalPosition(line, column);
}
result.carets.add(new CaretInfo(caretPosition,
selStartMarker == null || selEndMarker == null
? null
: new TextRange(selStartMarker.getStartOffset(), selEndMarker.getEndOffset())));
pos = Math.max(caretMarker == null ? -1 : caretMarker.getStartOffset(), selEndMarker == null ? -1 : selEndMarker.getEndOffset());
}
if (result.carets.isEmpty()) {
result.carets.add(new CaretInfo(null, null));
}
if (blockSelectionStartMarker != null) {
result.blockSelection = new TextRange(blockSelectionStartMarker.getStartOffset(), blockSelectionEndMarker.getStartOffset());
}
actionResult.setResult(result);
}
if (selStartMarker != null) {
document.deleteString(selStartMarker.getStartOffset(),
selStartMarker.getStartOffset() + SELECTION_START_TAG.length());
}
if (selEndMarker != null) {
document.deleteString(selEndMarker.getStartOffset(),
selEndMarker.getStartOffset() + SELECTION_END_TAG.length());
}
result.carets.add(new Caret(caretMarker == null ? null : caretMarker.getStartOffset(),
selStartMarker == null || selEndMarker == null
? null
: new TextRange(selStartMarker.getStartOffset(), selEndMarker.getEndOffset())));
pos = Math.max(caretMarker == null ? -1 : caretMarker.getStartOffset(), selEndMarker == null ? -1 : selEndMarker.getEndOffset());
}
if (result.carets.isEmpty()) {
result.carets.add(new Caret(null, null));
}
if (blockSelectionStartMarker != null) {
result.blockSelection = new TextRange(blockSelectionStartMarker.getStartOffset(), blockSelectionEndMarker.getStartOffset());
}
return result;
}.execute().getResultObject();
}
public static void verifyCaretAndSelectionState(Editor editor, CaretsState caretState) {
/**
* Applies given caret/selection state to the editor. Editor text must have been set up previously.
*/
public static void setCaretsAndSelection(Editor editor, CaretAndSelectionState caretsState) {
CaretModel caretModel = editor.getCaretModel();
List<com.intellij.openapi.editor.Caret> allCarets = new ArrayList<com.intellij.openapi.editor.Caret>(caretModel.getAllCarets());
assertEquals("Unexpected number of carets", caretState.carets.size(), allCarets.size());
if (caretModel.supportsMultipleCarets()) {
List<LogicalPosition> caretPositions = new ArrayList<LogicalPosition>();
List<Segment> selections = new ArrayList<Segment>();
for (CaretInfo caret : caretsState.carets) {
caretPositions.add(caret.position == null ? null : editor.offsetToLogicalPosition(caret.getCaretOffset(editor.getDocument())));
selections.add(caret.selection == null ? null : caret.selection);
}
caretModel.setCaretsAndSelections(caretPositions, selections);
}
else {
assertEquals("Multiple carets are not supported by the model", 1, caretsState.carets.size());
CaretInfo caret = caretsState.carets.get(0);
if (caret.position != null) {
caretModel.moveToOffset(caret.getCaretOffset(editor.getDocument()));
}
if (caret.selection != null) {
editor.getSelectionModel().setSelection(caret.selection.getStartOffset(), caret.selection.getEndOffset());
}
}
if (caretsState.blockSelection != null) {
editor.getSelectionModel().setBlockSelection(editor.offsetToLogicalPosition(caretsState.blockSelection.getStartOffset()),
editor.offsetToLogicalPosition(caretsState.blockSelection.getEndOffset()));
}
}
public static void verifyCaretAndSelectionState(Editor editor, CaretAndSelectionState caretState) {
verifyCaretAndSelectionState(editor, caretState, null);
}
public static void verifyCaretAndSelectionState(Editor editor, CaretAndSelectionState caretState, String message) {
boolean hasChecks = false;
for (int i = 0; i < caretState.carets.size(); i++) {
EditorTestUtil.CaretInfo expected = caretState.carets.get(i);
if (expected.position != null || expected.selection != null) {
hasChecks = true;
break;
}
}
if (!hasChecks) {
return; // nothing to check, so we skip caret/selection assertions
}
String messageSuffix = message == null ? "" : (message + ": ");
CaretModel caretModel = editor.getCaretModel();
List<Caret> allCarets = new ArrayList<Caret>(caretModel.getAllCarets());
assertEquals(messageSuffix + " Unexpected number of carets", caretState.carets.size(), allCarets.size());
for (int i = 0; i < caretState.carets.size(); i++) {
String caretDescription = caretState.carets.size() == 1 ? "" : "caret " + (i + 1) + "/" + caretState.carets.size() + " ";
com.intellij.openapi.editor.Caret currentCaret = allCarets.get(i);
LogicalPosition actualCaretPosition = currentCaret.getLogicalPosition();
LogicalPosition actualSelectionStart = editor.offsetToLogicalPosition(currentCaret.getSelectionStart());
LogicalPosition actualSelectionEnd = editor.offsetToLogicalPosition(currentCaret.getSelectionEnd());
EditorTestUtil.Caret expected = caretState.carets.get(i);
if (expected.offset != null) {
LogicalPosition expectedCaretPosition = editor.offsetToLogicalPosition(expected.offset);
assertEquals(caretDescription + "unexpected caret position", expectedCaretPosition, actualCaretPosition);
Caret currentCaret = allCarets.get(i);
int actualCaretLine = editor.getDocument().getLineNumber(currentCaret.getOffset());
int actualCaretColumn = currentCaret.getOffset() - editor.getDocument().getLineStartOffset(actualCaretLine);
LogicalPosition actualCaretPosition = new LogicalPosition(actualCaretLine, actualCaretColumn);
int[] selectionStarts = editor.getSelectionModel().getBlockSelectionStarts();
int[] selectionEnds = editor.getSelectionModel().getBlockSelectionEnds();
int selectionStart = editor.getSelectionModel().hasBlockSelection() ? selectionStarts[selectionStarts.length - 1] : currentCaret.getSelectionStart();
int selectionEnd = editor.getSelectionModel().hasBlockSelection() ? selectionEnds[selectionEnds.length - 1] : currentCaret.getSelectionEnd();
LogicalPosition actualSelectionStart = editor.offsetToLogicalPosition(selectionStart);
LogicalPosition actualSelectionEnd = editor.offsetToLogicalPosition(selectionEnd);
CaretInfo expected = caretState.carets.get(i);
if (expected.position != null) {
assertEquals(messageSuffix + caretDescription + "unexpected caret position", expected.position, actualCaretPosition);
}
if (expected.selection != null) {
LogicalPosition expectedSelectionStart = editor.offsetToLogicalPosition(expected.selection.getStartOffset());
LogicalPosition expectedSelectionEnd = editor.offsetToLogicalPosition(expected.selection.getEndOffset());
assertEquals(caretDescription + "unexpected selection start", expectedSelectionStart, actualSelectionStart);
assertEquals(caretDescription + "unexpected selection end", expectedSelectionEnd, actualSelectionEnd);
assertEquals(messageSuffix + caretDescription + "unexpected selection start", expectedSelectionStart, actualSelectionStart);
assertEquals(messageSuffix + caretDescription + "unexpected selection end", expectedSelectionEnd, actualSelectionEnd);
}
else {
assertFalse(caretDescription + "should has no selection, but was: (" + actualSelectionStart + ", " + actualSelectionEnd + ")",
assertFalse(messageSuffix + caretDescription + "should has no selection, but was: (" + actualSelectionStart + ", " + actualSelectionEnd + ")",
currentCaret.hasSelection());
}
}
@@ -322,22 +383,27 @@ public class EditorTestUtil {
Registry.get("editor.allow.multiple.carets").setValue(false);
}
public static class CaretsState {
@NotNull
public final List<Caret> carets = new ArrayList<Caret>();
public static class CaretAndSelectionState {
public final List<CaretInfo> carets = new ArrayList<CaretInfo>();
@Nullable
public TextRange blockSelection;
}
public static class Caret {
public static class CaretInfo {
@Nullable
public final Integer offset;
public final LogicalPosition position; // column number in this position is calculated in terms of characters,
// not in terms of visual position
// so Tab character always increases the column number by 1
@Nullable
public final TextRange selection;
public Caret(Integer offset, TextRange selection) {
this.offset = offset;
public CaretInfo(@Nullable LogicalPosition position, @Nullable TextRange selection) {
this.position = position;
this.selection = selection;
}
public int getCaretOffset(Document document) {
return document.getLineStartOffset(position.line) + position.column;
}
}
}
@@ -39,9 +39,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
@@ -52,7 +50,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.rt.execution.junit.FileComparisonFailure;
@@ -175,7 +172,7 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
}
final Document fakeDocument = new DocumentImpl(fileText);
EditorTestUtil.CaretsState caretsState = EditorTestUtil.extractCaretAndSelectionMarkers(fakeDocument);
EditorTestUtil.CaretAndSelectionState caretsState = EditorTestUtil.extractCaretAndSelectionMarkers(fakeDocument);
String newFileText = fakeDocument.getText();
Document document;
@@ -185,49 +182,13 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
catch (IOException e) {
throw new RuntimeException(e);
}
setupCaretAndSelection(caretsState, newFileText);
EditorTestUtil.setCaretsAndSelection(myEditor, caretsState);
setupEditorForInjectedLanguage();
result.setResult(document);
}
}.execute().getResultObject();
}
private static void setupCaretAndSelection(EditorTestUtil.CaretsState caretsState, String fileText) {
List<EditorTestUtil.Caret> carets = caretsState.carets;
if (myEditor.getCaretModel().supportsMultipleCarets()) {
List<LogicalPosition> caretPositions = new ArrayList<LogicalPosition>();
List<Segment> selections = new ArrayList<Segment>();
for (EditorTestUtil.Caret caret : carets) {
LogicalPosition pos = null;
if (caret.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(fileText, caret.offset);
int caretCol = EditorUtil.calcColumnNumber(null, myEditor.getDocument().getText(),
myEditor.getDocument().getLineStartOffset(caretLine), caret.offset,
CodeStyleSettingsManager.getSettings(getProject()).getIndentOptions(StdFileTypes.JAVA).TAB_SIZE);
pos = new LogicalPosition(caretLine, caretCol);
}
caretPositions.add(pos);
selections.add(caret.selection == null ? null : caret.selection);
}
myEditor.getCaretModel().setCaretsAndSelections(caretPositions, selections);
}
else {
assertEquals("Caret model doesn't support multiple carets", 1, carets.size());
EditorTestUtil.Caret caret = carets.get(0);
if (caret.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(fileText, caret.offset);
int caretCol = EditorUtil.calcColumnNumber(null, myEditor.getDocument().getText(),
myEditor.getDocument().getLineStartOffset(caretLine), caret.offset,
CodeStyleSettingsManager.getSettings(getProject()).getIndentOptions(StdFileTypes.JAVA).TAB_SIZE);
LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
myEditor.getCaretModel().moveToLogicalPosition(pos);
}
if (caret.selection != null) {
myEditor.getSelectionModel().setSelection(caret.selection.getStartOffset(), caret.selection.getEndOffset());
}
}
}
protected static Editor createEditor(@NotNull VirtualFile file) {
Editor editor = FileEditorManager.getInstance(getProject()).openTextEditor(new OpenFileDescriptor(getProject(), file, 0), false);
((EditorImpl)editor).setCaretActive();
@@ -345,10 +306,10 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
}
/**
* Same as checkResultByFile but text is provided directly.
* @param message - this check specific message. Added to text, caret position, selection checking. May be null
* @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing.
*/
* Same as checkResultByFile but text is provided directly.
* @param message - this check specific message. Added to text, caret position, selection checking. May be null
* @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing.
*/
protected void checkResultByText(final String message, @NotNull String fileText, final boolean ignoreTrailingSpaces) {
checkResultByText(message, fileText, ignoreTrailingSpaces, null);
}
@@ -370,7 +331,7 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
((DocumentImpl)document).stripTrailingSpaces(getProject());
}
EditorTestUtil.CaretsState carets = EditorTestUtil.extractCaretAndSelectionMarkers(document);
EditorTestUtil.CaretAndSelectionState carets = EditorTestUtil.extractCaretAndSelectionMarkers(document);
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
String newFileText = document.getText();
@@ -383,7 +344,7 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
}
assertEquals(failMessage, newFileText, fileText);
checkCaretAndSelectionPositions(carets, newFileText, message);
EditorTestUtil.verifyCaretAndSelectionState(myEditor, carets, message);
}
});
}
@@ -393,63 +354,6 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
return userMessage + " [" + engineMessage + "]";
}
private static String getCaretDescription(int caretNumber, int totalCarets) {
return totalCarets == 1 ? "" : "(caret " + (caretNumber + 1) + "/" + totalCarets + ")";
}
@SuppressWarnings("ConstantConditions")
private static void checkCaretAndSelectionPositions(EditorTestUtil.CaretsState caretState, String newFileText, String message) {
CaretModel caretModel = myEditor.getCaretModel();
List<Caret> allCarets = new ArrayList<Caret>(caretModel.getAllCarets());
assertEquals("Unexpected number of carets", caretState.carets.size(), allCarets.size());
for (int i = 0; i < caretState.carets.size(); i++) {
String caretDescription = getCaretDescription(i, caretState.carets.size());
Caret currentCaret = allCarets.get(i);
LogicalPosition actualCaretPosition = currentCaret.getLogicalPosition();
EditorTestUtil.Caret expected = caretState.carets.get(i);
if (expected.offset != null) {
int caretLine = StringUtil.offsetToLineNumber(newFileText, expected.offset);
int caretCol = EditorUtil.calcColumnNumber(null, newFileText,
StringUtil.lineColToOffset(newFileText, caretLine, 0),
expected.offset,
CodeStyleSettingsManager.getSettings(getProject()).getIndentOptions(StdFileTypes.JAVA).TAB_SIZE);
assertEquals(getMessage("caretLine" + caretDescription, message), caretLine + 1, actualCaretPosition.line + 1);
assertEquals(getMessage("caretColumn" + caretDescription, message), caretCol + 1, actualCaretPosition.column + 1);
}
if (expected.selection != null) {
int selStartLine = StringUtil.offsetToLineNumber(newFileText, expected.selection.getStartOffset());
int selStartCol = expected.selection.getStartOffset() - StringUtil.lineColToOffset(newFileText, selStartLine, 0);
int selEndLine = StringUtil.offsetToLineNumber(newFileText, expected.selection.getEndOffset());
int selEndCol = expected.selection.getEndOffset() - StringUtil.lineColToOffset(newFileText, selEndLine, 0);
assertEquals(
getMessage("selectionStartLine" + caretDescription, message),
selStartLine + 1,
StringUtil.offsetToLineNumber(newFileText, currentCaret.getSelectionStart()) + 1);
assertEquals(
getMessage("selectionStartCol" + caretDescription, message),
selStartCol + 1,
currentCaret.getSelectionStart() - StringUtil.lineColToOffset(newFileText, selStartLine, 0) + 1);
assertEquals(
getMessage("selectionEndLine" + caretDescription, message),
selEndLine + 1,
StringUtil.offsetToLineNumber(newFileText, currentCaret.getSelectionEnd()) + 1);
assertEquals(
getMessage("selectionEndCol" + caretDescription, message),
selEndCol + 1,
currentCaret.getSelectionEnd() - StringUtil.lineColToOffset(newFileText, selEndLine, 0) + 1);
}
else {
assertFalse(getMessage("must not have selection" + caretDescription, message), currentCaret.hasSelection());
}
}
}
@Override
public Object getData(String dataId) {
if (CommonDataKeys.EDITOR.is(dataId)) {
@@ -74,7 +74,6 @@ import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
@@ -86,7 +85,6 @@ import com.intellij.openapi.vfs.*;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
@@ -123,10 +121,6 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Dmitry Avdeev
*/
@@ -1054,7 +1048,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
protected void run(Result result) throws Throwable {
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text, getProject()), getHostFile().getText());
checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text), getHostFile().getText());
}
}.execute();
}
@@ -1307,7 +1301,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
VfsUtil.saveText(vFile, text);
configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile));
}
}.execute();
return myFile;
@@ -1340,7 +1334,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
private PsiFile configureByFileInner(final VirtualFile copy) {
return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy));
}
private PsiFile configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
@@ -1360,32 +1354,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
copy.getPath() +
", use copyFileToProject(..) method for this file instead of configureByFile(..)";
if (myEditor.getCaretModel().supportsMultipleCarets()) {
List<LogicalPosition> caretPositions = new ArrayList<LogicalPosition>();
List<Segment> selections = new ArrayList<Segment>();
for (EditorTestUtil.Caret caret : loader.caretState.carets) {
caretPositions.add(caret.offset == null ? null : myEditor.offsetToLogicalPosition(caret.offset));
selections.add(caret.selection == null ? null : caret.selection);
}
myEditor.getCaretModel().setCaretsAndSelections(caretPositions, selections);
}
else {
assert loader.caretState.carets.size() == 1 : "Multiple carets are not supported by the model";
EditorTestUtil.Caret caret = loader.caretState.carets.get(0);
int offset = caret.offset != null ? caret.offset : 0;
myEditor.getCaretModel().moveToOffset(offset);
if (caret.selection != null) {
myEditor.getSelectionModel().setSelection(caret.selection.getStartOffset(), caret.selection.getEndOffset());
}
else {
myEditor.getSelectionModel().removeSelection();
}
}
if (loader.caretState.blockSelection != null) {
myEditor.getSelectionModel().setBlockSelection(myEditor.offsetToLogicalPosition(loader.caretState.blockSelection.getStartOffset()),
myEditor.offsetToLogicalPosition(loader.caretState.blockSelection.getEndOffset()));
}
EditorTestUtil.setCaretsAndSelection(myEditor, loader.caretState);
Module module = getModule();
if (module != null) {
@@ -1647,14 +1616,13 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
static class SelectionAndCaretMarkupLoader {
final String filePath;
final String newFileText;
final EditorTestUtil.CaretsState caretState;
final EditorTestUtil.CaretAndSelectionState caretState;
static SelectionAndCaretMarkupLoader fromFile(String path, Project project, String charset) throws IOException {
return new SelectionAndCaretMarkupLoader(
project, StringUtil.convertLineSeparators(FileUtil.loadFile(new File(path), charset)), path);
static SelectionAndCaretMarkupLoader fromFile(String path, String charset) throws IOException {
return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(FileUtil.loadFile(new File(path), charset)), path);
}
static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) {
static SelectionAndCaretMarkupLoader fromFile(VirtualFile file) {
final String text;
try {
text = VfsUtilCore.loadText(file);
@@ -1662,24 +1630,17 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
catch (IOException e) {
throw new RuntimeException(e);
}
return new SelectionAndCaretMarkupLoader(project, StringUtil.convertLineSeparators(text), file.getPath());
return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(text), file.getPath());
}
static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
return new SelectionAndCaretMarkupLoader(project, text, null);
static SelectionAndCaretMarkupLoader fromText(String text) {
return new SelectionAndCaretMarkupLoader(text, null);
}
private SelectionAndCaretMarkupLoader(Project project, String fileText, String filePath) {
private SelectionAndCaretMarkupLoader(String fileText, String filePath) {
this.filePath = filePath;
final Document document = EditorFactory.getInstance().createDocument(fileText);
caretState = new WriteCommandAction<EditorTestUtil.CaretsState>(project) {
@Override
protected void run(@NotNull Result<EditorTestUtil.CaretsState> result) throws Exception {
result.setResult(EditorTestUtil.extractCaretAndSelectionMarkers(document));
}
}.execute().getResultObject();
caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
newFileText = document.getText();
}
}
@@ -1702,7 +1663,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
VirtualFile virtualFile = originalFile.getVirtualFile();
String charset = virtualFile == null? null : virtualFile.getCharset().name();
checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(path, getProject(), charset), fileText);
checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(path, charset), fileText);
}
@@ -1743,89 +1704,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
}
boolean hasChecks = false;
for (int i = 0; i < loader.caretState.carets.size(); i++) {
EditorTestUtil.Caret expected = loader.caretState.carets.get(i);
if (expected.offset != null || expected.selection != null) {
hasChecks = true;
break;
}
}
if (!hasChecks) {
return; // nothing to check, so we skip caret/selection assertions
}
CaretModel caretModel = editor.getCaretModel();
List<Caret> allCarets = new ArrayList<Caret>(caretModel.getAllCarets());
assertEquals("Unexpected number of carets", loader.caretState.carets.size(), allCarets.size());
for (int i = 0; i < loader.caretState.carets.size(); i++) {
EditorTestUtil.Caret expected = loader.caretState.carets.get(i);
String caretDescription = loader.caretState.carets.size() == 1 ? "" : "(" + (i + 1) + "/" + loader.caretState.carets.size() + ") ";
if (expected.offset != null) {
final int tabSize = CodeStyleSettingsManager.getSettings(getProject()).getIndentOptions(StdFileTypes.JAVA).TAB_SIZE;
int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, expected.offset);
int caretCol = EditorUtil.calcColumnNumber(null, loader.newFileText, StringUtil.lineColToOffset(loader.newFileText, caretLine, 0), expected.offset, tabSize);
final int actualLine = allCarets.get(i).getLogicalPosition().line;
final int actualCol = allCarets.get(i).getLogicalPosition().column;
boolean caretPositionEquals = caretLine == actualLine && caretCol == actualCol;
assertTrue("Caret" + caretDescription + " position in " + expectedFile + " differs. Expected " + genCaretPositionPresentation(caretLine, caretCol)
+ ". Actual " + genCaretPositionPresentation(actualLine, actualCol), caretPositionEquals);
}
if (expected.selection != null) {
int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, expected.selection.getStartOffset());
int selStartCol = expected.selection.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, expected.selection.getEndOffset());
int selEndCol = expected.selection.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
int selectionStart;
int selectionEnd;
if (editor.getSelectionModel().hasBlockSelection()) {
int[] starts = editor.getSelectionModel().getBlockSelectionStarts();
int[] ends = editor.getSelectionModel().getBlockSelectionEnds();
selectionStart = starts[starts.length-1];
selectionEnd = ends[ends.length-1];
}
else {
selectionStart = allCarets.get(i).getSelectionStart();
selectionEnd = allCarets.get(i).getSelectionEnd();
}
final int selStartLineActual = StringUtil.offsetToLineNumber(loader.newFileText, selectionStart);
final int selStartColActual = selectionStart - StringUtil.lineColToOffset(loader.newFileText, selStartLineActual, 0);
final int selEndLineActual = StringUtil.offsetToLineNumber(loader.newFileText, selectionEnd);
final int selEndColActual = selectionEnd - StringUtil.lineColToOffset(loader.newFileText, selEndLineActual, 0);
final boolean selectionEquals = selStartCol == selStartColActual &&
selStartLine == selStartLineActual &&
selEndCol == selEndColActual &&
selEndLine == selEndLineActual;
assertTrue(caretDescription + "selection in " + expectedFile + " differs. Expected " + genSelectionPresentation(selStartLine, selStartCol, selEndLine, selEndCol) +
". Actual " + genSelectionPresentation(selStartLineActual, selStartColActual, selEndLineActual, selEndColActual),
selectionEquals
);
}
else if (editor != null) {
assertFalse(caretDescription + "has no selection in " + expectedFile, editor.getSelectionModel().hasSelection());
}
}
}
private static String genCaretPositionPresentation(int line, int col) {
line++;
col++;
return "(" + line + ", " + col + ")";
}
private static String genSelectionPresentation(int startLine, int startCol, int endLine, int endCol) {
startCol++;
startLine++;
endCol++;
endLine++;
return "(" + startLine + ", " + startCol + ")-(" + endLine + ", " + endCol + ")";
EditorTestUtil.verifyCaretAndSelectionState(editor, loader.caretState);
}
private String stripTrailingSpaces(String actualText) {