| /* |
| * Copyright 2016 The Bazel Authors. All rights reserved. |
| * |
| * 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.google.idea.blaze.base; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral; |
| import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils; |
| import com.intellij.codeInsight.lookup.Lookup; |
| import com.intellij.codeInsight.lookup.LookupElement; |
| import com.intellij.codeInsight.lookup.LookupElementPresentation; |
| import com.intellij.lang.ASTNode; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.command.CommandProcessor; |
| import com.intellij.openapi.editor.Editor; |
| import com.intellij.openapi.editor.LogicalPosition; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.PsiDocumentManager; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.impl.source.PostprocessReformattingAspect; |
| import com.intellij.testFramework.EditorTestUtil; |
| import com.intellij.testFramework.EditorTestUtil.CaretAndSelectionState; |
| import com.intellij.testFramework.EditorTestUtil.CaretInfo; |
| import com.intellij.testFramework.EdtTestUtil; |
| import com.intellij.testFramework.fixtures.CodeInsightTestFixture; |
| import com.intellij.util.ThrowableRunnable; |
| import java.util.Arrays; |
| import javax.annotation.Nullable; |
| |
| /** Helper methods for editor tests. */ |
| public class EditorTestHelper { |
| private final Project project; |
| private final CodeInsightTestFixture testFixture; |
| |
| public EditorTestHelper(Project project, CodeInsightTestFixture testFixture) { |
| this.project = project; |
| this.testFixture = testFixture; |
| } |
| |
| public Editor openFileInEditor(PsiFile file) { |
| return openFileInEditor(file.getVirtualFile()); |
| } |
| |
| public Editor openFileInEditor(VirtualFile file) { |
| EdtTestUtil.runInEdtAndWait( |
| (ThrowableRunnable<Throwable>) () -> testFixture.openFileInEditor(file)); |
| return testFixture.getEditor(); |
| } |
| |
| /** @return null if the only item was auto-completed */ |
| @Nullable |
| public String[] getCompletionItemsAsStrings() { |
| LookupElement[] completionItems = testFixture.completeBasic(); |
| if (completionItems == null) { |
| return null; |
| } |
| return Arrays.stream(completionItems) |
| .map(LookupElement::getLookupString) |
| .toArray(String[]::new); |
| } |
| |
| /** @return null if the only item was auto-completed */ |
| @Nullable |
| public String[] getCompletionItemsAsSuggestionStrings() { |
| LookupElement[] completionItems = testFixture.completeBasic(); |
| if (completionItems == null) { |
| return null; |
| } |
| LookupElementPresentation presentation = new LookupElementPresentation(); |
| String[] strings = new String[completionItems.length]; |
| for (int i = 0; i < strings.length; i++) { |
| completionItems[i].renderElement(presentation); |
| strings[i] = presentation.getItemText(); |
| } |
| return strings; |
| } |
| |
| /** @return true if a LookupItem was inserted. */ |
| public boolean completeIfUnique() { |
| LookupElement[] completionItems = testFixture.completeBasic(); |
| if (completionItems == null) { |
| return true; |
| } |
| if (completionItems.length != 1) { |
| return false; |
| } |
| testFixture.getLookup().setCurrentItem(completionItems[0]); |
| testFixture.finishLookup(Lookup.NORMAL_SELECT_CHAR); |
| return true; |
| } |
| |
| /** Simulates a user typing action, at current caret position of file. */ |
| public void performTypingAction(PsiFile file, char typedChar) { |
| performTypingAction(openFileInEditor(file.getVirtualFile()), typedChar); |
| } |
| |
| /** Simulates a user typing action, at current caret position of document. */ |
| public void performTypingAction(Editor editor, char typedChar) { |
| EditorTestUtil.performTypingAction(editor, typedChar); |
| project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting(); |
| PsiDocumentManager.getInstance(project).commitAllDocuments(); |
| } |
| |
| /** |
| * Clicks the specified button in current document at the current caret position |
| * |
| * @param action which button to click (see {@link IdeActions}) |
| */ |
| public final void pressButton(final String action) { |
| CommandProcessor.getInstance() |
| .executeCommand(project, () -> testFixture.performEditorAction(action), "", null); |
| } |
| |
| public void setCaretPosition(Editor editor, int lineNumber, int columnNumber) { |
| final CaretInfo info = new CaretInfo(new LogicalPosition(lineNumber, columnNumber), null); |
| EdtTestUtil.runInEdtAndWait( |
| (ThrowableRunnable<Throwable>) |
| () -> |
| EditorTestUtil.setCaretsAndSelection( |
| editor, new CaretAndSelectionState(ImmutableList.of(info), null))); |
| } |
| |
| public void assertCaretPosition(Editor editor, int lineNumber, int columnNumber) { |
| CaretInfo info = new CaretInfo(new LogicalPosition(lineNumber, columnNumber), null); |
| EditorTestUtil.verifyCaretAndSelectionState( |
| editor, new CaretAndSelectionState(ImmutableList.of(info), null)); |
| } |
| |
| public void replaceStringContents(StringLiteral string, String newStringContents) { |
| Runnable renameOp = |
| () -> { |
| ASTNode node = string.getNode(); |
| node.replaceChild( |
| node.getFirstChildNode(), |
| PsiUtils.createNewLabel(string.getProject(), newStringContents)); |
| }; |
| ApplicationManager.getApplication() |
| .runWriteAction(() -> CommandProcessor.getInstance().runUndoTransparentAction(renameOp)); |
| } |
| } |