amount-to-words-multilang
Version:
Convert numbers to words in multiple languages (EN, TH, FR, JA, DE, ET, ES, FA, ZH)
129 lines (107 loc) • 4.84 kB
text/typescript
import { amountToWords } from '../src/index';
// Helper function to test error handling across locales
function testErrorAcrossLocales(input: number, expectedError: RegExp) {
const locales = ['en', 'th', 'fr', 'ja', 'de', 'et', 'es', 'fa', 'zh'] as const;
locales.forEach(locale => {
expect(() => amountToWords(input, locale)).toThrow(expectedError);
});
}
// Helper function to test valid conversion across locales
function testValidConversionAcrossLocales(amount: number) {
const locales = ['en', 'th', 'fr', 'ja', 'de', 'et', 'es', 'fa', 'zh'] as const;
locales.forEach(locale => {
const result = amountToWords(amount, locale);
expect(typeof result).toBe('string');
expect(result.length).toBeGreaterThan(0);
});
}
describe('Main System Tests', () => {
describe('Locale support', () => {
test('supports all implemented locales', () => {
const testAmount = 1234.56;
expect(() => amountToWords(testAmount, 'en')).not.toThrow();
expect(() => amountToWords(testAmount, 'th')).not.toThrow();
expect(() => amountToWords(testAmount, 'fr')).not.toThrow();
expect(() => amountToWords(testAmount, 'ja')).not.toThrow();
expect(() => amountToWords(testAmount, 'de')).not.toThrow();
expect(() => amountToWords(testAmount, 'et')).not.toThrow();
expect(() => amountToWords(testAmount, 'es')).not.toThrow();
expect(() => amountToWords(testAmount, 'fa')).not.toThrow();
expect(() => amountToWords(testAmount, 'zh')).not.toThrow();
});
test('throws error for unsupported locale', () => {
expect(() => amountToWords(100, 'pt' as any)).toThrow('Unsupported locale: pt');
expect(() => amountToWords(100, 'xyz' as any)).toThrow('Unsupported locale: xyz');
});
test('uses English as default locale', () => {
expect(amountToWords(100)).toBe('one hundred dollars');
});
});
describe('Cross-language consistency', () => {
const testCases = [
{ amount: 0, description: 'zero' },
{ amount: 1, description: 'one' },
{ amount: 11, description: 'eleven' },
{ amount: 21, description: 'twenty-one' },
{ amount: 100, description: 'one hundred' },
{ amount: 1000, description: 'one thousand' },
{ amount: 1234.56, description: 'complex amount' }
];
const locales = ['en', 'th', 'fr', 'ja', 'de', 'et', 'es', 'fa', 'zh'] as const;
testCases.forEach(({ amount, description }) => {
test(`all locales handle ${description} (${amount})`, () => {
testValidConversionAcrossLocales(amount);
});
});
});
describe('Input validation', () => {
test('validates number type', () => {
expect(() => amountToWords('100' as any)).toThrow('Amount must be a number');
expect(() => amountToWords(null as any)).toThrow('Amount must be a number');
expect(() => amountToWords(undefined as any)).toThrow('Amount must be a number');
expect(() => amountToWords({} as any)).toThrow('Amount must be a number');
});
test('handles floating point precision across locales', () => {
testValidConversionAcrossLocales(0.1 + 0.2);
testValidConversionAcrossLocales(1.005);
});
test('handles boundary values across locales', () => {
testValidConversionAcrossLocales(0);
testValidConversionAcrossLocales(0.01);
testValidConversionAcrossLocales(999999.99);
});
});
describe('Error handling consistency', () => {
test('all locales handle negative numbers consistently', () => {
testErrorAcrossLocales(-1, /negative|ลบ|négatif|負|negativ|负数/i);
});
test('all locales handle infinity consistently', () => {
testErrorAcrossLocales(Infinity, /finite|ถูกต้อง|fini|有限|endlich|有限的/i);
});
test('all locales handle NaN consistently', () => {
testErrorAcrossLocales(NaN, /finite|ถูกต้อง|fini|有限|endlich|有限的/i);
});
});
describe('Performance', () => {
test('handles multiple conversions efficiently', () => {
const start = Date.now();
const iterations = 1000;
for (let i = 0; i < iterations; i++) {
amountToWords(Math.random() * 1000000, 'en');
}
const duration = Date.now() - start;
expect(duration).toBeLessThan(5000); // Should complete in less than 5 seconds
});
test('handles large numbers efficiently', () => {
const start = Date.now();
amountToWords(999999999.99, 'en');
amountToWords(999999999.99, 'th');
amountToWords(999999999.99, 'fr');
amountToWords(999999999.99, 'ja');
amountToWords(999999999.99, 'de');
amountToWords(999999999.99, 'zh');
const duration = Date.now() - start;
expect(duration).toBeLessThan(1000); // Should complete in less than 1 second
});
});
});