From cfcadcb2959d2dbaf7d95e8b9a33c48b75480e9f Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 31 May 2021 17:32:56 +0200 Subject: [PATCH] Simplify proc_macro_srv tests --- Cargo.lock | 2 +- crates/proc_macro_srv/Cargo.toml | 5 +- .../fixtures/test_serialize_proc_macro.txt | 181 ------------------ crates/proc_macro_srv/src/tests/mod.rs | 92 +++++---- crates/proc_macro_srv/src/tests/utils.rs | 45 +++-- crates/proc_macro_test/src/lib.rs | 38 +++- 6 files changed, 119 insertions(+), 244 deletions(-) delete mode 100644 crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt diff --git a/Cargo.lock b/Cargo.lock index ee04cdce8e..505263c645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1143,13 +1143,13 @@ name = "proc_macro_srv" version = "0.0.0" dependencies = [ "cargo_metadata", + "expect-test", "libloading", "mbe", "memmap2", "object", "proc_macro_api", "proc_macro_test", - "serde_derive", "test_utils", "toolchain", "tt", diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml index 4ea41175e8..c15cb88214 100644 --- a/crates/proc_macro_srv/Cargo.toml +++ b/crates/proc_macro_srv/Cargo.toml @@ -20,10 +20,9 @@ proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } [dev-dependencies] test_utils = { path = "../test_utils" } +toolchain = { path = "../toolchain" } cargo_metadata = "0.13" +expect-test = "1.1.0" # used as proc macro test targets -serde_derive = "1.0.106" proc_macro_test = { path = "../proc_macro_test" } - -toolchain = { path = "../toolchain" } diff --git a/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt b/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt deleted file mode 100644 index eb67c71348..0000000000 --- a/crates/proc_macro_srv/src/tests/fixtures/test_serialize_proc_macro.txt +++ /dev/null @@ -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 diff --git a/crates/proc_macro_srv/src/tests/mod.rs b/crates/proc_macro_srv/src/tests/mod.rs index b4ab4c0776..5ca2b8a750 100644 --- a/crates/proc_macro_srv/src/tests/mod.rs +++ b/crates/proc_macro_srv/src/tests/mod.rs @@ -2,64 +2,86 @@ #[macro_use] mod utils; -use test_utils::assert_eq_text; +use expect_test::expect; use utils::*; #[test] -fn test_derive_serialize_proc_macro() { +fn test_derive_empty() { + assert_expand("DeriveEmpty", r#"struct S;"#, expect![[r#"SUBTREE $"#]]); +} + +#[test] +fn test_derive_error() { assert_expand( - "serde_derive", - "Serialize", - "1.0", - r"struct Foo {}", - include_str!("fixtures/test_serialize_proc_macro.txt"), + "DeriveError", + r#"struct S;"#, + expect![[r##" + SUBTREE $ + IDENT compile_error 4294967295 + PUNCH ! [alone] 4294967295 + SUBTREE () 4294967295 + LITERAL "#[derive(DeriveError)] struct S ;" 4294967295 + PUNCH ; [alone] 4294967295"##]], ); } #[test] -fn test_derive_serialize_proc_macro_failed() { +fn test_fn_like_macro() { assert_expand( - "serde_derive", - "Serialize", - "1.0", - r"struct {}", - r##" -SUBTREE $ - IDENT compile_error 4294967295 - PUNCH ! [alone] 4294967295 - SUBTREE {} 4294967295 - LITERAL "expected identifier" 4294967295 -"##, + "fn_like_noop", + r#"ident, 0, 1, []"#, + expect![[r#" + SUBTREE $ + IDENT ident 4294967295 + PUNCH , [alone] 4294967295 + LITERAL 0 4294967295 + PUNCH , [alone] 4294967295 + LITERAL 1 4294967295 + PUNCH , [alone] 4294967295 + SUBTREE [] 4294967295"#]], ); } #[test] -fn test_derive_proc_macro_list() { - let res = list("serde_derive", "1").join("\n"); - - assert_eq_text!( - r#"Serialize [CustomDerive] -Deserialize [CustomDerive]"#, - &res +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 non-derive macros correctly. +/// Tests that we find and classify all proc macros correctly. #[test] fn list_test_macros() { - let res = list("proc_macro_test", "0.0.0").join("\n"); + let res = list().join("\n"); - assert_eq_text!( - r#"function_like_macro [FuncLike] -attribute_macro [Attr] -DummyTrait [CustomDerive]"#, - &res - ); + expect![[r#" + fn_like_noop [FuncLike] + fn_like_panic [FuncLike] + fn_like_error [FuncLike] + attr_noop [Attr] + attr_panic [Attr] + attr_error [Attr] + DeriveEmpty [CustomDerive] + DerivePanic [CustomDerive] + DeriveError [CustomDerive]"#]] + .assert_eq(&res); } #[test] 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(); assert!(info.version.1 >= 50); } diff --git a/crates/proc_macro_srv/src/tests/utils.rs b/crates/proc_macro_srv/src/tests/utils.rs index f15381f0f4..f0a514b325 100644 --- a/crates/proc_macro_srv/src/tests/utils.rs +++ b/crates/proc_macro_srv/src/tests/utils.rs @@ -2,9 +2,9 @@ use crate::dylib; use crate::ProcMacroSrv; +use expect_test::Expect; use proc_macro_api::ListMacrosTask; use std::str::FromStr; -use test_utils::assert_eq_text; pub mod fixtures { use cargo_metadata::Message; @@ -12,9 +12,11 @@ pub mod fixtures { use std::process::Command; // 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()) - .args(&["check", "--tests", "--message-format", "json"]) + .args(&["build", "-p", name, "--message-format", "json"]) .output() .unwrap() .stdout; @@ -23,7 +25,7 @@ pub mod fixtures { match message.unwrap() { Message::CompilerArtifact(artifact) => { 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) { 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 { Some(crate::rustc_server::TokenStream::from_str(code).unwrap()) } -pub fn assert_expand( - crate_name: &str, - 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 assert_expand(macro_name: &str, ra_fixture: &str, expect: Expect) { + assert_expand_impl(macro_name, ra_fixture, None, expect); } -pub fn list(crate_name: &str, version: &str) -> Vec { - let path = fixtures::dylib_path(crate_name, version); +pub fn assert_expand_attr(macro_name: &str, ra_fixture: &str, attr_args: &str, expect: Expect) { + 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 { + let path = fixtures::proc_macro_test_dylib_path(); let task = ListMacrosTask { lib: path }; let mut srv = ProcMacroSrv::default(); let res = srv.list_macros(&task).unwrap(); diff --git a/crates/proc_macro_test/src/lib.rs b/crates/proc_macro_test/src/lib.rs index ec2a114a35..4b26d24721 100644 --- a/crates/proc_macro_test/src/lib.rs +++ b/crates/proc_macro_test/src/lib.rs @@ -3,16 +3,46 @@ use proc_macro::TokenStream; #[proc_macro] -pub fn function_like_macro(args: TokenStream) -> TokenStream { +pub fn fn_like_noop(args: TokenStream) -> TokenStream { 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] -pub fn attribute_macro(_args: TokenStream, item: TokenStream) -> TokenStream { +pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream { item } -#[proc_macro_derive(DummyTrait)] -pub fn derive_macro(_item: TokenStream) -> TokenStream { +#[proc_macro_attribute] +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() } + +#[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() +}