Closed Narann closed 3 years ago
Something like this could be added but I'd like to better understand the use case. In what situation do you know the number of lines but only check a subset of the content?
Hi and thanks for your answer. Here is the use case:
I have a tool that list header information:
#[test]
fn cmd_header_file_nuke_16_v9_f16_uncomp_1part() -> Result<(), Box<dyn std::error::Error>> {
let mut cmd = Command::cargo_bin(BIN_NAME)?;
cmd.arg("header")
.arg("tests/images/nuke_16/v9.0/f16_uncomp_1part.exr")
.assert()
.success()
.stdout(
predicate::str::contains("layer count: 1")
.and(predicate::str::contains("layer #0"))
.and(predicate::str::contains("compression: no compression"))
.and(predicate::str::contains("block: scanline"))
.and(predicate::str::contains("line_order: increasing"))
.and(predicate::str::contains("layer_size (v2u): (16, 16)"))
.and(predicate::str::contains(
"display_window (box2i): position: (0, 0), size: 16x16",
))
.and(predicate::str::contains("pixel_aspect_ratio (float): 1"))
.and(predicate::str::contains("layer_position (v2i): (0, 0)"))
.and(predicate::str::contains(
"screen_window_center (v2f): (0, 0)",
))
.and(predicate::str::contains("screen_window_width (float): 1"))
.and(predicate::str::contains(
"nuke/node_hash (string): \"b8af9cf2c951eddb\"",
))
.and(predicate::str::contains(
"nuke/foo/bar (string): \"my_value\"",
))
.and(predicate::str::contains("A, f16, sampling (1, 1)"))
.and(predicate::str::contains("B, f16, sampling (1, 1)"))
.and(predicate::str::contains("G, f16, sampling (1, 1)"))
.and(predicate::str::contains("R, f16, sampling (1, 1)"))
.and(predicate::str::contains("foo.alpha, f16, sampling (1, 1)"))
.and(predicate::str::contains("foo.blue, f16, sampling (1, 1)"))
.and(predicate::str::contains("foo.green, f16, sampling (1, 1)"))
.and(predicate::str::contains("foo.red, f16, sampling (1, 1)")),
);
Ok(())
}
As you can see, I add my checks line by line as it's easier to comment to find debug/find if there are regression and which information have a problem.
The problem is, if one or more lines appears in my output, test will pass. It's something I want to avoid and that's the reason why I try to find a kinda line_count()
predicate.
So you are technically right: I could simply check the whole output. But doing so, I would spend some time to find which line have a regression.
What I like with predicate
its how tests are both easy to write and manipulate so I thought it would make sense to have line_count()
.
Hope this makes sense.
Keep the good work! :)
PS: Any workaround is welcome.
So you are technically right: I could simply check the whole output. But doing so, I would spend some time to find which line have a regression.
Would predicates::str::similar
help? Unlike an eq
predicate, this will diff the content, highlighting which parts are different. You can configure it for whether the atoms are characters, words, or lines. We are looking at tweaking the API for what you select as the atom / split (see #102).
If that doesn't work, we can look into the line count. Another idea I'm playing with is where we support splitting the lines and you compare against an array of predicates, so something like
cmd.arg("header")
.arg("tests/images/nuke_16/v9.0/f16_uncomp_1part.exr")
.assert()
.success()
.stdout(
eq([
predicate::str::contains("layer count: 1"),
predicate::str::contains("layer #0"),
predicate::str::contains("compression: no compression"),
]).lines()
)
The API isn't feeling as clean (unsure on how to properly express it so the intent is clear and the API is discoverable).
Thanks for predicates::str::similar
, I will try it. :)
The second example lost looks less explicit than, for example:
predicate::str::lines_contains(["my line", "my other line"])
But I'm not experienced enough with rust to have strong opinion and maybe what you write make more sense. rust community seems to encourage highly nested functional style. Nothing wrong with that, I'm just not used to it.
I don' want to take you precious time anymore. I will try with:
predicate::str::is_match("\n").unwrap().count(3)
Seems to be what I want.
Keep the good work and have a nice day! :)
I actually have a situation where the output count (line count) is known, but the order is not, this means predicates::str::similar
almost always fail.
Thats too bad it doesn't work for your case but I like the is_match
approach. I think using that more flexible tool might be better than directly baking this in but feel free to suggest otherwise!
Hello,
First, thanks for your hard work on this crate, I use it with
assert_cmd
and it's easy to both read and use. :)I test every line, of my output, but I want to be sure I didn't miss anything.
Is there any hope to see a predicate for line count ?
Like a
predicate::str::line_count(5)
to check the output line count is5
?Hope this feature make sense and will brings some interest.
Keep the good work!