From 2e02523fe9a580f2f3ecd4e09290a9da014c7890 Mon Sep 17 00:00:00 2001 From: Dexter <37185622+dexterlabs1@users.noreply.github.com> Date: Tue, 6 Oct 2026 16:40:12 -0500 Subject: [PATCH] test: tolerate installed variants of bundled font families --- crates/engine/src/tests_text_edit.rs | 14 +++++++++--- crates/text/src/fonts.rs | 33 ++++++++++++++++++---------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/crates/engine/src/tests_text_edit.rs b/crates/engine/src/tests_text_edit.rs index e3b6e63f..d543fc9a 100644 --- a/crates/engine/src/tests_text_edit.rs +++ b/crates/engine/src/tests_text_edit.rs @@ -239,15 +239,23 @@ fn fonts_lists_bundled_and_installed_families() { assert!(inter["styles"].as_array().unwrap().contains(&json!("Bold"))); // Installed fonts are listed without any layer having asked for one. use effectcraft_text::fonts::FontSource as _; - for face in effectcraft_text::fonts::DirectorySource::system().faces() { + let installed = effectcraft_text::fonts::DirectorySource::system().faces(); + for face in &installed { assert!(fams.iter().any(|f| f["family"].as_str().unwrap().eq_ignore_ascii_case(&face.family)), "{} not listed", face.family); } // Filtered by name; rescanning keeps what was there. let r = s.execute("text.fonts", json!({"query": "noto ser", "rescan": true})).unwrap(); assert_eq!(r["families"][0]["family"], "Noto Serif"); - assert_eq!(r["families"][0]["styles"], json!(["Regular"])); + // The bundled face is Regular; the OS can also provide Bold, Italic, or other faces. + // Compare against the independent directory inventory rather than assuming an empty OS. + let mut expected_styles = std::collections::BTreeSet::from(["Regular".to_string()]); + expected_styles.extend(installed.iter().filter(|face| face.family.eq_ignore_ascii_case("Noto Serif")).map(|face| face.style.clone())); + let styles: Vec = r["families"][0]["styles"].as_array().unwrap().iter().map(|style| style.as_str().unwrap().to_string()).collect(); + assert_eq!(styles.iter().cloned().collect::>(), expected_styles); + assert_eq!(styles.len(), expected_styles.len(), "style menu has no duplicates"); assert!(r["families"].as_array().unwrap().iter().all(|f| f["family"].as_str().unwrap().to_lowercase().contains("noto ser"))); // The style menus offer a family's own styles. - assert_eq!(crate::font_styles("noto serif"), vec!["Regular".to_string()]); + assert_eq!(crate::font_styles("noto serif"), styles); + assert_eq!(crate::font_styles("NOTO SERIF"), styles); assert_eq!(crate::font_styles("No Such Family").len(), 5); } diff --git a/crates/text/src/fonts.rs b/crates/text/src/fonts.rs index 6e7bc1cb..62c753cb 100644 --- a/crates/text/src/fonts.rs +++ b/crates/text/src/fonts.rs @@ -679,18 +679,27 @@ mod tests { let b = resolve("inter", "bold"); assert_eq!(face(b.face).info.style, "Bold"); assert!(!b.synth_bold); - // Noto Serif has only Regular: Bold Italic is synthesised - let s = resolve("Noto Serif", "Bold Italic"); - assert_eq!(face(s.face).info.family, "Noto Serif"); - assert!(s.synth_bold && s.synth_italic); - // Inter Bold Italic: the bundled cuts' nearest is Italic (400) → synth bold. Listing the - // families scanned the system fonts, so an installed Inter's real Bold Italic wins. - let bi = resolve("Inter", "Bold Italic"); - let f = face(bi.face); - if f.info.origin == "bundled" { - assert!(f.info.italic && bi.synth_bold && !bi.synth_italic); - } else { - assert!(f.info.style.eq_ignore_ascii_case("Bold Italic") && !bi.synth_bold && !bi.synth_italic); + let faces = all_faces(); + assert!(faces.iter().any(|f| f.info.family == "Noto Serif" && f.info.style == "Regular" && f.info.origin == "bundled")); + // A real installed Bold Italic takes priority. Partial installed families can instead + // supply the nearest weight/slant, so neither synthesis flag is fixed by the OS. + for family in ["Noto Serif", "Inter"] { + let resolved = resolve(family, "Bold Italic"); + let selected = face(resolved.face); + assert!(selected.info.family.eq_ignore_ascii_case(family)); + assert!(!resolved.missing); + let candidates: Vec<_> = faces.iter().filter(|f| f.info.family.eq_ignore_ascii_case(family)).collect(); + if let Some(exact) = candidates.iter().find(|f| f.info.style.eq_ignore_ascii_case("Bold Italic")) { + assert_eq!(resolved.face, exact.id, "real style wins for {family}"); + assert!(!resolved.synth_bold && !resolved.synth_italic); + } else { + // Italic mismatch dominates any supported font weight distance. + let distance = |f: &Face| u32::from(f.info.weight.abs_diff(700)) + if f.info.italic { 0 } else { 1_000 }; + let nearest = candidates.iter().map(|f| distance(f)).min().unwrap(); + assert_eq!(distance(&selected), nearest, "closest available style for {family}"); + assert_eq!(resolved.synth_bold, selected.info.weight <= 500); + assert_eq!(resolved.synth_italic, !selected.info.italic); + } } }