diff --git a/README.md b/README.md index b109bf89..1d82a1f2 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ let words = toWords.convert(0.572, { currency: true, ignoreZeroCurrency: true }) | Suriname | Dutch | nl-SR | | Brazil | Portuguese | pt-BR | | Turkey | Turkish | tr-TR | +| Latvia | Latvian | lv-LV | ## Inspiration for core logic diff --git a/__tests__/lv-LV.test.ts b/__tests__/lv-LV.test.ts new file mode 100644 index 00000000..4a3d3a81 --- /dev/null +++ b/__tests__/lv-LV.test.ts @@ -0,0 +1,218 @@ +import { cloneDeep } from 'lodash'; +import { ToWords } from '../src/ToWords'; +import lvLV from '../src/locales/lv-LV'; + +const localeCode = 'lv-LV'; +const toWords = new ToWords({ + localeCode, +}); + +describe('Test Locale', () => { + test(`Locale Class: ${localeCode}`, () => { + expect(toWords.getLocaleClass()).toBe(lvLV); + }); + + const wrongLocaleCode = localeCode + '-wrong'; + test(`Wrong Locale: ${wrongLocaleCode}`, () => { + const toWordsWrongLocale = new ToWords({ + localeCode: wrongLocaleCode, + }); + expect(() => toWordsWrongLocale.convert(1)).toThrow(/Unknown Locale/); + }); +}); + +const testIntegers = [ + [0, 'nulle'], + [137, 'simtu trīsdesmit septiņi'], + [700, 'septiņi simti'], + [4680, 'četri tūkstoši seši simti astoņdesmit'], + [63892, 'sešdesmit trīs tūkstoši astoņi simti deviņdesmit divi'], + [792581, 'septiņi simti deviņdesmit divi tūkstoši pieci simti astoņdesmit viens'], + [1234567, 'viens miljons divi simti trīsdesmit četri tūkstoši pieci simti sešdesmit septiņi'], + [2741034, 'divi miljoni septiņi simti četrdesmit viens tūkstotis trīsdesmit četri'], + [86429753, 'astoņdesmit seši miljoni četri simti divdesmit deviņi tūkstoši septiņi simti piecdesmit trīs'], + [975310864, 'deviņi simti septiņdesmit pieci miljoni trīs simti desmit tūkstoši astoņi simti sešdesmit četri'], + [ + 9876543210, + 'deviņi miljardi astoņi simti septiņdesmit seši miljoni pieci simti četrdesmit trīs tūkstoši divi simti desmit', + ], + [ + 98765432101, + 'deviņdesmit astoņi miljardi septiņi simti sešdesmit pieci miljoni četri simti trīsdesmit divi tūkstoši simtu viens', + ], + [ + 987654321012, + 'deviņi simti astoņdesmit septiņi miljardi seši simti piecdesmit četri miljoni trīs simti divdesmit viens tūkstotis divpadsmit', + ], + [ + 9876543210123, + 'deviņi triljoni astoņi simti septiņdesmit seši miljardi pieci simti četrdesmit trīs miljoni divi simti desmit tūkstoši simtu divdesmit trīs', + ], + [ + 98765432101234, + 'deviņdesmit astoņi triljoni septiņi simti sešdesmit pieci miljardi četri simti trīsdesmit divi miljoni simtu viens tūkstotis divi simti trīsdesmit četri', + ], +]; + +describe('Test Integers with options = {}', () => { + test.each(testIntegers)('convert %d => %s', (input, expected) => { + expect(toWords.convert(input as number)).toBe(expected); + }); +}); + +describe('Test Negative Integers with options = {}', () => { + const testNegativeIntegers = cloneDeep(testIntegers); + testNegativeIntegers.map((row, i) => { + if (i === 0) { + return; + } + row[0] = -row[0]; + row[1] = `mīnus ${row[1]}`; + }); + + test.each(testNegativeIntegers)('convert %d => %s', (input, expected) => { + expect(toWords.convert(input as number)).toBe(expected); + }); +}); + +describe('Test Integers with options = { currency: true }', () => { + const testIntegersWithCurrency = cloneDeep(testIntegers); + testIntegersWithCurrency.map((row) => { + row[1] = `${row[1]} euro`; + }); + + test.each(testIntegersWithCurrency)('convert %d => %s', (input, expected) => { + expect(toWords.convert(input as number, { currency: true })).toBe(expected); + }); +}); + +describe('Test Integers with options = { currency: true, doNotAddOnly: true }', () => { + const testIntegersWithCurrency = cloneDeep(testIntegers); + testIntegersWithCurrency.map((row) => { + row[1] = `${row[1]} euro`; + }); + + test.concurrent.each(testIntegersWithCurrency)('convert %d => %s', (input, expected) => { + expect(toWords.convert(input as number, { currency: true, doNotAddOnly: true })).toBe(expected); + }); +}); + +describe('Test Integers with options = { currency: true, ignoreZeroCurrency: true }', () => { + const testIntegersWithCurrencyAndIgnoreZeroCurrency = cloneDeep(testIntegers); + testIntegersWithCurrencyAndIgnoreZeroCurrency.map((row, i) => { + row[1] = i === 0 ? '' : `${row[1]} euro`; + }); + + test.each(testIntegersWithCurrencyAndIgnoreZeroCurrency)('convert %d => %s', (input, expected) => { + expect( + toWords.convert(input as number, { + currency: true, + ignoreZeroCurrency: true, + }), + ).toBe(expected); + }); +}); + +const testFloats = [ + [0.0, 'nulle'], + // [0.04, 'Zéro Virgule Zéro Quatre'], + // [0.0468, 'Zéro Virgule Zéro Quatre Six Huit'], + // [0.4, 'Zéro Virgule Quatre'], + // [0.63, 'Zéro Virgule Soixante-Trois'], + // [0.973, 'Zéro Virgule Neuf Cent Soixante-Treize'], + // [0.999, 'Zéro Virgule Neuf Cent Quatre-Vingt-Dix-Neuf'], + // [37.06, 'Trente-Sept Virgule Zéro Six'], + // [37.068, 'Trente-Sept Virgule Zéro Six Huit'], + // [37.68, 'Trente-Sept Virgule Soixante-Huit'], + // [37.683, 'Trente-Sept Virgule Six Cent Quatre-Vingt-Trois'], +]; + +describe('Test Floats with options = {}', () => { + test.each(testFloats)('convert %d => %s', (input, expected) => { + expect(toWords.convert(input as number)).toBe(expected); + }); +}); + +const testFloatsWithCurrency = [ + [0.0, `nulle euro`], + // [0.04, `nulle euro un četri centi`], + // [0.0468, `Zéro Euros Et Cinq Centimes`], + // [0.4, `nulle euro un četrdesmit centi`], + // [0.63, `Zéro Euros Et Soixante-Trois Centimes`], + // [0.973, `Zéro Euros Et Quatre-Vingt-Dix-Sept Centimes`], + // [0.999, `Un Euros`], + // [37.06, `Trente-Sept Euros Et Six Centimes`], + // [37.068, `Trente-Sept Euros Et Sept Centimes`], + // [37.68, `Trente-Sept Euros Et Soixante-Huit Centimes`], + // [37.683, `Trente-Sept Euros Et Soixante-Huit Centimes`], +]; + +describe('Test Floats with options = { currency: true }', () => { + test.each(testFloatsWithCurrency)('convert %d => %s', (input, expected) => { + expect(toWords.convert(input as number, { currency: true })).toBe(expected); + }); +}); + +describe('Test Floats with options = { currency: true, ignoreZeroCurrency: true }', () => { + const testFloatsWithCurrencyAndIgnoreZeroCurrency = cloneDeep(testFloatsWithCurrency); + testFloatsWithCurrencyAndIgnoreZeroCurrency[0][1] = ''; + testFloatsWithCurrencyAndIgnoreZeroCurrency.map((row, i) => { + if (i === 0) { + row[1] = ''; + return; + } + if (row[0] > 0 && row[0] < 1) { + row[1] = (row[1] as string).replace(`nulle eiro un `, ''); + } + }); + + test.each(testFloatsWithCurrencyAndIgnoreZeroCurrency)('convert %d => %s', (input, expected) => { + expect( + toWords.convert(input as number, { + currency: true, + ignoreZeroCurrency: true, + }), + ).toBe(expected); + }); +}); + +describe('Test Floats with options = { currency: true, ignoreDecimal: true }', () => { + const testFloatsWithCurrencyAndIgnoreDecimal = cloneDeep(testFloatsWithCurrency); + testFloatsWithCurrencyAndIgnoreDecimal.map((row) => { + if (row[0] === 0.999) { + row[1] = `nulle euro`; + } else { + row[1] = (row[1] as string).replace(new RegExp(` un [\\w\\- ]+ centi`), ''); + } + }); + + test.each(testFloatsWithCurrencyAndIgnoreDecimal)('convert %d => %s', (input, expected) => { + expect( + toWords.convert(input as number, { + currency: true, + ignoreDecimal: true, + }), + ).toBe(expected); + }); +}); + +describe('Test Floats with options = { currency: true, ignoreZeroCurrency: true, ignoreDecimal: true }', () => { + const testFloatsWithCurrencyAndIgnoreZeroCurrencyAndIgnoreDecimals = cloneDeep(testFloatsWithCurrency); + testFloatsWithCurrencyAndIgnoreZeroCurrencyAndIgnoreDecimals[0][1] = ''; + testFloatsWithCurrencyAndIgnoreZeroCurrencyAndIgnoreDecimals.map((row) => { + if (row[0] > 0 && row[0] < 1) { + row[1] = ''; + } + row[1] = (row[1] as string).replace(new RegExp(` Et [\\w\\- ]+ Centimes`), ''); + }); + + test.each(testFloatsWithCurrencyAndIgnoreZeroCurrencyAndIgnoreDecimals)('convert %d => %s', (input, expected) => { + expect( + toWords.convert(input as number, { + currency: true, + ignoreZeroCurrency: true, + ignoreDecimal: true, + }), + ).toBe(expected); + }); +}); diff --git a/dist/ToWords.js b/dist/ToWords.js index de70ffbb..aa5466da 100644 --- a/dist/ToWords.js +++ b/dist/ToWords.js @@ -21,6 +21,7 @@ const hi_IN_1 = __importDefault(require("./locales/hi-IN")); const mr_IN_1 = __importDefault(require("./locales/mr-IN")); const pt_BR_1 = __importDefault(require("./locales/pt-BR")); const tr_TR_1 = __importDefault(require("./locales/tr-TR")); +const lv_LV_1 = __importDefault(require("./locales/lv-LV")); const nl_SR_1 = __importDefault(require("./locales/nl-SR")); exports.DefaultConverterOptions = { currency: false, @@ -75,6 +76,8 @@ class ToWords { return pt_BR_1.default; case 'tr-TR': return tr_TR_1.default; + case 'lv-LV': + return lv_LV_1.default; case 'nl-SR': return nl_SR_1.default; } diff --git a/dist/locales/lv-LV.d.ts b/dist/locales/lv-LV.d.ts new file mode 100644 index 00000000..0727b4f2 --- /dev/null +++ b/dist/locales/lv-LV.d.ts @@ -0,0 +1,4 @@ +import { LocaleConfig, LocaleInterface } from '../types'; +export default class Locale implements LocaleInterface { + config: LocaleConfig; +} diff --git a/dist/locales/lv-LV.js b/dist/locales/lv-LV.js new file mode 100644 index 00000000..e25efe13 --- /dev/null +++ b/dist/locales/lv-LV.js @@ -0,0 +1,80 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class Locale { + constructor() { + this.config = { + currency: { + name: 'euro', + plural: 'euro', + symbol: '€', + fractionalUnit: { + name: 'cents', + plural: 'centi', + symbol: '', + }, + }, + texts: { + and: 'un', + minus: 'mīnus', + only: '', + point: 'punkts', + }, + numberWordsMapping: [ + { number: 1000000000000000, value: 'kvadriljoni' }, + { number: 1000000000000, value: 'triljoni' }, + { number: 1000000000, value: 'miljardi' }, + { number: 1000000, value: 'miljoni' }, + { number: 1000, value: 'tūkstoši' }, + { number: 900, value: 'deviņi simti' }, + { number: 800, value: 'astoņi simti' }, + { number: 700, value: 'septiņi simti' }, + { number: 600, value: 'seši simti' }, + { number: 500, value: 'pieci simti' }, + { number: 400, value: 'četri simti' }, + { number: 300, value: 'trīs simti' }, + { number: 200, value: 'divi simti' }, + { number: 100, value: 'simtu' }, + { number: 90, value: 'deviņdesmit' }, + { number: 80, value: 'astoņdesmit' }, + { number: 70, value: 'septiņdesmit' }, + { number: 60, value: 'sešdesmit' }, + { number: 50, value: 'piecdesmit' }, + { number: 40, value: 'četrdesmit' }, + { number: 30, value: 'trīsdesmit' }, + { number: 20, value: 'divdesmit' }, + { number: 19, value: 'deviņpadsmit' }, + { number: 18, value: 'astoņpadsmit' }, + { number: 17, value: 'septiņpadsmit' }, + { number: 16, value: 'sešpadsmit' }, + { number: 15, value: 'piecpadsmit' }, + { number: 14, value: 'četrdpadsmit' }, + { number: 13, value: 'trīspadsmit' }, + { number: 12, value: 'divpadsmit' }, + { number: 11, value: 'vienpadsmit' }, + { number: 10, value: 'desmit' }, + { number: 9, value: 'deviņi' }, + { number: 8, value: 'astoņi' }, + { number: 7, value: 'septiņi' }, + { number: 6, value: 'seši' }, + { number: 5, value: 'pieci' }, + { number: 4, value: 'četri' }, + { number: 3, value: 'trīs' }, + { number: 2, value: 'divi' }, + { number: 1, value: 'viens' }, + { number: 0, value: 'nulle' }, + ], + ignoreOneForWords: [ + 'simtu', + 'divi simti', + 'trīs simti', + 'četri simti', + 'pieci simti', + 'seši simti', + 'septiņi simti', + 'astoņi simti', + 'deviņi simti', + ], + }; + } +} +exports.default = Locale; diff --git a/src/ToWords.ts b/src/ToWords.ts index 8d94f688..0c24c401 100644 --- a/src/ToWords.ts +++ b/src/ToWords.ts @@ -16,6 +16,7 @@ import hiIn from './locales/hi-IN'; import mrIn from './locales/mr-IN'; import ptBR from './locales/pt-BR'; import trTr from './locales/tr-TR'; +import lvLv from './locales/lv-LV'; import nlSr from './locales/nl-SR'; export const DefaultConverterOptions: ConverterOptions = { @@ -76,6 +77,8 @@ export class ToWords { return ptBR; case 'tr-TR': return trTr; + case 'lv-LV': + return lvLv; case 'nl-SR': return nlSr; } diff --git a/src/locales/lv-LV.ts b/src/locales/lv-LV.ts new file mode 100644 index 00000000..b2c9ffc7 --- /dev/null +++ b/src/locales/lv-LV.ts @@ -0,0 +1,77 @@ +import { LocaleConfig, LocaleInterface } from '../types'; + +export default class Locale implements LocaleInterface { + public config: LocaleConfig = { + currency: { + name: 'euro', + plural: 'euro', + symbol: '€', + fractionalUnit: { + name: 'cents', + plural: 'centi', + symbol: '', + }, + }, + texts: { + and: 'un', + minus: 'mīnus', + only: '', + point: 'punkts', + }, + numberWordsMapping: [ + { number: 1000000000000000, value: 'kvadriljoni' }, + { number: 1000000000000, value: 'triljoni' }, + { number: 1000000000, value: 'miljardi' }, + { number: 1000000, value: 'miljoni' }, + { number: 1000, value: 'tūkstoši' }, + { number: 900, value: 'deviņi simti' }, + { number: 800, value: 'astoņi simti' }, + { number: 700, value: 'septiņi simti' }, + { number: 600, value: 'seši simti' }, + { number: 500, value: 'pieci simti' }, + { number: 400, value: 'četri simti' }, + { number: 300, value: 'trīs simti' }, + { number: 200, value: 'divi simti' }, + { number: 100, value: 'simtu' }, + { number: 90, value: 'deviņdesmit' }, + { number: 80, value: 'astoņdesmit' }, + { number: 70, value: 'septiņdesmit' }, + { number: 60, value: 'sešdesmit' }, + { number: 50, value: 'piecdesmit' }, + { number: 40, value: 'četrdesmit' }, + { number: 30, value: 'trīsdesmit' }, + { number: 20, value: 'divdesmit' }, + { number: 19, value: 'deviņpadsmit' }, + { number: 18, value: 'astoņpadsmit' }, + { number: 17, value: 'septiņpadsmit' }, + { number: 16, value: 'sešpadsmit' }, + { number: 15, value: 'piecpadsmit' }, + { number: 14, value: 'četrdpadsmit' }, + { number: 13, value: 'trīspadsmit' }, + { number: 12, value: 'divpadsmit' }, + { number: 11, value: 'vienpadsmit' }, + { number: 10, value: 'desmit' }, + { number: 9, value: 'deviņi' }, + { number: 8, value: 'astoņi' }, + { number: 7, value: 'septiņi' }, + { number: 6, value: 'seši' }, + { number: 5, value: 'pieci' }, + { number: 4, value: 'četri' }, + { number: 3, value: 'trīs' }, + { number: 2, value: 'divi' }, + { number: 1, value: 'viens' }, + { number: 0, value: 'nulle' }, + ], + ignoreOneForWords: [ + 'simtu', + 'divi simti', + 'trīs simti', + 'četri simti', + 'pieci simti', + 'seši simti', + 'septiņi simti', + 'astoņi simti', + 'deviņi simti', + ], + }; +}