package com.intellij.flex.highlighting; import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.flex.util.ActionScriptDaemonAnalyzerTestCase; import com.intellij.flex.util.FlexTestUtils; import com.intellij.javascript.flex.css.FlexStylesIndexableSetContributor; import com.intellij.lang.javascript.JSTestOption; import com.intellij.lang.javascript.JSTestOptions; import com.intellij.lang.javascript.flex.FlexModuleType; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static com.intellij.openapi.vfs.VfsUtilCore.convertFromUrl; import static com.intellij.openapi.vfs.VfsUtilCore.urlToPath; public class ActionScriptStubsTest extends ActionScriptDaemonAnalyzerTestCase { protected List<PsiFile> myPsiFiles = new ArrayList<>(); @Override protected void setUp() throws Exception { VfsRootAccess.allowRootAccess(getTestRootDisposable(), urlToPath(convertFromUrl(FlexStylesIndexableSetContributor.class.getResource("FlexStyles.as")))); super.setUp(); } @Override protected void tearDown() throws Exception { myPsiFiles.clear(); super.tearDown(); } @Override protected String getBasePath() { return ""; } @Override protected String getTestDataPath() { return FlexTestUtils.getTestDataPath(FlexHighlightingTest.BASE_PATH); } @Override protected String getExtension() { return "as"; } @Override protected boolean enableJSIndex() { return false; // otherwise all the files will be parsed when building } @Override protected void setUpJdk() { FlexTestUtils.setupFlexSdk(myModule, getTestName(false), getClass()); } protected ModuleType getModuleType() { return FlexModuleType.getInstance(); } private void doTest(@Nullable final ThrowableRunnable<Exception> runnable, String... files) throws Exception { Runnable r = runnable != null ? () -> { try { runnable.run(); } catch (Exception e) { throw new RuntimeException(e); } } : null; doTestFor(true, r, files); assertNotParsed(myPsiFiles.subList(1, myPsiFiles.size())); // the first one was parsed during highlighting // we need to go though files open in editors assertNotParsed(ContainerUtil.mapNotNull(FileEditorManager.getInstance(myProject).getOpenFiles(), virtualFile -> { if (Comparing.equal(virtualFile, myFile.getVirtualFile())) { return null; // this one is opened in editor } Document document = ((TextEditor)FileEditorManager.getInstance(myProject).getSelectedEditor(virtualFile)).getEditor().getDocument(); return PsiDocumentManager.getInstance(myProject).getPsiFile(document); })); } @Override protected VirtualFile configureByFiles(final File projectRoot, @NotNull final VirtualFile[] vFiles) throws IOException { VirtualFile result = super.configureByFiles(projectRoot, vFiles); for (VirtualFile vFile : vFiles) { // to have new instance of PsiFile created that will replace original that was parsed in order // to build stubs, this one should not be parsed and should get stub tree loaded from index PsiFile file = myPsiManager.findFile(vFile); myPsiFiles.add(file); } assertNotParsed(myPsiFiles); return result; } @JSTestOptions({JSTestOption.WithLineMarkers, JSTestOption.WithJsSupportLoader}) public void testOverridingMarkersIncludes1() throws Exception { doTest(null, getTestName(false) + ".as", getTestName(false) + "_2.as", getTestName(false) + "_3.as", getTestName(false) + "_4.as"); } @JSTestOptions({JSTestOption.WithLineMarkers}) public void testCreateVariable() throws Exception { doTest(() -> { final IntentionAction action = LightQuickFixTestCase .findActionWithText(LightQuickFixTestCase.getAvailableActions(myEditor, myFile), "Create Field 'myfield'"); CommandProcessor.getInstance().executeCommand(getProject(), () -> action.invoke(myProject, myEditor, myFile), "Create field", null); checkResultByFile(getBasePath() + "/" + getTestName(false) + "_after.as"); }, getTestName(false) + ".as", "restparam.swc"); } // yole: I don't know why we care whether a user-initiated operation such as "override methods" expands stubs or not public void _testNoParseOnMethodOverride() throws Exception { doTest(() -> { PlatformTestUtil.invokeNamedAction("OverrideMethods"); checkResultByFile(getBasePath() + "/" + getTestName(false) + "_after.as"); }, getTestName(false) + ".as", getTestName(false) + "_2.as"); } // kostya: I don't know why we care whether a user-initiated operation such as "delegate methods" expands stubs or not public void _testNoParseOnMethodDelegate() throws Exception { doTest(() -> { PlatformTestUtil.invokeNamedAction("DelegateMethods"); checkResultByFile(getBasePath() + "/" + getTestName(false) + "_after.as"); }, getTestName(false) + ".as", getTestName(false) + "_2.as"); } private static void assertNotParsed(Collection<PsiFile> psiFiles) { for (PsiFile file : psiFiles) { if (file instanceof PsiFileImpl) { assertNull("File should not be parsed before stubs test", ((PsiFileImpl)file).getTreeElement()); } } } }