#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
use super::*;
use tempfile::TempDir;
#[test]
fn test_INSTALLER_001_init_creates_directory() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
let result = init_project(&project_path, None);
assert!(result.is_ok(), "Failed to initialize project: {:?}", result);
assert!(project_path.exists(), "Project directory was not created");
assert!(project_path.is_dir(), "Project path is not a directory");
}
#[test]
fn test_INSTALLER_001_init_creates_installer_toml() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
init_project(&project_path, None).unwrap();
let installer_toml = project_path.join("installer.toml");
assert!(installer_toml.exists(), "installer.toml was not created");
let content = std::fs::read_to_string(&installer_toml).unwrap();
assert!(
content.contains("[installer]"),
"Missing [installer] section"
);
assert!(
content.contains("name = \"test-installer\""),
"Missing name field"
);
}
#[test]
fn test_INSTALLER_001_init_creates_tests_directory() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
init_project(&project_path, None).unwrap();
let tests_dir = project_path.join("tests");
assert!(tests_dir.exists(), "tests/ directory was not created");
assert!(tests_dir.is_dir(), "tests path is not a directory");
let mod_rs = tests_dir.join("mod.rs");
assert!(mod_rs.exists(), "tests/mod.rs was not created");
let falsification_rs = tests_dir.join("falsification.rs");
assert!(
falsification_rs.exists(),
"tests/falsification.rs was not created"
);
}
#[test]
fn test_INSTALLER_001_init_creates_templates_directory() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
init_project(&project_path, None).unwrap();
let templates_dir = project_path.join("templates");
assert!(
templates_dir.exists(),
"templates/ directory was not created"
);
}
#[test]
fn test_INSTALLER_001_init_with_description() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
let result = init_project(&project_path, Some("My custom description")).unwrap();
assert_eq!(
result.description,
Some("My custom description".to_string())
);
let content = std::fs::read_to_string(project_path.join("installer.toml")).unwrap();
assert!(
content.contains("My custom description"),
"Description not in TOML"
);
}
#[test]
fn test_INSTALLER_001_init_returns_project_info() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("my-project");
let project = init_project(&project_path, None).unwrap();
assert_eq!(project.name, "my-project");
assert_eq!(project.path, project_path);
}
#[test]
fn test_INSTALLER_001_init_rejects_root_path() {
use std::path::Path;
let root_path = Path::new("/");
let result = init_project(root_path, None);
let _ = result;
}
#[test]
fn test_INSTALLER_002_validate_valid_installer() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("valid-installer");
init_project(&project_path, None).unwrap();
let result = validate_installer(&project_path);
assert!(
result.is_ok(),
"Valid installer should pass validation: {:?}",
result
);
let validation = result.unwrap();
assert!(validation.valid, "Validation should report valid=true");
}
#[test]
fn test_INSTALLER_002_validate_missing_installer_toml() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("empty-dir");
std::fs::create_dir_all(&project_path).unwrap();
let result = validate_installer(&project_path);
assert!(
result.is_err(),
"Should fail when installer.toml is missing"
);
let err = result.unwrap_err().to_string();
assert!(
err.contains("not found"),
"Error should mention file not found"
);
}
#[test]
fn test_INSTALLER_002_validate_invalid_toml() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("invalid-installer");
std::fs::create_dir_all(&project_path).unwrap();
std::fs::write(project_path.join("installer.toml"), "INVALID [[[").unwrap();
let result = validate_installer(&project_path);
assert!(result.is_err(), "Should fail on invalid TOML");
}
#[test]
fn test_INSTALLER_002_validate_counts_steps() {
let temp_dir = TempDir::new().unwrap();
let installer_toml = temp_dir.path().join("installer.toml");
let content = r#"
[installer]
name = "test"
version = "1.0.0"
[[step]]
id = "step1"
name = "Step 1"
action = "script"
[[step]]
id = "step2"
name = "Step 2"
action = "script"
"#;
std::fs::write(&installer_toml, content).unwrap();
let result = validate_installer(temp_dir.path()).unwrap();
assert_eq!(result.steps, 2, "Should count 2 steps");
}
#[test]
fn test_INSTALLER_002_validate_counts_artifacts() {
let temp_dir = TempDir::new().unwrap();
let installer_toml = temp_dir.path().join("installer.toml");
let content = r#"
[installer]
name = "test"
version = "1.0.0"
[[artifact]]
id = "artifact1"
url = "https://example.com/file1.tar.gz"
[[artifact]]
id = "artifact2"
url = "https://example.com/file2.tar.gz"
"#;
std::fs::write(&installer_toml, content).unwrap();
let result = validate_installer(temp_dir.path()).unwrap();
assert_eq!(result.artifacts, 2, "Should count 2 artifacts");
}
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn prop_valid_project_name_creates_directory(name in "[a-z][a-z0-9_-]{0,20}") {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join(&name);
let result = init_project(&project_path, None);
prop_assert!(result.is_ok(), "Failed for name: {}", name);
prop_assert!(project_path.exists());
}
#[test]
fn prop_generated_toml_is_valid(name in "[a-z][a-z0-9_-]{0,20}") {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join(&name);
init_project(&project_path, None).unwrap();
let content = std::fs::read_to_string(project_path.join("installer.toml")).unwrap();
let parsed: std::result::Result<InstallerSpec, _> = toml::from_str(&content);
prop_assert!(parsed.is_ok(), "Generated TOML is invalid: {:?}", parsed);
}
#[test]
fn prop_validation_is_idempotent(name in "[a-z][a-z0-9_-]{0,20}") {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join(&name);
init_project(&project_path, None).unwrap();
let result1 = validate_installer(&project_path);
let result2 = validate_installer(&project_path);
prop_assert!(result1.is_ok() == result2.is_ok());
if let (Ok(v1), Ok(v2)) = (result1, result2) {
prop_assert_eq!(v1.valid, v2.valid);
prop_assert_eq!(v1.steps, v2.steps);
prop_assert_eq!(v1.artifacts, v2.artifacts);
}
}
}
}
#[test]
fn test_INSTALLER_006_init_returns_project_info() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("my-app");
let result = init_project(&project_path, Some("Test description")).unwrap();
assert_eq!(result.name, "my-app");
assert_eq!(result.path, project_path);
assert_eq!(result.description, Some("Test description".to_string()));
}
#[test]
fn test_INSTALLER_006_validate_nonexistent_path() {
let result = validate_installer(std::path::Path::new("/nonexistent/path/to/installer"));
assert!(result.is_err());
}
#[test]
fn test_INSTALLER_006_validate_file_directly() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
init_project(&project_path, None).unwrap();
let result = validate_installer(&project_path.join("installer.toml"));
assert!(result.is_ok());
}
#[test]
fn test_INSTALLER_006_validation_result_fields() {
let temp_dir = TempDir::new().unwrap();
let project_path = temp_dir.path().join("test-installer");
init_project(&project_path, None).unwrap();
let result = validate_installer(&project_path).unwrap();
assert!(result.valid);
assert_eq!(result.steps, 1); assert!(result.warnings.is_empty());
assert!(result.errors.is_empty());
}
#[test]
fn test_INSTALLER_006_generate_installer_toml_content() {
let toml = generate_installer_toml("my-app", Some("My app description"));
assert!(toml.contains("name = \"my-app\""));
assert!(toml.contains("description = \"My app description\""));
assert!(toml.contains("[installer]"));
assert!(toml.contains("[[step]]"));
}
#[test]
fn test_INSTALLER_006_generate_installer_toml_default_description() {
let toml = generate_installer_toml("my-app", None);
assert!(toml.contains("name = \"my-app\""));
assert!(toml.contains("TDD-first installer"));
}
#[test]
fn test_INSTALLER_006_generate_test_mod_content() {
let content = generate_test_mod("my-app");
assert!(content.contains("Test module for my-app"));
assert!(content.contains("mod falsification"));
assert!(content.contains("EXTREME TDD"));
}
#[test]
fn test_INSTALLER_006_generate_falsification_tests_content() {
let content = generate_falsification_tests("my-app");
assert!(content.contains("Falsification tests for my-app"));
assert!(content.contains("Karl Popper"));
assert!(content.contains("falsify_step_idempotency"));
assert!(content.contains("falsify_dry_run_accuracy"));
assert!(content.contains("falsify_rollback_completeness"));
}