critical priority medium complexity testing pending testing specialist Tier 4

Acceptance Criteria

Test file `test/core/accessibility/contrast_ratio_validator_test.dart` exists and all tests pass
Test group 'relativeLuminance' covers: pure white = 1.0, pure black = 0.0, mid-grey #808080 within ±0.001 of expected 0.2159
Test group 'contrastRatio' covers: white/black = 21.0 ±0.001, black/white = 21.0 (symmetric), identical colors = 1.0
Test group 'validatePair - normal text' covers: ratio >= 4.5 passes AA, ratio < 4.5 fails AA, ratio >= 7.0 passes AAA
Test group 'validatePair - large text' covers: ratio >= 3.0 passes AA, ratio < 3.0 fails AA, ratio >= 4.5 passes AAA
Boundary test: a color pair producing exactly 4.5:1 returns passesAA=true
Boundary test: a color pair producing exactly 4.4999:1 returns passesAA=false
A parameterized test iterates over all pairs in the Accessibility Token Manifest fixture and asserts each passes AA
`flutter test --coverage` reports 100% branch coverage for `contrast_ratio_calculator.dart` and `contrast_ratio_validator.dart`
Tests run in under 5 seconds total

Technical Requirements

frameworks
Flutter
flutter_test
data models
ContrastRatioValidator
ValidationResult
WcagLevel
performance requirements
Full test suite completes in under 5 seconds

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Identify a Color value whose normalized channel falls between 0.03928 and 0.04045 to write the regression test that distinguishes WCAG 2.0 from WCAG 2.2 linearization — for example, a channel value of ~10/255 ≈ 0.0392. The test should assert the luminance matches the 2.4/0.04045 formula result, not the 2.2/0.03928 result. For manifest-driven tests, define a `ColorPairFixture` model and parse the JSON in `setUpAll`. Keep the fixture file minimal (10-15 pairs) to keep tests fast.

Use `const Color(0xFFRRGGBB)` syntax in tests for readability. Group coverage: the `<=0.04045` and `>0.04045` branches in `relativeLuminance` must each be exercised — the regression test above handles this. For `contrastRatio`, the `L1 >= L2` swap branch must be covered by testing both orders (foreground lighter and foreground darker).

Testing Requirements

Use `flutter_test` exclusively — no additional test packages required. Structure tests with nested `group()` blocks matching the class hierarchy: outer group per class, inner group per method. Use `closeTo(expected, delta)` for all floating-point ratio assertions with delta=0.001. For the parameterized manifest test, load `test/fixtures/manifest_color_pairs.json` using `File` and iterate with `for` loop inside a single test case or use `group`/`test` dynamic generation inside a `setUpAll` block.

Verify that `highestLevel` enum values are correct on boundary conditions — this is where off-by-one logic errors hide. Add a regression test for the known WCAG 2.0 vs 2.2 difference: the linearization threshold 0.04045 (not 0.03928) must be used, verified with a color value that falls between the two thresholds.

Component
Contrast Ratio Validator Service
service medium
Epic Risks (3)
high impact medium prob technical

The WCAG 2.2 relative luminance formula requires gamma-corrected sRGB calculations. Floating-point rounding differences between Dart and reference implementations could produce off-by-one classifications for near-threshold color pairs, resulting in pairs that just pass or just fail in CI but behave differently at runtime.

Mitigation & Contingency

Mitigation: Implement the algorithm directly from the WCAG 2.2 specification using the exact linearisation constants. Validate the Dart implementation against the W3C reference test vectors and against a known-good JavaScript implementation for at least 50 color pairs spanning the compliance boundaries.

Contingency: If discrepancies are found, add a configurable tolerance margin (e.g., ±0.005 on the ratio) and flag near-threshold pairs as warnings rather than hard failures, escalating to the design team for manual review.

medium impact high prob scope

The token manifest is a static data file. If developers add new color tokens to the design-token-provider without updating the manifest, the manifest becomes stale and the CI validator produces false negatives — passing builds that contain unvalidated color pairs.

Mitigation & Contingency

Mitigation: Add a CI step that cross-references every token constant exported by the design-token-provider against the manifest at build time, failing if any token is present in the provider but absent from the manifest. Document this requirement clearly in the contributing guide.

Contingency: If drift is detected post-merge, run a full manifest regeneration script and treat the resulting manifest diff as a blocking pull request with mandatory accessibility review.

medium impact medium prob dependency

The flutter_accessibility_lints package (or custom lint rules) may produce false positives on patterns the team deliberately uses — for example, decorative icon widgets that intentionally omit semantic labels. Excessive false positives will lead developers to add blanket ignore comments, undermining the entire lint strategy.

Mitigation & Contingency

Mitigation: Audit the full lint rule set against the existing codebase before enabling rules. Create a documented list of approved ignore-comment patterns with mandatory justification comments. Restrict ignore patterns to decorative-only contexts.

Contingency: If false positive rates exceed 10% of lint output, disable the highest-noise individual rules and replace them with targeted custom lint rules scoped to the specific patterns the team controls.