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;
}
}