test(cph-model): isolate version fixtures

This commit is contained in:
2026-07-10 02:33:12 +08:00
parent 008c8bcd09
commit b0eedfab05
3 changed files with 18 additions and 19 deletions
Generated
+1
View File
@@ -427,6 +427,7 @@ version = "0.0.2"
dependencies = [ dependencies = [
"cph-diag", "cph-diag",
"serde", "serde",
"tempfile",
"toml", "toml",
] ]
+3
View File
@@ -10,3 +10,6 @@ serde = { workspace = true }
# `preserve_order` keeps `[targets.*]` tables in TOML document order, which is # `preserve_order` keeps `[targets.*]` tables in TOML document order, which is
# the declared order this crate exposes via `Lesson.targets` (ADR-0009). # the declared order this crate exposes via `Lesson.targets` (ADR-0009).
toml = { workspace = true, features = ["preserve_order"] } toml = { workspace = true, features = ["preserve_order"] }
[dev-dependencies]
tempfile = "3"
+14 -19
View File
@@ -279,16 +279,15 @@ fn malformed_target_config_is_non_fatal_with_schema_violations() {
/// match exactly (ADR-0016's MVP rule). /// match exactly (ADR-0016's MVP rule).
const CPH_VERSION: &str = env!("CARGO_PKG_VERSION"); const CPH_VERSION: &str = env!("CARGO_PKG_VERSION");
/// Write a one-part lesson into a temp dir, optionally with a `.cph-version` /// Write a one-part lesson into a uniquely-created temp dir, optionally with a
/// file. Returns the temp dir so the caller runs `load`. /// `.cph-version` file. `TempDir` owns cleanup so parallel tests cannot delete
fn tmp_lesson_with_version(version: Option<&str>) -> PathBuf { /// one another's fixture after a timestamp collision.
let mut p = std::env::temp_dir(); fn tmp_lesson_with_version(version: Option<&str>) -> tempfile::TempDir {
let nanos = std::time::SystemTime::now() let tmp = tempfile::Builder::new()
.duration_since(std::time::UNIX_EPOCH) .prefix("cph-version-test-")
.unwrap() .tempdir()
.as_nanos(); .unwrap();
p.push(format!("cph-version-test-{nanos}")); let p = tmp.path();
std::fs::create_dir_all(&p).unwrap();
std::fs::write( std::fs::write(
p.join("manifest.toml"), p.join("manifest.toml"),
"[project]\nid = \"v\"\nname = \"v\"\n[info]\ntitle = \"v\"\n[[parts]]\nkind = \"segment\"\npath = \"segments/a\"\n", "[project]\nid = \"v\"\nname = \"v\"\n[info]\ntitle = \"v\"\n[[parts]]\nkind = \"segment\"\npath = \"segments/a\"\n",
@@ -301,14 +300,13 @@ fn tmp_lesson_with_version(version: Option<&str>) -> PathBuf {
if let Some(v) = version { if let Some(v) = version {
std::fs::write(p.join(".cph-version"), v).unwrap(); std::fs::write(p.join(".cph-version"), v).unwrap();
} }
p tmp
} }
#[test] #[test]
fn cph_version_matching_is_not_a_diagnostic() { fn cph_version_matching_is_not_a_diagnostic() {
let tmp = tmp_lesson_with_version(Some(CPH_VERSION)); let tmp = tmp_lesson_with_version(Some(CPH_VERSION));
let (_lesson, diags) = load(&tmp); let (_lesson, diags) = load(tmp.path());
let _ = std::fs::remove_dir_all(&tmp);
assert!( assert!(
diags.iter().all(|d| d.code != DiagCode::CphVersionMismatch), diags.iter().all(|d| d.code != DiagCode::CphVersionMismatch),
"a matching .cph-version must not warn, got {diags:?}" "a matching .cph-version must not warn, got {diags:?}"
@@ -318,8 +316,7 @@ fn cph_version_matching_is_not_a_diagnostic() {
#[test] #[test]
fn cph_version_mismatch_is_an_error_diagnostic() { fn cph_version_mismatch_is_an_error_diagnostic() {
let tmp = tmp_lesson_with_version(Some("99.99.99")); let tmp = tmp_lesson_with_version(Some("99.99.99"));
let (lesson, diags) = load(&tmp); let (lesson, diags) = load(tmp.path());
let _ = std::fs::remove_dir_all(&tmp);
// The lesson still loads (so other defects could surface), but the // The lesson still loads (so other defects could surface), but the
// mismatch is an error diagnostic — which alone makes it illegal. // mismatch is an error diagnostic — which alone makes it illegal.
assert!(lesson.is_some(), "a mismatch should not halt loading"); assert!(lesson.is_some(), "a mismatch should not halt loading");
@@ -339,8 +336,7 @@ fn cph_version_mismatch_is_an_error_diagnostic() {
fn cph_version_missing_is_skipped() { fn cph_version_missing_is_skipped() {
// No `.cph-version` file at all → skipped (ADR-0016 migration period; OPEN). // No `.cph-version` file at all → skipped (ADR-0016 migration period; OPEN).
let tmp = tmp_lesson_with_version(None); let tmp = tmp_lesson_with_version(None);
let (_lesson, diags) = load(&tmp); let (_lesson, diags) = load(tmp.path());
let _ = std::fs::remove_dir_all(&tmp);
assert!( assert!(
diags.iter().all(|d| d.code != DiagCode::CphVersionMismatch), diags.iter().all(|d| d.code != DiagCode::CphVersionMismatch),
"a missing .cph-version must be skipped, got {diags:?}" "a missing .cph-version must be skipped, got {diags:?}"
@@ -350,8 +346,7 @@ fn cph_version_missing_is_skipped() {
#[test] #[test]
fn cph_version_empty_is_an_error() { fn cph_version_empty_is_an_error() {
let tmp = tmp_lesson_with_version(Some(" \n")); let tmp = tmp_lesson_with_version(Some(" \n"));
let (_lesson, diags) = load(&tmp); let (_lesson, diags) = load(tmp.path());
let _ = std::fs::remove_dir_all(&tmp);
assert!( assert!(
diags diags
.iter() .iter()