| use std::getopts; |
| use std::test; |
| |
| use core::result; |
| use result::{Ok, Err}; |
| |
| use common::config; |
| use common::mode_run_pass; |
| use common::mode_run_fail; |
| use common::mode_compile_fail; |
| use common::mode_pretty; |
| use common::mode; |
| use util::logv; |
| |
| fn main() { |
| let args = os::args(); |
| 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"), |
| getopts::optflag(~"jit")]; |
| |
| assert (vec::is_not_empty(args)); |
| let args_ = vec::tail(args); |
| let matches = |
| match getopts::getopts(args_, opts) { |
| Ok(m) => m, |
| Err(f) => fail getopts::fail_str(f) |
| }; |
| |
| fn opt_path(m: getopts::Matches, nm: ~str) -> Path { |
| Path(getopts::opt_str(m, nm)) |
| } |
| |
| return {compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"), |
| run_lib_path: getopts::opt_str(matches, ~"run-lib-path"), |
| rustc_path: opt_path(matches, ~"rustc-path"), |
| src_base: opt_path(matches, ~"src-base"), |
| build_base: opt_path(matches, ~"build-base"), |
| aux_base: opt_path(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: option::map(&getopts::opt_maybe_str(matches, |
| ~"logfile"), |
| |s| Path(*s)), |
| runtool: getopts::opt_maybe_str(matches, ~"runtool"), |
| rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), |
| jit: getopts::opt_present(matches, ~"jit"), |
| 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.to_str())); |
| logv(c, fmt!("src_base: %s", config.src_base.to_str())); |
| logv(c, fmt!("build_base: %s", config.build_base.to_str())); |
| 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!("jit: %b", config.jit)); |
| logv(c, fmt!("verbose: %b", config.verbose)); |
| logv(c, fmt!("\n")); |
| } |
| |
| fn opt_str(maybestr: Option<~str>) -> ~str { |
| match 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 { |
| match 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 { |
| match 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::TestOpts { |
| {filter: |
| match config.filter { |
| option::Some(s) => option::Some(s), |
| option::None => option::None |
| }, |
| run_ignored: config.run_ignored, |
| logfile: |
| match config.logfile { |
| option::Some(s) => option::Some(s.to_str()), |
| option::None => option::None |
| } |
| } |
| } |
| |
| fn make_tests(config: config) -> ~[test::TestDesc] { |
| debug!("making tests from %s", |
| config.src_base.to_str()); |
| let mut tests = ~[]; |
| for os::list_dir_path(&config.src_base).each |file| { |
| let file = copy *file; |
| debug!("inspecting file %s", file.to_str()); |
| if is_test(config, file) { |
| tests.push(make_test(config, file)) |
| } |
| } |
| return tests; |
| } |
| |
| fn is_test(config: config, testfile: &Path) -> bool { |
| // Pretty-printer does not work with .rc files yet |
| let valid_extensions = |
| match config.mode { |
| mode_pretty => ~[~".rs"], |
| _ => ~[~".rc", ~".rs"] |
| }; |
| let invalid_prefixes = ~[~".", ~"#", ~"~"]; |
| let name = testfile.filename().get(); |
| |
| 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: &Path) -> |
| test::TestDesc { |
| { |
| name: make_test_name(config, testfile), |
| testfn: make_test_closure(config, testfile), |
| ignore: header::is_test_ignored(config, testfile), |
| should_fail: false |
| } |
| } |
| |
| fn make_test_name(config: config, testfile: &Path) -> ~str { |
| fmt!("[%s] %s", mode_str(config.mode), testfile.to_str()) |
| } |
| |
| fn make_test_closure(config: config, testfile: &Path) -> test::TestFn { |
| let testfile = testfile.to_str(); |
| fn~() { runtest::run(config, testfile) } |
| } |
| |
| // Local Variables: |
| // fill-column: 78; |
| // indent-tabs-mode: nil |
| // c-basic-offset: 4 |
| // buffer-file-coding-system: utf-8-unix |
| // End: |