Testing
Rut.ts has comprehensive test coverage to ensure reliability.
Test Suite#
The library is tested using Jest with 523 test cases covering all functions and edge cases.
Shell
npm testCoverage Statistics#
- 16 Test suites (one per public function, plus error, property-based, differential, bundle-smoke, and type-level suites)
- 523 Test cases (comprehensive coverage)
- 100% Pass rate ✅
Beyond example-based tests#
Example-based unit tests are only part of the story. The suite also runs:
- Property-based testing with fast-check — generated inputs assert invariants (round-tripping, idempotence, verifier correctness) across large random samples rather than a handful of hand-picked cases.
- A seeded, reproducible differential harness vs frozen v3.4.0 and v4.1.0 baselines — the current implementation is compared against verbatim snapshots of both prior major lines (
validateand, for 4.1.0,equals) on shared inputs; a fixed seed keeps any divergence reproducible. - Periodic Stryker mutation testing — mutants are injected to confirm the tests actually fail when behavior changes, reaching ~94% mutation score on the Modulo 11 hot path.
What's Tested#
✅ Valid RUT Cases#
- Different formats (with/without dots, hyphens)
- K verifier (uppercase and lowercase)
- 8 and 9 character RUTs
- All verifier digits (0-9, K)
✅ Invalid RUT Cases#
- Wrong verifier digits
- Leading-zero padding (rejected by the acceptance predicates since 5.0.0)
- Too short/long RUTs
- Invalid characters
- K not at the end
- Empty strings
- Non-string inputs
✅ Edge Cases#
- Body bounds: 7-digit floor (
1.000.000-9is the smallest valid RUT) and 8-digit maximum (99.999.999-9); just-under-minimum inputs are rejected - Verifier digit 0
- Multiple K letters
- Special characters
- Whitespace handling
- Parentheses
✅ Safe Mode#
- The 7 throwing helpers (
clean,format,decompose,getBody,getVerifier,calculateVerifier,mask) tested withthrowOnError: false - Null return validation
- Combined options testing
✅ Incremental Formatting#
- Progressive formatting at each length
- Hyphen appearance at 8+ chars
- Leading zeros in incremental mode
- Very long inputs
- Empty inputs
✅ Strict Mode#
- Suspicious pattern detection
- Normal RUTs pass strict mode
- Edge cases with strict mode
Test Organization#
Tests are organized by function:
Code
tests/
├── validate.test.ts (106 tests)
├── format.test.ts (69 tests)
├── clean.test.ts (62 tests)
├── calculateVerifier.test.ts (47 tests)
├── equals.test.ts (47 tests, default + requireValid:false modes)
├── getVerifier.test.ts (41 tests)
├── getBody.test.ts (29 tests)
├── decompose.test.ts (21 tests)
├── generate.test.ts (19 tests)
├── InvalidRutError.test.ts (18 tests)
├── property.test.ts (18 tests, property-based via fast-check)
├── isValidRut.test.ts (15 tests)
├── differential.test.ts (13 tests, full corpus opt-in via RUN_DIFFERENTIAL=1)
├── mask.test.ts (13 tests)
├── dist.smoke.test.ts (4 tests, runs against the built bundle)
└── types.test.ts (1 test, compile-time type assertions)
Each test file includes:
describeblocks for organization- Happy path tests
- Error case tests
- Edge case tests
- Safe mode tests
Running Tests#
Shell
# Run all tests
npm test
# Run specific test file
npm test validate
# Run in watch mode
npm test -- --watch
# Run with coverage
npm test -- --coverageExample Test Cases#
validate() Tests#
TypeScript
describe('validate', () => {
test('validates correct RUTs', () => {
expect(validate('12.345.678-5')).toBe(true)
expect(validate('18.972.631-7')).toBe(true)
})
test('rejects invalid RUTs', () => {
expect(validate('12.345.678-0')).toBe(false)
expect(validate('invalid')).toBe(false)
})
test('strict mode rejects suspicious patterns', () => {
expect(validate('11.111.111-1', { strict: true })).toBe(false)
})
})format() Tests#
TypeScript
describe('format', () => {
test('formats with dots', () => {
expect(format('123456785')).toBe('12.345.678-5')
})
test('formats without dots', () => {
expect(format('123456785', { dots: false })).toBe('12345678-5')
})
test('incremental formatting', () => {
expect(format('1234', { incremental: true })).toBe('1.234')
expect(format('12345678', { incremental: true })).toBe('1.234.567-8')
})
})Safe Mode Tests#
TypeScript
describe('safe mode', () => {
test('returns null instead of throwing', () => {
expect(clean('invalid', { throwOnError: false })).toBeNull()
expect(format('123', { throwOnError: false })).toBeNull()
expect(decompose('abc', { throwOnError: false })).toBeNull()
})
})Contributing Tests#
When contributing, please:
- Add tests for new features
- Ensure all tests pass
- Maintain test organization with
describeblocks - Test both happy paths and error cases
- Include edge cases
- Test safe mode behavior
See Contributing for more details.