Simplify proc_macro_srv tests

This commit is contained in:
Jonas Schievink 2021-05-31 17:32:56 +02:00
parent 70e347332d
commit cfcadcb295
6 changed files with 119 additions and 244 deletions

2
Cargo.lock generated
View file

@ -1143,13 +1143,13 @@ name = "proc_macro_srv"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"cargo_metadata", "cargo_metadata",
"expect-test",
"libloading", "libloading",
"mbe", "mbe",
"memmap2", "memmap2",
"object", "object",
"proc_macro_api", "proc_macro_api",
"proc_macro_test", "proc_macro_test",
"serde_derive",
"test_utils", "test_utils",
"toolchain", "toolchain",
"tt", "tt",

View file

@ -20,10 +20,9 @@ proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" }
[dev-dependencies] [dev-dependencies]
test_utils = { path = "../test_utils" } test_utils = { path = "../test_utils" }
toolchain = { path = "../toolchain" }
cargo_metadata = "0.13" cargo_metadata = "0.13"
expect-test = "1.1.0"
# used as proc macro test targets # used as proc macro test targets
serde_derive = "1.0.106"
proc_macro_test = { path = "../proc_macro_test" } proc_macro_test = { path = "../proc_macro_test" }
toolchain = { path = "../toolchain" }

View file

@ -1,181 +0,0 @@
SUBTREE $
PUNCH # [alone] 4294967295
SUBTREE [] 4294967295
IDENT doc 4294967295
SUBTREE () 4294967295
IDENT hidden 4294967295
PUNCH # [alone] 4294967295
SUBTREE [] 4294967295
IDENT allow 4294967295
SUBTREE () 4294967295
IDENT non_upper_case_globals 4294967295
PUNCH , [alone] 4294967295
IDENT unused_attributes 4294967295
PUNCH , [alone] 4294967295
IDENT unused_qualifications 4294967295
IDENT const 4294967295
IDENT _ 4294967295
PUNCH : [alone] 4294967295
SUBTREE () 4294967295
PUNCH = [alone] 4294967295
SUBTREE {} 4294967295
PUNCH # [alone] 4294967295
SUBTREE [] 4294967295
IDENT allow 4294967295
SUBTREE () 4294967295
IDENT unused_extern_crates 4294967295
PUNCH , [alone] 4294967295
IDENT clippy 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT useless_attribute 4294967295
IDENT extern 4294967295
IDENT crate 4294967295
IDENT serde 4294967295
IDENT as 4294967295
IDENT _serde 4294967295
PUNCH ; [alone] 4294967295
PUNCH # [alone] 4294967295
SUBTREE [] 4294967295
IDENT allow 4294967295
SUBTREE () 4294967295
IDENT unused_macros 4294967295
IDENT macro_rules 4294967295
PUNCH ! [alone] 4294967295
IDENT try 4294967295
SUBTREE {} 4294967295
SUBTREE () 4294967295
PUNCH $ [alone] 4294967295
IDENT __expr 4294967295
PUNCH : [alone] 4294967295
IDENT expr 4294967295
PUNCH = [joint] 4294967295
PUNCH > [alone] 4294967295
SUBTREE {} 4294967295
IDENT match 4294967295
PUNCH $ [alone] 4294967295
IDENT __expr 4294967295
SUBTREE {} 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT __private 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Ok 4294967295
SUBTREE () 4294967295
IDENT __val 4294967295
PUNCH = [joint] 4294967295
PUNCH > [alone] 4294967295
IDENT __val 4294967295
PUNCH , [alone] 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT __private 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Err 4294967295
SUBTREE () 4294967295
IDENT __err 4294967295
PUNCH = [joint] 4294967295
PUNCH > [alone] 4294967295
SUBTREE {} 4294967295
IDENT return 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT __private 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Err 4294967295
SUBTREE () 4294967295
IDENT __err 4294967295
PUNCH ; [alone] 4294967295
PUNCH # [alone] 4294967295
SUBTREE [] 4294967295
IDENT automatically_derived 4294967295
IDENT impl 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Serialize 4294967295
IDENT for 4294967295
IDENT Foo 4294967295
SUBTREE {} 4294967295
IDENT fn 4294967295
IDENT serialize 4294967295
PUNCH < [alone] 4294967295
IDENT __S 4294967295
PUNCH > [alone] 4294967295
SUBTREE () 4294967295
PUNCH & [alone] 4294967295
IDENT self 4294967295
PUNCH , [alone] 4294967295
IDENT __serializer 4294967295
PUNCH : [alone] 4294967295
IDENT __S 4294967295
PUNCH - [joint] 4294967295
PUNCH > [alone] 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT __private 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Result 4294967295
PUNCH < [alone] 4294967295
IDENT __S 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Ok 4294967295
PUNCH , [alone] 4294967295
IDENT __S 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Error 4294967295
PUNCH > [alone] 4294967295
IDENT where 4294967295
IDENT __S 4294967295
PUNCH : [alone] 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Serializer 4294967295
PUNCH , [alone] 4294967295
SUBTREE {} 4294967295
IDENT let 4294967295
IDENT __serde_state 4294967295
PUNCH = [alone] 4294967295
IDENT try 4294967295
PUNCH ! [alone] 4294967295
SUBTREE () 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT Serializer 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT serialize_struct 4294967295
SUBTREE () 4294967295
IDENT __serializer 4294967295
PUNCH , [alone] 4294967295
LITERAL "Foo" 4294967295
PUNCH , [alone] 4294967295
IDENT false 4294967295
IDENT as 4294967295
IDENT usize 4294967295
PUNCH ; [alone] 4294967295
IDENT _serde 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT ser 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT SerializeStruct 4294967295
PUNCH : [joint] 4294967295
PUNCH : [alone] 4294967295
IDENT end 4294967295
SUBTREE () 4294967295
IDENT __serde_state 4294967295
PUNCH ; [alone] 4294967295

