package ch.wlkl.shell;

import static ch.wlkl.shell.EnvMan.env;
import static ch.wlkl.shell.EnvMan.envMan;
import static ch.wlkl.shell.Strings.fill;
import static ch.wlkl.shell.Strings.quote;
import static ch.wlkl.shell.Strings.unquote;
import static ch.wlkl.shell.Strings.xQuote;
import static ch.wlkl.shell.Strings.xUnquote;

import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.util.Date;


/**
 * @author Keller
 * test Infrasturcture and all tests for package shBuf 
 *
 */

public class Test extends Top implements Read<String>, Write<String> {
	int errors = 0;
	final java.util.ArrayList<String> in = new java.util.ArrayList<String>();
	final java.util.ArrayList<String> out = new java.util.ArrayList<String>();
	final java.util.ArrayList<String> comp = new java.util.ArrayList<String>();
	int readIx = -1;
	int envManStackSize = 0;
	public final static String tempDir = "\\tmpelieli";
		
	public Test() {
		say("constructor " + this);
	}
	
	public void write(String data) {
		out.add(data);
		System.out.println(data);
	}
	
	public void input(String... strings) {
		in.clear();
		readIx = -1;
		Ut.addAll(in, strings);
	}
	
	public String read() {
		readIx++;
		if (readIx < in.size()) {
			out("read " + readIx + ": " + in.get(readIx));
			return in.get(readIx);
		} else {
			out("read " + readIx + "<<endOfInput>>");
			return null;
		}
	}
	
	public void reset(Object... args) {
		fail("reset");
	}
	
	public void open(String opt) {
	}

	public void close() {
	}

	public void begin(String txt) {
		readIx = -1;
		in.clear();
		out.clear();
		comp.clear();
		out("--- test begin " + txt);
		envMan().push(Env.make((Env<String, String>) null, "<£", this, ">£", this));
		envManStackSize = envMan().envStack.size();
	}
	
	public void compare(String... c) {
		for (int i=0; i < c.length; i++)
			comp.add(c[i]);		
	}
	
	public void end(String txt) {
		String r = "", c, o;
		StringBuffer t = new StringBuffer("");
		int min, d;
		out("--- test end " + txt + " readIx " + readIx);
		if (envManStackSize != envMan().envStack.size())
			err("envMan stack size is now " + envMan().envStack.size() + " but was " + envManStackSize + " at begin");
		else if (env().in() != this)
			err("env in changed");
		else if (env().out() != this)
			err("env out changed");
		else
			envMan().pop();
		for (String s: out)
			r = r + ", " + xQuote(s);
		say("output  = (" + (r.equals("") ? "" : r.substring(2)) + ')');
		r = "";
		for (String s: comp)
			r = r + ", " + xQuote(s);
		say("compare = (" + (r.equals("") ? "" : r.substring(2)) + ')');
		if (comp.size() != out.size())
			err("size mismatch out " + out.size() + " != " + comp.size() + " compare");
		min = out.size() < comp.size() ? out.size() : comp.size();
		for (int i=0; i < min; i++) {
			if (! (o =out.get(i)).equals((c = comp.get(i)))) {
				for (d=0;d < o.length() && d < c.length() && o.charAt(d) == c.charAt(d) ;d++);
				t.delete(0, t.length());
				t.append("*** difference at line " + i + ",char " + d);
				if (t.length() < d+9)
					t = t.append(fill(" ", d+9-t.length()));
				t.insert(d+9, '*');
				say(new String(t));	
				say ("compare: " + c);
				say ("out    : " + o);
				errors++;
			}
		}
	}
	
	public void out(String msg) {
		write("--- " + msg);
	}
	
	public void err(String msg) {
		write("*** error: " + msg);
		errors++;
	}
	public String writeTestFiles(String... names) {
		FileRW wf = new FileRW();
		for (int ix=0; ix < names.length; ix++) {
			wf.reset(tempDir + '\\' + names[ix]);
			wf.open("w");
			Ut.write(wf, "test file " + ix + " of " + names.length, "name = " + names[ix], "]end of test file " + ix + ": " + names[ix]);
			wf.close();
		}
		return tempDir;
	}

	public void removeTestFiles() {
		removeRecursive(new File(tempDir));
	}

	public void removeRecursive(File f) {
		if (f.isDirectory()) {
			File [] li = f.listFiles();
			for (int ix=0; ix < li.length; ix++)
				removeRecursive(li[ix]);
		}
		if (! f.delete())
			say("could not delete " + f);
	}

	/**
	 * test the test machine of class Test itself
	 */
	public void test() throws Exception {
		nameCnt(2);
		input("input eins", "input zwei");
		compare("--- --- test begin test", "--- 1. test out", "2. test write", "--- read 0: input eins", "test read r1 input eins", "--- read 1: input zwei", "test read r2 input zwei", "--- read 2<<endOfInput>>", "test read r3 null", "--- read 3<<endOfInput>>", "test read r4 null", "--- 3. out vor Exception", "--- catched java.lang.reflect.InvocationTargetException", "--- catched reason java.lang.Exception: test.throw", "--- --- test end test readIx 3");
		out("1. test out");
		write("2. test write");
		write("test read r1 " + read());
		write("test read r2 " + read());
		write("test read r3 " + read());
		write("test read r4 " + read());
		out("3. out vor Exception");
		throw new Exception("test.throw");
	}

	public void testEnv() {
		nameCnt(3);
		input("input einsA");
		compare("--- --- test begin testEnv", "--- 1. test out", "2. test write", "--- read 0: input einsA", "test read r1 input einsA", "--- read 1<<endOfInput>>", "test read r2 null", "--- 3. normaler Schluss", "--- --- test end testEnv readIx 1");
		out("1. test out");
		env().write("2. test write");
		env().write("test read r1 " + env().read());
		env().write("test read r2 " + env().read());
		out("3. normaler Schluss");
	}

	public void envVars() {
		compare("--- --- test begin envVars", "--- get(string) einString", "--- get(string.length) 9", "--- get(string.length.getClass) class java.lang.Integer", "--- get(string.length.getClass.getPackage) package java.lang, Java Platform API Specification, version 1.5", "--- get(self) ch.wlkl.shell.Test@1", "--- get(self.tempDir) \\tmpelieli", "--- --- test end envVars readIx -1");
		env().put("string", "einString");
		out("get(string) " + env().via("string"));
		out("get(string.length) " + env().via("string.length"));
		out("get(string.length.getClass) " + env().via("string.length.getClass"));
		out("get(string.length.getClass.getPackage) " + env().via("string.length.getClass.getPackage"));
		env().put("self", this);
		out("get(self) " + env().via("self"));
		out("get(self.tempDir) " + env().via("self.tempDir"));
	}


	/**
	 * test xQuote and xUnquote, quote and unquote from Util
	 */
	public void unQu() {
		compare("--- --- test begin unQu", "xQuote 0 => \"aha \\n	 so \\\\ \\\\\\\\ ''geht's'' oder\\\"\\\" nicht?\" => aha \n	 so \\ \\\\ ''geht's'' oder\"\" nicht? == true", "quote 0 => \"aha \n	 so \\ \\\\ ''geht's'' oder\"\"\"\" nicht?\" => aha \n	 so \\ \\\\ ''geht's'' oder\"\" nicht? == true", "xQuote 1 => \"\" =>  == false", "quote 1 => \"\" =>  == false", "xQuote 2 => \"\" =>  == true", "quote 2 => \"\" =>  == true", "xQuote 3 => \"\\\"\" => \" == true", "quote 3 => \"\"\"\" => \" == true", "xQuote 4 => \"\\n\\nblabla\" => \n\nblabla == true", "quote 4 => \"\n\nblabla\" => \n\nblabla == true", "--- --- test end unQu readIx -1");
		String [] qs = {"aha \n\t so \\ \\\\ ''geht's'' oder\"\" nicht?", null, "", "\"", "\n\nblabla", };
		for (int i=0; i<qs.length; i++) {
			write("xQuote " + i + " => " + xQuote(qs[i]) + " => " + xUnquote(xQuote(qs[i])) + " == " + (xUnquote(xQuote(qs[i])).equals(qs[i])));
			write("quote " + i + " => " + quote(qs[i]) + " => " + unquote(quote(qs[i])) + " == " + (unquote(quote(qs[i])).equals(qs[i])));
		}
	}

