import option; import std::getopts; import std::test; import str; import vec; import task; import core::result; import result::{ok, err}; import common::config; import common::mode_run_pass; import common::mode_run_fail; import common::mode_compile_fail; import common::mode_pretty; import common::mode; import util::logv; fn main(args: ~[~str]) { let config = parse_config(args); log_config(config); run_tests(config); } fn parse_config(args: ~[~str]) -> config { let opts = ~[getopts::reqopt(~"compile-lib-path"), getopts::reqopt(~"run-lib-path"), getopts::reqopt(~"rustc-path"), getopts::reqopt(~"src-base"), getopts::reqopt(~"build-base"), getopts::reqopt(~"aux-base"), getopts::reqopt(~"stage-id"), getopts::reqopt(~"mode"), getopts::optflag(~"ignored"), getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"), getopts::optflag(~"verbose"), getopts::optopt(~"logfile")]; assert (vec::is_not_empty(args)); let args_ = vec::tail(args); let matches = alt getopts::getopts(args_, opts) { ok(m) => m, err(f) => fail getopts::fail_str(f) }; return {compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"), run_lib_path: getopts::opt_str(matches, ~"run-lib-path"), rustc_path: getopts::opt_str(matches, ~"rustc-path"), src_base: getopts::opt_str(matches, ~"src-base"), build_base: getopts::opt_str(matches, ~"build-base"), aux_base: getopts::opt_str(matches, ~"aux-base"), stage_id: getopts::opt_str(matches, ~"stage-id"), mode: str_mode(getopts::opt_str(matches, ~"mode")), run_ignored: getopts::opt_present(matches, ~"ignored"), filter: if vec::len(matches.free) > 0u { option::some(matches.free[0]) } else { option::none }, logfile: getopts::opt_maybe_str(matches, ~"logfile"), runtool: getopts::opt_maybe_str(matches, ~"runtool"), rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), verbose: getopts::opt_present(matches, ~"verbose")}; } fn log_config(config: config) { let c = config; logv(c, fmt!{"configuration:"}); logv(c, fmt!{"compile_lib_path: %s", config.compile_lib_path}); logv(c, fmt!{"run_lib_path: %s", config.run_lib_path}); logv(c, fmt!{"rustc_path: %s", config.rustc_path}); logv(c, fmt!{"src_base: %s", config.src_base}); logv(c, fmt!{"build_base: %s", config.build_base}); logv(c, fmt!{"stage_id: %s", config.stage_id}); logv(c, fmt!{"mode: %s", mode_str(config.mode)}); logv(c, fmt!{"run_ignored: %b", config.run_ignored}); logv(c, fmt!{"filter: %s", opt_str(config.filter)}); logv(c, fmt!{"runtool: %s", opt_str(config.runtool)}); logv(c, fmt!{"rustcflags: %s", opt_str(config.rustcflags)}); logv(c, fmt!{"verbose: %b", config.verbose}); logv(c, fmt!{"\n"}); } fn opt_str(maybestr: option<~str>) -> ~str { alt maybestr { option::some(s) => s, option::none => ~"(none)" } } fn str_opt(maybestr: ~str) -> option<~str> { if maybestr != ~"(none)" { option::some(maybestr) } else { option::none } } fn str_mode(s: ~str) -> mode { alt s { ~"compile-fail" => mode_compile_fail, ~"run-fail" => mode_run_fail, ~"run-pass" => mode_run_pass, ~"pretty" => mode_pretty, _ => fail ~"invalid mode" } } fn mode_str(mode: mode) -> ~str { alt mode { mode_compile_fail => ~"compile-fail", mode_run_fail => ~"run-fail", mode_run_pass => ~"run-pass", mode_pretty => ~"pretty" } } fn run_tests(config: config) { let opts = test_opts(config); let tests = make_tests(config); let res = test::run_tests_console(opts, tests); if !res { fail ~"Some tests failed"; } } fn test_opts(config: config) -> test::test_opts { {filter: alt config.filter { option::some(s) => option::some(s), option::none => option::none }, run_ignored: config.run_ignored, logfile: alt config.logfile { option::some(s) => option::some(s), option::none => option::none } } } fn make_tests(config: config) -> ~[test::test_desc] { debug!{"making tests from %s", config.src_base}; let mut tests = ~[]; for os::list_dir_path(config.src_base).each |file| { let file = file; debug!{"inspecting file %s", file}; if is_test(config, file) { vec::push(tests, make_test(config, file)) } } return tests; } fn is_test(config: config, testfile: ~str) -> bool { // Pretty-printer does not work with .rc files yet let valid_extensions = alt config.mode { mode_pretty => ~[~".rs"], _ => ~[~".rc", ~".rs"] }; let invalid_prefixes = ~[~".", ~"#", ~"~"]; let name = path::basename(testfile); let mut valid = false; for valid_extensions.each |ext| { if str::ends_with(name, ext) { valid = true; } } for invalid_prefixes.each |pre| { if str::starts_with(name, pre) { valid = false; } } return valid; } fn make_test(config: config, testfile: ~str) -> test::test_desc { { name: make_test_name(config, testfile), fn: make_test_closure(config, testfile), ignore: header::is_test_ignored(config, testfile), should_fail: false } } fn make_test_name(config: config, testfile: ~str) -> ~str { fmt!{"[%s] %s", mode_str(config.mode), testfile} } fn make_test_closure(config: config, testfile: ~str) -> test::test_fn { fn~() { runtest::run(config, copy testfile) } } // Local Variables: // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4 // buffer-file-coding-system: utf-8-unix // End: