Repository navigation
test(docx): give every value a node holds a fate, and name the known gaps - #938
Merged
Merged
Conversation
…gaps DocxNodeFieldLedgerTest gives every field of every node a fate and stopped at the field: a part added to a value one holds - a style's colour, a run's alignment, a border's width, an enum's constant - passed it with no decision. DocxValueFieldLedgerTest walks the value types from the node classes and the output options, down to the last one they hold, through generics, arrays and sealed types, and gives each of their 421 parts a fate. It fails on a type or part with no entry, on an entry for a part that is gone, on a type any class may implement or extend, and on a node type held from outside the node ledger's packages. Read against the export, some parts are lost in a case the report does not name. Each is a gap, a fourth fate whose note opens with one of the known cases: 39 parts of values and 48 node fields, among them a top below zero, a panel's or a cell's padding below zero, a right border drawn short of its cell's edge, a cell margin Word gives the whole row, pictures in a list's items, a text badge's seat and a drawing painted over a layer of text. Node entries that said those cases were written now say so. A node's alignment, a row's arrangement and a paragraph's indent strategy move from written to reported, which the report already names. No production code changes.
DemchaAV
marked this pull request as draft
October 21, 2026 20:17
owePendingSpacingAfter keeps only a positive amount, and a list, a table, a row, a stack, a canvas, a shape container in the flow and a block with no paint of its own hand it their bottom edge. A bottom below zero then does not pull the next block up in Word, and the report says nothing. It is now the gap BOTTOM_PULL, on DocumentInsets.bottom and on the node entries it loses. A panel's top below zero is dropped whole, as a table's is, and TOP_PULL says so. A row's padding takes SPACE_BELOW_AT_THE_FOOT, as a table's does, and a row's side padding below zero joins PADDING_BELOW_ZERO. A page band's face is reported where it may not travel, as a run's is. The node check asserts that DocumentNode is among the nodes the walk reaches, so an empty walk cannot pass it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
DocxNodeFieldLedgerTestgives every field of every node, and every output option, a fate:written, reported where the author set it, or nothing for Word to carry. It fails on a field with
no entry. It stopped at the field. The values those fields hold are where most of what a page draws
is said: a style's colour, a run's alignment, a border's width, a chart's legend, an enum's
constants. A part added to one of them passed the ledger with no decision, written by the PDF
backend at once and possibly lost from the Word file without a note.
What changed
DocxValueFieldLedgerTest(new) walks every node class's record components andDocumentOutputOptions' components, through generics, arrays, wildcards, type variables andsealed types. It collects each
com.demcha.compose.*value type with its parts:Nodes stop the walk: they are the node ledger's. A type is read once, so a recursive bound
cannot loop. The test fails on:
DocumentNodenor a concrete class the node ledger lists, asone from another package would be.
Today it holds 107 types and 421 parts: 149 written, 221 reported, 12 with nothing for Word to
carry, 39 gaps.
A fourth fate,
GAP: a case the export knows it loses and its report does not name yet.fields()refuses any other. A gap is a known defect, held so the ledger stays true while itis open.
TOP_PULL): dropped on a picture, a barcode or a block written as a table,and on another block, what the space above cannot give;
BOTTOM_PULL) on a list, a table, a row, a stack, a canvas, a shapecontainer in the flow or a block with no paint of its own:
owePendingSpacingAfterkeepsonly a positive amount, so the next block is not pulled up;
container;
the gridline does not cover it;
spanning rows);
verticalAlign, and one where a paragraph's lines are not read;an auto one;
DocxNodeFieldLedgerTest: 48 entries one of those cases loses are now gaps. 20 of them wereWRITTEN; the rest wereREPORTEDfor other cases, which their notes keep after the gap's.Three fields move from written to reported, which the report already names:
AlignNode.alignandRowNode.arrangement:placeComposedAcross,nameTheColumnsLeftToWordand the no-layout note;
ParagraphNode.indentStrategy:paragraphLostandzoneParagraphLost.Fate,Entryandfields()are package-private, for the value ledger to share.CHANGELOG (Tests).
No production code changes.
Verification
Fail-closed: eight sabotages, each run alone and each caught by the test named for it:
coreinstalled, a new field onDocumentMetadata, a field of the open interfacetype
NodeDefinition, and a node record nested inDocumentMetadata, outside the ledgeredpackages.
Corpus: a probe over the 62 corpus documents finds the conditions of several gaps:
verticalAlignin a shape container's paragraph, in 2 templates;None of the corpus's rows has cell margins Word evens. Each corpus case is measured in Word and
closed in its own PR. The rest are outside the corpus.
./mvnw -B -ntp clean verify -pl :graph-compose-core,:graph-compose-render-pdf,:graph-compose-render-docx,:graph-compose-render-pptx,:graph-compose-templates,:graph-compose-testing,:graph-compose-qa,:graph-compose-coverage -am→ BUILD SUCCESS (render-docx 1989 tests, qa 1828). The JDK 17 checks pass: the knowledge
pack,
@Betastability doc, claims and routes, and core javadoc with 0 warnings.Lane: test (
render-docxledgers). No public API change.