weavatrix-graph 0.6.2

Deterministic, evidence-carrying graph core for Weavatrix repository intelligence
Documentation
use std::collections::BTreeSet;
use std::fs;
use std::path::{Path, PathBuf};
use weavatrix_graph::{EdgeKind, EvidenceKind, NodeKind};

#[test]
fn rust_sources_stay_small_and_focused() {
    let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let mut sources = Vec::new();
    collect_rust_sources(&root, &mut sources);

    for path in sources {
        let lines = fs::read_to_string(&path).unwrap().lines().count();
        assert!(
            lines <= 300,
            "{} has {lines} lines; split files before they become monoliths",
            path.strip_prefix(&root).unwrap().display()
        );
    }
}

#[test]
fn foundation_modules_use_facades_with_focused_leaf_files() {
    let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    assert_leaf_modules(
        &root,
        "src/model/mod.rs",
        "src/model",
        &["element.rs", "id.rs", "provenance.rs", "span.rs"],
    );
    assert_leaf_modules(
        &root,
        "src/kind/mod.rs",
        "src/kind",
        &["edge.rs", "evidence.rs", "node.rs", "string.rs"],
    );
    assert_leaf_modules(
        &root,
        "src/topology/mod.rs",
        "src/topology",
        &[
            "core.rs",
            "csr/mod.rs",
            "index.rs",
            "parallel.rs",
            "view.rs",
        ],
    );
    assert_leaf_modules(
        &root,
        "src/traversal_cache/mod.rs",
        "src/traversal_cache",
        &[
            "adaptive.rs",
            "build.rs",
            "core.rs",
            "eager.rs",
            "elias_fano.rs",
            "ergonomics.rs",
            "iter.rs",
            "packed.rs",
            "parallel.rs",
            "walk.rs",
        ],
    );
    assert_leaf_modules(
        &root,
        "src/graph/mod.rs",
        "src/graph",
        &[
            "builder.rs",
            "bulk.rs",
            "core.rs",
            "index.rs",
            "validate.rs",
        ],
    );
    assert_leaf_modules(
        &root,
        "src/working/mod.rs",
        "src/working",
        &["core.rs", "freeze.rs", "key.rs", "mutate.rs", "view.rs"],
    );
}

#[test]
fn behavior_modules_use_facades_with_focused_leaf_files() {
    let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    assert_leaf_modules(
        &root,
        "src/algo/mod.rs",
        "src/algo",
        &[
            "astar.rs",
            "bellman.rs",
            "components/mod.rs",
            "dominators.rs",
            "flow/mod.rs",
            "mst.rs",
            "rank.rs",
            "shortest.rs",
            "transitive.rs",
            "traversal.rs",
        ],
    );
    assert_leaf_modules(
        &root,
        "src/algo/flow/mod.rs",
        "src/algo/flow",
        &["core.rs", "cut.rs"],
    );
    assert_leaf_modules(
        &root,
        "src/algo/components/mod.rs",
        "src/algo/components",
        &["condensation.rs", "dag.rs", "scc.rs", "weak.rs"],
    );
    assert_leaf_modules(
        &root,
        "src/undirected/mod.rs",
        "src/undirected",
        &["core.rs", "view.rs"],
    );
    assert_leaf_modules(&root, "src/matrix/mod.rs", "src/matrix", &["dense.rs"]);
    assert_leaf_modules(
        &root,
        "src/generator/mod.rs",
        "src/generator",
        &["deterministic.rs", "random.rs"],
    );
}

#[test]
fn module_layout_uses_one_source_form() {
    let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let mut sources = Vec::new();
    collect_rust_sources(&root, &mut sources);

    for path in sources {
        if path.file_name().is_some_and(|name| name == "mod.rs") {
            continue;
        }
        let sibling_module = path.with_extension("");
        assert!(
            !sibling_module.is_dir(),
            "{} has both foo.rs and foo/ module forms",
            path.strip_prefix(&root).unwrap().display()
        );
    }
}

#[test]
fn dependency_declarations_are_not_duplicated() {
    let manifest =
        fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml")).unwrap();

    for section in ["dependencies", "dev-dependencies"] {
        let names = dependency_names(&manifest, section);
        let unique = names.iter().collect::<BTreeSet<_>>();
        assert_eq!(
            names.len(),
            unique.len(),
            "[{section}] contains duplicate package declarations"
        );
    }
}

