#![allow(deprecated)]
#![allow(clippy::unwrap_used)] #![allow(clippy::expect_used)]
#![allow(non_snake_case)]
use assert_cmd::Command;
use predicates::prelude::*;
fn bashrs_repl() -> Command {
let mut cmd = assert_cmd::cargo_bin_cmd!("bashrs");
cmd.arg("repl");
cmd
}
#[test]
fn test_REPL_003_002_repl_starts_and_quits() {
bashrs_repl()
.write_stdin("quit\n")
.assert()
.success()
.stdout(predicate::str::contains("bashrs REPL"))
.stdout(predicate::str::contains("Goodbye!"));
}
#[test]
fn test_REPL_003_002_repl_handles_empty_input() {
bashrs_repl()
.write_stdin("\n\nexit\n")
.assert()
.success()
.stdout(predicate::str::contains("bashrs REPL"));
}
#[test]
fn test_REPL_003_002_repl_handles_eof() {
bashrs_repl()
.write_stdin("") .assert()
.success()
.stdout(predicate::str::contains("bashrs REPL"))
.stdout(predicate::str::contains("EOF"));
}
#[test]
fn test_REPL_003_002_repl_shows_help() {
bashrs_repl()
.write_stdin("help\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("bashrs REPL v"))
.stdout(predicate::str::contains("OVERVIEW"))
.stdout(predicate::str::contains(":help commands"));
}
#[test]
fn test_REPL_003_002_repl_accepts_exit() {
bashrs_repl()
.write_stdin("exit\n")
.assert()
.success()
.stdout(predicate::str::contains("Goodbye!"));
}
#[test]
fn test_REPL_003_002_repl_debug_mode() {
let mut cmd = assert_cmd::cargo_bin_cmd!("bashrs");
cmd.arg("repl")
.arg("--debug")
.write_stdin("quit\n")
.assert()
.success()
.stdout(predicate::str::contains("bashrs REPL"));
}
#[test]
fn test_REPL_003_002_repl_custom_config() {
let mut cmd = assert_cmd::cargo_bin_cmd!("bashrs");
cmd.arg("repl")
.arg("--max-memory")
.arg("200")
.arg("--timeout")
.arg("60")
.arg("--max-depth")
.arg("200")
.write_stdin("quit\n")
.assert()
.success();
}
#[test]
fn test_REPL_003_002_repl_sandboxed() {
let mut cmd = assert_cmd::cargo_bin_cmd!("bashrs");
cmd.arg("repl")
.arg("--sandboxed")
.write_stdin("quit\n")
.assert()
.success()
.stdout(predicate::str::contains("bashrs REPL"));
}
#[test]
fn test_REPL_003_003_history_persistence() {
use std::fs;
use std::path::PathBuf;
let home = std::env::var("HOME")
.or_else(|_| std::env::var("USERPROFILE"))
.unwrap_or_else(|_| ".".to_string());
let history_path = PathBuf::from(home).join(".bashrs_history");
let _ = fs::remove_file(&history_path);
bashrs_repl().write_stdin("help\nexit\n").assert().success();
assert!(history_path.exists(), "History file should be created");
assert!(history_path.exists(), "History file should persist");
let _ = fs::remove_file(&history_path);
}
#[test]
#[ignore] fn test_REPL_003_003_multiple_commands() {
use std::fs;
use std::path::PathBuf;
let home = std::env::var("HOME")
.or_else(|_| std::env::var("USERPROFILE"))
.unwrap_or_else(|_| ".".to_string());
let history_path = PathBuf::from(home).join(".bashrs_history");
let _ = fs::remove_file(&history_path);
bashrs_repl()
.write_stdin("help\nhelp\nhelp\nquit\n")
.assert()
.success();
std::thread::sleep(std::time::Duration::from_millis(200));
if history_path.exists() {
let history_content = fs::read_to_string(&history_path).unwrap();
assert!(
!history_content.is_empty(),
"History should contain commands"
);
}
let _ = fs::remove_file(&history_path);
}
#[test]
fn test_REPL_003_004_shows_current_mode() {
bashrs_repl()
.write_stdin("quit\n")
.assert()
.success()
.stdout(predicate::str::contains("Current mode: normal"));
}
#[test]
fn test_REPL_003_004_mode_command_shows_modes() {
bashrs_repl()
.write_stdin(":mode\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Available modes"))
.stdout(predicate::str::contains("normal"))
.stdout(predicate::str::contains("purify"))
.stdout(predicate::str::contains("lint"))
.stdout(predicate::str::contains("debug"))
.stdout(predicate::str::contains("explain"));
}
#[test]
fn test_REPL_003_004_mode_switch_to_purify() {
bashrs_repl()
.write_stdin(":mode purify\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Switched to purify mode"));
}
#[test]
fn test_REPL_003_004_mode_switch_to_lint() {
bashrs_repl()
.write_stdin(":mode lint\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Switched to lint mode"));
}
#[test]
fn test_REPL_003_004_mode_switch_to_debug() {
bashrs_repl()
.write_stdin(":mode debug\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Switched to debug mode"));
}
#[test]
fn test_REPL_003_004_mode_switch_to_explain() {
bashrs_repl()
.write_stdin(":mode explain\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Switched to explain mode"));
}
#[test]
fn test_REPL_003_004_mode_invalid_shows_error() {
bashrs_repl()
.write_stdin(":mode invalid\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Error"))
.stdout(predicate::str::contains("Unknown mode"));
}
#[test]
fn test_REPL_003_004_mode_case_insensitive() {
bashrs_repl()
.write_stdin(":mode PURIFY\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Switched to purify mode"));
}
#[test]
fn test_REPL_003_004_multiple_mode_switches() {
bashrs_repl()
.write_stdin(":mode purify\n:mode lint\n:mode normal\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Switched to purify mode"))
.stdout(predicate::str::contains("Switched to lint mode"))
.stdout(predicate::str::contains("Switched to normal mode"));
}
#[test]
fn test_REPL_004_001_parse_simple_command_cli() {
bashrs_repl()
.write_stdin(":parse echo hello\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Parse successful"));
}
#[test]
fn test_REPL_004_001_parse_shows_ast() {
bashrs_repl()
.write_stdin(":parse ls -la\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("AST"))
.stdout(predicate::str::contains("Statements:"));
}
#[test]
fn test_REPL_004_001_parse_no_input_shows_usage() {
bashrs_repl()
.write_stdin(":parse\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Usage: :parse"));
}
#[test]
fn test_REPL_004_001_parse_invalid_syntax() {
bashrs_repl()
.write_stdin(":parse if then fi\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Syntax error"));
}
#[test]
fn test_REPL_004_001_help_shows_parse() {
bashrs_repl()
.write_stdin(":help commands\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains(":parse"))
.stdout(predicate::str::contains("Parse bash code"));
}
#[test]
fn test_REPL_005_001_purify_simple_command_cli() {
bashrs_repl()
.write_stdin(":purify mkdir /tmp/test\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Purification successful"));
}
#[test]
fn test_REPL_005_001_purify_shows_result() {
bashrs_repl()
.write_stdin(":purify echo hello\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Purification successful"));
}
#[test]
fn test_REPL_005_001_purify_no_input_shows_usage() {
bashrs_repl()
.write_stdin(":purify\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Usage: :purify"));
}
#[test]
fn test_REPL_005_001_help_shows_purify() {
bashrs_repl()
.write_stdin(":help commands\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains(":purify"))
.stdout(predicate::str::contains("Purify bash code"));
}
#[test]
fn test_REPL_006_001_lint_simple_command_cli() {
bashrs_repl()
.write_stdin(":lint echo hello\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("issue").or(predicate::str::contains("No issues")));
}
#[test]
fn test_REPL_006_001_lint_shows_diagnostics() {
bashrs_repl()
.write_stdin(":lint cat file.txt | grep pattern\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("issue").or(predicate::str::contains("No issues")));
}
#[test]
fn test_REPL_006_001_lint_no_input_shows_usage() {
bashrs_repl()
.write_stdin(":lint\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains("Usage: :lint"));
}
#[test]
fn test_REPL_006_001_help_shows_lint() {
bashrs_repl()
.write_stdin(":help commands\nquit\n")
.assert()
.success()
.stdout(predicate::str::contains(":lint"))
.stdout(predicate::str::contains("Lint bash code"));
}