alef 0.83.2

Opinionated polyglot binding generator for Rust libraries
Documentation
//! Regression coverage for alef task #509: `alef adopt` classified `.npmrc` as a format that
//! cannot carry a marker, even though `e2e::codegen::typescript`'s own node/napi generator
//! self-marks it with a hand-rolled `; <marker>` line. That mismatch sent every `.npmrc` adopt
//! through the presence-only `.alef-ownership.toml` fallback -- `report.recorded_unstampable`,
//! never `report.adopted` by way of a real stamp -- leaving a consumer tree's pre-existing
//! `.npmrc` byte-identical, still carrying an older, unrecognised wording, no matter how many
//! times `alef adopt --write` ran against it.
//!
//! The fix taught [`crate::cli::pipeline::generate::write::marker_header_syntax`] a `;`-comment
//! syntax for `.npmrc` (matched on file name, the same way `.clang-format` already is), so the
//! generic [`crate::cli::pipeline::stamp_for_adoption`] route -- the *same* table
//! `write_files_report`'s live guard and `alef verify`'s scan-set derivation both already
//! consult -- now answers this format the same way the generator's own emission already proves
//! it should: markable.

use super::*;

/// A `.npmrc` on disk with the pre-#509 wording (`"alef-generated"`, not `"generated by alef"`),
/// which [`content_has_alef_marker`] does not recognise -- the exact drifted shape a consumer
/// repo carries today.
const OLD_WORDING_NPMRC: &str =
    "; alef-generated — frozen-lockfile is disabled: legacy wording nobody re-spelled.\nfrozen-lockfile=false\n";

/// What the real generator emits today (`e2e::codegen::typescript::mod::generate`), rebuilt here
/// rather than imported so this module stays independent of the e2e codegen's own fixture/config
/// plumbing -- the shape under test is the marker table's answer, not the generator's wiring.
fn current_wording_npmrc() -> String {
    format!(
        "; {}\n; frozen-lockfile is disabled: the under-test napi package pins platform \
         optionalDependencies to the unpublished release version.\nfrozen-lockfile=false\n",
        crate::core::hash::STANDARD_HEADER_LINE
    )
}

/// If this regresses, the exact symptom task #509 reported: `report.recorded_unstampable`
/// carries `.npmrc` instead of `report.adopted` stamping it, and the file on disk stays
/// byte-for-byte the old wording -- `content_has_alef_marker` on it stays false forever, because
/// nothing ever put a recognisable marker in the file itself.
#[test]
fn drifted_npmrc_is_stamped_in_place_not_recorded_as_presence_only() {
    let dir = tempfile::tempdir().expect("tempdir");
    let base = dir.path();
    let target = seed(base, "e2e/node/.npmrc", OLD_WORDING_NPMRC);
    let generated = current_wording_npmrc();
    let outputs = managed("e2e/node/.npmrc", &generated, false, base);

    let report = run(&options(base, "e2e/node/.npmrc", true), &outputs).expect("adopt");

    let after = std::fs::read_to_string(&target).expect("read after");
    assert!(
        content_has_alef_marker(&after),
        "adoption must leave a marker the guard will recognise, got:\n{after}"
    );
    assert!(
        after.contains("legacy wording"),
        "adopt stamps the existing bytes, never replaces them with generated content, got:\n{after}"
    );
    assert_eq!(report.adopted, vec![PathBuf::from("e2e/node/.npmrc")]);
    assert!(
        report.recorded_unstampable.is_empty(),
        ".npmrc can carry a marker in its own bytes -- it must never fall back to the \
         presence-only ownership record, got: {:?}",
        report.recorded_unstampable
    );
    assert_eq!(report.diffs.len(), 1);
    assert_eq!(report.diffs[0].state, AdoptionState::Drifted);
}

/// Positive control mirroring the real generator's converged case: an `.npmrc` that already
/// carries today's wording is already owned and produces no diff at all -- adoption is a no-op,
/// not a second stamp on top of the first.
#[test]
fn already_current_wording_npmrc_is_already_owned() {
    let dir = tempfile::tempdir().expect("tempdir");
    let base = dir.path();
    let generated = current_wording_npmrc();
    seed(base, "e2e/node/.npmrc", &generated);
    let outputs = managed("e2e/node/.npmrc", &generated, false, base);

    let report = run(&options(base, "e2e/node/.npmrc", true), &outputs).expect("adopt");

    assert_eq!(report.already_owned, vec![PathBuf::from("e2e/node/.npmrc")]);
    assert!(report.adopted.is_empty());
    assert!(report.diffs.is_empty());
}