use super::super::{MigrationContext, history};
use super::config_refs::update_config_file_references;
use super::*;
use std::fs;
use tempfile::TempDir;
fn create_test_context(dir: &TempDir) -> MigrationContext {
let repo_root = dir.path().to_path_buf();
let project_config_path = repo_root.join(".ralph/config.json");
MigrationContext {
repo_root,
project_config_path,
global_config_path: None,
resolved_config: crate::contracts::Config::default(),
migration_history: history::MigrationHistory::default(),
}
}
#[test]
fn apply_file_rename_copies_file() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
let source = dir.path().join(".ralph/queue.json");
fs::write(&source, "{\"version\": 1}").unwrap();
apply_file_rename(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc").unwrap();
assert!(source.exists());
assert!(dir.path().join(".ralph/queue.jsonc").exists());
let original_content = fs::read_to_string(&source).unwrap();
let new_content = fs::read_to_string(dir.path().join(".ralph/queue.jsonc")).unwrap();
assert_eq!(original_content, new_content);
}
#[test]
fn apply_file_rename_without_backup_removes_original() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
let source = dir.path().join(".ralph/queue.json");
fs::write(&source, "{\"version\": 1}").unwrap();
let opts = FileMigrationOptions {
keep_backup: false,
update_config: false,
};
apply_file_rename_with_options(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc", &opts).unwrap();
assert!(!source.exists());
assert!(dir.path().join(".ralph/queue.jsonc").exists());
}
#[test]
fn apply_file_rename_fails_if_source_missing() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
let result = apply_file_rename(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc");
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("does not exist"));
}
#[test]
fn apply_file_rename_fails_if_destination_exists() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(dir.path().join(".ralph/queue.json"), "{}").unwrap();
fs::write(dir.path().join(".ralph/queue.jsonc"), "{}").unwrap();
let result = apply_file_rename(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc");
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("already exists"));
}
#[test]
fn update_config_file_references_updates_queue_file() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(
&ctx.project_config_path,
r#"{
"version": 1,
"queue": {
"file": ".ralph/queue.json"
}
}"#,
)
.unwrap();
update_config_file_references(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc").unwrap();
let content = fs::read_to_string(&ctx.project_config_path).unwrap();
assert!(content.contains("\"file\": \".ralph/queue.jsonc\""));
assert!(!content.contains("\"file\": \".ralph/queue.json\""));
}
#[test]
fn update_config_file_references_updates_done_file() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(
&ctx.project_config_path,
r#"{
"version": 1,
"queue": {
"done_file": ".ralph/done.json"
}
}"#,
)
.unwrap();
update_config_file_references(&ctx, ".ralph/done.json", ".ralph/done.jsonc").unwrap();
let content = fs::read_to_string(&ctx.project_config_path).unwrap();
assert!(content.contains("\"done_file\": \".ralph/done.jsonc\""));
}
#[test]
fn is_queue_json_to_jsonc_applicable_detects_correct_state() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
assert!(!is_queue_json_to_jsonc_applicable(&ctx));
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(dir.path().join(".ralph/queue.json"), "{}").unwrap();
assert!(is_queue_json_to_jsonc_applicable(&ctx));
fs::write(dir.path().join(".ralph/queue.jsonc"), "{}").unwrap();
assert!(is_queue_json_to_jsonc_applicable(&ctx));
}
#[test]
fn migrate_queue_json_to_jsonc_removes_legacy_file_when_jsonc_absent() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(dir.path().join(".ralph/queue.json"), "{\"version\": 1}").unwrap();
migrate_queue_json_to_jsonc(&ctx).unwrap();
assert!(!dir.path().join(".ralph/queue.json").exists());
assert!(dir.path().join(".ralph/queue.jsonc").exists());
}
#[test]
fn migrate_queue_json_to_jsonc_removes_legacy_file_when_jsonc_already_exists() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(dir.path().join(".ralph/queue.json"), "{\"legacy\": true}").unwrap();
fs::write(dir.path().join(".ralph/queue.jsonc"), "{\"version\": 1}").unwrap();
migrate_queue_json_to_jsonc(&ctx).unwrap();
assert!(!dir.path().join(".ralph/queue.json").exists());
assert!(dir.path().join(".ralph/queue.jsonc").exists());
}
#[test]
fn rollback_file_migration_restores_original() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
fs::create_dir_all(dir.path().join(".ralph")).unwrap();
fs::write(dir.path().join(".ralph/queue.json"), "{\"version\": 1}").unwrap();
apply_file_rename(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc").unwrap();
assert!(dir.path().join(".ralph/queue.json").exists());
assert!(dir.path().join(".ralph/queue.jsonc").exists());
rollback_file_migration(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc").unwrap();
assert!(dir.path().join(".ralph/queue.json").exists());
assert!(!dir.path().join(".ralph/queue.jsonc").exists());
}
#[test]
fn rollback_fails_if_original_missing() {
let dir = TempDir::new().unwrap();
let ctx = create_test_context(&dir);
let result = rollback_file_migration(&ctx, ".ralph/queue.json", ".ralph/queue.jsonc");
assert!(result.is_err());
}