#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
#![allow(non_snake_case)]
use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
fn bashrs_cmd() -> Command {
assert_cmd::cargo_bin_cmd!("bashrs")
}
#[test]
fn test_INSTALLER_CLI_001_init_creates_project() {
let temp_dir = TempDir::new().unwrap();
let project_name = "test-installer";
let project_path = temp_dir.path().join(project_name);
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success()
.stdout(predicate::str::contains("Initialized installer project"))
.stdout(predicate::str::contains("installer.toml"));
assert!(project_path.join("installer.toml").exists());
assert!(project_path.join("tests").exists());
assert!(project_path.join("tests").join("mod.rs").exists());
assert!(project_path.join("tests").join("falsification.rs").exists());
assert!(project_path.join("templates").exists());
}
#[test]
fn test_INSTALLER_CLI_001_init_with_description() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("my-project");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.arg("--description")
.arg("My custom installer")
.assert()
.success();
let content = fs::read_to_string(project_path.join("installer.toml")).unwrap();
assert!(content.contains("My custom installer"));
}
#[test]
fn test_INSTALLER_CLI_002_validate_valid_installer() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("valid-installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("validate")
.arg(&project_path)
.assert()
.success()
.stdout(predicate::str::contains("Installer is valid"));
}
#[test]
fn test_INSTALLER_CLI_002_validate_missing_installer() {
let temp_dir = TempDir::new().unwrap();
let nonexistent = temp_dir.path().join("nonexistent");
bashrs_cmd()
.arg("installer")
.arg("validate")
.arg(&nonexistent)
.assert()
.failure();
}
#[test]
fn test_INSTALLER_CLI_002_validate_invalid_toml() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path();
fs::write(project_path.join("installer.toml"), "INVALID [[[").unwrap();
bashrs_cmd()
.arg("installer")
.arg("validate")
.arg(project_path)
.assert()
.failure();
}
#[test]
fn test_INSTALLER_CLI_003_run_dry_run() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("run")
.arg(&project_path)
.arg("--dry-run")
.assert()
.success()
.stdout(predicate::str::contains("Dry-run mode"));
}
#[test]
fn test_INSTALLER_CLI_003_run_dry_run_diff() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("run")
.arg(&project_path)
.arg("--dry-run")
.arg("--diff")
.assert()
.success()
.stdout(predicate::str::contains("Dry-Run Diff Preview"));
}
#[test]
fn test_INSTALLER_CLI_004_graph_mermaid() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("graph")
.arg(&project_path)
.arg("--format")
.arg("mermaid")
.assert()
.success()
.stdout(predicate::str::contains("graph TD"));
}
#[test]
fn test_INSTALLER_CLI_004_graph_dot() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("graph")
.arg(&project_path)
.arg("--format")
.arg("dot")
.assert()
.success()
.stdout(predicate::str::contains("digraph InstallerGraph"));
}
#[test]
fn test_INSTALLER_CLI_004_graph_json() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("graph")
.arg(&project_path)
.arg("--format")
.arg("json")
.assert()
.success()
.stdout(predicate::str::contains("\"nodes\""));
}
#[test]
fn test_INSTALLER_CLI_005_lock_generate() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("lock")
.arg(&project_path)
.assert()
.success()
.stdout(predicate::str::contains("Managing lockfile"));
}
#[test]
fn test_INSTALLER_CLI_006_test_matrix() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("installer");
bashrs_cmd()
.arg("installer")
.arg("init")
.arg(&project_path)
.assert()
.success();
bashrs_cmd()
.arg("installer")
.arg("test")
.arg(&project_path)
.arg("--matrix")
.arg("ubuntu:22.04,debian:12")
.assert()
.success()
.stdout(predicate::str::contains("Container Test Matrix"))
.stdout(predicate::str::contains("ubuntu:22.04"))
.stdout(predicate::str::contains("debian:12"));
}
#[test]
fn test_INSTALLER_CLI_007_keyring_init() {
bashrs_cmd()
.arg("installer")
.arg("keyring")
.arg("init")
.assert()
.success()
.stdout(predicate::str::contains("Initialized keyring"));
}
#[test]
fn test_INSTALLER_CLI_007_keyring_list() {
bashrs_cmd()
.arg("installer")
.arg("keyring")
.arg("list")
.assert()
.success()
.stdout(predicate::str::contains("Keyring")); }
#[test]
fn test_INSTALLER_CLI_008_help_shows_subcommands() {
bashrs_cmd()
.arg("installer")
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("init"))
.stdout(predicate::str::contains("validate"))
.stdout(predicate::str::contains("run"))
.stdout(predicate::str::contains("test"))
.stdout(predicate::str::contains("graph"));
}
#[test]
fn test_INSTALLER_CLI_008_init_help() {
bashrs_cmd()
.arg("installer")
.arg("init")
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("TDD-first test harness"));
}
#[test]
fn test_INSTALLER_CLI_009_from_bash_converts_script() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("install.sh");
let output_path = temp_dir.path().join("my-installer");
fs::write(
&script_path,
r#"#!/bin/bash
apt-get update
apt-get install -y docker-ce nginx
mkdir -p /opt/myapp
"#,
)
.unwrap();
bashrs_cmd()
.arg("installer")
.arg("from-bash")
.arg(&script_path)
.arg("--output")
.arg(&output_path)
.assert()
.success()
.stdout(predicate::str::contains("Conversion complete"))
.stdout(predicate::str::contains("Steps generated"));
assert!(output_path.join("installer.toml").exists());
assert!(output_path.join("templates").exists());
let content = fs::read_to_string(output_path.join("installer.toml")).unwrap();
assert!(content.contains("[installer]"));
assert!(content.contains("[[step]]"));
}
#[test]
fn test_INSTALLER_CLI_009_from_bash_missing_file() {
let temp_dir = TempDir::new().unwrap();
let nonexistent = temp_dir.path().join("nonexistent.sh");
bashrs_cmd()
.arg("installer")
.arg("from-bash")
.arg(&nonexistent)
.assert()
.failure();
}
#[test]
fn test_INSTALLER_CLI_009_from_bash_default_output() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("docker-setup.sh");
fs::write(&script_path, "apt-get update").unwrap();
bashrs_cmd()
.current_dir(temp_dir.path())
.arg("installer")
.arg("from-bash")
.arg(&script_path)
.assert()
.success()
.stdout(predicate::str::contains("docker-setup-installer"));
}