#assertions #nlp #testing #fluent #assert #macro #struct-fields

fluent_field_assertions

FluentFieldAssertions是一个库,允许您使用类似自然语言的语法编写测试。

6个版本

0.2.0 2023年8月9日
0.1.4 2023年7月23日
0.1.3 2023年6月24日

#591过程宏

Download history 2/week @ 2024-03-10 35/week @ 2024-03-31

每月 94 次下载

MIT 许可证

11KB
106

FluentFieldAssertions

FluentFieldAssertions是一个库,允许您使用类似自然语言的语法编写测试。
使用此库,您可以以直观和可读的方式执行字段断言。

功能

  • 自然语言语法:您可以使用类似于自然语言的语法编写测试代码。
  • 方法链:您可以像方法调用一样链式断言,允许您在单个语句中表达多个断言。
  • 可读性和可维护性:代码变得简单且可读,提高了测试的可维护性。

用法

FluentFieldAssertions为每个字段生成了以下方法。

  • fn {field}_eq(&self,expected: {field_type}) -> &Self
    • 断言字段等于预期值。
  • fn {field}_ne(&self,expected: {field_type}) -> &Self
    • 断言字段不等于预期值。
  • fn {field}_satisfies(&self,pred: impl FnOnce(&{field_type}) -> bool) -> &Self
    • 断言字段满足谓词。
use fluent_field_assertions::FluentFieldAssertions;

#[derive(FluentFieldAssertions)]
struct User {
    id: usize,
    name: String,
    age: usize,
}

let user = User {
    id: 1,
    name: "Alice".to_string(),
    age: 17,
};

// You can write tests in a natural language-like syntax.
user.id_eq(&1)
    .name_eq(&"Alice".to_string())
    .age_satisfies(|age| age < &18);

// Same as above.
assert_eq!(user.id, 1);
assert_eq!(user.name, "Alice".to_string());
assert!(user.age < 18);

示例

基本结构体

您可以在基本结构体中使用它。
每个字段必须实现特性 EqDebug

use fluent_field_assertions::FluentFieldAssertions;

#[derive(FluentFieldAssertions)]
struct User {
    id: usize,
    name: String,
    age: usize,
    // You can skip assertion_methods for some fields.
    #[assertions(skip)]
    score: f64,
}

let user = User {
    id: 1,
    name: "Alice".to_string(),
    age: 17,
    score: 95.0,
};

// You can use `{field}_eq` to assert_eq!.
user.name_eq(&"Alice".to_string());
assert_eq!(user.name, "Alice".to_string()); // Same as above.

// You can use `{field}_ne` to assert_ne!.
user.name_ne(&"Bob".to_string());
assert_ne!(user.name, "Bob".to_string()); // Same as above.

// You can use `{field}_satisfies` to assert!.
user.name_satisfies(|name| name.starts_with('A'));
assert!(user.name.starts_with('A')); // Same as above.

// You can chain assertions as method calls.
user.id_eq(&1)
    .name_eq(&"Alice".to_string())
    .age_satisfies(|age| age < &18);

// Same as above.
assert_eq!(user.id, 1);
assert_eq!(user.name, "Alice".to_string());
assert!(user.age < 18);

泛型结构体

您也可以在泛型结构体中使用它。
在这种情况下,泛型类型 T 必须实现特性 EqDebug

use core::fmt::Debug;
use fluent_field_assertions::FluentFieldAssertions;

#[derive(FluentFieldAssertions)]
struct Point<T>
// Generics type `T` must implement trait `Eq` and `Debug`.
where
    T: Eq + Debug,
{
    x: T,
    y: T,
    z: T,
    // You can skip assertion_methods for some fields.
    #[assertions(skip)]
    #[allow(dead_code)]
    t: T,
}

let point = Point {
    x: 1,
    y: 2,
    z: 3,
    t: 4,
};

point.x_eq(&1).y_ne(&9).z_satisfies(|z| z % 3 == 0);

依赖项

~320–780KB
~18K SLoC