/* * Copyright 2003-2015 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.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.project.Project; import com.intellij.util.ui.UIUtil; import jetbrains.mps.ide.editor.MPSEditorOpener; import jetbrains.mps.ide.project.ProjectHelper; import jetbrains.mps.idea.core.facet.MPSFacetConfiguration; import jetbrains.mps.lang.test.runtime.LightEnvironment; import jetbrains.mps.lang.test.runtime.TestRunner; import jetbrains.mps.lang.test.runtime.TransformationTest; import jetbrains.mps.lang.test.runtime.TransformationTestRunner; import jetbrains.mps.persistence.DefaultModelRoot; import jetbrains.mps.project.MPSProject; import jetbrains.mps.smodel.SModelFileTracker; import jetbrains.mps.vfs.FileSystem; import jetbrains.mps.vfs.IFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SModel; import org.jetbrains.mps.openapi.model.SNode; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class EditorTests extends DataMPSFixtureTestCase { private List<TransformationTest> tests = new ArrayList<TransformationTest>(); @Override protected void prepareTestData(MPSFacetConfiguration configuration) throws Exception { IFile test = copyResource("models", "test.mps", "test.mps", "/tests/editorTests/models/test.mps"); DefaultModelRoot root = new DefaultModelRoot(); root.setContentRoot(test.getParent().getPath()); root.addFile(DefaultModelRoot.SOURCE_ROOTS, test.getParent().getPath()); configuration.getBean().setModelRoots(Arrays.<org.jetbrains.mps.openapi.persistence.ModelRoot>asList(root)); } @Override protected void setUp() throws Exception { super.setUp(); // this is to prevent exceptions in the project components that get "projectClosed" notifications ApplicationManagerEx.getApplicationEx().doNotSave(); final Exception[] thrown = new Exception[1]; runModelRead(new Runnable() { @Override public void run() { DefaultModelRoot sModelRoot = (DefaultModelRoot) myFacet.getSolution().getModelRoots().iterator().next(); String path = sModelRoot.getFiles(DefaultModelRoot.SOURCE_ROOTS).iterator().next(); final IFile modelFile = FileSystem.getInstance().getFile(path + "/test.mps"); final List<SNode> roots = new ArrayList<SNode>(); SModel descr = SModelFileTracker.getInstance(ProjectHelper.getProjectRepository(myProjectBuilder.getFixture().getProject())).findModel(modelFile); if (descr == null) { thrown[0] = new IllegalStateException("model not found"); return; } for (SNode root : descr.getRootNodes()) { roots.add(root); } for (SNode r : roots) { if ("EditorTestCase".equals(r.getConcept().getName())) { try { Class<?> cls = Class.forName(jetbrains.mps.util.SNodeOperations.getModelLongName(descr) + "." + r.getName() + "_Test"); Method mth = cls.getMethod("test_" + r.getName()); TransformationTest btt = (TransformationTest) cls.newInstance(); final TestRunner testRunner = new SimpleTransformationTestRunner(r, mth); btt.setTestRunner(testRunner); tests.add(btt); } catch (Exception e) { thrown[0] = e; } } } } }); if (thrown[0] != null) throw thrown[0]; //Flush all EDT events to be made before run tests UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { try { flushEDT(); } catch (InterruptedException e) { e.printStackTrace(); } } }); } @Override protected void tearDown() throws Exception { final Exception[] thrown = new Exception[1]; UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { try { EditorTests.super.tearDown(); } catch (Exception e) { thrown[0] = e; } } }); if (thrown[0] != null) throw thrown[0]; //TODO: see commit 543037363dfc71abd442f8963c60bfcbb066fcfb and 6f76d0b27dad6b10b908eebb158d8a8e81f7fbe4 in IDEA to decide how to handle this /*Project prj = myModule.getProject(); if (prj instanceof ProjectImpl) { ((ProjectImpl)prj).setTemporarilyDisposed(true); }*/ } public void test_AllEditorTests() throws Throwable { for (TransformationTest btt : tests) { ((SimpleTransformationTestRunner) btt.getTestRunner()).doTest(btt); } } public class SimpleTransformationTestRunner extends TransformationTestRunner { private SNode myRoot; private Method myTestMethod; public SimpleTransformationTestRunner(SNode root, Method testMethod) { super(new LightEnvironment()); myRoot = root; myTestMethod = testMethod; } public void doTest(TransformationTest btt) throws Throwable { try { myTestMethod.invoke(btt); } catch (InvocationTargetException e) { throw e.getCause(); } } @Override public void initTest(final TransformationTest btt, @NotNull String projectName, String model) throws Exception { UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { final MPSProject mpsProject = ProjectHelper.fromIdeaProject(myModule.getProject()); mpsProject.getModelAccess().runWriteAction(new Runnable() { @Override public void run() { new MPSEditorOpener(mpsProject).openNode(myRoot, true, true); btt.setModelDescriptor(myRoot.getModel()); btt.setProject(mpsProject); } }); } }); } @Override public void initTest(final TransformationTest btt, @NotNull String projectName, String model, boolean reOpenProject) throws Exception { // TODO use flags initTest(btt, projectName, model); } @Override public void runTest(TransformationTest btt, String className, String methodName, boolean runInCommand) throws Throwable { try { Class<?> cls = Class.forName(className); Object obj = cls.newInstance(); cls.getField("myModel").set(obj, btt.getModelDescriptor()); cls.getField("myProject").set(obj, btt.getProject()); Method mth = cls.getMethod(methodName); mth.invoke(obj); } catch (InvocationTargetException e) { throw e.getCause(); } } } }