Skip to content

Commit

Permalink
feat: add support for en-MM
Browse files Browse the repository at this point in the history
  • Loading branch information
mastermunj committed Nov 20, 2020
1 parent e7bae2b commit b48eade
Show file tree
Hide file tree
Showing 8 changed files with 363 additions and 2 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,17 @@ let words = toWords.convert(0.572, { currency: true, ignoreZeroCurrency: true })
## Options
| Option | Type | Default | Description |
| ------------- | ------------- | ------------- | ------------- |
| localeCode | string | 'en-IN' | Locale code for selecting i18n.<br/>Supported Locale: `en-IN`, `en-MU`, `en-US` and `fa-IR`.<br/>Please open PR if more needed. |
| localeCode | string | 'en-IN' | Locale code for selecting i18n. |
| currency | boolean | false | Whether the number to be converted into words written as currency.<br/>*Note: When currency:true, number will be rounded off to two decimals before converting to words* |
| ignoreDecimal | boolean | false | Whether to ignore fractional unit of number while converting into words. |
| ignoreZeroCurrency | boolean | false | Whether to ignore zero currency value while converting into words. |

## Supported Locale
* en-IN (default)
* en-MM
* en-MU
* en-US
* fa-IR

## Inspiration for core logic
[https://stackoverflow.com/a/46221860](https://stackoverflow.com/a/46221860)
214 changes: 214 additions & 0 deletions __tests__/en-MM.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { ToWords } from '../src/to-words';
import cloneDeep from 'lodash/cloneDeep';

const toWords = new ToWords({
localeCode: 'en-MM',
});

const testIntegers = [
[0, 'Zero'],
[137, 'One Hundred Thirty Seven'],
[700, 'Seven Hundred'],
[4680, 'Four Thousand Six Hundred Eighty'],
[63892, 'Sixty Three Thousand Eight Hundred Ninety Two'],
[792581, 'Seven Lakh Ninety Two Thousand Five Hundred Eighty One'],
[2741034, 'Twenty Seven Lakh Forty One Thousand Thirty Four'],
[
86429753,
'Eight Crore Sixty Four Lakh Twenty Nine Thousand Seven Hundred Fifty Three',
],
[
975310864,
'Ninety Seven Crore Fifty Three Lakh Ten Thousand Eight Hundred Sixty Four',
],
[
9876543210,
'Nine Hundred Eighty Seven Crore Sixty Five Lakh Forty Three Thousand Two Hundred Ten',
],
[
98765432101,
'Nine Thousand Eight Hundred Seventy Six Crore Fifty Four Lakh Thirty Two Thousand One Hundred One',
],
[
987654321012,
'Ninety Eight Thousand Seven Hundred Sixty Five Crore Forty Three Lakh Twenty One Thousand Twelve',
],
[
9876543210123,
'Nine Lakh Eighty Seven Thousand Six Hundred Fifty Four Crore Thirty Two Lakh Ten Thousand One Hundred Twenty Three',
],
[
98765432101234,
'Ninety Eight Lakh Seventy Six Thousand Five Hundred Forty Three Crore Twenty One Lakh One Thousand Two Hundred Thirty Four',
],
];

describe('Test Integers with options = {}', () => {
test.each(testIntegers)('convert %d => %s', (input, expected) => {
expect(toWords.convert(input as number)).toBe(expected);
});
});

const testNegativeIntegers = cloneDeep(testIntegers);
testNegativeIntegers.map((row, i) => {
if (i === 0) {
return;
}
row[0] = -row[0];
row[1] = `Minus ${row[1]}`;
});

describe('Test Negative Integers with options = {}', () => {
test.each(testNegativeIntegers)('convert %d => %s', (input, expected) => {
expect(toWords.convert(input as number)).toBe(expected);
});
});

const testIntegersWithCurrency = cloneDeep(testIntegers);
testIntegersWithCurrency.map((row) => {
row[1] = `${row[1]} Kyats Only`;
});

describe('Test Integers with options = { currency: true }', () => {
test.each(testIntegersWithCurrency)('convert %d => %s', (input, expected) => {
expect(toWords.convert(input as number, { currency: true })).toBe(expected);
});
});

const testIntegersWithCurrencyAndIgnoreZeroCurrency = cloneDeep(
testIntegersWithCurrency,
);
testIntegersWithCurrencyAndIgnoreZeroCurrency[0][1] = '';

describe('Test Integers with options = { currency: true, ignoreZeroCurrency: true }', () => {
test.each(testIntegersWithCurrencyAndIgnoreZeroCurrency)(
'convert %d => %s',
(input, expected) => {
expect(
toWords.convert(input as number, {
currency: true,
ignoreZeroCurrency: true,
}),
).toBe(expected);
},
);
});

const testFloats = [
[0.0, 'Zero'],
[0.04, 'Zero Point Zero Four'],
[0.0468, 'Zero Point Zero Four Six Eight'],
[0.4, 'Zero Point Four'],
[0.63, 'Zero Point Sixty Three'],
[0.973, 'Zero Point Nine Hundred Seventy Three'],
[0.999, 'Zero Point Nine Hundred Ninety Nine'],
[37.06, 'Thirty Seven Point Zero Six'],
[37.068, 'Thirty Seven Point Zero Six Eight'],
[37.68, 'Thirty Seven Point Sixty Eight'],
[37.683, 'Thirty Seven Point Six Hundred Eighty Three'],
];

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, `Zero Kyats Only`],
[0.04, `Zero Kyats And Four Pyas Only`],
[0.0468, `Zero Kyats And Five Pyas Only`],
[0.4, `Zero Kyats And Forty Pyas Only`],
[0.63, `Zero Kyats And Sixty Three Pyas Only`],
[0.973, `Zero Kyats And Ninety Seven Pyas Only`],
[0.999, `One Kyats Only`],
[37.06, `Thirty Seven Kyats And Six Pyas Only`],
[37.068, `Thirty Seven Kyats And Seven Pyas Only`],
[37.68, `Thirty Seven Kyats And Sixty Eight Pyas Only`],
[37.683, `Thirty Seven Kyats And Sixty Eight Pyas Only`],
];

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);
});
});

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(`Zero Kyats And `, '');
}
});

