pray-core 1.12.1

Core library for Prayfile, the package manager for the language placed before inference
Documentation
use super::registry_cache_directory;
use serde::Deserialize;
use std::fs;
use std::path::Path;

#[derive(Deserialize)]
struct CacheFixture {
    source_key: String,
    package_name: String,
    version: String,
    relative_path: String,
}

#[test]
fn registry_cache_path_matches_shared_fixture() {
    let fixture_path = Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("../../testdata/shared/registry-cache/identity-first.json");
    let fixture: CacheFixture =
        serde_json::from_str(&fs::read_to_string(fixture_path).expect("fixture"))
            .expect("valid fixture");

    let path = registry_cache_directory(
        Path::new("/project"),
        &fixture.source_key,
        &fixture.package_name,
        &fixture.version,
    )
    .expect("cache path");

    assert_eq!(path, Path::new("/project").join(fixture.relative_path));
}

#[test]
fn registry_cache_path_rejects_unsafe_identity_segments() {
    for package_name in [
        "sample",
        "sample/base/extra",
        "sample//base",
        "./base",
        "../base",
        "sample/..",
        r"sample\base",
    ] {
        assert!(
            registry_cache_directory(Path::new("/project"), "source", package_name, "1.0.0")
                .is_err(),
            "{package_name:?} should be rejected"
        );
    }

    for version in ["", ".", "..", "1/2", r"1\2"] {
        assert!(
            registry_cache_directory(Path::new("/project"), "source", "sample/base", version)
                .is_err(),
            "{version:?} should be rejected"
        );
    }
}