assertor icon indicating copy to clipboard operation
assertor copied to clipboard

Feature idea - enumeration variant matching

Open weilbith opened this issue 2 years ago • 4 comments

Hey 👋🏾

I really like the fluid syntax of this library. While working with it, a few assertions would be great to have. Some of them are for ergonomics when working with enumeration variants. Like simple matching. So I could imagine for example something like:

enum Color {
   RED,
   GREEN,
   BLUE,
   RGB(u8, u8, u8),
}

assert_that!(Color::RED).matches(Color::RED);
assert_that!(Color::RGB(255, 0, 0)).matches(Color::RGB(_, _, _));
assert_that!(Color::RGB(255, 0, 0)).matches(Color::RGB(_, _, 0));

With the "default" API you can write these simply with assert!(matches!(...)). But then we have the syntax of the assertor it's assert_that! mixed with the other. Which does not read and feel great. So I though it might be easy enough to add this? 🙈

In any case: thanks for this library. Like it so far!

weilbith avatar Sep 19 '23 14:09 weilbith

Thank you for your proposal!

Introducing pattern matching with descriptive error message is challenging as far as my knowledge goes. matches!() macro in Rust std is a syntax suger of match expression (doc), and there is no API in Rust lang to get "why it doesn't match" given a match expression and a value. So, library cannot output descriptive error message beyond assert!(matches!(...)).

It may be worth enabling users to delegate checking by passing an anonymous function; for example assert_that!(...).is(|actual_value| matches!(actual, Color::RGB(_, _, 0))). This API could be used with macros representing anonymous functions like assert_that!(...).is(matching!(Color::RGB(_,_,0))).

cocuh avatar Sep 21 '23 15:09 cocuh

Interesting. Sorry, I haven't thought about the error messages. Very good point. How would this problem of descriptive error message be solved for the very generic approach you proposed? 🤔

weilbith avatar Sep 22 '23 08:09 weilbith

In the generic approach in my comment, error message for assert_that!(Color::RGB(1,2,3)).is(matching!(Color::RGB(_,_,0))) can be:

Expected `matching!(Color::RGB(_,_,0))` to return true for a value `RGB(1,2,3)`, but it doesn't.

The actual value (=RGB(1,2,3)) is additional information compared to the original asserting, assert!(matches!(...)).

It may have slight difficulties in macros to stringify the delegated function though, it is possible, I think.

cocuh avatar Sep 25 '23 08:09 cocuh

Alright, sounds like a good extension to me. :+1:

weilbith avatar Sep 27 '23 08:09 weilbith