describe('Test Floats with options = { currency: true, ignoreZeroCurrency: true }', () => {
test.each(testFloatsWithCurrencyAndIgnoreZeroCurrency)(
'convert %d => %s',
(input, expected) => {
expect(
toWords.convert(input as number, {
currency: true,
ignoreZeroCurrency: true,
}),
).toBe(expected);
},
);
});

const testFloatsWithCurrencyAndIgnoreDecimal = cloneDeep(
testFloatsWithCurrency,
);
testFloatsWithCurrencyAndIgnoreDecimal.map((row) => {
if (row[0] === 0.999) {
row[1] = `Zero Kyats Only`;
} else {
row[1] = (row[1] as string).replace(new RegExp(` And [\\w ]+ Pyas`), '');
}
});

describe('Test Floats with options = { currency: true, ignoreDecimal: true }', () => {
test.each(testFloatsWithCurrencyAndIgnoreDecimal)(
'convert %d => %s',
(input, expected) => {
expect(
toWords.convert(input as number, {
currency: true,
ignoreDecimal: true,
}),
).toBe(expected);
},
);
});

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(` And [\\w ]+ Pyas`), '');
});

describe('Test Floats with options = { currency: true, ignoreZeroCurrency: true, ignoreDecimal: true }', () => {
test.each(testFloatsWithCurrencyAndIgnoreZeroCurrencyAndIgnoreDecimals)(
'convert %d => %s',
(input, expected) => {
expect(
toWords.convert(input as number, {
currency: true,
ignoreZeroCurrency: true,
ignoreDecimal: true,
}),
).toBe(expected);
},
);
});
23 changes: 23 additions & 0 deletions dist/locales/en-MM.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { LocaleInterface } from './locale.interface';
export declare class Locale implements LocaleInterface {
currency: {
name: string;
plural: string;
symbol: string;
fractionalUnit: {
name: string;
plural: string;
symbol: string;
};
};
texts: {
and: string;
minus: string;
only: string;
point: string;
};
numberWordsMapping: {
number: number;
value: string;
}[];
}
58 changes: 58 additions & 0 deletions dist/locales/en-MM.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Locale = void 0;
class Locale {
constructor() {
this.currency = {
name: 'Kyat',
plural: 'Kyats',
symbol: 'K',
fractionalUnit: {
name: 'Pya',
plural: 'Pyas',
symbol: '',
},
};
this.texts = {
and: 'And',
minus: 'Minus',
only: 'Only',
point: 'Point',
};
this.numberWordsMapping = [
{ number: 10000000, value: 'Crore' },
{ number: 100000, value: 'Lakh' },
{ number: 1000, value: 'Thousand' },
{ number: 100, value: 'Hundred' },
{ number: 90, value: 'Ninety' },
{ number: 80, value: 'Eighty' },
{ number: 70, value: 'Seventy' },
{ number: 60, value: 'Sixty' },
{ number: 50, value: 'Fifty' },
{ number: 40, value: 'Forty' },
{ number: 30, value: 'Thirty' },
{ number: 20, value: 'Twenty' },
{ number: 19, value: 'Nineteen' },
{ number: 18, value: 'Eighteen' },
{ number: 17, value: 'Seventeen' },
{ number: 16, value: 'Sixteen' },
{ number: 15, value: 'Fifteen' },
{ number: 14, value: 'Fourteen' },
{ number: 13, value: 'Thirteen' },
{ number: 12, value: 'Twelve' },
{ number: 11, value: 'Eleven' },
{ number: 10, value: 'Ten' },
{ number: 9, value: 'Nine' },
{ number: 8, value: 'Eight' },
{ number: 7, value: 'Seven' },
{ number: 6, value: 'Six' },
{ number: 5, value: 'Five' },
{ number: 4, value: 'Four' },
{ number: 3, value: 'Three' },
{ number: 2, value: 'Two' },
{ number: 1, value: 'One' },
{ number: 0, value: 'Zero' },
];
}
}
exports.Locale = Locale;
2 changes: 2 additions & 0 deletions dist/to-words.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class ToWords {
switch (this.options.localeCode) {
case 'en-IN':
return require('./locales/en-IN').Locale;
case 'en-MM':
return require('./locales/en-MM').Locale;
case 'en-MU':
return require('./locales/en-MU').Locale;
case 'en-US':
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"lint:fix": "npm run lint -- --fix",
"release": "standard-version",
"release:mock": "npm run release -- --dry-run",
"test": "jest --detectOpenHandles --coverage",
"test": "jest --detectOpenHandles --coverage --no-cache",
"test:watch": "npm run test -- --watch"
},
"husky": {
Expand Down
56 changes: 56 additions & 0 deletions src/locales/en-MM.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { LocaleInterface } from './locale.interface';

export class Locale implements LocaleInterface {
public currency = {
name: 'Kyat',
plural: 'Kyats',
symbol: 'K',
fractionalUnit: {
name: 'Pya',
plural: 'Pyas',
symbol: '',
},
};

public texts = {
and: 'And',
minus: 'Minus',
only: 'Only',
point: 'Point',
};

public numberWordsMapping = [
{ number: 10000000, value: 'Crore' },
{ number: 100000, value: 'Lakh' },
{ number: 1000, value: 'Thousand' },
{ number: 100, value: 'Hundred' },
{ number: 90, value: 'Ninety' },
{ number: 80, value: 'Eighty' },
{ number: 70, value: 'Seventy' },
{ number: 60, value: 'Sixty' },
{ number: 50, value: 'Fifty' },
{ number: 40, value: 'Forty' },
{ number: 30, value: 'Thirty' },
{ number: 20, value: 'Twenty' },
{ number: 19, value: 'Nineteen' },
{ number: 18, value: 'Eighteen' },
{ number: 17, value: 'Seventeen' },
{ number: 16, value: 'Sixteen' },
{ number: 15, value: 'Fifteen' },
{ number: 14, value: 'Fourteen' },
{ number: 13, value: 'Thirteen' },
{ number: 12, value: 'Twelve' },
{ number: 11, value: 'Eleven' },
{ number: 10, value: 'Ten' },
{ number: 9, value: 'Nine' },
{ number: 8, value: 'Eight' },
{ number: 7, value: 'Seven' },
{ number: 6, value: 'Six' },
{ number: 5, value: 'Five' },
{ number: 4, value: 'Four' },
{ number: 3, value: 'Three' },
{ number: 2, value: 'Two' },
{ number: 1, value: 'One' },
{ number: 0, value: 'Zero' },
];
}
Loading

0 comments on commit b48eade

Please sign in to comment.