java/ch/wlkl/wsm/Tester.java

package ch.wlkl.wsm;

import java.util.ArrayList;

import static ch.wlkl.wsm.Parser.xQuote;
import static ch.wlkl.env.Env.*;

/**
 * @author Walter Keller Tester is the test driver
 * 
 */

public class TesterRemove {
    private static Tester singleton;
    static final String preTit = "--- ";
    static final String preErr = "*** err ";

    final ArrayList<String> cases = new ArrayList<String>();
    int errs = 0;
    int totErrs = 0;
    int totOuts = 0;
    final ArrayList<String> output = new ArrayList<String>();
    String[] compare = null;
    
    public Tester begin(String name, String... comp) {
        if (compare != null)
            err("Tester.begin(" + name + "; ...) but old case "
                    + cases.get(cases.size() - 1) + " not ended");
        cases.add(name);
        compare = comp;
        out(preTit + cases.size() + " Tester.begin " + name);
        return this;
    }
    
    public Tester out(String m) {
        int ox = output.size();
        if (ox == compare.length) {
            out(preErr + ++errs + ": more new lines then old(" + compare.length
                    + ")");
        } else if (ox < compare.length && !m.equals(compare[ox])) {
            String t = preErr + ++errs + " old line " + ox + " (next, len="
                    + compare[ox].length() + ") <> new (overnext len="
                    + m.length() + ")";
            int cx;
            for (cx = 0; cx < m.length() && cx < compare[ox].length()
                    && m.charAt(cx) == compare[ox].charAt(cx); cx++)
                ;
            t += " firstDiff at " + cx;
            while (t.length() < cx)
                t += "          ";
            if (cx > preErr.length())
                t = t.substring(0, cx - 2) + ">>!<<" + t.substring(cx - 2);
            out(t);
            out(compare[ox]);
        }
        output.add(m);
        out(m);
        return this;
    }

    public Tester out(String m, Throwable t) {
        return out(m + ", " + WSM.throwsMsg(preErr + m, t));
    }
    
    public Tester end() {
        if (output.size() < compare.length) {
            out(preErr + ++errs + " more old lines (" + compare.length
                    + ") than new output (" + output.size() + ")");
            for (int ix = output.size(); ix < compare.length
                    && ix < output.size() + 5; ix++)
                out("  " + ix + ": " + compare[ix]);
        }
        out(preTit + cases.size() + " Tester.end "
                + cases.get(cases.size() - 1) + " with " + errs
                + " errors, total " + cases.size() + " cases, "
                + (totErrs += errs) + " errors and "
                + (totOuts += output.size()) + " lines");
        if (errs > 0) {
            out("\tbegin(\"" + cases.get(cases.size() - 1) + "\"");
            for (String s : output)
                out("\t\t, " + xQuote(s));
            out("\t\t);");
        }
        errs = 0;
        compare = null;
        output.clear();
        return this;
    }

    /*
     *  the static interface using the singleton pattern
     */

    public static Tester singleton() {
        if (singleton == null)
            singleton = new Tester();
        return singleton;
    }

    public static Tester singleton(Tester single) {
        if (singleton != null)
            out(preTit + "overwriting old singleton " + singleton
                    + " by new one " + single);
        return singleton = single;
    }

    public static Tester sBegin(String name, String... comp) {
        return singleton().begin(name, comp);
    }

    public static Tester sOut(String m) {
        return singleton().out(m);
    }
    
    public static Tester sEnd() {
        return singleton.end();
    }
/*
 * some small test cases to test the tester .....
 */
    public Tester testTester() {
        for (int q = 0; q < 2; q++) {
            begin("test1", "test1 out 1", "test1 out 2", "test1 out 3",
                    "test1 fertig, richtig mit 0 errors, ...");
            out("test1 out 1");
            out("test1 out 2").out("test1 out 3");
            out("test1 fertig, richtig mit 0 errors, ...").end();
        }

        begin("test2", "Test2 out 1", "test2 out 2 ", "test2 out?3",
                "test2 fertig, richtig mit 3 errors, ...");
        out("test2 out 1");
        out("test2 out 2").out("test2 out 3");
        out("test2 fertig, richtig mit 3 errors, ...").end();

        Tester.sBegin("test3", "test3 out 1", "test3 out 2", "test3 out 3",
                "test3 fertig, richtig mit 1 errors, ...");
        out("test3 out 1");
        end();
        begin("test4", "test4 out 1");
        out("test4 out 1")
                .out("test4 out 2")
                .out("test4 fertig, richtig mit   1 errors, total 5 cases, 5 errors and 16 lines");
        return end();
    }

    public static void main(String... args) {
        singleton().testTester();
    }
}