Gets the name of a number, even if it's stupidly big. Supersedes TheoryOfNekomata/number-name.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

336 lines
12 KiB

  1. import { describe, it, expect } from 'vitest';
  2. import {
  3. AllowedValue,
  4. parse,
  5. stringify,
  6. systems,
  7. } from '../../../src';
  8. const options = {
  9. system: systems.enUS.shortCount,
  10. };
  11. const doExpect = (
  12. value: AllowedValue,
  13. stringified: string,
  14. parsedValue: AllowedValue = value,
  15. ) => {
  16. const stringifyOptions = {
  17. ...options,
  18. };
  19. const parseOptions = {
  20. ...options,
  21. type: typeof value as ('number' | 'string' | 'bigint'),
  22. };
  23. expect(stringify(value, stringifyOptions)).toBe(stringified);
  24. expect(parse(stringified, parseOptions)).toBe(parsedValue);
  25. };
  26. describe('American short count', () => {
  27. describe('individual cases', () => {
  28. const longNumberValue1 = '123,456,789,012,345,678,901,234,567,890';
  29. const longNumberStringified1 = [
  30. 'one hundred twenty-three octillion',
  31. 'four hundred fifty-six septillion',
  32. 'seven hundred eighty-nine sextillion',
  33. 'twelve quintillion',
  34. 'three hundred forty-five quadrillion',
  35. 'six hundred seventy-eight trillion',
  36. 'nine hundred one billion',
  37. 'two hundred thirty-four million',
  38. 'five hundred sixty-seven thousand',
  39. 'eight hundred ninety',
  40. ].join(' ');
  41. const longNumberParsedValue = '1.2345678901234567890123456789e+29';
  42. it.each`
  43. value | stringified | parsedValue
  44. ${1000} | ${'one thousand'} | ${1000}
  45. ${10000} | ${'ten thousand'} | ${10000}
  46. ${12012} | ${'twelve thousand twelve'} | ${12012}
  47. ${12020} | ${'twelve thousand twenty'} | ${12020}
  48. ${20000} | ${'twenty thousand'} | ${20000}
  49. ${100000} | ${'one hundred thousand'} | ${100000}
  50. ${123456} | ${'one hundred twenty-three thousand four hundred fifty-six'} | ${123456}
  51. ${'1000005000000'} | ${'one trillion five million'} | ${'1.000005e+12'}
  52. ${longNumberValue1} | ${longNumberStringified1} | ${longNumberParsedValue}
  53. ${'1e3006'} | ${'one milliauntillion'} | ${'1e+3006'}
  54. `('converts $value to $stringified', ({
  55. value,
  56. stringified,
  57. parsedValue,
  58. }: { value: AllowedValue, stringified: string, parsedValue: AllowedValue }) => {
  59. doExpect(value, stringified, parsedValue);
  60. });
  61. it('converts one millia^1-tillion to 1e+3003', () => {
  62. expect(parse('one millia^1-tillion')).toBe('1e+3003');
  63. });
  64. });
  65. describe('blanket cases', () => {
  66. it('converts one millia^2-tillion', () => {
  67. const value = '1e+3000003';
  68. const stringified = 'one millia^2-tillion';
  69. expect(parse(stringified)).toBe(value);
  70. expect(stringify(value, { stringifyGroupsOptions: { shortenMillia: true } }))
  71. .toBe(stringified);
  72. });
  73. it('converts one millia^2-unmilliatillion', () => {
  74. const value = '1e+3003003';
  75. const stringified = 'one millia^2-unmilliatillion';
  76. expect(stringify(value, { stringifyGroupsOptions: { shortenMillia: true } }))
  77. .toBe(stringified);
  78. expect(parse(stringified)).toBe(value);
  79. });
  80. it('converts one milliamilliaunmilliatillion', () => {
  81. const value = '1e+3003003';
  82. const stringified = 'one milliamilliaunmilliatillion';
  83. expect(stringify(value)).toBe(stringified);
  84. expect(parse(stringified)).toBe('1e+3003003');
  85. });
  86. });
  87. describe('general', () => {
  88. describe('0-9', () => {
  89. it.each`
  90. value | numberName
  91. ${0} | ${'zero'}
  92. ${1} | ${'one'}
  93. ${2} | ${'two'}
  94. ${3} | ${'three'}
  95. ${4} | ${'four'}
  96. ${5} | ${'five'}
  97. ${6} | ${'six'}
  98. ${7} | ${'seven'}
  99. ${8} | ${'eight'}
  100. ${9} | ${'nine'}
  101. `('converts $ones to $numberName', ({ value, numberName }: { value: number, numberName: string }) => {
  102. doExpect(value, numberName);
  103. });
  104. });
  105. describe('10-19', () => {
  106. it.each`
  107. value | numberName
  108. ${10} | ${'ten'}
  109. ${11} | ${'eleven'}
  110. ${12} | ${'twelve'}
  111. ${13} | ${'thirteen'}
  112. ${14} | ${'fourteen'}
  113. ${15} | ${'fifteen'}
  114. ${16} | ${'sixteen'}
  115. ${17} | ${'seventeen'}
  116. ${18} | ${'eighteen'}
  117. ${19} | ${'nineteen'}
  118. `('converts $tenPlusOnes to $numberName', ({ value, numberName }: { value: number, numberName: string }) => {
  119. doExpect(value, numberName);
  120. });
  121. });
  122. describe.each`
  123. tensStart | tensEnd | tensBase
  124. ${20} | ${29} | ${'twenty'}
  125. ${30} | ${39} | ${'thirty'}
  126. ${40} | ${49} | ${'forty'}
  127. ${50} | ${59} | ${'fifty'}
  128. ${60} | ${69} | ${'sixty'}
  129. ${70} | ${79} | ${'seventy'}
  130. ${80} | ${89} | ${'eighty'}
  131. ${90} | ${99} | ${'ninety'}
  132. `('$tensStart-$tensEnd', ({
  133. tensStart, tensBase,
  134. }: { tensStart: number, tensBase: string }) => {
  135. it.each`
  136. value | numberName
  137. ${tensStart} | ${tensBase}
  138. ${tensStart + 1} | ${`${tensBase}-one`}
  139. ${tensStart + 2} | ${`${tensBase}-two`}
  140. ${tensStart + 3} | ${`${tensBase}-three`}
  141. ${tensStart + 4} | ${`${tensBase}-four`}
  142. ${tensStart + 5} | ${`${tensBase}-five`}
  143. ${tensStart + 6} | ${`${tensBase}-six`}
  144. ${tensStart + 7} | ${`${tensBase}-seven`}
  145. ${tensStart + 8} | ${`${tensBase}-eight`}
  146. ${tensStart + 9} | ${`${tensBase}-nine`}
  147. `('converts $value to $numberName', ({ value, numberName }: { value: number, numberName: string }) => {
  148. doExpect(value, numberName);
  149. });
  150. });
  151. describe.each`
  152. hundredsStart | hundredsEnd | hundredsBase
  153. ${100} | ${199} | ${'one hundred'}
  154. ${200} | ${299} | ${'two hundred'}
  155. ${300} | ${399} | ${'three hundred'}
  156. ${400} | ${499} | ${'four hundred'}
  157. ${500} | ${599} | ${'five hundred'}
  158. ${600} | ${699} | ${'six hundred'}
  159. ${700} | ${799} | ${'seven hundred'}
  160. ${800} | ${899} | ${'eight hundred'}
  161. ${900} | ${999} | ${'nine hundred'}
  162. `('$hundredsStart-$hundredsEnd', ({
  163. hundredsStart, hundredsBase,
  164. }: { hundredsStart: number, hundredsBase: string }) => {
  165. describe(`${hundredsStart}-${hundredsStart + 9}`, () => {
  166. it.each`
  167. value | numberName
  168. ${hundredsStart} | ${hundredsBase}
  169. ${hundredsStart + 1} | ${`${hundredsBase} one`}
  170. ${hundredsStart + 2} | ${`${hundredsBase} two`}
  171. ${hundredsStart + 3} | ${`${hundredsBase} three`}
  172. ${hundredsStart + 4} | ${`${hundredsBase} four`}
  173. ${hundredsStart + 5} | ${`${hundredsBase} five`}
  174. ${hundredsStart + 6} | ${`${hundredsBase} six`}
  175. ${hundredsStart + 7} | ${`${hundredsBase} seven`}
  176. ${hundredsStart + 8} | ${`${hundredsBase} eight`}
  177. ${hundredsStart + 9} | ${`${hundredsBase} nine`}
  178. `('converts $value to $numberName', ({ value, numberName }: { value: number, numberName: string }) => {
  179. doExpect(value, numberName);
  180. });
  181. });
  182. describe(`${hundredsStart + 10}-${hundredsStart + 19}`, () => {
  183. it.each`
  184. value | numberName
  185. ${hundredsStart + 10} | ${`${hundredsBase} ten`}
  186. ${hundredsStart + 11} | ${`${hundredsBase} eleven`}
  187. ${hundredsStart + 12} | ${`${hundredsBase} twelve`}
  188. ${hundredsStart + 13} | ${`${hundredsBase} thirteen`}
  189. ${hundredsStart + 14} | ${`${hundredsBase} fourteen`}
  190. ${hundredsStart + 15} | ${`${hundredsBase} fifteen`}
  191. ${hundredsStart + 16} | ${`${hundredsBase} sixteen`}
  192. ${hundredsStart + 17} | ${`${hundredsBase} seventeen`}
  193. ${hundredsStart + 18} | ${`${hundredsBase} eighteen`}
  194. ${hundredsStart + 19} | ${`${hundredsBase} nineteen`}
  195. `('converts $value to $numberName', ({ value, numberName }: { value: number, numberName: string }) => {
  196. doExpect(value, numberName);
  197. });
  198. });
  199. describe.each`
  200. start | end | base
  201. ${20} | ${29} | ${'twenty'}
  202. ${30} | ${39} | ${'thirty'}
  203. ${40} | ${49} | ${'forty'}
  204. ${50} | ${59} | ${'fifty'}
  205. ${60} | ${69} | ${'sixty'}
  206. ${70} | ${79} | ${'seventy'}
  207. ${80} | ${89} | ${'eighty'}
  208. ${90} | ${99} | ${'ninety'}
  209. `('$start-$end', ({
  210. start, base,
  211. }: { start: number, base: string }) => {
  212. it.each`
  213. value | numberName
  214. ${hundredsStart + start} | ${`${hundredsBase} ${base}`}
  215. ${hundredsStart + start + 1} | ${`${hundredsBase} ${base}-one`}
  216. ${hundredsStart + start + 2} | ${`${hundredsBase} ${base}-two`}
  217. ${hundredsStart + start + 3} | ${`${hundredsBase} ${base}-three`}
  218. ${hundredsStart + start + 4} | ${`${hundredsBase} ${base}-four`}
  219. ${hundredsStart + start + 5} | ${`${hundredsBase} ${base}-five`}
  220. ${hundredsStart + start + 6} | ${`${hundredsBase} ${base}-six`}
  221. ${hundredsStart + start + 7} | ${`${hundredsBase} ${base}-seven`}
  222. ${hundredsStart + start + 8} | ${`${hundredsBase} ${base}-eight`}
  223. ${hundredsStart + start + 9} | ${`${hundredsBase} ${base}-nine`}
  224. `('converts $value to $numberName', ({ value, numberName }: { value: number, numberName: string }) => {
  225. doExpect(value, numberName);
  226. });
  227. });
  228. });
  229. });
  230. it.each`
  231. value | numberName
  232. ${'1e+6'} | ${'one million'}
  233. ${'1e+9'} | ${'one billion'}
  234. ${'1e+12'} | ${'one trillion'}
  235. ${'1e+15'} | ${'one quadrillion'}
  236. ${'1e+18'} | ${'one quintillion'}
  237. ${'1e+21'} | ${'one sextillion'}
  238. ${'1e+24'} | ${'one septillion'}
  239. ${'1e+27'} | ${'one octillion'}
  240. ${'1e+30'} | ${'one nonillion'}
  241. `('converts $value to $numberName', ({ value, numberName }: { value: string, numberName: string }) => {
  242. doExpect(value, numberName);
  243. });
  244. it.each`
  245. value | numberName
  246. ${'1e+33'} | ${'one decillion'}
  247. ${'1e+36'} | ${'one undecillion'}
  248. ${'1e+39'} | ${'one duodecillion'}
  249. ${'1e+42'} | ${'one tredecillion'}
  250. ${'1e+45'} | ${'one quattuordecillion'}
  251. ${'1e+48'} | ${'one quindecillion'}
  252. ${'1e+51'} | ${'one sexdecillion'}
  253. ${'1e+54'} | ${'one septendecillion'}
  254. ${'1e+57'} | ${'one octodecillion'}
  255. ${'1e+60'} | ${'one novemdecillion'}
  256. `('converts $value to $numberName', ({ value, numberName }: { value: string, numberName: string }) => {
  257. doExpect(value, numberName);
  258. });
  259. it.each`
  260. value | numberName
  261. ${'1e+63'} | ${'one vigintillion'}
  262. ${'1e+66'} | ${'one unvigintillion'}
  263. ${'1e+69'} | ${'one duovigintillion'}
  264. ${'1e+72'} | ${'one trevigintillion'}
  265. ${'1e+75'} | ${'one quattuorvigintillion'}
  266. ${'1e+78'} | ${'one quinvigintillion'}
  267. ${'1e+81'} | ${'one sexvigintillion'}
  268. ${'1e+84'} | ${'one septenvigintillion'}
  269. ${'1e+87'} | ${'one octovigintillion'}
  270. ${'1e+90'} | ${'one novemvigintillion'}
  271. `('converts $value to $numberName', ({ value, numberName }: { value: string, numberName: string }) => {
  272. doExpect(value, numberName);
  273. });
  274. it.each`
  275. value | numberName
  276. ${'1e+93'} | ${'one trigintillion'}
  277. ${'1e+123'} | ${'one quadragintillion'}
  278. ${'1e+153'} | ${'one quinquagintillion'}
  279. ${'1e+183'} | ${'one sexagintillion'}
  280. ${'1e+213'} | ${'one septuagintillion'}
  281. ${'1e+243'} | ${'one octogintillion'}
  282. ${'1e+273'} | ${'one nonagintillion'}
  283. `('converts $value to $numberName', ({ value, numberName }: { value: string, numberName: string }) => {
  284. doExpect(value, numberName);
  285. });
  286. it.each`
  287. value | numberName
  288. ${'1e+303'} | ${'one centillion'}
  289. ${'1e+306'} | ${'one cenuntillion'}
  290. ${'1e+309'} | ${'one cenduotillion'}
  291. ${'1e+312'} | ${'one centretillion'}
  292. ${'1e+315'} | ${'one cenquattuortillion'}
  293. ${'1e+318'} | ${'one cenquintillion'}
  294. ${'1e+321'} | ${'one censextillion'}
  295. ${'1e+324'} | ${'one censeptentillion'}
  296. ${'1e+327'} | ${'one cenoctotillion'}
  297. ${'1e+330'} | ${'one cennovemtillion'}
  298. ${'1e+603'} | ${'one duocentillion'}
  299. ${'1e+903'} | ${'one trecentillion'}
  300. ${'1e+1203'} | ${'one quadringentillion'}
  301. ${'1e+1503'} | ${'one quingentillion'}
  302. ${'1e+1803'} | ${'one sescentillion'}
  303. ${'1e+2103'} | ${'one septingentillion'}
  304. ${'1e+2403'} | ${'one octingentillion'}
  305. ${'1e+2703'} | ${'one nongentillion'}
  306. `('converts $value to $numberName', ({ value, numberName }: { value: string, numberName: string }) => {
  307. doExpect(value, numberName);
  308. });
  309. it('converts \'1e+3003\' to \'one milliatillion\'', () => {
  310. doExpect('1e+3003', 'one milliatillion');
  311. });
  312. });