uselesskey-core-cache 0.7.1

Identity-keyed typed cache primitives for uselesskey fixture factories.
Documentation
use std::sync::Arc;

use proptest::prelude::*;
use uselesskey_core_cache::ArtifactCache;
use uselesskey_core_id::{ArtifactId, DerivationVersion};

fn make_id(label: &str, variant: &str) -> ArtifactId {
    ArtifactId::new(
        "domain:prop",
        label,
        b"spec",
        variant,
        DerivationVersion::V1,
    )
}

proptest! {
    #![proptest_config(ProptestConfig { cases: 128, ..ProptestConfig::default() })]

    #[test]
    fn insert_get_roundtrip(label in "[a-z]{1,16}", value in any::<u64>()) {
        let cache = ArtifactCache::new();
        let id = make_id(&label, "good");

        cache.insert_if_absent_typed(id.clone(), Arc::new(value));
        let got = cache.get_typed::<u64>(&id).unwrap();
        prop_assert_eq!(*got, value);
    }

    #[test]
    fn insert_if_absent_keeps_first(label in "[a-z]{1,8}", v1 in any::<u32>(), v2 in any::<u32>()) {
        let cache = ArtifactCache::new();
        let id = make_id(&label, "good");

        let first = cache.insert_if_absent_typed(id.clone(), Arc::new(v1));
        let second = cache.insert_if_absent_typed(id.clone(), Arc::new(v2));
        prop_assert!(Arc::ptr_eq(&first, &second));
        prop_assert_eq!(*first, v1);
    }

    #[test]
    fn distinct_labels_stored_independently(
        label_a in "[a-z]{1,8}",
        label_b in "[a-z]{1,8}",
        va in any::<u32>(),
        vb in any::<u32>(),
    ) {
        prop_assume!(label_a != label_b);
        let cache = ArtifactCache::new();
        let id_a = make_id(&label_a, "good");
        let id_b = make_id(&label_b, "good");

        cache.insert_if_absent_typed(id_a.clone(), Arc::new(va));
        cache.insert_if_absent_typed(id_b.clone(), Arc::new(vb));

        prop_assert_eq!(*cache.get_typed::<u32>(&id_a).unwrap(), va);
        prop_assert_eq!(*cache.get_typed::<u32>(&id_b).unwrap(), vb);
        prop_assert_eq!(cache.len(), 2);
    }

    #[test]
    fn len_matches_distinct_inserts(count in 1usize..32) {
        let cache = ArtifactCache::new();
        for i in 0..count {
            let id = make_id(&format!("k{i}"), "good");
            cache.insert_if_absent_typed(id, Arc::new(i as u32));
        }
        prop_assert_eq!(cache.len(), count);
    }

    #[test]
    fn clear_always_empties(count in 1usize..32) {
        let cache = ArtifactCache::new();
        for i in 0..count {
            let id = make_id(&format!("k{i}"), "good");
            cache.insert_if_absent_typed(id, Arc::new(i as u32));
        }
        cache.clear();
        prop_assert!(cache.is_empty());
        prop_assert_eq!(cache.len(), 0);
    }

    #[test]
    fn get_absent_key_returns_none(label in "[a-z]{1,16}") {
        let cache = ArtifactCache::new();
        let id = make_id(&label, "good");
        prop_assert!(cache.get_typed::<u32>(&id).is_none());
    }

    #[test]
    fn distinct_variants_stored_independently(
        label in "[a-z]{1,8}",
        variant_a in "[a-z]{1,8}",
        variant_b in "[a-z]{1,8}",
    ) {
        prop_assume!(variant_a != variant_b);
        let cache = ArtifactCache::new();
        let id_a = make_id(&label, &variant_a);
        let id_b = make_id(&label, &variant_b);

        cache.insert_if_absent_typed(id_a.clone(), Arc::new(1u32));
        cache.insert_if_absent_typed(id_b.clone(), Arc::new(2u32));

        prop_assert_eq!(*cache.get_typed::<u32>(&id_a).unwrap(), 1);
        prop_assert_eq!(*cache.get_typed::<u32>(&id_b).unwrap(), 2);
    }
}