use std::{fs, path::PathBuf};
use dotr_dear::{
cli::{DeployArgs, DiffArgs, ImportArgs, InitArgs, run_cli},
config::Config,
};
mod common;
const PLAYGROUND_DIR: &str = "tests/playground";
const NVIM_PATH: &str = "src/nvim/";
const BASHRC_PATH: &str = "src/.bashrc";
const TMUX_PATH: &str = "src/tmux/";
struct TestFixture {
cwd: PathBuf,
}
impl TestFixture {
fn new() -> Self {
let cwd = PathBuf::from(PLAYGROUND_DIR);
common::setup(&cwd);
Self { cwd }
}
fn get_cli(&self, command: Option<dotr_dear::cli::Command>) -> dotr_dear::cli::Cli {
dotr_dear::cli::Cli {
command,
working_dir: Some(PLAYGROUND_DIR.to_string()),
}
}
fn init(&self) {
run_cli(self.get_cli(Some(dotr_dear::cli::Command::Init(InitArgs {}))))
.expect("Init failed");
}
fn import(&self, path: &str) {
run_cli(
self.get_cli(Some(dotr_dear::cli::Command::Import(ImportArgs {
path: path.to_string(),
..Default::default()
}))),
)
.expect("Import failed");
}
fn deploy(&self, packages: Option<Vec<String>>) {
run_cli(
self.get_cli(Some(dotr_dear::cli::Command::Deploy(DeployArgs {
packages,
profile: None,
ignore_errors: false,
clean: false,
dry_run: false,
}))),
)
.expect("Deploy failed");
}
fn diff(&self, packages: Option<Vec<String>>) -> Result<(), anyhow::Error> {
run_cli(self.get_cli(Some(dotr_dear::cli::Command::Diff(DiffArgs {
packages,
profile: None,
ignore_errors: false,
}))))
}
#[allow(dead_code)]
fn get_config(&self) -> Config {
Config::from_path(&self.cwd).expect("Failed to load config")
}
fn write_file(&self, path: &str, content: &str) {
let file_path = self.cwd.join(path);
fs::write(file_path, content).unwrap_or_else(|_| panic!("Failed to write file: {}", path));
}
fn get_package_name(&self, path: &str) -> String {
let args = ImportArgs {
path: path.to_string(),
..Default::default()
};
dotr_dear::package::get_pkg_name_and_rel_path(&args, &self.cwd)
.unwrap()
.0
}
}
impl Drop for TestFixture {
fn drop(&mut self) {
common::teardown(&self.cwd);
}
}
#[test]
fn test_diff_no_changes() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Modified\n");
fixture.deploy(None);
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_with_changes() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Modified\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Modified again\nexport PATH=/test\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_specific_package() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.import(NVIM_PATH);
fixture.write_file("src/.bashrc", "# Bashrc modified\n");
fixture.write_file("src/nvim/init.lua", "-- Nvim modified\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Bashrc changed again\n");
let bashrc_name = fixture.get_package_name(BASHRC_PATH);
let result = fixture.diff(Some(vec![bashrc_name]));
assert!(result.is_ok());
}
#[test]
fn test_diff_multiple_specific_packages() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.import(NVIM_PATH);
fixture.write_file("src/.bashrc", "# Bashrc\n");
fixture.write_file("src/nvim/init.lua", "-- Nvim\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Bashrc changed\n");
fixture.write_file("src/nvim/init.lua", "-- Nvim changed\n");
let bashrc_name = fixture.get_package_name(BASHRC_PATH);
let nvim_name = fixture.get_package_name(NVIM_PATH);
let result = fixture.diff(Some(vec![bashrc_name, nvim_name]));
assert!(result.is_ok());
}
#[test]
fn test_diff_directory_package() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(TMUX_PATH);
fixture.write_file("src/tmux/tmux.conf", "# Tmux modified\n");
fixture.write_file("src/tmux/theme.conf", "# Theme modified\n");
fixture.deploy(None);
fixture.write_file("src/tmux/tmux.conf", "# Tmux changed again\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_all_files_in_directory_changed() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(TMUX_PATH);
fixture.write_file("src/tmux/tmux.conf", "# Tmux\n");
fixture.write_file("src/tmux/theme.conf", "# Theme\n");
fixture.deploy(None);
fixture.write_file("src/tmux/tmux.conf", "# Tmux changed\n");
fixture.write_file("src/tmux/theme.conf", "# Theme changed\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_nonexistent_package() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
let result = fixture.diff(Some(vec!["nonexistent_package".to_string()]));
assert!(
result.is_err(),
"Diff with nonexistent package should error"
);
assert!(
result.unwrap_err().to_string().contains("not found"),
"Error should mention package not found"
);
}
#[test]
fn test_diff_file_not_yet_deployed() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Modified but not deployed\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_after_multiple_changes() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Version 1\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Version 2\nexport PATH=/usr/bin\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_with_additions() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Line 1\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Line 1\n# Line 2\n# Line 3\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_with_deletions() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Line 1\n# Line 2\n# Line 3\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Line 1\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_with_modifications() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "# Original line\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Modified line\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_empty_file() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.write_file("src/.bashrc", "");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# New content\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}
#[test]
fn test_diff_all_packages() {
let fixture = TestFixture::new();
fixture.init();
fixture.import(BASHRC_PATH);
fixture.import(NVIM_PATH);
fixture.import(TMUX_PATH);
fixture.write_file("src/.bashrc", "# Bashrc\n");
fixture.write_file("src/nvim/init.lua", "-- Nvim\n");
fixture.write_file("src/tmux/tmux.conf", "# Tmux\n");
fixture.deploy(None);
fixture.write_file("src/.bashrc", "# Bashrc changed\n");
fixture.write_file("src/nvim/init.lua", "-- Nvim changed\n");
fixture.write_file("src/tmux/tmux.conf", "# Tmux changed\n");
let result = fixture.diff(None);
assert!(result.is_ok());
}