hi, I'm new to Rust, I've been trying to find a solution to my problem on the internet, but everywhere (example) they recommend passing an option to a function, but I need the function to not receive anything
The solution for testing functions that perform I/O is to avoid hardcoding the source to read from. Instead of making the function write to/read from stdout/stdin, make it take a Read and Write instead:
use std::io;
fn yes_or_no<R, W>(prompt: &str, mut reader: R, mut writer: W) -> io::Result<bool>
where
R: io::BufRead,
W: io::Write,
{
let approvals_array = ["y", "yes", "т", "так", "д", "да"];
write!(writer, "{} ", prompt);
writer.flush()?;
let mut input = String::new();
reader.read_line(&mut input)?;
let input = input.trim().to_lowercase();
Ok(approvals_array.contains(&input.as_str()))
}
Then you can test it using e.g. io::Cursor and/or Vec: Playground
Is it possible to not pass mut reader: R, mut writer: W to the function, because then in all places where this function will be used, io::stdout() will have to be fussed, I think it will be redundant (unnecessary) because it will be everywhere standard input ?
I'm trying to develop an application in a group to make sure that they understand correctly what behavior of the function I expect, I wanted to write unit tests that would reflect the nuances of behavior depending on certain input data, maybe there is a solution?
I've used this crate for testing an app processes stdin appropriately. assert_cmd crate
You can build up unit tests in tests/cli.rs and run with cargo test.
This may be of use.
Dear @H2CO3, thanks for the suggestion. When I tried using the yes_or_no() in the main I got the error:
Compiling upcase v0.1.0 (C:\Users\manukyae\00-work\stdin-buff)
error[E0277]: the trait bound `Stdin: BufRead` is not satisfied
--> src\main.rs:4:29
|
4 | yes_or_no("yes or no?", &mut io::stdin(), &... | --------- ^^^^^^^^^^^^^^^^ the trait `BufRead` is not implemented for `Stdin`
| |
| required by a bound introduced by this call
|