assert-rs / predicates-rs

Boolean-valued predicate functions in Rust
docs.rs/predicates
Apache License 2.0
173 stars 29 forks source link

[Feature Request] Make `not` and `predicates::PredicateBooleanExt` more visible in docs #120

Closed Derpford closed 2 years ago

Derpford commented 2 years ago

I'm working on unit tests for a CLI tool, and I need to verify that the tool does not add files to a list inside the config file under certain conditions (i.e., dotfiles, files that aren't on the list of types to track, etc).

As of right now, I'm using a series of contains predicates alongside assert_fs, with #[should_panic], like so:

#[test]
#[should_panic]
fn test_config_fail() {
  let mut temp = assert_fs::TempDir::new().unwrap();
  make_test_folders(&mut temp).unwrap();
  // Command runs here.
  // ...
  let cfg = temp.child("./config.file");
  cfg.assert(predicate::str::contains(".invisible.txt"));
  cfg.assert(predicate::str::contains("whoops.md"));
  //...
}

However, there's a problem with this approach. If the first assert panics, as it should...the rest of the asserts are never touched, because the first one panicked!

I need a way to invert a contains predicate--that is, I need something that checks to make sure a substring doesn't exist in a target string. It's not practical for me to use the ne predicate, because A) the config file contains a lot of lines and B) the order the config file initially puts files in is not deterministic, so it would be prone to false negatives.

epage commented 2 years ago

We do provide not on an extension trait. Normally we would only provide additional variants of a predicate on top of what you can build up if there is some customization to the formatting we want. I've not been able to think of some custom formatting a doesnt_contain would provide.

We probably need to raise the visibility of the not predicate in the documentation.

Derpford commented 2 years ago

So I tried adding not() to my predicates, like so:

cfg.assert(predicate::str::contains("example.foo").not());

And I got the following error: image

It seems that contains simply doesn't have not().

epage commented 2 years ago

not is on an extension trait. You'd need to use predicates::PredicateBooleanExt; though I'm surprised the compiler didn't tell you that (it usually does) so I worry something else might also be going on that we'll need to debug.

Derpford commented 2 years ago

Ah, yeah, that was a couple lines up. Lemme try again...

Derpford commented 2 years ago

That worked. Thanks for your help! I'll leave this issue open with an edited name for now, since you mentioned improving the docs.