rust/src/compiletest/compiletest.rs
2012-07-14 17:37:20 -07:00

192 lines
5.7 KiB
Rust

import option;
import std::getopts;
import std::test;
import str;
import vec;
import task;
import core::result;
import result::{ok, err};
import comm::port;
import comm::chan;
import comm::send;
import comm::recv;
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 match =
alt getopts::getopts(args_, opts) {
ok(m) { m }
err(f) { fail getopts::fail_str(f) }
};
ret {compile_lib_path: getopts::opt_str(match, ~"compile-lib-path"),
run_lib_path: getopts::opt_str(match, ~"run-lib-path"),
rustc_path: getopts::opt_str(match, ~"rustc-path"),
src_base: getopts::opt_str(match, ~"src-base"),
build_base: getopts::opt_str(match, ~"build-base"),
aux_base: getopts::opt_str(match, ~"aux-base"),
stage_id: getopts::opt_str(match, ~"stage-id"),
mode: str_mode(getopts::opt_str(match, ~"mode")),
run_ignored: getopts::opt_present(match, ~"ignored"),
filter:
if vec::len(match.free) > 0u {
option::some(match.free[0])
} else { option::none },
logfile: getopts::opt_maybe_str(match, ~"logfile"),
runtool: getopts::opt_maybe_str(match, ~"runtool"),
rustcflags: getopts::opt_maybe_str(match, ~"rustcflags"),
verbose: getopts::opt_present(match, ~"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))
}
}
ret 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; }
}
ret 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: