/* * Copyright 2003-2016 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 jetbrains.mps.idea.core.tests; import com.intellij.facet.FacetManager; import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent.Callback; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiPackage; import com.intellij.refactoring.rename.RenameProcessor; import com.intellij.testFramework.MapDataContext; import com.intellij.testFramework.TestActionEvent; import jetbrains.mps.ide.project.ProjectHelper; import jetbrains.mps.ide.vfs.VirtualFileUtils; import jetbrains.mps.idea.core.actions.MakeDirAModel; import jetbrains.mps.idea.core.facet.MPSFacetConfiguration; import jetbrains.mps.idea.core.facet.MPSFacetType; import jetbrains.mps.persistence.DefaultModelRoot; import jetbrains.mps.project.LanguageImportHelper.Interaction; import jetbrains.mps.smodel.SModelFileTracker; import jetbrains.mps.smodel.SModelInternal; import jetbrains.mps.util.IterableUtil; import jetbrains.mps.workbench.choose.ChooseByNameData; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.module.SModule; import org.jetbrains.mps.openapi.module.SRepository; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; /** * Created by danilla on 03/06/16. */ public class UseLanguageInPackageTest extends DataMPSFixtureTestCase { private VirtualFile myPackageDir; @Override protected void prepareTestData(MPSFacetConfiguration configuration) throws Exception { myModule = configuration.getFacet().getModule(); VirtualFile[] sourceRoots = ModuleRootManager.getInstance(myModule).getSourceRoots(); assertEquals(sourceRoots.length, 1); String sourceRootPath = sourceRoots[0].getPath(); DefaultModelRoot root = new DefaultModelRoot(); root.setContentRoot(sourceRootPath); root.addFile(DefaultModelRoot.SOURCE_ROOTS, sourceRootPath); configuration.getBean().setModelRoots(Arrays.<org.jetbrains.mps.openapi.persistence.ModelRoot>asList(root)); myPackageDir = VfsUtil.createDirectories(sourceRootPath + "/com/jetbrains/pkg"); } protected void doTest(Interaction interaction) { Project project = myProjectBuilder.getFixture().getProject(); Ref<PsiDirectory> dirElement = new Ref<>(); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { dirElement.set(PsiManager.getInstance(project).findDirectory(myPackageDir)); } }); MakeDirAModel action = new MakeDirAModel(); // Couldn't make a more honest context to work. By more honest I mean the one taken from project pane, // either by DataManager or new TestDataContext. Hence, constructing an artificial data context. // Doing it by project pane would require us to have TestProjectTreeStructure in this test // AnActionEvent e = new TestActionEvent(DataManager.getInstance().getDataContext(pane.get().getTree()), action); // AnActionEvent e = new TestActionEvent(new TestDataContext(pane.get(), project), action); // where pane is Ref<AbstractProjectViewPSIPane> MapDataContext dataContext = new MapDataContext(); dataContext.put(PlatformDataKeys.PROJECT, project); dataContext.put(LangDataKeys.MODULE, myModule); dataContext.put(PlatformDataKeys.PSI_ELEMENT, dirElement.get()); dataContext.put(PlatformDataKeys.VIRTUAL_FILE_ARRAY, new VirtualFile[]{dirElement.get().getVirtualFile()}); dataContext.put(MakeDirAModel.LANGUAGE_IMPORT_INTERACTION, interaction); AnActionEvent e = new TestActionEvent(dataContext, action); action.update(e); assertTrue(e.getPresentation().isEnabled()); action.beforeActionPerformedUpdate(e); ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { action.actionPerformed(e); } }, ModalityState.NON_MODAL); } protected final Interaction cancelInteraction = new Interaction() { @Override public void chooseLanguage(ChooseByNameData<SLanguage> data, Callback callback) { // closing it right away without choosing anything // we _must_ close the "window", real UI probably always calls this method callback.onClose(); } @Override public Set<SLanguage> chooseAdditionalLanguages(Set<SLanguage> set) { return null; } }; protected final Interaction chooseOnlyBaseLanguageInteraction = new Interaction() { @Override public void chooseLanguage(ChooseByNameData<SLanguage> data, Callback callback) { String[] names = data.getNames(true); assertTrue(Arrays.asList(names).contains("jetbrains.mps.baseLanguage")); Object[] navigationItems = data.getElementsByName("jetbrains.mps.baseLanguage", true, null); assertTrue(navigationItems.length > 0); callback.elementChosen(navigationItems[0]); // we _must_ close the "window", real UI probably always calls this method callback.onClose(); } @Override public Set<SLanguage> chooseAdditionalLanguages(Set<SLanguage> set) { // equivalent of hitting 'none' in the dialog box asking if we want to import more langs return Collections.emptySet(); } }; public void testCancelCreationOfModelInDir() { doTest(cancelInteraction); // check no model has been created SRepository repository = ProjectHelper.getProjectRepository(myProjectBuilder.getFixture().getProject()); repository.getModelAccess().runReadAction(new Runnable() { @Override public void run() { SModel smodel = SModelFileTracker.getInstance(repository).findModel(VirtualFileUtils.toIFile(myPackageDir)); assertNull("Model must not have been created under the directory because the action was cancelled", smodel); } }); } public void testCreateModelInDir() { doTest(chooseOnlyBaseLanguageInteraction); SRepository repository = ProjectHelper.getProjectRepository(myProjectBuilder.getFixture().getProject()); repository.getModelAccess().runReadAction(new Runnable() { @Override public void run() { SModel smodel = SModelFileTracker.getInstance(repository).findModel(VirtualFileUtils.toIFile(myPackageDir)); assertNotNull("Model hasn't been created under the directory", smodel); Collection<SLanguage> importedLanguages = ((SModelInternal) smodel).importedLanguageIds(); assertTrue("Model is expected to have exactly one used language", importedLanguages.size() == 1); assertEquals("jetbrains.mps.baseLanguage", importedLanguages.iterator().next().getQualifiedName()); } }); } public void testRenamePackage() { doTest(chooseOnlyBaseLanguageInteraction); Project project = myProjectBuilder.getFixture().getProject(); ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { PsiPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage("com.jetbrains.pkg"); assertNotNull(psiPackage); new RenameProcessor(project, psiPackage, "com.jetbrains.pkgRenamed", false, false).run(); } }, null, null); } }, ModalityState.NON_MODAL); ProjectHelper.getModelAccess(project).runReadAction(new Runnable() { @Override public void run() { SModule module = FacetManager.getInstance(myModule).getFacetByType(MPSFacetType.ID).getSolution(); List<SModel> smodels = IterableUtil.asList(module.getModels()); assertEquals("Exactly one model must be in the idea solution after package rename", 1, smodels.size()); SModel smodel = smodels.get(0); assertEquals("com.jetbrains.pkgRenamed", smodel.getName().getLongName()); } }); } }