use super::*;
#[test]
fn extract_contract_stem_basic() {
let content = r#"#[contract("softmax-kernel-v1", equation = "softmax")]"#;
assert_eq!(
extract_contract_stem(content),
Some("softmax-kernel-v1".to_string())
);
}
#[test]
fn extract_contract_stem_with_yaml() {
let content = r#"contract("rmsnorm-kernel-v1.yaml", equation = "rmsnorm")"#;
assert_eq!(
extract_contract_stem(content),
Some("rmsnorm-kernel-v1".to_string())
);
}
#[test]
fn extract_equation_basic() {
let content = r#"#[contract("softmax-kernel-v1", equation = "softmax")]"#;
assert_eq!(extract_equation(content), Some("softmax".to_string()));
}
#[test]
fn extract_equation_missing() {
let content = r#"#[contract("softmax-kernel-v1")]"#;
assert_eq!(extract_equation(content), None);
}
#[test]
fn extract_patterns_kaizen() {
let patterns = extract_patterns("// KAIZEN-050: fused softmax backward");
assert_eq!(patterns, vec!["KAIZEN-050"]);
}
#[test]
fn extract_patterns_contract_id() {
let patterns = extract_patterns("// C-XENT-002: refs softmax-kernel-v1");
assert_eq!(patterns, vec!["C-XENT-002"]);
}
#[test]
fn extract_patterns_multiple() {
let patterns = extract_patterns("KAIZEN-050 and KAIZEN-051 and C-SM-001");
assert_eq!(patterns.len(), 3);
assert!(patterns.contains(&"KAIZEN-050".to_string()));
assert!(patterns.contains(&"KAIZEN-051".to_string()));
assert!(patterns.contains(&"C-SM-001".to_string()));
}
#[test]
fn extract_patterns_none() {
let patterns = extract_patterns("just regular code");
assert!(patterns.is_empty());
}
fn repo_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.canonicalize()
.unwrap()
}
fn has_sibling_repos() -> bool {
let root = repo_root();
let Some(parent) = root.parent() else {
return false;
};
["trueno", "bashrs", "forjar"]
.iter()
.any(|name| parent.join(name).exists())
}
fn siblings_have_history() -> bool {
let root = repo_root();
let parent = match root.parent() {
Some(p) => p,
None => return false,
};
let output = std::process::Command::new("git")
.args(["rev-list", "--count", "HEAD"])
.current_dir(parent.join("aprender"))
.output();
match output {
Ok(o) if o.status.success() => {
let count: usize = String::from_utf8_lossy(&o.stdout)
.trim()
.parse()
.unwrap_or(0);
count >= 10
}
_ => false,
}
}
#[test]
fn discover_real_sibling_projects() {
if !has_sibling_repos() { return; }
let root = repo_root();
let parent = root.parent().unwrap();
let projects = discover_projects(parent, &root);
let names: Vec<&str> = projects.iter().map(|p| p.name.as_str()).collect();
assert!(
!projects.is_empty(),
"Should discover sibling projects, found: {names:?}"
);
}
#[test]
fn build_cross_project_index() {
if !has_sibling_repos() { return; }
let index = CrossProjectIndex::build(&repo_root());
assert!(index.project_count() > 0, "Should discover projects");
assert!(
index.total_call_sites() > 0,
"Should find contract call sites"
);
}
#[test]
fn call_sites_for_known_contract() {
if !has_sibling_repos() { return; }
let index = CrossProjectIndex::build(&repo_root());
let _sites = index.call_sites_for("metrics-regression-v1");
}
#[test]
fn binding_refs_for_aprender() {
if !has_sibling_repos() { return; }
let index = CrossProjectIndex::build(&repo_root());
let refs = index.binding_refs_for("softmax-kernel-v1");
assert!(!refs.is_empty(), "Should find binding ref for softmax");
}
#[test]
fn kaizen_refs_in_trueno() {
if !has_sibling_repos() { return; }
let index = CrossProjectIndex::build(&repo_root());
let refs = index.kaizen_refs_for("KAIZEN-015");
assert!(!refs.is_empty(), "Should find KAIZEN-015 in trueno");
}
#[test]
fn parse_contract_annotation_line() {
let line = "/home/user/aprender/src/metrics/mod.rs:39:#[provable_contracts_macros::contract(\"metrics-regression-v1\", equation = \"r_squared\")]";
let project_path = Path::new("/home/user/aprender");
let site = parse_contract_annotation(line, "aprender", project_path).unwrap();
assert_eq!(site.contract_stem, "metrics-regression-v1");
assert_eq!(site.equation, Some("r_squared".to_string()));
assert_eq!(site.line, 39);
assert_eq!(site.project, "aprender");
}
#[test]
fn find_binding_path_real() {
if !has_sibling_repos() { return; }
let root = repo_root();
let aprender_dir = root.parent().unwrap().join("aprender");
let bp = find_binding_path(&aprender_dir, "aprender");
assert!(bp.is_some(), "Should find binding.yaml for aprender");
}
#[test]
fn call_sites_for_unknown_contract() {
let index = CrossProjectIndex::build(&repo_root());
let sites = index.call_sites_for("nonexistent-contract-v1");
assert!(sites.is_empty());
}
#[test]
fn cross_project_index_accessors() {
if !has_sibling_repos() { return; }
let index = CrossProjectIndex::build(&repo_root());
assert!(index.project_count() >= 4, "Should find aprender, trueno, entrenar, bashrs");
assert!(index.total_call_sites() > 5, "aprender has many contract annotations");
}
#[test]
fn commit_refs_discovered() {
if !has_sibling_repos() { return; }
if !siblings_have_history() { return; }
let index = CrossProjectIndex::build(&repo_root());
let total_commit_refs: usize = index.commit_refs.values().map(Vec::len).sum();
assert!(
total_commit_refs > 0,
"Should find commit refs across projects, found 0"
);
}
#[test]
fn commit_refs_for_unknown() {
let index = CrossProjectIndex::build(&repo_root());
let refs = index.commit_refs_for("NONEXISTENT-999");
assert!(refs.is_empty());
}
#[test]
fn build_with_extra_project() {
if !has_sibling_repos() { return; }
let root = repo_root();
let index = CrossProjectIndex::build_with_extra(&root, Some(Path::new("/tmp/nonexistent")));
assert!(index.project_count() > 0);
}
#[test]
fn build_with_extra_duplicate() {
let root = repo_root();
let aprender = root.parent().unwrap().join("aprender");
if aprender.exists() {
let index = CrossProjectIndex::build_with_extra(&root, Some(&aprender));
let aprender_count = index.projects.iter().filter(|p| p.name == "aprender").count();
assert_eq!(aprender_count, 1, "Should not duplicate aprender");
}
}