diff options
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/lib.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax_ext/test.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax_ext/test_case.rs | 75 |
3 files changed, 85 insertions, 2 deletions
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index a9990cdeabf..e16f3b1ccb3 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -54,6 +54,7 @@ mod global_asm; mod log_syntax; mod trace_macros; mod test; +mod test_case; pub mod proc_macro_registrar; @@ -145,6 +146,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, assert: assert::expand_assert, } + register(Symbol::intern("test_case"), MultiModifier(Box::new(test_case::expand))); // format_args uses `unstable` things internally. register(Symbol::intern("format_args"), diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index d9d0f3d0a32..be3485cfa7c 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -135,8 +135,14 @@ pub fn expand_test_or_bench( }; let mut test_const = cx.item(sp, item.ident.gensym(), - // #[test_case] - vec![cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("test_case")))], + vec![ + // #[cfg(test)] + cx.attribute(attr_sp, cx.meta_list(attr_sp, Symbol::intern("cfg"), vec![ + cx.meta_list_item_word(attr_sp, Symbol::intern("test")) + ])), + // #[rustc_test_marker] + cx.attribute(attr_sp, cx.meta_word(attr_sp, Symbol::intern("rustc_test_marker"))) + ], // const $ident: test::TestDescAndFn = ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), // test::TestDescAndFn { diff --git a/src/libsyntax_ext/test_case.rs b/src/libsyntax_ext/test_case.rs new file mode 100644 index 00000000000..0128db7dd78 --- /dev/null +++ b/src/libsyntax_ext/test_case.rs @@ -0,0 +1,75 @@ + +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// #[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. + +use syntax::ext::base::*; +use syntax::ext::build::AstBuilder; +use syntax::ext::hygiene::{self, Mark, SyntaxContext}; +use syntax::ast; +use syntax::source_map::respan; +use syntax::symbol::Symbol; +use syntax_pos::{DUMMY_SP, Span}; +use syntax::source_map::{ExpnInfo, MacroAttribute}; +use syntax::feature_gate; + +pub fn expand( + ecx: &mut ExtCtxt, + attr_sp: Span, + _meta_item: &ast::MetaItem, + anno_item: Annotatable +) -> Vec<Annotatable> { + if !ecx.ecfg.enable_custom_test_frameworks() { + feature_gate::emit_feature_err(&ecx.parse_sess, + "custom_test_frameworks", + attr_sp, + feature_gate::GateIssue::Language, + feature_gate::EXPLAIN_CUSTOM_TEST_FRAMEWORKS); + + return vec![anno_item]; + } + + if !ecx.ecfg.should_test { return vec![]; } + + let sp = { + let mark = Mark::fresh(Mark::root()); + mark.set_expn_info(ExpnInfo { + call_site: DUMMY_SP, + def_site: None, + format: MacroAttribute(Symbol::intern("test_case")), + allow_internal_unstable: true, + allow_internal_unsafe: false, + local_inner_macros: false, + edition: hygiene::default_edition(), + }); + attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)) + }; + + 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, Symbol::intern("rustc_test_marker"))) + ); + item + }); + + return vec![Annotatable::Item(item)] +} |
