Increase test coverage on separate number systems.master
@@ -0,0 +1,28 @@ | |||
import hundredTimes from './hundredTimes' | |||
it('should exist', () => { | |||
expect(hundredTimes).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof hundredTimes).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(hundredTimes).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'100'} | ${'einhundert'} | |||
${2} | ${'200'} | ${'zweihundert'} | |||
${3} | ${'300'} | ${'dreihundert'} | |||
${4} | ${'400'} | ${'vierhundert'} | |||
${5} | ${'500'} | ${'fünfhundert'} | |||
${6} | ${'600'} | ${'sechshundert'} | |||
${7} | ${'700'} | ${'siebenhundert'} | |||
${8} | ${'800'} | ${'achthundert'} | |||
${9} | ${'900'} | ${'neunhundert'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(hundredTimes(value)).toBe(name) | |||
}) |
@@ -0,0 +1,21 @@ | |||
import NAMES from '../names.json' | |||
interface HundredTimes { | |||
(x100: number): string | |||
} | |||
/** | |||
* Get the name of some number in the hundreds place. | |||
* @param {number} x100 - The number in the hundreds place. | |||
* @returns {string} The name of the number in the hundreds place. | |||
*/ | |||
const hundredTimes: HundredTimes = (x100) => ( | |||
x100 === 0 | |||
? NAMES.units[0] | |||
: [ | |||
NAMES.units[x100], | |||
NAMES.hundred, | |||
].join('') | |||
) | |||
export default hundredTimes |
@@ -0,0 +1,187 @@ | |||
import combiningPrefix from './combiningPrefix' | |||
it('should exist', () => { | |||
expect(combiningPrefix).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof combiningPrefix).toBe('function') | |||
}) | |||
it('should accept 4 arguments', () => { | |||
expect(combiningPrefix).toHaveLength(4) | |||
}) | |||
describe('on 0 in hundreds place', () => { | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
value | display | name | |||
${1} | ${'1'} | ${'mi'} | |||
${2} | ${'2'} | ${'bi'} | |||
${3} | ${'3'} | ${'tri'} | |||
${4} | ${'4'} | ${'quadri'} | |||
${5} | ${'5'} | ${'quinti'} | |||
${6} | ${'6'} | ${'sexti'} | |||
${7} | ${'7'} | ${'septi'} | |||
${8} | ${'8'} | ${'octi'} | |||
${9} | ${'9'} | ${'noni'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(0, 0, value)).toBe(name) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${1} | ${'deci'} | |||
${2} | ${'viginti'} | |||
${3} | ${'triginti'} | |||
${4} | ${'quadraginti'} | |||
${5} | ${'quinquaginti'} | |||
${6} | ${'sexaginti'} | |||
${7} | ${'septuaginti'} | |||
${8} | ${'octoginti'} | |||
${9} | ${'nonaginti'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${tensName} | |||
${1} | ${'un' + tensName} | |||
${2} | ${'duo' + tensName} | |||
${3} | ${'tre' + tensName} | |||
${4} | ${'quattuor' + tensName} | |||
${5} | ${'quin' + tensName} | |||
${6} | ${'sex' + tensName} | |||
${7} | ${'septen' + tensName} | |||
${8} | ${'octo' + tensName} | |||
${9} | ${'novem' + tensName} | |||
`(`should return "$display" for ${tens}$ones`, ({ ones, display, }) => { | |||
expect(combiningPrefix(0, tens, ones)).toBe(display) | |||
}) | |||
}) | |||
}) | |||
describe.each` | |||
hundreds | hundredsName | |||
${1} | ${'cen'} | |||
${2} | ${'duocen'} | |||
${3} | ${'trecen'} | |||
${4} | ${'quadringen'} | |||
${5} | ${'quingen'} | |||
${6} | ${'sescen'} | |||
${7} | ${'septingen'} | |||
${8} | ${'octingen'} | |||
${9} | ${'nongen'} | |||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||
describe.each` | |||
tens | tensName | |||
${0} | ${'ti'} | |||
${1} | ${'deci'} | |||
${2} | ${'viginti'} | |||
${3} | ${'triginti'} | |||
${4} | ${'quadraginti'} | |||
${5} | ${'quinquaginti'} | |||
${6} | ${'sexaginti'} | |||
${7} | ${'septuaginti'} | |||
${8} | ${'octoginti'} | |||
${9} | ${'nonaginti'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${hundredsName + tensName} | |||
${1} | ${hundredsName + 'un' + tensName} | |||
${2} | ${hundredsName + 'duo' + tensName} | |||
${3} | ${hundredsName + 'tre' + tensName} | |||
${4} | ${hundredsName + 'quattuor' + tensName} | |||
${5} | ${hundredsName + 'quin' + tensName} | |||
${6} | ${hundredsName + 'sex' + tensName} | |||
${7} | ${hundredsName + 'septen' + tensName} | |||
${8} | ${hundredsName + 'octo' + tensName} | |||
${9} | ${hundredsName + 'novem' + tensName} | |||
`(`should return "$display" for ${hundreds}${tens}$ones`, ({ ones, display, }) => { | |||
expect(combiningPrefix(hundreds, tens, ones)).toBe(display) | |||
}) | |||
}) | |||
}) | |||
describe.each` | |||
hundredThousands | hundredThousandsName | |||
${1} | ${'cen'} | |||
${2} | ${'duocen'} | |||
${3} | ${'trecen'} | |||
${4} | ${'quadringen'} | |||
${5} | ${'quingen'} | |||
${6} | ${'sescen'} | |||
${7} | ${'septingen'} | |||
${8} | ${'octingen'} | |||
${9} | ${'nongen'} | |||
`('on $hundredThousands in hundred thousands place', ({ hundredThousands, hundredThousandsName, }) => { | |||
describe.each` | |||
tenThousands | tenThousandsName | |||
${0} | ${''} | |||
${1} | ${'dec'} | |||
${2} | ${'vigin'} | |||
${3} | ${'trigin'} | |||
${4} | ${'quadragin'} | |||
${5} | ${'quinquagin'} | |||
${6} | ${'sexagin'} | |||
${7} | ${'septuagin'} | |||
${8} | ${'octogin'} | |||
${9} | ${'nonagin'} | |||
`('on $tenThousands in ten thousands place', ({ tenThousands, tenThousandsName, }) => { | |||
test.each` | |||
thousands | display | name | |||
${0} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milliati'} | |||
${1000} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milliati'} | |||
${2000} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duo' + tenThousandsName + 'milliati'} | |||
${3000} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milliati'} | |||
${4000} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'quattuor' + tenThousandsName + 'milliati'} | |||
${5000} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'quin' + tenThousandsName + 'milliati'} | |||
${6000} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'sex' + tenThousandsName + 'milliati'} | |||
${7000} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milliati'} | |||
${8000} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'octo' + tenThousandsName + 'milliati'} | |||
${9000} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'novem' + tenThousandsName + 'milliati'} | |||
`(`should return "$name" for $display`, ({ thousands, name, }) => { | |||
const kiloHundreds = ( | |||
hundredThousands * 1000 | |||
+ tenThousands * 100 | |||
+ thousands / 100 | |||
) | |||
expect(combiningPrefix( | |||
kiloHundreds, | |||
0, | |||
0, | |||
)).toBe(name) | |||
}) | |||
}) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'1000000'} | ${'milliamilliati'} | |||
${2} | ${'2000000'} | ${'duomilliamilliati'} | |||
${3} | ${'3000000'} | ${'tremilliamilliati'} | |||
${4} | ${'4000000'} | ${'quattuormilliamilliati'} | |||
${5} | ${'5000000'} | ${'quinmilliamilliati'} | |||
${6} | ${'6000000'} | ${'sexmilliamilliati'} | |||
${7} | ${'7000000'} | ${'septenmilliamilliati'} | |||
${8} | ${'8000000'} | ${'octomilliamilliati'} | |||
${9} | ${'9000000'} | ${'novemmilliamilliati'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(value * 10000, 0, 0)).toBe(name) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'1001000'} | ${'milliamilliaunmilliati'} | |||
${2} | ${'2002000'} | ${'duomilliamilliaduomilliati'} | |||
${3} | ${'3003000'} | ${'tremilliamilliatremilliati'} | |||
${4} | ${'4004000'} | ${'quattuormilliamilliaquattuormilliati'} | |||
${5} | ${'5005000'} | ${'quinmilliamilliaquinmilliati'} | |||
${6} | ${'6006000'} | ${'sexmilliamilliasexmilliati'} | |||
${7} | ${'7007000'} | ${'septenmilliamilliaseptenmilliati'} | |||
${8} | ${'8008000'} | ${'octomilliamilliaoctomilliati'} | |||
${9} | ${'9009000'} | ${'novemmilliamillianovemmilliati'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(value * 10010, 0, 0)).toBe(name) | |||
}) | |||
@@ -0,0 +1,109 @@ | |||
import NAMES from '../../names.json' | |||
import ones from './ones' | |||
import tens from './tens' | |||
import hundreds from './hundreds' | |||
interface CombiningPrefix { | |||
( | |||
kiloHundreds: number, | |||
kiloTens: number, | |||
kiloOnes: number, | |||
kiloPower?: number, | |||
): string, | |||
} | |||
const combiningPrefix: CombiningPrefix = ( | |||
kiloHundredsRaw, | |||
kiloTens, | |||
kiloOnes, | |||
kiloPower = 0, | |||
) => { | |||
let kiloHundreds = kiloHundredsRaw | |||
let prefix = '' | |||
const isMillia = kiloHundredsRaw >= 10 | |||
if (isMillia) { | |||
prefix += combiningPrefix( | |||
Math.floor(kiloHundredsRaw / 1000), | |||
Math.floor(kiloHundredsRaw / 100 % 10), | |||
Math.floor(kiloHundredsRaw / 10 % 10), | |||
kiloPower + 1, | |||
) | |||
kiloHundreds = kiloHundredsRaw % 10 | |||
} | |||
const hasHundreds = kiloHundreds > 0 | |||
if (hasHundreds) { | |||
prefix += hundreds(kiloHundreds) | |||
} | |||
if ( | |||
( | |||
kiloPower > 0 | |||
&& ( | |||
( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes > 1 | |||
) | |||
|| ( | |||
( | |||
kiloHundreds > 0 | |||
|| kiloTens > 0 | |||
) | |||
&& kiloOnes > 0 | |||
) | |||
|| ( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes === 1 | |||
&& prefix.endsWith(NAMES.kiloThousand) | |||
) | |||
) | |||
) | |||
) { | |||
// http://www.isthe.com/chongo/tech/math/number/howhigh.html | |||
// Section: Titanic size numbers < 10^3000003 | |||
prefix += ones( | |||
kiloOnes, | |||
false | |||
) | |||
} | |||
if (kiloPower === 0 && kiloOnes > 0) { | |||
const special = kiloHundreds === 0 && kiloTens === 0 | |||
prefix += ones( | |||
kiloOnes, | |||
special | |||
) | |||
if (special && [5, 6].includes(kiloOnes)) { | |||
prefix += 't' | |||
} | |||
} | |||
if (kiloTens > 0) { | |||
prefix += tens(kiloTens) | |||
} | |||
if (kiloPower > 0) { | |||
if (!( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes === 0 | |||
)) { | |||
for (let p = 0; p < kiloPower; p += 1) { | |||
prefix += NAMES.kiloThousand | |||
} | |||
} | |||
return prefix | |||
} | |||
if ( | |||
(kiloHundreds === 0 && kiloTens > 1) | |||
|| (kiloHundreds > 0 && kiloTens !== 1) | |||
|| kiloHundredsRaw >= 10 | |||
) { | |||
prefix += 't' | |||
} | |||
return prefix + 'i' | |||
} | |||
export default combiningPrefix |
@@ -0,0 +1,28 @@ | |||
import hundreds from './hundreds' | |||
it('should exist', () => { | |||
expect(hundreds).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof hundreds).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(hundreds).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'100'} | ${'cen'} | |||
${2} | ${'200'} | ${'duocen'} | |||
${3} | ${'300'} | ${'trecen'} | |||
${4} | ${'400'} | ${'quadringen'} | |||
${5} | ${'500'} | ${'quingen'} | |||
${6} | ${'600'} | ${'sescen'} | |||
${7} | ${'700'} | ${'septingen'} | |||
${8} | ${'800'} | ${'octingen'} | |||
${9} | ${'900'} | ${'nongen'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(hundreds(value)).toBe(name) | |||
}) |
@@ -0,0 +1,9 @@ | |||
import NAMES from '../../names.json' | |||
interface Hundreds { | |||
(kiloHundreds: number): string, | |||
} | |||
const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds] | |||
export default hundreds |
@@ -0,0 +1,49 @@ | |||
import ones from './ones' | |||
it('should exist', () => { | |||
expect(ones).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof ones).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(ones).toHaveLength(2) | |||
}) | |||
describe('on ordinary units', () => { | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${''} | |||
${1} | ${'1'} | ${'un'} | |||
${2} | ${'2'} | ${'duo'} | |||
${3} | ${'3'} | ${'tre'} | |||
${4} | ${'4'} | ${'quattuor'} | |||
${5} | ${'5'} | ${'quin'} | |||
${6} | ${'6'} | ${'sex'} | |||
${7} | ${'7'} | ${'septen'} | |||
${8} | ${'8'} | ${'octo'} | |||
${9} | ${'9'} | ${'novem'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value, false)).toBe(name) | |||
}) | |||
}) | |||
describe('on special units', () => { | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${''} | |||
${1} | ${'1'} | ${'m'} | |||
${2} | ${'2'} | ${'b'} | |||
${3} | ${'3'} | ${'tr'} | |||
${4} | ${'4'} | ${'quadr'} | |||
${5} | ${'5'} | ${'quin'} | |||
${6} | ${'6'} | ${'sex'} | |||
${7} | ${'7'} | ${'sept'} | |||
${8} | ${'8'} | ${'oct'} | |||
${9} | ${'9'} | ${'non'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value, true)).toBe(name) | |||
}) | |||
}) |
@@ -0,0 +1,13 @@ | |||
import NAMES from '../../names.json' | |||
interface Ones { | |||
(kiloOnes: number, special: boolean): string, | |||
} | |||
const ones: Ones = (kiloOnes, special = false) => ( | |||
special | |||
? NAMES.kiloSpecialUnits[kiloOnes] | |||
: NAMES.kiloUnits[kiloOnes] | |||
) | |||
export default ones |
@@ -0,0 +1,28 @@ | |||
import tens from './tens' | |||
it('should exist', () => { | |||
expect(tens).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tens).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tens).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'10'} | ${'dec'} | |||
${2} | ${'20'} | ${'vigin'} | |||
${3} | ${'30'} | ${'trigin'} | |||
${4} | ${'40'} | ${'quadragin'} | |||
${5} | ${'50'} | ${'quinquagin'} | |||
${6} | ${'60'} | ${'sexagin'} | |||
${7} | ${'70'} | ${'septuagin'} | |||
${8} | ${'80'} | ${'octogin'} | |||
${9} | ${'90'} | ${'nonagin'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tens(value)).toBe(name) | |||
}) |
@@ -0,0 +1,9 @@ | |||
import NAMES from '../../names.json' | |||
interface Tens { | |||
(kiloTens: number): string, | |||
} | |||
const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens] | |||
export default tens |
@@ -0,0 +1,30 @@ | |||
import ones from './ones' | |||
it('should exist', () => { | |||
expect(ones).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof ones).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(ones).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${'zero'} | |||
${1} | ${'1'} | ${'ein'} | |||
${2} | ${'2'} | ${'zwei'} | |||
${3} | ${'3'} | ${'drei'} | |||
${4} | ${'4'} | ${'vier'} | |||
${5} | ${'5'} | ${'fünf'} | |||
${6} | ${'6'} | ${'sechs'} | |||
${7} | ${'7'} | ${'sieben'} | |||
${8} | ${'8'} | ${'acht'} | |||
${9} | ${'9'} | ${'neun'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value)).toBe(name) | |||
}) | |||
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface Ones { | |||
(x1: number): string | |||
} | |||
/** | |||
* Get the name of some number in the ones place. | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number in the ones place. | |||
*/ | |||
const ones: Ones = (x1) => NAMES.units[x1] | |||
export default ones |
@@ -0,0 +1,29 @@ | |||
import tenPlus from './tenPlus' | |||
it('should exist', () => { | |||
expect(tenPlus).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tenPlus).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tenPlus).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${0} | ${'10'} | ${'zehn'} | |||
${1} | ${'11'} | ${'elf'} | |||
${2} | ${'12'} | ${'zwölf'} | |||
${3} | ${'13'} | ${'dreizehn'} | |||
${4} | ${'14'} | ${'vierzehn'} | |||
${5} | ${'15'} | ${'fünfzehn'} | |||
${6} | ${'16'} | ${'sechzehn'} | |||
${7} | ${'17'} | ${'siebzehn'} | |||
${8} | ${'18'} | ${'achtzehn'} | |||
${9} | ${'19'} | ${'neunzehn'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tenPlus(value)).toBe(name) | |||
}) |
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface TenPlus { | |||
(ones: number): string | |||
} | |||
/** | |||
* Get the name of some number plus ten. | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number plus ten. | |||
*/ | |||
const tenPlus: TenPlus = (x1) => (x1 === 0 ? NAMES.tenTimes[1] : NAMES.tenPlus[x1]) | |||
export default tenPlus |
@@ -0,0 +1,28 @@ | |||
import tenTimes from './tenTimes' | |||
it('should exist', () => { | |||
expect(tenTimes).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tenTimes).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tenTimes).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'10'} | ${'zehn'} | |||
${2} | ${'20'} | ${'zwanzig'} | |||
${3} | ${'30'} | ${'dreißig'} | |||
${4} | ${'40'} | ${'vierzig'} | |||
${5} | ${'50'} | ${'fünfzig'} | |||
${6} | ${'60'} | ${'sechzig'} | |||
${7} | ${'70'} | ${'siebzig'} | |||
${8} | ${'80'} | ${'achtzig'} | |||
${9} | ${'90'} | ${'neunzig'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tenTimes(value)).toBe(name) | |||
}) |
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface TenTimes { | |||
(x10: number): string | |||
} | |||
/** | |||
* Get the name of some number in the tens place. | |||
* @param {number} x10 - The number in the tens place. | |||
* @returns {string} The name of the number in the tens place. | |||
*/ | |||
const tenTimes: TenTimes = (x10) => NAMES.tenTimes[x10] | |||
export default tenTimes |
@@ -0,0 +1,77 @@ | |||
import tensFn from './tens' | |||
it('should exist', () => { | |||
expect(tensFn).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tensFn).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(tensFn).toHaveLength(2) | |||
}) | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${'zero'} | |||
${1} | ${'ein'} | |||
${2} | ${'zwei'} | |||
${3} | ${'drei'} | |||
${4} | ${'vier'} | |||
${5} | ${'fünf'} | |||
${6} | ${'sechs'} | |||
${7} | ${'sieben'} | |||
${8} | ${'acht'} | |||
${9} | ${'neun'} | |||
`(`should return "$onesName" for $ones`, ({ ones, onesName, }) => { | |||
expect(tensFn(0, ones)).toBe(onesName) | |||
}) | |||
}) | |||
describe('on 1 in tens place', () => { | |||
test.each` | |||
ones | tenPlusName | |||
${0} | ${'zehn'} | |||
${1} | ${'elf'} | |||
${2} | ${'zwölf'} | |||
${3} | ${'dreizehn'} | |||
${4} | ${'vierzehn'} | |||
${5} | ${'fünfzehn'} | |||
${6} | ${'sechzehn'} | |||
${7} | ${'siebzehn'} | |||
${8} | ${'achtzehn'} | |||
${9} | ${'neunzehn'} | |||
`(`should return "$tenPlusName" for 1$ones`, ({ ones, tenPlusName, }) => { | |||
expect(tensFn(1, ones)).toBe(tenPlusName) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${2} | ${'zwanzig'} | |||
${3} | ${'dreißig'} | |||
${4} | ${'vierzig'} | |||
${5} | ${'fünfzig'} | |||
${6} | ${'sechzig'} | |||
${7} | ${'siebzig'} | |||
${8} | ${'achtzig'} | |||
${9} | ${'neunzig'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${'' + tensName} | |||
${1} | ${'einund' + tensName} | |||
${2} | ${'zweiund' + tensName} | |||
${3} | ${'dreiund' + tensName} | |||
${4} | ${'vierund' + tensName} | |||
${5} | ${'fünfund' + tensName} | |||
${6} | ${'sechsund' + tensName} | |||
${7} | ${'siebenund' + tensName} | |||
${8} | ${'achtund' + tensName} | |||
${9} | ${'neunund' + tensName} | |||
`(`should return "$display" for ${tens}$ones`, ({ ones, display, }) => { | |||
expect(tensFn(tens, ones)).toBe(display) | |||
}) | |||
}) |
@@ -0,0 +1,35 @@ | |||
import NAMES from '../names.json' | |||
import ones from '../base/ones' | |||
import tenPlus from '../base/tenPlus' | |||
import getBaseTenTimesName from '../base/tenTimes' | |||
interface Tens { | |||
(x10: number, x1: number): string, | |||
} | |||
const tens: Tens = (x10, x1) => { | |||
switch (x10) { | |||
case 0: | |||
return ones(x1) | |||
case 1: | |||
if (x1 > 0) { | |||
return tenPlus(x1) | |||
} | |||
break | |||
default: | |||
break | |||
} | |||
return ( | |||
x1 > 0 | |||
? [ | |||
ones(x1), | |||
NAMES.and, | |||
getBaseTenTimesName(x10), | |||
] | |||
.join('') | |||
: getBaseTenTimesName(x10) | |||
) | |||
} | |||
export default tens |
@@ -0,0 +1,129 @@ | |||
import getKiloName from './getLongKiloName' | |||
it('should exist', () => { | |||
expect(getKiloName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getKiloName).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(getKiloName).toHaveLength(1) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${0} | ${''} | |||
${1} | ${'Tausend'} | |||
${2} | ${'Million'} | |||
${3} | ${'Milliard'} | |||
${4} | ${'Billion'} | |||
${5} | ${'Billiard'} | |||
${6} | ${'Trillion'} | |||
${7} | ${'Trilliard'} | |||
${8} | ${'Quadrillion'} | |||
${9} | ${'Quadrilliard'} | |||
${10} | ${'Quintillion'} | |||
${11} | ${'Quintilliard'} | |||
${12} | ${'Sextillion'} | |||
${13} | ${'Sextilliard'} | |||
${14} | ${'Septillion'} | |||
${15} | ${'Septilliard'} | |||
${16} | ${'Octillion'} | |||
${17} | ${'Octilliard'} | |||
${18} | ${'Nonillion'} | |||
${19} | ${'Nonilliard'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${20} | ${'Decillion'} | |||
${40} | ${'Vigintillion'} | |||
${60} | ${'Trigintillion'} | |||
${80} | ${'Quadragintillion'} | |||
${100} | ${'Quinquagintillion'} | |||
${120} | ${'Sexagintillion'} | |||
${140} | ${'Septuagintillion'} | |||
${160} | ${'Octogintillion'} | |||
${180} | ${'Nonagintillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${200} | ${'Centillion'} | |||
${400} | ${'Duocentillion'} | |||
${600} | ${'Trecentillion'} | |||
${800} | ${'Quadringentillion'} | |||
${1000} | ${'Quingentillion'} | |||
${1200} | ${'Sescentillion'} | |||
${1400} | ${'Septingentillion'} | |||
${1600} | ${'Octingentillion'} | |||
${1800} | ${'Nongentillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${2000} | ${'Milliatillion'} | |||
${4000} | ${'Duomilliatillion'} | |||
${6000} | ${'Tremilliatillion'} | |||
${8000} | ${'Quattuormilliatillion'} | |||
${10000} | ${'Quinmilliatillion'} | |||
${12000} | ${'Sexmilliatillion'} | |||
${14000} | ${'Septenmilliatillion'} | |||
${16000} | ${'Octomilliatillion'} | |||
${18000} | ${'Novemmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${20000} | ${'Decmilliatillion'} | |||
${40000} | ${'Viginmilliatillion'} | |||
${60000} | ${'Triginmilliatillion'} | |||
${80000} | ${'Quadraginmilliatillion'} | |||
${100000} | ${'Quinquaginmilliatillion'} | |||
${120000} | ${'Sexaginmilliatillion'} | |||
${140000} | ${'Septuaginmilliatillion'} | |||
${160000} | ${'Octoginmilliatillion'} | |||
${180000} | ${'Nonaginmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${200000} | ${'Cenmilliatillion'} | |||
${400000} | ${'Duocenmilliatillion'} | |||
${600000} | ${'Trecenmilliatillion'} | |||
${800000} | ${'Quadringenmilliatillion'} | |||
${1000000} | ${'Quingenmilliatillion'} | |||
${1200000} | ${'Sescenmilliatillion'} | |||
${1400000} | ${'Septingenmilliatillion'} | |||
${1600000} | ${'Octingenmilliatillion'} | |||
${1800000} | ${'Nongenmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${2000000} | ${'Milliamilliatillion'} | |||
${4000000} | ${'Duomilliamilliatillion'} | |||
${6000000} | ${'Tremilliamilliatillion'} | |||
${8000000} | ${'Quattuormilliamilliatillion'} | |||
${10000000} | ${'Quinmilliamilliatillion'} | |||
${12000000} | ${'Sexmilliamilliatillion'} | |||
${14000000} | ${'Septenmilliamilliatillion'} | |||
${16000000} | ${'Octomilliamilliatillion'} | |||
${18000000} | ${'Novemmilliamilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) |
@@ -0,0 +1,33 @@ | |||
import { GetKiloName, } from '../../common/NumberSystem' | |||
import NAMES from './names.json' | |||
import getKiloCombiningPrefix from './base/kilo/combiningPrefix' | |||
const capitalizeFirstLetter = (word: string) => ( | |||
word.slice(0, 1).toUpperCase() + word.slice(1) | |||
) | |||
const getLongKiloName: GetKiloName = thousandPower => { | |||
if (thousandPower === 0) { | |||
return '' | |||
} | |||
if (thousandPower === 1) { | |||
return capitalizeFirstLetter(NAMES.thousand) | |||
} | |||
const kilo = thousandPower | |||
const kiloHundreds = Math.floor(kilo / 2 / 100) | |||
const kiloTens = Math.floor(kilo / 2 / 10 % 10) | |||
const kiloOnes = Math.floor(kilo / 2 % 10) | |||
const kiloCombiningPrefix = getKiloCombiningPrefix( | |||
kiloHundreds, | |||
kiloTens, | |||
kiloOnes | |||
) | |||
return capitalizeFirstLetter( | |||
thousandPower % 2 === 0 | |||
? kiloCombiningPrefix + NAMES.kiloEvenSuffix | |||
: kiloCombiningPrefix + NAMES.kiloOddSuffix | |||
) | |||
} | |||
export default getLongKiloName |
@@ -17,7 +17,7 @@ | |||
"zwölf", | |||
"dreizehn", | |||
"vierzehn", | |||
"fünfzhen", | |||
"fünfzehn", | |||
"sechzehn", | |||
"siebzehn", | |||
"achtzehn", | |||
@@ -38,6 +38,7 @@ | |||
"hundred": "hundert", | |||
"thousand": "tausend", | |||
"kiloSpecialUnits": [ | |||
"", | |||
"m", | |||
"b", | |||
"tr", | |||
@@ -49,6 +50,7 @@ | |||
"non" | |||
], | |||
"kiloUnits": [ | |||
"", | |||
"un", | |||
"duo", | |||
"tre", | |||
@@ -60,6 +62,7 @@ | |||
"novem" | |||
], | |||
"kiloTens": [ | |||
"", | |||
"dec", | |||
"vigin", | |||
"trigin", | |||
@@ -71,6 +74,7 @@ | |||
"nonagin" | |||
], | |||
"kiloHundreds": [ | |||
"", | |||
"cen", | |||
"duocen", | |||
"trecen", | |||
@@ -9,6 +9,6 @@ interface TenPlus { | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number plus ten. | |||
*/ | |||
const tenPlus: TenPlus = (x1) => NAMES.tenPlus[x1] | |||
const tenPlus: TenPlus = (x1) => (x1 === 0 ? NAMES.tenTimes[1] : NAMES.tenPlus[x1]) | |||
export default tenPlus |
@@ -0,0 +1,28 @@ | |||
import hundredTimes from './hundredTimes' | |||
it('should exist', () => { | |||
expect(hundredTimes).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof hundredTimes).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(hundredTimes).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'100'} | ${'sandaan'} | |||
${2} | ${'200'} | ${'dalawandaan'} | |||
${3} | ${'300'} | ${'tatlongdaan'} | |||
${4} | ${'400'} | ${'apatnaraan'} | |||
${5} | ${'500'} | ${'limandaan'} | |||
${6} | ${'600'} | ${'animnaraan'} | |||
${7} | ${'700'} | ${'pitongdaan'} | |||
${8} | ${'800'} | ${'walongdaan'} | |||
${9} | ${'900'} | ${'siyamnaraan'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(hundredTimes(value)).toBe(name) | |||
}) |
@@ -0,0 +1,59 @@ | |||
import NAMES from '../names.json' | |||
interface HundredTimes { | |||
(x100: number): string | |||
} | |||
/** | |||
* Get the name of some number in the hundreds place. | |||
* @param {number} x100 - The number in the hundreds place. | |||
* @returns {string} The name of the number in the hundreds place. | |||
*/ | |||
const hundredTimes: HundredTimes = (x100) => { | |||
if (x100 === 0) { | |||
return NAMES.units[0] | |||
} | |||
const hundredFactor = NAMES.units[x100] | |||
let hundredFactorCombining: string | |||
let infix: string | |||
let hundredSuffixCombining: string | |||
switch (x100) { | |||
case 1: | |||
hundredFactorCombining = hundredFactor.slice(1) | |||
infix = 'n' | |||
hundredSuffixCombining = NAMES.hundred | |||
break | |||
case 2: | |||
case 5: | |||
hundredFactorCombining = hundredFactor | |||
infix = 'n' | |||
hundredSuffixCombining = NAMES.hundred | |||
break | |||
default: | |||
case 3: | |||
case 7: | |||
case 8: | |||
hundredFactorCombining = hundredFactor | |||
infix = 'ng' | |||
hundredSuffixCombining = NAMES.hundred | |||
break | |||
case 4: | |||
case 6: | |||
case 9: | |||
hundredFactorCombining = hundredFactor | |||
infix = 'na' | |||
hundredSuffixCombining = 'r' + NAMES.hundred.slice(1) | |||
break | |||
} | |||
return [ | |||
hundredFactorCombining, | |||
infix, | |||
hundredSuffixCombining, | |||
] | |||
.join('') | |||
} | |||
export default hundredTimes |
@@ -0,0 +1,187 @@ | |||
import combiningPrefix from './combiningPrefix' | |||
it('should exist', () => { | |||
expect(combiningPrefix).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof combiningPrefix).toBe('function') | |||
}) | |||
it('should accept 4 arguments', () => { | |||
expect(combiningPrefix).toHaveLength(4) | |||
}) | |||
describe('on 0 in hundreds place', () => { | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
value | display | name | |||
${1} | ${'1'} | ${'mi'} | |||
${2} | ${'2'} | ${'bi'} | |||
${3} | ${'3'} | ${'tri'} | |||
${4} | ${'4'} | ${'kuwadri'} | |||
${5} | ${'5'} | ${'kuwinti'} | |||
${6} | ${'6'} | ${'seksti'} | |||
${7} | ${'7'} | ${'septi'} | |||
${8} | ${'8'} | ${'okti'} | |||
${9} | ${'9'} | ${'noni'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(0, 0, value)).toBe(name) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${1} | ${'desi'} | |||
${2} | ${'bihinti'} | |||
${3} | ${'trihinti'} | |||
${4} | ${'kuwadrahinti'} | |||
${5} | ${'kuwinkuwahinti'} | |||
${6} | ${'seksahinti'} | |||
${7} | ${'septuwahinti'} | |||
${8} | ${'oktohinti'} | |||
${9} | ${'nonahinti'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${tensName} | |||
${1} | ${'un' + tensName} | |||
${2} | ${'duwo' + tensName} | |||
${3} | ${'tre' + tensName} | |||
${4} | ${'kuwatuwor' + tensName} | |||
${5} | ${'kuwin' + tensName} | |||
${6} | ${'seks' + tensName} | |||
${7} | ${'septen' + tensName} | |||
${8} | ${'okto' + tensName} | |||
${9} | ${'nobem' + tensName} | |||
`(`should return "$display" for ${tens}$ones`, ({ ones, display, }) => { | |||
expect(combiningPrefix(0, tens, ones)).toBe(display) | |||
}) | |||
}) | |||
}) | |||
describe.each` | |||
hundreds | hundredsName | |||
${1} | ${'sen'} | |||
${2} | ${'duwosen'} | |||
${3} | ${'tresen'} | |||
${4} | ${'kuwadringhen'} | |||
${5} | ${'kuwinghen'} | |||
${6} | ${'sesen'} | |||
${7} | ${'septinghen'} | |||
${8} | ${'oktinghen'} | |||
${9} | ${'nonghen'} | |||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||
describe.each` | |||
tens | tensName | |||
${0} | ${'ti'} | |||
${1} | ${'desi'} | |||
${2} | ${'bihinti'} | |||
${3} | ${'trihinti'} | |||
${4} | ${'kuwadrahinti'} | |||
${5} | ${'kuwinkuwahinti'} | |||
${6} | ${'seksahinti'} | |||
${7} | ${'septuwahinti'} | |||
${8} | ${'oktohinti'} | |||
${9} | ${'nonahinti'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${hundredsName + tensName} | |||
${1} | ${hundredsName + 'un' + tensName} | |||
${2} | ${hundredsName + 'duwo' + tensName} | |||
${3} | ${hundredsName + 'tre' + tensName} | |||
${4} | ${hundredsName + 'kuwatuwor' + tensName} | |||
${5} | ${hundredsName + 'kuwin' + tensName} | |||
${6} | ${hundredsName + 'seks' + tensName} | |||
${7} | ${hundredsName + 'septen' + tensName} | |||
${8} | ${hundredsName + 'okto' + tensName} | |||
${9} | ${hundredsName + 'nobem' + tensName} | |||
`(`should return "$display" for ${hundreds}${tens}$ones`, ({ ones, display, }) => { | |||
expect(combiningPrefix(hundreds, tens, ones)).toBe(display) | |||
}) | |||
}) | |||
}) | |||
describe.each` | |||
hundredThousands | hundredThousandsName | |||
${1} | ${'sen'} | |||
${2} | ${'duwosen'} | |||
${3} | ${'tresen'} | |||
${4} | ${'kuwadringhen'} | |||
${5} | ${'kuwinghen'} | |||
${6} | ${'sesen'} | |||
${7} | ${'septinghen'} | |||
${8} | ${'oktinghen'} | |||
${9} | ${'nonghen'} | |||
`('on $hundredThousands in hundred thousands place', ({ hundredThousands, hundredThousandsName, }) => { | |||
describe.each` | |||
tenThousands | tenThousandsName | |||
${0} | ${''} | |||
${1} | ${'des'} | |||
${2} | ${'bihin'} | |||
${3} | ${'trihin'} | |||
${4} | ${'kuwadrahin'} | |||
${5} | ${'kuwinkuwahin'} | |||
${6} | ${'seksahin'} | |||
${7} | ${'septuwahin'} | |||
${8} | ${'oktohin'} | |||
${9} | ${'nonahin'} | |||
`('on $tenThousands in ten thousands place', ({ tenThousands, tenThousandsName, }) => { | |||
test.each` | |||
thousands | display | name | |||
${0} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milyati'} | |||
${1000} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milyati'} | |||
${2000} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duwo' + tenThousandsName + 'milyati'} | |||
${3000} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milyati'} | |||
${4000} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'kuwatuwor' + tenThousandsName + 'milyati'} | |||
${5000} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'kuwin' + tenThousandsName + 'milyati'} | |||
${6000} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'seks' + tenThousandsName + 'milyati'} | |||
${7000} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milyati'} | |||
${8000} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'okto' + tenThousandsName + 'milyati'} | |||
${9000} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'nobem' + tenThousandsName + 'milyati'} | |||
`(`should return "$name" for $display`, ({ thousands, name, }) => { | |||
const kiloHundreds = ( | |||
hundredThousands * 1000 | |||
+ tenThousands * 100 | |||
+ thousands / 100 | |||
) | |||
expect(combiningPrefix( | |||
kiloHundreds, | |||
0, | |||
0, | |||
)).toBe(name) | |||
}) | |||
}) | |||
}) | |||
it.each` | |||
value | display | name | |||
${1} | ${'1000000'} | ${'milyamilyati'} | |||
${2} | ${'2000000'} | ${'duwomilyamilyati'} | |||
${3} | ${'3000000'} | ${'tremilyamilyati'} | |||
${4} | ${'4000000'} | ${'kuwatuwormilyamilyati'} | |||
${5} | ${'5000000'} | ${'kuwinmilyamilyati'} | |||
${6} | ${'6000000'} | ${'seksmilyamilyati'} | |||
${7} | ${'7000000'} | ${'septenmilyamilyati'} | |||
${8} | ${'8000000'} | ${'oktomilyamilyati'} | |||
${9} | ${'9000000'} | ${'nobemmilyamilyati'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(value * 10000, 0, 0)).toBe(name) | |||
}) | |||
it.each` | |||
value | display | name | |||
${1} | ${'1001000'} | ${'milyamilyaunmilyati'} | |||
${2} | ${'2002000'} | ${'duwomilyamilyaduwomilyati'} | |||
${3} | ${'3003000'} | ${'tremilyamilyatremilyati'} | |||
${4} | ${'4004000'} | ${'kuwatuwormilyamilyakuwatuwormilyati'} | |||
${5} | ${'5005000'} | ${'kuwinmilyamilyakuwinmilyati'} | |||
${6} | ${'6006000'} | ${'seksmilyamilyaseksmilyati'} | |||
${7} | ${'7007000'} | ${'septenmilyamilyaseptenmilyati'} | |||
${8} | ${'8008000'} | ${'oktomilyamilyaoktomilyati'} | |||
${9} | ${'9009000'} | ${'nobemmilyamilyanobemmilyati'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(value * 10010, 0, 0)).toBe(name) | |||
}) | |||
@@ -0,0 +1,109 @@ | |||
import NAMES from '../../names.json' | |||
import ones from './ones' | |||
import tens from './tens' | |||
import hundreds from './hundreds' | |||
interface CombiningPrefix { | |||
( | |||
kiloHundreds: number, | |||
kiloTens: number, | |||
kiloOnes: number, | |||
kiloPower?: number, | |||
): string, | |||
} | |||
const combiningPrefix: CombiningPrefix = ( | |||
kiloHundredsRaw, | |||
kiloTens, | |||
kiloOnes, | |||
kiloPower = 0, | |||
) => { | |||
let kiloHundreds = kiloHundredsRaw | |||
let prefix = '' | |||
const isMillia = kiloHundredsRaw >= 10 | |||
if (isMillia) { | |||
prefix += combiningPrefix( | |||
Math.floor(kiloHundredsRaw / 1000), | |||
Math.floor(kiloHundredsRaw / 100 % 10), | |||
Math.floor(kiloHundredsRaw / 10 % 10), | |||
kiloPower + 1, | |||
) | |||
kiloHundreds = kiloHundredsRaw % 10 | |||
} | |||
const hasHundreds = kiloHundreds > 0 | |||
if (hasHundreds) { | |||
prefix += hundreds(kiloHundreds) | |||
} | |||
if ( | |||
( | |||
kiloPower > 0 | |||
&& ( | |||
( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes > 1 | |||
) | |||
|| ( | |||
( | |||
kiloHundreds > 0 | |||
|| kiloTens > 0 | |||
) | |||
&& kiloOnes > 0 | |||
) | |||
|| ( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes === 1 | |||
&& prefix.endsWith(NAMES.kiloThousand) | |||
) | |||
) | |||
) | |||
) { | |||
// http://www.isthe.com/chongo/tech/math/number/howhigh.html | |||
// Section: Titanic size numbers < 10^3000003 | |||
prefix += ones( | |||
kiloOnes, | |||
false | |||
) | |||
} | |||
if (kiloPower === 0 && kiloOnes > 0) { | |||
const special = kiloHundreds === 0 && kiloTens === 0 | |||
prefix += ones( | |||
kiloOnes, | |||
special | |||
) | |||
if (special && [5, 6].includes(kiloOnes)) { | |||
prefix += 't' | |||
} | |||
} | |||
if (kiloTens > 0) { | |||
prefix += tens(kiloTens) | |||
} | |||
if (kiloPower > 0) { | |||
if (!( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes === 0 | |||
)) { | |||
for (let p = 0; p < kiloPower; p += 1) { | |||
prefix += NAMES.kiloThousand | |||
} | |||
} | |||
return prefix | |||
} | |||
if ( | |||
(kiloHundreds === 0 && kiloTens > 1) | |||
|| (kiloHundreds > 0 && kiloTens !== 1) | |||
|| kiloHundredsRaw >= 10 | |||
) { | |||
prefix += 't' | |||
} | |||
return prefix + 'i' | |||
} | |||
export default combiningPrefix |
@@ -0,0 +1,28 @@ | |||
import hundreds from './hundreds' | |||
it('should exist', () => { | |||
expect(hundreds).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof hundreds).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(hundreds).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'100'} | ${'sen'} | |||
${2} | ${'200'} | ${'duwosen'} | |||
${3} | ${'300'} | ${'tresen'} | |||
${4} | ${'400'} | ${'kuwadringhen'} | |||
${5} | ${'500'} | ${'kuwinghen'} | |||
${6} | ${'600'} | ${'sesen'} | |||
${7} | ${'700'} | ${'septinghen'} | |||
${8} | ${'800'} | ${'oktinghen'} | |||
${9} | ${'900'} | ${'nonghen'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(hundreds(value)).toBe(name) | |||
}) |
@@ -0,0 +1,9 @@ | |||
import NAMES from '../../names.json' | |||
interface Hundreds { | |||
(kiloHundreds: number): string, | |||
} | |||
const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds] | |||
export default hundreds |
@@ -0,0 +1,49 @@ | |||
import ones from './ones' | |||
it('should exist', () => { | |||
expect(ones).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof ones).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(ones).toHaveLength(2) | |||
}) | |||
describe('on ordinary units', () => { | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${''} | |||
${1} | ${'1'} | ${'un'} | |||
${2} | ${'2'} | ${'duwo'} | |||
${3} | ${'3'} | ${'tre'} | |||
${4} | ${'4'} | ${'kuwatuwor'} | |||
${5} | ${'5'} | ${'kuwin'} | |||
${6} | ${'6'} | ${'seks'} | |||
${7} | ${'7'} | ${'septen'} | |||
${8} | ${'8'} | ${'okto'} | |||
${9} | ${'9'} | ${'nobem'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value, false)).toBe(name) | |||
}) | |||
}) | |||
describe('on special units', () => { | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${''} | |||
${1} | ${'1'} | ${'m'} | |||
${2} | ${'2'} | ${'b'} | |||
${3} | ${'3'} | ${'tr'} | |||
${4} | ${'4'} | ${'kuwadr'} | |||
${5} | ${'5'} | ${'kuwin'} | |||
${6} | ${'6'} | ${'seks'} | |||
${7} | ${'7'} | ${'sept'} | |||
${8} | ${'8'} | ${'okt'} | |||
${9} | ${'9'} | ${'non'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value, true)).toBe(name) | |||
}) | |||
}) |
@@ -0,0 +1,13 @@ | |||
import NAMES from '../../names.json' | |||
interface Ones { | |||
(kiloOnes: number, special: boolean): string, | |||
} | |||
const ones: Ones = (kiloOnes, special = false) => ( | |||
special | |||
? NAMES.kiloSpecialUnits[kiloOnes] | |||
: NAMES.kiloUnits[kiloOnes] | |||
) | |||
export default ones |
@@ -0,0 +1,28 @@ | |||
import tens from './tens' | |||
it('should exist', () => { | |||
expect(tens).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tens).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tens).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'10'} | ${'des'} | |||
${2} | ${'20'} | ${'bihin'} | |||
${3} | ${'30'} | ${'trihin'} | |||
${4} | ${'40'} | ${'kuwadrahin'} | |||
${5} | ${'50'} | ${'kuwinkuwahin'} | |||
${6} | ${'60'} | ${'seksahin'} | |||
${7} | ${'70'} | ${'septuwahin'} | |||
${8} | ${'80'} | ${'oktohin'} | |||
${9} | ${'90'} | ${'nonahin'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tens(value)).toBe(name) | |||
}) |
@@ -0,0 +1,9 @@ | |||
import NAMES from '../../names.json' | |||
interface Tens { | |||
(kiloTens: number): string, | |||
} | |||
const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens] | |||
export default tens |
@@ -0,0 +1,30 @@ | |||
import ones from './ones' | |||
it('should exist', () => { | |||
expect(ones).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof ones).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(ones).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${'sero'} | |||
${1} | ${'1'} | ${'isa'} | |||
${2} | ${'2'} | ${'dalawa'} | |||
${3} | ${'3'} | ${'tatlo'} | |||
${4} | ${'4'} | ${'apat'} | |||
${5} | ${'5'} | ${'lima'} | |||
${6} | ${'6'} | ${'anim'} | |||
${7} | ${'7'} | ${'pito'} | |||
${8} | ${'8'} | ${'walo'} | |||
${9} | ${'9'} | ${'siyam'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value)).toBe(name) | |||
}) | |||
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface Ones { | |||
(x1: number): string | |||
} | |||
/** | |||
* Get the name of some number in the ones place. | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number in the ones place. | |||
*/ | |||
const ones: Ones = (x1) => NAMES.units[x1] | |||
export default ones |
@@ -0,0 +1,29 @@ | |||
import tenPlus from './tenPlus' | |||
it('should exist', () => { | |||
expect(tenPlus).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tenPlus).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tenPlus).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${0} | ${'10'} | ${'sampu'} | |||
${1} | ${'11'} | ${'labing-isa'} | |||
${2} | ${'12'} | ${'labindalawa'} | |||
${3} | ${'13'} | ${'labintatlo'} | |||
${4} | ${'14'} | ${'labing-apat'} | |||
${5} | ${'15'} | ${'labinlima'} | |||
${6} | ${'16'} | ${'labing-anim'} | |||
${7} | ${'17'} | ${'labimpito'} | |||
${8} | ${'18'} | ${'labingwalo'} | |||
${9} | ${'19'} | ${'labinsiyam'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tenPlus(value)).toBe(name) | |||
}) |
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface TenPlus { | |||
(ones: number): string | |||
} | |||
/** | |||
* Get the name of some number plus ten. | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number plus ten. | |||
*/ | |||
const tenPlus: TenPlus = (x1) => (x1 === 0 ? NAMES.tenTimes[1] : NAMES.tenPlus[x1]) | |||
export default tenPlus |
@@ -0,0 +1,28 @@ | |||
import tenTimes from './tenTimes' | |||
it('should exist', () => { | |||
expect(tenTimes).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tenTimes).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tenTimes).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'10'} | ${'sampu'} | |||
${2} | ${'20'} | ${'dalawampu'} | |||
${3} | ${'30'} | ${'tatlumpu'} | |||
${4} | ${'40'} | ${'apatnapu'} | |||
${5} | ${'50'} | ${'limampu'} | |||
${6} | ${'60'} | ${'animnapu'} | |||
${7} | ${'70'} | ${'pitumpu'} | |||
${8} | ${'80'} | ${'walumpu'} | |||
${9} | ${'90'} | ${'siyamnapu'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tenTimes(value)).toBe(name) | |||
}) |
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface TenTimes { | |||
(x10: number): string | |||
} | |||
/** | |||
* Get the name of some number in the tens place. | |||
* @param {number} x10 - The number in the tens place. | |||
* @returns {string} The name of the number in the tens place. | |||
*/ | |||
const tenTimes: TenTimes = (x10) => NAMES.tenTimes[x10] | |||
export default tenTimes |
@@ -0,0 +1,80 @@ | |||
import tensFn from './tens' | |||
it('should exist', () => { | |||
expect(tensFn).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tensFn).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(tensFn).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(tensFn(0, ones)).toBe(onesName) | |||
}) | |||
}) | |||
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(tensFn(1, ones)).toBe(tenPlusName) | |||
}) | |||
}) | |||
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(tensFn(tens, ones)).toBe([ | |||
tensName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) |
@@ -0,0 +1,37 @@ | |||
import NAMES from '../names.json' | |||
import ones from '../base/ones' | |||
import tenPlus from '../base/tenPlus' | |||
import getBaseTenTimesName from '../base/tenTimes' | |||
interface Tens { | |||
(x10: number, x1: number): string, | |||
} | |||
const tens: Tens = (x10, x1) => { | |||
switch (x10) { | |||
case 0: | |||
return ones(x1) | |||
case 1: | |||
if (x1 > 0) { | |||
return tenPlus(x1) | |||
} | |||
break | |||
default: | |||
break | |||
} | |||
return ( | |||
x1 > 0 | |||
? [ | |||
getBaseTenTimesName(x10), | |||
"'", | |||
NAMES.and.slice(1), | |||
' ', | |||
ones(x1), | |||
] | |||
.join('') | |||
: getBaseTenTimesName(x10) | |||
) | |||
} | |||
export default tens |
@@ -0,0 +1,106 @@ | |||
import getKiloCount from './getKiloCount' | |||
it('should exist', () => { | |||
expect(getKiloCount).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getKiloCount).toBe('function') | |||
}) | |||
it('should accept 3 arguments', () => { | |||
expect(getKiloCount).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, }) => { | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${''} | |||
${1} | ${' at isa'} | |||
${2} | ${' at dalawa'} | |||
${3} | ${' at tatlo'} | |||
${4} | ${' at apat'} | |||
${5} | ${' at lima'} | |||
${6} | ${' at anim'} | |||
${7} | ${' at pito'} | |||
${8} | ${' at walo'} | |||
${9} | ${' at siyam'} | |||
`(`should return "${hundredsName}$onesName" for ${hundreds}0$ones`, ({ ones, onesName, }) => { | |||
expect(getKiloCount(hundreds, 0, ones)).toBe([ | |||
hundredsName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) | |||
describe('on 1 in tens place', () => { | |||
test.each` | |||
ones | tenPlusName | |||
${0} | ${' at sampu'} | |||
${1} | ${' labing-isa'} | |||
${2} | ${' labindalawa'} | |||
${3} | ${' labintatlo'} | |||
${4} | ${' labing-apat'} | |||
${5} | ${' labinlima'} | |||
${6} | ${' labing-anim'} | |||
${7} | ${' labimpito'} | |||
${8} | ${' labingwalo'} | |||
${9} | ${' labinsiyam'} | |||
`(`should return "${hundredsName}$tenPlusName" for ${hundreds}1$ones`, ({ ones, tenPlusName, }) => { | |||
expect(getKiloCount(hundreds, 1, ones)).toBe([ | |||
hundredsName, | |||
tenPlusName | |||
].join('')) | |||
}) | |||
}) | |||
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, }) => { | |||
it(`should return "${hundredsName} at${tensName}" for ${hundreds}${tens}0`, () => { | |||
expect(getKiloCount(hundreds, tens, 0)).toBe([ | |||
hundredsName, | |||
tensName, | |||
].join(' at')) | |||
}) | |||
test.each` | |||
ones | onesName | |||
${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 "${hundredsName}${tensName}$onesName" for ${hundreds}${tens}$ones`, ({ ones, onesName, }) => { | |||
expect(getKiloCount(hundreds, tens, ones)).toBe([ | |||
hundredsName, | |||
tensName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) | |||
}) |
@@ -0,0 +1,41 @@ | |||
import NAMES from './names.json' | |||
import { GetKiloCount, } from '../../common/NumberSystem' | |||
import constructTens from './construct/tens' | |||
import hundredTimes from './base/hundredTimes' | |||
const getKiloCount: GetKiloCount = ( | |||
x100, | |||
x10, | |||
x1 | |||
) => { | |||
if (x100 < 1) { | |||
return constructTens(x10, x1) | |||
} | |||
if (x10 === 0) { | |||
if (x1 === 0) { | |||
return hundredTimes(x100) | |||
} | |||
return [ | |||
hundredTimes(x100), | |||
NAMES.and, | |||
constructTens(0, x1), | |||
] | |||
.join(' ') | |||
} | |||
if (x1 === 0) { | |||
return [ | |||
hundredTimes(x100), | |||
NAMES.and, | |||
constructTens(x10, x1), | |||
] | |||
.join(' ') | |||
} | |||
return [ | |||
hundredTimes(x100), | |||
constructTens(x10, x1), | |||
] | |||
.join(' ') | |||
} | |||
export default getKiloCount |
@@ -39,10 +39,10 @@ | |||
"thousand": "libo", | |||
"kiloSpecialUnits": [ | |||
"", | |||
"mi", | |||
"bi", | |||
"tri", | |||
"kuwadri", | |||
"m", | |||
"b", | |||
"tr", | |||
"kuwadr", | |||
"kuwin", | |||
"seks", | |||
"sept", | |||
@@ -52,7 +52,7 @@ | |||
"kiloUnits": [ | |||
"", | |||
"un", | |||
"duo", | |||
"duwo", | |||
"tre", | |||
"kuwatuwor", | |||
"kuwin", | |||
@@ -64,26 +64,26 @@ | |||
"kiloTens": [ | |||
"", | |||
"des", | |||
"bigin", | |||
"trigin", | |||
"kuwadragin", | |||
"kuwinkuwagin", | |||
"seksagin", | |||
"septuwagin", | |||
"oktogin", | |||
"nonagin" | |||
"bihin", | |||
"trihin", | |||
"kuwadrahin", | |||
"kuwinkuwahin", | |||
"seksahin", | |||
"septuwahin", | |||
"oktohin", | |||
"nonahin" | |||
], | |||
"kiloHundreds": [ | |||
"", | |||
"sen", | |||
"duosen", | |||
"duwosen", | |||
"tresen", | |||
"kuwadringen", | |||
"kuwingen", | |||
"kuwadringhen", | |||
"kuwinghen", | |||
"sesen", | |||
"septingen", | |||
"oktingen", | |||
"nongen" | |||
"septinghen", | |||
"oktinghen", | |||
"nonghen" | |||
], | |||
"kiloThousand": "milya", | |||
"kiloEvenSuffix": "lyon", | |||