#[test]
fn canonical_kind_strings_are_unique_within_each_contract() {
    let node_kinds = [
        NodeKind::Repository,
        NodeKind::File,
        NodeKind::Module,
        NodeKind::Package,
        NodeKind::Function,
        NodeKind::Method,
        NodeKind::Struct,
        NodeKind::Enum,
        NodeKind::Trait,
        NodeKind::TypeAlias,
        NodeKind::Constant,
        NodeKind::Static,
        NodeKind::Service,
        NodeKind::Endpoint,
        NodeKind::Table,
        NodeKind::Column,
        NodeKind::Topic,
        NodeKind::ConsumerGroup,
        NodeKind::Exchange,
        NodeKind::Queue,
        NodeKind::Binding,
        NodeKind::Collection,
        NodeKind::Index,
        NodeKind::KubernetesResource,
        NodeKind::Container,
        NodeKind::ConfigKey,
        NodeKind::Unknown,
    ];
    let edge_kinds = [
        EdgeKind::Contains,
        EdgeKind::Imports,
        EdgeKind::Calls,
        EdgeKind::References,
        EdgeKind::Method,
        EdgeKind::Implements,
        EdgeKind::ReExports,
        EdgeKind::DependsOn,
        EdgeKind::Inherits,
        EdgeKind::Publishes,
        EdgeKind::Consumes,
        EdgeKind::Binds,
        EdgeKind::Reads,
        EdgeKind::Writes,
        EdgeKind::Deploys,
        EdgeKind::Exposes,
        EdgeKind::Mounts,
        EdgeKind::Configures,
    ];
    let evidence_kinds = [
        EvidenceKind::ExactLsp,
        EvidenceKind::Extracted,
        EvidenceKind::ResolvedCanonical,
        EvidenceKind::Inferred,
        EvidenceKind::Conflict,
        EvidenceKind::Parsed,
        EvidenceKind::Resolved,
        EvidenceKind::Manifest,
        EvidenceKind::Literal,
        EvidenceKind::Toolchain,
        EvidenceKind::Runtime,
    ];

    assert_unique("node", node_kinds.iter().map(NodeKind::as_str));
    assert_unique("edge", edge_kinds.iter().map(EdgeKind::as_str));
    assert_unique("evidence", evidence_kinds.iter().map(EvidenceKind::as_str));
}

fn assert_leaf_modules(root: &Path, facade: &str, directory: &str, leaves: &[&str]) {
    let facade_lines = fs::read_to_string(root.join(facade))
        .unwrap()
        .lines()
        .count();
    assert!(
        facade_lines <= 40,
        "{facade} should stay a small re-export facade, not hold domain logic"
    );
    for leaf in leaves {
        assert!(
            root.join(directory).join(leaf).is_file(),
            "{directory}/{leaf} is required by the module layout"
        );
    }
}

fn assert_unique<'value>(contract: &str, values: impl IntoIterator<Item = &'value str>) {
    let values = values.into_iter().collect::<Vec<_>>();
    let unique = values.iter().collect::<BTreeSet<_>>();
    assert_eq!(
        values.len(),
        unique.len(),
        "{contract} kind contract contains duplicate wire values"
    );
}

fn dependency_names(manifest: &str, section: &str) -> Vec<String> {
    manifest
        .split(&format!("[{section}]"))
        .nth(1)
        .unwrap_or_default()
        .split('[')
        .next()
        .unwrap_or_default()
        .lines()
        .map(str::trim)
        .filter(|line| !line.is_empty() && !line.starts_with('#'))
        .filter_map(|line| line.split_once('=').map(|(name, _)| name.trim().to_owned()))
        .collect()
}

fn collect_rust_sources(directory: &Path, output: &mut Vec<PathBuf>) {
    if directory.ends_with("target") || directory.ends_with(".git") {
        return;
    }
    let mut entries = fs::read_dir(directory)
        .unwrap()
        .collect::<std::io::Result<Vec<_>>>()
        .unwrap();
    entries.sort_by_key(std::fs::DirEntry::file_name);
    for entry in entries {
        let path = entry.path();
        if path.is_dir() {
            collect_rust_sources(&path, output);
        } else if path.extension().is_some_and(|extension| extension == "rs") {
            output.push(path);
        }
    }
}