Gets the name of a number, even if it's stupidly big. Supersedes TheoryOfNekomata/number-name.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 

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