TypeScript Quality Tools -- Stryker and SonarJS
Status: Requested — validated on experimental branch
Repository: arda-frontend-app
Validated branch: jmpicnic/stryker-exp
Summary
Section titled “Summary”Two complementary quality tools have been validated for adoption:
- Stryker — mutation testing. Makes small automated changes to production code (mutants) and runs tests. Surviving mutants reveal test gaps.
- SonarJS — complexity metrics. Measures cognitive and cyclomatic complexity via ESLint rules.
The SonarJS portion has a full proposal at SonarJS Integration and is ready to implement. The Stryker portion is still in the requested state.
Stryker Mutation Testing
Section titled “Stryker Mutation Testing”What It Does
Section titled “What It Does”Stryker creates thousands of small source mutations (flip operators, replace strings, remove blocks), runs the test suite for each, and identifies “surviving” mutants — mutations that did not cause any test to fail. Surviving mutants indicate gaps in test effectiveness.
Mutation score = (killed + timeout) / total mutants. Focus on the production code score.
Baseline Results
Section titled “Baseline Results”Trial run on itemFormValidator.ts: 85.71% mutation score (6 killed, 1 survived, 4 TS errors). The surviving mutant was typeof form.name === 'string' replaced with true — no test covers the non-string case.
Known Restrictions (Next.js + Stryker SWC)
Section titled “Known Restrictions (Next.js + Stryker SWC)”Stryker’s instrumenter breaks three Next.js SWC compile-time validations. Three files must be excluded from mutation:
| File | Issue |
|---|---|
src/app/order-queue/page.tsx | next/dynamic() options must be object literal |
src/app/receiving/page.tsx | Same as above |
src/components/ui/loader.tsx | <style jsx> children must be template literals |
These files are still tested — just not mutated. The exclusions can be removed if SWC compatibility improves.
Configuration Files Needed
Section titled “Configuration Files Needed”stryker.config.mjs— main config with Jest runner, TypeScript checker, HTML reporter.jest.config.stryker.js— restricted Jest config that skipssrc/tests/and mocksnext/dynamic.tsconfig.stryker.json— excludes test/mock/e2e files for the TypeScript checker.__mocks__/next/dynamic.js— mock to avoid SWC validation errors.
CI Integration
Section titled “CI Integration”Recommended: PR-scoped mutation testing (only files changed in the PR). Full codebase runs (35,000+ mutants) take 13-20 hours on a 4-core machine and are suited for weekly scheduled jobs.
Ratcheting Strategy
Section titled “Ratcheting Strategy”- Week 1: Establish baselines with permissive thresholds (SonarJS cognitive 25, cyclomatic 20; no Stryker break threshold).
- Weeks 2-4: Fix worst hotspots. Run scoped Stryker on
src/lib/to establish mutation score baseline. - Month 2: Tighten SonarJS thresholds (cognitive 20, cyclomatic 15). Set
thresholds.break: 60for Stryker onsrc/lib/. - Ongoing: Add Stryker PR gate. Ratchet SonarJS
--max-warningsdown each sprint.
Copyright: © Arda Systems 2025-2026, All rights reserved