java/ch/wlkl/env/IOTest.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ch.wlkl.env;

import static ch.wlkl.env.Env.*;
import static ch.wlkl.env.Ut.*;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 *
 * @author walter
 */
public class IOTest extends IOSimple {

    int cm1 = 0;
    int er1 = 0;
    int ou1 = 0;
    int de1 = 0;
    int tCase = 0;
    int tErr = 0;
    int cmp = 0;
    int err = 0;
    int out = 0;
    int deb = 0;
    String name = null;
    int ioStackSz = -1;

    public void test(Consumer<IOTest>... l) {
        test("", l);
    }
    
    public void test(String nm, Consumer<IOTest>... l) {
        int oldCase = tCase;
        All2S oldAll2S = env.all2s;
        if (nm != null && nm.length() != 0)
            hdFi(1, nm + " begin ");
        push(this);
        ioStackSz = env.ioStack.size();
        check();

        for (Consumer<IOTest> t : l) {
            testOne(t);
        }
        
        check();
        total(nm);
        pop();
        ioStackSz = -9;
    }

    public void testOne(Consumer<IOTest> t) {
        clear();
        try {
            t.accept(this);
        } catch (Throwable ex) {
            err("testOne " + name + " caught " + ex.getClass().getSimpleName(), ex);
        }
        if (name != null) {
            end();
        }
    }

    public IOTest check() {
        if (!assertsEnabled()) {
            env.dy("Asserts must be enabled!!!");
        }
        assert io == this && ioStackSz == env.ioStack.size() : assFail("mismatch Env.io", io, " <> this ", this);
        return this;
    }

    public void outln(String s) {
        if (name == null)
            begin(null);
        super.outln(s);
        ou1++;
    }

    public void debug(int l, String m, Object... o) {
        de1++;
        super.debug(l, m, o);
    }

    public void err(String m, Object... o) {
        er1++;
        super.err(m, o);
    }

    public void begin(String nm, String... c) {
        begin(nm);
    }
    
    public void begin(String nm) {
        if (name != null) { // do not use err to avoid stackoverflow
            hdFi(0, "error begin(" + nm + ") but still in " + name);
            er1 ++ ;
        } else if (ou1 != 0 | er1 != 0 | de1 != 0) { // do not use err to avoid stackoverflow
            hdFi(0, "error begin(" + nm + ") not after testEnd");
            er1 ++ ;
        }
        tCase ++;
        ou1 = 0;
        cm1 = -9;
        name = nm != null ? nm : "anonymousTest" + tCase;
        hd(2, "begin " + name);
        check();
    }

    public static boolean assertsEnabled() {
        boolean assertsEnabled = false;
        assert assertsEnabled = true; // Intentional side effect!!!
        return assertsEnabled;
    }

    public void end1() {
        if (name == null) {
            err("end() but not in test");
        }
        hdFi(2, "end " + name + ": " + (cm1 < 0 ? "" : cm1 + " compareDifferences, ") + er1 +" errors, " + ou1 + " says and " + de1 + " debugs");
    }

    public void end() {
        check();
        end1();
        end2();
    }

    public void end2() {
        if (cm1 > 0) {
            tErr++;
            cmp += cm1;
        }
        err += er1;
        out += ou1;
        deb += de1;
        clear();
    }
    
    public void clear() {
        er1 = ou1 = de1 = 0;
        cm1 = -9;
        name = null;
//        debugLevel = 99;
        all2s.clear();
    }

    public void total(String ti) {
        if (er1 != 0 | ou1 != 0 | de1 != 0 | name != null) {
            err("total not after end");
        }
        hdFi(1, "total " + tErr + " failed of " + tCase + " tests after " + ti + " with " + err + " errors, " + out + " out and " + deb + " debugs");
    }

    public void total(IOTest... l) {
        dy("deimplemented");
        int sOk = tCase, sErr = tErr, sE = err, sS = out, sD = deb;

        if (er1 != 0 | ou1 != 0 | de1 != 0 | name != null) {
            err("total not after end");
        }

        for (IOTest i : l) {
            if (i.er1 != 0 | i.ou1 != 0 | i.de1 != 0 | i.name != null) {
                err("total not after end");
            }
            sOk += i.tCase;
            sErr += i.tErr;
            sE += i.err;
            sS += i.out;
            sD += i.deb;
        }
        String m = "total " + (sOk + sErr) + " tests, " + sErr + " bad with " + sE + " errors, " + sS + " out and " + sD + " debugs";
        if (err == 0) {
            out("--- " + m + " --------");
        } else {
            err("*** " + m + " *********");
        }
    }

    public void test(Class c, Object... p) {
        for (int ix = 0;; ix++) {
            int cnt = 0, iy;
            Object inst = null;
            hd(1, "test " + c);
            for (; ix < p.length && p[ix] instanceof String; ix++) {
                for (String m : spacePlus.split((String) p[ix])) {
                    if (m.length() > 0) {
                        cnt++;
                        inst = test(c, inst, m);
                    }
                }
            }
            if (cnt == 0) {
                inst = test(c, inst, "test");
            }
            if (ix >= p.length) {
                break;
            }
            if (cnt > 1) {
                total("test " + c);
            }
            c = (Class) p[ix];
        }
        total("test");
    }

    public Object test(Class c, Object inst, String nm) {
        Method m = null;
        try {
            m = c.getDeclaredMethod(nm, IOTest.class);
            if (Modifier.isStatic(m.getModifiers())) {
                m.invoke(null, this);
            } else {
                if (inst == null) {
                    out("creating instance");
                    inst = c.getDeclaredConstructor().newInstance();
                }
                m.invoke(inst, this);
            }
        } catch (NoSuchMethodException eM) {
            try {
                m = c.getDeclaredMethod(nm);
                if (Modifier.isStatic(m.getModifiers())) {
                    begin("static method " + nm + " in " + c);
                    m.invoke(null);
                } else {
                    begin("method " + nm + " in " + c);
                    if (inst == null) {
                        out("creating instance");
                        inst = c.getDeclaredConstructor().newInstance();
                    }
                    m.invoke(inst);
                }
            } catch (Exception ex) {
                err("test method " + nm + "() in " + c + " caught: ", ex);
            }
        } catch (Exception ex) {
            err("test method " + nm + "(IOTest) in " + c + " caught: ", ex);
        }
        if (name != null) {
            end();
        } else if (er1 != 0) {
            name = "method " + (m == null ? nm : m.toString());
            end();
        }
        return inst;
    }
}