	public void bar() {
		nameCnt(5);
		compare("--- --- test begin bar", "--- read 0: input eins", "--- read 1: input zwei zwo 2", "--- read 2: input drei Schluss.", "--- read 3<<endOfInput>>", "write 3 nach barLast 1", "<3<2<1write 1 nach barBegin1>2>3>", "<3<2<1(input eins)1>2>3>", "<3<2<1(input zwei zwo 2)1>2>3>", "<3<2<1(input drei Schluss.)1>2>3>", "<3<2<1write 2 nach preSuf ()1>2>3>", "--- --- test end bar readIx 3");
		input("input eins", "input zwei zwo 2", "input drei Schluss.");
		envMan().barBegin();
		env().write("write 1 nach barBegin");
		Ut.preSuf("(", ")");
		env().write("write 2 nach preSuf ()");
		envMan().barLast();
		env().write("write 3 nach barLast 1");
		envMan().barBegin();
		Ut.preSuf("<1", "1>");
		envMan().bar();
		Ut.preSuf("<2", "2>");
		envMan().barLast();
		Ut.preSuf("<3", "3>");
		envMan().barEnd();
		envMan().barEnd();	
	}

	public void barLazy() {
		nameCnt(5);
		compare("--- --- test begin barLazy", "write 3 nach barLast 1", "<3<2<1write 1 nach barBegin1>2>3>", "--- read 0: input eins", "<3<2<1(input eins)1>2>3>", "--- read 1: input zwei zwo 2", "<3<2<1(input zwei zwo 2)1>2>3>", "--- read 2: input drei Schluss.", "<3<2<1(input drei Schluss.)1>2>3>", "--- read 3<<endOfInput>>", "<3<2<1write 2 nach lazyReader preSuf ()1>2>3>", "--- --- test end barLazy readIx 3");
		input("input eins", "input zwei zwo 2", "input drei Schluss.");
		envMan().barBegin();
		env().write("write 1 nach barBegin");
		env().lazyReader(new PreSuf(env().in(), "(", ")"));
		env().write("write 2 nach lazyReader preSuf ()");
		envMan().barLast();
		env().write("write 3 nach barLast 1");
		envMan().barBegin();
		env().lazyReader(new PreSuf(env().in(), "<1", "1>"));
		envMan().bar();
		env().lazyReader(new PreSuf(env().in(), "<2", "2>"));
		envMan().barLast();
		env().lazyReader(new PreSuf(env().in(), "<3", "3>"));
		envMan().barEnd();
		envMan().barEnd();	
	}

	public void wc () {
		nameCnt(2);
		compare("--- --- test begin wc", "--- read 0: eins zwei drei", "--- read 1: zehn elf zwölf", "--- read 2: zwanzig 21 end", "--- read 3<<endOfInput>>", "eins zwei drei", "zehn elf zwölf", "zwanzig 21 end", "counted 3 lines, 9 words, 42 chars", "counted 4 lines, 16 words, 76 chars", "counted 5 lines, 23 words, 111 chars", "--- --- test end wc readIx 3");
		input("eins zwei drei", "zehn elf zwölf", "zwanzig 21 end");
		envMan().barBegin();
		Strings.wc(true);
		envMan().bar();
		Strings.wc(true);
		envMan().barLast();
		Strings.wc(true);
		envMan().barEnd();
	}
	
	public void words() {
		compare("--- --- test begin words", "--- read 0: eins zwei drei", "eins", "zwei", "drei", "--- read 1: zehn elf zwölf", "zehn", "elf", "zwölf", "--- read 2: zwanzig 21 end", "zwanzig", "21", "end", "--- read 3<<endOfInput>>", "--- --- test end words readIx 3");
		input("eins zwei drei", "zehn elf zwölf", "zwanzig 21 end");
		Strings.words();
	}

	public void writeCat() {
		final String tst = new java.util.Date().toString();
		final String fn = tempDir + "\\eins\\Writer.tst1";
		java.io.File f = new java.io.File(fn);
		FileRW wri = new FileRW(f.getAbsolutePath());
		compare("--- --- test begin writeCat", "--- opening WriteFile \\tmpelieli\\eins\\Writer.tst1", "--- closing WriteFile", "--- reading", "eins " + tst, "zwei", "drei " + tst, "--- writing to Cat c2", "--- reading Cat c2", "eins " + tst, "zwei", "drei " + tst, "line after absolute path", "eins " + tst, "zwei", "drei " + tst, "line after writeRead cat", "--- --- test end writeCat readIx -1");
		out("opening WriteFile " + fn);
		wri.open("w");
		Ut.write(wri, "eins " + tst, "zwei", "drei " + tst);
		out("closing WriteFile");
		wri.close();
		out("reading");
		Read<String> cat = new Cat<String>(f.getAbsolutePath());
		cat.open("r");
		Ut.write(EnvMan.env().out(), cat);
		cat.close();
		out("writing to Cat c2");
		Cat<String> c2 = new Cat<String>(f.getAbsolutePath());
		c2.addIo("-r£", new Buf<String>("line after absolute path"));
		c2.addIo("-£", cat);
		c2.addIo("-£", new Buf<String>("line after writeRead cat"));
		c2.open("r");
		out("reading Cat c2");
		Ut.write(this, c2);
		f.delete();
		(f = f.getParentFile()).delete();
		(f = f.getParentFile()).delete();
	}
	
	public void dir() {
		removeTestFiles();
		final String dn = writeTestFiles("eins\\elf.tst1", "eins\\zwoelf.tst1", "zwei/zwanz/f201", "zwei/zwanz/f202");
		compare("--- --- test begin dir", "--- creating dir \\tmpelieli", "--- write dir \\tmpelieli", "\\tmpelieli\\eins\\elf.tst1", "\\tmpelieli\\eins\\zwoelf.tst1", "\\tmpelieli\\zwei\\zwanz\\f201", "\\tmpelieli\\zwei\\zwanz\\f202", "--- read dir before close null", "--- open dir -d, -l1 \\tmpelieli", "--- write dir", "\\tmpelieli", "\\tmpelieli\\eins", "\\tmpelieli\\eins\\elf.tst1", "\\tmpelieli\\eins\\zwoelf.tst1", "\\tmpelieli\\zwei", "\\tmpelieli\\zwei\\zwanz", "\\tmpelieli\\zwei\\zwanz\\f201", "\\tmpelieli\\zwei\\zwanz\\f202", "\\tmpelieli", "\\tmpelieli\\eins", "\\tmpelieli\\zwei", "--- --- test end dir readIx -1");
		out("creating dir " + dn);
		out("write dir " + dn);
		Dir dir = new Dir(dn);
		dir.open("r");
		Ut.write(EnvMan.env().out(), dir);
		out("read dir before close " + dir.read());
		dir.close();
		// out("read dir after close " + dir.read());
		out("open dir -d, -l1 "+ dn);
		dir.reset("-d", dn, "-l1", dn, null);
		dir.open("r");
		out("write dir");
		Ut.write(EnvMan.env().out(), dir);
		removeTestFiles();
	}

	public void parser() {
		compare("--- --- test begin parser", "--- parsing: 2 lines: Wort,1234 'a''b'          ? wie Geht$s ", "word:   Wort", "lit:    ,", "number: 1234", "space:  1", "string: 'a''b'", "space:  10", "notDol: ? wie Geht", "lit:    $", "word:   s", "space:  1", "eol  :   nextLine() true", "string: \"quote (\"\")\"", "space:  3", "eol  :   nextLine() false", "--- parsing: 4 lines: vor $*( komment 1 $*) kommentar und $*( noch", "word:   vor", "spaCom: null", "word:   kommentar", "spaCom: null", "word:   und", "spaCom: null", "word:   schluss", "eol  :   nextLine() false", "--- parsing: 4 lines: ", "eol  :   nextLine() true", "space:  1", "eol  :   nextLine() true", "word:   eins", "space:  1", "fatal fail ch.wlkl.shell.Parser@2: lit:    fail ==> fail\ntok fail charIx 9:  zwei\nin line 2: eins fail zwei", "--- catched java.lang.reflect.InvocationTargetException", "--- catched reason java.lang.AssertionError: lit:    fail ==> fail\ntok fail charIx 9:  zwei\nin line 2: eins fail zwei", "--- --- test end parser readIx -1");
		parser(false, "Wort,1234 'a''b'          ? wie Geht$s ", "\"quote (\"\")\"   ");
		parser(true, "vor $*( komment 1 $*) kommentar und $*( noch","","1234 $*('a'$*) b", "sdf $*) schluss");
		parser(false, ""," ","eins fail zwei", "");
	}
	
