package jetbrains.mps.testbench.junit.suites; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import jetbrains.mps.project.Project; import jetbrains.mps.tool.environment.Environment; import java.util.List; import org.junit.runner.Runner; import org.junit.runners.model.RunnerBuilder; import org.junit.runners.model.InitializationError; import java.util.Collections; import jetbrains.mps.testbench.junit.runners.FromModulesListProjectStrategy; import jetbrains.mps.tool.environment.EnvironmentConfig; import jetbrains.mps.internal.collections.runtime.IMapping; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.io.File; import jetbrains.mps.tool.environment.IdeaEnvironment; import java.util.Map; import java.util.LinkedHashMap; import java.util.HashMap; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.ArrayList; import org.jetbrains.mps.openapi.module.SModule; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.module.ReloadableModule; import org.apache.log4j.Level; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.internal.collections.runtime.Sequence; import org.jetbrains.mps.openapi.model.SNode; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import jetbrains.mps.smodel.behaviour.BHReflection; import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId; import jetbrains.mps.testbench.junit.runners.DelegatingRunner; /** * Currently used for ant tests * todo: WatchingSuite? */ public class MpsTestsSuite extends BaseMpsSuite { private static final Logger LOG = LogManager.getLogger(MpsTestsSuite.class); private static final String PROPERTY_LIBRARY = "mps.libraries"; private static final String MPS_MACRO_PREFIX = "mps.macro."; private final Project myContextProject; private final Environment myEnvironment; private final List<Runner> myChildren; public MpsTestsSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError { super(klass, Collections.<Runner>emptyList()); // todo: read config from annotations before start (project / ?) myEnvironment = initIdeaEnvironment(); myContextProject = myEnvironment.createProject(new FromModulesListProjectStrategy()); myChildren = createChildRunners(myContextProject, builder); } public Environment initIdeaEnvironment() { EnvironmentConfig config = EnvironmentConfig.defaultConfig(); for (IMapping<String, String> lib : MapSequence.fromMap(loadLibraries())) { config = config.addLib(lib.value()); } for (IMapping<String, File> macro : MapSequence.fromMap(loadMacros())) { config = config.addMacro(macro.key(), macro.value()); } return IdeaEnvironment.getOrCreate(config); } private static Map<String, String> loadLibraries() { Map<String, String> result = MapSequence.fromMap(new LinkedHashMap<String, String>(16, (float) 0.75, false)); String librariesString = System.getProperty(MpsTestsSuite.PROPERTY_LIBRARY); if ((librariesString == null || librariesString.length() == 0)) { return result; } String[] libraries = librariesString.split(File.pathSeparator); for (String lib : libraries) { File libFile = new File(lib); if (libFile.exists()) { MapSequence.fromMap(result).put(libFile.getName(), lib); } } return result; } private static Map<String, File> loadMacros() { Map<String, File> result = MapSequence.fromMap(new HashMap<String, File>()); for (Map.Entry<Object, Object> property : SetSequence.fromSet(System.getProperties().entrySet())) { if (property.getKey() instanceof String && property.getValue() instanceof String) { String key = (String) property.getKey(); String value = (String) property.getValue(); if (key.startsWith(MpsTestsSuite.MPS_MACRO_PREFIX) && key.length() > MpsTestsSuite.MPS_MACRO_PREFIX.length()) { String macroSuffix = key.substring(MpsTestsSuite.MPS_MACRO_PREFIX.length()); MapSequence.fromMap(result).put(macroSuffix, new File(value)); } } } return result; } @Override protected List<Runner> getChildren() { return myChildren; } private List<Runner> createChildRunners(Project project, final RunnerBuilder builder) { final List<Runner> result = new ArrayList<Runner>(); project.getModelAccess().runReadAction(new Runnable() { public void run() { for (SModule module : ListSequence.fromList(myContextProject.getProjectModules())) { ClassLoader moduleCL = ((ReloadableModule) module).getClassLoader(); if (moduleCL == null) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Classloader is not found for the " + module); } continue; } for (SModel model : Sequence.fromIterable(module.getModels())) { for (SNode testCase : ListSequence.fromList(SModelOperations.roots(((SModel) model), MetaAdapterFactory.getInterfaceConcept(0xf61473f9130f42f6L, 0xb98d6c438812c2f6L, 0x11b2709bd56L, "jetbrains.mps.baseLanguage.unitTest.structure.ITestCase")))) { String testClassName = ((String) BHReflection.invoke(testCase, SMethodTrimmedId.create("getClassName", null, "hGBnqtL"))); try { Class<?> testClass = moduleCL.loadClass(testClassName); result.add(new DelegatingRunner(builder, testClass)); } catch (ClassNotFoundException e) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Cannot find the test class " + testClassName + "; will skip this test class"); } } } } } } }); return result; } }