capability-skeleton 0.1.0

A Rust library for managing and building complex hierarchical tree structures such as skill trees. Supports serialization, error handling, and deep tree metrics.
Documentation
// ---------------- [ File: capability-skeleton/src/edge_cases_assessment.rs ]
crate::ix!();

#[cfg(test)]
mod skeleton_measurement_edge_cases_assessment {
    use super::*;

    /// This helper builds a linear chain of `n` nodes, or caps at 255 if `n` is too large.
    fn make_linear_chain_skeleton(n: u16) -> Skeleton {
        let chain_len = if n > 255 { 255 } else { n };
        trace!("Constructing a linear chain of length={}", chain_len);

        let mut nodes = Vec::with_capacity(chain_len as usize);

        for i in 0..chain_len {
            let mut builder = SkeletonNodeBuilder::default()
                .id(i)
                .name(format!("node_{}", i))
                .original_key(format!("node_{}", i));
            // If not the last => add next child
            if i < chain_len - 1 {
                builder = builder.child_ids(vec![i+1]);
            }
            // if child_ids is empty => LeafHolder, else => Dispatch
            let kind = if i < chain_len - 1 {
                NodeKind::Dispatch
            } else {
                NodeKind::LeafHolder
            };
            let node = builder.build(kind).expect("build node");
            nodes.push(node);
        }

        SkeletonBuilder::default()
            .nodes(nodes)
            .root_id(Some(0_u16))
            .build()
            .expect("build skeleton")
    }

    fn make_uniform_branching_skeleton(node_count: u16, each_child_count: u8) -> Skeleton {
        trace!(
            "Constructing a skeleton with {} nodes, each having {} children (where possible).",
            node_count,
            each_child_count
        );
        let mut nodes = Vec::new();
        for i in 0..node_count {
            let mut child_ids = Vec::new();
            let base_child_id = (i + 1) * 100;
            for c in 0..each_child_count {
                child_ids.push(base_child_id + c as u16);
            }
            let k = if child_ids.is_empty() {
                NodeKind::LeafHolder
            } else {
                NodeKind::Dispatch
            };
            let node = SkeletonNodeBuilder::default()
                .id(i)
                .child_ids(child_ids)
                .name(format!("branchyNode_{}", i))
                .original_key(format!("branchyNode_{}", i))
                .build(k)
                .expect("build node");
            nodes.push(node);
        }
        SkeletonBuilder::default()
            .nodes(nodes)
            .root_id(Some(0_u16))
            .build()
            .expect("build skeleton")
    }

    #[traced_test]
    fn depth_saturates_at_255() {
        let skel = make_linear_chain_skeleton(300);
        let depth = skel.measure_tree_depth();
        assert_eq!(depth, 255);
    }

    #[traced_test]
    fn uniform_branching_with_invalid_children() {
        let skel = make_uniform_branching_skeleton(10, 5);
        let stats = skel.measure_tree_weighted_branching();

        assert_eq!(*stats.total_nodes_in_tree(), 10);
        // each node had 5 child_ids => total=50 => min=5, max=5
        assert_eq!(*stats.min_child_count_in_tree(), 5);
        assert_eq!(*stats.max_child_count_in_tree(), 5);
        assert_eq!(*stats.total_child_count_in_tree(), 50);
        assert!((*stats.average_child_count_in_tree() - 5.0).abs() < f32::EPSILON);
    }

    #[traced_test]
    fn all_leaf_scenario_for_level_skipping() {
        // 5 nodes, each with no children => BFS sees only the root
        let mut nodes = Vec::new();
        for i in 0..5_u16 {
            // LeafHolder
            let node = SkeletonNodeBuilder::default()
                .id(i)
                .name(format!("leafOnly_{}", i))
                .original_key(format!("leafOnly_{}", i))
                .build(NodeKind::LeafHolder)
                .unwrap();
            nodes.push(node);
        }
        let skel = SkeletonBuilder::default()
            .nodes(nodes)
            .root_id(Some(0_u16))
            .build()
            .unwrap();

        let stats_map = skel.measure_tree_level_skipping();
        // BFS sees only node0 => level=0 => node_count=1 => leaf_count=1
        let root_level = stats_map.get(&0).unwrap();
        assert_eq!(*root_level.total_node_count(), 1);
        assert_eq!(*root_level.total_leaf_count(), 1);
    }

