Skip to main content

callisto_cli/
tty.rs

1/// Returns `true` when stdin is a terminal (interactive), `false` otherwise
2/// (e.g. a pipe or redirected file -- the common CI case).
3///
4/// Centralizes the TTY check so `add` and `init` share one predicate
5/// instead of each duplicating `IsTerminal`. Thin wrapper over
6/// [`std::io::IsTerminal::is_terminal`], no state -- callers inject a
7/// `bool` test double rather than testing this directly, since the OS
8/// determines the trait's return value, not Rust code. Non-interactive-path
9/// coverage lives in `cli_tests.rs`'s `test_add_non_interactive_via_pipe`
10/// (pipes stdin, asserts `callisto add` skips the TTY wizard).
11pub fn is_interactive() -> bool {
12    use std::io::IsTerminal as _;
13    std::io::stdin().is_terminal()
14}
15
16#[cfg(test)]
17mod tests {
18    use super::*;
19
20    /// Verifies the function compiles and returns a `bool`. In a standard test
21    /// environment stdin is typically *not* a terminal (tests are invoked by
22    /// `cargo test`, which redirects stdin), so the expected value is `false`.
23    /// This test is deliberately lightweight: the real coverage is provided by
24    /// the binary-level integration test `test_add_non_interactive_via_pipe`.
25    #[test]
26    fn is_interactive_returns_bool_in_test_environment() {
27        // `cargo test` does not allocate a TTY for stdin, so this must be false.
28        let result = is_interactive();
29        assert!(
30            !result,
31            "is_interactive() should return false in a non-TTY test environment"
32        );
33    }
34}