	public void parser(boolean sc, String... srces) {
		Parser p = new Parser(new Buf<String>(srces));
		out("parsing: " + srces.length + " lines: " + srces[0]);
		while (! p.atEnd()) {
			if      (p.lit("fail"))  		p.fail("lit:    fail ==> fail");
			else if (p.next(Parser.shName))   write("word:   " + p.tok);
			else if (p.next(Parser.number)) write("number: " + p.tok);
			else if (p.next(Parser.string)) write("string: " + p.tok);
			else if (sc && p.spaceComment())write("spaCom: " + p.tok);
			else if (p.next(Parser.space))  write("space:  " + p.tok.length());
			else if (p.lit("$")||p.lit(","))write("lit:    " + p.tok);
			else if (p.next(Parser.notDo)) write("notDol: " + p.tok);
			else if (p.atEol())             write("eol  :   nextLine() " + p.switchLine());
			else                            p.fail ("cannot scan");
		}
	}
	
	public void cmpLoad() throws Exception {
		JavaCmpLoad<Object> loader = new JavaCmpLoad<Object>(null, null, false, null, Object.class);
		System.out.println(loader);
		int c0 = 1 + Integer.parseInt(loader.uniqueName(""));
		say("c0 " + c0);
		String pckg = loader.pckg.toString();
		compare("--- --- test begin cmpLoad", "java.compiler: null", "class loaded class java.lang.String", "create object from classclass " + pckg + ".Eins" + c0, "found method public void " + pckg + ".Eins" + c0 + ".say()", "found method public static void " + pckg + ".Eins" + c0 + ".sayStatic()", "create object from classclass " + pckg + ".Eins" + ++c0, "found method public void " + pckg + ".Eins" + c0 + ".say()", "found method public static void " + pckg + ".Eins" + c0 + ".sayStatic()", "create object from classclass " + pckg + ".Eins" + --c0, "found method public void " + pckg + ".Eins" + c0 + ".say()", "found method public static void " + pckg + ".Eins" + c0 + ".sayStatic()", "--- --- test end cmpLoad readIx -1");
		write("java.compiler: " + System.getProperty("java.compiler"));
		say("classLoader: " + this.getClass().getClassLoader());
		String name = null;
		Class cl = loader.loadClass("java.lang.String");
		write("class loaded " + cl);
		Class<? extends Object> c1 = loader.makeClass(name = loader.uniqueName("Eins"),
				loader.classSource(new Object[0], name, new Object[0]
				, "	public static void sayStatic() {"
				, "		System.out.println(\"sayStatic temp Class " + name + ' ' + new Date() + "\");"
				, "	}"
				, "	public void say() {"
				, "		System.out.println(\"say temp " + name + "class \" + getClass());"
				, "}"));
		testClass(c1);
		Class<? extends Object> c2 = loader.makeClass(name = loader.uniqueName("Eins"),
				loader.classSource(new Object[0], name, new Object[0]
				, "	public static void sayStatic() {"
				, "		System.out.println(\"sayStatic temp Class " + name + ' ' + new Date() + "\");"
				, "	}"
				, "	public void say() {"
				, "		System.out.println(\"say temp " + name + "class \" + getClass());"
				, "}"));
		testClass(c2);
		testClass(c1);
	}

	public void testClass(Class<? extends Object> cl) throws Exception {
		Object o = cl.newInstance();
		write("create object from class" + cl);
		Method m = cl.getMethod("say");
		write("found method " + m);
		m.invoke(o);
		m = cl.getMethod("sayStatic");
		write("found method " + m);
		m.invoke(null);
	}
	public Run compile(char type, String... srces) {
		out("compile " + (type == 's' ? "coSh: " : "data: ") + srces.length + " lines: " + srces[0]);
		Run r = new Compiler(EnvMan.envMan().loader(), new Buf<String>(srces)).compileInstance(type);
		say("compiled: >>>>>>>>>>>\n" + r + "\n<<<<<<<<<<<<");
		return r;
	}
	
	public void shell(String... srces) {
		Run r = compile('s', srces);
		run(r);
	}

	public void data(String... srces) {
		Run r = compile('d', srces);
		run(r);
	}

	public void run(Run r) {
		out("run without input");
		input();
		in.clear();
		r.run();
		out("run with 3 inputs");
		input("eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !");
		r.run();
	}
	
	public void sSyntax() {
		System.out.println(new Compiler(EnvMan.envMan().loader(), new Buf<String>()).loader);		
		compare("--- --- test begin sSyntax", "--- compile coSh: 1 lines: EnvMan.env().write(\"write eins\") $}; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read())", "fatal fail ch.wlkl.shell.Parser@3: pipe or $; expected: compile shell stopped before end of input\ntok null charIx 33: $}; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read())\nin line 0: EnvMan.env().write(\"write eins\") $}; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read())", "--- catched java.lang.reflect.InvocationTargetException", "--- catched reason java.lang.AssertionError: pipe or $; expected: compile shell stopped before end of input\ntok null charIx 33: $}; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read())\nin line 0: EnvMan.env().write(\"write eins\") $}; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read())", "--- --- test end sSyntax readIx -1");
		shell("EnvMan.env().write(\"write eins\") $}; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read())");
	}

	public void sJavaSyntax() {
		PrintStream out = System.out;
		Buf<String> bb = new Buf<String>();
		compare("--- --- test begin sJavaSyntax", "--- before redirecting System.out", "--- after redirecting System.out", "--- compile coSh: 1 lines: $(abc$)", "--- catched Throwable java.lang.AssertionError: compile rc 1 errors for class temporary.shell.TempRun1", "--- before resetting System.out", "--- after resetting System.out, intercepted out 12", "--- after redirecting System.out", "--- compile coSh: 1 lines: $(abc$)", "D:\\java\\src\\temporary\\shell\\TempRun1.java:6: not a statement", "(abc)", "^", "D:\\java\\src\\temporary\\shell\\TempRun1.java:7: ';' expected", "}", "^", "2 errors", "fatal fail: compile rc 1 errors for class temporary.shell.TempRun1", "--- catched Throwable java.lang.AssertionError: compile rc 1 errors for class temporary.shell.TempRun1", "--- before resetting System.out", "--- after intercepted output", "--- --- test end sJavaSyntax readIx -1");
		bb.open("w");
		out("before redirecting System.out");
		envMan().push(new Env<String, String>(">£", bb));
		System.setOut(new PrintStream(new OutputStream2Write(bb)));
		out("after redirecting System.out");
		try {
			shell("$(abc$)");
		} catch (Throwable e) {
			out("catched Throwable " + e);
		}
		out("before resetting System.out");
		envMan().pop();
		System.setOut(out);
		out("after resetting System.out, intercepted out " + bb.contents.size());
		bb.open("r");
		Ut.write(this, bb);
		out("after intercepted output");
	}

	public void dConst() {
		compare("--- --- test begin dConst", "--- compile data: 3 lines: data line eins mit text", "--- run without input", "data line eins mit text", "    und zwei    ", "das genügt doch wohl! ", "--- run with 3 inputs", "data line eins mit text", "    und zwei    ", "das genügt doch wohl! ", "--- compile data: 7 lines: a", "--- run without input", "a", "b", "", "d", "", " ", "g.", "--- run with 3 inputs", "a", "b", "", "d", "", " ", "g.", "--- --- test end dConst readIx -1");
		data("data line eins mit text", "    und zwei    ", "das genügt doch wohl! ");
		data("a","b","", "d", "", " ", "g.");
	}

