代码之家  ›  专栏  ›  技术社区  ›  Shepmaster Tim Diekmann

如何基于功能标志有条件地执行模块级doctest?

  •  10
  • Shepmaster Tim Diekmann  · 技术社区  · 6 年前

    我正在为一个模块编写文档,该模块有一些由Cargo功能标志控制的选项。我希望始终显示此文档,以便板条箱的消费者知道它可用,但我只需要在启用该功能时运行该示例。

    lib。卢比

    //! This crate has common utility functions
    //!
    //! ```
    //! assert_eq!(2, featureful::add_one(1));
    //! ```
    //!
    //! You may also want to use the feature flag `solve_halting_problem`:
    //!
    //! ```
    //! assert!(featureful::is_p_equal_to_np());
    //! ```
    
    pub fn add_one(a: i32) -> i32 {
        a + 1
    }
    
    #[cfg(feature = "solve_halting_problem")]
    pub fn is_p_equal_to_np() -> bool {
        true
    }
    

    货物汤姆

    [package]
    name = "featureful"
    version = "0.1.0"
    authors = ["An Devloper <an.devloper@example.com>"]
    
    [features]
    solve_halting_problem = []
    
    [dependencies]
    

    在启用该功能的情况下运行,将按预期运行两个doctest:

    $ cargo test --features=solve_halting_problem
       Doc-tests featureful
    
    running 2 tests
    test src/lib.rs -  (line 7) ... ok
    test src/lib.rs -  (line 3) ... ok
    
    test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
    

    不使用该功能运行时出错:

    $ cargo test
       Doc-tests featureful
    
    running 2 tests
    test src/lib.rs -  (line 7) ... FAILED
    test src/lib.rs -  (line 3) ... ok
    
    failures:
    
    ---- src/lib.rs -  (line 7) stdout ----
        error[E0425]: cannot find function `is_p_equal_to_np` in module `featureful`
     --> src/lib.rs:8:21
      |
    4 | assert!(featureful::is_p_equal_to_np());
      |                     ^^^^^^^^^^^^^^^^ not found in `featureful`
    

    两者 ```ignore ```no_run 无论功能是否启用,修改器都会应用,因此它们似乎没有什么用处。


    How would one achieve conditional compilation with Rust projects that have doctests? 很接近,但答案集中在 功能 通过条件编译而非 模块

    2 回复  |  直到 6 年前
        1
  •  11
  •   Shepmaster Tim Diekmann    6 年前

    我只看到一个解决方案:把 #[cfg] 测试内部:

    //! ```
    //! #[cfg(feature = "solve_halting_problem")]
    //! assert!(featureful::is_p_equal_to_np());
    //! ```
    

    这将计为测试,但当功能未启用时,它将为空。您可以将此与 hide portions of the example 事实上你可以把 #【cfg】 整个块上的属性:

    //! ```
    //! # #[cfg(feature = "solve_halting_problem")] {
    //! assert!(featureful::is_p_equal_to_np());
    //! // Better double check
    //! assert!(featureful::is_p_equal_to_np());
    //! # }
    //! ```
    

    作为提示,也许你可以 #![feature(doc_cfg)] 像这样:

    /// This function is super useful
    ///
    /// ```
    /// assert!(featureful::is_p_equal_to_np());
    /// ```
    #[cfg(any(feature = "solve_halting_problem", feature = "dox"))]
    #[doc(cfg(feature = "solve_halting_problem"))]
    pub fn is_p_equal_to_np() -> bool {
        true
    }
    

    当功能被禁用时,这将不会运行测试,但这将生成带有 cargo doc --features dox

        2
  •  1
  •   Yotam Ofek    2 年前

    这也行得通,而且我认为更干净:

    //! This crate has common utility functions
    //!
    //! ```
    //! assert_eq!(2, featureful::add_one(1));
    //! ```
    //!
    #![cfg_attr(
        not(feature = "solve_halting_problem"),
        doc = "You may also want to use the feature flag `solve_halting_problem`:"
    )]
    #![cfg_attr(
        feature = "solve_halting_problem",
        doc = "This example works because the `solve_halting_problem` feature flag is enabled:"
    )]
    //!
    #![cfg_attr(not(feature = "solve_halting_problem"), doc = "```ignore")]
    #![cfg_attr(feature = "solve_halting_problem", doc = "```")]
    //! assert!(featureful::is_p_equal_to_np());
    //! ```