Unit Testing ROT13 Implementations
Write comprehensive unit tests for a ROT13 function. Cover edge cases including empty strings, non-alpha characters, mixed case, double application, and Unicode.
Programming
Detailed Explanation
Testing ROT13 Implementations
A ROT13 function seems simple, but thorough testing requires covering many edge cases. Here is a comprehensive test suite.
Core Test Cases
describe('rot13', () => {
// Basic functionality
test('encodes lowercase letters', () => {
expect(rot13('hello')).toBe('uryyb');
});
test('encodes uppercase letters', () => {
expect(rot13('HELLO')).toBe('URYYB');
});
test('preserves mixed case', () => {
expect(rot13('Hello World')).toBe('Uryyb Jbeyq');
});
});
Self-Reciprocal Property
test('double application returns original', () => {
const original = 'The Quick Brown Fox';
expect(rot13(rot13(original))).toBe(original);
});
test('double application on all printable ASCII', () => {
const all = Array.from({ length: 95 }, (_, i) =>
String.fromCharCode(32 + i)
).join('');
expect(rot13(rot13(all))).toBe(all);
});
Edge Cases
test('empty string returns empty', () => {
expect(rot13('')).toBe('');
});
test('digits pass through unchanged', () => {
expect(rot13('abc123def')).toBe('nop123qrs');
});
test('punctuation and spaces unchanged', () => {
expect(rot13('Hello, World!')).toBe('Uryyb, Jbeyq!');
});
test('single character boundary: a and z', () => {
expect(rot13('a')).toBe('n');
expect(rot13('z')).toBe('m');
expect(rot13('A')).toBe('N');
expect(rot13('Z')).toBe('M');
});
test('boundary: m and n', () => {
expect(rot13('m')).toBe('z');
expect(rot13('n')).toBe('a');
expect(rot13('M')).toBe('Z');
expect(rot13('N')).toBe('A');
});
Non-English Characters
test('non-ASCII letters pass through unchanged', () => {
expect(rot13('café')).toBe('pnsé'); // é is not shifted
expect(rot13('naïve')).toBe('anïir'); // ï is not shifted
});
test('emoji pass through unchanged', () => {
expect(rot13('hello 👋')).toBe('uryyb 👋');
});
test('CJK characters pass through', () => {
expect(rot13('hello世界')).toBe('uryyb世界');
});
Property-Based Testing
For maximum confidence, use property-based testing:
test.prop('rot13 is an involution', [fc.string()], (s) => {
expect(rot13(rot13(s))).toBe(s);
});
test.prop('length is preserved', [fc.string()], (s) => {
expect(rot13(s).length).toBe(s.length);
});
test.prop('non-alpha chars unchanged', [fc.string()], (s) => {
const nonAlpha = s.replace(/[a-zA-Z]/g, '');
const encoded = rot13(s).replace(/[a-zA-Z]/g, '');
expect(encoded).toBe(nonAlpha);
});
Use Case
Comprehensive ROT13 test suites are used in programming courses to teach test-driven development, edge case thinking, and property-based testing. They also serve as practical examples when demonstrating testing frameworks like Jest, Vitest, or pytest.