@@ -0,0 +1,11 @@ | |||||
root = true | |||||
[*] | |||||
charset = utf-8 | |||||
end_of_line = lf | |||||
indent_size = 2 | |||||
indent_style = space | |||||
insert_final_newline = true | |||||
max_line_length = 120 | |||||
tab_width = 8 | |||||
trim_trailing_whitespace = true |
@@ -0,0 +1,92 @@ | |||||
.DS_Store | |||||
.AppleDouble | |||||
.LSOverride | |||||
._* | |||||
.DocumentRevisions-V100 | |||||
.fseventsd | |||||
.Spotlight-V100 | |||||
.TemporaryItems | |||||
.Trashes | |||||
.VolumeIcon.icns | |||||
.com.apple.timemachine.donotpresent | |||||
.AppleDB | |||||
.AppleDesktop | |||||
Network Trash Folder | |||||
Temporary Items | |||||
.apdisk | |||||
.idea/ | |||||
cmake-build-*/ | |||||
*.iws | |||||
out/ | |||||
.idea_modules/ | |||||
atlassian-ide-plugin.xml | |||||
com_crashlytics_export_strings.xml | |||||
crashlytics.properties | |||||
crashlytics-build.properties | |||||
fabric.properties | |||||
.vscode/ | |||||
*.code-workspace | |||||
.history/ | |||||
Thumbs.db | |||||
Thumbs.db:encryptable | |||||
ehthumbs.db | |||||
ehthumbs_vista.db | |||||
*.stackdump | |||||
[Dd]esktop.ini | |||||
$RECYCLE.BIN/ | |||||
*.cab | |||||
*.msi | |||||
*.msix | |||||
*.msm | |||||
*.msp | |||||
*.lnk | |||||
logs | |||||
*.log | |||||
npm-debug.log* | |||||
yarn-debug.log* | |||||
yarn-error.log* | |||||
lerna-debug.log* | |||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |||||
pids | |||||
*.pid | |||||
*.seed | |||||
*.pid.lock | |||||
lib-cov | |||||
coverage | |||||
*.lcov | |||||
.nyc_output | |||||
.grunt | |||||
bower_components | |||||
.lock-wscript | |||||
build/Release | |||||
node_modules/ | |||||
jspm_packages/ | |||||
web_modules/ | |||||
*.tsbuildinfo | |||||
.npm | |||||
.eslintcache | |||||
.rpt2_cache/ | |||||
.rts2_cache_cjs/ | |||||
.rts2_cache_es/ | |||||
.rts2_cache_umd/ | |||||
.node_repl_history | |||||
*.tgz | |||||
.yarn-integrity | |||||
.env | |||||
.env.test | |||||
.cache | |||||
.parcel-cache | |||||
.next | |||||
.nuxt | |||||
dist | |||||
.cache/ | |||||
.vuepress/dist | |||||
.serverless/ | |||||
.fusebox/ | |||||
.dynamodb/ | |||||
.tern-port | |||||
.vscode-test | |||||
.yarn/cache | |||||
.yarn/unplugged | |||||
.yarn/build-state.yml | |||||
.pnp.* |
@@ -0,0 +1,11 @@ | |||||
{ | |||||
"printWidth": 120, | |||||
"semi": false, | |||||
"singleQuote": true, | |||||
"jsxSingleQuote": false, | |||||
"trailingComma": "all", | |||||
"arrowParens": "always", | |||||
"jsxBracketSameLine": false, | |||||
"quoteProps": "as-needed", | |||||
"endOfLine": "lf" | |||||
} |
@@ -0,0 +1,21 @@ | |||||
MIT License | |||||
Copyright (c) 2020 Allan Crisostomo | |||||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
of this software and associated documentation files (the "Software"), to deal | |||||
in the Software without restriction, including without limitation the rights | |||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the Software is | |||||
furnished to do so, subject to the following conditions: | |||||
The above copyright notice and this permission notice shall be included in all | |||||
copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
SOFTWARE. |
@@ -0,0 +1,27 @@ | |||||
# TSDX Bootstrap | |||||
This project was bootstrapped with [TSDX](https://github.com/jaredpalmer/tsdx). | |||||
## Local Development | |||||
Below is a list of commands you will probably find useful. | |||||
### `npm start` or `yarn start` | |||||
Runs the project in development/watch mode. Your project will be rebuilt upon changes. TSDX has a special logger for you convenience. Error messages are pretty printed and formatted for compatibility VS Code's Problems tab. | |||||
<img src="https://user-images.githubusercontent.com/4060187/52168303-574d3a00-26f6-11e9-9f3b-71dbec9ebfcb.gif" width="600" /> | |||||
Your library will be rebuilt if you make edits. | |||||
### `npm run build` or `yarn build` | |||||
Bundles the package to the `dist` folder. | |||||
The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module). | |||||
<img src="https://user-images.githubusercontent.com/4060187/52168322-a98e5b00-26f6-11e9-8cf6-222d716b75ef.gif" width="600" /> | |||||
### `npm test` or `yarn test` | |||||
Runs the test watcher (Jest) in an interactive mode. | |||||
By default, runs tests related to files changed since the last commit. |
@@ -0,0 +1,36 @@ | |||||
{ | |||||
"version": "0.1.0", | |||||
"license": "MIT", | |||||
"main": "dist/index.js", | |||||
"typings": "dist/index.d.ts", | |||||
"files": [ | |||||
"dist", | |||||
"src" | |||||
], | |||||
"engines": { | |||||
"node": ">=10" | |||||
}, | |||||
"scripts": { | |||||
"start": "tsdx watch", | |||||
"build": "tsdx build", | |||||
"test": "tsdx test --verbose", | |||||
"lint": "tsdx lint", | |||||
"prepare": "tsdx build" | |||||
}, | |||||
"peerDependencies": {}, | |||||
"husky": { | |||||
"hooks": { | |||||
"pre-commit": "tsdx lint" | |||||
} | |||||
}, | |||||
"name": "@theoryofnekomata/number-name", | |||||
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com> (https://modal.sh)", | |||||
"module": "dist/number-name.esm.js", | |||||
"devDependencies": { | |||||
"fast-check": "^2.1.0", | |||||
"husky": "^4.2.5", | |||||
"tsdx": "^0.13.2", | |||||
"tslib": "^2.0.1", | |||||
"typescript": "^3.9.7" | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
export default () => { | |||||
throw Error('Not yet implemented!') | |||||
} |
@@ -0,0 +1,81 @@ | |||||
import getHundredName from './getHundredName' | |||||
it('should exist', () => { | |||||
expect(getHundredName).toBeDefined() | |||||
}) | |||||
it('should be a callable', () => { | |||||
expect(typeof getHundredName).toBe('function') | |||||
}) | |||||
it('should accept 2 arguments', () => { | |||||
expect(getHundredName).toHaveLength(2) | |||||
}) | |||||
describe('on 0 in tens place', () => { | |||||
test.each` | |||||
ones | onesName | |||||
${0} | ${'zero'} | |||||
${1} | ${'one'} | |||||
${2} | ${'two'} | |||||
${3} | ${'three'} | |||||
${4} | ${'four'} | |||||
${5} | ${'five'} | |||||
${6} | ${'six'} | |||||
${7} | ${'seven'} | |||||
${8} | ${'eight'} | |||||
${9} | ${'nine'} | |||||
`(`should return "$onesName" for $ones`, ({ ones, onesName, }) => { | |||||
expect(getHundredName(0, ones)).toBe(onesName) | |||||
}) | |||||
}) | |||||
describe('on 1 in tens place', () => { | |||||
test.each` | |||||
ones | tenPlusName | |||||
${0} | ${'ten'} | |||||
${1} | ${'eleven'} | |||||
${2} | ${'twelve'} | |||||
${3} | ${'thirteen'} | |||||
${4} | ${'fourteen'} | |||||
${5} | ${'fifteen'} | |||||
${6} | ${'sixteen'} | |||||
${7} | ${'seventeen'} | |||||
${8} | ${'eighteen'} | |||||
${9} | ${'nineteen'} | |||||
`(`should return "$tenPlusName" for 1$ones`, ({ ones, tenPlusName, }) => { | |||||
expect(getHundredName(1, ones)).toBe(tenPlusName) | |||||
}) | |||||
}) | |||||
describe.each` | |||||
tens | tensName | |||||
${2} | ${'twenty'} | |||||
${3} | ${'thirty'} | |||||
${4} | ${'forty'} | |||||
${5} | ${'fifty'} | |||||
${6} | ${'sixty'} | |||||
${7} | ${'seventy'} | |||||
${8} | ${'eighty'} | |||||
${9} | ${'ninety'} | |||||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||||
test.each` | |||||
ones | onesName | |||||
${0} | ${''} | |||||
${1} | ${' one'} | |||||
${2} | ${' two'} | |||||
${3} | ${' three'} | |||||
${4} | ${' four'} | |||||
${5} | ${' five'} | |||||
${6} | ${' six'} | |||||
${7} | ${' seven'} | |||||
${8} | ${' eight'} | |||||
${9} | ${' nine'} | |||||
`(`should return "${tensName}$onesName" for ${tens}$ones`, ({ ones, onesName, }) => { | |||||
expect(getHundredName(tens, ones)).toBe([ | |||||
tensName, | |||||
onesName | |||||
].join('')) | |||||
}) | |||||
}) | |||||
@@ -0,0 +1,31 @@ | |||||
import NAMES from './names.json' | |||||
interface GetHundredName { | |||||
(tens: number, ones: number): string, | |||||
} | |||||
const getHundredName: GetHundredName = (tens, ones) => { | |||||
switch (tens) { | |||||
case 0: | |||||
return NAMES.base.units[ones] | |||||
case 1: | |||||
if (ones > 0) { | |||||
return NAMES.base.tenPlus[ones] | |||||
} | |||||
break | |||||
default: | |||||
break | |||||
} | |||||
return ( | |||||
ones > 0 | |||||
? [ | |||||
NAMES.base.tens[tens], | |||||
NAMES.base.units[ones], | |||||
] | |||||
.join(' ') | |||||
: NAMES.base.tens[tens] | |||||
) | |||||
} | |||||
export default getHundredName |
@@ -0,0 +1,30 @@ | |||||
import getThousandName from './getThousandName' | |||||
it('should exist', () => { | |||||
expect(getThousandName).toBeDefined() | |||||
}) | |||||
it('should be a callable', () => { | |||||
expect(typeof getThousandName).toBe('function') | |||||
}) | |||||
it('should accept 3 arguments', () => { | |||||
expect(getThousandName).toHaveLength(3) | |||||
}) | |||||
describe.each` | |||||
hundreds | hundredsName | |||||
${1} | ${'one hundred'} | |||||
${2} | ${'two hundred'} | |||||
${3} | ${'three hundred'} | |||||
${4} | ${'four hundred'} | |||||
${5} | ${'five hundred'} | |||||
${6} | ${'six hundred'} | |||||
${7} | ${'seven hundred'} | |||||
${8} | ${'eight hundred'} | |||||
${9} | ${'nine hundred'} | |||||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||||
it(`should return "${hundredsName}" on ${hundreds}00`, () => { | |||||
expect(getThousandName(hundreds, 0, 0)).toBe(hundredsName) | |||||
}) | |||||
}) |
@@ -0,0 +1,29 @@ | |||||
import getHundredName from './getHundredName' | |||||
import NAMES from './names.json' | |||||
interface GetThousandName { | |||||
(hundreds: number, tens: number, ones: number): string, | |||||
} | |||||
const getThousandName: GetThousandName = (hundreds, tens, ones) => { | |||||
if (hundreds === 0) { | |||||
return getHundredName(tens, ones) | |||||
} | |||||
if (tens === 0 && ones === 0) { | |||||
return [ | |||||
NAMES.base.units[hundreds], | |||||
NAMES.hundred, | |||||
] | |||||
.join(' ') | |||||
} | |||||
return [ | |||||
NAMES.base.units[hundreds], | |||||
NAMES.hundred, | |||||
getHundredName(tens, ones), | |||||
] | |||||
.join(' ') | |||||
} | |||||
export default getThousandName |
@@ -0,0 +1,32 @@ | |||||
{ | |||||
"base": { | |||||
"units": ["zero" , "one" , "two" , "three" , "four" , "five" , "six" , "seven" , "eight" , "nine" ], | |||||
"tenPlus": ["ten" , "eleven" , "twelve" , "thirteen" , "fourteen" , "fifteen" , "sixteen" , "seventeen" , "eighteen" , "nineteen"], | |||||
"tens": ["zero" , "ten" , "twenty" , "thirty" , "forty" , "fifty" , "sixty" , "seventy" , "eighty" , "ninety" ] | |||||
}, | |||||
"prefix": { | |||||
"units": { | |||||
"formal": ["" , "un" , "duo" , "tre" , "quattuor" , "quin" , "sex" , "septen" , "octo" , "novem" ], | |||||
"informal": ["" , "un" , "do" , "tre" , "quattuor" , "quin" , "sex" , "septen" , "octo" , "novem" ] | |||||
}, | |||||
"tens": { | |||||
"formal": ["" , "dec" , "vigin" , "trigin" , "quadragin" , "quinquagin" , "sexagin" , "septuagin" , "octogin" , "nonagin" ], | |||||
"informal": ["" , "dec" , "vigin" , "trigin" , "quadragin" , "quinquagin" , "sexagin" , "septuagin" , "octogin" , "nonagin" ] | |||||
}, | |||||
"hundreds": { | |||||
"formal": ["" , "cen" , "duocen" , "trecen" , "quadringen" , "quingen" , "sescen" , "septingen" , "octingen" , "nongen" ], | |||||
"informal": ["" , "cen" , "ducen" , "trecen" , "quadringen" , "quingen" , "sescen" , "septingen" , "octingen" , "nongen" ] | |||||
}, | |||||
"special": { | |||||
"formal": ["" , "mi" , "bi" , "tri" , "quadri" , "quin" , "sex" , "sept" , "oct" , "non" ], | |||||
"informal": ["" , "mi" , "bi" , "tri" , "quadri" , "quin" , "sex" , "sept" , "oct" , "non" ] | |||||
} | |||||
}, | |||||
"hundred": "hundred", | |||||
"thousand": "thousand", | |||||
"millia": "millia", | |||||
"suffix": { | |||||
"llion": "llion", | |||||
"lliard": "lliard" | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
import getBaseHundredUnit from './getBaseHundredUnit' | |||||
it('should exist', () => { | |||||
expect(getBaseHundredUnit).toBeDefined() | |||||
}) | |||||
it('should be a callable', () => { | |||||
expect(typeof getBaseHundredUnit).toBe('function') | |||||
}) | |||||
it('should accept 3 arguments', () => { | |||||
expect(getBaseHundredUnit).toHaveLength(1) | |||||
}) | |||||
test.each` | |||||
hundreds | hundredsName | hundredsDisplay | |||||
${1} | ${'sandaan'} | ${100} | |||||
${2} | ${'dalawandaan'} | ${200} | |||||
${3} | ${'tatlongdaan'} | ${300} | |||||
${4} | ${'apatnaraan'} | ${400} | |||||
${5} | ${'limandaan'} | ${500} | |||||
${6} | ${'animnaraan'} | ${600} | |||||
${7} | ${'pitongdaan'} | ${700} | |||||
${8} | ${'walongdaan'} | ${800} | |||||
${9} | ${'siyamnaraan'} | ${900} | |||||
`('should return "$hundredsName" on $hundredsDisplay', ({ hundreds, hundredsName, }) => { | |||||
expect(getBaseHundredUnit(hundreds)).toBe(hundredsName) | |||||
}) |
@@ -0,0 +1,28 @@ | |||||
import NAMES from './names.json' | |||||
interface GetBaseHundredUnit { | |||||
(hundreds: number): string | |||||
} | |||||
const getBaseHundredUnit: GetBaseHundredUnit = hundreds => { | |||||
let hundredsUnit = NAMES.base.units[hundreds] | |||||
const hundredsSuffix = NAMES.hundred | |||||
const unitLastCharacter = hundredsUnit.slice(-1) | |||||
switch (unitLastCharacter) { | |||||
case 't': | |||||
case 'm': | |||||
return hundredsUnit + 'nar' + hundredsSuffix.slice(1) | |||||
case 'a': | |||||
if (hundredsUnit.startsWith('i')) { | |||||
hundredsUnit = hundredsUnit.slice(1) | |||||
} | |||||
return hundredsUnit + 'n' + hundredsSuffix | |||||
case 'o': | |||||
default: | |||||
break | |||||
} | |||||
return hundredsUnit + 'ng' + hundredsSuffix | |||||
} | |||||
export default getBaseHundredUnit |
@@ -0,0 +1,30 @@ | |||||
import NAMES from './names.json' | |||||
interface GetBaseTenUnit { | |||||
(tens: number): string | |||||
} | |||||
const getBaseTenUnit: GetBaseTenUnit = (tens) => { | |||||
let tenUnit = NAMES.base.units[tens] | |||||
const tenSuffix = NAMES.ten | |||||
const unitLastCharacter = tenUnit.slice(-1) | |||||
switch (unitLastCharacter) { | |||||
case 't': | |||||
case 'm': | |||||
return tenUnit + 'na' + tenSuffix | |||||
case 'o': | |||||
tenUnit = tenUnit.slice(0, -1) + 'u' | |||||
break | |||||
case 'a': | |||||
if (tenUnit.startsWith('i')) { | |||||
tenUnit = tenUnit.slice(1) | |||||
} | |||||
break | |||||
default: | |||||
break | |||||
} | |||||
return tenUnit + 'm' + tenSuffix | |||||
} | |||||
export default getBaseTenUnit |
@@ -0,0 +1,62 @@ | |||||
import getHundredName from './getHundredName' | |||||
it('should exist', () => { | |||||
expect(getHundredName).toBeDefined() | |||||
}) | |||||
it('should be a callable', () => { | |||||
expect(typeof getHundredName).toBe('function') | |||||
}) | |||||
it('should accept 2 arguments', () => { | |||||
expect(getHundredName).toHaveLength(2) | |||||
}) | |||||
describe('on 0 in tens place', () => { | |||||
test.each` | |||||
ones | onesName | |||||
${0} | ${'sero'} | |||||
${1} | ${'isa'} | |||||
${2} | ${'dalawa'} | |||||
${3} | ${'tatlo'} | |||||
${4} | ${'apat'} | |||||
${5} | ${'lima'} | |||||
${6} | ${'anim'} | |||||
${7} | ${'pito'} | |||||
${8} | ${'walo'} | |||||
${9} | ${'siyam'} | |||||
`(`should return "$onesName" for $ones`, ({ ones, onesName, }) => { | |||||
expect(getHundredName(0, ones)).toBe(onesName) | |||||
}) | |||||
}) | |||||
describe.each` | |||||
tens | tensName | |||||
${2} | ${'dalawampu'} | |||||
${3} | ${'tatlumpu'} | |||||
${4} | ${'apatnapu'} | |||||
${5} | ${'limampu'} | |||||
${6} | ${'animnapu'} | |||||
${7} | ${'pitumpu'} | |||||
${8} | ${'walumpu'} | |||||
${9} | ${'siyamnapu'} | |||||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||||
test.each` | |||||
ones | onesName | |||||
${0} | ${''} | |||||
${1} | ${"'t isa"} | |||||
${2} | ${"'t dalawa"} | |||||
${3} | ${"'t tatlo"} | |||||
${4} | ${"'t apat"} | |||||
${5} | ${"'t lima"} | |||||
${6} | ${"'t anim"} | |||||
${7} | ${"'t pito"} | |||||
${8} | ${"'t walo"} | |||||
${9} | ${"'t siyam"} | |||||
`(`should return "${tensName}$onesName" for ${tens}$ones`, ({ ones, onesName, }) => { | |||||
expect(getHundredName(tens, ones)).toBe([ | |||||
tensName, | |||||
onesName | |||||
].join('')) | |||||
}) | |||||
}) |
@@ -0,0 +1,34 @@ | |||||
import NAMES from './names.json' | |||||
import getTenPlusName from './getTenPlusName' | |||||
import getBaseTenUnit from './getBaseTenUnit' | |||||
interface GetHundredName { | |||||
(tens: number, ones: number): string, | |||||
} | |||||
const getHundredName: GetHundredName = (tens, ones) => { | |||||
switch (tens) { | |||||
case 0: | |||||
return NAMES.base.units[ones] | |||||
case 1: | |||||
if (ones > 0) { | |||||
return getTenPlusName(ones) | |||||
} | |||||
break | |||||
default: | |||||
break | |||||
} | |||||
if (ones > 0) { | |||||
return [ | |||||
getBaseTenUnit(tens), | |||||
"'", | |||||
NAMES.and.slice(1), | |||||
' ', | |||||
NAMES.base.units[ones], | |||||
].join('') | |||||
} | |||||
return getBaseTenUnit(tens) | |||||
} | |||||
export default getHundredName |
@@ -0,0 +1,31 @@ | |||||
import getTenPlusName from './getTenPlusName' | |||||
it('should exist', () => { | |||||
expect(getTenPlusName).toBeDefined() | |||||
}) | |||||
it('should be a callable', () => { | |||||
expect(typeof getTenPlusName).toBe('function') | |||||
}) | |||||
it('should accept 1 argument', () => { | |||||
expect(getTenPlusName).toHaveLength(1) | |||||
}) | |||||
describe('on 1 in tens place', () => { | |||||
test.each` | |||||
ones | tenPlusName | |||||
${0} | ${'sampu'} | |||||
${1} | ${'labing-isa'} | |||||
${2} | ${'labindalawa'} | |||||
${3} | ${'labintatlo'} | |||||
${4} | ${'labing-apat'} | |||||
${5} | ${'labinlima'} | |||||
${6} | ${'labing-anim'} | |||||
${7} | ${'labimpito'} | |||||
${8} | ${'labingwalo'} | |||||
${9} | ${'labinsiyam'} | |||||
`(`should return "$tenPlusName" for 1$ones`, ({ ones, tenPlusName, }) => { | |||||
expect(getTenPlusName(ones)).toBe(tenPlusName) | |||||
}) | |||||
}) |
@@ -0,0 +1,34 @@ | |||||
import NAMES from './names.json' | |||||
interface GetTenPlusName { | |||||
(ones: number): string, | |||||
} | |||||
const getTenPlusName: GetTenPlusName = (ones) => { | |||||
if (ones === 0) { | |||||
return NAMES.base.tens[1] | |||||
} | |||||
const unit = NAMES.base.units[ones] | |||||
const tenPlusPrefix = NAMES.tenPlus | |||||
const unitFirstCharacter = unit.charAt(0) | |||||
switch (unitFirstCharacter) { | |||||
case 'i': | |||||
case 'a': | |||||
return tenPlusPrefix + 'ng-' + unit | |||||
case 'd': | |||||
case 't': | |||||
case 'l': | |||||
case 's': | |||||
return tenPlusPrefix + 'n' + unit | |||||
case 'p': | |||||
return tenPlusPrefix + 'm' + unit | |||||
default: | |||||
break | |||||
} | |||||
return tenPlusPrefix + 'ng' + unit | |||||
} | |||||
export default getTenPlusName |
@@ -0,0 +1,41 @@ | |||||
import getThousandName from './getThousandName' | |||||
it('should exist', () => { | |||||
expect(getThousandName).toBeDefined() | |||||
}) | |||||
it('should be a callable', () => { | |||||
expect(typeof getThousandName).toBe('function') | |||||
}) | |||||
it('should accept 3 arguments', () => { | |||||
expect(getThousandName).toHaveLength(3) | |||||
}) | |||||
describe.each` | |||||
hundreds | hundredsName | |||||
${1} | ${'sandaan'} | |||||
${2} | ${'dalawandaan'} | |||||
${3} | ${'tatlongdaan'} | |||||
${4} | ${'apatnaraan'} | |||||
${5} | ${'limandaan'} | |||||
${6} | ${'animnaraan'} | |||||
${7} | ${'pitongdaan'} | |||||
${8} | ${'walongdaan'} | |||||
${9} | ${'siyamnaraan'} | |||||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||||
test.each` | |||||
ones | onesName | |||||
${1} | ${'isa'} | |||||
${2} | ${'dalawa'} | |||||
${3} | ${'tatlo'} | |||||
${4} | ${'apat'} | |||||
${5} | ${'lima'} | |||||
${6} | ${'anim'} | |||||
${7} | ${'pito'} | |||||
${8} | ${'walo'} | |||||
${9} | ${'siyam'} | |||||
`(`should return "${hundredsName} at $onesName" on ${hundreds}0$ones`, ({ ones, onesName, }) => { | |||||
expect(getThousandName(hundreds, 0, ones)).toBe(hundredsName + ' at ' + onesName) | |||||
}) | |||||
}) |
@@ -0,0 +1,34 @@ | |||||
import getHundredName from './getHundredName' | |||||
import NAMES from './names.json' | |||||
import getBaseHundredUnit from './getBaseHundredUnit' | |||||
interface GetThousandName { | |||||
(hundreds: number, tens: number, ones: number): string, | |||||
} | |||||
const getThousandName: GetThousandName = (hundreds, tens, ones) => { | |||||
if (hundreds === 0) { | |||||
return getHundredName(tens, ones) | |||||
} | |||||
if (tens === 0 && ones === 0) { | |||||
return getBaseHundredUnit(hundreds) | |||||
} | |||||
if (tens === 0) { | |||||
return [ | |||||
getBaseHundredUnit(hundreds), | |||||
NAMES.and, | |||||
NAMES.base.units[ones], | |||||
] | |||||
.join(' ') | |||||
} | |||||
return [ | |||||
getBaseHundredUnit(hundreds), | |||||
getHundredName(tens, ones), | |||||
] | |||||
.join(' ') | |||||
} | |||||
export default getThousandName |
@@ -0,0 +1,180 @@ | |||||
{ | |||||
"base": { | |||||
"units": [ | |||||
"sero", | |||||
"isa", | |||||
"dalawa", | |||||
"tatlo", | |||||
"apat", | |||||
"lima", | |||||
"anim", | |||||
"pito", | |||||
"walo", | |||||
"siyam" | |||||
], | |||||
"tenPlus": [ | |||||
"sampu", | |||||
"labing-isa", | |||||
"labindalawa", | |||||
"labintatlo", | |||||
"labing-apat", | |||||
"labinlima", | |||||
"labing-anim", | |||||
"labimpito", | |||||
"labingwalo", | |||||
"labinsiyam" | |||||
], | |||||
"tens": [ | |||||
"sero", | |||||
"sampu", | |||||
"dalawampu", | |||||
"tatlumpu", | |||||
"apatnapu", | |||||
"limampu", | |||||
"animnapu", | |||||
"pitumpu", | |||||
"walumpu", | |||||
"siyamnapu" | |||||
], | |||||
"hundreds": [ | |||||
"sero", | |||||
"sandaan", | |||||
"dalawandaan", | |||||
"tatlongdaan", | |||||
"apatnaraan", | |||||
"limandaan", | |||||
"animnaraan", | |||||
"pitongdaan", | |||||
"walongdaan", | |||||
"siyamnaraan" | |||||
], | |||||
"thousands": [ | |||||
"sero", | |||||
"sanlibo", | |||||
"dalawanlibo", | |||||
"tatlonglibo", | |||||
"apatnalibo", | |||||
"limanlibo", | |||||
"animnalibo", | |||||
"pitonglibo", | |||||
"walonglibo", | |||||
"siyamnalibo" | |||||
] | |||||
}, | |||||
"prefix": { | |||||
"units": { | |||||
"formal": [ | |||||
"", | |||||
"un", | |||||
"duo", | |||||
"tre", | |||||
"kuwatuwor", | |||||
"kuwin", | |||||
"seks", | |||||
"septen", | |||||
"okto", | |||||
"nobem" | |||||
], | |||||
"informal": [ | |||||
"", | |||||
"un", | |||||
"do", | |||||
"tre", | |||||
"kuwatuwor", | |||||
"kuwin", | |||||
"seks", | |||||
"septen", | |||||
"okto", | |||||
"nobem" | |||||
] | |||||
}, | |||||
"tens": { | |||||
"formal": [ | |||||
"", | |||||
"des", | |||||
"bigin", | |||||
"trigin", | |||||
"kuwadragin", | |||||
"kuwinkuwagin", | |||||
"seksagin", | |||||
"septuwagin", | |||||
"oktogin", | |||||
"nonagin" | |||||
], | |||||
"informal": [ | |||||
"", | |||||
"des", | |||||
"bigin", | |||||
"trigin", | |||||
"kuwadragin", | |||||
"kuwinkuwagin", | |||||
"seksagin", | |||||
"septuwagin", | |||||
"oktogin", | |||||
"nonagin" | |||||
] | |||||
}, | |||||
"hundreds": { | |||||
"formal": [ | |||||
"", | |||||
"sen", | |||||
"duosen", | |||||
"tresen", | |||||
"kuwadringen", | |||||
"kuwingen", | |||||
"sesen", | |||||
"septingen", | |||||
"oktingen", | |||||
"nongen" | |||||
], | |||||
"informal": [ | |||||
"", | |||||
"sen", | |||||
"dusen", | |||||
"tresen", | |||||
"kuwadringen", | |||||
"kuwingen", | |||||
"sesen", | |||||
"septingen", | |||||
"oktingen", | |||||
"nongen" | |||||
] | |||||
}, | |||||
"special": { | |||||
"formal": [ | |||||
"", | |||||
"mi", | |||||
"bi", | |||||
"tri", | |||||
"kuwadri", | |||||
"kuwin", | |||||
"seks", | |||||
"sept", | |||||
"okt", | |||||
"non" | |||||
], | |||||
"informal": [ | |||||
"", | |||||
"mi", | |||||
"bi", | |||||
"tri", | |||||
"kuwadri", | |||||
"kuwin", | |||||
"seks", | |||||
"sept", | |||||
"okt", | |||||
"non" | |||||
] | |||||
} | |||||
}, | |||||
"and": "at", | |||||
"ten": "pu", | |||||
"hundred": "daan", | |||||
"tenPlus": "labi", | |||||
"thousand": "libo", | |||||
"millia": "milya", | |||||
"suffix": { | |||||
"llion": "lyon", | |||||
"lliard": "lyard" | |||||
} | |||||
} |
@@ -0,0 +1,21 @@ | |||||
{ | |||||
"include": ["src", "types"], | |||||
"compilerOptions": { | |||||
"module": "esnext", | |||||
"lib": ["dom", "esnext"], | |||||
"importHelpers": true, | |||||
"declaration": true, | |||||
"sourceMap": true, | |||||
"rootDir": "./src", | |||||
"strict": true, | |||||
"noUnusedLocals": true, | |||||
"noUnusedParameters": true, | |||||
"noImplicitReturns": true, | |||||
"noImplicitAny": true, | |||||
"noFallthroughCasesInSwitch": true, | |||||
"moduleResolution": "node", | |||||
"resolveJsonModule": true, | |||||
"jsx": "react", | |||||
"esModuleInterop": true | |||||
} | |||||
} |