#fork #section #nested #test #subtest

crossroads

一个将一个函数转换成多个用户定义的分支点的宏!

2 个版本

0.1.1 2022年12月21日
0.1.0 2022年12月21日

#612测试

MIT 许可证

18KB
154

crossroads

该库包含一个简单的 proc 宏,其目的是将一个函数转换成多个!

为了说明这一点,假设你有一些类似的测试用例

use std::collections::HashMap;

#[test]
fn empty_be_default() {
    let map: HashMap<String, usize> = Default::default();
    
    assert!(map.is_empty());
}

#[test]
fn empty_after_clear() {
    let mut map: HashMap<String, usize> = Default::default();

    map.insert("test".to_string(), 1);
    map.clear();

    assert!(map.is_empty());
}

#[test]
fn empty_after_remove() {
    let mut map: HashMap<String, usize> = Default::default();

    map.insert("test".to_string(), 1);
    map.remove("test");

    assert!(map.is_empty());
}

该软件包允许你编写以下代码

use std::collections::HashMap;
use crossroads::crossroads;

#[crossroads]
#[test]
fn empty() {
    let mut map: HashMap<String, usize> = Default::default();

    match fork!() {
        by_default => {}
        after_add => {
            map.insert("Key".to_owned(), 1337);
            match fork!() {
                and_remove => map.remove("Key"),
                and_clear => map.clear(),
            };
        }
    }

    assert!(map.is_empty());
}

该宏计算通过 fork!() 的所有可能路径,并为每个路径创建函数版本。然后,这些函数可以被测试系统获取(作为属性下面的 #[crossroads] 属性也被克隆)。在这种情况下,你会得到如下输出(运行 cargo test --examples 以重现

running 3 tests
test empty_by_default ... ok
test empty_after_add_and_clear ... ok
test empty_after_add_and_remove ... ok

这个想法受到了 @Nested 测试在 JUnit 5 中的Catch2 中的doctest 中的子测试 的启发。

问题

常见问题的答案

  1. 你为什么决定使用标准的 match 语法而不是引入自定义语法,例如 fork! { a => { .. }, b => { .. }}

使用proc宏确实可以提供完全自定义的语法。然而,我决定仅使用match结构,因为它使代码格式化工具(尤其是rustfmt)工作得更加顺畅。

贡献

我欢迎任何建议/功能请求/更改/错误修复。如果您已经有了具体的更改,请随意提交一个PR。或者,您可以打开一个issue,我们可以讨论可能的解决方案/可行性。

请注意,您对此项目的任何贡献都假定是在与项目剩余部分相同的许可证下。请确保您有合法权利授予您的工作此类许可证。

一般要求

  • CI检查必须在您的PR中全部通过。
  • 在审查/批准后,请将您的分支更新到master分支的最新版本。

许可证

此库根据MIT许可证授权,有关详细信息,请参阅LICENSE

依赖项

约1.5MB
约34K SLoC