    #[traced_test]
    fn no_leaf_scenario_for_level_skipping() {
        // 3 nodes => each references next => final references nonexistent => no structural leaves
        let n0 = SkeletonNodeBuilder::default()
            .id(0u16)
            .child_ids(vec![1u16])
            .name("node0")
            .original_key("node0")
            .build(NodeKind::Dispatch)
            .unwrap();
        let n1 = SkeletonNodeBuilder::default()
            .id(1u16)
            .child_ids(vec![2u16])
            .name("node1")
            .original_key("node1")
            .build(NodeKind::Dispatch)
            .unwrap();
        let n2 = SkeletonNodeBuilder::default()
            .id(2u16)
            .child_ids(vec![99u16])
            .name("node2")
            .original_key("node2")
            .build(NodeKind::Dispatch)
            .unwrap();

        let skel = SkeletonBuilder::default()
            .nodes(vec![n0,n1,n2])
            .root_id(Some(0u16))
            .build()
            .unwrap();

        let skip_stats = skel.measure_tree_level_skipping();
        // BFS => level0 => node0 => leaf_count=0, level1 => node1 => 0, level2 => node2 => 0
        assert_eq!(*skip_stats.get(&0).unwrap().total_leaf_count(), 0);
        assert_eq!(*skip_stats.get(&1).unwrap().total_leaf_count(), 0);
        assert_eq!(*skip_stats.get(&2).unwrap().total_leaf_count(), 0);
    }

    #[traced_test]
    fn large_leaf_count_density() {
        // 3 nodes, each leaf_count=65535
        let n0 = SkeletonNodeBuilder::default()
            .id(0u16)
            .leaf_count(65535)
            .name("massLeafNode0")
            .original_key("massLeafNode0")
            .build(NodeKind::LeafHolder)
            .unwrap();
        let n1 = SkeletonNodeBuilder::default()
            .id(1u16)
            .leaf_count(65535)
            .name("massLeafNode1")
            .original_key("massLeafNode1")
            .build(NodeKind::LeafHolder)
            .unwrap();
        let n2 = SkeletonNodeBuilder::default()
            .id(2u16)
            .leaf_count(65535)
            .name("massLeafNode2")
            .original_key("massLeafNode2")
            .build(NodeKind::LeafHolder)
            .unwrap();

        let skel = SkeletonBuilder::default()
            .nodes(vec![n0, n1, n2])
            .root_id(Some(0u16))
            .build()
            .unwrap();

        let dist = skel.measure_tree_density_distribution();
        assert_eq!(dist, vec![65535, 65535, 65535]);
    }

    #[traced_test]
    fn random_sub_branch_ordering_is_unknown() {
        let nodeA = SkeletonNodeBuilder::default()
            .id(0u16)
            .child_ids(vec![55u16, 3u16, 999u16, 1u16])
            .name("nodeA")
            .original_key("nodeA")
            .build(NodeKind::Dispatch)
            .unwrap();
        let nodeB = SkeletonNodeBuilder::default()
            .id(55u16)
            .name("nodeB")
            .original_key("nodeB")
            .build(NodeKind::LeafHolder)
            .unwrap();

        let skel = SkeletonBuilder::default()
            .nodes(vec![nodeA, nodeB])
            .root_id(Some(0u16))
            .build()
            .unwrap();

        let orderings = skel.measure_tree_sub_branch_orderings();
        assert_eq!(orderings.len(), 2);
        for ord in orderings {
            assert!(matches!(ord, SubBranchOrdering::None));
        }
    }
}