	public void dComment() {
		compare("--- --- test begin dComment", "--- compile data: 4 lines: data line $*( mit kommentar 1 $*)eins $*( und $*( geschateltem $*) kommentar $*)mit text", "--- run without input", "data line eins mit text", "    und zwei    ", "das genügt doch wohl! ", "--- run with 3 inputs", "data line eins mit text", "    und zwei    ", "das genügt doch wohl! ", "--- --- test end dComment readIx -1");
		data("data line $*( mit kommentar 1 $*)eins $*( und $*( geschateltem $*) kommentar $*)mit text", "    und zwei    $** eol komment $*) $*(  ", "das $*+ eol incl kommentar   ", "$*(  $\"$*)\"sdf $*)genügt doch wohl! ");
	}

	public void dString() {
		compare("--- --- test begin dString", "--- compile data: 3 lines: data $\"String darf auch $, $$, $*( enthalten\".", "--- run without input", "data String darf auch $, $$, $*( enthalten.", " apoString  $ $? $$$ ", " doppel quotes \"2 \"\"4 ' ''$ und apo  doppelt '2 ''4 oder \"1 \"\"2 $$$!!!", "--- run with 3 inputs", "data String darf auch $, $$, $*( enthalten.", " apoString  $ $? $$$ ", " doppel quotes \"2 \"\"4 ' ''$ und apo  doppelt '2 ''4 oder \"1 \"\"2 $$$!!!", "--- --- test end dString readIx -1");
		data("data $\"String darf auch $, $$, $*( enthalten\".", " apoString $' $ $? $$$' ", "$\" doppel quotes \"\"2 \"\"\"\"4 ' ''$\" und apo $' doppelt ''2 ''''4 oder \"1 \"\"2 $$$'!!!");
	}

	public void dJava() {
		compare("--- --- test begin dJava", "--- compile data: 2 lines: data $(\"ab\" + $*+", "--- run without input", "data abcd12  efg   end", "--- run with 3 inputs", "data abcd12  efg   end", "--- --- test end dJava readIx -1");
		data("data $(\"ab\" + $*+", " \"cd\" + (3*4) + $-[  efg   $] + $\"end\"$)");
	}

	public void dVars() {
		compare("--- --- test begin dVars", "--- compile data: 9 lines: data line 1  ", "--- run without input", "data line 1  ", " v1=value of variable v1: equal value of variable v1. ", "v1=value of variable v1, v2=zwei , v3=drei, {v2v3} = zwei vor drei.", "${?  v$(1+1$) }=true ${?v5}=false", "--- read 0<<endOfInput>>", "${>inp}=false inp=<<<inp not defined>>>", "--- run with 3 inputs", "data line 1  ", " v1=value of variable v1: equal value of variable v1. ", "v1=value of variable v1, v2=zwei , v3=drei, {v2v3} = zwei vor drei.", "${?  v$(1+1$) }=true ${?v5}=false", "--- read 0: eins zwei drei", "${>inp}=true inp=eins zwei drei", "--- --- test end dVars readIx 0");
		data("data line 1  ", "  $=  v1   =   value of variable v1   ", " v1=$v1: equal ${v1}. ", "    $=v2 = zwei  $=v3=drei ", " $=zweidrei $*+ sdf ", "= zwei vor drei  ", "v1=$v1, v2=$v2 , v3=$v3, {v2v3} = ${$v2$v3}.", "$'${?  v$(1+1$) }'=${?  v$(1+1$) } $'${?v5}'=${?v5}", "$'${>inp}'=${>inp} inp=$(${?inp} ? $inp : $'<<<inp not defined>>>'$)");
	}

	public void dInp() {
		String d = writeTestFiles("eins.dInp") + "\\eins.dInp";
		compare("--- --- test begin dInp", "--- compile data: 4 lines: text eins $<<eof", "--- run without input", "text eins ", "data $line 1  ", "data line zwei$$ eof", "...auuserhalb data", "test file 0 of 1", "name = eins.dInp", "]end of test file 0: eins.dInp", "...nach $<...eins", "--- run with 3 inputs", "text eins ", "data $line 1  ", "data line zwei$$ eof", "...auuserhalb data", "test file 0 of 1", "name = eins.dInp", "]end of test file 0: eins.dInp", "...nach $<...eins", "--- compile data: 5 lines: $=v1=varEins", "--- run without input", "text zehn ", "data varEins ", "data line zwei v2=varZwei $$ eof", "...auuserhalb data elf v1=varEins v2=varZwei", "--- run with 3 inputs", "text zehn ", "data varEins ", "data line zwei v2=varZwei $$ eof", "...auuserhalb data elf v1=varEins v2=varZwei", "--- --- test end dInp readIx -1");
		data("text eins $<<eof", "data $line 1  ", "data line zwei$$ eof", "eof...auuserhalb data$<" + d + " $[...nach $'$<'...eins$]");
		data("$=v1=varEins", "text zehn $<<[eof", "data $v1 $=v2=varZwei     ", "data line zwei v2=$v2 $'$$' eof", "eof...auuserhalb data elf v1=$v1 v2=$v2");
		removeTestFiles();
	}
	public void dData() {
		compare("--- --- test begin dData", "--- compile data: 8 lines: $$ vor $'$-[ data Ex $]' $-[ 		", "--- run without input", "vor $-[ data Ex $] eins zwei vor leer  vier...nach data Ex", "vor $-[ data St $]  	eins zwei v=var<v>expanded end...nachher", "--- run with 3 inputs", "vor $-[ data Ex $] eins zwei vor leer  vier...nach data Ex", "vor $-[ data St $]  	eins zwei v=var<v>expanded end...nachher", "--- --- test end dData readIx -1");
//		data(" $$ vor $'$-[ data St $]' $-[ 	eins$=v=var<v>expanded$]");
		data("$$ vor $'$-[ data Ex $]' $-[ 		", "eins", "zwei vor leer", "", "vier$]...nach data Ex $$ vor $'$-[ data St $]' $-[ 	eins", "    $=v=var<v>expanded  ", "zwei v=$v end", " 	 	$]...nachher");
	}


	public void sJava() {
		compare("--- --- test begin sJava", "--- compile coSh: 5 lines: EnvMan.env().", "--- run without input", "write eins", "--- read 0<<endOfInput>>", "write zwei read null", "--- run with 3 inputs", "write eins", "--- read 0: eins zwei drei", "write zwei read eins zwei drei", "--- --- test end sJava readIx 0");
		shell("EnvMan.env().", "	   \n", "  \n", "  ", "    \n   write(\"write eins\"); $; EnvMan.env().write(\"write zwei read \" + EnvMan.env().read());");
	}

	public void sString() {
		compare("--- --- test begin sString", "--- compile coSh: 1 lines: EnvMan.env().write($'write eins in '' apos $ $$ $$$'+ \";\"); $; EnvMan.env().write($\"write zwei in \"\" quotes $ $$ read \" + EnvMan.env().read());", "--- run without input", "write eins in ' apos $ $$ $$$;", "--- read 0<<endOfInput>>", "write zwei in \" quotes $ $$ read null", "--- run with 3 inputs", "write eins in ' apos $ $$ $$$;", "--- read 0: eins zwei drei", "write zwei in \" quotes $ $$ read eins zwei drei", "--- --- test end sString readIx 0");
		shell("EnvMan.env().write($'write eins in '' apos $ $$ $$$'+ \";\"); $; EnvMan.env().write($\"write zwei in \"\" quotes $ $$ read \" + EnvMan.env().read());");
	}

	
	public void sVars() {
		compare("--- --- test begin sVars", "--- compile coSh: 2 lines: $=a1=aEins$=a2=value a2 zwo$$ $( \"write a1 = \" + $a1 $)$$ a2 = ${a2} ", "--- run without input", "write a1 = aEins", "a2 = value a2 zwo", "var v1 aEins mit geschachtelem Namen", "--- run with 3 inputs", "write a1 = aEins", "a2 = value a2 zwo", "var v1 aEins mit geschachtelem Namen", "--- --- test end sVars readIx -1");
		shell("$=a1=aEins$=a2=value a2 zwo$$ $( \"write a1 = \" + $a1 $)$$ a2 = ${a2} ",
				"$=va=a$;$$   var v1 ${  $va$(1*1$) } mit geschachtelem Namen");
	}

