#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use crate::scaffold::config::AgentFramework;
use crate::scaffold::config::WasmFramework;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_generate_pforge_hook() {
let config = HookConfig {
project_type: TemplateType::Agent {
based_on: AgentFramework::Pforge,
},
quality_gates: QualityGateConfig::default(),
};
let script = generate_pre_commit_hook(&config).unwrap();
assert!(script.contains("#!/bin/bash"));
assert!(script.contains("cargo clippy"));
assert!(script.contains("cargo test"));
assert!(script.contains("pforge project"));
}
#[test]
fn test_generate_wasm_hook() {
let config = HookConfig {
project_type: TemplateType::Wasm {
based_on: WasmFramework::WasmLabs,
},
quality_gates: QualityGateConfig::default(),
};
let script = generate_pre_commit_hook(&config).unwrap();
assert!(script.contains("#!/bin/bash"));
assert!(script.contains("cargo clippy"));
assert!(script.contains("cargo test"));
assert!(script.contains("wasm32-unknown-unknown"));
assert!(script.contains("WASM project"));
}
#[test]
fn test_install_pre_commit_hook() {
let temp_dir = TempDir::new().unwrap();
let git_dir = temp_dir.path().join(".git/hooks");
fs::create_dir_all(&git_dir).unwrap();
let script = "#!/bin/bash\necho test";
install_pre_commit_hook(temp_dir.path(), script).unwrap();
let hook_path = git_dir.join("pre-commit");
assert!(hook_path.exists());
let content = fs::read_to_string(&hook_path).unwrap();
assert_eq!(content, script);
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = fs::metadata(&hook_path).unwrap().permissions();
assert!(perms.mode() & 0o111 != 0, "Hook should be executable");
}
}
#[test]
fn test_hook_script_format() {
let config = HookConfig {
project_type: TemplateType::Agent {
based_on: AgentFramework::Pforge,
},
quality_gates: QualityGateConfig::extreme_tdd(),
};
let script = generate_pre_commit_hook(&config).unwrap();
assert!(script.contains("All quality gates passed"));
assert!(script.contains("set -e")); }
#[test]
fn test_generate_post_commit_hook() {
let hook = generate_post_commit_hook();
assert!(hook.starts_with("#!/bin/bash"));
assert!(hook.contains("TICKET-PMAT-"));
assert!(hook.contains("pmat maintain update-roadmap"));
}
#[test]
fn test_install_post_commit_hook() {
let temp_dir = TempDir::new().unwrap();
let git_dir = temp_dir.path().join(".git/hooks");
fs::create_dir_all(&git_dir).unwrap();
install_post_commit_hook(temp_dir.path()).unwrap();
let hook_path = git_dir.join("post-commit");
assert!(hook_path.exists());
let content = fs::read_to_string(&hook_path).unwrap();
assert!(content.contains("#!/bin/bash"));
assert!(content.contains("TICKET-PMAT-"));
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = fs::metadata(&hook_path).unwrap().permissions();
assert!(perms.mode() & 0o111 != 0, "Hook should be executable");
}
}
#[test]
fn test_post_commit_hook_silent_failure() {
let hook = generate_post_commit_hook();
assert!(hook.contains("|| true"));
assert!(hook.contains("2>/dev/null"));
}
#[test]
fn test_generate_hook_with_gates_fast() {
let hook = generate_pre_commit_hook_with_gates_fast();
assert!(hook.starts_with("#!/bin/bash"));
assert!(hook.contains("TICKET-PMAT-5021"));
assert!(hook.contains("cargo clippy"));
assert!(hook.contains("cargo test"));
assert!(hook.contains("fast mode"));
assert!(hook.contains("--no-verify"));
}
#[test]
fn test_generate_gate_config_toml() {
let toml = generate_gate_config_toml();
assert!(toml.contains("run_clippy = true"));
assert!(toml.contains("min_coverage = 80.0"));
assert!(toml.contains("max_complexity = 10"));
assert!(toml.contains("[gates]"));
}
#[test]
fn test_install_gate_config() {
let temp_dir = TempDir::new().unwrap();
install_gate_config(temp_dir.path()).unwrap();
let config_path = temp_dir.path().join(".pmat-gates.toml");
assert!(config_path.exists());
let content = fs::read_to_string(&config_path).unwrap();
assert!(content.contains("run_clippy"));
assert!(content.contains("min_coverage"));
}
#[test]
fn test_install_all_hooks_with_gates() {
let temp_dir = TempDir::new().unwrap();
let git_dir = temp_dir.path().join(".git/hooks");
fs::create_dir_all(&git_dir).unwrap();
install_all_hooks_with_gates(temp_dir.path()).unwrap();
let pre_commit = git_dir.join("pre-commit");
assert!(pre_commit.exists());
let content = fs::read_to_string(&pre_commit).unwrap();
assert!(content.contains("fast mode"));
let post_commit = git_dir.join("post-commit");
assert!(post_commit.exists());
let config = temp_dir.path().join(".pmat-gates.toml");
assert!(config.exists());
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = fs::metadata(&pre_commit).unwrap().permissions();
assert!(perms.mode() & 0o111 != 0, "Pre-commit should be executable");
}
}
#[test]
fn test_hook_bypass_documentation() {
let hook = generate_pre_commit_hook_with_gates_fast();
assert!(hook.contains("--no-verify"));
assert!(hook.contains("To bypass:"));
}
#[test]
fn test_hook_execution_time_hint() {
let hook = generate_pre_commit_hook_with_gates_fast();
assert!(hook.contains("<30s") || hook.contains("fast"));
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use super::*;
use crate::scaffold::config::{AgentFramework, WasmFramework};
use proptest::prelude::*;
proptest! {
#[test]
fn prop_hooks_are_valid_bash(is_agent in any::<bool>()) {
let project_type = if is_agent {
TemplateType::Agent { based_on: AgentFramework::Pforge }
} else {
TemplateType::Wasm { based_on: WasmFramework::WasmLabs }
};
let config = HookConfig {
project_type,
quality_gates: QualityGateConfig::default(),
};
let script = generate_pre_commit_hook(&config).unwrap();
prop_assert!(script.starts_with("#!/bin/bash"));
prop_assert!(script.contains("set -e"));
prop_assert!(script.contains("exit 0"));
}
#[test]
fn prop_hooks_check_clippy_and_tests(is_agent in any::<bool>()) {
let project_type = if is_agent {
TemplateType::Agent { based_on: AgentFramework::Pforge }
} else {
TemplateType::Wasm { based_on: WasmFramework::WasmLabs }
};
let config = HookConfig {
project_type,
quality_gates: QualityGateConfig::default(),
};
let script = generate_pre_commit_hook(&config).unwrap();
prop_assert!(script.contains("cargo clippy"));
prop_assert!(script.contains("cargo test"));
}
}
#[test]
fn prop_wasm_hooks_verify_wasm_build() {
let config = HookConfig {
project_type: TemplateType::Wasm {
based_on: WasmFramework::WasmLabs,
},
quality_gates: QualityGateConfig::default(),
};
let script = generate_pre_commit_hook(&config).unwrap();
assert!(script.contains("wasm32-unknown-unknown"));
}
}