Skip to content

feat: add measurement-validator module (Phase 1 & 2)#4

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/add-measurement-validator-module
Draft

feat: add measurement-validator module (Phase 1 & 2)#4
Copilot wants to merge 3 commits intomainfrom
copilot/add-measurement-validator-module

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 4, 2026

Adds a src/measurement-validator/ module that detects and classifies divergence between Pretext (canvas) and DOM text measurements, with multi-language fixture coverage and report generation.

Core module (src/measurement-validator/)

  • types.tsMeasurementSample, MeasurementResult, LineComparison, DivergenceAnalysis, SEVERITY_THRESHOLDS (exact < 0.1px, minor < 0.5px, major < 2.0px, critical ≥ 2.0px)
  • dom-adapter.ts — DOM measurement via offsetHeight/offsetWidth; measureLineWidths returns container width per line (Range-based per-line accuracy is a known follow-up)
  • comparator.tsMeasurementComparator.compare(sample, pretextLayout)MeasurementResult; classifySeverity(delta)
  • classifier.tsclassifyDivergence tests causes in priority order: font fallback (widths similar to serif → font not loaded) → bidi shaping (RTL Unicode ranges) → emoji → browser quirk (Safari UA)
  • test-suite.tsTestSuite accepts an optional LayoutProvider callback so callers supply real Pretext layout; omitting it runs in DOM-only mode (all Pretext widths = 0)
  • report-generator.tsgenerateJSONReport, generateConsoleSummary, generateDetailedReport, generateLanguageBreakdown
  • index.ts — full public re-exports

Test fixtures (test/fixtures/) — 29 samples, 13+ languages

english-samples.json (10), rtl-samples.json (5: Arabic/Hebrew/Urdu), cjk-samples.json (5: Chinese/Japanese/Korean), complex-script-samples.json (5: Thai/Myanmar/Khmer/Hindi), mixed-bidi-samples.json (4: mixed RTL+LTR)

Tests (test/)

  • measurement-validator.test.ts — severity thresholds, report generators, fixture shape validation, MeasurementComparator integration (DOM mocked via Reflect.set)
  • classifier.test.tsdetectBidi, detectEmoji, detectBrowserQuirk, classifyDivergence pass/diverge paths; UA-based quirk tests set and clean up globalThis.navigator

Docs (docs/)

measurement-validator.md (API reference), classifier-guide.md (per-detector usage), language-matrix.md (support matrix + known limitations per script)

Usage

import { MeasurementComparator, classifyDivergence, generateConsoleSummary } from './src/measurement-validator/index.ts'

const comparator = new MeasurementComparator()
const result = await comparator.compare(
  { text: 'Hello world', font: '16px Arial', maxWidth: 400, lineHeight: 20 },
  layoutWithLines(prepare('Hello world', '16px Arial'), 400, 20),
)
const analysis = await classifyDivergence(result, sample)
// analysis.rootCause → 'font_fallback' | 'bidi_shaping' | 'emoji_rendering' | 'browser_quirk' | 'unknown'
console.log(generateConsoleSummary([result]))
Original prompt

Phase 1 & 2: Complete Measurement Validator Implementation

EXECUTIVE SUMMARY

Build a complete Measurement Validator module for Pretext that:

  1. Detects divergence between canvas (Pretext) and DOM measurements
  2. Identifies root causes (font fallback, bidi, emoji, browser quirks)
  3. Supports 20+ languages (English, Arabic, Chinese, Japanese, Thai, etc.)
  4. Provides actionable reports (JSON, console, detailed)
  5. Integrates seamlessly with existing Pretext test infrastructure

FILES TO CREATE - PHASE 1 & 2 COMBINED

CORE MODULE (src/measurement-validator/)

1. types.ts - All TypeScript interfaces

interface MeasurementSample
interface MeasurementResult
interface LineComparison
interface DivergenceAnalysis
const SEVERITY_THRESHOLDS

2. dom-adapter.ts - Browser DOM measurement

async function measureDOMText(sample)
function getComputedLineHeight(element)
function measureLineWidths(container, lineCount)

3. comparator.ts - Pretext vs DOM comparison

class MeasurementComparator {
  async compare(sample, pretextLayout)
}
function classifySeverity(delta)

4. classifier.ts - Root cause detection