	public void sBlock() {
		compare("--- --- test begin sBlock", "--- compile coSh: 3 lines: $$ before block1 $@{", "--- run without input", "before block1", "in block 1", "in block 1.1 end", "in block 1 mid", "in block 1.2 end", "in block 1 end", "after block", "--- run with 3 inputs", "before block1", "in block 1", "in block 1.1 end", "in block 1 mid", "in block 1.2 end", "in block 1 end", "after block", "--- --- test end sBlock readIx -1");
		shell("$$ before block1 $@{", " $$ in block 1 $@{ $$ in block 1.1 end ", "$} $$ in block 1 mid $@{ $$ in block 1.2 end $} $$ in block 1 end $} $$ after block");
	}

//	public void sBlock2() {
//		compare("--- --- test begin sBlock", "--- compile coSh: 4 lines: $$ before data block $@[ data block 1.1", "--- run without input", "before data block", " data block 1.1", "data block 1.2", "--- read 0<<endOfInput>>", "nested shell block reads null !!", "data block 1.2 ", "after data block", "--- run with 3 inputs", "before data block", " data block 1.1", "data block 1.2", "--- read 0: eins zwei drei", "nested shell block reads eins zwei drei !!", "data block 1.2 ", "after data block", "--- --- test end sBlock readIx 0");
//		shell("$$ before data block $@[ data block 1.1", "data block 1.2", "  $@{$$ nested shell block reads $-(EnvMan.env().read() $) !! $}  ", "data block 1.2 $] $$ after data block");
//	}

//	public void dBlock() {
//		compare("--- --- test begin dBlock", "--- compile data: 5 lines: data before shBlock $@{ $$ before data block $@[ data block 1.1", "--- run without input", "data before shBlock ", "before data block", " data block 1.1", "data block 1.2", "--- read 0<<endOfInput>>", "nested shell block reads null !!", "data block 1.2 ", "after data block", "--- read 1<<endOfInput>>", " data after shBlock read null end", "--- run with 3 inputs", "data before shBlock ", "before data block", " data block 1.1", "data block 1.2", "--- read 0: eins zwei drei", "nested shell block reads eins zwei drei !!", "data block 1.2 ", "after data block", "--- read 1: zehn elf zwölf?", " data after shBlock read zehn elf zwölf? end", "--- --- test end dBlock readIx 1");
//		data("data before shBlock $@{ $$ before data block $@[ data block 1.1", "data block 1.2", "  $@{$$ nested shell block reads $-(EnvMan.env().read() $) !! $}  ", "data block 1.2 $] $$ after data block", "$} data after shBlock read $-(EnvMan.env().read() $) end");
//	}


	public void sShString() {
		compare("--- --- test begin sShString", "--- compile coSh: 1 lines: $$sSHString anfang $-{$$write eins in $-{$$ shString $} after2 $} after1", "--- run without input", "sSHString anfang write eins in shString after2 after1", "--- run with 3 inputs", "sSHString anfang write eins in shString after2 after1", "--- --- test end sShString readIx -1");
		shell("$$sSHString anfang $-{$$write eins in $-{$$ shString $} after2 $} after1");
	}

