From 695964bfa167fa0306f4e35023845cabc7b21976 Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Fri, 12 Jun 2026 00:55:47 +0100 Subject: [PATCH] chore(docs): sweep aftermath - hasContent null contract, bisect note, debug-overlay guides Documents and pins the SectionLookup.hasContent null tolerance that five v2 presets rely on since the import sweep folded their explicit guards (SectionLookupTest guards the contract against a future exhaustive-switch rewrite). Adds a CHANGELOG Internal note recording the sweep's mechanical code rewrites (~40 files: Template record conversions, Collections.addAll, wildcard imports, guard folding) so future bisects do not skip f04a7dce on the strength of its message. Extends getting-started and production-rendering with the DocumentDebugOptions node-label workflow. --- CHANGELOG.md | 13 ++++++++ docs/getting-started.md | 12 ++++++++ docs/operations/production-rendering.md | 10 ++++--- .../cv/v2/components/SectionLookup.java | 10 ++++++- .../cv/v2/components/SectionLookupTest.java | 30 +++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookupTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 729ab7bb7..4f017437f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -185,6 +185,19 @@ Entries land here as they merge. `ChartStyle` palette override (navy/gold) and an explicit 0–100 axis — ~90 lines of hand-drawn AWT geometry replaced by a declarative spec. +### Internal + +- **Sweep follow-up note for future bisectors.** The v1.8.0 import/Javadoc + sweep (`f04a7dce`, part of #162) also carried mechanical code rewrites in + roughly 40 files beyond its stated scope: ~30 private preset `Template` + classes converted to records, constructor copy-loops replaced with + `Collections.addAll`, explicit imports collapsed to wildcards, and five + presets' explicit `section == null` guards folded into + `SectionLookup.hasContent`'s null tolerance (now documented on the method + and pinned by `SectionLookupTest`). All rewrites were verified + behavior-preserving by the full gate at merge time; recorded here so a + future bisect does not skip that commit on the strength of its message. + ### Tests - Chart geometry pinned without rendering: `NiceScaleTest` golden tables and diff --git a/docs/getting-started.md b/docs/getting-started.md index 066075a19..22de720cd 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -120,6 +120,18 @@ document.guideLines(true); byte[] debugPdf = document.toPdfBytes(); ``` +Need to know *which* block is which? `DocumentDebugOptions` adds semantic +node labels on top of the guides — every rendered node gets a small corner +badge with the same stable path `layoutSnapshot()` reports: + +```java +document.debug(DocumentDebugOptions.guidesAndNodeLabels()); +byte[] labelledPdf = document.toPdfBytes(); +``` + +Spot the misplaced block on the sheet, read its badge, then search that +name in your builder code. + ## Module-First Authoring Use modules when you are building a normal document section. A module diff --git a/docs/operations/production-rendering.md b/docs/operations/production-rendering.md index 9c6733174..cb3d10a3d 100644 --- a/docs/operations/production-rendering.md +++ b/docs/operations/production-rendering.md @@ -42,10 +42,12 @@ the session. ## Debug Output -Use `GraphCompose.document(path).guideLines(true)` or -`document.guideLines(true)` only for local diagnostics, visual tests, and layout -debugging. Guide lines are a render-only overlay and do not change pagination or -layout snapshots. Production services should normally leave them disabled. +Use `GraphCompose.document(path).guideLines(true)`, `document.guideLines(true)`, +or the fuller `document.debug(DocumentDebugOptions.guidesAndNodeLabels())` — +which adds semantic node-path badges on top of the guides — only for local +diagnostics, visual tests, and layout debugging. Debug overlays are render-only +and do not change pagination or layout snapshots. Production services should +normally leave them disabled. ## Cache And Privacy Policy diff --git a/src/main/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookup.java b/src/main/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookup.java index 7686d0139..727c203a2 100644 --- a/src/main/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookup.java +++ b/src/main/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookup.java @@ -42,7 +42,15 @@ public static CvSection firstMatching(List sections, /** * Reports whether the section carries any renderable content. * - * @param section the section to inspect + *

{@code null} is accepted and reports {@code false}. Preset + * call sites feed this method straight from {@link #firstMatching}, which + * returns {@code null} when no section title matches, and rely on the + * null tolerance to silently skip absent modules. Keep that tolerance if + * this method is ever rewritten as an exhaustive {@code switch} over the + * sealed {@code CvSection} hierarchy — {@code SectionLookupTest} pins the + * contract.

+ * + * @param section the section to inspect; may be {@code null} * @return {@code true} if the section has non-empty body, entries, * rows, or skill groups */ diff --git a/src/test/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookupTest.java b/src/test/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookupTest.java new file mode 100644 index 000000000..afd5d33a8 --- /dev/null +++ b/src/test/java/com/demcha/compose/document/templates/cv/v2/components/SectionLookupTest.java @@ -0,0 +1,30 @@ +package com.demcha.compose.document.templates.cv.v2.components; + +import com.demcha.compose.document.templates.cv.v2.data.ParagraphSection; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Pins the {@link SectionLookup#hasContent} null contract: six v2 presets + * call it directly on {@code SectionLookup.firstMatching(...)} results + * (which are {@code null} when no section title matches) without their own + * null guards, so a {@code null} section must keep reporting {@code false} + * — never throw — even if the method is later rewritten as an exhaustive + * switch over the sealed {@code CvSection} hierarchy. + */ +class SectionLookupTest { + + @Test + void hasContentToleratesNullSections() { + assertThat(SectionLookup.hasContent(null)).isFalse(); + } + + @Test + void hasContentSeesParagraphBodies() { + assertThat(SectionLookup.hasContent(new ParagraphSection("Profile", "Seasoned engineer."))) + .isTrue(); + assertThat(SectionLookup.hasContent(new ParagraphSection("Profile", " "))) + .isFalse(); + } +}