diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/WholeProjectAnalyzerFacade.java b/idea/src/org/jetbrains/jet/plugin/compiler/WholeProjectAnalyzerFacade.java index ec99fa7d3df..b858df279df 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/WholeProjectAnalyzerFacade.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/WholeProjectAnalyzerFacade.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.plugin.compiler; import com.google.common.collect.Sets; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.ex.CompilerPathsEx; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; @@ -41,7 +40,7 @@ public final class WholeProjectAnalyzerFacade { final Set namespaces = Sets.newLinkedHashSet(); final ProjectRootManager rootManager = ProjectRootManager.getInstance(project); - if (rootManager != null && !ApplicationManager.getApplication().isUnitTestMode()) { + if (rootManager != null /* && !ApplicationManager.getApplication().isUnitTestMode() */) { VirtualFile[] contentRoots = rootManager.getContentRoots(); CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() { @@ -57,7 +56,6 @@ public final class WholeProjectAnalyzerFacade { } } }); - } namespaces.add(rootFile.getRootNamespace()); diff --git a/idea/testData/quickfix/autoImports/afterKotlinImport.kt b/idea/testData/quickfix/autoImports/afterKotlinImport.kt new file mode 100644 index 00000000000..e6c19003945 --- /dev/null +++ b/idea/testData/quickfix/autoImports/afterKotlinImport.kt @@ -0,0 +1,7 @@ +// "Import Class" "true" + +import TestData.TestSample + +fun test() { + val a = TestSample +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/beforeKotlinImport.Data.Sample.kt b/idea/testData/quickfix/autoImports/beforeKotlinImport.Data.Sample.kt new file mode 100644 index 00000000000..24ab2e94d15 --- /dev/null +++ b/idea/testData/quickfix/autoImports/beforeKotlinImport.Data.Sample.kt @@ -0,0 +1,3 @@ +namespace TestData + +class TestSample() {} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/beforeKotlinImport.Main.kt b/idea/testData/quickfix/autoImports/beforeKotlinImport.Main.kt new file mode 100644 index 00000000000..9136601298a --- /dev/null +++ b/idea/testData/quickfix/autoImports/beforeKotlinImport.Main.kt @@ -0,0 +1,5 @@ +// "Import Class" "true" + +fun test() { + val a = TestSample +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java new file mode 100644 index 00000000000..6a977c15ca0 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java @@ -0,0 +1,191 @@ +package org.jetbrains.jet.plugin.quickfix; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.Pair; +import com.intellij.rt.execution.junit.FileComparisonFailure; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * @author Nikolay Krasko + */ +public abstract class JetPsiCheckerMultifileTest extends DaemonAnalyzerTestCase { + + public final static String MAIN_SUBSTRING = ".Main"; + public final static String DATA_SUBSTRING = ".Data"; + + private final String dataPath; + private final String name; + + public JetPsiCheckerMultifileTest(String dataPath, String name) { + this.dataPath = dataPath; + this.name = name; + + setName("testRun"); + } + + protected boolean shouldBeAvailableAfterExecution() { + return false; + } + + public void testRun() throws Exception { + configureByFiles(null, getFileNames(getTestFiles()).toArray(new String[1])); + doTest(); + } + + public void doTest() { + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + @Override + public void run() { + try { + final Pair pair = LightQuickFixTestCase.parseActionHint(getFile(), loadFile(getFile().getName())); + final String text = pair.getFirst(); + + final boolean actionShouldBeAvailable = pair.getSecond(); + + doAction(text, actionShouldBeAvailable, getTestDataPath()); + } + catch (FileComparisonFailure e){ + throw e; + } + catch (Throwable e) { + e.printStackTrace(); + fail(getTestName(true)); + } + } + }, "", ""); + } + + @SuppressWarnings({"HardCodedStringLiteral"}) + public void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath) + throws Exception { + IntentionAction action = LightQuickFixTestCase.findActionWithText(getAvailableActions(), text); + if (action == null) { + if (actionShouldBeAvailable) { + List actions = getAvailableActions(); + List texts = new ArrayList(); + for (IntentionAction intentionAction : actions) { + texts.add(intentionAction.getText()); + } + Collection infos = doHighlighting(); + fail("Action with text '" + text + "' is not available in test " + testFullPath + "\n" + + "Available actions (" + texts.size() + "): " + texts + "\n" + + actions + "\n" + + "Infos:" + infos); + } + } + else { + if (!actionShouldBeAvailable) { + fail("Action '" + text + "' is available (but must not) in test " + testFullPath); + } + + ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText()); + + UIUtil.dispatchAllInvocationEvents(); + + if (!shouldBeAvailableAfterExecution()) { + final IntentionAction afterAction = LightQuickFixTestCase.findActionWithText(getAvailableActions(), text); + + if (afterAction != null) { + fail("Action '" + text + "' is still available after its invocation in test " + testFullPath); + } + } + + checkResultByFile(name.replace("before", "after").replace(MAIN_SUBSTRING, "") + ".kt"); + } + } + + protected List getTestFiles() { + File dir = new File(getTestDataPath()); + + assertTrue("Main file should contain .Main. substring", name.contains(MAIN_SUBSTRING)); + final String testPrefix = name.replace(MAIN_SUBSTRING, ""); + + // Files of single test + FilenameFilter resultFilter = new FilenameFilter() { + @Override + public boolean accept(File file, String s) { + return s.contains(testPrefix) && !s.contains("after"); + } + }; + + List allTestFiles = Arrays.asList(dir.listFiles(resultFilter)); + + final Collection mainFiles = Collections2.filter(allTestFiles, new Predicate() { + @Override + public boolean apply(@Nullable File file) { + return file != null && file.getName().contains(MAIN_SUBSTRING); + } + }); + + assertTrue("No main file for test", mainFiles.size() > 0); + assertTrue("Too many main files for the test", mainFiles.size() <= 1); + + final Collection dataFiles = Collections2.filter(allTestFiles, new Predicate() { + @Override + public boolean apply(@Nullable File file) { + return file != null && file.getName().contains(DATA_SUBSTRING); + } + }); + + final ArrayList fileResult = new ArrayList(allTestFiles); + fileResult.addAll(dataFiles); + + return fileResult; + } + + protected static List getFileNames(List files) { + return Lists.newArrayList(Collections2.transform(files, new Function() { + @Override + public String apply(File file) { + return file.getName(); + } + })); + } + + protected List getAvailableActions() { + doHighlighting(); + return LightQuickFixTestCase.getAvailableActions(getEditor(), getFile()); + } + + @Override + public String getName() { + return "test" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase()); + } + + @Override + protected String getTestDataPath() { + return PluginTestCaseBase.getTestDataPathBase() + "/quickfix/" + dataPath + "/"; + } + + @Override + protected Sdk getTestProjectJdk() { + return PluginTestCaseBase.jdkFromIdeaHome(); + } + + public static boolean isMultiFileName(String fileName) { + return fileName.contains(MAIN_SUBSTRING) || fileName.contains(DATA_SUBSTRING); + } + + public static boolean isMainFile(String fileName) { + return fileName.contains(MAIN_SUBSTRING); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java index 62faeb23d10..c56724b64cb 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetQuickFixTest.java @@ -39,29 +39,61 @@ public class JetQuickFixTest extends LightQuickFixTestCase { } }; } + + private static class JetPsiCheckerMultifileTestImpl extends JetPsiCheckerMultifileTest { + public JetPsiCheckerMultifileTestImpl(String dataPath, String name) { + super(dataPath, name); + } + } public static Test suite() { //setFilter(); //to launch only part of tests TestSuite suite = new TestSuite(); - FilenameFilter fileNameFilter = new FilenameFilter() { + + FilenameFilter singleFileNameFilter = new FilenameFilter() { @Override public boolean accept(File file, String s) { - if (s.startsWith("before")) return true; - return false; + return s.startsWith("before") && !JetPsiCheckerMultifileTest.isMultiFileName(s); } }; - JetTestCaseBuilder.NamedTestFactory namedTestFactory = new JetTestCaseBuilder.NamedTestFactory() { + + FilenameFilter multifileFileNameFilter = new FilenameFilter() { + @Override + public boolean accept(File file, String s) { + return s.startsWith("before") && JetPsiCheckerMultifileTest.isMainFile(s); + } + }; + + JetTestCaseBuilder.NamedTestFactory singleFileNamedTestFactory = new JetTestCaseBuilder.NamedTestFactory() { @NotNull @Override public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { return new JetQuickFixTest(dataPath, name); } }; + + JetTestCaseBuilder.NamedTestFactory multiFileNamedTestFactory = new JetTestCaseBuilder.NamedTestFactory() { + @NotNull + @Override + public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { + return new JetPsiCheckerMultifileTestImpl(dataPath, name); + } + }; + File dir = new File(getTestDataPathBase()); List subDirs = Arrays.asList(quickFixTestsFilter != null ? dir.list(quickFixTestsFilter) : dir.list()); Collections.sort(subDirs); for (String subDirName : subDirs) { - suite.addTest(JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, fileNameFilter, namedTestFactory)); + + final TestSuite singleFileTestSuite = JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, singleFileNameFilter, singleFileNamedTestFactory); + if (singleFileTestSuite.countTestCases() != 0) { + suite.addTest(singleFileTestSuite); + } + + final TestSuite multiFileTestSuite = JetTestCaseBuilder.suiteForDirectory(getTestDataPathBase(), subDirName, true, multifileFileNameFilter, multiFileNamedTestFactory); + if (multiFileTestSuite.countTestCases() != 0) { + suite.addTest(multiFileTestSuite); + } } return suite;