New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tests/util
: Enhance CmdResult
#4259
Comments
The first two sound good! The last one I'm not sure about for two reasons (but happy to be convinced otherwise):
|
Regarding your concerns about the lifetimes etc. I found it easier to quickly implement a working version, which should be self-explaining, in a draft pr #4261. Concerning I skimmed through the tests and refactored two of them to demonstrate the #[test]
fn test_uname_processor() {
new_ucmd!()
.arg("-p")
.succeeds()
.stdout_str_apply(str::trim_end)
.stdout_only("unknown");
} over #[test]
fn test_uname_processor() {
let result = new_ucmd!().arg("-p").succeeds();
assert_eq!(result.stdout_str().trim_end(), "unknown");
} Having such methods is a convenient way to edit |
I see, it's owned values all the way through with a bit of new_ucmd!()
.arg("-i")
.succeeds()
.stdout_check(|s| {
s.trim_end() == "somestring"
}); |
To be precise, a new state is created but the old state isn't mutated. This is maybe relevant because the old let result = ucommand.run();
result.stdout_str_apply(str::trim).stdout_is("unknown");
result.stdout_str_apply(str::trim_end).stdout_is(" unknown"); I like your predicate method! I would like to have both methods for full power and flexibility, perhaps modifying your suggestion a bit to |
Yeah that's true and indeed a bit better, but the fact remains that the order of assertions now matters. |
I'm not sure I understand. Can you please give an example in which the order of the assertions matters? |
Ah sorry for being vague, I just mean this: ucommand
.run()
.stdout_only("hello world") // fails
.stdout_str_apply(str::trim)
.stdout_only("hello world"); // works |
Ok, I see, but what's unclear or wrong about it? |
The assertions are generally independent of each other and with this function they aren't anymore. That's all :) |
Upon second thought, that's maybe not what I dislike. I find it counterintuitive that by applying a function on the ucommand
.run()
.stdout_str_check(|s| {
s.trim() == "something"
})
.stderr_str_check(|s| {
s.trim() == "something else"
});
// vs
ucommand
.run()
.stdout_str_apply(str::trim)
.stdout_is("something")
.stderr_str_apply(str::trim)
.stderr_is("something else"); |
I think both methods have their field of application :) They can be combined if wished so. In the end, it's up to the user how to realize it. Do you want to implement the predicate API? If not, I could do it as part of #4261. |
The applications are basically the same though. In my opinion they're too similar to have both. If you can give a realistic example where the apply API is clearly better I might be convinced, but I can't think of any.
Feel free to give it a shot! |
The advantage of the apply api is, that the existing assertion methods in I would classify the The Having both apis makes |
Oh yeah I totally didn't think of those other methods. Very good point! Thanks! |
Sure. I implemented everything we discussed here in the associated pr, if you wanna have a look. The PR's ready so far but since we're already talking about
|
Maybe it's better two address those in another PR? Sounds like it would require changes in a lot of tests. |
On a related note, I think we can get rid of the bytes methods by making something like the I.e. trait AssertOutput {
fn assert_equal(self, output: &[u8]);
}
impl AssertOutput for &str { todo!() }
impl AssertOutput for &[u8] { todo!() }
impl CmdResult {
fn stdout_is(expected: impl AssertOutput) { todo!() }
} We could then also implement |
yep no problem, although only the changes of
I like the idea! Let's try it, but maybe also in another pr? |
Yeah the second suggestion is small indeed. And yeah my idea was indeed also for another PR. |
`tests/util`: Implement enhancements of `CmdResult` #4259
I would love to enhance the existing functionality of
CmdResult
by a few points.Use
ExitStatus
instead ofcode
andsuccess
We get the
ExitStatus
from thewait
methods inUChild
, so no extraction ofcode
andsuccess
is required to initialize theCmdResult
. On unix platforms we could provide a method inCmdResult
to assert signals or whatever is available instd::os::unix::ExitStatusExt
.Rename
stderr_is
tostderr_trimmed_is
and provide astderr_is
method which asserts the stderr untrimmedThis method gave a hard time once, until I found out that stderr is trimmed. The trimming should be more obvious.
Provide
stdout_apply
,stdout_str_apply
,stderr_apply
andstderr_str_apply
methods which apply a function to the stdout (stderr) and return aCmdResult
Such method calls could for example look like
This has the advantage, that we can stay in the
CmdResult
chain, instead of breaking out withlet stdout = ucommand.run().stdout_str()
, then doing something withstdout
and then asserting thisstdout
manually.The text was updated successfully, but these errors were encountered: