From ff3e4e6010b905bf7dc09c507a2078426efa9d37 Mon Sep 17 00:00:00 2001 From: Trevor Brown Date: Mon, 9 Nov 2026 09:38:56 -0500 Subject: [PATCH] M12: sticky growth checked with a measured font; the normalize note drops sticky size (#2164 review) The growth test scans the system fonts, as the other text-measuring engine tests do (#333), and asserts the note grows taller unconditionally instead of only when text happened to measure. docs/boards-parity.md no longer lists a sticky's text size among what the normalize pass derives. Co-Authored-By: Claude Opus 5.5 Model-Effort: Opus 5.5 checked the findings and wrote --- crates/engine/src/board_tests.rs | 11 ++++++----- docs/boards-parity.md | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/engine/src/board_tests.rs b/crates/engine/src/board_tests.rs index 1b0ac120c..eb00647ac 100644 --- a/crates/engine/src/board_tests.rs +++ b/crates/engine/src/board_tests.rs @@ -116,6 +116,9 @@ fn a_new_sticky_starts_at_18() { #[test] fn a_sticky_keeps_its_text_size_as_text_is_added() { + // The note's growth needs text measured: without craft-fonts that is with a system font, + // scanned here rather than by whichever test happens to run first (#333). + figcraft_text::scan_system_fonts(); let mut s = board(); let r = s.execute("board.sticky", &json!({"x": 0, "y": 0, "text": "one"})).unwrap(); let (st, note) = (id(&r, "id"), id(&r, "text")); @@ -129,10 +132,8 @@ fn a_sticky_keeps_its_text_size_as_text_is_added() { let ten = node(&s, note).kind.text().unwrap().clone(); assert_eq!(ten.characters.matches('\n').count(), 9, "ten lines"); assert_eq!(ten.style.font_size, 18.0); - // Growth needs text measured: a build without the craft-fonts input measures nothing (the same - // reason `a_double_click_types_in_the_cell...` fails there), so it is only checked where it is. - let measured = node(&s, note).height > text_height; - assert!(!measured || node(&s, st).height > height, "ten lines make the note taller"); + assert!(node(&s, note).height > text_height, "ten lines make the text taller"); + assert!(node(&s, st).height > height, "and the note"); assert_eq!(node(&s, st).child_layout.sizing_v, figcraft_doc::Sizing::Hug, "the note hugs its text"); let (w, h10) = (node(&s, st).width, node(&s, st).height); crate::textedit::insert(&mut s, &"a long paragraph ".repeat(15)).unwrap(); @@ -142,7 +143,7 @@ fn a_sticky_keeps_its_text_size_as_text_is_added() { assert_eq!(t.style.font_size, 18.0); assert!(t.runs.iter().all(|r| r.style.font_size == 18.0)); assert_eq!(node(&s, st).width, w, "the note keeps its width"); - assert!(!measured || node(&s, st).height > h10, "and grows taller"); + assert!(node(&s, st).height > h10, "and grows taller"); } #[test] diff --git a/docs/boards-parity.md b/docs/boards-parity.md index 2cc099f08..f874daad5 100644 --- a/docs/boards-parity.md +++ b/docs/boards-parity.md @@ -17,8 +17,8 @@ design product). The work item is gap 24 in [`gaps.md`](gaps.md). Board objects are ordinary layers with a small `board` field on the node (`figcraft_doc::BoardItem`), so rendering, hit testing, undo, saving, SVG/PNG/PDF export, copy and paste and live sessions work on them unchanged. The file kind (`Document.kind`) is saved in `.figcraft` and reaches people who -join a live session in their snapshot. What follows from the metadata (a sticky's text size, a -shape's text room, connector routes and their labels) is recomputed in the engine's normalize pass, +join a live session in their snapshot. What follows from the metadata (a shape's text +room, connector routes and their labels) is recomputed in the engine's normalize pass, deterministically from the document, so local edits, undo and edits from others in a live session all end with the same geometry.