diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index a7af4ac59ca..a32b9715664 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -41,6 +41,7 @@ import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import junit.framework.TestCase; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -629,22 +630,52 @@ public class JetTestUtils { return result.toString(); } - public static String getLastCommentInFile(JetFile file) { + public enum CommentType { + ALL, + LINE_COMMENT, + BLOCK_COMMENT + } + + @NotNull + public static String getLastCommentInFile(@NotNull JetFile file) { + return KotlinPackage.first(getLastCommentsInFile(file, CommentType.ALL, true)); + } + + @NotNull + public static List getLastCommentsInFile(@NotNull JetFile file, CommentType commentType, boolean assertMustExist) { PsiElement lastChild = file.getLastChild(); if (lastChild != null && lastChild.getNode().getElementType().equals(JetTokens.WHITE_SPACE)) { lastChild = lastChild.getPrevSibling(); } assert lastChild != null; - if (lastChild.getNode().getElementType().equals(JetTokens.BLOCK_COMMENT)) { - String lastChildText = lastChild.getText(); - return lastChildText.substring(2, lastChildText.length() - 2).trim(); + List comments = ContainerUtil.newArrayList(); + + while (true) { + if (lastChild.getNode().getElementType().equals(JetTokens.BLOCK_COMMENT)) { + if (commentType == CommentType.ALL || commentType == CommentType.BLOCK_COMMENT) { + String lastChildText = lastChild.getText(); + comments.add(lastChildText.substring(2, lastChildText.length() - 2).trim()); + } + } + else if (lastChild.getNode().getElementType().equals(JetTokens.EOL_COMMENT)) { + if (commentType == CommentType.ALL || commentType == CommentType.LINE_COMMENT) { + comments.add(lastChild.getText().substring(2).trim()); + } + } + else { + break; + } + + lastChild = lastChild.getPrevSibling(); } - else if (lastChild.getNode().getElementType().equals(JetTokens.EOL_COMMENT)) { - return lastChild.getText().substring(2).trim(); - } else { - throw new AssertionError("Test file '" + file.getName() + "' should end in a comment; last node was: " + lastChild); + + if (comments.isEmpty() && assertMustExist) { + throw new AssertionError(String.format( + "Test file '%s' should end in a comment of type %s; last node was: %s", file.getName(), commentType, lastChild)); } + + return comments; } public static void compileJavaFiles(@NotNull Collection files, List options) throws IOException { diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 5814862e7cb..e82519d0fd6 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -88,6 +88,7 @@ import org.jetbrains.jet.completion.AbstractCompiledKotlinInJavaCompletionTest import org.jetbrains.jet.completion.AbstractKotlinSourceInJavaCompletionTest import org.jetbrains.jet.checkers.AbstractJetDiagnosticsTestWithStdLib import org.jetbrains.jet.plugin.codeInsight.AbstractInsertImportOnPasteTest +import org.jetbrains.jet.plugin.codeInsight.AbstractLineMarkersTest import org.jetbrains.jet.resolve.AbstractReferenceToJavaWithWrongFileStructureTest import org.jetbrains.jet.plugin.navigation.AbstractKotlinGotoTest import org.jetbrains.jet.plugin.AbstractExpressionSelectionTest @@ -534,6 +535,10 @@ fun main(args: Array) { model("copyPaste/imports", pattern = """^([^\.]+)\.kt$""", testMethod = "doTestCut", testClassName = "Cut", recursive = false) } + testClass(javaClass()) { + model("codeInsight/lineMarker") + } + testClass(javaClass()) { model("shortenRefs", pattern = """^([^\.]+)\.kt$""") } diff --git a/idea/testData/codeInsight/lineMarker/FakeOverrideForClasses.kt b/idea/testData/codeInsight/lineMarker/FakeOverrideForClasses.kt new file mode 100644 index 00000000000..848bf691e33 --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/FakeOverrideForClasses.kt @@ -0,0 +1,25 @@ +package sample + +trait S { + fun foo(t: T): T + + val some: T? get + + var other: T? + get + set +} + +open abstract class S1 : S + +class S2 : S1() { + override val some: String = "S" + + override var other: String? + get() = null + set(value) {} + + override fun foo(t: String): String { + return super.foo(t) + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/lineMarker/FakeOverrideToStringInTrait.kt b/idea/testData/codeInsight/lineMarker/FakeOverrideToStringInTrait.kt new file mode 100644 index 00000000000..30749065d0e --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/FakeOverrideToStringInTrait.kt @@ -0,0 +1,9 @@ +trait A { + override fun toString() = "A" +} + +abstract class B: A + +class C: B() { + override fun toString() = "B" +} diff --git a/idea/testData/codeInsight/lineMarker/FakeOverridesForTraitFunWithImpl.kt b/idea/testData/codeInsight/lineMarker/FakeOverridesForTraitFunWithImpl.kt new file mode 100644 index 00000000000..bb42b7011d0 --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/FakeOverridesForTraitFunWithImpl.kt @@ -0,0 +1,25 @@ +trait A { + fun foo(): String = "A" + + // TODO: B shoudn't be mentioned + val some: String? get() = null + + // TODO: B shoudn't be mentioned + var other: String? + get() = null + set(value) {} +} + +open class B: A + +class C: B() { + override val some: String = "S" + + override var other: String? + get() = null + set(value) {} + + override fun foo(): String { + return super.foo() + } +} diff --git a/idea/testData/codeInsight/lineMarker/NavigateToSeveralSuperElements.kt b/idea/testData/codeInsight/lineMarker/NavigateToSeveralSuperElements.kt new file mode 100644 index 00000000000..ad300b501fe --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/NavigateToSeveralSuperElements.kt @@ -0,0 +1,22 @@ +trait A1 { + fun foo() +} + +trait B1 { + fun foo() +} + +class C1: A1, B1 { + override fun foo() {} +} + +/* +LINEMARKER: Implements function in 'A1'
Implements function in 'B1' +TARGETS: +NavigateToSeveralSuperElements.kt + fun <1>foo() +} + +trait B1 { + fun <2>foo() +*/ \ No newline at end of file diff --git a/idea/testData/codeInsight/lineMarker/Overloads.kt b/idea/testData/codeInsight/lineMarker/Overloads.kt new file mode 100644 index 00000000000..c988c04a619 --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/Overloads.kt @@ -0,0 +1,9 @@ +trait A { + fun foo(str: String) + fun foo() +} + +open class B : A { + override fun foo(str: String) { } + override fun foo() { } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/lineMarker/OverrideIconForOverloadMethodBug.kt b/idea/testData/codeInsight/lineMarker/OverrideIconForOverloadMethodBug.kt new file mode 100644 index 00000000000..eae09271244 --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/OverrideIconForOverloadMethodBug.kt @@ -0,0 +1,20 @@ +trait SkipSupport { + fun skip(why: String) + fun skip() +} + +public trait SkipSupportWithDefaults : SkipSupport { + // TODO: should be "Is overriden in SkipSupportImpl" + override fun skip(why: String) {} + + // TODO: fix bug with 'null' marker + override fun skip() { + skip("not given") + } +} + +open class SkipSupportImpl: SkipSupportWithDefaults { + override fun skip(why: String) = throw RuntimeException(why) +} + +// KT-4428 Incorrect override icon shown for overloaded methods \ No newline at end of file diff --git a/idea/testData/codeInsight/lineMarker/ToStringInTrait.kt b/idea/testData/codeInsight/lineMarker/ToStringInTrait.kt new file mode 100644 index 00000000000..d5968f4dc0a --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/ToStringInTrait.kt @@ -0,0 +1,10 @@ +public trait Foo { + override fun toString() = "str" +} + +/* +LINEMARKER: Overrides function in 'Any' +TARGETS: +Any.kt + public open fun <1>toString(): String +*/ \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractLineMarkersTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractLineMarkersTest.java new file mode 100644 index 00000000000..dee4b1a6e79 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/AbstractLineMarkersTest.java @@ -0,0 +1,172 @@ +/* + * Copyright 2010-2014 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 org.jetbrains.jet.plugin.codeInsight; + +import com.intellij.codeInsight.daemon.GutterIconNavigationHandler; +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.rt.execution.junit.FileComparisonFailure; +import com.intellij.testFramework.ExpectedHighlightingData; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; +import org.jetbrains.jet.plugin.PluginTestCaseBase; +import org.jetbrains.jet.plugin.highlighter.JetLineMarkerProvider; +import org.jetbrains.jet.plugin.navigation.NavigationTestUtils; +import org.jetbrains.jet.testing.HighlightTestDataUtil; +import org.jetbrains.jet.testing.ReferenceUtils; +import org.junit.Assert; + +import java.io.File; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public abstract class AbstractLineMarkersTest extends JetLightCodeInsightFixtureTestCase { + + private static final String LINE_MARKER_PREFIX = "LINEMARKER:"; + private static final String TARGETS_PREFIX = "TARGETS"; + + @Override + protected String getBasePath() { + return PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE + "/codeInsight/lineMarker"; + } + + public void doTest(String path) { + try { + myFixture.configureByFile(path); + Project project = myFixture.getProject(); + Document document = myFixture.getEditor().getDocument(); + + ExpectedHighlightingData data = new ExpectedHighlightingData( + document, false, false, false, myFixture.getFile()); + data.init(); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + myFixture.doHighlighting(); + + List markers = DaemonCodeAnalyzerImpl.getLineMarkers(document, project); + + try { + data.checkLineMarkers(markers, document.getText()); + } + catch (AssertionError error) { + try { + String actualTextWithTestData = HighlightTestDataUtil.insertInfoTags(markers, false, myFixture.getFile().getText()); + JetTestUtils.assertEqualsToFile(new File(getTestDataPath(), fileName()), actualTextWithTestData); + } + catch (FileComparisonFailure failure) { + throw new FileComparisonFailure(error.getMessage() + "\n" + failure.getMessage(), + failure.getExpected(), + failure.getActual(), + failure.getFilePath()); + } + } + + assertNavigationElements(markers); + } + catch (Exception exc) { + throw new RuntimeException(exc); + } + } + + private void assertNavigationElements(List markers) { + List navigationDataComments = JetTestUtils.getLastCommentsInFile( + (JetFile) myFixture.getFile(), JetTestUtils.CommentType.BLOCK_COMMENT, false); + if (navigationDataComments.isEmpty()) return; + + for (String navigationComment : navigationDataComments) { + final String description = getLineMarkerDescription(navigationComment); + LineMarkerInfo navigateMarker = ContainerUtil.find(markers, new Condition() { + @Override + public boolean value(LineMarkerInfo marker) { + String tooltip = marker.getLineMarkerTooltip(); + return tooltip != null && tooltip.startsWith(description); + } + }); + + assertNotNull( + String.format("Can't find marker for navigation check with description \"%s\"", description), + navigateMarker); + + GutterIconNavigationHandler handler = navigateMarker.getNavigationHandler(); + if (handler instanceof JetLineMarkerProvider.KotlinSuperNavigationHandler) { + PsiElement element = navigateMarker.getElement(); + + //noinspection unchecked + handler.navigate(null, element); + List navigateElements = + ((JetLineMarkerProvider.KotlinSuperNavigationHandler) handler).getNavigationElements(); + + Collections.sort(navigateElements, new Comparator() { + @Override + public int compare(@NotNull NavigatablePsiElement first, @NotNull NavigatablePsiElement second) { + String elementFirstStr = ReferenceUtils.renderAsGotoImplementation(first); + String elementSecondStr = ReferenceUtils.renderAsGotoImplementation(second); + + return elementFirstStr.compareTo(elementSecondStr); + } + }); + + String actualNavigationData = + NavigationTestUtils.getNavigateElementsText(myFixture.getProject(), navigateElements); + + assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData); + } + else { + Assert.fail("Only JetLineMarkerProvider.KotlinSuperNavigationHandler are supported in navigate check"); + } + } + } + + private static String getLineMarkerDescription(String navigationComment) { + int firstLineEnd = navigationComment.indexOf("\n"); + assertTrue("The first line in block comment must contain description of marker for navigation check", firstLineEnd != -1); + + String navigationMarkerText = navigationComment.substring(0, firstLineEnd); + + assertTrue(String.format("Add %s directive in first line of comment", LINE_MARKER_PREFIX), + navigationMarkerText.startsWith(LINE_MARKER_PREFIX)); + + navigationMarkerText = navigationMarkerText.substring(LINE_MARKER_PREFIX.length()); + + return navigationMarkerText.trim(); + } + + private static String getExpectedNavigationText(String navigationComment) { + int firstLineEnd = navigationComment.indexOf("\n"); + + String expectedNavigationText = navigationComment.substring(firstLineEnd + 1); + + assertTrue( + String.format("Marker %s is expected before navigation data", TARGETS_PREFIX), + expectedNavigationText.startsWith(TARGETS_PREFIX)); + + expectedNavigationText = expectedNavigationText.substring(expectedNavigationText.indexOf("\n") + 1); + + return expectedNavigationText; + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/LineMarkersTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/LineMarkersTestGenerated.java new file mode 100644 index 00000000000..796ecbf2163 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/LineMarkersTestGenerated.java @@ -0,0 +1,143 @@ +/* + * Copyright 2010-2014 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 org.jetbrains.jet.plugin.codeInsight; + +import com.intellij.testFramework.TestDataPath; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; +import org.jetbrains.jet.JUnit3RunnerWithInners; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/codeInsight/lineMarker") +@TestDataPath("$PROJECT_ROOT") +@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) +public class LineMarkersTestGenerated extends AbstractLineMarkersTest { + public void testAllFilesPresentInLineMarker() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/codeInsight/lineMarker"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("Class.kt") + public void testClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/Class.kt"); + doTest(fileName); + } + + @TestMetadata("ClassObjectInStaticNestedClass.kt") + public void testClassObjectInStaticNestedClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/ClassObjectInStaticNestedClass.kt"); + doTest(fileName); + } + + @TestMetadata("DelegatedFun.kt") + public void testDelegatedFun() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/DelegatedFun.kt"); + doTest(fileName); + } + + @TestMetadata("DelegatedProperty.kt") + public void testDelegatedProperty() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/DelegatedProperty.kt"); + doTest(fileName); + } + + @TestMetadata("FakeOverrideForClasses.kt") + public void testFakeOverrideForClasses() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/FakeOverrideForClasses.kt"); + doTest(fileName); + } + + @TestMetadata("FakeOverrideFun.kt") + public void testFakeOverrideFun() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/FakeOverrideFun.kt"); + doTest(fileName); + } + + @TestMetadata("FakeOverrideFunWithMostRelevantImplementation.kt") + public void testFakeOverrideFunWithMostRelevantImplementation() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/FakeOverrideFunWithMostRelevantImplementation.kt"); + doTest(fileName); + } + + @TestMetadata("FakeOverrideProperty.kt") + public void testFakeOverrideProperty() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/FakeOverrideProperty.kt"); + doTest(fileName); + } + + @TestMetadata("FakeOverrideToStringInTrait.kt") + public void testFakeOverrideToStringInTrait() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/FakeOverrideToStringInTrait.kt"); + doTest(fileName); + } + + @TestMetadata("FakeOverridesForTraitFunWithImpl.kt") + public void testFakeOverridesForTraitFunWithImpl() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/FakeOverridesForTraitFunWithImpl.kt"); + doTest(fileName); + } + + @TestMetadata("NavigateToSeveralSuperElements.kt") + public void testNavigateToSeveralSuperElements() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/NavigateToSeveralSuperElements.kt"); + doTest(fileName); + } + + @TestMetadata("Overloads.kt") + public void testOverloads() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/Overloads.kt"); + doTest(fileName); + } + + @TestMetadata("OverrideFunction.kt") + public void testOverrideFunction() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/OverrideFunction.kt"); + doTest(fileName); + } + + @TestMetadata("OverrideIconForOverloadMethodBug.kt") + public void testOverrideIconForOverloadMethodBug() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/OverrideIconForOverloadMethodBug.kt"); + doTest(fileName); + } + + @TestMetadata("PropertyOverride.kt") + public void testPropertyOverride() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/PropertyOverride.kt"); + doTest(fileName); + } + + @TestMetadata("ToStringInTrait.kt") + public void testToStringInTrait() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/ToStringInTrait.kt"); + doTest(fileName); + } + + @TestMetadata("Trait.kt") + public void testTrait() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/Trait.kt"); + doTest(fileName); + } + +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java deleted file mode 100644 index 6875e7d7c73..00000000000 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2010-2014 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 org.jetbrains.jet.plugin.codeInsight; - -import com.intellij.codeInsight.daemon.LineMarkerInfo; -import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.rt.execution.junit.FileComparisonFailure; -import com.intellij.testFramework.ExpectedHighlightingData; -import org.jetbrains.jet.JetTestUtils; -import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; -import org.jetbrains.jet.plugin.PluginTestCaseBase; -import org.jetbrains.jet.testing.HighlightTestDataUtil; - -import java.io.File; -import java.util.List; - -public class OverrideImplementLineMarkerTest extends JetLightCodeInsightFixtureTestCase { - @Override - protected String getBasePath() { - return PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE + "/codeInsight/lineMarker"; - } - - public void testTrait() throws Throwable { - doTest(); - } - - public void testClass() throws Throwable { - doTest(); - } - - public void testOverrideFunction() throws Throwable { - doTest(); - } - - public void testPropertyOverride() throws Throwable { - doTest(); - } - - public void testDelegatedFun() throws Exception { - doTest(); - } - - public void testFakeOverrideFun() throws Exception { - doTest(); - } - - public void testDelegatedProperty() throws Exception { - doTest(); - } - - public void testClassObjectInStaticNestedClass() throws Exception { - doTest(); - } - - public void testFakeOverrideProperty() throws Exception { - doTest(); - } - - public void testFakeOverrideFunWithMostRelevantImplementation() throws Exception { - doTest(); - } - - private void doTest() { - try { - myFixture.configureByFile(fileName()); - Project project = myFixture.getProject(); - Document document = myFixture.getEditor().getDocument(); - - ExpectedHighlightingData data = new ExpectedHighlightingData(document, false, false, false, myFixture.getFile()); - data.init(); - - PsiDocumentManager.getInstance(project).commitAllDocuments(); - - myFixture.doHighlighting(); - - List markers = DaemonCodeAnalyzerImpl.getLineMarkers(document, project); - - try { - data.checkLineMarkers(markers, document.getText()); - } - catch (AssertionError error) { - try { - String actualTextWithTestData = HighlightTestDataUtil.insertInfoTags(markers, false, myFixture.getFile().getText()); - JetTestUtils.assertEqualsToFile(new File(getTestDataPath(), fileName()), actualTextWithTestData); - } - catch (FileComparisonFailure failure) { - throw new FileComparisonFailure(error.getMessage() + "\n" + failure.getMessage(), - failure.getExpected(), - failure.getActual(), - failure.getFilePath()); - } - } - } - catch (Exception exc) { - throw new RuntimeException(exc); - } - } -} diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java index ee46fd676f4..e556d317dd6 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToLibrarySourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 JetBrains s.r.o. + * Copyright 2010-2014 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. @@ -17,19 +17,18 @@ package org.jetbrains.jet.plugin.libraries; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.util.containers.MultiMap; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.plugin.JdkAndMockLibraryProjectDescriptor; +import org.jetbrains.jet.plugin.navigation.NavigationTestUtils; import org.jetbrains.jet.plugin.references.JetReference; import java.util.*; @@ -109,7 +108,8 @@ public class NavigateToLibrarySourceTest extends AbstractNavigateToLibraryTest { private void checkAnnotatedLibraryCode(boolean forceResolve) { JetSourceNavigationHelper.setForceResolve(forceResolve); - String actualCode = getActualAnnotatedLibraryCode(); + String actualCode = NavigationTestUtils + .getNavigateElementsText(myFixture.getProject(), collectInterestingNavigationElements()); String expectedCode = getExpectedAnnotatedLibraryCode(); assertSameLines(expectedCode, actualCode); } @@ -134,63 +134,15 @@ public class NavigateToLibrarySourceTest extends AbstractNavigateToLibraryTest { return referenceContainersToReferences.values(); } - private String getActualAnnotatedLibraryCode() { - MultiMap> filesToNumbersAndOffsets = new MultiMap>(); - int refNumber = 1; - for (JetReference ref : collectInterestingReferences()) { - PsiElement target = ref.resolve(); - assertNotNull(target); - PsiElement navigationElement = target.getNavigationElement(); - Pair numberAndOffset = new Pair(refNumber++, navigationElement.getTextOffset()); - filesToNumbersAndOffsets.putValue(navigationElement.getContainingFile(), numberAndOffset); - } - - if (filesToNumbersAndOffsets.isEmpty()) { - return ""; - } - - List files = new ArrayList(filesToNumbersAndOffsets.keySet()); - Collections.sort(files, new Comparator() { + private Collection collectInterestingNavigationElements() { + return ContainerUtil.map(collectInterestingReferences(), new Function() { @Override - public int compare(PsiFile o1, PsiFile o2) { - return o1.getName().compareTo(o2.getName()); + public PsiElement fun(JetReference reference) { + PsiElement target = reference.resolve(); + assertNotNull(target); + return target.getNavigationElement(); } }); - - StringBuilder result = new StringBuilder(); - for (PsiFile file : files) { - List> numbersAndOffsets = new ArrayList>(filesToNumbersAndOffsets.get(file)); - - Collections.sort(numbersAndOffsets, Collections.reverseOrder(new Comparator>() { - @Override - public int compare(Pair t1, Pair t2) { - int offsets = t1.second.compareTo(t2.second); - return offsets == 0 ? t1.first.compareTo(t2.first) : offsets; - } - })); - - Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file); - assertNotNull(document); - StringBuilder resultForFile = new StringBuilder(document.getText()); - for (Pair numberOffset : numbersAndOffsets) { - resultForFile.insert(numberOffset.second, String.format("<%d>", numberOffset.first)); - } - - int minLine = Integer.MAX_VALUE; - int maxLine = Integer.MIN_VALUE; - for (Pair numberOffset : numbersAndOffsets) { - int lineNumber = document.getLineNumber(numberOffset.second); - minLine = Math.min(minLine, lineNumber); - maxLine = Math.max(maxLine, lineNumber); - } - - Document annotated = EditorFactory.getInstance().createDocument(resultForFile); - String filePart = annotated.getText().substring(annotated.getLineStartOffset(minLine), - annotated.getLineEndOffset(maxLine)); - result.append(" ").append(file.getName()).append("\n"); - result.append(filePart).append("\n"); - } - return result.toString(); } private String getExpectedAnnotatedLibraryCode() { @@ -199,7 +151,6 @@ public class NavigateToLibrarySourceTest extends AbstractNavigateToLibraryTest { return JetTestUtils.getLastCommentedLines(document); } - @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/NavigationTestUtils.java b/idea/tests/org/jetbrains/jet/plugin/navigation/NavigationTestUtils.java index 82929ddfc41..0bc2d05f3d7 100644 --- a/idea/tests/org/jetbrains/jet/plugin/navigation/NavigationTestUtils.java +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/NavigationTestUtils.java @@ -21,18 +21,24 @@ import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import com.intellij.codeInsight.navigation.GotoImplementationHandler; import com.intellij.codeInsight.navigation.GotoTargetHandler; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.testFramework.UsefulTestCase; +import com.intellij.util.containers.MultiMap; +import junit.framework.TestCase; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.InTextDirectivesUtils; import org.jetbrains.jet.testing.ReferenceUtils; import org.junit.Assert; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; public final class NavigationTestUtils { private NavigationTestUtils() { @@ -64,4 +70,60 @@ public final class NavigationTestUtils { UsefulTestCase.assertOrderedEquals(Collections.emptyList(), expectedReferences); } } + + public static String getNavigateElementsText(Project project, Collection navigableElements) { + MultiMap> filesToNumbersAndOffsets = new MultiMap>(); + int refNumber = 1; + for (PsiElement navigationElement : navigableElements) { + Pair numberAndOffset = new Pair(refNumber++, navigationElement.getTextOffset()); + filesToNumbersAndOffsets.putValue(navigationElement.getContainingFile(), numberAndOffset); + } + + if (filesToNumbersAndOffsets.isEmpty()) { + return ""; + } + + List files = new ArrayList(filesToNumbersAndOffsets.keySet()); + Collections.sort(files, new Comparator() { + @Override + public int compare(@NotNull PsiFile f1, @NotNull PsiFile f2) { + return f1.getName().compareTo(f2.getName()); + } + }); + + StringBuilder result = new StringBuilder(); + for (PsiFile file : files) { + List> numbersAndOffsets = new ArrayList>(filesToNumbersAndOffsets.get(file)); + + Collections.sort(numbersAndOffsets, Collections.reverseOrder(new Comparator>() { + @Override + public int compare(Pair t1, Pair t2) { + int offsets = t1.second.compareTo(t2.second); + return offsets == 0 ? t1.first.compareTo(t2.first) : offsets; + } + })); + + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + TestCase.assertNotNull(document); + StringBuilder resultForFile = new StringBuilder(document.getText()); + for (Pair numberOffset : numbersAndOffsets) { + resultForFile.insert(numberOffset.second, String.format("<%d>", numberOffset.first)); + } + + int minLine = Integer.MAX_VALUE; + int maxLine = Integer.MIN_VALUE; + for (Pair numberOffset : numbersAndOffsets) { + int lineNumber = document.getLineNumber(numberOffset.second); + minLine = Math.min(minLine, lineNumber); + maxLine = Math.max(maxLine, lineNumber); + } + + Document annotated = EditorFactory.getInstance().createDocument(resultForFile); + String filePart = annotated.getText().substring(annotated.getLineStartOffset(minLine), + annotated.getLineEndOffset(maxLine)); + result.append(" ").append(file.getName()).append("\n"); + result.append(filePart).append("\n"); + } + return result.toString(); + } }