async function classifyDivergence(result, sample)
async function detectFontFallback(sample)
function detectBidi(sample)
function detectEmoji(sample)
function detectBrowserQuirk(sample)

5. test-suite.ts - Multi-language test runner

class TestSuite {
  async load(corpusPath)
  async run()
  summarize(results)
  async runByLanguage(languageGroup)
}

6. report-generator.ts - Output formatting

function generateJSONReport(results)
function generateConsoleSummary(results)
function generateDetailedReport(results)
function generateLanguageBreakdown(results)

7. index.ts - Public API exports

export { MeasurementComparator }
export { measureDOMText }
export { classifyDivergence }
export { TestSuite }
export { generateJSONReport, generateConsoleSummary }
export type { MeasurementSample, MeasurementResult, DivergenceAnalysis }

TEST SUITE (test/)

8. measurement-validator.test.ts - Phase 1 integration tests

  • Test basic measurement comparison
  • Test all English fixtures
  • Test report generation

9. classifier.test.ts - Phase 2 classifier tests

  • Test font fallback detection
  • Test bidi detection
  • Test emoji detection
  • Test browser quirk detection

TEST FIXTURES (test/fixtures/)

10. english-samples.json - 10 English test cases
11. rtl-samples.json - 5 RTL test cases (Arabic, Hebrew, Urdu)
12. cjk-samples.json - 5 CJK test cases (Chinese, Japanese, Korean)
13. complex-script-samples.json - 5 complex script tests (Thai, Myanmar, Khmer)
14. mixed-bidi-samples.json - 4 mixed RTL/LTR test cases

DOCUMENTATION (docs/)

15. measurement-validator.md - Getting started + API reference
16. classifier-guide.md - How to use classifier + examples
17. language-matrix.md - Language support matrix + known issues


IMPLEMENTATION - ALL CODE READY TO PASTE

1. src/measurement-validator/types.ts

/**
 * Measurement Validator Types
 */

export interface MeasurementSample {
  text: string
  font: string
  maxWidth: number
  lineHeight?: number
  whiteSpace?: 'normal' | 'pre-wrap'
}

export interface LineComparison {
  index: number
  text: string
  pretextWidth: number
  domWidth: number
  delta: number
  percentError: number
  severity: 'exact' | 'minor' | 'major' | 'critical'
}

export interface MeasurementResult {
  sample: MeasurementSample
  lines: LineComparison[]
  totalLines: number
  exactMatches: number
  minorDelta: number
  majorDelta: number
  criticalDelta: number
  overallSeverity: 'pass' | 'warning' | 'error' | 'critical'
  timestamp: string
  executionTimeMs: number
}

export interface DivergenceAnalysis {
  detected: boolean
  severity: 'minor' | 'major' | 'critical'
  rootCause?: 'font_fallback' | 'bidi_shaping' | 'emoji_rendering' | 'browser_quirk' | 'variable_font' | 'unknown'
  confidence: number
  recommendation: string
  details: Record<string, unknown>
}

export const SEVERITY_THRESHOLDS = {
  exact: 0.1,
  minor: 0.5,
  major: 2.0,
  critical: Infinity,
} as const

2. src/measurement-validator/dom-adapter.ts

/**
 * DOM Measurement Adapter
 */

import type { MeasurementSample } from './types'

export interface DOMTextMetrics {
  lineCount: number
  lineWidths: number[]
  totalHeight: number
  firstLineHeight: number
}

export async function measureDOMText(sample: MeasurementSample): Promise<DOMTextMetrics> {
  if (typeof document !== 'undefined' && document.fonts) {
    await document.fonts.ready
  }

  const container = document.createElement('div')
  container.style.position = 'absolute'
  container.style.visibility = 'hidden'
  container.style.left = '-9999px'
  container.style.top = '-9999px'
  container.style.font = sample.font
  container...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Copilot AI and others added 2 commits April 4, 2026 20:17
…yout provider, docs

Agent-Logs-Url: https://github.com/Himaan1998Y/pretext/sessions/3d85a02c-aa18-40cd-b13d-37f52bf0883c

Co-authored-by: Himaan1998Y <210527591+Himaan1998Y@users.noreply.github.com>
Copilot AI changed the title [WIP] Add complete measurement validator implementation for Pretext feat: add measurement-validator module (Phase 1 & 2) Apr 4, 2026
Copilot AI requested a review from Himaan1998Y April 4, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants