单元测试 Rust Syn crate

Unit testing Rust Syn crate

来自Syn documentation

Syn operates on the token representation provided by the proc-macro2 crate from crates.io rather than using the compiler's built in proc-macro crate directly. This enables code using Syn to execute outside of the context of a procedural macro, such as in unit tests or build.rs

我正在尝试为一些 Syn 函数启用单元测试,但是无论我尝试了什么,我都无法让它工作。它不适用于 proc_macro2::TokenStream 类型,但它不适用于 proc_macro::TokenStream,因为我们不在 proc-macro 上下文中。

link to playground

use quote::quote;
use syn;

fn test() {
    // let stream: syn::export::TokenStream = quote!{fn foo() {};}.into(); // doesn't work
    let stream: proc_macro2::TokenStream = quote!{fn foo() {};}.into(); // doesn't work
    // let item = parse_macro_input!(stream as Item); // doesn't work
    let item = syn::parse(stream).unwrap();

}

fn main() {
    test();
}

任何有关如何在 proc-macro 上下文之外测试 syn 函数的帮助将不胜感激。我知道 trybuild crate,但我希望能够先对宏的函数进行单元测试。

It does not work with the proc_macro2::TokenStream type, but it won't work with the proc_macro::TokenStream because we are not in a proc-macro context.

是的,这就是重点!导出程序宏的 crate 不能导出其他任何东西,但是 proc_macro 只能用于导出宏的 crate。这就是为什么proc_macro2首先存在的原因。

您需要使用多个 crate 才能为使用 synproc_macro2 的代码编写测试:

  • 你的 public 板条箱用 #[proc_macro] 等声明宏,除了将 proc_macro::TokenStream 转换为 proc_macro2::TokenStream 之外几乎没有什么作用,反之亦然。
  • 一个“内部”包,包含大部分实际代码,它依赖于 proc_macro2 而不是 proc_macro。您的测试可以在这里进行。

您看到的错误是因为 syn::parse 接受 proc_macro::TokenStream。您可以改用 syn::parse2,除了它接受 proc_macro2::TokenStream.

之外,它是相同的