use bashkit::{Bash, FileSystem, InMemoryFs};
use std::path::Path;
use std::sync::Arc;
#[tokio::test]
async fn live_mount_makes_files_visible() {
let mut bash = Bash::new();
let data_fs = Arc::new(InMemoryFs::new());
data_fs
.write_file(Path::new("/hello.txt"), b"world")
.await
.unwrap();
bash.mount("/mnt/data", data_fs).unwrap();
let result = bash.exec("cat /mnt/data/hello.txt").await.unwrap();
assert_eq!(result.stdout, "world");
}
#[tokio::test]
async fn live_unmount_removes_files() {
let mut bash = Bash::new();
let tmp_fs = Arc::new(InMemoryFs::new());
tmp_fs
.write_file(Path::new("/file.txt"), b"temp")
.await
.unwrap();
bash.mount("/scratch", tmp_fs).unwrap();
let result = bash.exec("cat /scratch/file.txt").await.unwrap();
assert_eq!(result.stdout, "temp");
bash.unmount("/scratch").unwrap();
let result = bash.exec("cat /scratch/file.txt 2>&1").await.unwrap();
assert_ne!(result.exit_code, 0);
}
#[tokio::test]
async fn live_mount_preserves_shell_state() {
let mut bash = Bash::new();
bash.exec("export MY_VAR=preserved").await.unwrap();
bash.exec("cd /tmp").await.unwrap();
let data_fs = Arc::new(InMemoryFs::new());
data_fs
.write_file(Path::new("/data.txt"), b"content")
.await
.unwrap();
bash.mount("/mnt/data", data_fs).unwrap();
let result = bash.exec("echo $MY_VAR").await.unwrap();
assert_eq!(result.stdout, "preserved\n");
let result = bash.exec("pwd").await.unwrap();
assert_eq!(result.stdout, "/tmp\n");
let result = bash.exec("cat /mnt/data/data.txt").await.unwrap();
assert_eq!(result.stdout, "content");
}
#[tokio::test]
async fn live_mount_works_with_builder() {
let mut bash = Bash::builder()
.mount_text("/config/app.conf", "debug=true\n")
.env("HOME", "/home/user")
.build();
let result = bash.exec("cat /config/app.conf").await.unwrap();
assert_eq!(result.stdout, "debug=true\n");
let plugin_fs = Arc::new(InMemoryFs::new());
plugin_fs
.write_file(Path::new("/init.sh"), b"echo plugin loaded")
.await
.unwrap();
bash.mount("/plugins", plugin_fs).unwrap();
let result = bash.exec("cat /plugins/init.sh").await.unwrap();
assert_eq!(result.stdout, "echo plugin loaded");
let result = bash.exec("echo $HOME").await.unwrap();
assert_eq!(result.stdout, "/home/user\n");
}
#[tokio::test]
async fn unmount_nonexistent_returns_error() {
let bash = Bash::new();
assert!(bash.unmount("/nonexistent").is_err());
}
#[tokio::test]
async fn multiple_live_mounts() {
let mut bash = Bash::new();
let fs_a = Arc::new(InMemoryFs::new());
fs_a.write_file(Path::new("/a.txt"), b"AAA").await.unwrap();
let fs_b = Arc::new(InMemoryFs::new());
fs_b.write_file(Path::new("/b.txt"), b"BBB").await.unwrap();
bash.mount("/mnt/a", fs_a).unwrap();
bash.mount("/mnt/b", fs_b).unwrap();
let result = bash.exec("cat /mnt/a/a.txt").await.unwrap();
assert_eq!(result.stdout, "AAA");
let result = bash.exec("cat /mnt/b/b.txt").await.unwrap();
assert_eq!(result.stdout, "BBB");
bash.unmount("/mnt/a").unwrap();
let result = bash.exec("cat /mnt/b/b.txt").await.unwrap();
assert_eq!(result.stdout, "BBB");
}
#[tokio::test]
async fn live_mount_replace() {
let mut bash = Bash::new();
let fs_v1 = Arc::new(InMemoryFs::new());
fs_v1
.write_file(Path::new("/version"), b"v1")
.await
.unwrap();
let fs_v2 = Arc::new(InMemoryFs::new());
fs_v2
.write_file(Path::new("/version"), b"v2")
.await
.unwrap();
bash.mount("/app", fs_v1).unwrap();
let result = bash.exec("cat /app/version").await.unwrap();
assert_eq!(result.stdout, "v1");
bash.mount("/app", fs_v2).unwrap();
let result = bash.exec("cat /app/version").await.unwrap();
assert_eq!(result.stdout, "v2");
}