diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java index d5e108e416b0..4084643b6647 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/CompletionHintsTest.java @@ -26,7 +26,6 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.actionSystem.IdeActions; -import com.intellij.openapi.editor.VisualPosition; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.registry.RegistryValue; import com.intellij.util.ui.UIUtil; @@ -61,28 +60,24 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { // check hints appearance on completion configureJava("class C { void m() { System.setPro } }"); complete("setProperty"); - checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); // check that hints don't disappear after daemon highlighting passes waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); // test Tab/Shift+Tab navigation - checkResult("class C { void m() { System.setProperty(, ) } }"); - assertTrue(myFixture.getEditor().getCaretModel().getLogicalPosition().leansForward); next(); - checkResult("class C { void m() { System.setProperty(, ) } }"); - assertTrue(myFixture.getEditor().getCaretModel().getLogicalPosition().leansForward); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); prev(); - checkResult("class C { void m() { System.setProperty(, ) } }"); - assertTrue(myFixture.getEditor().getCaretModel().getLogicalPosition().leansForward); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); // test hints remain shown while entering parameter values myFixture.type("\"a"); next(); myFixture.type("\"b"); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { System.setProperty(\"a\", \"b\") } }"); + checkResultWithInlays("class C { void m() { System.setProperty(\"a\", \"b\") } }"); // test hints disappearance when caret moves out of parameter list right(); @@ -90,35 +85,31 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { right(); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { System.setProperty(\"a\", \"b\") } }"); + checkResultWithInlays("class C { void m() { System.setProperty(\"a\", \"b\") } }"); } public void testBasicScenarioWithHintsEnabledForMethod() throws Exception { // check hints appearance on completion configureJava("class C { void m() { Character.for } }"); complete("forDigit"); - checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); // check that hints don't disappear after daemon highlighting passes waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); // test Tab/Shift+Tab navigation - checkResult("class C { void m() { Character.forDigit(, ) } }"); - assertTrue(myFixture.getEditor().getCaretModel().getLogicalPosition().leansForward); next(); - checkResult("class C { void m() { Character.forDigit(, ) } }"); - assertTrue(myFixture.getEditor().getCaretModel().getLogicalPosition().leansForward); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); prev(); - checkResult("class C { void m() { Character.forDigit(, ) } }"); - assertTrue(myFixture.getEditor().getCaretModel().getLogicalPosition().leansForward); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); // test hints remain shown while entering parameter values myFixture.type("1"); next(); myFixture.type("2"); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit(1, 2) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(1, 2) } }"); // test hints don't disappear when caret moves out of parameter list right(); @@ -126,7 +117,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { right(); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit(1, 2) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(1, 2) } }"); } public void testWithHintsEnabledForNonLiterals() throws Exception { @@ -137,10 +128,10 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { configureJava("class C { void m() { Character.for } }"); complete("forDigit"); - checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); } finally { option.set(savedValue); @@ -150,23 +141,21 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { public void testSwitchingOverloads() { configureJava("class C { void m() { Character.to } }"); complete("toChars(int codePoint)"); - checkResultWithInlays("class C { void m() { Character.toChars() } }"); + checkResultWithInlays("class C { void m() { Character.toChars() } }"); showParameterInfo(); myFixture.performEditorAction("MethodOverloadSwitchDown"); checkResultWithInlays( - "class C { void m() { Character.toChars(, , ) } }"); + "class C { void m() { Character.toChars(, , ) } }"); } public void testSwitchingOverloadsWithParameterFilled() { configureJava("class C { void m() { Character.to } }"); complete("toChars(int codePoint)"); type("123"); - checkResultWithInlays("class C { void m() { Character.toChars(123) } }"); + checkResultWithInlays("class C { void m() { Character.toChars(123) } }"); showParameterInfo(); myFixture.performEditorAction("MethodOverloadSwitchDown"); - checkResultWithInlays( - "class C { void m() { Character.toChars(123, , ) } }"); - checkResult("class C { void m() { Character.toChars(123, , ) } }"); + checkResultWithInlays("class C { void m() { Character.toChars(123, , ) } }"); } public void testSwitchingOverloadsForMethodWithDisabledHints() throws Exception { @@ -179,7 +168,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { checkResultWithInlays("class C {\n" + " int some(int from, int to) { return 0; }\n" + " int some(int from, int to, int other) { return 0; }\n" + - " void m() { some(, , ) }\n" + + " void m() { some(, , ) }\n" + "}"); showParameterInfo(); myFixture.performEditorAction("MethodOverloadSwitchDown"); @@ -187,23 +176,23 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { checkResultWithInlays("class C {\n" + " int some(int from, int to) { return 0; }\n" + " int some(int from, int to, int other) { return 0; }\n" + - " void m() { some(, ) }\n" + + " void m() { some(, ) }\n" + "}"); } public void testNoHintsForMethodReference() { configureJava("class C {\n" + - " interface I { void i(int p); }\n" + - " void referenced(int a) {}\n" + - " void m(I lambda) {}\n" + - " void m2() { m(this::) }\n" + - "}"); + " interface I { void i(int p); }\n" + + " void referenced(int a) {}\n" + + " void m(I lambda) {}\n" + + " void m2() { m(this::) }\n" + + "}"); complete("referenced"); checkResultWithInlays("class C {\n" + " interface I { void i(int p); }\n" + " void referenced(int a) {}\n" + " void m(I lambda) {}\n" + - " void m2() { m(this::referenced) }\n" + + " void m2() { m(this::referenced) }\n" + "}"); } @@ -211,13 +200,11 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { configureJava("class C { void m() { System.setPro } }"); complete("setProperty"); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); myFixture.type("System.getPro"); complete("getProperty(String key, String def)"); waitForAllAsyncStuff(); - checkResultWithInlays( - "class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); - checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); } public void testTabWithNestedCompletion() throws Exception { @@ -227,40 +214,39 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { myFixture.type("System.getPro"); complete("getProperty(String key, String def)"); waitForAllAsyncStuff(); - checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); next(); - checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); next(); - checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); next(); - checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); next(); - checkResult("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(System.getProperty(, ), ) } }"); } public void testNoHintsForMethodWithOneParameterFromBlackList() { configureJava("class C { void m() { System.getPro } }"); complete("getProperty(String key)"); - checkResult("class C { void m() { System.getProperty() } }"); - checkResultWithInlays("class C { void m() { System.getProperty() } }"); + checkResultWithInlays("class C { void m() { System.getProperty() } }"); } public void testHintsDisappearWhenNumberOfParametersIsChangedDirectly() throws Exception { configureJava("class C { void m() { System.getPro } }"); complete("getProperty(String key, String def)"); - checkResultWithInlays("class C { void m() { System.getProperty(, ) } }"); + checkResultWithInlays("class C { void m() { System.getProperty(, ) } }"); myFixture.performEditorAction(IdeActions.ACTION_EDITOR_DELETE); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { System.getProperty( ) } }"); + checkResultWithInlays("class C { void m() { System.getProperty( ) } }"); } public void testHintsDisappearWhenNumberOfParametersIsChangedDirectlyWithNoOverloads() throws Exception { configureJava("class C { void m() { Character.for } }"); complete("forDigit"); - checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(, ) } }"); myFixture.performEditorAction(IdeActions.ACTION_EDITOR_DELETE); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit( ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit( ) } }"); } public void testCaretIsToTheRightOfHintAfterSmartInnerCompletion() throws Exception { @@ -268,10 +254,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { complete("setProperty"); type("new String().trim"); myFixture.complete(CompletionType.SMART); - checkResultWithInlays("class C { void m() { System.setProperty(new String().trim(), ) } }"); - checkResult("class C { void m() { System.setProperty(new String().trim(), ) } }"); - assertEquals(getEditor().offsetToVisualPosition(getEditor().getCaretModel().getOffset(), true, false), - getEditor().getCaretModel().getVisualPosition()); + checkResultWithInlays("class C { void m() { System.setProperty(new String().trim(), ) } }"); } public void testNoHintsDuplicationWhenTypingToTheLeftOfHint() throws Exception { @@ -282,10 +265,10 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { right(); type("2"); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit(1,2 ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(1,2 ) } }"); myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_LINE_END); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { Character.forDigit(1,2 ) } }"); + checkResultWithInlays("class C { void m() { Character.forDigit(1,2 ) } }"); } public void testIntroduceVariableIntention() throws Exception { @@ -334,9 +317,7 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { next(); next(); prev(); - checkResult("class C { void m() { System.getProperty(, ) } }"); - checkResultWithInlays("class C { void m() { System.getProperty(, ) } }"); - assertFalse(getEditor().getInlayModel().hasInlineElementAt(getEditor().getCaretModel().getVisualPosition())); + checkResultWithInlays("class C { void m() { System.getProperty(, ) } }"); } public void testPrevParameterFromOutsideWhenParametersAreNotEmpty() throws Exception { @@ -348,104 +329,66 @@ public class CompletionHintsTest extends LightFixtureCompletionTestCase { next(); waitForAllAsyncStuff(); prev(); - checkResult("class C { void m() { System.getProperty(\"a\", \"b\") } }"); - checkResultWithInlays("class C { void m() { System.getProperty(\"a\", \"b\") } }"); + checkResultWithInlays("class C { void m() { System.getProperty(\"a\", \"b\") } }"); } public void testVararg() throws Exception { configureJava("class C { void m() { String.for } }"); complete(); - checkResult("class C { void m() { String.format() } }"); - checkResultWithInlays("class C { void m() { String.format() } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { void m() { String.format() } }"); type("\"a"); next(); - checkResult("class C { void m() { String.format(\"a\", ) } }"); - checkResultWithInlays("class C { void m() { String.format(\"a\", ) } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { void m() { String.format(\"a\", ) } }"); next(); - checkResult("class C { void m() { String.format(\"a\") } }"); - checkResultWithInlays("class C { void m() { String.format(\"a\") } }"); + checkResultWithInlays("class C { void m() { String.format(\"a\") } }"); prev(); - checkResult("class C { void m() { String.format(\"a\", ) } }"); - checkResultWithInlays("class C { void m() { String.format(\"a\", ) } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { void m() { String.format(\"a\", ) } }"); prev(); - checkResult("class C { void m() { String.format(\"a\") } }"); - checkResultWithInlays("class C { void m() { String.format(\"a\") } }"); - assertCaretBeforeInlay(); + checkResultWithInlays("class C { void m() { String.format(\"a\") } }"); } public void testVarargWithNoMandatoryArguments() throws Exception { configureJava("class C { int vararg(int... args){ return 0; } void m() { varar } }"); complete(); - checkResult("class C { int vararg(int... args){ return 0; } void m() { vararg() } }"); - checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg() } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg() } }"); type("1"); next(); - checkResult("class C { int vararg(int... args){ return 0; } void m() { vararg(1, ) } }"); - checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1, ) } }"); + checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1, ) } }"); next(); - checkResult("class C { int vararg(int... args){ return 0; } void m() { vararg(1) } }"); - checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1) } }"); + checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1) } }"); prev(); - checkResult("class C { int vararg(int... args){ return 0; } void m() { vararg(1, ) } }"); - checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1, ) } }"); + checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1, ) } }"); prev(); - checkResult("class C { int vararg(int... args){ return 0; } void m() { vararg(1) } }"); - checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1) } }"); + checkResultWithInlays("class C { int vararg(int... args){ return 0; } void m() { vararg(1) } }"); } public void testVarargWithTwoMandatoryArguments() throws Exception { configureJava("class C { int vararg(int a, int b, int... args){ return 0; } void m() { varar } }"); complete(); - checkResult("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(, ) } }"); - checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(, ) } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(, ) } }"); type("1"); next(); - checkResult("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, ) } }"); - checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, ) } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, ) } }"); type("2"); next(); - checkResult("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2, ) } }"); - checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2, ) } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2, ) } }"); next(); - checkResult("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2) } }"); - checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2) } }"); + checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2) } }"); prev(); - checkResult("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2, ) } }"); - checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2, ) } }"); - assertCaretAfterInlay(); + checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2, ) } }"); prev(); - checkResult("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2) } }"); - checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2) } }"); - assertCaretBeforeInlay(); + checkResultWithInlays("class C { int vararg(int a, int b, int... args){ return 0; } void m() { vararg(1, 2) } }"); } public void testHintsDontDisappearWhenNavigatingAwayFromUncompletedInvocation() throws Exception { configureJava("class C { void m() { System.setPro } }"); complete("setProperty"); waitForAllAsyncStuff(); - checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); + checkResultWithInlays("class C { void m() { System.setProperty(, ) } }"); myFixture.getEditor().getCaretModel().moveToOffset(0); type(' '); waitForAllAsyncStuff(); - checkResultWithInlays(" class C { void m() { System.setProperty(, ) } }"); - } - - private void assertCaretBeforeInlay() { - VisualPosition posFromOffset = myFixture.getEditor().offsetToVisualPosition(myFixture.getEditor().getCaretModel().getOffset()); - assertEquals(posFromOffset, myFixture.getEditor().getCaretModel().getVisualPosition()); - } - - private void assertCaretAfterInlay() { - VisualPosition posFromOffset = myFixture.getEditor().offsetToVisualPosition(myFixture.getEditor().getCaretModel().getOffset()); - assertEquals(new VisualPosition(posFromOffset.line, posFromOffset.column + 1), - myFixture.getEditor().getCaretModel().getVisualPosition()); + checkResultWithInlays(" class C { void m() { System.setProperty(, ) } }"); } private void checkResult(String text) { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 48c6ef063a4d..0e1015b75f53 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -27,7 +27,6 @@ import com.intellij.codeInsight.daemon.GutterMark; import com.intellij.codeInsight.daemon.impl.*; import com.intellij.codeInsight.folding.CodeFoldingManager; import com.intellij.codeInsight.highlighting.actions.HighlightUsagesAction; -import com.intellij.codeInsight.hints.InlayInfo; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.impl.IntentionListStep; import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler; @@ -115,6 +114,7 @@ import com.intellij.refactoring.rename.*; import com.intellij.rt.execution.junit.FileComparisonFailure; import com.intellij.testFramework.*; import com.intellij.testFramework.fixtures.*; +import com.intellij.testFramework.utils.inlays.CaretAndInlaysInfo; import com.intellij.testFramework.utils.inlays.InlayHintsChecker; import com.intellij.ui.breadcrumbs.BreadcrumbsProvider; import com.intellij.ui.breadcrumbs.BreadcrumbsUtil; @@ -1760,9 +1760,9 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig public void checkResultWithInlays(String text) { Document checkDocument = new DocumentImpl(text); InlayHintsChecker checker = new InlayHintsChecker(this); - List inlayInfos = checker.extractInlays(checkDocument); + CaretAndInlaysInfo inlaysAndCaretInfo = checker.extractInlaysAndCaretInfo(checkDocument); checkResult(checkDocument.getText()); - checker.verifyInlays(inlayInfos, text); + checker.verifyInlaysAndCaretInfo(inlaysAndCaretInfo, text); } @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayParameterHintsTest.kt b/platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayParameterHintsTest.kt index 12630cde0fbd..5ec9f101b54a 100644 --- a/platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayParameterHintsTest.kt +++ b/platform/testFramework/src/com/intellij/testFramework/utils/inlays/InlayParameterHintsTest.kt @@ -20,11 +20,15 @@ import com.intellij.codeInsight.hints.InlayInfo import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.editor.Document +import com.intellij.openapi.editor.VisualPosition import com.intellij.openapi.editor.ex.EditorSettingsExternalizable +import com.intellij.openapi.util.TextRange import com.intellij.rt.execution.junit.FileComparisonFailure import com.intellij.testFramework.VfsTestUtil import com.intellij.testFramework.fixtures.CodeInsightTestFixture import junit.framework.ComparisonFailure +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import java.util.regex.Pattern @@ -33,7 +37,7 @@ class InlayHintsChecker(private val myFixture: CodeInsightTestFixture) { private var isParamHintsEnabledBefore = false companion object { - val pattern: Pattern = Pattern.compile("") + val pattern: Pattern = Pattern.compile("()|()|()|") private val default = ParameterNameHintsSettings() } @@ -55,19 +59,19 @@ class InlayHintsChecker(private val myFixture: CodeInsightTestFixture) { val file = myFixture.file val document = myFixture.getDocument(file) val originalText = document.text - val expectedInlays: List = extractInlays(document) - myFixture.doHighlighting(); - verifyInlays(expectedInlays, originalText) + val expectedInlaysAndCaret = extractInlaysAndCaretInfo(document) + myFixture.doHighlighting() + verifyInlaysAndCaretInfo(expectedInlaysAndCaret, originalText) } - fun verifyInlays(expectedInlays : List, originalText: String) { + fun verifyInlaysAndCaretInfo(expectedInlaysAndCaret: CaretAndInlaysInfo, originalText: String) { val file = myFixture.file val document = myFixture.getDocument(file) val actual: List> = getActualInlays() - val expected = expectedInlays.map { Pair(it.offset, it.text) } + val expected = expectedInlaysAndCaret.inlays.map { Pair(it.offset, it.text) } - if (expectedInlays.size != actual.size || actual.zip(expected).any { it.first != it.second }) { + if (expectedInlaysAndCaret.inlays.size != actual.size || actual.zip(expected).any { it.first != it.second }) { val proposedText = StringBuilder(document.text) actual.asReversed().forEach { proposedText.insert(it.first, "") } @@ -75,6 +79,19 @@ class InlayHintsChecker(private val myFixture: CodeInsightTestFixture) { throw FileComparisonFailure("Hints differ", originalText, proposedText.toString(), originalPath) } ?: throw ComparisonFailure("Hints differ", originalText, proposedText.toString()) } + + if (expectedInlaysAndCaret.caretOffset != null) { + assertEquals("Unexpected caret offset", expectedInlaysAndCaret.caretOffset, myFixture.editor.caretModel.offset) + val position = myFixture.editor.offsetToVisualPosition(expectedInlaysAndCaret.caretOffset) + assertEquals("Unexpected caret visual position", + VisualPosition(position.line, position.column + expectedInlaysAndCaret.inlaysBeforeCaret), + myFixture.editor.caretModel.visualPosition) + val selectionModel = myFixture.editor.selectionModel + if (expectedInlaysAndCaret.selection == null) assertFalse(selectionModel.hasSelection()) + else assertEquals("Unexpected selection", + expectedInlaysAndCaret.selection, + TextRange(selectionModel.selectionStart, selectionModel.selectionEnd)) + } } private fun getActualInlays(): List> { @@ -88,25 +105,45 @@ class InlayHintsChecker(private val myFixture: CodeInsightTestFixture) { .sortedBy { it.first } } - fun extractInlays(document: Document): List { + fun extractInlaysAndCaretInfo(document: Document): CaretAndInlaysInfo { val text = document.text val matcher = pattern.matcher(text) val inlays = mutableListOf() var extractedLength = 0 + var caretOffset : Int? = null + var inlaysBeforeCaret = 0 + var selectionStart : Int? = null + var selectionEnd : Int? = null while (matcher.find()) { val start = matcher.start() val matchedLength = matcher.end() - start val realStartOffset = start - extractedLength - inlays += InlayInfo(matcher.group(1), realStartOffset) + if (matcher.group(1) != null) { + caretOffset = realStartOffset + inlays.asReversed() + .takeWhile { it.offset == caretOffset } + .forEach { inlaysBeforeCaret++ } + } + else if (matcher.group(2) != null) { + selectionStart = realStartOffset + } + else if (matcher.group(3) != null) { + selectionEnd = realStartOffset + } + else { + inlays += InlayInfo(matcher.group(4), realStartOffset) + } removeText(document, realStartOffset, matchedLength) extractedLength += (matcher.end() - start) } - return inlays + return CaretAndInlaysInfo(caretOffset, inlaysBeforeCaret, + if (selectionStart == null || selectionEnd == null) null else TextRange(selectionStart, selectionEnd), + inlays) } private fun removeText(document: Document, realStartOffset: Int, matchedLength: Int) { @@ -116,4 +153,6 @@ class InlayHintsChecker(private val myFixture: CodeInsightTestFixture) { } -} \ No newline at end of file +} + +class CaretAndInlaysInfo (val caretOffset: Int?, val inlaysBeforeCaret: Int, val selection: TextRange?, val inlays: List) \ No newline at end of file