-
Notifications
You must be signed in to change notification settings - Fork 76
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
Expose a testing API that accepts a sequence of commands and/or keystrokes to execute the prompt. #71
Comments
Layer 1: receive a sequence of commands as input. This layer could not even know about the existence of keystrokes. Layer 2: receive a sequence of Layer 3: Full E2E testing with a tty. This will allow us to test our integrations with each terminal backend. enigo might be a good way to go about it |
Hey @mikaelmello 👋 I am relatively new to Rust and starting playing with this library for a cool way for my cli tools to take input from users rather than always as args. I really like this library. The type to filter functionality in the select and multiselect was a cool surprise for me. Nice! 👍 I’m trying to convince my boss to use Rust and things like this at work, but they want to see good tests for “enterprise level code”. I took a stab at it on my own, but I’m not exactly sure how to go from the ‘Key’ to making it think that key was pressed. See this related issue . I think sending the raw Key events is fine for me- at least it will allow me to navigate through the prompts and get stuff done. I think at least adding an example of doing this in the README could be an easy win. I do also like the idea of having some higher level commands though… for example a function that takes a vec of choices and under the hood maps to all the arrow / filtering / space key presses that go into selecting a bunch of things on a multiselect… I have some bandwidth to think about this if you need any help as well. Thanks! |
hey @JimLynchCodes , 100%. Unfortunately this hasn't been implemented as of now, a few months back I did try tackling this but it was more complex than I expected, so it kind of got brushed aside, I intend to revisit it over the next couple of weeks |
No worries @mikaelmello. It's not super urgent for me. Here are some things I've been trying, nothing exactly working yet but it might be interesting to you... actually ChatGPT gave me some of this code, but it doesn't compile. 😆 😅 I think a chainable "stdin" function like this where I can just pass in a string would be a nice API, at least for "Confirm". let output = Command::cargo_bin("mybin")
.unwrap()
.current_dir(temp_dir.path())
.stdin("yes\n") // Mock the user input
.stdin(Stdio::piped("foo"))
.assert()
.success();
assert_eq!(output, "You said yes!"); Unfortunately though, this "stdin" function doesn't take a string or string slice... here is my compiler error:
I also tried using this strange and imo very ugly syntax, but I am still getting a compile error, "no method names use std::io::{Read, Write};
use std::process::{Command, Stdio};
...
let mut child_process = Command::new("mybin")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
// Send input to the child process
let input_data = "hello world\n";
child_process
.stdin
.as_mut()
.unwrap()
.write_all(input_data.as_bytes())
.unwrap();
// Read output from the child process
let mut output_data = String::new();
child_process
.stdout
.as_mut()
.unwrap()
.read_to_string(&mut output_data)
.unwrap();
// Wait for the child process to exit
let exit_status = child_process.wait().unwrap(); |
If anyone finds it helpful, I had some basic success with using https://github.com/rust-cli/rexpect to test |
That is indeed really helpful, I found the project where you're doing that (cargo-wizard right? really awesome btw)! Will take some inspiration from it when I find the time: https://github.com/Kobzol/cargo-wizard/blob/main/tests/integration/utils/terminal.rs |
@JimLynchCodes #[test]
fn om_init() -> anyhow::Result<()> {
let temp_dir = assert_fs::TempDir::new().unwrap();
om()?
.arg("init")
.arg(temp_dir.path())
.write_stdin("\n\n")
.assert()
.success();
temp_dir.close().unwrap();
Ok(())
} However, this crashes at runtime (during
|
This will allow both we and our users to make the prompts fully testable.
It will heavily rely on #70
The text was updated successfully, but these errors were encountered: