diff --git a/src/test/java/de/tla2b/util/AbstractParseModuleTest.java b/src/test/java/de/tla2b/util/AbstractParseModuleTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f30bbdb7f17abad6510b26ae11e5d9935407e329 --- /dev/null +++ b/src/test/java/de/tla2b/util/AbstractParseModuleTest.java @@ -0,0 +1,107 @@ +package de.tla2b.util; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +import de.tla2b.util.PolySuite.Configuration; + + +public abstract class AbstractParseModuleTest { + private static final String[] SUFFIX = { ".tla" }; + + private static final class ModuleFilenameFilter implements FilenameFilter { + + + public boolean accept(final File dir, final String name) { + for (int i = 0; i < SUFFIX.length; i++) { + if (name.endsWith(SUFFIX[i])) { + return true; + } + } + return false; + } + } + + protected static File[] getModules(String path) { + final File dir = new File(path); + return dir.listFiles(new ModuleFilenameFilter()); + } + + protected static File[] getModulesRecursively(String path, ArrayList<String> ignoreList) { + File[] files = walk(path, ignoreList).toArray(new File[0]); + return files; + } + + private static ArrayList<File> walk(String path, ArrayList<String> ignoreList) { + File root = new File(path); + File[] list = root.listFiles(); + + ArrayList<File> files = new ArrayList<File>(); + if (list == null) + return files; + + for (File f : list) { + if (f.isDirectory()) { + boolean visitDir = true; + for (String string : ignoreList) { + File ignore = new File(string); + try { + if(f.getCanonicalPath().equals(ignore.getCanonicalPath())){ + visitDir = false; + } + } catch (IOException e) { + visitDir = false; + } + } + if(visitDir){ + files.addAll(walk(f.getAbsolutePath(),ignoreList)); + } + + } else { + String name =f.getName(); + for (int i = 0; i < SUFFIX.length; i++) { + if (name.endsWith(SUFFIX[i])) { + files.add(f); + } + } + } + } + return files; + } + + protected static Configuration getConfiguration2(ArrayList<String> list, ArrayList<String> ignoreList) { + final ArrayList<File> allModules = new ArrayList<File>(); + + final ArrayList<Object> expectedValues = new ArrayList<Object>(); + for (String path : list) { + File[] modules = getModulesRecursively(path, ignoreList); + allModules.addAll(Arrays.asList(modules)); + for (int i = 0; i < modules.length; i++) { + expectedValues.add(1); + } + } + + return new Configuration() { + public int size() { + return allModules.size(); + } + + public File getTestValue(int index) { + return allModules.get(index); + } + + public String getTestName(int index) { + return allModules.get(index).getName(); + } + + public Object getExpectedValue(int index) { + return expectedValues.get(index); + } + }; + } + + +} \ No newline at end of file diff --git a/src/test/java/de/tla2b/util/PolySuite.java b/src/test/java/de/tla2b/util/PolySuite.java new file mode 100644 index 0000000000000000000000000000000000000000..328d0c506f242810c68d0e6a83d87ce740f2eace --- /dev/null +++ b/src/test/java/de/tla2b/util/PolySuite.java @@ -0,0 +1,140 @@ +package de.tla2b.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.runner.Runner; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.Suite; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; +import org.junit.runners.model.TestClass; + +public class PolySuite extends Suite { + + // ////////////////////////////// + // Public helper interfaces + + /** + * Annotation for a method which returns a {@link Configuration} + * to be injected into the test class constructor + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public static @interface Config { + } + + public static interface Configuration { + int size(); + Object getTestValue(int index); + Object getExpectedValue(int index); + String getTestName(int index); + } + + // ////////////////////////////// + // Fields + + private final List<Runner> runners; + + // ////////////////////////////// + // Constructor + + /** + * Only called reflectively. Do not use programmatically. + * @param c the test class + * @throws Throwable if something bad happens + */ + public PolySuite(Class<?> c) throws Throwable { + super(c, Collections.<Runner>emptyList()); + TestClass testClass = getTestClass(); + Class<?> jTestClass = testClass.getJavaClass(); + Configuration configuration = getConfiguration(testClass); + List<Runner> runners = new ArrayList<Runner>(); + for (int i = 0, size = configuration.size(); i < size; i++) { + SingleRunner runner = new SingleRunner(jTestClass, configuration.getTestValue(i), configuration.getTestName(i), configuration.getExpectedValue(i)); + runners.add(runner); + } + this.runners = runners; + } + + // ////////////////////////////// + // Overrides + + @Override + protected List<Runner> getChildren() { + return runners; + } + + // ////////////////////////////// + // Private + + private Configuration getConfiguration(TestClass testClass) throws Throwable { + return (Configuration) getConfigMethod(testClass).invokeExplosively(null); + } + + private FrameworkMethod getConfigMethod(TestClass testClass) { + List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Config.class); + if (methods.isEmpty()) { + throw new IllegalStateException("@" + Config.class.getSimpleName() + " method not found"); + } + if (methods.size() > 1) { + throw new IllegalStateException("Too many @" + Config.class.getSimpleName() + " methods"); + } + FrameworkMethod method = methods.get(0); + int modifiers = method.getMethod().getModifiers(); + if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { + throw new IllegalStateException("@" + Config.class.getSimpleName() + " method \"" + method.getName() + "\" must be public static"); + } + return method; + } + + // ////////////////////////////// + // Helper classes + + private static class SingleRunner extends BlockJUnit4ClassRunner { + + private final Object testVal; + private final Object expectedVal; + private final String testName; + + SingleRunner(Class<?> testClass, Object testVal, String testName, Object expectedVal) throws InitializationError { + super(testClass); + this.testVal = testVal; + this.expectedVal = expectedVal; + this.testName = testName; + } + + @Override + protected Object createTest() throws Exception { + return getTestClass().getOnlyConstructor().newInstance(testVal, expectedVal); + } + + @Override + protected String getName() { + return testName; + } + + @Override + protected String testName(FrameworkMethod method) { + return testName + ": " + method.getName(); + } + + @Override + protected void validateConstructor(List<Throwable> errors) { + validateOnlyOneConstructor(errors); + } + + @Override + protected Statement classBlock(RunNotifier notifier) { + return childrenInvoker(notifier); + } + } + } \ No newline at end of file