【问题标题】:Unit testing Rust Syn crate单元测试 Rust Syn crate
【发布时间】:2020-12-12 19:52:06
【问题描述】:

来自Syn documentation

Syn 对 crates.io 的 proc-macro2 crate 提供的令牌表示进行操作,而不是直接使用编译器内置的 proc-macro crate。这使得使用Syn 的代码可以在过程宏的上下文之外执行,例如在单元测试或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,但我希望能够先对宏的功能进行单元测试。

【问题讨论】:

    标签: unit-testing parsing rust rust-macros rust-proc-macros


    【解决方案1】:

    它不适用于proc_macro2::TokenStream 类型,但它不适用于proc_macro::TokenStream,因为我们不在proc-macro 上下文中。

    是的,这就是重点!导出过程宏的 crates 不能导出其他任何东西,但 proc_macro 只能在导出宏的 crates 中使用。这就是proc_macro2首先存在的原因。

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

    • 您的公共 crate 使用 #[proc_macro] 等声明宏,除了将 proc_macro::TokenStream 转换为 proc_macro2::TokenStream 和反之亦然之外,几乎没有做任何事情。
    • 一个“内部”包,包含大部分实际代码,它依赖于proc_macro2,但不依赖于proc_macro。您的测试可以在这里进行。

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

    【讨论】:

    • 我上面的代码示例没有声明宏或依赖于proc_macro。我的测试需要什么样的外观才能实际使用 syn 函数?
    • 您可以使用parse2 而不是parse 来接受proc_macro2::TokenStream
    • 所以事实证明我不需要单独的 crate 来编写测试,只要我使用 syn::parse2 就可以在 proc-macro crate 中使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多