POJO tests
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 18 Aug 2019 17:48:56 +0000 (19:48 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 18 Aug 2019 17:48:56 +0000 (19:48 +0200)
org.argeo.util/ext/test/org/argeo/util/ThroughputTest.java
org.argeo.util/src/org/argeo/util/test/Test.java [new file with mode: 0644]
org.argeo.util/src/org/argeo/util/test/TestStatus.java [new file with mode: 0644]

index fc8007efdd2d47cf20000cb406b69de33affa5f5..65d0a58e76803def223f70960d6087e756698c70 100644 (file)
  */
 package org.argeo.util;
 
-import junit.framework.TestCase;
+public class ThroughputTest {
+       public void testParse() throws Exception {
+//             assert 0 == 1;
 
-public class ThroughputTest extends TestCase {
-       public void testParse() {
                Throughput t;
                t = new Throughput("3.54/s");
-               assertEquals(3.54d, t.getValue());
-               assertEquals(Throughput.Unit.s, t.getUnit());
-               assertEquals(282l, (long) t.asMsPeriod());
+               assert 3.54d == t.getValue();
+               assert Throughput.Unit.s.equals(t.getUnit());
+               assert 282l == (long) t.asMsPeriod();
 
                t = new Throughput("35698.2569/h");
-               assertEquals(Throughput.Unit.h, t.getUnit());
-               assertEquals(101l, (long) t.asMsPeriod());
+               assert Throughput.Unit.h.equals(t.getUnit());
+               assert 101l == (long) t.asMsPeriod();
        }
 }
diff --git a/org.argeo.util/src/org/argeo/util/test/Test.java b/org.argeo.util/src/org/argeo/util/test/Test.java
new file mode 100644 (file)
index 0000000..74f165e
--- /dev/null
@@ -0,0 +1,93 @@
+package org.argeo.util.test;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/** A generic tester based on Java assertions and functional programming. */
+public class Test {
+       private Map<String, TestStatus> results = Collections.synchronizedSortedMap(new TreeMap<>());
+
+       protected void execute(String className) throws Throwable {
+               ClassLoader classLoader = Test.class.getClassLoader();
+               Class<?> clss = classLoader.loadClass(className);
+               boolean assertionsEnabled = clss.desiredAssertionStatus();
+               if (!assertionsEnabled)
+                       throw new IllegalStateException("Test runner " + getClass().getName()
+                                       + " requires Java assertions to be enabled. Call the JVM with the -ea argument.");
+               Object obj = clss.getDeclaredConstructor().newInstance();
+               List<Method> methods = findMethods(clss);
+               if (methods.size() == 0)
+                       throw new IllegalArgumentException("No test method found in " + clss);
+               // TODO make order more predictable?
+               for (Method method : methods) {
+                       String uid = method.getDeclaringClass().getName() + "#" + method.getName();
+                       TestStatus testStatus = new TestStatus(uid);
+                       try {
+                               method.invoke(obj);
+                               testStatus.setPassed();
+                       } catch (Exception e) {
+                               testStatus.setFailed(e);
+                       } finally {
+                               results.put(uid, testStatus);
+                       }
+               }
+       }
+
+       protected List<Method> findMethods(Class<?> clss) {
+               List<Method> methods = new ArrayList<Method>();
+//             Method call = getMethod(clss, "call");
+//             if (call != null)
+//                     methods.add(call);
+//
+               for (Method method : clss.getMethods()) {
+                       if (method.getName().startsWith("test")) {
+                               methods.add(method);
+                       }
+               }
+               return methods;
+       }
+
+       protected Method getMethod(Class<?> clss, String name, Class<?>... parameterTypes) {
+               try {
+                       return clss.getMethod(name, parameterTypes);
+               } catch (NoSuchMethodException e) {
+                       return null;
+               } catch (SecurityException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       public static void main(String[] args) {
+               // deal with arguments
+               String className;
+               if (args.length < 1) {
+                       System.err.println(usage());
+                       System.exit(1);
+                       throw new IllegalArgumentException();
+               } else {
+                       className = args[0];
+               }
+
+               Test test = new Test();
+               try {
+                       test.execute(className);
+               } catch (Throwable e) {
+                       e.printStackTrace();
+               }
+
+               Map<String, TestStatus> r = test.results;
+               for (String uid : r.keySet()) {
+                       TestStatus testStatus = r.get(uid);
+                       System.out.println(testStatus);
+               }
+       }
+
+       public static String usage() {
+               return "java " + Test.class.getName() + " [test class name]";
+
+       }
+}
diff --git a/org.argeo.util/src/org/argeo/util/test/TestStatus.java b/org.argeo.util/src/org/argeo/util/test/TestStatus.java
new file mode 100644 (file)
index 0000000..79cfbcd
--- /dev/null
@@ -0,0 +1,98 @@
+package org.argeo.util.test;
+
+import java.io.Serializable;
+
+/** The status of a test. */
+public class TestStatus implements Serializable {
+       private static final long serialVersionUID = 6272975746885487000L;
+
+       private Boolean passed = null;
+       private final String uid;
+       private Throwable throwable = null;
+
+       public TestStatus(String uid) {
+               this.uid = uid;
+       }
+
+       /** For cloning. */
+       public TestStatus(String uid, Boolean passed, Throwable throwable) {
+               this(uid);
+               this.passed = passed;
+               this.throwable = throwable;
+       }
+
+       public synchronized Boolean isRunning() {
+               return passed == null;
+       }
+
+       public synchronized Boolean isPassed() {
+               assert passed != null;
+               return passed;
+       }
+
+       public synchronized Boolean isFailed() {
+               assert passed != null;
+               return !passed;
+       }
+
+       public synchronized void setPassed() {
+               setStatus(true);
+       }
+
+       public synchronized void setFailed() {
+               setStatus(false);
+       }
+
+       public synchronized void setFailed(Throwable throwable) {
+               setStatus(false);
+               setThrowable(throwable);
+       }
+
+       protected void setStatus(Boolean passed) {
+               if (this.passed != null)
+                       throw new IllegalStateException("Passed status of test " + uid + " is already set (to " + passed + ")");
+               this.passed = passed;
+       }
+
+       protected void setThrowable(Throwable throwable) {
+               if (this.throwable != null)
+                       throw new IllegalStateException("Throwable of test " + uid + " is already set (to " + passed + ")");
+               this.throwable = throwable;
+       }
+
+       public String getUid() {
+               return uid;
+       }
+
+       public Throwable getThrowable() {
+               return throwable;
+       }
+
+       @Override
+       protected Object clone() throws CloneNotSupportedException {
+               // TODO Auto-generated method stub
+               return super.clone();
+       }
+
+       @Override
+       public boolean equals(Object o) {
+               if (o instanceof TestStatus) {
+                       TestStatus other = (TestStatus) o;
+                       // we don't check consistency for performance purposes
+                       // this equals() is supposed to be used in collections or for transfer
+                       return other.uid.equals(uid);
+               }
+               return false;
+       }
+
+       @Override
+       public int hashCode() {
+               return uid.hashCode();
+       }
+
+       @Override
+       public String toString() {
+               return uid + "\t" + (passed ? "passed" : "failed");
+       }
+
+}