Add the ability to ignore tests by compiler config
[test] [ignore(cfg(target_os = "win32"))]
This commit is contained in:
parent
2e0593d999
commit
f7ebe23ae1
@ -18,6 +18,7 @@ export require_unique_names;
|
||||
export get_attr_name;
|
||||
export get_meta_item_name;
|
||||
export get_meta_item_value_str;
|
||||
export get_meta_item_list;
|
||||
export mk_name_value_item_str;
|
||||
export mk_name_value_item;
|
||||
export mk_list_item;
|
||||
@ -85,6 +86,13 @@ fn get_meta_item_value_str(meta: @ast::meta_item) -> option::t<str> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_meta_item_list(meta: @ast::meta_item) -> option::t<[@ast::meta_item]> {
|
||||
alt meta.node {
|
||||
ast::meta_list(_, l) { option::some(l) }
|
||||
_ { option::none }
|
||||
}
|
||||
}
|
||||
|
||||
fn attr_meta(attr: ast::attribute) -> @ast::meta_item { @attr.node.value }
|
||||
|
||||
// Get the meta_items from inside a vector of attributes
|
||||
|
@ -3,6 +3,7 @@ import syntax::{ast, fold};
|
||||
import attr;
|
||||
|
||||
export strip_unconfigured_items;
|
||||
export metas_in_cfg;
|
||||
|
||||
// Support conditional compilation by transforming the AST, stripping out
|
||||
// any items that do not belong in the current configuration
|
||||
@ -88,31 +89,24 @@ fn native_item_in_cfg(cfg: ast::crate_cfg, item: @ast::native_item) -> bool {
|
||||
// Determine if an item should be translated in the current crate
|
||||
// configuration based on the item's attributes
|
||||
fn in_cfg(cfg: ast::crate_cfg, attrs: [ast::attribute]) -> bool {
|
||||
metas_in_cfg(cfg, attr::attr_metas(attrs))
|
||||
}
|
||||
|
||||
fn metas_in_cfg(cfg: ast::crate_cfg, metas: [@ast::meta_item]) -> bool {
|
||||
|
||||
// The "cfg" attributes on the item
|
||||
let item_cfg_attrs = attr::find_attrs_by_name(attrs, "cfg");
|
||||
let item_has_cfg_attrs = vec::len(item_cfg_attrs) > 0u;
|
||||
if !item_has_cfg_attrs { ret true; }
|
||||
let cfg_metas = attr::find_meta_items_by_name(metas, "cfg");
|
||||
|
||||
// Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes,
|
||||
// so we can match against them. This is the list of configurations for
|
||||
// which the item is valid
|
||||
let item_cfg_metas = {
|
||||
fn extract_metas(&&inner_items: [@ast::meta_item],
|
||||
&&cfg_item: @ast::meta_item) -> [@ast::meta_item] {
|
||||
alt cfg_item.node {
|
||||
ast::meta_list(name, items) {
|
||||
assert (name == "cfg");
|
||||
inner_items + items
|
||||
}
|
||||
_ { inner_items }
|
||||
}
|
||||
}
|
||||
let cfg_metas = attr::attr_metas(item_cfg_attrs);
|
||||
vec::foldl(extract_metas, [], cfg_metas)
|
||||
};
|
||||
let cfg_metas = vec::concat(vec::filter_map(
|
||||
{|&&i| attr::get_meta_item_list(i)}, cfg_metas));
|
||||
|
||||
for cfg_mi: @ast::meta_item in item_cfg_metas {
|
||||
let has_cfg_metas = vec::len(cfg_metas) > 0u;
|
||||
if !has_cfg_metas { ret true; }
|
||||
|
||||
for cfg_mi: @ast::meta_item in cfg_metas {
|
||||
if attr::contains(cfg, cfg_mi) { ret true; }
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ type test = {span: span, path: [ast::ident], ignore: bool};
|
||||
|
||||
type test_ctxt =
|
||||
@{sess: session::session,
|
||||
crate: @ast::crate,
|
||||
next_node_id: node_id_gen,
|
||||
mutable path: [ast::ident],
|
||||
mutable testfns: [test]};
|
||||
@ -41,6 +42,7 @@ fn modify_for_testing(sess: session::session,
|
||||
|
||||
let cx: test_ctxt =
|
||||
@{sess: sess,
|
||||
crate: crate,
|
||||
next_node_id: next_node_id_fn,
|
||||
mutable path: [],
|
||||
mutable testfns: []};
|
||||
@ -102,7 +104,8 @@ fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) ->
|
||||
}
|
||||
_ {
|
||||
log "this is a test function";
|
||||
let test = {span: i.span, path: cx.path, ignore: is_ignored(i)};
|
||||
let test = {span: i.span,
|
||||
path: cx.path, ignore: is_ignored(cx, i)};
|
||||
cx.testfns += [test];
|
||||
log #fmt["have %u test functions", vec::len(cx.testfns)];
|
||||
}
|
||||
@ -133,8 +136,16 @@ fn is_test_fn(i: @ast::item) -> bool {
|
||||
ret has_test_attr && has_test_signature(i);
|
||||
}
|
||||
|
||||
fn is_ignored(i: @ast::item) -> bool {
|
||||
attr::contains_name(attr::attr_metas(i.attrs), "ignore")
|
||||
fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool {
|
||||
let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore");
|
||||
let ignoreitems = attr::attr_metas(ignoreattrs);
|
||||
let cfg_metas = vec::concat(vec::filter_map(
|
||||
{|&&i| attr::get_meta_item_list(i)}, ignoreitems));
|
||||
ret if vec::is_not_empty(ignoreitems) {
|
||||
config::metas_in_cfg(cx.crate.node.config, cfg_metas)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn add_test_module(cx: test_ctxt, m: ast::_mod) -> ast::_mod {
|
||||
|
31
src/test/run-pass/test-ignore-cfg.rs
Normal file
31
src/test/run-pass/test-ignore-cfg.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// compile-flags: --test --cfg ignorecfg
|
||||
// xfail-fast
|
||||
// xfail-pretty
|
||||
|
||||
use std;
|
||||
import std::option;
|
||||
import std::vec;
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(ignorecfg))]
|
||||
fn shouldignore() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(noignorecfg))]
|
||||
fn shouldnotignore() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checktests() {
|
||||
// Pull the tests out of the secret test module
|
||||
let tests = __test::tests();
|
||||
|
||||
let shouldignore = option::get(
|
||||
vec::find({|t| t.name == "shouldignore"}, tests));
|
||||
assert shouldignore.ignore == true;
|
||||
|
||||
let shouldnotignore = option::get(
|
||||
vec::find({|t| t.name == "shouldnotignore"}, tests));
|
||||
assert shouldnotignore.ignore == false;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user