View file

@ -2,64 +2,86 @@
#[macro_use] #[macro_use]
mod utils; mod utils;
use test_utils::assert_eq_text; use expect_test::expect;
use utils::*; use utils::*;
#[test] #[test]
fn test_derive_serialize_proc_macro() { fn test_derive_empty() {
assert_expand( assert_expand("DeriveEmpty", r#"struct S;"#, expect![[r#"SUBTREE $"#]]);
"serde_derive",
"Serialize",
"1.0",
r"struct Foo {}",
include_str!("fixtures/test_serialize_proc_macro.txt"),
);
} }
#[test] #[test]
fn test_derive_serialize_proc_macro_failed() { fn test_derive_error() {
assert_expand( assert_expand(
"serde_derive", "DeriveError",
"Serialize", r#"struct S;"#,
"1.0", expect![[r##"
r"struct {}",
r##"
SUBTREE $ SUBTREE $
IDENT compile_error 4294967295 IDENT compile_error 4294967295
PUNCH ! [alone] 4294967295 PUNCH ! [alone] 4294967295
SUBTREE {} 4294967295 SUBTREE () 4294967295
LITERAL "expected identifier" 4294967295 LITERAL "#[derive(DeriveError)] struct S ;" 4294967295
"##, PUNCH ; [alone] 4294967295"##]],
); );
} }
#[test] #[test]
fn test_derive_proc_macro_list() { fn test_fn_like_macro() {
let res = list("serde_derive", "1").join("\n"); assert_expand(
"fn_like_noop",
assert_eq_text!( r#"ident, 0, 1, []"#,
r#"Serialize [CustomDerive] expect![[r#"
Deserialize [CustomDerive]"#, SUBTREE $
&res IDENT ident 4294967295
PUNCH , [alone] 4294967295
LITERAL 0 4294967295
PUNCH , [alone] 4294967295
LITERAL 1 4294967295
PUNCH , [alone] 4294967295
SUBTREE [] 4294967295"#]],
); );
} }
/// Tests that we find and classify non-derive macros correctly. #[test]
fn test_attr_macro() {
// Corresponds to
// #[proc_macro_test::attr_error(some arguments)]
// mod m {}
assert_expand_attr(
"attr_error",
r#"mod m {}"#,
r#"some arguments"#,
expect![[r##"
SUBTREE $
IDENT compile_error 4294967295
PUNCH ! [alone] 4294967295
SUBTREE () 4294967295
LITERAL "#[attr_error(some arguments)] mod m {}" 4294967295
PUNCH ; [alone] 4294967295"##]],
);
}
/// Tests that we find and classify all proc macros correctly.
#[test] #[test]
fn list_test_macros() { fn list_test_macros() {
let res = list("proc_macro_test", "0.0.0").join("\n"); let res = list().join("\n");
assert_eq_text!( expect![[r#"
r#"function_like_macro [FuncLike] fn_like_noop [FuncLike]
attribute_macro [Attr] fn_like_panic [FuncLike]
DummyTrait [CustomDerive]"#, fn_like_error [FuncLike]
&res attr_noop [Attr]
); attr_panic [Attr]
attr_error [Attr]
DeriveEmpty [CustomDerive]
DerivePanic [CustomDerive]
DeriveError [CustomDerive]"#]]
.assert_eq(&res);
} }
#[test] #[test]
fn test_version_check() { fn test_version_check() {
let path = fixtures::dylib_path("proc_macro_test", "0.0.0"); let path = fixtures::proc_macro_test_dylib_path();
let info = proc_macro_api::read_dylib_info(&path).unwrap(); let info = proc_macro_api::read_dylib_info(&path).unwrap();
assert!(info.version.1 >= 50); assert!(info.version.1 >= 50);
} }

View file

@ -2,9 +2,9 @@
use crate::dylib; use crate::dylib;
use crate::ProcMacroSrv; use crate::ProcMacroSrv;
use expect_test::Expect;
use proc_macro_api::ListMacrosTask; use proc_macro_api::ListMacrosTask;
use std::str::FromStr; use std::str::FromStr;
use test_utils::assert_eq_text;
pub mod fixtures { pub mod fixtures {
use cargo_metadata::Message; use cargo_metadata::Message;
@ -12,9 +12,11 @@ pub mod fixtures {
use std::process::Command; use std::process::Command;
// Use current project metadata to get the proc-macro dylib path // Use current project metadata to get the proc-macro dylib path
pub fn dylib_path(crate_name: &str, version: &str) -> std::path::PathBuf { pub fn proc_macro_test_dylib_path() -> std::path::PathBuf {
let name = "proc_macro_test";
let version = "0.0.0";
let command = Command::new(toolchain::cargo()) let command = Command::new(toolchain::cargo())
.args(&["check", "--tests", "--message-format", "json"]) .args(&["build", "-p", name, "--message-format", "json"])
.output() .output()
.unwrap() .unwrap()
.stdout; .stdout;
@ -23,7 +25,7 @@ pub mod fixtures {
match message.unwrap() { match message.unwrap() {
Message::CompilerArtifact(artifact) => { Message::CompilerArtifact(artifact) => {
if artifact.target.kind.contains(&"proc-macro".to_string()) { if artifact.target.kind.contains(&"proc-macro".to_string()) {
let repr = format!("{} {}", crate_name, version); let repr = format!("{} {}", name, version);
if artifact.package_id.repr.starts_with(&repr) { if artifact.package_id.repr.starts_with(&repr) {
return PathBuf::from(&artifact.filenames[0]); return PathBuf::from(&artifact.filenames[0]);
} }
@ -33,7 +35,7 @@ pub mod fixtures {
} }
} }
panic!("No proc-macro dylib for {} found!", crate_name); panic!("No proc-macro dylib for {} found!", name);
} }
} }
@ -41,23 +43,26 @@ fn parse_string(code: &str) -> Option<crate::rustc_server::TokenStream> {
Some(crate::rustc_server::TokenStream::from_str(code).unwrap()) Some(crate::rustc_server::TokenStream::from_str(code).unwrap())
} }
pub fn assert_expand( pub fn assert_expand(macro_name: &str, ra_fixture: &str, expect: Expect) {
crate_name: &str, assert_expand_impl(macro_name, ra_fixture, None, expect);
macro_name: &str,
version: &str,
ra_fixture: &str,
expect: &str,
) {
let path = fixtures::dylib_path(crate_name, version);
let expander = dylib::Expander::new(&path).unwrap();
let fixture = parse_string(ra_fixture).unwrap();
let res = expander.expand(macro_name, &fixture.into_subtree(), None).unwrap();
assert_eq_text!(&expect.trim(), &format!("{:?}", res));
} }
pub fn list(crate_name: &str, version: &str) -> Vec<String> { pub fn assert_expand_attr(macro_name: &str, ra_fixture: &str, attr_args: &str, expect: Expect) {
let path = fixtures::dylib_path(crate_name, version); assert_expand_impl(macro_name, ra_fixture, Some(attr_args), expect);
}
fn assert_expand_impl(macro_name: &str, input: &str, attr: Option<&str>, expect: Expect) {
let path = fixtures::proc_macro_test_dylib_path();
let expander = dylib::Expander::new(&path).unwrap();
let fixture = parse_string(input).unwrap();
let attr = attr.map(|attr| parse_string(attr).unwrap().into_subtree());
let res = expander.expand(macro_name, &fixture.into_subtree(), attr.as_ref()).unwrap();
expect.assert_eq(&format!("{:?}", res));
}
pub fn list() -> Vec<String> {
let path = fixtures::proc_macro_test_dylib_path();
let task = ListMacrosTask { lib: path }; let task = ListMacrosTask { lib: path };
let mut srv = ProcMacroSrv::default(); let mut srv = ProcMacroSrv::default();
let res = srv.list_macros(&task).unwrap(); let res = srv.list_macros(&task).unwrap();

View file

@ -3,16 +3,46 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
#[proc_macro] #[proc_macro]
pub fn function_like_macro(args: TokenStream) -> TokenStream { pub fn fn_like_noop(args: TokenStream) -> TokenStream {
args args
} }
#[proc_macro]
pub fn fn_like_panic(args: TokenStream) -> TokenStream {
panic!("fn_like_panic!({})", args);
}
#[proc_macro]
pub fn fn_like_error(args: TokenStream) -> TokenStream {
format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap()
}
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn attribute_macro(_args: TokenStream, item: TokenStream) -> TokenStream { pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream {
item item
} }
#[proc_macro_derive(DummyTrait)] #[proc_macro_attribute]
pub fn derive_macro(_item: TokenStream) -> TokenStream { pub fn attr_panic(args: TokenStream, item: TokenStream) -> TokenStream {
panic!("#[attr_panic {}] {}", args, item);
}
#[proc_macro_attribute]
pub fn attr_error(args: TokenStream, item: TokenStream) -> TokenStream {
format!("compile_error!(\"#[attr_error({})] {}\");", args, item).parse().unwrap()
}
#[proc_macro_derive(DeriveEmpty)]
pub fn derive_empty(_item: TokenStream) -> TokenStream {
TokenStream::new() TokenStream::new()
} }
#[proc_macro_derive(DerivePanic)]
pub fn derive_panic(item: TokenStream) -> TokenStream {
panic!("#[derive(DerivePanic)] {}", item);
}
#[proc_macro_derive(DeriveError)]
pub fn derive_error(item: TokenStream) -> TokenStream {
format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap()
}