- Created bf-300b5 template in notes/bf-lpyhe-template.md with: * Standard assertion message structure * 6 example assertions covering different types * Placeholders for dynamic values * Guidelines for usage and config references - Designed 73 assertion messages in notes/bf-4kbre-messages.md: * 9 messages for unmapped.rs (basic detection) * 63 messages for encoding.rs (CMAP parsing, filtering) * 1 message for resolver.rs (Level 2 resolution) - All messages follow template structure with 4 required elements: * Description of expected behavior * Expected condition * Found/actual condition * Why this matters (references build/unmapped-glyph-names.json) - Categorized by assertion type: * Skip Verification (23) * Inclusion Verification (28) * Count Verification (18) * Diagnostic Verification (11) * Set Membership, Order, Duplicate Handling, etc. Closes bf-w1o10. Verification: notes/bf-4kbre-messages.md, notes/bf-lpyhe-template.md.
5.5 KiB
5.5 KiB
Assertion Message Template
Bead ID: bf-lpyhe
Template Version: 1.0
Date: 2026-07-06
Standard Template
All assertion messages should follow this structure:
"<Description of expected behavior>. \
Expected: <expected condition with specific value>. \
Found: <actual condition or observed value>. \
Why this matters: <rationale and reference to source of truth>."
Template Components
1. Description of Expected Behavior
- What: Clear, concise statement of what should happen
- Format: Present tense, descriptive
- Example: ".notdef should be recognized as an unmapped glyph name"
2. Expected Condition
- what: The exact expected state or return value
- Format:
Expected: <function call> == <expected value>orExpected: <expected state> - Example:
Expected: is_unmapped_glyph_name(".notdef") == true
3. Found / Actual Condition
- What: What was actually observed or returned
- Format:
Found: <actual value>or use placeholder{:?}for runtime values - Example:
Found: falseorFound: {:?}(for format! macros)
4. Why This Matters (Context)
- What: Rationale linking the expectation to its source of truth
- Format: Reference to configuration files, specs, or design docs
- Example:
Why this matters: .notdef is defined in build/unmapped-glyph-names.json as a standard PDF special glyph.
Template Examples by Assertion Type
Example 1: Unmapped Glyph Detection (Positive Case)
".notdef should be recognized as an unmapped glyph name. \
Expected: is_unmapped_glyph_name(\".notdef\") == true. \
Found: false. \
Why this matters: .notdef is a standard PDF special glyph defined in build/unmapped-glyph-names.json that should never appear in text extraction output."
Example 2: Normal Glyph Verification (Negative Case)
"Normal glyph 'A' should not be recognized as unmapped. \
Expected: is_unmapped_glyph_name(\"A\") == false. \
Found: true. \
Why this matters: Letter glyphs are valid Unicode characters and should not be filtered by the unmapped glyph detection logic."
Example 3: Set Membership Verification
"UNMAPPED_GLYPH_NAMES set should contain '.notdef'. \
Expected: UNMAPPED_GLYPH_NAMES.contains(\".notdef\") == true. \
Found: false. \
Why this matters: .notdef is a core unmapped glyph defined in build/unmapped-glyph-names.json configuration and must be present in the runtime set."
Example 4: CMAP Parsing Behavior (Skip Verification)
"Code 39 should not have a mapping (.notdef skipped). \
Expected: None. \
Found: {:?}. \
Why this matters: .notdef is in the default unmapped_glyph_names set (from build/unmapped-glyph-names.json), so it should be silently filtered during /Differences array parsing."
Example 5: Count Verification
"Overlay should contain exactly 1 entry. \
Expected: 1 entry (grave at 96). \
Found: {} entries. \
Why this matters: .notdef at 39 was skipped per build/unmapped-glyph-names.json, leaving only grave in the overlay."
Example 6: Diagnostic Verification
"Skipping .notdef should not generate diagnostics. \
Expected: empty diagnostics. \
Found: {} diagnostics. \
Why this matters: Skipping unmapped glyphs is silent behavior by design - these glyphs are filtered during parsing without producing warnings."
Placeholders for Dynamic Values
When the actual value is determined at runtime, use these placeholders:
{:?}- For Debug formatting (used inassert!macros with format strings){}- For Display formatting{variable}- Document that a specific variable name will be interpolated
Configuration File References
Always reference the source of truth in the "Why this matters" section:
- build/unmapped-glyph-names.json - Default unmapped glyph set
- build/font-fingerprints.json - Font fingerprint database
- PDF specification - When referencing spec-defined behavior
- Design docs - When referencing architectural decisions
Template Usage Guidelines
- Be Specific: Include exact function names, parameters, and expected values
- Be Complete: Never omit the "Why this matters" section
- Be Accurate: The "Found" value should match what the test actually observes
- Be Consistent: Use the same phrasing for similar assertions across tests
- Reference Sources: Always link to the configuration file or spec that defines the expectation
Template for Different Assertion Types
Positive Assertions (Should be true)
"<subject> should <expected behavior>. \
Expected: <condition> == true. \
Found: false. \
Why this matters: <rationale with source reference>."
Negative Assertions (Should NOT be true)
"<subject> should not <unexpected behavior>. \
Expected: <condition> == false. \
Found: true. \
Why this matters: <rationale with source reference>."
Set Membership Assertions
"<set> should contain '<item>'. \
Expected: <set>.contains(\"<item>\") == true. \
Found: false. \
Why this matters: <item> is defined in <config file> and must be present in the runtime set."
Count/Quantity Assertions
"<collection> should contain exactly <n> <items>. \
Expected: <n> entries (<item list>). \
Found: {} entries. \
Why this matters: <rationale explaining expected count based on filtering rules>."
Empty/None Assertions
"<subject> should be <empty|None>. \
Expected: <expected state>. \
Found: {:?}. \
Why this matters: <rationale explaining why this should be empty/None>."
Template Status: Active
Maintained By: pdftract testing team
Last Updated: 2026-07-06