about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/getopts.rs1
-rw-r--r--src/lib/test.rs100
2 files changed, 79 insertions, 22 deletions
diff --git a/src/lib/getopts.rs b/src/lib/getopts.rs
index bdcfbea3b28..7ce3355b205 100644
--- a/src/lib/getopts.rs
+++ b/src/lib/getopts.rs
@@ -17,6 +17,7 @@ export optflag;
 export optflagopt;
 export optmulti;
 export getopts;
+export getopts_ivec;
 export result;
 export success;
 export failure;
diff --git a/src/lib/test.rs b/src/lib/test.rs
index 037206b39f3..cfca12480a1 100644
--- a/src/lib/test.rs
+++ b/src/lib/test.rs
@@ -8,10 +8,13 @@ export test_fn;
 export test_desc;
 export test_main;
 export test_result;
+export test_opts;
 export tr_ok;
 export tr_failed;
 export tr_ignored;
 export run_test;
+export filter_tests;
+export parse_opts;
 
 // The name of a test. By convention this follows the rules for rust
 // paths, i.e it should be a series of identifiers seperated by double
@@ -34,19 +37,52 @@ type test_desc = rec(test_name name,
 // The default console test runner. It accepts the command line
 // arguments and a vector of test_descs (generated at compile time).
 fn test_main(&vec[str] args, &test_desc[] tests) {
-    if (!run_tests(parse_opts(args), tests)) {
+    auto ivec_args = {
+        auto iargs = ~[];
+        for (str arg in args) {
+            iargs += ~[arg]
+        }
+        iargs
+    };
+    check ivec::is_not_empty(ivec_args);
+    auto opts = alt (parse_opts(ivec_args)) {
+        either::left(?o) { o }
+        either::right(?m) { fail m }
+    };
+    if (!run_tests(opts, tests)) {
         fail "Some tests failed";
     }
 }
 
-type test_opts = rec(option::t[str] filter);
+type test_opts = rec(option::t[str] filter,
+                     bool run_ignored);
+
+type opt_res = either::t[test_opts, str];
+
+// Parses command line arguments into test options
+fn parse_opts(&str[] args) : ivec::is_not_empty(args) -> opt_res {
+
+    // FIXME (#649): Shouldn't have to check here
+    check ivec::is_not_empty(args);
+    auto args_ = ivec::tail(args);
+    auto opts = ~[getopts::optflag("ignored")];
+    auto match = alt (getopts::getopts_ivec(args_, opts)) {
+        getopts::success(?m) { m }
+        getopts::failure(?f) { ret either::right(getopts::fail_str(f)) }
+    };
+
+    auto filter = if (vec::len(match.free) > 0u) {
+        option::some(match.free.(0))
+    } else {
+        option::none
+    };
+
+    auto run_ignored = getopts::opt_present(match, "ignored");
+
+    auto test_opts = rec(filter = filter,
+                         run_ignored = run_ignored);
 
-fn parse_opts(&vec[str] args) -> test_opts {
-    rec(filter = if (vec::len(args) > 1u) {
-            option::some(args.(1))
-        } else {
-            option::none
-        })
+    ret either::left(test_opts);
 }
 
 tag test_result {
@@ -135,23 +171,43 @@ fn run_tests(&test_opts opts, &test_desc[] tests) -> bool {
 }
 
 fn filter_tests(&test_opts opts, &test_desc[] tests) -> test_desc[] {
-    if (option::is_none(opts.filter)) {
-        ret tests;
-    }
+    auto filtered = tests;
 
-    auto filter_str = alt opts.filter { option::some(?f) { f }
-                                        option::none { "" } };
+    filtered = if (option::is_none(opts.filter)) {
+        filtered
+    } else {
+        auto filter_str = alt opts.filter { option::some(?f) { f }
+                                            option::none { "" } };
+
+        auto filter = bind fn(&test_desc test,
+                              str filter_str) -> option::t[test_desc] {
+            if (str::find(test.name, filter_str) >= 0) {
+                ret option::some(test);
+            } else {
+                ret option::none;
+            }
+        } (_, filter_str);
 
-    auto filter = bind fn(&test_desc test,
-                          str filter_str) -> option::t[test_desc] {
-        if (str::find(test.name, filter_str) >= 0) {
-            ret option::some(test);
-        } else {
-            ret option::none;
-        }
-    } (_, filter_str);
+        ivec::filter_map(filter, filtered)
+    };
+
+    filtered = if (!opts.run_ignored) {
+        filtered
+    } else {
+        auto filter = fn(&test_desc test) -> option::t[test_desc] {
+            if (test.ignore) {
+                ret option::some(rec(name = test.name,
+                                     fn = test.fn,
+                                     ignore = false));
+            } else {
+                ret option::none;
+            }
+        };
+
+        ivec::filter_map(filter, filtered)
+    };
 
-    ret ivec::filter_map(filter, tests);
+    ret filtered;
 }
 
 fn run_test(&test_desc test) -> test_result {