#[cfg(test)]
mod pack_test_template {
use crate::packs::Severity;
use crate::packs::test_helpers::*;
use crate::packs::core::git as example_pack;
#[test]
fn test_pack_creation() {
let pack = example_pack::create_pack();
validate_pack(&pack);
}
#[test]
fn test_destructive_reset_hard_basic() {
let pack = example_pack::create_pack();
assert_blocks(&pack, "git reset --hard", "destroys uncommitted changes");
}
#[test]
fn test_destructive_reset_hard_with_ref() {
let pack = example_pack::create_pack();
assert_blocks(&pack, "git reset --hard HEAD", "destroys uncommitted");
assert_blocks(&pack, "git reset --hard HEAD~1", "destroys uncommitted");
assert_blocks(
&pack,
"git reset --hard origin/main",
"destroys uncommitted",
);
assert_blocks(&pack, "git reset --hard abc123", "destroys uncommitted");
}
#[test]
fn test_destructive_reset_hard_severity() {
let pack = example_pack::create_pack();
assert_blocks_with_severity(&pack, "git reset --hard", Severity::Critical);
}
#[test]
fn test_destructive_reset_hard_pattern_name() {
let pack = example_pack::create_pack();
assert_blocks_with_pattern(&pack, "git reset --hard", "reset-hard");
}
#[test]
fn test_destructive_push_force_variations() {
let pack = example_pack::create_pack();
assert_blocks(&pack, "git push --force", "destroy remote history");
assert_blocks(
&pack,
"git push origin main --force",
"destroy remote history",
);
assert_blocks(
&pack,
"git push --force origin main",
"destroy remote history",
);
assert_blocks(&pack, "git push -f", "destroy remote history");
assert_blocks(&pack, "git push origin main -f", "destroy remote history");
}
#[test]
fn test_safe_checkout_new_branch() {
let pack = example_pack::create_pack();
assert_safe_pattern_matches(&pack, "git checkout -b feature");
assert_safe_pattern_matches(&pack, "git checkout -b feature/new-thing");
assert_safe_pattern_matches(&pack, "git checkout -b fix-123");
}
#[test]
fn test_safe_restore_staged() {
let pack = example_pack::create_pack();
assert_allows(&pack, "git restore --staged file.txt");
assert_allows(&pack, "git restore -S file.txt");
}
#[test]
fn test_safe_clean_dry_run() {
let pack = example_pack::create_pack();
assert_allows(&pack, "git clean -n");
assert_allows(&pack, "git clean -dn");
assert_allows(&pack, "git clean --dry-run");
}
#[test]
fn test_edge_case_extra_whitespace() {
let pack = example_pack::create_pack();
assert_blocks(&pack, "git reset --hard", "destroys uncommitted");
assert_blocks(&pack, "git push --force", "destroy remote history");
}
#[test]
fn test_edge_case_minimal_commands() {
let pack = example_pack::create_pack();
assert_no_match(&pack, "");
assert_no_match(&pack, "git");
}
#[test]
fn test_edge_case_quoted_arguments() {
let pack = example_pack::create_pack();
assert_blocks(&pack, "git reset --hard \"HEAD\"", "destroys uncommitted");
}
#[test]
fn test_edge_case_special_characters() {
let pack = example_pack::create_pack();
assert_blocks(
&pack,
"git push --force origin feature/my-branch",
"destroy remote",
);
assert_blocks(
&pack,
"git push --force origin bugfix/issue#123",
"destroy remote",
);
}
#[test]
fn test_specificity_unrelated_commands() {
let pack = example_pack::create_pack();
assert_no_match(&pack, "ls -la");
assert_no_match(&pack, "cat file.txt");
assert_no_match(&pack, "cargo build");
assert_no_match(&pack, "npm install");
}
#[test]
fn test_specificity_safe_git_commands() {
let pack = example_pack::create_pack();
assert_allows(&pack, "git status");
assert_allows(&pack, "git log");
assert_allows(&pack, "git diff");
assert_allows(&pack, "git add .");
assert_allows(&pack, "git commit -m 'message'");
assert_allows(&pack, "git push"); assert_allows(&pack, "git pull");
assert_allows(&pack, "git fetch");
assert_allows(&pack, "git branch -d feature"); }
#[test]
fn test_specificity_substring_not_matched() {
let pack = example_pack::create_pack();
assert_no_match(&pack, "cat .gitignore");
assert_no_match(&pack, "echo digit");
assert_no_match(&pack, "legitimate command with git in path");
}
#[test]
fn test_severity_critical_patterns() {
let pack = example_pack::create_pack();
assert_blocks_with_severity(&pack, "git reset --hard", Severity::Critical);
assert_blocks_with_severity(&pack, "git clean -f", Severity::Critical);
assert_blocks_with_severity(&pack, "git push --force", Severity::Critical);
assert_blocks_with_severity(&pack, "git stash clear", Severity::Critical);
}
#[test]
fn test_severity_high_patterns() {
let pack = example_pack::create_pack();
assert_blocks_with_severity(&pack, "git checkout -- file.txt", Severity::High);
assert_blocks_with_severity(&pack, "git restore file.txt", Severity::High);
}
#[test]
fn test_severity_medium_patterns() {
let pack = example_pack::create_pack();
assert_blocks_with_severity(&pack, "git stash drop", Severity::Medium);
assert_blocks_with_severity(&pack, "git branch -D feature", Severity::Medium);
}
#[test]
fn test_performance_normal_commands() {
let pack = example_pack::create_pack();
assert_matches_within_budget(&pack, "git reset --hard");
assert_matches_within_budget(&pack, "git push --force origin main");
assert_matches_within_budget(&pack, "git checkout -b feature/new-thing");
}
#[test]
fn test_performance_pathological_inputs() {
let pack = example_pack::create_pack();
let long_flags = format!("git {}", "-".repeat(1000));
assert_matches_within_budget(&pack, &long_flags);
let many_spaces = format!("git{}{}", " ".repeat(100), "status");
assert_matches_within_budget(&pack, &many_spaces);
}
#[test]
fn test_batch_reset_variants() {
let pack = example_pack::create_pack();
let reset_commands = vec![
"git reset --hard",
"git reset --hard HEAD",
"git reset --hard HEAD~1",
"git reset --hard HEAD~10",
"git reset --hard origin/main",
"git reset --hard abc123def456",
];
test_batch_blocks(&pack, &reset_commands, "reset");
}
#[test]
fn test_batch_readonly_commands() {
let pack = example_pack::create_pack();
let readonly_commands = vec![
"git status",
"git log",
"git log --oneline",
"git diff",
"git diff --cached",
"git show HEAD",
"git branch",
"git branch -a",
"git remote -v",
];
test_batch_allows(&pack, &readonly_commands);
}
#[test]
fn test_logged_batch_execution() {
let pack = example_pack::create_pack();
let mut runner = LoggedPackTestRunner::debug(&pack);
runner.assert_blocks("git reset --hard", "destroys uncommitted");
runner.assert_blocks("git push --force", "destroy remote");
runner.assert_allows("git status");
runner.assert_allows("git log");
let report = runner.finish();
assert!(report.contains("core.git"));
assert!(report.contains("passed"));
}
}