diff options
Diffstat (limited to 'src/libsyntax_ext/test.rs')
| -rw-r--r-- | src/libsyntax_ext/test.rs | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index d381c42f9ce..a2d93d01cec 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -7,11 +7,44 @@ use syntax::ext::base::*; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; use syntax::print::pprust; +use syntax::source_map::respan; use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; use std::iter; +// #[test_case] is used by custom test authors to mark tests +// When building for test, it needs to make the item public and gensym the name +// Otherwise, we'll omit the item. This behavior means that any item annotated +// with #[test_case] is never addressable. +// +// We mark item with an inert attribute "rustc_test_marker" which the test generation +// logic will pick up on. +pub fn expand_test_case( + ecx: &mut ExtCtxt<'_>, + attr_sp: Span, + meta_item: &ast::MetaItem, + anno_item: Annotatable +) -> Vec<Annotatable> { + check_builtin_macro_attribute(ecx, meta_item, sym::test_case); + + if !ecx.ecfg.should_test { return vec![]; } + + let sp = attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id)); + let mut item = anno_item.expect_item(); + item = item.map(|mut item| { + item.vis = respan(item.vis.span, ast::VisibilityKind::Public); + item.ident = item.ident.gensym(); + item.attrs.push( + ecx.attribute(sp, + ecx.meta_word(sp, sym::rustc_test_marker)) + ); + item + }); + + return vec![Annotatable::Item(item)] +} + pub fn expand_test( cx: &mut ExtCtxt<'_>, attr_sp: Span, |
