alef 0.74.0

Opinionated polyglot binding generator for Rust libraries
Documentation
use super::*;

/// `sync_versions` must bump `[package] version` in the alef-generated e2e Rust
/// harness manifest at `<e2e.output>/rust/Cargo.toml` (default output dir "e2e").
///
/// Regression test: `sync_rust_test_app_version` read `e2e.registry.output`
/// (default "test_apps", used only in registry-mode e2e) instead of `e2e.output`
/// (default "e2e", used by the local/path-mode e2e harness that `alef e2e generate`
/// writes to by default). Because the two are different directories, the function
/// looked for `test_apps/rust/Cargo.toml`, found nothing there, and silently
/// no-opped — leaving the real `e2e/rust/Cargo.toml` on the previous version after
/// every bump.
#[test]
fn sync_versions_bumps_e2e_rust_harness_package_version() {
    use crate::core::config::NewAlefConfig;

    let _guard = CWD_LOCK.lock().unwrap_or_else(|e| e.into_inner());
    let original_cwd = std::env::current_dir().expect("cwd");

    let tmp = tempfile::tempdir().expect("tempdir");
    let root = tmp.path();

    std::fs::write(
        root.join("Cargo.toml"),
        "[workspace.package]\nversion = \"1.3.1\"\n\n[workspace]\nresolver = \"2\"\nmembers = []\n",
    )
    .expect("write Cargo.toml");

    let e2e_rust_dir = root.join("e2e/rust");
    std::fs::create_dir_all(&e2e_rust_dir).expect("mkdir e2e/rust");
    std::fs::write(
        e2e_rust_dir.join("Cargo.toml"),
        concat!(
            "# Code generated by alef — DO NOT EDIT.\n",
            "# alef:hash:deadbeef\n",
            "[package]\n",
            "name = \"mock-server\"\n",
            "version = \"1.3.0\"\n",
            "edition = \"2024\"\n",
            "\n",
            "[dependencies]\n",
            "anyhow = \"1\"\n",
        ),
    )
    .expect("write e2e/rust/Cargo.toml");

    let alef_toml = format!(
        concat!(
            "[workspace]\n",
            "languages = [\"rust\"]\n\n",
            "[[crates]]\n",
            "name = \"mylib\"\n",
            "sources = []\n",
            "version_from = \"{cargo_toml}\"\n\n",
            "[crates.e2e]\n",
            "languages = []\n\n",
            "[crates.e2e.call]\n",
            "module = \"mylib\"\n",
            "function = \"parse\"\n",
        ),
        cargo_toml = root.join("Cargo.toml").display().to_string().replace('\\', "/"),
    );
    let alef_toml_path = root.join("alef.toml");
    std::fs::write(&alef_toml_path, &alef_toml).expect("write alef.toml");

    let cfg: NewAlefConfig = toml::from_str(&alef_toml).expect("parse alef.toml");
    let mut resolved = cfg.resolve().expect("resolve config");
    let resolved_cfg = resolved.remove(0);

    std::env::set_current_dir(root).expect("set_current_dir");
    let sync_result = sync_versions(&resolved_cfg, &alef_toml_path, None, true, true, None);
    let _ = std::env::set_current_dir(&original_cwd);
    sync_result.expect("sync_versions ok");

    let out = std::fs::read_to_string(e2e_rust_dir.join("Cargo.toml")).expect("read e2e/rust/Cargo.toml");
    assert!(
        out.contains("version = \"1.3.1\""),
        "e2e/rust/Cargo.toml [package] version must be bumped to 1.3.1, got:\n{out}"
    );
    assert!(
        !out.contains("version = \"1.3.0\""),
        "stale version 1.3.0 must be gone from e2e/rust/Cargo.toml, got:\n{out}"
    );
}