Mercurial > projects > dang
view tests/run.d @ 166:9cfa33517526
Codegen support for new expressions (very lame so far)
Calls the correct constructor, but it doesn't get a this pointer
Objects are simply malloced, no GC
author | Anders Halager <halager@gmail.com> |
---|---|
date | Tue, 22 Jul 2008 21:34:53 +0200 |
parents | 0ea5d2f3e96b |
children | e1e170c2cd44 |
line wrap: on
line source
// skip module run.d; import tango.core.Array, tango.io.FileConduit, tango.io.FileScan, tango.io.Stdout, tango.sys.Process, tango.text.Ascii, tango.text.Regex, tango.text.Util; // -- Settings -- char[] compiler = "./Dang"; char[] test_folder = "tests"; char[] valid_filenames = r"^[^.].*"; bool print_expected = false; // the tests can be sorted by one of the following functions bool nameSort (FilePath a, FilePath b) { return a.name < b.name; } bool pathSort (FilePath a, FilePath b) { return a.toString < b.toString; } bool modifiedSort(FilePath a, FilePath b) { return a.modified < b.modified; } bool createdSort (FilePath a, FilePath b) { return a.created < b.created; } const sortBy = &pathSort; // -- end of settings enum TestResult { Skipped, Expected, Unexpected } void main(char[][] args) { scope scan = new FileScan; // scope regex = new Regex(valid_filenames); // DMD FAILS!! ?? // Return true for files/folders to include bool filter(FilePath p, bool isDir) { if (isDir) return p.name[0] != '.'; else return p.ext == "d" ; //&& regex.test(p.name); } scan.sweep(test_folder, &filter, true); FilePath[] files = scan.files; int total_tests = files.length; // Sort the result by the chosen function - default is the full path sort(files, sortBy); int[TestResult.max + 1] results = 0; foreach (i, ref test; files) { begin_test(i + 1, total_tests, test.name); TestResult res = run_test(test); results[res] += 1; end_test(); } Stdout.format("\r{,80}\r", " "); Stdout.newline; int good = TestResult.Expected; int bad = TestResult.Unexpected; int tests_run = results[good] + results[bad]; Stdout.formatln("{}/{} tests failed", results[bad], tests_run); } void begin_test(int number, int total_tests, char[] name) { char[60] progressbar = ' '; int progress = number*progressbar.length/total_tests; progressbar[0 .. progress] = '='; if(progress) progressbar[progress-1] = '>'; Stdout.format("\r{}% - [{}]", 1e2 * number / total_tests, progressbar); Stdout.flush(); //Thread.sleep(0.05); } void end_test() { } enum { NoFail, CompiletimeFail, RuntimeFail } private int min(int a, int b) { return a < b? a : b; } TestResult run_test(ref FilePath p) { auto file = new FileConduit(p.toString(), FileConduit.ReadExisting); char[256] content; int len = file.read(content); file.close(); char[] line = content[0 .. min(len, content.find('\n'))]; bool compile = true; int fail = NoFail; if (line.length >= 2 && line[0 .. 2] == "//") { foreach (command; line[2 .. $].delimiters(",;")) switch (toLower(substitute(command, " ", ""))) { case "skip", "dontcompile": compile = false; break; case "fail", "compilefail", "compiletimefail", "failatcompiletime": fail = CompiletimeFail; break; case "runtime", "runtimefail", "failatruntime": fail = RuntimeFail; Stderr("== Compiled tests will not be run! ==").newline; return TestResult.Skipped; default: break; } } if (compile) { auto process = new Process(compiler, "--gen-llvm", p.toString()); process.execute(); auto result = process.wait(); return resultOf(p, result.status, fail); } return TestResult.Skipped; } private TestResult resultOf(FilePath p, int result, int expected) { char[] good(char[] s) { version (Posix) return "\033[1;32m" ~ s ~ "\033[m"; else return s; } char[] bad(char[] s) { s = s ~ " - Unexpected"; version (Posix) return "\033[1;31m" ~ s ~ "\033[m"; else return s; } bool unexpected = (result != expected); auto f = unexpected? &bad : &good; char[] s = (result == 0)? "SUCCESS" : "FAILURE"; // always print if unexpeted, otherwise check the settings if (unexpected || print_expected) { Stdout.format("\r{,80}\r", " "); Stdout.format(" {,-45}", p); Stdout(f(s)).newline; } return unexpected? TestResult.Unexpected : TestResult.Expected; }