about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-14 16:05:33 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-14 17:13:12 -0700
commit20e94de3925af29bd73a0f0f0b0706da72271115 (patch)
treefa40d1bcea157b4ddc596db6ffd2e4777c6a03a6 /src
parent81acf69f9708a236ef78faa180575ae7b618fba9 (diff)
downloadrust-20e94de3925af29bd73a0f0f0b0706da72271115.tar.gz
rust-20e94de3925af29bd73a0f0f0b0706da72271115.zip
Add a flag to run ignored tests. Issue #428
Diffstat (limited to 'src')
-rw-r--r--src/lib/getopts.rs1
-rw-r--r--src/lib/test.rs100
-rw-r--r--src/test/stdtest/test.rs40
3 files changed, 119 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 {
diff --git a/src/test/stdtest/test.rs b/src/test/stdtest/test.rs
index 17f18a5151e..0079a94522b 100644
--- a/src/test/stdtest/test.rs
+++ b/src/test/stdtest/test.rs
@@ -1,4 +1,8 @@
 import std::test;
+import std::str;
+import std::option;
+import std::either;
+import std::ivec;
 
 #[test]
 fn do_not_run_ignored_tests() {
@@ -26,6 +30,42 @@ fn ignored_tests_result_in_ignored() {
     assert res == test::tr_ignored;
 }
 
+#[test]
+fn first_free_arg_should_be_a_filter() {
+    auto args = ~["progname", "filter"];
+    check ivec::is_not_empty(args);
+    auto opts = alt test::parse_opts(args) { either::left(?o) { o } };
+    assert str::eq("filter", option::get(opts.filter));
+}
+
+#[test]
+fn parse_ignored_flag() {
+    auto args = ~["progname", "filter", "--ignored"];
+    check ivec::is_not_empty(args);
+    auto opts = alt test::parse_opts(args) { either::left(?o) { o } };
+    assert opts.run_ignored;
+}
+
+#[test]
+fn filter_for_ignored_option() {
+    // When we run ignored tests the test filter should filter out all the
+    // unignored tests and flip the ignore flag on the rest to false
+
+    auto opts = rec(filter = option::none,
+                    run_ignored = true);
+    auto tests = ~[rec(name = "1",
+                       fn = fn() {},
+                       ignore = true),
+                   rec(name = "2",
+                       fn = fn() {},
+                       ignore = false)];
+    auto filtered = test::filter_tests(opts, tests);
+
+    assert ivec::len(filtered) == 1u;
+    assert filtered.(0).name == "1";
+    assert filtered.(0).ignore == false;
+}
+
 // Local Variables:
 // mode: rust;
 // fill-column: 78;