	public void sBar() {
		compare("--- --- test begin sBar", "--- compile coSh: 1 lines: Strings.wc(true); $| Strings.wc(true);", "--- run without input", "--- read 0<<endOfInput>>", "counted 0 lines, 0 words, 0 chars", "counted 1 lines, 7 words, 33 chars", "--- run with 3 inputs", "--- read 0: eins zwei drei", "--- read 1: zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "counted 4 lines, 23 words, 104 chars", "--- compile coSh: 1 lines: Strings.wc(true); EnvMan.env().write(\"bef 1. bar\"); $| EnvMan.env().write(\"after 1. bar\");Strings.wc(true); EnvMan.env().write(\"bef 2. bar\"); $| Strings.wc(true);", "--- run without input", "--- read 0<<endOfInput>>", "after 1. bar", "counted 0 lines, 0 words, 0 chars", "bef 1. bar", "counted 2 lines, 10 words, 43 chars", "bef 2. bar", "counted 5 lines, 23 words, 100 chars", "--- run with 3 inputs", "--- read 0: eins zwei drei", "--- read 1: zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "after 1. bar", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "bef 1. bar", "counted 5 lines, 26 words, 114 chars", "bef 2. bar", "counted 8 lines, 39 words, 172 chars", "--- compile coSh: 1 lines: Strings.wc(true); $| Strings.wc(true); $|Strings.wc(true); $|Strings.wc(true); $| Strings.wc(true);    ", "--- run without input", "--- read 0<<endOfInput>>", "counted 0 lines, 0 words, 0 chars", "counted 1 lines, 7 words, 33 chars", "counted 2 lines, 14 words, 67 chars", "counted 3 lines, 21 words, 102 chars", "counted 4 lines, 28 words, 138 chars", "--- run with 3 inputs", "--- read 0: eins zwei drei", "--- read 1: zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "counted 4 lines, 23 words, 104 chars", "counted 5 lines, 30 words, 140 chars", "counted 6 lines, 37 words, 176 chars", "counted 7 lines, 44 words, 212 chars", "--- --- test end sBar readIx 3");
		shell("Strings.wc(true); $| Strings.wc(true);");
		shell("Strings.wc(true); EnvMan.env().write(\"bef 1. bar\"); $| EnvMan.env().write(\"after 1. bar\");Strings.wc(true); EnvMan.env().write(\"bef 2. bar\"); $| Strings.wc(true);");
		shell("Strings.wc(true); $| Strings.wc(true); $|Strings.wc(true); $|Strings.wc(true); $| Strings.wc(true);    ");
	}

	public void sRedirB() {
		final String tst = new java.util.Date().toString();
		compare("--- --- test begin sRedirB", "--- compile coSh: 4 lines: $>#eins ", "--- run without input", "--- read 0<<endOfInput>>", "counted 0 lines, 0 words, 0 chars", "ende " + tst + " #eins", "write " + tst + " eine zeile auf zwei", "counted 0 lines, 0 words, 0 chars", "ende " + tst + " #eins", "counted 2 lines, 15 words, 73 chars", "--- run with 3 inputs", "--- read 0: eins zwei drei", "--- read 1: zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "ende " + tst + " #eins", "write " + tst + " eine zeile auf zwei", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "ende " + tst + " #eins", "counted 5 lines, 31 words, 144 chars", "--- --- test end sRedirB readIx 3");
		shell("$>#eins ", "Strings.wc(true);", "EnvMan.env().write(\"ende " + tst + " #eins\");  $; $>#zwei $<#eins    ","EnvMan.env().write(\"write " + tst + " eine zeile auf zwei\"); Strings.wc(true); $; $<+#eins  $<#zwei ");
	}

	public void sRedirF() {
		final String tst = new java.util.Date().toString();
		final String fn = tempDir + "\\eins\\sRedirF.";
		compare("--- --- test begin sRedirF", "--- compile coSh: 4 lines: $>" + fn + "eins  ", "--- run without input", "--- read 0<<endOfInput>>", "out ... eins", "counted 0 lines, 0 words, 0 chars", "ende " + tst + " eins ", "out ...eins ...zwei", "counted 0 lines, 0 words, 0 chars", "ende " + tst + " eins ", "write " + tst + " eine zeile auf zwei", "counted 0 lines, 0 words, 0 chars", "ende " + tst + " eins ", "counted 2 lines, 15 words, 73 chars", "--- run with 3 inputs", "--- read 0: eins zwei drei", "--- read 1: zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "out ... eins", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "ende " + tst + " eins ", "out ...eins ...zwei", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "ende " + tst + " eins ", "write " + tst + " eine zeile auf zwei", "eins zwei drei", "zehn elf zwölf?", "zwanzig 21 22 23 24 ... 29 und Schluss !", "counted 3 lines, 16 words, 69 chars", "ende " + tst + " eins ", "counted 5 lines, 31 words, 144 chars", "--- --- test end sRedirF readIx 3");
		shell("$>" + fn + "eins  ", "Strings.wc(true);", "EnvMan.env().write(\"ende " + tst + " eins \");  $; $$ out ... eins $; $<" + fn + "eins $; $>" + fn + "zwei $<" + fn + "eins ", "EnvMan.env().write(\"write " + tst + " eine zeile auf zwei\"); Strings.wc(true); $; $$ out ...eins ...zwei $; $<+" + fn + "eins  $<" + fn + "zwei ");
	}

	public void sHereData() {
		compare("--- --- test begin sHereData", "--- compile coSh: 4 lines: $<<eins  ", "--- run without input", "data line eins", "data line zwei $$$$$ schluss", "--- run with 3 inputs", "data line eins", "data line zwei $$$$$ schluss", "--- --- test end sHereData readIx -1");
		shell("$<<eins  ", "data line eins", "data line zwei $$$$$ schluss", "eins");
	}

	public void sRedirCat() {
		final String tst = new java.util.Date().toString();
		compare("--- --- test begin sRedirCat", "--- compile coSh: 4 lines: $>#eins $$ buf eins " + tst + " the only line $; $<+#eins $<<+eof ", "--- run without input", "buf eins " + tst + " the only line", "hereData line eins", "herda line two last", "--- read 0<<endOfInput>>", "buf eins " + tst + " the only line", "--- run with 3 inputs", "buf eins " + tst + " the only line", "hereData line eins", "herda line two last", "--- read 0: eins zwei drei", "eins zwei drei", "--- read 1: zehn elf zwölf?", "zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "buf eins " + tst + " the only line", "--- --- test end sRedirCat readIx 3");
		shell("$>#eins $$ buf eins " + tst + " the only line $; $<+#eins $<<+eof ","hereData line eins", "herda line two last", "eof $<+£$(EnvMan.env().in()$) $<#eins");
	}

	public void sRedirRW()  {
		final String tst = (String) (new Date()).toString();
		compare("--- --- test begin sRedirRW", "--- compile coSh: 3 lines: Buf<String> b = new Buf<String>(\"Zeile eins " + tst + "\"); $; $>>£$(b$) $$ zeile zwei " + tst + "$; $<+£$(b$) $<+-£$(EnvMan.env().in()$)$<<eof  ", "--- run without input", "Zeile eins " + tst + "", "zeile zwei " + tst + "", "--- read 0<<endOfInput>>", "zeile drei heredata nach stdIn", "--- run with 3 inputs", "Zeile eins " + tst + "", "zeile zwei " + tst + "", "--- read 0: eins zwei drei", "eins zwei drei", "--- read 1: zehn elf zwölf?", "zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "zeile drei heredata nach stdIn", "--- --- test end sRedirRW readIx 3");
		shell("Buf<String> b = new Buf<String>(\"Zeile eins " + tst + "\"); $; $>>£$(b$) $$ zeile zwei " + tst + "$; $<+£$(b$) $<+-£$(EnvMan.env().in()$)$<<eof  ", "zeile drei heredata nach stdIn", "eof  ");
	}

	public void sCatAss() {
		compare("--- --- test begin sCatAss", "--- compile coSh: 4 lines: $=vss=valStrStr $$ vss $vss", "--- run without input", "vss valStrStr", "vsV valStrValue", "vNs valNameString", "vNV valNameValue", "--- run with 3 inputs", "vss valStrStr", "vsV valStrValue", "vNs valNameString", "vNV valNameValue", "--- --- test end sCatAss readIx -1");
//		shell("$=vss=valStrStr $$ vss $vss", "$=vsV=$-{$$ valStrValue$} "); 
		shell("$=vss=valStrStr $$ vss $vss", "$=vsV=$-{$$ valStrValue$} $$ vsV $vsV", "$= $-{$$ vNs $} =valNameString $$ vNs $vNs", "$= $-{$$ vNV $} =$-{$$valNameValue$} $$ vNV $vNV");
	}

	public void sCatWr() {
		compare("--- --- test begin sCatWr", "--- compile coSh: 2 lines: $$ write1 mit $-{$$ nested write. $} und noch mehr text", "--- run without input", "write1 mit nested write. und noch mehr text", "write2 mit nested write1 und inner nested write2. end1 und noch mehr text", "--- run with 3 inputs", "write1 mit nested write. und noch mehr text", "write2 mit nested write1 und inner nested write2. end1 und noch mehr text", "--- --- test end sCatWr readIx -1");
		shell("$$ write1 mit $-{$$ nested write. $} und noch mehr text", "$$ write2 mit $-{$$ nested write1 und $-{$$ inner nested write2. $} end1 $} und noch mehr text");
	}

	public void sRunD() {
		final String tst = new java.util.Date().toString();
		compare("--- --- test begin sRunD", "--- compile coSh: 9 lines: $>#dat $<<eof ", "--- run without input", "input dat #dat", "data line 1  $@{$=tst= " + tst + "$} ", " data line 2 mit tst $tst", "compile #dat to cmp", "run cmp", "data line 1  ", " data line 2 mit tst " + tst, "--- run with 3 inputs", "input dat #dat", "data line 1  $@{$=tst= " + tst + "$} ", " data line 2 mit tst $tst", "compile #dat to cmp", "run cmp", "data line 1  ", " data line 2 mit tst " + tst, "--- --- test end sRunD readIx -1");
		shell("$>#dat $<<eof ", "data line 1  $@{$=tst= " + tst + "$} ", " data line 2 mit tst $tst", "eof $;", "$$ input dat #dat $; $<#dat $;", "$$ compile #dat to cmp $;", "$<#dat $=cmp  = $-cmpData ", "$$run cmp", "$@run $cmp");
	}

	public void sRunS() {
		final String tst = new java.util.Date().toString();
		compare("--- --- test begin sRunS", "--- compile coSh: 9 lines: $>#dat $<<eof ", "--- run without input", "input dat #dat", "$$ data line 1 $=tst= " + tst + " ", "$$ data line 2 mit tst $tst", "compile #dat to cmp", "run cmp", "data line 1", "data line 2 mit tst " + tst, "--- run with 3 inputs", "input dat #dat", "$$ data line 1 $=tst= " + tst + " ", "$$ data line 2 mit tst $tst", "compile #dat to cmp", "run cmp", "data line 1", "data line 2 mit tst " + tst, "--- --- test end sRunS readIx -1");
		shell("$>#dat $<<eof ", "$$ data line 1 $=tst= " + tst + " ", "$$ data line 2 mit tst $tst", "eof $;", "$$ input dat #dat $; $<#dat $;", "$$ compile #dat to cmp $;", "$<#dat $=cmp  : Run  £   $-cmpData  ", "$$run cmp", "$@run $cmp");
	}


	public void sReadInto() {
		compare("--- --- test begin sReadInto", "--- compile coSh: 1 lines: int i; for (i=1; ${> gelesen } ; i++ ) $@{ $$ gelesen $(i$) $gelesen $} $$ total $(i-1$) gelesen", "--- run without input", "--- read 0<<endOfInput>>", "total 0 gelesen", "--- run with 3 inputs", "--- read 0: eins zwei drei", "gelesen 1 eins zwei drei", "--- read 1: zehn elf zwölf?", "gelesen 2 zehn elf zwölf?", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "gelesen 3 zwanzig 21 22 23 24 ... 29 und Schluss !", "--- read 3<<endOfInput>>", "total 3 gelesen", "--- --- test end sReadInto readIx 3");
		shell("int i; for (i=1; ${> gelesen } ; i++ ) $@{ $$ gelesen $(i$) $gelesen $} $$ total $(i-1$) gelesen");
	}

	public void sTypeVar() {
		compare("--- --- test begin sTypeVar", "--- compile coSh: 1 lines: $=vi£ new Integer(123) $$ vi ${vi : Integer} class $(${vi : Integer}.getClass()$)", "--- run without input", "vi 123 class class java.lang.Integer", "--- run with 3 inputs", "vi 123 class class java.lang.Integer", "--- --- test end sTypeVar readIx -1");
		shell("$=vi£ new Integer(123) $$ vi ${vi : Integer} class $(${vi : Integer}.getClass()$)");
	}

	public void typeRW() {
		compare("--- --- test begin typeRW", "read 123 : class java.lang.Integer", "read 5 : class java.lang.Integer", "--- --- test end typeRW readIx -1");
		EnvMan.envMan().barBegin().write(123);
		EnvMan.env(null, (Integer) null).write(5);
		EnvMan.envMan().barLast();
		Object i;
		while (null != (i = EnvMan.env().read()))
				EnvMan.env().write("read " + i + " : " + i.getClass());
		EnvMan.envMan().barEnd();		
	}

	public void sTypeRW() {
		compare("--- --- test begin sTypeRW", "--- compile coSh: 1 lines: $£ 5*7 $@{  Integer [] ia = {12, 13}; $£ ia $|: Integer[] boolean b = ${>ia}; $£ ${ia}.length  $£ ${ia: Integer[]}[1]  $£ $ia [0] $} $|:Integer   while ( ${>abc} ) $@{ $£ $'abc=' + ${abc : Object} + $': ' + ${abc: Object}.getClass() $} $$ eof read", "--- run without input", "abc=35: class java.lang.Integer", "abc=2: class java.lang.Integer", "abc=13: class java.lang.Integer", "abc=12: class java.lang.Integer", "eof read", "--- run with 3 inputs", "abc=35: class java.lang.Integer", "abc=2: class java.lang.Integer", "abc=13: class java.lang.Integer", "abc=12: class java.lang.Integer", "eof read", "--- --- test end sTypeRW readIx -1");
		shell("$£ 5*7 $@{  Integer [] ia = {12, 13}; $£ ia $|: Integer[] boolean b = ${>ia}; $£ ${ia}.length  $£ ${ia: Integer[]}[1]  $£ $ia [0] $} $|:Integer   while ( ${>abc} ) $@{ $£ $'abc=' + ${abc : Object} + $': ' + ${abc: Object}.getClass() $} $$ eof read");
	}


	public void sInDo()  {
		nameCnt(50);
		final String fn = tempDir + "\\eins\\cInDo.tst1";
		compare("--- --- test begin sInDo", "--- compile coSh: 14 lines: $=v1=v1Leer$$writing \\tmpelieli\\eins\\cInDo.tst1$; $>\\tmpelieli\\eins\\cInDo.tst1 $<<eof", "--- run without input", "writing \\tmpelieli\\eins\\cInDo.tst1", "input fn ohne Dollar", "$@{$=v1=valueEins$ix $}eins $'$v1' $v1", "zwei $'$[1+1)' $(1+1$)", "input fn with compile ix 7", "eins $v1 valueEins7", "zwei $[1+1) 2", "input fn with compile ix 8", "eins $v1 valueEins8", "zwei $[1+1) 2", "after loop ix 8 v1 valueEins8 !ix 9", "--- run with 3 inputs", "writing \\tmpelieli\\eins\\cInDo.tst1", "input fn ohne Dollar", "$@{$=v1=valueEins$ix $}eins $'$v1' $v1", "zwei $'$[1+1)' $(1+1$)", "input fn with compile ix 7", "eins $v1 valueEins7", "zwei $[1+1) 2", "input fn with compile ix 8", "eins $v1 valueEins8", "zwei $[1+1) 2", "after loop ix 8 v1 valueEins8 !ix 9", "--- --- test end sInDo readIx -1");
		// compare("--- --- test begin cInDo", "--- compile sequence: 4 lines: $$writing \\tmpelieli\\eins\\cInDo.tst1$; $>\\tmpelieli\\eins\\cInDo.tst1 $<<eof", "--- opening", "writing \\tmpelieli\\eins\\cInDo.tst1", "input fn ohne Dollar", "   $:{ $=v1=valueEins$ix $:}eins $'$v1' $v1", "zwei $'$[1+1)' $[1+1$]", "input fn with Dollar ix 7", "eins $v1 valueEins7", "zwei $[1+1) 2", "input fn with Dollar ix 8", "eins $v1 valueEins8", "zwei $[1+1) 2", "after loop ix 8 v1 valueEins8 !ix 9", "--- closing", "--- opening again", "--- closing again", "--- compile sequence: 1 lines:  $$ $[ $'$[ text $]' $] $$ zehn $( $$ $'$(...$) text' $$ input file fn $; $< \\tmpelieli\\eins\\cInDo.tst1 $; $$ end input and $'$)' $) zwanzig $$ geschachtelt $( $$ aeussere Schachtel $( $$ mittlere Schachtel $( $$ innerste Schachtel $) end Mitte $) end aussen $)", "--- opening", "$[ text $]", "zehn  $(...$) textinput file fn   $:{ $=v1=valueEins$ix $:}eins $'$v1' $v1zwei $'$[1+1)' $[1+1$]end input and $) zwanzig", "geschachtelt  aeussere Schachtel  mittlere Schachtel  innerste Schachtel end Mitte end aussen", "--- closing", "--- opening again", "--- closing again", "--- --- test end cInDo");
		shell("$=v1=v1Leer$$writing " + fn + "$; $>" + fn + " $<<eof", 
				"$@{$=v1=valueEins$ix $}eins $'$v1' $v1", 
				"zwei $'$[1+1)' $(1+1$)", 
				"eof $;",
				"$$ input fn ohne Dollar $;", 
				"$<" + fn + "$;",
				"int ix; for (ix=7; ix<9; ix++) ",
				"{",
				"$=ix£String.valueOf(ix)",
				"$$input fn with compile ix $ix $;",
				"$<$\"" + fn + "\" $= runIt =  $-cmpData $;",
				"$@run $runIt",
				"}",
				"$$ after loop ix $ix v1 $v1 !ix $(ix$)");
//		shell(" $$ $-[ $'$-[ text $]' $] $$ zehn $-( $$ $'$(...$) text' $$ input file fn $; $< " + fn + " $; $$ end input and $'$)' $) zwanzig $$ geschachtelt $( $$ aeussere Schachtel $( $$ mittlere Schachtel $( $$ innerste Schachtel $) end Mitte $) end aussen $)");
		new File(fn).delete();
	}

	public void sData() {
		compare("--- --- test begin sData", "--- compile coSh: 3 lines: $$ line $'$$' eins $£ \"line \" + $'$£' + (1+1) $[line drei data", "--- run without input", "line $$ eins", "line $£2", "line drei data", "line vier data", "line fuenf [[ ", "line sechs [[{", "line sieben [[{[", "line acht [[{[]}] ", "line neun out end", "--- run with 3 inputs", "line $$ eins", "line $£2", "line drei data", "line vier data", "line fuenf [[ ", "line sechs [[{", "line sieben [[{[", "line acht [[{[]}] ", "line neun out end", "--- --- test end sData readIx -1");
		// compare("--- --- test begin cInDo", "--- compile sequence: 4 lines: $$writing \\tmpelieli\\eins\\cInDo.tst1$; $>\\tmpelieli\\eins\\cInDo.tst1 $<<eof", "--- opening", "writing \\tmpelieli\\eins\\cInDo.tst1", "input fn ohne Dollar", "   $:{ $=v1=valueEins$ix $:}eins $'$v1' $v1", "zwei $'$[1+1)' $[1+1$]", "input fn with Dollar ix 7", "eins $v1 valueEins7", "zwei $[1+1) 2", "input fn with Dollar ix 8", "eins $v1 valueEins8", "zwei $[1+1) 2", "after loop ix 8 v1 valueEins8 !ix 9", "--- closing", "--- opening again", "--- closing again", "--- compile sequence: 1 lines:  $$ $[ $'$[ text $]' $] $$ zehn $( $$ $'$(...$) text' $$ input file fn $; $< \\tmpelieli\\eins\\cInDo.tst1 $; $$ end input and $'$)' $) zwanzig $$ geschachtelt $( $$ aeussere Schachtel $( $$ mittlere Schachtel $( $$ innerste Schachtel $) end Mitte $) end aussen $)", "--- opening", "$[ text $]", "zehn  $(...$) textinput file fn   $:{ $=v1=valueEins$ix $:}eins $'$v1' $v1zwei $'$[1+1)' $[1+1$]end input and $) zwanzig", "geschachtelt  aeussere Schachtel  mittlere Schachtel  innerste Schachtel end Mitte end aussen", "--- closing", "--- opening again", "--- closing again", "--- --- test end cInDo");
		shell("$$ line $'$$' eins $£ \"line \" + $'$£' + (1+1) $[line drei data", "line vier data$[line fuenf [[ $@{$$ line sechs [[{ $[line sieben [[{[$]$}$] ", "line acht [[{[]}] $] $$line neun out end"); 		
	}

	public void dLoop() {
		compare("--- --- test begin dLoop", "--- compile data: 2 lines: vor Loop $@for  var $$ loop<${var}>   ", "--- run without input", "vor Loop ", "--- read 0<<endOfInput>>", "nach loop", "--- run with 3 inputs", "vor Loop ", "--- read 0: eins zwei drei", "loop<eins zwei drei>", "--- read 1: zehn elf zwölf?", "loop<zehn elf zwölf?>", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "loop<zwanzig 21 22 23 24 ... 29 und Schluss !>", "--- read 3<<endOfInput>>", "nach loop", "--- compile data: 2 lines: vor Loop $@for  xyz $[loop line", "--- run without input", "vor Loop ", "--- read 0<<endOfInput>>", "nach loop", "--- run with 3 inputs", "vor Loop ", "--- read 0: eins zwei drei", "loop line", "eins zwei drei in one line", "--- read 1: zehn elf zwölf?", "loop line", "zehn elf zwölf? in one line", "--- read 2: zwanzig 21 22 23 24 ... 29 und Schluss !", "loop line", "zwanzig 21 22 23 24 ... 29 und Schluss ! in one line", "--- read 3<<endOfInput>>", "nach loop", "--- --- test end dLoop readIx 3");
		data("vor Loop $@for  var $$ loop<${var}>   ", "nach loop"); 		
		data("vor Loop $@for  xyz $[loop line", "$xyz in one line$]nach loop"); 		
	}

	public void war() throws Exception {
		removeTestFiles();
		final String dn = writeTestFiles("eins\\elf.tst1", "eins\\zwoelf.tst1", "zwei/zwanz/f201", "zwei/zwanz/f202");
		War w = new War();
		FileRW c = new FileRW();
		Dir d = new Dir();
		compare("--- --- test begin war", "--- cf aaa", "added 5 of 5 files to "+dn+"/aaa.war", "--- xf aaa", "extracted 5 of 5 files from "+dn+"/aaa.war", "--- dir " + dn + "/extract/aaa", dn+"\\extract\\aaa\\aaa.war", dn+"\\extract\\aaa\\eins\\elf.tst1", dn+"\\extract\\aaa\\eins\\zwoelf.tst1", dn+"\\extract\\aaa\\zwei\\zwanz\\f201", dn+"\\extract\\aaa\\zwei\\zwanz\\f202", "--- cat \\tmpelieli/extract/aaa/zwei/zwanz/f201", "test file 2 of 4", "name = zwei/zwanz/f201", "]end of test file 2: zwei/zwanz/f201", "--- cf bbb", "added 11 of 11 files to "+dn+"/bbb.war", "--- xf bbb", "extracted 11 of 11 files from "+dn+"/bbb.war", "--- xf bbb/aaa ==> ccc", "extracted 5 of 5 files from "+dn+"/extract/bbb/aaa.war", "--- dir \\tmpelieli/extract/ccc", dn+"\\extract\\ccc\\aaa.war", dn+"\\extract\\ccc\\eins\\elf.tst1", dn+"\\extract\\ccc\\eins\\zwoelf.tst1", dn+"\\extract\\ccc\\zwei\\zwanz\\f201", dn+"\\extract\\ccc\\zwei\\zwanz\\f202", "--- cat \\tmpelieli/extract/ccc/eins/elft.tst1", "test file 0 of 4", "name = eins\\elf.tst1", "]end of test file 0: eins\\elf.tst1", "--- --- test end war readIx -1");
		out("cf aaa");
		w.run("cf", dn + "/aaa.war",  "-C" + dn, " .");
		out("xf aaa");
		w.run("xf", dn + "/aaa.war", "-C" + dn + "/extract/aaa", ".");
		out("dir " + dn +"/extract/aaa");
		d.reset(dn +"/extract/aaa");
		d.open("r");
		Ut.write(EnvMan.env().out(), d);
		d.close();
		out("cat " + dn +"/extract/aaa/zwei/zwanz/f201");
		c.reset(dn +"/extract/aaa/zwei/zwanz/f201");
		c.open("r");
		Ut.write(EnvMan.env().out(), c);
		c.close();
		out("cf bbb");
		w.run("cf", dn + "/bbb.war", "-C" + dn, ".");
		out("xf bbb");
		w.run(Parser.space.split("xf " + dn + "/bbb.war -C" + dn + "/extract/bbb ."));
		out("xf bbb/aaa ==> ccc");
		w.run(Parser.space.split("xf " + dn + "/extract/bbb/aaa.war -C" + dn + "/extract/ccc ."));
		out("dir " + dn +"/extract/ccc");
		d.reset(dn +"/extract/ccc");
		d.open("r");
		Ut.write(EnvMan.env().out(), d);
		d.close();
		out("cat " + dn +"/extract/ccc/eins/elft.tst1");
		c.reset(dn +"/extract/ccc/eins/elf.tst1");
		c.open("r");
		Ut.write(EnvMan.env().out(), c);
		c.close();
		removeTestFiles();
	}
	
	int test (String nm) {
		int prev = errors;
		try {
			begin(nm);
			getClass().getMethod(nm).invoke(this);
		} catch (Throwable e) {
			out("catched " + e);
			out("catched reason " + e.getCause() );
			e.printStackTrace();
		}
		end(nm);
		return errors - prev;		
	}
		
	@SuppressWarnings("unused") 
	public static void main(String[] args) {
		Test t = new Test();
		String [] def1 = {"test", "testEnv", "envVars", "unQu", "bar", "barLazy", "wc", "words", "writeCat", "dir", "parser", "cmpLoad",
				"sSyntax", "sJavaSyntax", "dConst", "dComment", "dString", "dJava", "dVars", "dInp", "dData",
				"sJava", "sString", "sJava", "sString", "sVars",  "sBlock", "sShString",
				"sBar", "sRedirB", "sRedirF", "sHereData" , "sRedirCat", "sRedirRW",
				"sCatAss", "sCatWr", "sRunD", "sRunS", "sReadInto", "sTypeVar", "typeRW", "sTypeRW", "sInDo", "sData", "dLoop", "war"};
//		still toDo war, sInDo mit Schachtelung
		String [] def2 = {"sRedirB"}; // {"sTypeRW"};
		String [] def = def1;
		if ( args == null || args.length == 0)
			args = def;
		if (false) {
			String [] a2 = new String [args.length * 2];
			for (int i=0; i<args.length;i++) {
				a2[2*i] = args[i];
				a2[2*i + 1] = args[i];
			}
			args = a2;
		}
		int [] ers = new int [args.length];
		String aa = ":";
		int fE = -1;
		for (int i=0; i<args.length;i++) {
			ers[i] = t.test(args[i]);
			aa += ' ' + args[i] + "=" + ers[i];
			if (fE < 0 && ers[i] != 0)
				fE = i;
//			if (t.errors > 0)
//				break;
		}
		String to = "test main end " + t.errors + " errors" + (t.errors <= 0 ? "" : ", first " + fE + " " + args[fE]);
		
		if (fE >= 0 && fE < args.length - 2) {
			sSay("replay first error " + fE + ' ' + args[fE]);
			t.test(args[fE]);
			sSay(to);
		}
		sSay(aa);
		sSay(to);
	}
	
}

